[PATCH] au1200fb: Remove accidentally duplicated content of au1200fb.c

Content of file au1200fb.c was duplicated. Remove.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Ralf Baechle and committed by Linus Torvalds 991cef7b 4661e3ea

-1922
-1922
drivers/video/au1200fb.c
··· 1920 1921 MODULE_DESCRIPTION(DRIVER_DESC); 1922 MODULE_LICENSE("GPL"); 1923 - /* 1924 - * BRIEF MODULE DESCRIPTION 1925 - * Au1200 LCD Driver. 1926 - * 1927 - * Copyright 2004-2005 AMD 1928 - * Author: AMD 1929 - * 1930 - * Based on: 1931 - * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device 1932 - * Created 28 Dec 1997 by Geert Uytterhoeven 1933 - * 1934 - * This program is free software; you can redistribute it and/or modify it 1935 - * under the terms of the GNU General Public License as published by the 1936 - * Free Software Foundation; either version 2 of the License, or (at your 1937 - * option) any later version. 1938 - * 1939 - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 1940 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1941 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 1942 - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1943 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1944 - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 1945 - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 1946 - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1947 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1948 - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1949 - * 1950 - * You should have received a copy of the GNU General Public License along 1951 - * with this program; if not, write to the Free Software Foundation, Inc., 1952 - * 675 Mass Ave, Cambridge, MA 02139, USA. 1953 - */ 1954 - 1955 - #include <linux/module.h> 1956 - #include <linux/platform_device.h> 1957 - #include <linux/kernel.h> 1958 - #include <linux/errno.h> 1959 - #include <linux/string.h> 1960 - #include <linux/mm.h> 1961 - #include <linux/fb.h> 1962 - #include <linux/init.h> 1963 - #include <linux/interrupt.h> 1964 - #include <linux/ctype.h> 1965 - #include <linux/dma-mapping.h> 1966 - 1967 - #include <asm/mach-au1x00/au1000.h> 1968 - #include "au1200fb.h" 1969 - 1970 - #ifdef CONFIG_PM 1971 - #include <asm/mach-au1x00/au1xxx_pm.h> 1972 - #endif 1973 - 1974 - #ifndef CONFIG_FB_AU1200_DEVS 1975 - #define CONFIG_FB_AU1200_DEVS 4 1976 - #endif 1977 - 1978 - #define DRIVER_NAME "au1200fb" 1979 - #define DRIVER_DESC "LCD controller driver for AU1200 processors" 1980 - 1981 - #define DEBUG 1 1982 - 1983 - #define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg) 1984 - #define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg) 1985 - #define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg) 1986 - 1987 - #if DEBUG 1988 - #define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg) 1989 - #else 1990 - #define print_dbg(f, arg...) do {} while (0) 1991 - #endif 1992 - 1993 - 1994 - #define AU1200_LCD_FB_IOCTL 0x46FF 1995 - 1996 - #define AU1200_LCD_SET_SCREEN 1 1997 - #define AU1200_LCD_GET_SCREEN 2 1998 - #define AU1200_LCD_SET_WINDOW 3 1999 - #define AU1200_LCD_GET_WINDOW 4 2000 - #define AU1200_LCD_SET_PANEL 5 2001 - #define AU1200_LCD_GET_PANEL 6 2002 - 2003 - #define SCREEN_SIZE (1<< 1) 2004 - #define SCREEN_BACKCOLOR (1<< 2) 2005 - #define SCREEN_BRIGHTNESS (1<< 3) 2006 - #define SCREEN_COLORKEY (1<< 4) 2007 - #define SCREEN_MASK (1<< 5) 2008 - 2009 - struct au1200_lcd_global_regs_t { 2010 - unsigned int flags; 2011 - unsigned int xsize; 2012 - unsigned int ysize; 2013 - unsigned int backcolor; 2014 - unsigned int brightness; 2015 - unsigned int colorkey; 2016 - unsigned int mask; 2017 - unsigned int panel_choice; 2018 - char panel_desc[80]; 2019 - 2020 - }; 2021 - 2022 - #define WIN_POSITION (1<< 0) 2023 - #define WIN_ALPHA_COLOR (1<< 1) 2024 - #define WIN_ALPHA_MODE (1<< 2) 2025 - #define WIN_PRIORITY (1<< 3) 2026 - #define WIN_CHANNEL (1<< 4) 2027 - #define WIN_BUFFER_FORMAT (1<< 5) 2028 - #define WIN_COLOR_ORDER (1<< 6) 2029 - #define WIN_PIXEL_ORDER (1<< 7) 2030 - #define WIN_SIZE (1<< 8) 2031 - #define WIN_COLORKEY_MODE (1<< 9) 2032 - #define WIN_DOUBLE_BUFFER_MODE (1<< 10) 2033 - #define WIN_RAM_ARRAY_MODE (1<< 11) 2034 - #define WIN_BUFFER_SCALE (1<< 12) 2035 - #define WIN_ENABLE (1<< 13) 2036 - 2037 - struct au1200_lcd_window_regs_t { 2038 - unsigned int flags; 2039 - unsigned int xpos; 2040 - unsigned int ypos; 2041 - unsigned int alpha_color; 2042 - unsigned int alpha_mode; 2043 - unsigned int priority; 2044 - unsigned int channel; 2045 - unsigned int buffer_format; 2046 - unsigned int color_order; 2047 - unsigned int pixel_order; 2048 - unsigned int xsize; 2049 - unsigned int ysize; 2050 - unsigned int colorkey_mode; 2051 - unsigned int double_buffer_mode; 2052 - unsigned int ram_array_mode; 2053 - unsigned int xscale; 2054 - unsigned int yscale; 2055 - unsigned int enable; 2056 - }; 2057 - 2058 - 2059 - struct au1200_lcd_iodata_t { 2060 - unsigned int subcmd; 2061 - struct au1200_lcd_global_regs_t global; 2062 - struct au1200_lcd_window_regs_t window; 2063 - }; 2064 - 2065 - #if defined(__BIG_ENDIAN) 2066 - #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11 2067 - #else 2068 - #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00 2069 - #endif 2070 - #define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565 2071 - 2072 - /* Private, per-framebuffer management information (independent of the panel itself) */ 2073 - struct au1200fb_device { 2074 - struct fb_info fb_info; /* FB driver info record */ 2075 - 2076 - int plane; 2077 - unsigned char* fb_mem; /* FrameBuffer memory map */ 2078 - unsigned int fb_len; 2079 - dma_addr_t fb_phys; 2080 - }; 2081 - 2082 - static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS]; 2083 - /********************************************************************/ 2084 - 2085 - /* LCD controller restrictions */ 2086 - #define AU1200_LCD_MAX_XRES 1280 2087 - #define AU1200_LCD_MAX_YRES 1024 2088 - #define AU1200_LCD_MAX_BPP 32 2089 - #define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */ 2090 - #define AU1200_LCD_NBR_PALETTE_ENTRIES 256 2091 - 2092 - /* Default number of visible screen buffer to allocate */ 2093 - #define AU1200FB_NBR_VIDEO_BUFFERS 1 2094 - 2095 - /********************************************************************/ 2096 - 2097 - static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR; 2098 - static int window_index = 2; /* default is zero */ 2099 - static int panel_index = 2; /* default is zero */ 2100 - static struct window_settings *win; 2101 - static struct panel_settings *panel; 2102 - static int noblanking = 1; 2103 - static int nohwcursor = 0; 2104 - 2105 - struct window_settings { 2106 - unsigned char name[64]; 2107 - uint32 mode_backcolor; 2108 - uint32 mode_colorkey; 2109 - uint32 mode_colorkeymsk; 2110 - struct { 2111 - int xres; 2112 - int yres; 2113 - int xpos; 2114 - int ypos; 2115 - uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */ 2116 - uint32 mode_winenable; 2117 - } w[4]; 2118 - }; 2119 - 2120 - #if defined(__BIG_ENDIAN) 2121 - #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00 2122 - #else 2123 - #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01 2124 - #endif 2125 - 2126 - extern int board_au1200fb_panel_init (void); 2127 - extern int board_au1200fb_panel_shutdown (void); 2128 - 2129 - #ifdef CONFIG_PM 2130 - int au1200fb_pm_callback(au1xxx_power_dev_t *dev, 2131 - au1xxx_request_t request, void *data); 2132 - au1xxx_power_dev_t *LCD_pm_dev; 2133 - #endif 2134 - 2135 - /* 2136 - * Default window configurations 2137 - */ 2138 - static struct window_settings windows[] = { 2139 - { /* Index 0 */ 2140 - "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", 2141 - /* mode_backcolor */ 0x006600ff, 2142 - /* mode_colorkey,msk*/ 0, 0, 2143 - { 2144 - { 2145 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2146 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2147 - LCD_WINCTRL1_PO_16BPP, 2148 - /* mode_winenable*/ LCD_WINENABLE_WEN0, 2149 - }, 2150 - { 2151 - /* xres, yres, xpos, ypos */ 100, 100, 100, 100, 2152 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2153 - LCD_WINCTRL1_PO_16BPP | 2154 - LCD_WINCTRL1_PIPE, 2155 - /* mode_winenable*/ LCD_WINENABLE_WEN1, 2156 - }, 2157 - { 2158 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2159 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2160 - LCD_WINCTRL1_PO_16BPP, 2161 - /* mode_winenable*/ 0, 2162 - }, 2163 - { 2164 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2165 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2166 - LCD_WINCTRL1_PO_16BPP | 2167 - LCD_WINCTRL1_PIPE, 2168 - /* mode_winenable*/ 0, 2169 - }, 2170 - }, 2171 - }, 2172 - 2173 - { /* Index 1 */ 2174 - "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", 2175 - /* mode_backcolor */ 0x006600ff, 2176 - /* mode_colorkey,msk*/ 0, 0, 2177 - { 2178 - { 2179 - /* xres, yres, xpos, ypos */ 320, 240, 5, 5, 2180 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP | 2181 - LCD_WINCTRL1_PO_00, 2182 - /* mode_winenable*/ LCD_WINENABLE_WEN0, 2183 - }, 2184 - { 2185 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2186 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 2187 - | LCD_WINCTRL1_PO_16BPP, 2188 - /* mode_winenable*/ 0, 2189 - }, 2190 - { 2191 - /* xres, yres, xpos, ypos */ 100, 100, 0, 0, 2192 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2193 - LCD_WINCTRL1_PO_16BPP | 2194 - LCD_WINCTRL1_PIPE, 2195 - /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, 2196 - }, 2197 - { 2198 - /* xres, yres, xpos, ypos */ 200, 25, 0, 0, 2199 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2200 - LCD_WINCTRL1_PO_16BPP | 2201 - LCD_WINCTRL1_PIPE, 2202 - /* mode_winenable*/ 0, 2203 - }, 2204 - }, 2205 - }, 2206 - { /* Index 2 */ 2207 - "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", 2208 - /* mode_backcolor */ 0x006600ff, 2209 - /* mode_colorkey,msk*/ 0, 0, 2210 - { 2211 - { 2212 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2213 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2214 - LCD_WINCTRL1_PO_16BPP, 2215 - /* mode_winenable*/ LCD_WINENABLE_WEN0, 2216 - }, 2217 - { 2218 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2219 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2220 - LCD_WINCTRL1_PO_16BPP, 2221 - /* mode_winenable*/ 0, 2222 - }, 2223 - { 2224 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2225 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP | 2226 - LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE, 2227 - /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, 2228 - }, 2229 - { 2230 - /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 2231 - /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 2232 - LCD_WINCTRL1_PO_16BPP | 2233 - LCD_WINCTRL1_PIPE, 2234 - /* mode_winenable*/ 0, 2235 - }, 2236 - }, 2237 - }, 2238 - /* Need VGA 640 @ 24bpp, @ 32bpp */ 2239 - /* Need VGA 800 @ 24bpp, @ 32bpp */ 2240 - /* Need VGA 1024 @ 24bpp, @ 32bpp */ 2241 - }; 2242 - 2243 - /* 2244 - * Controller configurations for various panels. 2245 - */ 2246 - 2247 - struct panel_settings 2248 - { 2249 - const char name[25]; /* Full name <vendor>_<model> */ 2250 - 2251 - struct fb_monspecs monspecs; /* FB monitor specs */ 2252 - 2253 - /* panel timings */ 2254 - uint32 mode_screen; 2255 - uint32 mode_horztiming; 2256 - uint32 mode_verttiming; 2257 - uint32 mode_clkcontrol; 2258 - uint32 mode_pwmdiv; 2259 - uint32 mode_pwmhi; 2260 - uint32 mode_outmask; 2261 - uint32 mode_fifoctrl; 2262 - uint32 mode_toyclksrc; 2263 - uint32 mode_backlight; 2264 - uint32 mode_auxpll; 2265 - int (*device_init)(void); 2266 - int (*device_shutdown)(void); 2267 - #define Xres min_xres 2268 - #define Yres min_yres 2269 - u32 min_xres; /* Minimum horizontal resolution */ 2270 - u32 max_xres; /* Maximum horizontal resolution */ 2271 - u32 min_yres; /* Minimum vertical resolution */ 2272 - u32 max_yres; /* Maximum vertical resolution */ 2273 - }; 2274 - 2275 - /********************************************************************/ 2276 - /* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */ 2277 - 2278 - /* List of panels known to work with the AU1200 LCD controller. 2279 - * To add a new panel, enter the same specifications as the 2280 - * Generic_TFT one, and MAKE SURE that it doesn't conflicts 2281 - * with the controller restrictions. Restrictions are: 2282 - * 2283 - * STN color panels: max_bpp <= 12 2284 - * STN mono panels: max_bpp <= 4 2285 - * TFT panels: max_bpp <= 16 2286 - * max_xres <= 800 2287 - * max_yres <= 600 2288 - */ 2289 - static struct panel_settings known_lcd_panels[] = 2290 - { 2291 - [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */ 2292 - .name = "QVGA_320x240", 2293 - .monspecs = { 2294 - .modedb = NULL, 2295 - .modedb_len = 0, 2296 - .hfmin = 30000, 2297 - .hfmax = 70000, 2298 - .vfmin = 60, 2299 - .vfmax = 60, 2300 - .dclkmin = 6000000, 2301 - .dclkmax = 28000000, 2302 - .input = FB_DISP_RGB, 2303 - }, 2304 - .mode_screen = LCD_SCREEN_SX_N(320) | 2305 - LCD_SCREEN_SY_N(240), 2306 - .mode_horztiming = 0x00c4623b, 2307 - .mode_verttiming = 0x00502814, 2308 - .mode_clkcontrol = 0x00020002, /* /4=24Mhz */ 2309 - .mode_pwmdiv = 0x00000000, 2310 - .mode_pwmhi = 0x00000000, 2311 - .mode_outmask = 0x00FFFFFF, 2312 - .mode_fifoctrl = 0x2f2f2f2f, 2313 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2314 - .mode_backlight = 0x00000000, 2315 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2316 - .device_init = NULL, 2317 - .device_shutdown = NULL, 2318 - 320, 320, 2319 - 240, 240, 2320 - }, 2321 - 2322 - [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */ 2323 - .name = "VGA_640x480", 2324 - .monspecs = { 2325 - .modedb = NULL, 2326 - .modedb_len = 0, 2327 - .hfmin = 30000, 2328 - .hfmax = 70000, 2329 - .vfmin = 60, 2330 - .vfmax = 60, 2331 - .dclkmin = 6000000, 2332 - .dclkmax = 28000000, 2333 - .input = FB_DISP_RGB, 2334 - }, 2335 - .mode_screen = 0x13f9df80, 2336 - .mode_horztiming = 0x003c5859, 2337 - .mode_verttiming = 0x00741201, 2338 - .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ 2339 - .mode_pwmdiv = 0x00000000, 2340 - .mode_pwmhi = 0x00000000, 2341 - .mode_outmask = 0x00FFFFFF, 2342 - .mode_fifoctrl = 0x2f2f2f2f, 2343 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2344 - .mode_backlight = 0x00000000, 2345 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2346 - .device_init = NULL, 2347 - .device_shutdown = NULL, 2348 - 640, 480, 2349 - 640, 480, 2350 - }, 2351 - 2352 - [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */ 2353 - .name = "SVGA_800x600", 2354 - .monspecs = { 2355 - .modedb = NULL, 2356 - .modedb_len = 0, 2357 - .hfmin = 30000, 2358 - .hfmax = 70000, 2359 - .vfmin = 60, 2360 - .vfmax = 60, 2361 - .dclkmin = 6000000, 2362 - .dclkmax = 28000000, 2363 - .input = FB_DISP_RGB, 2364 - }, 2365 - .mode_screen = 0x18fa5780, 2366 - .mode_horztiming = 0x00dc7e77, 2367 - .mode_verttiming = 0x00584805, 2368 - .mode_clkcontrol = 0x00020000, /* /2=48Mhz */ 2369 - .mode_pwmdiv = 0x00000000, 2370 - .mode_pwmhi = 0x00000000, 2371 - .mode_outmask = 0x00FFFFFF, 2372 - .mode_fifoctrl = 0x2f2f2f2f, 2373 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2374 - .mode_backlight = 0x00000000, 2375 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2376 - .device_init = NULL, 2377 - .device_shutdown = NULL, 2378 - 800, 800, 2379 - 600, 600, 2380 - }, 2381 - 2382 - [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */ 2383 - .name = "XVGA_1024x768", 2384 - .monspecs = { 2385 - .modedb = NULL, 2386 - .modedb_len = 0, 2387 - .hfmin = 30000, 2388 - .hfmax = 70000, 2389 - .vfmin = 60, 2390 - .vfmax = 60, 2391 - .dclkmin = 6000000, 2392 - .dclkmax = 28000000, 2393 - .input = FB_DISP_RGB, 2394 - }, 2395 - .mode_screen = 0x1ffaff80, 2396 - .mode_horztiming = 0x007d0e57, 2397 - .mode_verttiming = 0x00740a01, 2398 - .mode_clkcontrol = 0x000A0000, /* /1 */ 2399 - .mode_pwmdiv = 0x00000000, 2400 - .mode_pwmhi = 0x00000000, 2401 - .mode_outmask = 0x00FFFFFF, 2402 - .mode_fifoctrl = 0x2f2f2f2f, 2403 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2404 - .mode_backlight = 0x00000000, 2405 - .mode_auxpll = 6, /* 72MHz AUXPLL */ 2406 - .device_init = NULL, 2407 - .device_shutdown = NULL, 2408 - 1024, 1024, 2409 - 768, 768, 2410 - }, 2411 - 2412 - [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */ 2413 - .name = "XVGA_1280x1024", 2414 - .monspecs = { 2415 - .modedb = NULL, 2416 - .modedb_len = 0, 2417 - .hfmin = 30000, 2418 - .hfmax = 70000, 2419 - .vfmin = 60, 2420 - .vfmax = 60, 2421 - .dclkmin = 6000000, 2422 - .dclkmax = 28000000, 2423 - .input = FB_DISP_RGB, 2424 - }, 2425 - .mode_screen = 0x27fbff80, 2426 - .mode_horztiming = 0x00cdb2c7, 2427 - .mode_verttiming = 0x00600002, 2428 - .mode_clkcontrol = 0x000A0000, /* /1 */ 2429 - .mode_pwmdiv = 0x00000000, 2430 - .mode_pwmhi = 0x00000000, 2431 - .mode_outmask = 0x00FFFFFF, 2432 - .mode_fifoctrl = 0x2f2f2f2f, 2433 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2434 - .mode_backlight = 0x00000000, 2435 - .mode_auxpll = 10, /* 120MHz AUXPLL */ 2436 - .device_init = NULL, 2437 - .device_shutdown = NULL, 2438 - 1280, 1280, 2439 - 1024, 1024, 2440 - }, 2441 - 2442 - [5] = { /* Samsung 1024x768 TFT */ 2443 - .name = "Samsung_1024x768_TFT", 2444 - .monspecs = { 2445 - .modedb = NULL, 2446 - .modedb_len = 0, 2447 - .hfmin = 30000, 2448 - .hfmax = 70000, 2449 - .vfmin = 60, 2450 - .vfmax = 60, 2451 - .dclkmin = 6000000, 2452 - .dclkmax = 28000000, 2453 - .input = FB_DISP_RGB, 2454 - }, 2455 - .mode_screen = 0x1ffaff80, 2456 - .mode_horztiming = 0x018cc677, 2457 - .mode_verttiming = 0x00241217, 2458 - .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */ 2459 - .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */ 2460 - .mode_pwmhi = 0x03400000, /* SCB 0x0 */ 2461 - .mode_outmask = 0x00FFFFFF, 2462 - .mode_fifoctrl = 0x2f2f2f2f, 2463 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2464 - .mode_backlight = 0x00000000, 2465 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2466 - .device_init = board_au1200fb_panel_init, 2467 - .device_shutdown = board_au1200fb_panel_shutdown, 2468 - 1024, 1024, 2469 - 768, 768, 2470 - }, 2471 - 2472 - [6] = { /* Toshiba 640x480 TFT */ 2473 - .name = "Toshiba_640x480_TFT", 2474 - .monspecs = { 2475 - .modedb = NULL, 2476 - .modedb_len = 0, 2477 - .hfmin = 30000, 2478 - .hfmax = 70000, 2479 - .vfmin = 60, 2480 - .vfmax = 60, 2481 - .dclkmin = 6000000, 2482 - .dclkmax = 28000000, 2483 - .input = FB_DISP_RGB, 2484 - }, 2485 - .mode_screen = LCD_SCREEN_SX_N(640) | 2486 - LCD_SCREEN_SY_N(480), 2487 - .mode_horztiming = LCD_HORZTIMING_HPW_N(96) | 2488 - LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51), 2489 - .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | 2490 - LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32), 2491 - .mode_clkcontrol = 0x00000000, /* /4=24Mhz */ 2492 - .mode_pwmdiv = 0x8000063f, 2493 - .mode_pwmhi = 0x03400000, 2494 - .mode_outmask = 0x00fcfcfc, 2495 - .mode_fifoctrl = 0x2f2f2f2f, 2496 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2497 - .mode_backlight = 0x00000000, 2498 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2499 - .device_init = board_au1200fb_panel_init, 2500 - .device_shutdown = board_au1200fb_panel_shutdown, 2501 - 640, 480, 2502 - 640, 480, 2503 - }, 2504 - 2505 - [7] = { /* Sharp 320x240 TFT */ 2506 - .name = "Sharp_320x240_TFT", 2507 - .monspecs = { 2508 - .modedb = NULL, 2509 - .modedb_len = 0, 2510 - .hfmin = 12500, 2511 - .hfmax = 20000, 2512 - .vfmin = 38, 2513 - .vfmax = 81, 2514 - .dclkmin = 4500000, 2515 - .dclkmax = 6800000, 2516 - .input = FB_DISP_RGB, 2517 - }, 2518 - .mode_screen = LCD_SCREEN_SX_N(320) | 2519 - LCD_SCREEN_SY_N(240), 2520 - .mode_horztiming = LCD_HORZTIMING_HPW_N(60) | 2521 - LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2), 2522 - .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | 2523 - LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5), 2524 - .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/ 2525 - .mode_pwmdiv = 0x8000063f, 2526 - .mode_pwmhi = 0x03400000, 2527 - .mode_outmask = 0x00fcfcfc, 2528 - .mode_fifoctrl = 0x2f2f2f2f, 2529 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2530 - .mode_backlight = 0x00000000, 2531 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2532 - .device_init = board_au1200fb_panel_init, 2533 - .device_shutdown = board_au1200fb_panel_shutdown, 2534 - 320, 320, 2535 - 240, 240, 2536 - }, 2537 - 2538 - [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */ 2539 - .name = "Toppoly_TD070WGCB2", 2540 - .monspecs = { 2541 - .modedb = NULL, 2542 - .modedb_len = 0, 2543 - .hfmin = 30000, 2544 - .hfmax = 70000, 2545 - .vfmin = 60, 2546 - .vfmax = 60, 2547 - .dclkmin = 6000000, 2548 - .dclkmax = 28000000, 2549 - .input = FB_DISP_RGB, 2550 - }, 2551 - .mode_screen = LCD_SCREEN_SX_N(856) | 2552 - LCD_SCREEN_SY_N(480), 2553 - .mode_horztiming = LCD_HORZTIMING_HND2_N(43) | 2554 - LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114), 2555 - .mode_verttiming = LCD_VERTTIMING_VND2_N(20) | 2556 - LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4), 2557 - .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ 2558 - .mode_pwmdiv = 0x8000063f, 2559 - .mode_pwmhi = 0x03400000, 2560 - .mode_outmask = 0x00fcfcfc, 2561 - .mode_fifoctrl = 0x2f2f2f2f, 2562 - .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 2563 - .mode_backlight = 0x00000000, 2564 - .mode_auxpll = 8, /* 96MHz AUXPLL */ 2565 - .device_init = board_au1200fb_panel_init, 2566 - .device_shutdown = board_au1200fb_panel_shutdown, 2567 - 856, 856, 2568 - 480, 480, 2569 - }, 2570 - }; 2571 - 2572 - #define NUM_PANELS (ARRAY_SIZE(known_lcd_panels)) 2573 - 2574 - /********************************************************************/ 2575 - 2576 - #ifdef CONFIG_PM 2577 - static int set_brightness(unsigned int brightness) 2578 - { 2579 - unsigned int hi1, divider; 2580 - 2581 - /* limit brightness pwm duty to >= 30/1600 */ 2582 - if (brightness < 30) { 2583 - brightness = 30; 2584 - } 2585 - divider = (lcd->pwmdiv & 0x3FFFF) + 1; 2586 - hi1 = (lcd->pwmhi >> 16) + 1; 2587 - hi1 = (((brightness & 0xFF) + 1) * divider >> 8); 2588 - lcd->pwmhi &= 0xFFFF; 2589 - lcd->pwmhi |= (hi1 << 16); 2590 - 2591 - return brightness; 2592 - } 2593 - #endif /* CONFIG_PM */ 2594 - 2595 - static int winbpp (unsigned int winctrl1) 2596 - { 2597 - int bits = 0; 2598 - 2599 - /* how many bits are needed for each pixel format */ 2600 - switch (winctrl1 & LCD_WINCTRL1_FRM) { 2601 - case LCD_WINCTRL1_FRM_1BPP: 2602 - bits = 1; 2603 - break; 2604 - case LCD_WINCTRL1_FRM_2BPP: 2605 - bits = 2; 2606 - break; 2607 - case LCD_WINCTRL1_FRM_4BPP: 2608 - bits = 4; 2609 - break; 2610 - case LCD_WINCTRL1_FRM_8BPP: 2611 - bits = 8; 2612 - break; 2613 - case LCD_WINCTRL1_FRM_12BPP: 2614 - case LCD_WINCTRL1_FRM_16BPP655: 2615 - case LCD_WINCTRL1_FRM_16BPP565: 2616 - case LCD_WINCTRL1_FRM_16BPP556: 2617 - case LCD_WINCTRL1_FRM_16BPPI1555: 2618 - case LCD_WINCTRL1_FRM_16BPPI5551: 2619 - case LCD_WINCTRL1_FRM_16BPPA1555: 2620 - case LCD_WINCTRL1_FRM_16BPPA5551: 2621 - bits = 16; 2622 - break; 2623 - case LCD_WINCTRL1_FRM_24BPP: 2624 - case LCD_WINCTRL1_FRM_32BPP: 2625 - bits = 32; 2626 - break; 2627 - } 2628 - 2629 - return bits; 2630 - } 2631 - 2632 - static int fbinfo2index (struct fb_info *fb_info) 2633 - { 2634 - int i; 2635 - 2636 - for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { 2637 - if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info)) 2638 - return i; 2639 - } 2640 - printk("au1200fb: ERROR: fbinfo2index failed!\n"); 2641 - return -1; 2642 - } 2643 - 2644 - static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, 2645 - int xpos, int ypos) 2646 - { 2647 - uint32 winctrl0, winctrl1, winenable, fb_offset = 0; 2648 - int xsz, ysz; 2649 - 2650 - /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */ 2651 - 2652 - winctrl0 = lcd->window[plane].winctrl0; 2653 - winctrl1 = lcd->window[plane].winctrl1; 2654 - winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN); 2655 - winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY); 2656 - 2657 - /* Check for off-screen adjustments */ 2658 - xsz = win->w[plane].xres; 2659 - ysz = win->w[plane].yres; 2660 - if ((xpos + win->w[plane].xres) > panel->Xres) { 2661 - /* Off-screen to the right */ 2662 - xsz = panel->Xres - xpos; /* off by 1 ??? */ 2663 - /*printk("off screen right\n");*/ 2664 - } 2665 - 2666 - if ((ypos + win->w[plane].yres) > panel->Yres) { 2667 - /* Off-screen to the bottom */ 2668 - ysz = panel->Yres - ypos; /* off by 1 ??? */ 2669 - /*printk("off screen bottom\n");*/ 2670 - } 2671 - 2672 - if (xpos < 0) { 2673 - /* Off-screen to the left */ 2674 - xsz = win->w[plane].xres + xpos; 2675 - fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8); 2676 - xpos = 0; 2677 - /*printk("off screen left\n");*/ 2678 - } 2679 - 2680 - if (ypos < 0) { 2681 - /* Off-screen to the top */ 2682 - ysz = win->w[plane].yres + ypos; 2683 - /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */ 2684 - ypos = 0; 2685 - /*printk("off screen top\n");*/ 2686 - } 2687 - 2688 - /* record settings */ 2689 - win->w[plane].xpos = xpos; 2690 - win->w[plane].ypos = ypos; 2691 - 2692 - xsz -= 1; 2693 - ysz -= 1; 2694 - winctrl0 |= (xpos << 21); 2695 - winctrl0 |= (ypos << 10); 2696 - winctrl1 |= (xsz << 11); 2697 - winctrl1 |= (ysz << 0); 2698 - 2699 - /* Disable the window while making changes, then restore WINEN */ 2700 - winenable = lcd->winenable & (1 << plane); 2701 - au_sync(); 2702 - lcd->winenable &= ~(1 << plane); 2703 - lcd->window[plane].winctrl0 = winctrl0; 2704 - lcd->window[plane].winctrl1 = winctrl1; 2705 - lcd->window[plane].winbuf0 = 2706 - lcd->window[plane].winbuf1 = fbdev->fb_phys; 2707 - lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ 2708 - lcd->winenable |= winenable; 2709 - au_sync(); 2710 - 2711 - return 0; 2712 - } 2713 - 2714 - static void au1200_setpanel (struct panel_settings *newpanel) 2715 - { 2716 - /* 2717 - * Perform global setup/init of LCD controller 2718 - */ 2719 - uint32 winenable; 2720 - 2721 - /* Make sure all windows disabled */ 2722 - winenable = lcd->winenable; 2723 - lcd->winenable = 0; 2724 - au_sync(); 2725 - /* 2726 - * Ensure everything is disabled before reconfiguring 2727 - */ 2728 - if (lcd->screen & LCD_SCREEN_SEN) { 2729 - /* Wait for vertical sync period */ 2730 - lcd->intstatus = LCD_INT_SS; 2731 - while ((lcd->intstatus & LCD_INT_SS) == 0) { 2732 - au_sync(); 2733 - } 2734 - 2735 - lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ 2736 - 2737 - do { 2738 - lcd->intstatus = lcd->intstatus; /*clear interrupts*/ 2739 - au_sync(); 2740 - /*wait for controller to shut down*/ 2741 - } while ((lcd->intstatus & LCD_INT_SD) == 0); 2742 - 2743 - /* Call shutdown of current panel (if up) */ 2744 - /* this must occur last, because if an external clock is driving 2745 - the controller, the clock cannot be turned off before first 2746 - shutting down the controller. 2747 - */ 2748 - if (panel->device_shutdown != NULL) 2749 - panel->device_shutdown(); 2750 - } 2751 - 2752 - /* Newpanel == NULL indicates a shutdown operation only */ 2753 - if (newpanel == NULL) 2754 - return; 2755 - 2756 - panel = newpanel; 2757 - 2758 - printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres); 2759 - 2760 - /* 2761 - * Setup clocking if internal LCD clock source (assumes sys_auxpll valid) 2762 - */ 2763 - if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) 2764 - { 2765 - uint32 sys_clksrc; 2766 - au_writel(panel->mode_auxpll, SYS_AUXPLL); 2767 - sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; 2768 - sys_clksrc |= panel->mode_toyclksrc; 2769 - au_writel(sys_clksrc, SYS_CLKSRC); 2770 - } 2771 - 2772 - /* 2773 - * Configure panel timings 2774 - */ 2775 - lcd->screen = panel->mode_screen; 2776 - lcd->horztiming = panel->mode_horztiming; 2777 - lcd->verttiming = panel->mode_verttiming; 2778 - lcd->clkcontrol = panel->mode_clkcontrol; 2779 - lcd->pwmdiv = panel->mode_pwmdiv; 2780 - lcd->pwmhi = panel->mode_pwmhi; 2781 - lcd->outmask = panel->mode_outmask; 2782 - lcd->fifoctrl = panel->mode_fifoctrl; 2783 - au_sync(); 2784 - 2785 - /* fixme: Check window settings to make sure still valid 2786 - * for new geometry */ 2787 - #if 0 2788 - au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos); 2789 - au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos); 2790 - au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos); 2791 - au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos); 2792 - #endif 2793 - lcd->winenable = winenable; 2794 - 2795 - /* 2796 - * Re-enable screen now that it is configured 2797 - */ 2798 - lcd->screen |= LCD_SCREEN_SEN; 2799 - au_sync(); 2800 - 2801 - /* Call init of panel */ 2802 - if (panel->device_init != NULL) panel->device_init(); 2803 - 2804 - /* FIX!!!! not appropriate on panel change!!! Global setup/init */ 2805 - lcd->intenable = 0; 2806 - lcd->intstatus = ~0; 2807 - lcd->backcolor = win->mode_backcolor; 2808 - 2809 - /* Setup Color Key - FIX!!! */ 2810 - lcd->colorkey = win->mode_colorkey; 2811 - lcd->colorkeymsk = win->mode_colorkeymsk; 2812 - 2813 - /* Setup HWCursor - FIX!!! Need to support this eventually */ 2814 - lcd->hwc.cursorctrl = 0; 2815 - lcd->hwc.cursorpos = 0; 2816 - lcd->hwc.cursorcolor0 = 0; 2817 - lcd->hwc.cursorcolor1 = 0; 2818 - lcd->hwc.cursorcolor2 = 0; 2819 - lcd->hwc.cursorcolor3 = 0; 2820 - 2821 - 2822 - #if 0 2823 - #define D(X) printk("%25s: %08X\n", #X, X) 2824 - D(lcd->screen); 2825 - D(lcd->horztiming); 2826 - D(lcd->verttiming); 2827 - D(lcd->clkcontrol); 2828 - D(lcd->pwmdiv); 2829 - D(lcd->pwmhi); 2830 - D(lcd->outmask); 2831 - D(lcd->fifoctrl); 2832 - D(lcd->window[0].winctrl0); 2833 - D(lcd->window[0].winctrl1); 2834 - D(lcd->window[0].winctrl2); 2835 - D(lcd->window[0].winbuf0); 2836 - D(lcd->window[0].winbuf1); 2837 - D(lcd->window[0].winbufctrl); 2838 - D(lcd->window[1].winctrl0); 2839 - D(lcd->window[1].winctrl1); 2840 - D(lcd->window[1].winctrl2); 2841 - D(lcd->window[1].winbuf0); 2842 - D(lcd->window[1].winbuf1); 2843 - D(lcd->window[1].winbufctrl); 2844 - D(lcd->window[2].winctrl0); 2845 - D(lcd->window[2].winctrl1); 2846 - D(lcd->window[2].winctrl2); 2847 - D(lcd->window[2].winbuf0); 2848 - D(lcd->window[2].winbuf1); 2849 - D(lcd->window[2].winbufctrl); 2850 - D(lcd->window[3].winctrl0); 2851 - D(lcd->window[3].winctrl1); 2852 - D(lcd->window[3].winctrl2); 2853 - D(lcd->window[3].winbuf0); 2854 - D(lcd->window[3].winbuf1); 2855 - D(lcd->window[3].winbufctrl); 2856 - D(lcd->winenable); 2857 - D(lcd->intenable); 2858 - D(lcd->intstatus); 2859 - D(lcd->backcolor); 2860 - D(lcd->winenable); 2861 - D(lcd->colorkey); 2862 - D(lcd->colorkeymsk); 2863 - D(lcd->hwc.cursorctrl); 2864 - D(lcd->hwc.cursorpos); 2865 - D(lcd->hwc.cursorcolor0); 2866 - D(lcd->hwc.cursorcolor1); 2867 - D(lcd->hwc.cursorcolor2); 2868 - D(lcd->hwc.cursorcolor3); 2869 - #endif 2870 - } 2871 - 2872 - static void au1200_setmode(struct au1200fb_device *fbdev) 2873 - { 2874 - int plane = fbdev->plane; 2875 - /* Window/plane setup */ 2876 - lcd->window[plane].winctrl1 = ( 0 2877 - | LCD_WINCTRL1_PRI_N(plane) 2878 - | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */ 2879 - ) ; 2880 - 2881 - au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos); 2882 - 2883 - lcd->window[plane].winctrl2 = ( 0 2884 - | LCD_WINCTRL2_CKMODE_00 2885 - | LCD_WINCTRL2_DBM 2886 - | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length) 2887 - | LCD_WINCTRL2_SCX_1 2888 - | LCD_WINCTRL2_SCY_1 2889 - ) ; 2890 - lcd->winenable |= win->w[plane].mode_winenable; 2891 - au_sync(); 2892 - } 2893 - 2894 - 2895 - /* Inline helpers */ 2896 - 2897 - /*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/ 2898 - /*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/ 2899 - 2900 - #define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN) 2901 - 2902 - /* Bitfields format supported by the controller. */ 2903 - static struct fb_bitfield rgb_bitfields[][4] = { 2904 - /* Red, Green, Blue, Transp */ 2905 - [LCD_WINCTRL1_FRM_16BPP655 >> 25] = 2906 - { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, 2907 - 2908 - [LCD_WINCTRL1_FRM_16BPP565 >> 25] = 2909 - { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, 2910 - 2911 - [LCD_WINCTRL1_FRM_16BPP556 >> 25] = 2912 - { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } }, 2913 - 2914 - [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] = 2915 - { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, 2916 - 2917 - [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] = 2918 - { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } }, 2919 - 2920 - [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] = 2921 - { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } }, 2922 - 2923 - [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] = 2924 - { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } }, 2925 - 2926 - [LCD_WINCTRL1_FRM_24BPP >> 25] = 2927 - { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } }, 2928 - 2929 - [LCD_WINCTRL1_FRM_32BPP >> 25] = 2930 - { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } }, 2931 - }; 2932 - 2933 - /*-------------------------------------------------------------------------*/ 2934 - 2935 - /* Helpers */ 2936 - 2937 - static void au1200fb_update_fbinfo(struct fb_info *fbi) 2938 - { 2939 - /* FIX!!!! This also needs to take the window pixel format into account!!! */ 2940 - 2941 - /* Update var-dependent FB info */ 2942 - if (panel_is_color(panel)) { 2943 - if (fbi->var.bits_per_pixel <= 8) { 2944 - /* palettized */ 2945 - fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR; 2946 - fbi->fix.line_length = fbi->var.xres_virtual / 2947 - (8/fbi->var.bits_per_pixel); 2948 - } else { 2949 - /* non-palettized */ 2950 - fbi->fix.visual = FB_VISUAL_TRUECOLOR; 2951 - fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8); 2952 - } 2953 - } else { 2954 - /* mono FIX!!! mono 8 and 4 bits */ 2955 - fbi->fix.visual = FB_VISUAL_MONO10; 2956 - fbi->fix.line_length = fbi->var.xres_virtual / 8; 2957 - } 2958 - 2959 - fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual; 2960 - print_dbg("line length: %d\n", fbi->fix.line_length); 2961 - print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel); 2962 - } 2963 - 2964 - /*-------------------------------------------------------------------------*/ 2965 - 2966 - /* AU1200 framebuffer driver */ 2967 - 2968 - /* fb_check_var 2969 - * Validate var settings with hardware restrictions and modify it if necessary 2970 - */ 2971 - static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, 2972 - struct fb_info *fbi) 2973 - { 2974 - struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; 2975 - u32 pixclock; 2976 - int screen_size, plane; 2977 - 2978 - plane = fbdev->plane; 2979 - 2980 - /* Make sure that the mode respect all LCD controller and 2981 - * panel restrictions. */ 2982 - var->xres = win->w[plane].xres; 2983 - var->yres = win->w[plane].yres; 2984 - 2985 - /* No need for virtual resolution support */ 2986 - var->xres_virtual = var->xres; 2987 - var->yres_virtual = var->yres; 2988 - 2989 - var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1); 2990 - 2991 - screen_size = var->xres_virtual * var->yres_virtual; 2992 - if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8); 2993 - else screen_size /= (8/var->bits_per_pixel); 2994 - 2995 - if (fbdev->fb_len < screen_size) 2996 - return -EINVAL; /* Virtual screen is to big, abort */ 2997 - 2998 - /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */ 2999 - /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel 3000 - * clock can only be obtain by dividing this value by an even integer. 3001 - * Fallback to a slower pixel clock if necessary. */ 3002 - pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin); 3003 - pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2)); 3004 - 3005 - if (AU1200_LCD_MAX_CLK % pixclock) { 3006 - int diff = AU1200_LCD_MAX_CLK % pixclock; 3007 - pixclock -= diff; 3008 - } 3009 - 3010 - var->pixclock = KHZ2PICOS(pixclock/1000); 3011 - #if 0 3012 - if (!panel_is_active(panel)) { 3013 - int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1; 3014 - 3015 - if (!panel_is_color(panel) 3016 - && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) { 3017 - /* STN 8bit mono panel support is up to 6MHz pixclock */ 3018 - var->pixclock = KHZ2PICOS(6000); 3019 - } else if (!pcd) { 3020 - /* Other STN panel support is up to 12MHz */ 3021 - var->pixclock = KHZ2PICOS(12000); 3022 - } 3023 - } 3024 - #endif 3025 - /* Set bitfield accordingly */ 3026 - switch (var->bits_per_pixel) { 3027 - case 16: 3028 - { 3029 - /* 16bpp True color. 3030 - * These must be set to MATCH WINCTRL[FORM] */ 3031 - int idx; 3032 - idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25; 3033 - var->red = rgb_bitfields[idx][0]; 3034 - var->green = rgb_bitfields[idx][1]; 3035 - var->blue = rgb_bitfields[idx][2]; 3036 - var->transp = rgb_bitfields[idx][3]; 3037 - break; 3038 - } 3039 - 3040 - case 32: 3041 - { 3042 - /* 32bpp True color. 3043 - * These must be set to MATCH WINCTRL[FORM] */ 3044 - int idx; 3045 - idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25; 3046 - var->red = rgb_bitfields[idx][0]; 3047 - var->green = rgb_bitfields[idx][1]; 3048 - var->blue = rgb_bitfields[idx][2]; 3049 - var->transp = rgb_bitfields[idx][3]; 3050 - break; 3051 - } 3052 - default: 3053 - print_dbg("Unsupported depth %dbpp", var->bits_per_pixel); 3054 - return -EINVAL; 3055 - } 3056 - 3057 - return 0; 3058 - } 3059 - 3060 - /* fb_set_par 3061 - * Set hardware with var settings. This will enable the controller with a 3062 - * specific mode, normally validated with the fb_check_var method 3063 - */ 3064 - static int au1200fb_fb_set_par(struct fb_info *fbi) 3065 - { 3066 - struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; 3067 - 3068 - au1200fb_update_fbinfo(fbi); 3069 - au1200_setmode(fbdev); 3070 - 3071 - return 0; 3072 - } 3073 - 3074 - /* fb_setcolreg 3075 - * Set color in LCD palette. 3076 - */ 3077 - static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, 3078 - unsigned blue, unsigned transp, struct fb_info *fbi) 3079 - { 3080 - volatile u32 *palette = lcd->palette; 3081 - u32 value; 3082 - 3083 - if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1)) 3084 - return -EINVAL; 3085 - 3086 - if (fbi->var.grayscale) { 3087 - /* Convert color to grayscale */ 3088 - red = green = blue = 3089 - (19595 * red + 38470 * green + 7471 * blue) >> 16; 3090 - } 3091 - 3092 - if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) { 3093 - /* Place color in the pseudopalette */ 3094 - if (regno > 16) 3095 - return -EINVAL; 3096 - 3097 - palette = (u32*) fbi->pseudo_palette; 3098 - 3099 - red >>= (16 - fbi->var.red.length); 3100 - green >>= (16 - fbi->var.green.length); 3101 - blue >>= (16 - fbi->var.blue.length); 3102 - 3103 - value = (red << fbi->var.red.offset) | 3104 - (green << fbi->var.green.offset)| 3105 - (blue << fbi->var.blue.offset); 3106 - value &= 0xFFFF; 3107 - 3108 - } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) { 3109 - /* COLOR TFT PALLETTIZED (use RGB 565) */ 3110 - value = (red & 0xF800)|((green >> 5) & 3111 - 0x07E0)|((blue >> 11) & 0x001F); 3112 - value &= 0xFFFF; 3113 - 3114 - } else if (0 /*panel_is_color(fbdev->panel)*/) { 3115 - /* COLOR STN MODE */ 3116 - value = 0x1234; 3117 - value &= 0xFFF; 3118 - } else { 3119 - /* MONOCHROME MODE */ 3120 - value = (green >> 12) & 0x000F; 3121 - value &= 0xF; 3122 - } 3123 - 3124 - palette[regno] = value; 3125 - 3126 - return 0; 3127 - } 3128 - 3129 - /* fb_blank 3130 - * Blank the screen. Depending on the mode, the screen will be 3131 - * activated with the backlight color, or desactivated 3132 - */ 3133 - static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) 3134 - { 3135 - /* Short-circuit screen blanking */ 3136 - if (noblanking) 3137 - return 0; 3138 - 3139 - switch (blank_mode) { 3140 - 3141 - case FB_BLANK_UNBLANK: 3142 - case FB_BLANK_NORMAL: 3143 - /* printk("turn on panel\n"); */ 3144 - au1200_setpanel(panel); 3145 - break; 3146 - case FB_BLANK_VSYNC_SUSPEND: 3147 - case FB_BLANK_HSYNC_SUSPEND: 3148 - case FB_BLANK_POWERDOWN: 3149 - /* printk("turn off panel\n"); */ 3150 - au1200_setpanel(NULL); 3151 - break; 3152 - default: 3153 - break; 3154 - 3155 - } 3156 - 3157 - /* FB_BLANK_NORMAL is a soft blank */ 3158 - return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0; 3159 - } 3160 - 3161 - /* fb_mmap 3162 - * Map video memory in user space. We don't use the generic fb_mmap 3163 - * method mainly to allow the use of the TLB streaming flag (CCA=6) 3164 - */ 3165 - static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 3166 - 3167 - { 3168 - unsigned int len; 3169 - unsigned long start=0, off; 3170 - struct au1200fb_device *fbdev = (struct au1200fb_device *) info; 3171 - 3172 - #ifdef CONFIG_PM 3173 - au1xxx_pm_access(LCD_pm_dev); 3174 - #endif 3175 - 3176 - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { 3177 - return -EINVAL; 3178 - } 3179 - 3180 - start = fbdev->fb_phys & PAGE_MASK; 3181 - len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); 3182 - 3183 - off = vma->vm_pgoff << PAGE_SHIFT; 3184 - 3185 - if ((vma->vm_end - vma->vm_start + off) > len) { 3186 - return -EINVAL; 3187 - } 3188 - 3189 - off += start; 3190 - vma->vm_pgoff = off >> PAGE_SHIFT; 3191 - 3192 - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 3193 - pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ 3194 - 3195 - vma->vm_flags |= VM_IO; 3196 - 3197 - return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 3198 - vma->vm_end - vma->vm_start, 3199 - vma->vm_page_prot); 3200 - 3201 - return 0; 3202 - } 3203 - 3204 - static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) 3205 - { 3206 - 3207 - unsigned int hi1, divider; 3208 - 3209 - /* SCREEN_SIZE: user cannot reset size, must switch panel choice */ 3210 - 3211 - if (pdata->flags & SCREEN_BACKCOLOR) 3212 - lcd->backcolor = pdata->backcolor; 3213 - 3214 - if (pdata->flags & SCREEN_BRIGHTNESS) { 3215 - 3216 - // limit brightness pwm duty to >= 30/1600 3217 - if (pdata->brightness < 30) { 3218 - pdata->brightness = 30; 3219 - } 3220 - divider = (lcd->pwmdiv & 0x3FFFF) + 1; 3221 - hi1 = (lcd->pwmhi >> 16) + 1; 3222 - hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8); 3223 - lcd->pwmhi &= 0xFFFF; 3224 - lcd->pwmhi |= (hi1 << 16); 3225 - } 3226 - 3227 - if (pdata->flags & SCREEN_COLORKEY) 3228 - lcd->colorkey = pdata->colorkey; 3229 - 3230 - if (pdata->flags & SCREEN_MASK) 3231 - lcd->colorkeymsk = pdata->mask; 3232 - au_sync(); 3233 - } 3234 - 3235 - static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) 3236 - { 3237 - unsigned int hi1, divider; 3238 - 3239 - pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1; 3240 - pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1; 3241 - 3242 - pdata->backcolor = lcd->backcolor; 3243 - pdata->colorkey = lcd->colorkey; 3244 - pdata->mask = lcd->colorkeymsk; 3245 - 3246 - // brightness 3247 - hi1 = (lcd->pwmhi >> 16) + 1; 3248 - divider = (lcd->pwmdiv & 0x3FFFF) + 1; 3249 - pdata->brightness = ((hi1 << 8) / divider) - 1; 3250 - au_sync(); 3251 - } 3252 - 3253 - static void set_window(unsigned int plane, 3254 - struct au1200_lcd_window_regs_t *pdata) 3255 - { 3256 - unsigned int val, bpp; 3257 - 3258 - /* Window control register 0 */ 3259 - if (pdata->flags & WIN_POSITION) { 3260 - val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX | 3261 - LCD_WINCTRL0_OY); 3262 - val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX); 3263 - val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY); 3264 - lcd->window[plane].winctrl0 = val; 3265 - } 3266 - if (pdata->flags & WIN_ALPHA_COLOR) { 3267 - val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A); 3268 - val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A); 3269 - lcd->window[plane].winctrl0 = val; 3270 - } 3271 - if (pdata->flags & WIN_ALPHA_MODE) { 3272 - val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN); 3273 - val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN); 3274 - lcd->window[plane].winctrl0 = val; 3275 - } 3276 - 3277 - /* Window control register 1 */ 3278 - if (pdata->flags & WIN_PRIORITY) { 3279 - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI); 3280 - val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI); 3281 - lcd->window[plane].winctrl1 = val; 3282 - } 3283 - if (pdata->flags & WIN_CHANNEL) { 3284 - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE); 3285 - val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE); 3286 - lcd->window[plane].winctrl1 = val; 3287 - } 3288 - if (pdata->flags & WIN_BUFFER_FORMAT) { 3289 - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM); 3290 - val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM); 3291 - lcd->window[plane].winctrl1 = val; 3292 - } 3293 - if (pdata->flags & WIN_COLOR_ORDER) { 3294 - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO); 3295 - val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO); 3296 - lcd->window[plane].winctrl1 = val; 3297 - } 3298 - if (pdata->flags & WIN_PIXEL_ORDER) { 3299 - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO); 3300 - val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO); 3301 - lcd->window[plane].winctrl1 = val; 3302 - } 3303 - if (pdata->flags & WIN_SIZE) { 3304 - val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX | 3305 - LCD_WINCTRL1_SZY); 3306 - val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX); 3307 - val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY); 3308 - lcd->window[plane].winctrl1 = val; 3309 - /* program buffer line width */ 3310 - bpp = winbpp(val) / 8; 3311 - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX); 3312 - val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX); 3313 - lcd->window[plane].winctrl2 = val; 3314 - } 3315 - 3316 - /* Window control register 2 */ 3317 - if (pdata->flags & WIN_COLORKEY_MODE) { 3318 - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE); 3319 - val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE); 3320 - lcd->window[plane].winctrl2 = val; 3321 - } 3322 - if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) { 3323 - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM); 3324 - val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM); 3325 - lcd->window[plane].winctrl2 = val; 3326 - } 3327 - if (pdata->flags & WIN_RAM_ARRAY_MODE) { 3328 - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM); 3329 - val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM); 3330 - lcd->window[plane].winctrl2 = val; 3331 - } 3332 - 3333 - /* Buffer line width programmed with WIN_SIZE */ 3334 - 3335 - if (pdata->flags & WIN_BUFFER_SCALE) { 3336 - val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX | 3337 - LCD_WINCTRL2_SCY); 3338 - val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX); 3339 - val |= ((pdata->ysize) & LCD_WINCTRL2_SCY); 3340 - lcd->window[plane].winctrl2 = val; 3341 - } 3342 - 3343 - if (pdata->flags & WIN_ENABLE) { 3344 - val = lcd->winenable; 3345 - val &= ~(1<<plane); 3346 - val |= (pdata->enable & 1) << plane; 3347 - lcd->winenable = val; 3348 - } 3349 - au_sync(); 3350 - } 3351 - 3352 - static void get_window(unsigned int plane, 3353 - struct au1200_lcd_window_regs_t *pdata) 3354 - { 3355 - /* Window control register 0 */ 3356 - pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21; 3357 - pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10; 3358 - pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2; 3359 - pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1; 3360 - 3361 - /* Window control register 1 */ 3362 - pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30; 3363 - pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29; 3364 - pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25; 3365 - pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24; 3366 - pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22; 3367 - pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1; 3368 - pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1; 3369 - 3370 - /* Window control register 2 */ 3371 - pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24; 3372 - pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23; 3373 - pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; 3374 - 3375 - pdata->enable = (lcd->winenable >> plane) & 1; 3376 - au_sync(); 3377 - } 3378 - 3379 - static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, 3380 - unsigned long arg) 3381 - { 3382 - int plane; 3383 - int val; 3384 - 3385 - #ifdef CONFIG_PM 3386 - au1xxx_pm_access(LCD_pm_dev); 3387 - #endif 3388 - 3389 - plane = fbinfo2index(info); 3390 - print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane); 3391 - 3392 - if (cmd == AU1200_LCD_FB_IOCTL) { 3393 - struct au1200_lcd_iodata_t iodata; 3394 - 3395 - if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata))) 3396 - return -EFAULT; 3397 - 3398 - print_dbg("FB IOCTL called\n"); 3399 - 3400 - switch (iodata.subcmd) { 3401 - case AU1200_LCD_SET_SCREEN: 3402 - print_dbg("AU1200_LCD_SET_SCREEN\n"); 3403 - set_global(cmd, &iodata.global); 3404 - break; 3405 - 3406 - case AU1200_LCD_GET_SCREEN: 3407 - print_dbg("AU1200_LCD_GET_SCREEN\n"); 3408 - get_global(cmd, &iodata.global); 3409 - break; 3410 - 3411 - case AU1200_LCD_SET_WINDOW: 3412 - print_dbg("AU1200_LCD_SET_WINDOW\n"); 3413 - set_window(plane, &iodata.window); 3414 - break; 3415 - 3416 - case AU1200_LCD_GET_WINDOW: 3417 - print_dbg("AU1200_LCD_GET_WINDOW\n"); 3418 - get_window(plane, &iodata.window); 3419 - break; 3420 - 3421 - case AU1200_LCD_SET_PANEL: 3422 - print_dbg("AU1200_LCD_SET_PANEL\n"); 3423 - if ((iodata.global.panel_choice >= 0) && 3424 - (iodata.global.panel_choice < 3425 - NUM_PANELS)) 3426 - { 3427 - struct panel_settings *newpanel; 3428 - panel_index = iodata.global.panel_choice; 3429 - newpanel = &known_lcd_panels[panel_index]; 3430 - au1200_setpanel(newpanel); 3431 - } 3432 - break; 3433 - 3434 - case AU1200_LCD_GET_PANEL: 3435 - print_dbg("AU1200_LCD_GET_PANEL\n"); 3436 - iodata.global.panel_choice = panel_index; 3437 - break; 3438 - 3439 - default: 3440 - return -EINVAL; 3441 - } 3442 - 3443 - val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata)); 3444 - if (val) { 3445 - print_dbg("error: could not copy %d bytes\n", val); 3446 - return -EFAULT; 3447 - } 3448 - } 3449 - 3450 - return 0; 3451 - } 3452 - 3453 - 3454 - static struct fb_ops au1200fb_fb_ops = { 3455 - .owner = THIS_MODULE, 3456 - .fb_check_var = au1200fb_fb_check_var, 3457 - .fb_set_par = au1200fb_fb_set_par, 3458 - .fb_setcolreg = au1200fb_fb_setcolreg, 3459 - .fb_blank = au1200fb_fb_blank, 3460 - .fb_fillrect = cfb_fillrect, 3461 - .fb_copyarea = cfb_copyarea, 3462 - .fb_imageblit = cfb_imageblit, 3463 - .fb_sync = NULL, 3464 - .fb_ioctl = au1200fb_ioctl, 3465 - .fb_mmap = au1200fb_fb_mmap, 3466 - }; 3467 - 3468 - /*-------------------------------------------------------------------------*/ 3469 - 3470 - static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs) 3471 - { 3472 - /* Nothing to do for now, just clear any pending interrupt */ 3473 - lcd->intstatus = lcd->intstatus; 3474 - au_sync(); 3475 - 3476 - return IRQ_HANDLED; 3477 - } 3478 - 3479 - /*-------------------------------------------------------------------------*/ 3480 - 3481 - /* AU1200 LCD device probe helpers */ 3482 - 3483 - static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) 3484 - { 3485 - struct fb_info *fbi = &fbdev->fb_info; 3486 - int bpp; 3487 - 3488 - memset(fbi, 0, sizeof(struct fb_info)); 3489 - fbi->fbops = &au1200fb_fb_ops; 3490 - 3491 - bpp = winbpp(win->w[fbdev->plane].mode_winctrl1); 3492 - 3493 - /* Copy monitor specs from panel data */ 3494 - /* fixme: we're setting up LCD controller windows, so these dont give a 3495 - damn as to what the monitor specs are (the panel itself does, but that 3496 - isnt done here...so maybe need a generic catchall monitor setting??? */ 3497 - memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs)); 3498 - 3499 - /* We first try the user mode passed in argument. If that failed, 3500 - * or if no one has been specified, we default to the first mode of the 3501 - * panel list. Note that after this call, var data will be set */ 3502 - if (!fb_find_mode(&fbi->var, 3503 - fbi, 3504 - NULL, /* drv_info.opt_mode, */ 3505 - fbi->monspecs.modedb, 3506 - fbi->monspecs.modedb_len, 3507 - fbi->monspecs.modedb, 3508 - bpp)) { 3509 - 3510 - print_err("Cannot find valid mode for panel %s", panel->name); 3511 - return -EFAULT; 3512 - } 3513 - 3514 - fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); 3515 - if (!fbi->pseudo_palette) { 3516 - return -ENOMEM; 3517 - } 3518 - memset(fbi->pseudo_palette, 0, sizeof(u32) * 16); 3519 - 3520 - if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { 3521 - print_err("Fail to allocate colormap (%d entries)", 3522 - AU1200_LCD_NBR_PALETTE_ENTRIES); 3523 - kfree(fbi->pseudo_palette); 3524 - return -EFAULT; 3525 - } 3526 - 3527 - strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id)); 3528 - fbi->fix.smem_start = fbdev->fb_phys; 3529 - fbi->fix.smem_len = fbdev->fb_len; 3530 - fbi->fix.type = FB_TYPE_PACKED_PIXELS; 3531 - fbi->fix.xpanstep = 0; 3532 - fbi->fix.ypanstep = 0; 3533 - fbi->fix.mmio_start = 0; 3534 - fbi->fix.mmio_len = 0; 3535 - fbi->fix.accel = FB_ACCEL_NONE; 3536 - 3537 - fbi->screen_base = (char __iomem *) fbdev->fb_mem; 3538 - 3539 - au1200fb_update_fbinfo(fbi); 3540 - 3541 - return 0; 3542 - } 3543 - 3544 - /*-------------------------------------------------------------------------*/ 3545 - 3546 - /* AU1200 LCD controller device driver */ 3547 - 3548 - static int au1200fb_drv_probe(struct device *dev) 3549 - { 3550 - struct au1200fb_device *fbdev; 3551 - unsigned long page; 3552 - int bpp, plane, ret; 3553 - 3554 - if (!dev) 3555 - return -EINVAL; 3556 - 3557 - for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { 3558 - bpp = winbpp(win->w[plane].mode_winctrl1); 3559 - if (win->w[plane].xres == 0) 3560 - win->w[plane].xres = panel->Xres; 3561 - if (win->w[plane].yres == 0) 3562 - win->w[plane].yres = panel->Yres; 3563 - 3564 - fbdev = &_au1200fb_devices[plane]; 3565 - memset(fbdev, 0, sizeof(struct au1200fb_device)); 3566 - fbdev->plane = plane; 3567 - 3568 - /* Allocate the framebuffer to the maximum screen size */ 3569 - fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; 3570 - 3571 - fbdev->fb_mem = dma_alloc_noncoherent(dev, 3572 - PAGE_ALIGN(fbdev->fb_len), 3573 - &fbdev->fb_phys, GFP_KERNEL); 3574 - if (!fbdev->fb_mem) { 3575 - print_err("fail to allocate frambuffer (size: %dK))", 3576 - fbdev->fb_len / 1024); 3577 - return -ENOMEM; 3578 - } 3579 - 3580 - /* 3581 - * Set page reserved so that mmap will work. This is necessary 3582 - * since we'll be remapping normal memory. 3583 - */ 3584 - for (page = (unsigned long)fbdev->fb_phys; 3585 - page < PAGE_ALIGN((unsigned long)fbdev->fb_phys + 3586 - fbdev->fb_len); 3587 - page += PAGE_SIZE) { 3588 - SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */ 3589 - } 3590 - print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); 3591 - print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); 3592 - 3593 - /* Init FB data */ 3594 - if ((ret = au1200fb_init_fbinfo(fbdev)) < 0) 3595 - goto failed; 3596 - 3597 - /* Register new framebuffer */ 3598 - if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) { 3599 - print_err("cannot register new framebuffer"); 3600 - goto failed; 3601 - } 3602 - 3603 - au1200fb_fb_set_par(&fbdev->fb_info); 3604 - 3605 - #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) 3606 - if (plane == 0) 3607 - if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) { 3608 - /* Start display and show logo on boot */ 3609 - fb_set_cmap(&fbdev->fb_info.cmap, 3610 - &fbdev->fb_info); 3611 - 3612 - fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR); 3613 - } 3614 - #endif 3615 - } 3616 - 3617 - /* Now hook interrupt too */ 3618 - if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq, 3619 - SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) { 3620 - print_err("fail to request interrupt line %d (err: %d)", 3621 - AU1200_LCD_INT, ret); 3622 - goto failed; 3623 - } 3624 - 3625 - return 0; 3626 - 3627 - failed: 3628 - /* NOTE: This only does the current plane/window that failed; others are still active */ 3629 - if (fbdev->fb_mem) 3630 - dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), 3631 - fbdev->fb_mem, fbdev->fb_phys); 3632 - if (fbdev->fb_info.cmap.len != 0) 3633 - fb_dealloc_cmap(&fbdev->fb_info.cmap); 3634 - if (fbdev->fb_info.pseudo_palette) 3635 - kfree(fbdev->fb_info.pseudo_palette); 3636 - if (plane == 0) 3637 - free_irq(AU1200_LCD_INT, (void*)dev); 3638 - return ret; 3639 - } 3640 - 3641 - static int au1200fb_drv_remove(struct device *dev) 3642 - { 3643 - struct au1200fb_device *fbdev; 3644 - int plane; 3645 - 3646 - if (!dev) 3647 - return -ENODEV; 3648 - 3649 - /* Turn off the panel */ 3650 - au1200_setpanel(NULL); 3651 - 3652 - for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) 3653 - { 3654 - fbdev = &_au1200fb_devices[plane]; 3655 - 3656 - /* Clean up all probe data */ 3657 - unregister_framebuffer(&fbdev->fb_info); 3658 - if (fbdev->fb_mem) 3659 - dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), 3660 - fbdev->fb_mem, fbdev->fb_phys); 3661 - if (fbdev->fb_info.cmap.len != 0) 3662 - fb_dealloc_cmap(&fbdev->fb_info.cmap); 3663 - if (fbdev->fb_info.pseudo_palette) 3664 - kfree(fbdev->fb_info.pseudo_palette); 3665 - } 3666 - 3667 - free_irq(AU1200_LCD_INT, (void *)dev); 3668 - 3669 - return 0; 3670 - } 3671 - 3672 - #ifdef CONFIG_PM 3673 - static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level) 3674 - { 3675 - /* TODO */ 3676 - return 0; 3677 - } 3678 - 3679 - static int au1200fb_drv_resume(struct device *dev, u32 level) 3680 - { 3681 - /* TODO */ 3682 - return 0; 3683 - } 3684 - #endif /* CONFIG_PM */ 3685 - 3686 - static struct device_driver au1200fb_driver = { 3687 - .name = "au1200-lcd", 3688 - .bus = &platform_bus_type, 3689 - .probe = au1200fb_drv_probe, 3690 - .remove = au1200fb_drv_remove, 3691 - #ifdef CONFIG_PM 3692 - .suspend = au1200fb_drv_suspend, 3693 - .resume = au1200fb_drv_resume, 3694 - #endif 3695 - }; 3696 - 3697 - /*-------------------------------------------------------------------------*/ 3698 - 3699 - /* Kernel driver */ 3700 - 3701 - static void au1200fb_setup(void) 3702 - { 3703 - char* options = NULL; 3704 - char* this_opt; 3705 - int num_panels = ARRAY_SIZE(known_lcd_panels); 3706 - int panel_idx = -1; 3707 - 3708 - fb_get_options(DRIVER_NAME, &options); 3709 - 3710 - if (options) { 3711 - while ((this_opt = strsep(&options,",")) != NULL) { 3712 - /* Panel option - can be panel name, 3713 - * "bs" for board-switch, or number/index */ 3714 - if (!strncmp(this_opt, "panel:", 6)) { 3715 - int i; 3716 - long int li; 3717 - char *endptr; 3718 - this_opt += 6; 3719 - /* First check for index, which allows 3720 - * to short circuit this mess */ 3721 - li = simple_strtol(this_opt, &endptr, 0); 3722 - if (*endptr == '\0') { 3723 - panel_idx = (int)li; 3724 - } 3725 - else if (strcmp(this_opt, "bs") == 0) { 3726 - extern int board_au1200fb_panel(void); 3727 - panel_idx = board_au1200fb_panel(); 3728 - } 3729 - 3730 - else 3731 - for (i = 0; i < num_panels; i++) { 3732 - if (!strcmp(this_opt, known_lcd_panels[i].name)) { 3733 - panel_idx = i; 3734 - break; 3735 - } 3736 - } 3737 - 3738 - if ((panel_idx < 0) || (panel_idx >= num_panels)) { 3739 - print_warn("Panel %s not supported!", this_opt); 3740 - } 3741 - else 3742 - panel_index = panel_idx; 3743 - } 3744 - 3745 - else if (strncmp(this_opt, "nohwcursor", 10) == 0) { 3746 - nohwcursor = 1; 3747 - } 3748 - 3749 - /* Unsupported option */ 3750 - else { 3751 - print_warn("Unsupported option \"%s\"", this_opt); 3752 - } 3753 - } 3754 - } 3755 - } 3756 - 3757 - #ifdef CONFIG_PM 3758 - static int au1200fb_pm_callback(au1xxx_power_dev_t *dev, 3759 - au1xxx_request_t request, void *data) { 3760 - int retval = -1; 3761 - unsigned int d = 0; 3762 - unsigned int brightness = 0; 3763 - 3764 - if (request == AU1XXX_PM_SLEEP) { 3765 - board_au1200fb_panel_shutdown(); 3766 - } 3767 - else if (request == AU1XXX_PM_WAKEUP) { 3768 - if(dev->prev_state == SLEEP_STATE) 3769 - { 3770 - int plane; 3771 - au1200_setpanel(panel); 3772 - for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { 3773 - struct au1200fb_device *fbdev; 3774 - fbdev = &_au1200fb_devices[plane]; 3775 - au1200fb_fb_set_par(&fbdev->fb_info); 3776 - } 3777 - } 3778 - 3779 - d = *((unsigned int*)data); 3780 - if(d <=10) brightness = 26; 3781 - else if(d<=20) brightness = 51; 3782 - else if(d<=30) brightness = 77; 3783 - else if(d<=40) brightness = 102; 3784 - else if(d<=50) brightness = 128; 3785 - else if(d<=60) brightness = 153; 3786 - else if(d<=70) brightness = 179; 3787 - else if(d<=80) brightness = 204; 3788 - else if(d<=90) brightness = 230; 3789 - else brightness = 255; 3790 - set_brightness(brightness); 3791 - } else if (request == AU1XXX_PM_GETSTATUS) { 3792 - return dev->cur_state; 3793 - } else if (request == AU1XXX_PM_ACCESS) { 3794 - if (dev->cur_state != SLEEP_STATE) 3795 - return retval; 3796 - else { 3797 - au1200_setpanel(panel); 3798 - } 3799 - } else if (request == AU1XXX_PM_IDLE) { 3800 - } else if (request == AU1XXX_PM_CLEANUP) { 3801 - } 3802 - 3803 - return retval; 3804 - } 3805 - #endif 3806 - 3807 - static int __init au1200fb_init(void) 3808 - { 3809 - print_info("" DRIVER_DESC ""); 3810 - 3811 - /* Setup driver with options */ 3812 - au1200fb_setup(); 3813 - 3814 - /* Point to the panel selected */ 3815 - panel = &known_lcd_panels[panel_index]; 3816 - win = &windows[window_index]; 3817 - 3818 - printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); 3819 - printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); 3820 - 3821 - /* Kickstart the panel, the framebuffers/windows come soon enough */ 3822 - au1200_setpanel(panel); 3823 - 3824 - #ifdef CONFIG_PM 3825 - LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL); 3826 - if ( LCD_pm_dev == NULL) 3827 - printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n"); 3828 - else 3829 - printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n"); 3830 - #endif 3831 - 3832 - return driver_register(&au1200fb_driver); 3833 - } 3834 - 3835 - static void __exit au1200fb_cleanup(void) 3836 - { 3837 - driver_unregister(&au1200fb_driver); 3838 - } 3839 - 3840 - module_init(au1200fb_init); 3841 - module_exit(au1200fb_cleanup); 3842 - 3843 - MODULE_DESCRIPTION(DRIVER_DESC); 3844 - MODULE_LICENSE("GPL");
··· 1920 1921 MODULE_DESCRIPTION(DRIVER_DESC); 1922 MODULE_LICENSE("GPL");