···11+ MFP Configuration for PXA2xx/PXA3xx Processors22+33+ Eric Miao <eric.miao@marvell.com>44+55+MFP stands for Multi-Function Pin, which is the pin-mux logic on PXA3xx and66+later PXA series processors. This document describes the existing MFP API,77+and how board/platform driver authors could make use of it.88+99+ Basic Concept1010+===============1111+1212+Unlike the GPIO alternate function settings on PXA25x and PXA27x, a new MFP1313+mechanism is introduced from PXA3xx to completely move the pin-mux functions1414+out of the GPIO controller. In addition to pin-mux configurations, the MFP1515+also controls the low power state, driving strength, pull-up/down and event1616+detection of each pin. Below is a diagram of internal connections between1717+the MFP logic and the remaining SoC peripherals:1818+1919+ +--------+2020+ | |--(GPIO19)--+2121+ | GPIO | |2222+ | |--(GPIO...) |2323+ +--------+ |2424+ | +---------+2525+ +--------+ +------>| |2626+ | PWM2 |--(PWM_OUT)-------->| MFP |2727+ +--------+ +------>| |-------> to external PAD2828+ | +---->| |2929+ +--------+ | | +-->| |3030+ | SSP2 |---(TXD)----+ | | +---------+3131+ +--------+ | |3232+ | |3333+ +--------+ | |3434+ | Keypad |--(MKOUT4)----+ |3535+ +--------+ |3636+ |3737+ +--------+ |3838+ | UART2 |---(TXD)--------+3939+ +--------+4040+4141+NOTE: the external pad is named as MFP_PIN_GPIO19, it doesn't necessarily4242+mean it's dedicated for GPIO19, only as a hint that internally this pin4343+can be routed from GPIO19 of the GPIO controller.4444+4545+To better understand the change from PXA25x/PXA27x GPIO alternate function4646+to this new MFP mechanism, here are several key points:4747+4848+ 1. GPIO controller on PXA3xx is now a dedicated controller, same as other4949+ internal controllers like PWM, SSP and UART, with 128 internal signals5050+ which can be routed to external through one or more MFPs (e.g. GPIO<0>5151+ can be routed through either MFP_PIN_GPIO0 as well as MFP_PIN_GPIO0_2,5252+ see arch/arm/mach-pxa/mach/include/mfp-pxa300.h)5353+5454+ 2. Alternate function configuration is removed from this GPIO controller,5555+ the remaining functions are pure GPIO-specific, i.e.5656+5757+ - GPIO signal level control5858+ - GPIO direction control5959+ - GPIO level change detection6060+6161+ 3. Low power state for each pin is now controlled by MFP, this means the6262+ PGSRx registers on PXA2xx are now useless on PXA3xx6363+6464+ 4. Wakeup detection is now controlled by MFP, PWER does not control the6565+ wakeup from GPIO(s) any more, depending on the sleeping state, ADxER6666+ (as defined in pxa3xx-regs.h) controls the wakeup from MFP6767+6868+NOTE: with such a clear separation of MFP and GPIO, by GPIO<xx> we normally6969+mean it is a GPIO signal, and by MFP<xxx> or pin xxx, we mean a physical7070+pad (or ball).7171+7272+ MFP API Usage7373+===============7474+7575+For board code writers, here are some guidelines:7676+7777+1. include ONE of the following header files in your <board>.c:7878+7979+ - #include <mach/mfp-pxa25x.h>8080+ - #include <mach/mfp-pxa27x.h>8181+ - #include <mach/mfp-pxa300.h>8282+ - #include <mach/mfp-pxa320.h>8383+ - #include <mach/mfp-pxa930.h>8484+8585+ NOTE: only one file in your <board>.c, depending on the processors used,8686+ because pin configuration definitions may conflict in these file (i.e.8787+ same name, different meaning and settings on different processors). E.g.8888+ for zylonite platform, which support both PXA300/PXA310 and PXA320, two8989+ separate files are introduced: zylonite_pxa300.c and zylonite_pxa320.c9090+ (in addition to handle MFP configuration differences, they also handle9191+ the other differences between the two combinations).9292+9393+ NOTE: PXA300 and PXA310 are almost identical in pin configurations (with9494+ PXA310 supporting some additional ones), thus the difference is actually9595+ covered in a single mfp-pxa300.h.9696+9797+2. prepare an array for the initial pin configurations, e.g.:9898+9999+ static unsigned long mainstone_pin_config[] __initdata = {100100+ /* Chip Select */101101+ GPIO15_nCS_1,102102+103103+ /* LCD - 16bpp Active TFT */104104+ GPIOxx_TFT_LCD_16BPP,105105+ GPIO16_PWM0_OUT, /* Backlight */106106+107107+ /* MMC */108108+ GPIO32_MMC_CLK,109109+ GPIO112_MMC_CMD,110110+ GPIO92_MMC_DAT_0,111111+ GPIO109_MMC_DAT_1,112112+ GPIO110_MMC_DAT_2,113113+ GPIO111_MMC_DAT_3,114114+115115+ ...116116+117117+ /* GPIO */118118+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,119119+ };120120+121121+ a) once the pin configurations are passed to pxa{2xx,3xx}_mfp_config(),122122+ and written to the actual registers, they are useless and may discard,123123+ adding '__initdata' will help save some additional bytes here.124124+125125+ b) when there is only one possible pin configurations for a component,126126+ some simplified definitions can be used, e.g. GPIOxx_TFT_LCD_16BPP on127127+ PXA25x and PXA27x processors128128+129129+ c) if by board design, a pin can be configured to wake up the system130130+ from low power state, it can be 'OR'ed with any of:131131+132132+ WAKEUP_ON_EDGE_BOTH133133+ WAKEUP_ON_EDGE_RISE134134+ WAKEUP_ON_EDGE_FALL135135+ WAKEUP_ON_LEVEL_HIGH - specifically for enabling of keypad GPIOs,136136+137137+ to indicate that this pin has the capability of wake-up the system,138138+ and on which edge(s). This, however, doesn't necessarily mean the139139+ pin _will_ wakeup the system, it will only when set_irq_wake() is140140+ invoked with the corresponding GPIO IRQ (GPIO_IRQ(xx) or gpio_to_irq())141141+ and eventually calls gpio_set_wake() for the actual register setting.142142+143143+ d) although PXA3xx MFP supports edge detection on each pin, the144144+ internal logic will only wakeup the system when those specific bits145145+ in ADxER registers are set, which can be well mapped to the146146+ corresponding peripheral, thus set_irq_wake() can be called with 147147+ the peripheral IRQ to enable the wakeup.148148+149149+150150+ MFP on PXA3xx151151+===============152152+153153+Every external I/O pad on PXA3xx (excluding those for special purpose) has154154+one MFP logic associated, and is controlled by one MFP register (MFPR).155155+156156+The MFPR has the following bit definitions (for PXA300/PXA310/PXA320):157157+158158+ 31 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0159159+ +-------------------------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+160160+ | RESERVED |PS|PU|PD| DRIVE |SS|SD|SO|EC|EF|ER|--| AF_SEL |161161+ +-------------------------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+162162+163163+ Bit 3: RESERVED164164+ Bit 4: EDGE_RISE_EN - enable detection of rising edge on this pin165165+ Bit 5: EDGE_FALL_EN - enable detection of falling edge on this pin166166+ Bit 6: EDGE_CLEAR - disable edge detection on this pin167167+ Bit 7: SLEEP_OE_N - enable outputs during low power modes168168+ Bit 8: SLEEP_DATA - output data on the pin during low power modes169169+ Bit 9: SLEEP_SEL - selection control for low power modes signals170170+ Bit 13: PULLDOWN_EN - enable the internal pull-down resistor on this pin171171+ Bit 14: PULLUP_EN - enable the internal pull-up resistor on this pin172172+ Bit 15: PULL_SEL - pull state controlled by selected alternate function173173+ (0) or by PULL{UP,DOWN}_EN bits (1)174174+175175+ Bit 0 - 2: AF_SEL - alternate function selection, 8 possibilities, from 0-7176176+ Bit 10-12: DRIVE - drive strength and slew rate177177+ 0b000 - fast 1mA178178+ 0b001 - fast 2mA179179+ 0b002 - fast 3mA180180+ 0b003 - fast 4mA181181+ 0b004 - slow 6mA182182+ 0b005 - fast 6mA183183+ 0b006 - slow 10mA184184+ 0b007 - fast 10mA185185+186186+ MFP Design for PXA2xx/PXA3xx187187+==============================188188+189189+Due to the difference of pin-mux handling between PXA2xx and PXA3xx, a unified190190+MFP API is introduced to cover both series of processors.191191+192192+The basic idea of this design is to introduce definitions for all possible pin193193+configurations, these definitions are processor and platform independent, and194194+the actual API invoked to convert these definitions into register settings and195195+make them effective there-after.196196+197197+ Files Involved198198+ --------------199199+200200+ - arch/arm/mach-pxa/include/mach/mfp.h201201+202202+ for203203+ 1. Unified pin definitions - enum constants for all configurable pins204204+ 2. processor-neutral bit definitions for a possible MFP configuration205205+206206+ - arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h207207+208208+ for PXA3xx specific MFPR register bit definitions and PXA3xx common pin209209+ configurations210210+211211+ - arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h212212+213213+ for PXA2xx specific definitions and PXA25x/PXA27x common pin configurations214214+215215+ - arch/arm/mach-pxa/include/mach/mfp-pxa25x.h216216+ arch/arm/mach-pxa/include/mach/mfp-pxa27x.h217217+ arch/arm/mach-pxa/include/mach/mfp-pxa300.h218218+ arch/arm/mach-pxa/include/mach/mfp-pxa320.h219219+ arch/arm/mach-pxa/include/mach/mfp-pxa930.h220220+221221+ for processor specific definitions222222+223223+ - arch/arm/mach-pxa/mfp-pxa3xx.c224224+ - arch/arm/mach-pxa/mfp-pxa2xx.c225225+226226+ for implementation of the pin configuration to take effect for the actual227227+ processor.228228+229229+ Pin Configuration230230+ -----------------231231+232232+ The following comments are copied from mfp.h (see the actual source code233233+ for most updated info)234234+235235+ /*236236+ * a possible MFP configuration is represented by a 32-bit integer237237+ *238238+ * bit 0.. 9 - MFP Pin Number (1024 Pins Maximum)239239+ * bit 10..12 - Alternate Function Selection240240+ * bit 13..15 - Drive Strength241241+ * bit 16..18 - Low Power Mode State242242+ * bit 19..20 - Low Power Mode Edge Detection243243+ * bit 21..22 - Run Mode Pull State244244+ *245245+ * to facilitate the definition, the following macros are provided246246+ *247247+ * MFP_CFG_DEFAULT - default MFP configuration value, with248248+ * alternate function = 0,249249+ * drive strength = fast 3mA (MFP_DS03X)250250+ * low power mode = default251251+ * edge detection = none252252+ *253253+ * MFP_CFG - default MFPR value with alternate function254254+ * MFP_CFG_DRV - default MFPR value with alternate function and255255+ * pin drive strength256256+ * MFP_CFG_LPM - default MFPR value with alternate function and257257+ * low power mode258258+ * MFP_CFG_X - default MFPR value with alternate function,259259+ * pin drive strength and low power mode260260+ */261261+262262+ Examples of pin configurations are:263263+264264+ #define GPIO94_SSP3_RXD MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)265265+266266+ which reads GPIO94 can be configured as SSP3_RXD, with alternate function267267+ selection of 1, driving strength of 0b101, and a float state in low power268268+ modes.269269+270270+ NOTE: this is the default setting of this pin being configured as SSP3_RXD271271+ which can be modified a bit in board code, though it is not recommended to272272+ do so, simply because this default setting is usually carefully encoded,273273+ and is supposed to work in most cases.274274+275275+ Register Settings276276+ -----------------277277+278278+ Register settings on PXA3xx for a pin configuration is actually very279279+ straight-forward, most bits can be converted directly into MFPR value280280+ in a easier way. Two sets of MFPR values are calculated: the run-time281281+ ones and the low power mode ones, to allow different settings.282282+283283+ The conversion from a generic pin configuration to the actual register284284+ settings on PXA2xx is a bit complicated: many registers are involved,285285+ including GAFRx, GPDRx, PGSRx, PWER, PKWR, PFER and PRER. Please see286286+ mfp-pxa2xx.c for how the conversion is made.
+90-2
Documentation/fb/pxafb.txt
···55options=<OPTIONS> when modular or video=pxafb:<OPTIONS> when built in.6677For example:88- modprobe pxafb options=mode:640x480-8,passive88+ modprobe pxafb options=vmem:2M,mode:640x480-8,passive99or on the kernel command line1010- video=pxafb:mode:640x480-8,passive1010+ video=pxafb:vmem:2M,mode:640x480-8,passive1111+1212+vmem: VIDEO_MEM_SIZE1313+ Amount of video memory to allocate (can be suffixed with K or M1414+ for kilobytes or megabytes)11151216mode:XRESxYRES[-BPP]1317 XRES == LCCR1_PPL + 1···5652pixclockpol:POLARITY5753 pixel clock polarity5854 0 => falling edge, 1 => rising edge5555+5656+5757+Overlay Support for PXA27x and later LCD controllers5858+====================================================5959+6060+ PXA27x and later processors support overlay1 and overlay2 on-top of the6161+ base framebuffer (although under-neath the base is also possible). They6262+ support palette and no-palette RGB formats, as well as YUV formats (only6363+ available on overlay2). These overlays have dedicated DMA channels and6464+ behave in a similar way as a framebuffer.6565+6666+ However, there are some differences between these overlay framebuffers6767+ and normal framebuffers, as listed below:6868+6969+ 1. overlay can start at a 32-bit word aligned position within the base7070+ framebuffer, which means they have a start (x, y). This information7171+ is encoded into var->nonstd (no, var->xoffset and var->yoffset are7272+ not for such purpose).7373+7474+ 2. overlay framebuffer is allocated dynamically according to specified7575+ 'struct fb_var_screeninfo', the amount is decided by:7676+7777+ var->xres_virtual * var->yres_virtual * bpp7878+7979+ bpp = 16 -- for RGB565 or RGBT5558080+ = 24 -- for YUV444 packed8181+ = 24 -- for YUV444 planar8282+ = 16 -- for YUV422 planar (1 pixel = 1 Y + 1/2 Cb + 1/2 Cr)8383+ = 12 -- for YUV420 planar (1 pixel = 1 Y + 1/4 Cb + 1/4 Cr)8484+8585+ NOTE:8686+8787+ a. overlay does not support panning in x-direction, thus8888+ var->xres_virtual will always be equal to var->xres8989+9090+ b. line length of overlay(s) must be on a 32-bit word boundary,9191+ for YUV planar modes, it is a requirement for the component9292+ with minimum bits per pixel, e.g. for YUV420, Cr component9393+ for one pixel is actually 2-bits, it means the line length9494+ should be a multiple of 16-pixels9595+9696+ c. starting horizontal position (XPOS) should start on a 32-bit9797+ word boundary, otherwise the fb_check_var() will just fail.9898+9999+ d. the rectangle of the overlay should be within the base plane,100100+ otherwise fail101101+102102+ Applications should follow the sequence below to operate an overlay103103+ framebuffer:104104+105105+ a. open("/dev/fb[1-2]", ...)106106+ b. ioctl(fd, FBIOGET_VSCREENINFO, ...)107107+ c. modify 'var' with desired parameters:108108+ 1) var->xres and var->yres109109+ 2) larger var->yres_virtual if more memory is required,110110+ usually for double-buffering111111+ 3) var->nonstd for starting (x, y) and color format112112+ 4) var->{red, green, blue, transp} if RGB mode is to be used113113+ d. ioctl(fd, FBIOPUT_VSCREENINFO, ...)114114+ e. ioctl(fd, FBIOGET_FSCREENINFO, ...)115115+ f. mmap116116+ g. ...117117+118118+ 3. for YUV planar formats, these are actually not supported within the119119+ framebuffer framework, application has to take care of the offsets120120+ and lengths of each component within the framebuffer.121121+122122+ 4. var->nonstd is used to pass starting (x, y) position and color format,123123+ the detailed bit fields are shown below:124124+125125+ 31 23 20 10 0126126+ +-----------------+---+----------+----------+127127+ | ... unused ... |FOR| XPOS | YPOS |128128+ +-----------------+---+----------+----------+129129+130130+ FOR - color format, as defined by OVERLAY_FORMAT_* in pxafb.h131131+ 0 - RGB132132+ 1 - YUV444 PACKED133133+ 2 - YUV444 PLANAR134134+ 3 - YUV422 PLANAR135135+ 4 - YUR420 PLANAR136136+137137+ XPOS - starting horizontal position138138+ YPOS - starting vertical position
+16
arch/arm/mach-pxa/generic.c
···2424#include <asm/system.h>2525#include <asm/pgtable.h>2626#include <asm/mach/map.h>2727+#include <asm/mach-types.h>27282829#include <mach/pxa-regs.h>2930#include <mach/reset.h>···3938 if (cpu_is_pxa3xx())4039 pxa3xx_clear_reset_status(mask);4140}4141+4242+unsigned long get_clock_tick_rate(void)4343+{4444+ unsigned long clock_tick_rate;4545+4646+ if (cpu_is_pxa25x())4747+ clock_tick_rate = 3686400;4848+ else if (machine_is_mainstone())4949+ clock_tick_rate = 3249600;5050+ else5151+ clock_tick_rate = 3250000;5252+5353+ return clock_tick_rate;5454+}5555+EXPORT_SYMBOL(get_clock_tick_rate);42564357/*4458 * Get the clock frequency as reflected by CCCR and the turbo flag.
+2
arch/arm/mach-pxa/include/mach/hardware.h
···291291 */292292extern unsigned int get_memclk_frequency_10khz(void);293293294294+/* return the clock tick rate of the OS timer */295295+extern unsigned long get_clock_tick_rate(void);294296#endif295297296298#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
···113113 unsigned int num_modes;114114115115 unsigned int lcd_conn;116116+ unsigned long video_mem_size;116117117118 u_int fixed_modes:1,118119 cmap_inverse:1,
···1010 * published by the Free Software Foundation.1111 */12121313+/* Various drivers are still using the constant of CLOCK_TICK_RATE, for1414+ * those drivers to at least work, the definition is provided here.1515+ *1616+ * NOTE: this is no longer accurate when multiple processors and boards1717+ * are selected, newer drivers should not depend on this any more. Use1818+ * either the clocksource/clockevent or get this at run-time by calling1919+ * get_clock_tick_rate() (as defined in generic.c).2020+ */13211422#if defined(CONFIG_PXA25x)1523/* PXA250/210 timer base */
···2424#include <asm/mach/time.h>2525#include <mach/hardware.h>2626#include <mach/pxa-regs.h>2727-#include <asm/mach-types.h>28272928/*3029 * This is PXA's sched_clock implementation. This has a resolution···150151151152static void __init pxa_timer_init(void)152153{153153- unsigned long clock_tick_rate;154154+ unsigned long clock_tick_rate = get_clock_tick_rate();154155155156 OIER = 0;156157 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;157157-158158- if (cpu_is_pxa25x())159159- clock_tick_rate = 3686400;160160- else if (machine_is_mainstone())161161- clock_tick_rate = 3249600;162162- else163163- clock_tick_rate = 3250000;164158165159 set_oscr2ns_scale(clock_tick_rate);166160
+4
arch/arm/mach-sa1100/include/mach/hardware.h
···5959# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))6060# define __PREG(x) (io_v2p((unsigned long)&(x)))61616262+static inline unsigned long get_clock_tick_rate(void)6363+{6464+ return 3686400;6565+}6266#else63676468# define __REG(x) io_p2v(x)
+7-5
drivers/rtc/rtc-sa1100.c
···3838#include <mach/pxa-regs.h>3939#endif40404141-#define TIMER_FREQ CLOCK_TICK_RATE4241#define RTC_DEF_DIVIDER 32768 - 14342#define RTC_DEF_TRIM 044434544static unsigned long rtc_freq = 1024;4545+static unsigned long timer_freq;4646static struct rtc_time rtc_alarm;4747static DEFINE_SPINLOCK(sa1100_rtc_lock);4848···157157 rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);158158159159 if (rtc_timer1_count == 1)160160- rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));160160+ rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2)));161161162162 return IRQ_HANDLED;163163}···166166{167167 if (data & RTC_PF) {168168 /* interpolate missed periods and set match for the next */169169- unsigned long period = TIMER_FREQ/rtc_freq;169169+ unsigned long period = timer_freq / rtc_freq;170170 unsigned long oscr = OSCR;171171 unsigned long osmr1 = OSMR1;172172 unsigned long missed = (oscr - osmr1)/period;···263263 return 0;264264 case RTC_PIE_ON:265265 spin_lock_irq(&sa1100_rtc_lock);266266- OSMR1 = TIMER_FREQ/rtc_freq + OSCR;266266+ OSMR1 = timer_freq / rtc_freq + OSCR;267267 OIER |= OIER_E1;268268 rtc_timer1_count = 1;269269 spin_unlock_irq(&sa1100_rtc_lock);···271271 case RTC_IRQP_READ:272272 return put_user(rtc_freq, (unsigned long *)arg);273273 case RTC_IRQP_SET:274274- if (arg < 1 || arg > TIMER_FREQ)274274+ if (arg < 1 || arg > timer_freq)275275 return -EINVAL;276276 rtc_freq = arg;277277 return 0;···351351static int sa1100_rtc_probe(struct platform_device *pdev)352352{353353 struct rtc_device *rtc;354354+355355+ timer_freq = get_clock_tick_rate();354356355357 /*356358 * According to the manual we should be able to let RTTR be zero
+5
drivers/video/Kconfig
···1817181718181818 If unsure, say N.1819181918201820+config FB_PXA_OVERLAY18211821+ bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"18221822+ default n18231823+ depends on FB_PXA && (PXA27x || PXA3xx)18241824+18201825config FB_PXA_SMARTPANEL18211826 bool "PXA Smartpanel LCD support"18221827 default n
+613-246
drivers/video/pxafb.c
···2020 *2121 * linux-arm-kernel@lists.arm.linux.org.uk2222 *2323+ * Add support for overlay1 and overlay2 based on pxafb_overlay.c:2424+ *2525+ * Copyright (C) 2004, Intel Corporation2626+ *2727+ * 2003/08/27: <yu.tang@intel.com>2828+ * 2004/03/10: <stanley.cai@intel.com>2929+ * 2004/10/28: <yan.yin@intel.com>3030+ *3131+ * Copyright (C) 2006-2008 Marvell International Ltd.3232+ * All Rights Reserved2333 */24342535#include <linux/module.h>···7666 LCCR0_SFM | LCCR0_LDM | LCCR0_ENB)77677868#define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP | LCCR3_VSP |\7979- LCCR3_PCD | LCCR3_BPP)6969+ LCCR3_PCD | LCCR3_BPP(0xf))80708171static int pxafb_activate_var(struct fb_var_screeninfo *var,8272 struct pxafb_info *);8373static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);7474+static void setup_base_frame(struct pxafb_info *fbi, int branch);7575+static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,7676+ unsigned long offset, size_t size);7777+7878+static unsigned long video_mem_size = 0;84798580static inline unsigned long8681lcd_readl(struct pxafb_info *fbi, unsigned int off)···167152 val |= ((blue >> 8) & 0x000000fc);168153 ((u32 *)(fbi->palette_cpu))[regno] = val;169154 break;155155+ case LCCR4_PAL_FOR_3:156156+ val = ((red << 8) & 0x00ff0000);157157+ val |= ((green >> 0) & 0x0000ff00);158158+ val |= ((blue >> 8) & 0x000000ff);159159+ ((u32 *)(fbi->palette_cpu))[regno] = val;160160+ break;170161 }171162172163 return 0;···233212 return ret;234213}235214236236-/*237237- * pxafb_bpp_to_lccr3():238238- * Convert a bits per pixel value to the correct bit pattern for LCCR3239239- */240240-static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var)215215+/* calculate pixel depth, transparency bit included, >=16bpp formats _only_ */216216+static inline int var_to_depth(struct fb_var_screeninfo *var)241217{242242- int ret = 0;218218+ return var->red.length + var->green.length +219219+ var->blue.length + var->transp.length;220220+}221221+222222+/* calculate 4-bit BPP value for LCCR3 and OVLxC1 */223223+static int pxafb_var_to_bpp(struct fb_var_screeninfo *var)224224+{225225+ int bpp = -EINVAL;226226+243227 switch (var->bits_per_pixel) {244244- case 1: ret = LCCR3_1BPP; break;245245- case 2: ret = LCCR3_2BPP; break;246246- case 4: ret = LCCR3_4BPP; break;247247- case 8: ret = LCCR3_8BPP; break;248248- case 16: ret = LCCR3_16BPP; break;228228+ case 1: bpp = 0; break;229229+ case 2: bpp = 1; break;230230+ case 4: bpp = 2; break;231231+ case 8: bpp = 3; break;232232+ case 16: bpp = 4; break;249233 case 24:250250- switch (var->red.length + var->green.length +251251- var->blue.length + var->transp.length) {252252- case 18: ret = LCCR3_18BPP_P | LCCR3_PDFOR_3; break;253253- case 19: ret = LCCR3_19BPP_P; break;234234+ switch (var_to_depth(var)) {235235+ case 18: bpp = 6; break; /* 18-bits/pixel packed */236236+ case 19: bpp = 8; break; /* 19-bits/pixel packed */237237+ case 24: bpp = 9; break;254238 }255239 break;256240 case 32:257257- switch (var->red.length + var->green.length +258258- var->blue.length + var->transp.length) {259259- case 18: ret = LCCR3_18BPP | LCCR3_PDFOR_3; break;260260- case 19: ret = LCCR3_19BPP; break;261261- case 24: ret = LCCR3_24BPP | LCCR3_PDFOR_3; break;262262- case 25: ret = LCCR3_25BPP; break;241241+ switch (var_to_depth(var)) {242242+ case 18: bpp = 5; break; /* 18-bits/pixel unpacked */243243+ case 19: bpp = 7; break; /* 19-bits/pixel unpacked */244244+ case 25: bpp = 10; break;263245 }264246 break;265247 }266266- return ret;248248+ return bpp;249249+}250250+251251+/*252252+ * pxafb_var_to_lccr3():253253+ * Convert a bits per pixel value to the correct bit pattern for LCCR3254254+ *255255+ * NOTE: for PXA27x with overlays support, the LCCR3_PDFOR_x bits have an256256+ * implication of the acutal use of transparency bit, which we handle it257257+ * here separatedly. See PXA27x Developer's Manual, Section <<7.4.6 Pixel258258+ * Formats>> for the valid combination of PDFOR, PAL_FOR for various BPP.259259+ *260260+ * Transparency for palette pixel formats is not supported at the moment.261261+ */262262+static uint32_t pxafb_var_to_lccr3(struct fb_var_screeninfo *var)263263+{264264+ int bpp = pxafb_var_to_bpp(var);265265+ uint32_t lccr3;266266+267267+ if (bpp < 0)268268+ return 0;269269+270270+ lccr3 = LCCR3_BPP(bpp);271271+272272+ switch (var_to_depth(var)) {273273+ case 16: lccr3 |= var->transp.length ? LCCR3_PDFOR_3 : 0; break;274274+ case 18: lccr3 |= LCCR3_PDFOR_3; break;275275+ case 24: lccr3 |= var->transp.length ? LCCR3_PDFOR_2 : LCCR3_PDFOR_3;276276+ break;277277+ case 19:278278+ case 25: lccr3 |= LCCR3_PDFOR_0; break;279279+ }280280+ return lccr3;281281+}282282+283283+#define SET_PIXFMT(v, r, g, b, t) \284284+({ \285285+ (v)->transp.offset = (t) ? (r) + (g) + (b) : 0; \286286+ (v)->transp.length = (t) ? (t) : 0; \287287+ (v)->blue.length = (b); (v)->blue.offset = 0; \288288+ (v)->green.length = (g); (v)->green.offset = (b); \289289+ (v)->red.length = (r); (v)->red.offset = (b) + (g); \290290+})291291+292292+/* set the RGBT bitfields of fb_var_screeninf according to293293+ * var->bits_per_pixel and given depth294294+ */295295+static void pxafb_set_pixfmt(struct fb_var_screeninfo *var, int depth)296296+{297297+ if (depth == 0)298298+ depth = var->bits_per_pixel;299299+300300+ if (var->bits_per_pixel < 16) {301301+ /* indexed pixel formats */302302+ var->red.offset = 0; var->red.length = 8;303303+ var->green.offset = 0; var->green.length = 8;304304+ var->blue.offset = 0; var->blue.length = 8;305305+ var->transp.offset = 0; var->transp.length = 8;306306+ }307307+308308+ switch (depth) {309309+ case 16: var->transp.length ?310310+ SET_PIXFMT(var, 5, 5, 5, 1) : /* RGBT555 */311311+ SET_PIXFMT(var, 5, 6, 5, 0); break; /* RGB565 */312312+ case 18: SET_PIXFMT(var, 6, 6, 6, 0); break; /* RGB666 */313313+ case 19: SET_PIXFMT(var, 6, 6, 6, 1); break; /* RGBT666 */314314+ case 24: var->transp.length ?315315+ SET_PIXFMT(var, 8, 8, 7, 1) : /* RGBT887 */316316+ SET_PIXFMT(var, 8, 8, 8, 0); break; /* RGB888 */317317+ case 25: SET_PIXFMT(var, 8, 8, 8, 1); break; /* RGBT888 */318318+ }267319}268320269321#ifdef CONFIG_CPU_FREQ···398304 var->lower_margin = mode->lower_margin;399305 var->sync = mode->sync;400306 var->grayscale = mode->cmap_greyscale;401401- var->xres_virtual = var->xres;402402- var->yres_virtual = var->yres;307307+308308+ /* set the initial RGBA bitfields */309309+ pxafb_set_pixfmt(var, mode->depth);310310+}311311+312312+static int pxafb_adjust_timing(struct pxafb_info *fbi,313313+ struct fb_var_screeninfo *var)314314+{315315+ int line_length;316316+317317+ var->xres = max_t(int, var->xres, MIN_XRES);318318+ var->yres = max_t(int, var->yres, MIN_YRES);319319+320320+ if (!(fbi->lccr0 & LCCR0_LCDT)) {321321+ clamp_val(var->hsync_len, 1, 64);322322+ clamp_val(var->vsync_len, 1, 64);323323+ clamp_val(var->left_margin, 1, 255);324324+ clamp_val(var->right_margin, 1, 255);325325+ clamp_val(var->upper_margin, 1, 255);326326+ clamp_val(var->lower_margin, 1, 255);327327+ }328328+329329+ /* make sure each line is aligned on word boundary */330330+ line_length = var->xres * var->bits_per_pixel / 8;331331+ line_length = ALIGN(line_length, 4);332332+ var->xres = line_length * 8 / var->bits_per_pixel;333333+334334+ /* we don't support xpan, force xres_virtual to be equal to xres */335335+ var->xres_virtual = var->xres;336336+337337+ if (var->accel_flags & FB_ACCELF_TEXT)338338+ var->yres_virtual = fbi->fb.fix.smem_len / line_length;339339+ else340340+ var->yres_virtual = max(var->yres_virtual, var->yres);341341+342342+ /* check for limits */343343+ if (var->xres > MAX_XRES || var->yres > MAX_YRES)344344+ return -EINVAL;345345+346346+ if (var->yres > var->yres_virtual)347347+ return -EINVAL;348348+349349+ return 0;403350}404351405352/*···456321{457322 struct pxafb_info *fbi = (struct pxafb_info *)info;458323 struct pxafb_mach_info *inf = fbi->dev->platform_data;459459-460460- if (var->xres < MIN_XRES)461461- var->xres = MIN_XRES;462462- if (var->yres < MIN_YRES)463463- var->yres = MIN_YRES;324324+ int err;464325465326 if (inf->fixed_modes) {466327 struct pxafb_mode_info *mode;···465334 if (!mode)466335 return -EINVAL;467336 pxafb_setmode(var, mode);468468- } else {469469- if (var->xres > inf->modes->xres)470470- return -EINVAL;471471- if (var->yres > inf->modes->yres)472472- return -EINVAL;473473- if (var->bits_per_pixel > inf->modes->bpp)474474- return -EINVAL;475337 }476338477477- var->xres_virtual =478478- max(var->xres_virtual, var->xres);479479- var->yres_virtual =480480- max(var->yres_virtual, var->yres);339339+ /* do a test conversion to BPP fields to check the color formats */340340+ err = pxafb_var_to_bpp(var);341341+ if (err < 0)342342+ return err;481343482482- /*483483- * Setup the RGB parameters for this display.484484- *485485- * The pixel packing format is described on page 7-11 of the486486- * PXA2XX Developer's Manual.487487- */488488- if (var->bits_per_pixel == 16) {489489- var->red.offset = 11; var->red.length = 5;490490- var->green.offset = 5; var->green.length = 6;491491- var->blue.offset = 0; var->blue.length = 5;492492- var->transp.offset = var->transp.length = 0;493493- } else if (var->bits_per_pixel > 16) {494494- struct pxafb_mode_info *mode;344344+ pxafb_set_pixfmt(var, var_to_depth(var));495345496496- mode = pxafb_getmode(inf, var);497497- if (!mode)498498- return -EINVAL;499499-500500- switch (mode->depth) {501501- case 18: /* RGB666 */502502- var->transp.offset = var->transp.length = 0;503503- var->red.offset = 12; var->red.length = 6;504504- var->green.offset = 6; var->green.length = 6;505505- var->blue.offset = 0; var->blue.length = 6;506506- break;507507- case 19: /* RGBT666 */508508- var->transp.offset = 18; var->transp.length = 1;509509- var->red.offset = 12; var->red.length = 6;510510- var->green.offset = 6; var->green.length = 6;511511- var->blue.offset = 0; var->blue.length = 6;512512- break;513513- case 24: /* RGB888 */514514- var->transp.offset = var->transp.length = 0;515515- var->red.offset = 16; var->red.length = 8;516516- var->green.offset = 8; var->green.length = 8;517517- var->blue.offset = 0; var->blue.length = 8;518518- break;519519- case 25: /* RGBT888 */520520- var->transp.offset = 24; var->transp.length = 1;521521- var->red.offset = 16; var->red.length = 8;522522- var->green.offset = 8; var->green.length = 8;523523- var->blue.offset = 0; var->blue.length = 8;524524- break;525525- default:526526- return -EINVAL;527527- }528528- } else {529529- var->red.offset = var->green.offset = 0;530530- var->blue.offset = var->transp.offset = 0;531531- var->red.length = 8;532532- var->green.length = 8;533533- var->blue.length = 8;534534- var->transp.length = 0;535535- }346346+ err = pxafb_adjust_timing(fbi, var);347347+ if (err)348348+ return err;536349537350#ifdef CONFIG_CPU_FREQ538351 pr_debug("pxafb: dma period = %d ps\n",···484409#endif485410486411 return 0;487487-}488488-489489-static inline void pxafb_set_truecolor(u_int is_true_color)490490-{491491- /* do your machine-specific setup if needed */492412}493413494414/*···518448519449 fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0];520450521521- /*522522- * Set (any) board control register to handle new color depth523523- */524524- pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);525525-526451 if (fbi->fb.var.bits_per_pixel >= 16)527452 fb_dealloc_cmap(&fbi->fb.cmap);528453 else···525460526461 pxafb_activate_var(var, fbi);527462463463+ return 0;464464+}465465+466466+static int pxafb_pan_display(struct fb_var_screeninfo *var,467467+ struct fb_info *info)468468+{469469+ struct pxafb_info *fbi = (struct pxafb_info *)info;470470+ int dma = DMA_MAX + DMA_BASE;471471+472472+ if (fbi->state != C_ENABLE)473473+ return 0;474474+475475+ setup_base_frame(fbi, 1);476476+477477+ if (fbi->lccr0 & LCCR0_SDS)478478+ lcd_writel(fbi, FBR1, fbi->fdadr[dma + 1] | 0x1);479479+480480+ lcd_writel(fbi, FBR0, fbi->fdadr[dma] | 0x1);528481 return 0;529482}530483···581498 return 0;582499}583500584584-static int pxafb_mmap(struct fb_info *info,585585- struct vm_area_struct *vma)586586-{587587- struct pxafb_info *fbi = (struct pxafb_info *)info;588588- unsigned long off = vma->vm_pgoff << PAGE_SHIFT;589589-590590- if (off < info->fix.smem_len) {591591- vma->vm_pgoff += fbi->video_offset / PAGE_SIZE;592592- return dma_mmap_writecombine(fbi->dev, vma, fbi->map_cpu,593593- fbi->map_dma, fbi->map_size);594594- }595595- return -EINVAL;596596-}597597-598501static struct fb_ops pxafb_ops = {599502 .owner = THIS_MODULE,600503 .fb_check_var = pxafb_check_var,601504 .fb_set_par = pxafb_set_par,505505+ .fb_pan_display = pxafb_pan_display,602506 .fb_setcolreg = pxafb_setcolreg,603507 .fb_fillrect = cfb_fillrect,604508 .fb_copyarea = cfb_copyarea,605509 .fb_imageblit = cfb_imageblit,606510 .fb_blank = pxafb_blank,607607- .fb_mmap = pxafb_mmap,608511};512512+513513+#ifdef CONFIG_FB_PXA_OVERLAY514514+static void overlay1fb_setup(struct pxafb_layer *ofb)515515+{516516+ int size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual;517517+ unsigned long start = ofb->video_mem_phys;518518+ setup_frame_dma(ofb->fbi, DMA_OV1, PAL_NONE, start, size);519519+}520520+521521+/* Depending on the enable status of overlay1/2, the DMA should be522522+ * updated from FDADRx (when disabled) or FBRx (when enabled).523523+ */524524+static void overlay1fb_enable(struct pxafb_layer *ofb)525525+{526526+ int enabled = lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN;527527+ uint32_t fdadr1 = ofb->fbi->fdadr[DMA_OV1] | (enabled ? 0x1 : 0);528528+529529+ lcd_writel(ofb->fbi, enabled ? FBR1 : FDADR1, fdadr1);530530+ lcd_writel(ofb->fbi, OVL1C2, ofb->control[1]);531531+ lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] | OVLxC1_OEN);532532+}533533+534534+static void overlay1fb_disable(struct pxafb_layer *ofb)535535+{536536+ uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);537537+538538+ lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);539539+540540+ lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));541541+ lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));542542+ lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);543543+544544+ if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)545545+ pr_warning("%s: timeout disabling overlay1\n", __func__);546546+547547+ lcd_writel(ofb->fbi, LCCR5, lccr5);548548+}549549+550550+static void overlay2fb_setup(struct pxafb_layer *ofb)551551+{552552+ int size, div = 1, pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd);553553+ unsigned long start[3] = { ofb->video_mem_phys, 0, 0 };554554+555555+ if (pfor == OVERLAY_FORMAT_RGB || pfor == OVERLAY_FORMAT_YUV444_PACKED) {556556+ size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual;557557+ setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size);558558+ } else {559559+ size = ofb->fb.var.xres_virtual * ofb->fb.var.yres_virtual;560560+ switch (pfor) {561561+ case OVERLAY_FORMAT_YUV444_PLANAR: div = 1; break;562562+ case OVERLAY_FORMAT_YUV422_PLANAR: div = 2; break;563563+ case OVERLAY_FORMAT_YUV420_PLANAR: div = 4; break;564564+ }565565+ start[1] = start[0] + size;566566+ start[2] = start[1] + size / div;567567+ setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size);568568+ setup_frame_dma(ofb->fbi, DMA_OV2_Cb, -1, start[1], size / div);569569+ setup_frame_dma(ofb->fbi, DMA_OV2_Cr, -1, start[2], size / div);570570+ }571571+}572572+573573+static void overlay2fb_enable(struct pxafb_layer *ofb)574574+{575575+ int pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd);576576+ int enabled = lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN;577577+ uint32_t fdadr2 = ofb->fbi->fdadr[DMA_OV2_Y] | (enabled ? 0x1 : 0);578578+ uint32_t fdadr3 = ofb->fbi->fdadr[DMA_OV2_Cb] | (enabled ? 0x1 : 0);579579+ uint32_t fdadr4 = ofb->fbi->fdadr[DMA_OV2_Cr] | (enabled ? 0x1 : 0);580580+581581+ if (pfor == OVERLAY_FORMAT_RGB || pfor == OVERLAY_FORMAT_YUV444_PACKED)582582+ lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2);583583+ else {584584+ lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2);585585+ lcd_writel(ofb->fbi, enabled ? FBR3 : FDADR3, fdadr3);586586+ lcd_writel(ofb->fbi, enabled ? FBR4 : FDADR4, fdadr4);587587+ }588588+ lcd_writel(ofb->fbi, OVL2C2, ofb->control[1]);589589+ lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] | OVLxC1_OEN);590590+}591591+592592+static void overlay2fb_disable(struct pxafb_layer *ofb)593593+{594594+ uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);595595+596596+ lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);597597+598598+ lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));599599+ lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));600600+ lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);601601+ lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);602602+ lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);603603+604604+ if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)605605+ pr_warning("%s: timeout disabling overlay2\n", __func__);606606+}607607+608608+static struct pxafb_layer_ops ofb_ops[] = {609609+ [0] = {610610+ .enable = overlay1fb_enable,611611+ .disable = overlay1fb_disable,612612+ .setup = overlay1fb_setup,613613+ },614614+ [1] = {615615+ .enable = overlay2fb_enable,616616+ .disable = overlay2fb_disable,617617+ .setup = overlay2fb_setup,618618+ },619619+};620620+621621+static int overlayfb_open(struct fb_info *info, int user)622622+{623623+ struct pxafb_layer *ofb = (struct pxafb_layer *)info;624624+625625+ /* no support for framebuffer console on overlay */626626+ if (user == 0)627627+ return -ENODEV;628628+629629+ /* allow only one user at a time */630630+ if (atomic_inc_and_test(&ofb->usage))631631+ return -EBUSY;632632+633633+ /* unblank the base framebuffer */634634+ fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);635635+ return 0;636636+}637637+638638+static int overlayfb_release(struct fb_info *info, int user)639639+{640640+ struct pxafb_layer *ofb = (struct pxafb_layer*) info;641641+642642+ atomic_dec(&ofb->usage);643643+ ofb->ops->disable(ofb);644644+645645+ free_pages_exact(ofb->video_mem, ofb->video_mem_size);646646+ ofb->video_mem = NULL;647647+ ofb->video_mem_size = 0;648648+ return 0;649649+}650650+651651+static int overlayfb_check_var(struct fb_var_screeninfo *var,652652+ struct fb_info *info)653653+{654654+ struct pxafb_layer *ofb = (struct pxafb_layer *)info;655655+ struct fb_var_screeninfo *base_var = &ofb->fbi->fb.var;656656+ int xpos, ypos, pfor, bpp;657657+658658+ xpos = NONSTD_TO_XPOS(var->nonstd);659659+ ypos = NONSTD_TO_XPOS(var->nonstd);660660+ pfor = NONSTD_TO_PFOR(var->nonstd);661661+662662+ bpp = pxafb_var_to_bpp(var);663663+ if (bpp < 0)664664+ return -EINVAL;665665+666666+ /* no support for YUV format on overlay1 */667667+ if (ofb->id == OVERLAY1 && pfor != 0)668668+ return -EINVAL;669669+670670+ /* for YUV packed formats, bpp = 'minimum bpp of YUV components' */671671+ switch (pfor) {672672+ case OVERLAY_FORMAT_RGB:673673+ bpp = pxafb_var_to_bpp(var);674674+ if (bpp < 0)675675+ return -EINVAL;676676+677677+ pxafb_set_pixfmt(var, var_to_depth(var));678678+ break;679679+ case OVERLAY_FORMAT_YUV444_PACKED: bpp = 24; break;680680+ case OVERLAY_FORMAT_YUV444_PLANAR: bpp = 8; break;681681+ case OVERLAY_FORMAT_YUV422_PLANAR: bpp = 4; break;682682+ case OVERLAY_FORMAT_YUV420_PLANAR: bpp = 2; break;683683+ default:684684+ return -EINVAL;685685+ }686686+687687+ /* each line must start at a 32-bit word boundary */688688+ if ((xpos * bpp) % 32)689689+ return -EINVAL;690690+691691+ /* xres must align on 32-bit word boundary */692692+ var->xres = roundup(var->xres * bpp, 32) / bpp;693693+694694+ if ((xpos + var->xres > base_var->xres) ||695695+ (ypos + var->yres > base_var->yres))696696+ return -EINVAL;697697+698698+ var->xres_virtual = var->xres;699699+ var->yres_virtual = max(var->yres, var->yres_virtual);700700+ return 0;701701+}702702+703703+static int overlayfb_map_video_memory(struct pxafb_layer *ofb)704704+{705705+ struct fb_var_screeninfo *var = &ofb->fb.var;706706+ int pfor = NONSTD_TO_PFOR(var->nonstd);707707+ int size, bpp = 0;708708+709709+ switch (pfor) {710710+ case OVERLAY_FORMAT_RGB: bpp = var->bits_per_pixel; break;711711+ case OVERLAY_FORMAT_YUV444_PACKED: bpp = 24; break;712712+ case OVERLAY_FORMAT_YUV444_PLANAR: bpp = 24; break;713713+ case OVERLAY_FORMAT_YUV422_PLANAR: bpp = 16; break;714714+ case OVERLAY_FORMAT_YUV420_PLANAR: bpp = 12; break;715715+ }716716+717717+ ofb->fb.fix.line_length = var->xres_virtual * bpp / 8;718718+719719+ size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);720720+721721+ /* don't re-allocate if the original video memory is enough */722722+ if (ofb->video_mem) {723723+ if (ofb->video_mem_size >= size)724724+ return 0;725725+726726+ free_pages_exact(ofb->video_mem, ofb->video_mem_size);727727+ }728728+729729+ ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);730730+ if (ofb->video_mem == NULL)731731+ return -ENOMEM;732732+733733+ ofb->video_mem_phys = virt_to_phys(ofb->video_mem);734734+ ofb->video_mem_size = size;735735+736736+ ofb->fb.fix.smem_start = ofb->video_mem_phys;737737+ ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual;738738+ ofb->fb.screen_base = ofb->video_mem;739739+ return 0;740740+}741741+742742+static int overlayfb_set_par(struct fb_info *info)743743+{744744+ struct pxafb_layer *ofb = (struct pxafb_layer *)info;745745+ struct fb_var_screeninfo *var = &info->var;746746+ int xpos, ypos, pfor, bpp, ret;747747+748748+ ret = overlayfb_map_video_memory(ofb);749749+ if (ret)750750+ return ret;751751+752752+ bpp = pxafb_var_to_bpp(var);753753+ xpos = NONSTD_TO_XPOS(var->nonstd);754754+ ypos = NONSTD_TO_XPOS(var->nonstd);755755+ pfor = NONSTD_TO_PFOR(var->nonstd);756756+757757+ ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |758758+ OVLxC1_BPP(bpp);759759+ ofb->control[1] = OVLxC2_XPOS(xpos) | OVLxC2_YPOS(ypos);760760+761761+ if (ofb->id == OVERLAY2)762762+ ofb->control[1] |= OVL2C2_PFOR(pfor);763763+764764+ ofb->ops->setup(ofb);765765+ ofb->ops->enable(ofb);766766+ return 0;767767+}768768+769769+static struct fb_ops overlay_fb_ops = {770770+ .owner = THIS_MODULE,771771+ .fb_open = overlayfb_open,772772+ .fb_release = overlayfb_release,773773+ .fb_check_var = overlayfb_check_var,774774+ .fb_set_par = overlayfb_set_par,775775+};776776+777777+static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,778778+ struct pxafb_layer *ofb, int id)779779+{780780+ sprintf(ofb->fb.fix.id, "overlay%d", id + 1);781781+782782+ ofb->fb.fix.type = FB_TYPE_PACKED_PIXELS;783783+ ofb->fb.fix.xpanstep = 0;784784+ ofb->fb.fix.ypanstep = 1;785785+786786+ ofb->fb.var.activate = FB_ACTIVATE_NOW;787787+ ofb->fb.var.height = -1;788788+ ofb->fb.var.width = -1;789789+ ofb->fb.var.vmode = FB_VMODE_NONINTERLACED;790790+791791+ ofb->fb.fbops = &overlay_fb_ops;792792+ ofb->fb.flags = FBINFO_FLAG_DEFAULT;793793+ ofb->fb.node = -1;794794+ ofb->fb.pseudo_palette = NULL;795795+796796+ ofb->id = id;797797+ ofb->ops = &ofb_ops[id];798798+ atomic_set(&ofb->usage, 0);799799+ ofb->fbi = fbi;800800+ init_completion(&ofb->branch_done);801801+}802802+803803+static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)804804+{805805+ int i, ret;806806+807807+ for (i = 0; i < 2; i++) {808808+ init_pxafb_overlay(fbi, &fbi->overlay[i], i);809809+ ret = register_framebuffer(&fbi->overlay[i].fb);810810+ if (ret) {811811+ dev_err(fbi->dev, "failed to register overlay %d\n", i);812812+ return ret;813813+ }814814+ }815815+816816+ /* mask all IU/BS/EOF/SOF interrupts */817817+ lcd_writel(fbi, LCCR5, ~0);818818+819819+ /* place overlay(s) on top of base */820820+ fbi->lccr0 |= LCCR0_OUC;821821+ pr_info("PXA Overlay driver loaded successfully!\n");822822+ return 0;823823+}824824+825825+static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)826826+{827827+ int i;828828+829829+ for (i = 0; i < 2; i++)830830+ unregister_framebuffer(&fbi->overlay[i].fb);831831+}832832+#else833833+static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}834834+static inline void pxafb_overlay_exit(struct pxafb_info *fbi) {}835835+#endif /* CONFIG_FB_PXA_OVERLAY */609836610837/*611838 * Calculate the PCD value from the clock rate (in picoseconds).···996603EXPORT_SYMBOL(pxafb_get_hsync_time);997604998605static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,999999- unsigned int offset, size_t size)606606+ unsigned long start, size_t size)1000607{1001608 struct pxafb_dma_descriptor *dma_desc, *pal_desc;1002609 unsigned int dma_desc_off, pal_desc_off;100361010041004- if (dma < 0 || dma >= DMA_MAX)611611+ if (dma < 0 || dma >= DMA_MAX * 2)1005612 return -EINVAL;10066131007614 dma_desc = &fbi->dma_buff->dma_desc[dma];1008615 dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[dma]);100961610101010- dma_desc->fsadr = fbi->screen_dma + offset;617617+ dma_desc->fsadr = start;1011618 dma_desc->fidr = 0;1012619 dma_desc->ldcmd = size;101362010141014- if (pal < 0 || pal >= PAL_MAX) {621621+ if (pal < 0 || pal >= PAL_MAX * 2) {1015622 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;1016623 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;1017624 } else {···1035642 }10366431037644 return 0;645645+}646646+647647+static void setup_base_frame(struct pxafb_info *fbi, int branch)648648+{649649+ struct fb_var_screeninfo *var = &fbi->fb.var;650650+ struct fb_fix_screeninfo *fix = &fbi->fb.fix;651651+ int nbytes, dma, pal, bpp = var->bits_per_pixel;652652+ unsigned long offset;653653+654654+ dma = DMA_BASE + (branch ? DMA_MAX : 0);655655+ pal = (bpp >= 16) ? PAL_NONE : PAL_BASE + (branch ? PAL_MAX : 0);656656+657657+ nbytes = fix->line_length * var->yres;658658+ offset = fix->line_length * var->yoffset + fbi->video_mem_phys;659659+660660+ if (fbi->lccr0 & LCCR0_SDS) {661661+ nbytes = nbytes / 2;662662+ setup_frame_dma(fbi, dma + 1, PAL_NONE, offset + nbytes, nbytes);663663+ }664664+665665+ setup_frame_dma(fbi, dma, pal, offset, nbytes);1038666}10396671040668#ifdef CONFIG_FB_PXA_SMARTPANEL···1111697 lcd_writel(fbi, LCCR1, fbi->reg_lccr1);1112698 lcd_writel(fbi, LCCR2, fbi->reg_lccr2);1113699 lcd_writel(fbi, LCCR3, fbi->reg_lccr3);700700+ lcd_writel(fbi, LCCR4, fbi->reg_lccr4);1114701 lcd_writel(fbi, FDADR0, fbi->fdadr[0]);1115702 lcd_writel(fbi, FDADR6, fbi->fdadr[6]);1116703···1306891 struct pxafb_info *fbi)1307892{1308893 u_long flags;13091309- size_t nbytes;131089413111311-#if DEBUG_VAR13121312- if (!(fbi->lccr0 & LCCR0_LCDT)) {13131313- if (var->xres < 16 || var->xres > 1024)13141314- printk(KERN_ERR "%s: invalid xres %d\n",13151315- fbi->fb.fix.id, var->xres);13161316- switch (var->bits_per_pixel) {13171317- case 1:13181318- case 2:13191319- case 4:13201320- case 8:13211321- case 16:13221322- case 24:13231323- case 32:13241324- break;13251325- default:13261326- printk(KERN_ERR "%s: invalid bit depth %d\n",13271327- fbi->fb.fix.id, var->bits_per_pixel);13281328- break;13291329- }13301330-13311331- if (var->hsync_len < 1 || var->hsync_len > 64)13321332- printk(KERN_ERR "%s: invalid hsync_len %d\n",13331333- fbi->fb.fix.id, var->hsync_len);13341334- if (var->left_margin < 1 || var->left_margin > 255)13351335- printk(KERN_ERR "%s: invalid left_margin %d\n",13361336- fbi->fb.fix.id, var->left_margin);13371337- if (var->right_margin < 1 || var->right_margin > 255)13381338- printk(KERN_ERR "%s: invalid right_margin %d\n",13391339- fbi->fb.fix.id, var->right_margin);13401340- if (var->yres < 1 || var->yres > 1024)13411341- printk(KERN_ERR "%s: invalid yres %d\n",13421342- fbi->fb.fix.id, var->yres);13431343- if (var->vsync_len < 1 || var->vsync_len > 64)13441344- printk(KERN_ERR "%s: invalid vsync_len %d\n",13451345- fbi->fb.fix.id, var->vsync_len);13461346- if (var->upper_margin < 0 || var->upper_margin > 255)13471347- printk(KERN_ERR "%s: invalid upper_margin %d\n",13481348- fbi->fb.fix.id, var->upper_margin);13491349- if (var->lower_margin < 0 || var->lower_margin > 255)13501350- printk(KERN_ERR "%s: invalid lower_margin %d\n",13511351- fbi->fb.fix.id, var->lower_margin);13521352- }13531353-#endif1354895 /* Update shadow copy atomically */1355896 local_irq_save(flags);1356897···1317946#endif1318947 setup_parallel_timing(fbi, var);1319948949949+ setup_base_frame(fbi, 0);950950+1320951 fbi->reg_lccr0 = fbi->lccr0 |1321952 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |1322953 LCCR0_QDM | LCCR0_BM | LCCR0_OUM);132395413241324- fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);13251325-13261326- nbytes = var->yres * fbi->fb.fix.line_length;13271327-13281328- if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {13291329- nbytes = nbytes / 2;13301330- setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes);13311331- }13321332-13331333- if ((var->bits_per_pixel >= 16) || (fbi->lccr0 & LCCR0_LCDT))13341334- setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes);13351335- else13361336- setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes);955955+ fbi->reg_lccr3 |= pxafb_var_to_lccr3(var);13379561338957 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;1339958 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);···1337976 (lcd_readl(fbi, LCCR1) != fbi->reg_lccr1) ||1338977 (lcd_readl(fbi, LCCR2) != fbi->reg_lccr2) ||1339978 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||979979+ (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||1340980 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||1341981 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))1342982 pxafb_schedule_work(fbi, C_REENABLE);···13841022 return;1385102313861024 /* Sequence from 11.7.10 */10251025+ lcd_writel(fbi, LCCR4, fbi->reg_lccr4);13871026 lcd_writel(fbi, LCCR3, fbi->reg_lccr3);13881027 lcd_writel(fbi, LCCR2, fbi->reg_lccr2);13891028 lcd_writel(fbi, LCCR1, fbi->reg_lccr1);···14261063static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)14271064{14281065 struct pxafb_info *fbi = dev_id;14291429- unsigned int lccr0, lcsr = lcd_readl(fbi, LCSR);10661066+ unsigned int lccr0, lcsr, lcsr1;1430106710681068+ lcsr = lcd_readl(fbi, LCSR);14311069 if (lcsr & LCSR_LDD) {14321070 lccr0 = lcd_readl(fbi, LCCR0);14331071 lcd_writel(fbi, LCCR0, lccr0 | LCCR0_LDM);···14391075 if (lcsr & LCSR_CMD_INT)14401076 complete(&fbi->command_done);14411077#endif14421442-14431078 lcd_writel(fbi, LCSR, lcsr);10791079+10801080+#ifdef CONFIG_FB_PXA_OVERLAY10811081+ lcsr1 = lcd_readl(fbi, LCSR1);10821082+ if (lcsr1 & LCSR1_BS(1))10831083+ complete(&fbi->overlay[0].branch_done);10841084+10851085+ if (lcsr1 & LCSR1_BS(2))10861086+ complete(&fbi->overlay[1].branch_done);10871087+10881088+ lcd_writel(fbi, LCSR1, lcsr1);10891089+#endif14441090 return IRQ_HANDLED;14451091}14461092···16411267#define pxafb_resume NULL16421268#endif1643126916441644-/*16451645- * pxafb_map_video_memory():16461646- * Allocates the DRAM memory for the frame buffer. This buffer is16471647- * remapped into a non-cached, non-buffered, memory region to16481648- * allow palette and pixel writes to occur without flushing the16491649- * cache. Once this area is remapped, all virtual memory16501650- * access to the video memory should occur at the new region.16511651- */16521652-static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi)12701270+static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi)16531271{16541654- /*16551655- * We reserve one page for the palette, plus the size16561656- * of the framebuffer.16571657- */16581658- fbi->video_offset = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));16591659- fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + fbi->video_offset);16601660- fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,16611661- &fbi->map_dma, GFP_KERNEL);12721272+ int size = PAGE_ALIGN(fbi->video_mem_size);1662127316631663- if (fbi->map_cpu) {16641664- /* prevent initial garbage on screen */16651665- memset(fbi->map_cpu, 0, fbi->map_size);16661666- fbi->fb.screen_base = fbi->map_cpu + fbi->video_offset;16671667- fbi->screen_dma = fbi->map_dma + fbi->video_offset;12741274+ fbi->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);12751275+ if (fbi->video_mem == NULL)12761276+ return -ENOMEM;1668127716691669- /*16701670- * FIXME: this is actually the wrong thing to place in16711671- * smem_start. But fbdev suffers from the problem that16721672- * it needs an API which doesn't exist (in this case,16731673- * dma_writecombine_mmap)16741674- */16751675- fbi->fb.fix.smem_start = fbi->screen_dma;16761676- fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;12781278+ fbi->video_mem_phys = virt_to_phys(fbi->video_mem);12791279+ fbi->video_mem_size = size;1677128016781678- fbi->dma_buff = (void *) fbi->map_cpu;16791679- fbi->dma_buff_phys = fbi->map_dma;16801680- fbi->palette_cpu = (u16 *) fbi->dma_buff->palette;12811281+ fbi->fb.fix.smem_start = fbi->video_mem_phys;12821282+ fbi->fb.fix.smem_len = fbi->video_mem_size;12831283+ fbi->fb.screen_base = fbi->video_mem;1681128416821682- pr_debug("pxafb: palette_mem_size = 0x%08x\n", fbi->palette_size*sizeof(u16));16831683- }16841684-16851685- return fbi->map_cpu ? 0 : -ENOMEM;16861686-}16871687-16881688-static void pxafb_decode_mode_info(struct pxafb_info *fbi,16891689- struct pxafb_mode_info *modes,16901690- unsigned int num_modes)16911691-{16921692- unsigned int i, smemlen;16931693-16941694- pxafb_setmode(&fbi->fb.var, &modes[0]);16951695-16961696- for (i = 0; i < num_modes; i++) {16971697- smemlen = modes[i].xres * modes[i].yres * modes[i].bpp / 8;16981698- if (smemlen > fbi->fb.fix.smem_len)16991699- fbi->fb.fix.smem_len = smemlen;17001700- }12851285+ return fbi->video_mem ? 0 : -ENOMEM;17011286}1702128717031288static void pxafb_decode_mach_info(struct pxafb_info *fbi,17041289 struct pxafb_mach_info *inf)17051290{17061291 unsigned int lcd_conn = inf->lcd_conn;12921292+ struct pxafb_mode_info *m;12931293+ int i;1707129417081295 fbi->cmap_inverse = inf->cmap_inverse;17091296 fbi->cmap_static = inf->cmap_static;12971297+ fbi->lccr4 = inf->lccr4;1710129817111299 switch (lcd_conn & LCD_TYPE_MASK) {17121300 case LCD_TYPE_MONO_STN:···16931357 /* fall back to backward compatibility way */16941358 fbi->lccr0 = inf->lccr0;16951359 fbi->lccr3 = inf->lccr3;16961696- fbi->lccr4 = inf->lccr4;16971360 goto decode_mode;16981361 }16991362···17061371 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0;1707137217081373decode_mode:17091709- pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);13741374+ pxafb_setmode(&fbi->fb.var, &inf->modes[0]);13751375+13761376+ /* decide video memory size as follows:13771377+ * 1. default to mode of maximum resolution13781378+ * 2. allow platform to override13791379+ * 3. allow module parameter to override13801380+ */13811381+ for (i = 0, m = &inf->modes[0]; i < inf->num_modes; i++, m++)13821382+ fbi->video_mem_size = max_t(size_t, fbi->video_mem_size,13831383+ m->xres * m->yres * m->bpp / 8);13841384+13851385+ if (inf->video_mem_size > fbi->video_mem_size)13861386+ fbi->video_mem_size = inf->video_mem_size;13871387+13881388+ if (video_mem_size > fbi->video_mem_size)13891389+ fbi->video_mem_size = video_mem_size;17101390}1711139117121392static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)···17491399 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;17501400 fbi->fb.fix.type_aux = 0;17511401 fbi->fb.fix.xpanstep = 0;17521752- fbi->fb.fix.ypanstep = 0;14021402+ fbi->fb.fix.ypanstep = 1;17531403 fbi->fb.fix.ywrapstep = 0;17541404 fbi->fb.fix.accel = FB_ACCEL_NONE;17551405···17571407 fbi->fb.var.activate = FB_ACTIVATE_NOW;17581408 fbi->fb.var.height = -1;17591409 fbi->fb.var.width = -1;17601760- fbi->fb.var.accel_flags = 0;14101410+ fbi->fb.var.accel_flags = FB_ACCELF_TEXT;17611411 fbi->fb.var.vmode = FB_VMODE_NONINTERLACED;1762141217631413 fbi->fb.fbops = &pxafb_ops;···1849149918501500 s[0] = '\0';1851150118521852- if (!strncmp(this_opt, "mode:", 5)) {15021502+ if (!strncmp(this_opt, "vmem:", 5)) {15031503+ video_mem_size = memparse(this_opt + 5, NULL);15041504+ } else if (!strncmp(this_opt, "mode:", 5)) {18531505 return parse_opt_mode(dev, this_opt);18541506 } else if (!strncmp(this_opt, "pixclock:", 9)) {18551507 mode->pixclock = simple_strtoul(this_opt+9, NULL, 0);···20881736 goto failed_free_res;20891737 }2090173820912091- /* Initialize video memory */20922092- ret = pxafb_map_video_memory(fbi);17391739+ fbi->dma_buff_size = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));17401740+ fbi->dma_buff = dma_alloc_coherent(fbi->dev, fbi->dma_buff_size,17411741+ &fbi->dma_buff_phys, GFP_KERNEL);17421742+ if (fbi->dma_buff == NULL) {17431743+ dev_err(&dev->dev, "failed to allocate memory for DMA\n");17441744+ ret = -ENOMEM;17451745+ goto failed_free_io;17461746+ }17471747+17481748+ ret = pxafb_init_video_memory(fbi);20931749 if (ret) {20941750 dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret);20951751 ret = -ENOMEM;20962096- goto failed_free_io;17521752+ goto failed_free_dma;20971753 }2098175420991755 irq = platform_get_irq(dev, 0);···21491789 goto failed_free_cmap;21501790 }2151179117921792+ pxafb_overlay_init(fbi);17931793+21521794#ifdef CONFIG_CPU_FREQ21531795 fbi->freq_transition.notifier_call = pxafb_freq_transition;21541796 fbi->freq_policy.notifier_call = pxafb_freq_policy;···21731811failed_free_irq:21741812 free_irq(irq, fbi);21751813failed_free_mem:21762176- dma_free_writecombine(&dev->dev, fbi->map_size,21772177- fbi->map_cpu, fbi->map_dma);18141814+ free_pages_exact(fbi->video_mem, fbi->video_mem_size);18151815+failed_free_dma:18161816+ dma_free_coherent(&dev->dev, fbi->dma_buff_size,18171817+ fbi->dma_buff, fbi->dma_buff_phys);21781818failed_free_io:21791819 iounmap(fbi->mmio_base);21801820failed_free_res:···2201183722021838 info = &fbi->fb;2203183918401840+ pxafb_overlay_exit(fbi);22041841 unregister_framebuffer(info);2205184222061843 pxafb_disable_controller(fbi);···22121847 irq = platform_get_irq(dev, 0);22131848 free_irq(irq, fbi);2214184922152215- dma_free_writecombine(&dev->dev, fbi->map_size,22162216- fbi->map_cpu, fbi->map_dma);18501850+ free_pages_exact(fbi->video_mem, fbi->video_mem_size);18511851+18521852+ dma_free_writecombine(&dev->dev, fbi->dma_buff_size,18531853+ fbi->dma_buff, fbi->dma_buff_phys);2217185422181855 iounmap(fbi->mmio_base);22191856
+61-16
drivers/video/pxafb.h
···5454#define PALETTE_SIZE (256 * 4)5555#define CMD_BUFF_SIZE (1024 * 50)56565757+/* NOTE: the palette and frame dma descriptors are doubled to allow5858+ * the 2nd set for branch settings (FBRx)5959+ */5760struct pxafb_dma_buff {5861 unsigned char palette[PAL_MAX * PALETTE_SIZE];5962 uint16_t cmd_buff[CMD_BUFF_SIZE];6060- struct pxafb_dma_descriptor pal_desc[PAL_MAX];6161- struct pxafb_dma_descriptor dma_desc[DMA_MAX];6363+ struct pxafb_dma_descriptor pal_desc[PAL_MAX * 2];6464+ struct pxafb_dma_descriptor dma_desc[DMA_MAX * 2];6565+};6666+6767+enum {6868+ OVERLAY1,6969+ OVERLAY2,7070+};7171+7272+enum {7373+ OVERLAY_FORMAT_RGB = 0,7474+ OVERLAY_FORMAT_YUV444_PACKED,7575+ OVERLAY_FORMAT_YUV444_PLANAR,7676+ OVERLAY_FORMAT_YUV422_PLANAR,7777+ OVERLAY_FORMAT_YUV420_PLANAR,7878+};7979+8080+#define NONSTD_TO_XPOS(x) (((x) >> 0) & 0x3ff)8181+#define NONSTD_TO_YPOS(x) (((x) >> 10) & 0x3ff)8282+#define NONSTD_TO_PFOR(x) (((x) >> 20) & 0x7)8383+8484+struct pxafb_layer;8585+8686+struct pxafb_layer_ops {8787+ void (*enable)(struct pxafb_layer *);8888+ void (*disable)(struct pxafb_layer *);8989+ void (*setup)(struct pxafb_layer *);9090+};9191+9292+struct pxafb_layer {9393+ struct fb_info fb;9494+ int id;9595+ atomic_t usage;9696+ uint32_t control[2];9797+9898+ struct pxafb_layer_ops *ops;9999+100100+ void __iomem *video_mem;101101+ unsigned long video_mem_phys;102102+ size_t video_mem_size;103103+ struct completion branch_done;104104+105105+ struct pxafb_info *fbi;62106};6310764108struct pxafb_info {···11369 void __iomem *mmio_base;1147011571 struct pxafb_dma_buff *dma_buff;7272+ size_t dma_buff_size;11673 dma_addr_t dma_buff_phys;117117- dma_addr_t fdadr[DMA_MAX];7474+ dma_addr_t fdadr[DMA_MAX * 2];11875119119- /*120120- * These are the addresses we mapped121121- * the framebuffer memory region to.122122- */123123- /* raw memory addresses */124124- dma_addr_t map_dma; /* physical */125125- u_char * map_cpu; /* virtual */126126- u_int map_size;127127-128128- /* addresses of pieces placed in raw buffer */129129- u_char * screen_cpu; /* virtual address of frame buffer */130130- dma_addr_t screen_dma; /* physical address of frame buffer */7676+ void __iomem *video_mem; /* virtual address of frame buffer */7777+ unsigned long video_mem_phys; /* physical address of frame buffer */7878+ size_t video_mem_size; /* size of the frame buffer */13179 u16 * palette_cpu; /* virtual address of palette memory */13280 u_int palette_size;133133- ssize_t video_offset;1348113582 u_int lccr0;13683 u_int lccr3;···155120 struct task_struct *smart_thread;156121#endif157122123123+#ifdef CONFIG_FB_PXA_OVERLAY124124+ struct pxafb_layer overlay[2];125125+#endif126126+158127#ifdef CONFIG_CPU_FREQ159128 struct notifier_block freq_transition;160129 struct notifier_block freq_policy;···189150 */190151#define MIN_XRES 64191152#define MIN_YRES 64153153+154154+/* maximum X and Y resolutions - note these are limits from the register155155+ * bits length instead of the real ones156156+ */157157+#define MAX_XRES 1024158158+#define MAX_YRES 1024192159193160#endif /* __PXAFB_H__ */
+6-5
drivers/watchdog/sa1100_wdt.c
···3636#include <mach/reset.h>3737#include <mach/hardware.h>38383939-#define OSCR_FREQ CLOCK_TICK_RATE4040-3939+static unsigned long oscr_freq;4140static unsigned long sa1100wdt_users;4241static int pre_margin;4342static int boot_status;···123124 break;124125 }125126126126- pre_margin = OSCR_FREQ * time;127127+ pre_margin = oscr_freq * time;127128 OSMR3 = OSCR + pre_margin;128129 /*fall through*/129130130131 case WDIOC_GETTIMEOUT:131131- ret = put_user(pre_margin / OSCR_FREQ, p);132132+ ret = put_user(pre_margin / oscr_freq, p);132133 break;133134 }134135 return ret;···155156{156157 int ret;157158159159+ oscr_freq = get_clock_tick_rate();160160+158161 /*159162 * Read the reset status, and save it for later. If160163 * we suspend, RCSR will be cleared, and the watchdog···164163 */165164 boot_status = (reset_status & RESET_STATUS_WATCHDOG) ?166165 WDIOF_CARDRESET : 0;167167- pre_margin = OSCR_FREQ * margin;166166+ pre_margin = oscr_freq * margin;168167169168 ret = misc_register(&sa1100dog_miscdev);170169 if (ret == 0)