Commit 1fca06fafb235a88c4fa91294aa1726c0e22855b

Authored by Al Viro
1 parent a47df1518e

au1200fb: io_remap_pfn_range() sets VM_IO

... and single return is quite sufficient to get out of function, TYVM

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 0 additions and 4 deletions Inline Diff

drivers/video/au1200fb.c
1 /* 1 /*
2 * BRIEF MODULE DESCRIPTION 2 * BRIEF MODULE DESCRIPTION
3 * Au1200 LCD Driver. 3 * Au1200 LCD Driver.
4 * 4 *
5 * Copyright 2004-2005 AMD 5 * Copyright 2004-2005 AMD
6 * Author: AMD 6 * Author: AMD
7 * 7 *
8 * Based on: 8 * Based on:
9 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device 9 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
10 * Created 28 Dec 1997 by Geert Uytterhoeven 10 * Created 28 Dec 1997 by Geert Uytterhoeven
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify it 12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the 13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your 14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. 15 * option) any later version.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * 27 *
28 * You should have received a copy of the GNU General Public License along 28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc., 29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA. 30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */ 31 */
32 32
33 #include <linux/module.h> 33 #include <linux/module.h>
34 #include <linux/platform_device.h> 34 #include <linux/platform_device.h>
35 #include <linux/kernel.h> 35 #include <linux/kernel.h>
36 #include <linux/errno.h> 36 #include <linux/errno.h>
37 #include <linux/string.h> 37 #include <linux/string.h>
38 #include <linux/mm.h> 38 #include <linux/mm.h>
39 #include <linux/fb.h> 39 #include <linux/fb.h>
40 #include <linux/init.h> 40 #include <linux/init.h>
41 #include <linux/interrupt.h> 41 #include <linux/interrupt.h>
42 #include <linux/ctype.h> 42 #include <linux/ctype.h>
43 #include <linux/dma-mapping.h> 43 #include <linux/dma-mapping.h>
44 #include <linux/slab.h> 44 #include <linux/slab.h>
45 45
46 #include <asm/mach-au1x00/au1000.h> 46 #include <asm/mach-au1x00/au1000.h>
47 #include <asm/mach-au1x00/au1200fb.h> /* platform_data */ 47 #include <asm/mach-au1x00/au1200fb.h> /* platform_data */
48 #include "au1200fb.h" 48 #include "au1200fb.h"
49 49
50 #define DRIVER_NAME "au1200fb" 50 #define DRIVER_NAME "au1200fb"
51 #define DRIVER_DESC "LCD controller driver for AU1200 processors" 51 #define DRIVER_DESC "LCD controller driver for AU1200 processors"
52 52
53 #define DEBUG 0 53 #define DEBUG 0
54 54
55 #define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg) 55 #define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
56 #define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg) 56 #define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
57 #define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg) 57 #define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
58 58
59 #if DEBUG 59 #if DEBUG
60 #define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg) 60 #define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
61 #else 61 #else
62 #define print_dbg(f, arg...) do {} while (0) 62 #define print_dbg(f, arg...) do {} while (0)
63 #endif 63 #endif
64 64
65 65
66 #define AU1200_LCD_FB_IOCTL 0x46FF 66 #define AU1200_LCD_FB_IOCTL 0x46FF
67 67
68 #define AU1200_LCD_SET_SCREEN 1 68 #define AU1200_LCD_SET_SCREEN 1
69 #define AU1200_LCD_GET_SCREEN 2 69 #define AU1200_LCD_GET_SCREEN 2
70 #define AU1200_LCD_SET_WINDOW 3 70 #define AU1200_LCD_SET_WINDOW 3
71 #define AU1200_LCD_GET_WINDOW 4 71 #define AU1200_LCD_GET_WINDOW 4
72 #define AU1200_LCD_SET_PANEL 5 72 #define AU1200_LCD_SET_PANEL 5
73 #define AU1200_LCD_GET_PANEL 6 73 #define AU1200_LCD_GET_PANEL 6
74 74
75 #define SCREEN_SIZE (1<< 1) 75 #define SCREEN_SIZE (1<< 1)
76 #define SCREEN_BACKCOLOR (1<< 2) 76 #define SCREEN_BACKCOLOR (1<< 2)
77 #define SCREEN_BRIGHTNESS (1<< 3) 77 #define SCREEN_BRIGHTNESS (1<< 3)
78 #define SCREEN_COLORKEY (1<< 4) 78 #define SCREEN_COLORKEY (1<< 4)
79 #define SCREEN_MASK (1<< 5) 79 #define SCREEN_MASK (1<< 5)
80 80
81 struct au1200_lcd_global_regs_t { 81 struct au1200_lcd_global_regs_t {
82 unsigned int flags; 82 unsigned int flags;
83 unsigned int xsize; 83 unsigned int xsize;
84 unsigned int ysize; 84 unsigned int ysize;
85 unsigned int backcolor; 85 unsigned int backcolor;
86 unsigned int brightness; 86 unsigned int brightness;
87 unsigned int colorkey; 87 unsigned int colorkey;
88 unsigned int mask; 88 unsigned int mask;
89 unsigned int panel_choice; 89 unsigned int panel_choice;
90 char panel_desc[80]; 90 char panel_desc[80];
91 91
92 }; 92 };
93 93
94 #define WIN_POSITION (1<< 0) 94 #define WIN_POSITION (1<< 0)
95 #define WIN_ALPHA_COLOR (1<< 1) 95 #define WIN_ALPHA_COLOR (1<< 1)
96 #define WIN_ALPHA_MODE (1<< 2) 96 #define WIN_ALPHA_MODE (1<< 2)
97 #define WIN_PRIORITY (1<< 3) 97 #define WIN_PRIORITY (1<< 3)
98 #define WIN_CHANNEL (1<< 4) 98 #define WIN_CHANNEL (1<< 4)
99 #define WIN_BUFFER_FORMAT (1<< 5) 99 #define WIN_BUFFER_FORMAT (1<< 5)
100 #define WIN_COLOR_ORDER (1<< 6) 100 #define WIN_COLOR_ORDER (1<< 6)
101 #define WIN_PIXEL_ORDER (1<< 7) 101 #define WIN_PIXEL_ORDER (1<< 7)
102 #define WIN_SIZE (1<< 8) 102 #define WIN_SIZE (1<< 8)
103 #define WIN_COLORKEY_MODE (1<< 9) 103 #define WIN_COLORKEY_MODE (1<< 9)
104 #define WIN_DOUBLE_BUFFER_MODE (1<< 10) 104 #define WIN_DOUBLE_BUFFER_MODE (1<< 10)
105 #define WIN_RAM_ARRAY_MODE (1<< 11) 105 #define WIN_RAM_ARRAY_MODE (1<< 11)
106 #define WIN_BUFFER_SCALE (1<< 12) 106 #define WIN_BUFFER_SCALE (1<< 12)
107 #define WIN_ENABLE (1<< 13) 107 #define WIN_ENABLE (1<< 13)
108 108
109 struct au1200_lcd_window_regs_t { 109 struct au1200_lcd_window_regs_t {
110 unsigned int flags; 110 unsigned int flags;
111 unsigned int xpos; 111 unsigned int xpos;
112 unsigned int ypos; 112 unsigned int ypos;
113 unsigned int alpha_color; 113 unsigned int alpha_color;
114 unsigned int alpha_mode; 114 unsigned int alpha_mode;
115 unsigned int priority; 115 unsigned int priority;
116 unsigned int channel; 116 unsigned int channel;
117 unsigned int buffer_format; 117 unsigned int buffer_format;
118 unsigned int color_order; 118 unsigned int color_order;
119 unsigned int pixel_order; 119 unsigned int pixel_order;
120 unsigned int xsize; 120 unsigned int xsize;
121 unsigned int ysize; 121 unsigned int ysize;
122 unsigned int colorkey_mode; 122 unsigned int colorkey_mode;
123 unsigned int double_buffer_mode; 123 unsigned int double_buffer_mode;
124 unsigned int ram_array_mode; 124 unsigned int ram_array_mode;
125 unsigned int xscale; 125 unsigned int xscale;
126 unsigned int yscale; 126 unsigned int yscale;
127 unsigned int enable; 127 unsigned int enable;
128 }; 128 };
129 129
130 130
131 struct au1200_lcd_iodata_t { 131 struct au1200_lcd_iodata_t {
132 unsigned int subcmd; 132 unsigned int subcmd;
133 struct au1200_lcd_global_regs_t global; 133 struct au1200_lcd_global_regs_t global;
134 struct au1200_lcd_window_regs_t window; 134 struct au1200_lcd_window_regs_t window;
135 }; 135 };
136 136
137 #if defined(__BIG_ENDIAN) 137 #if defined(__BIG_ENDIAN)
138 #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11 138 #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
139 #else 139 #else
140 #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00 140 #define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
141 #endif 141 #endif
142 #define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565 142 #define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
143 143
144 /* Private, per-framebuffer management information (independent of the panel itself) */ 144 /* Private, per-framebuffer management information (independent of the panel itself) */
145 struct au1200fb_device { 145 struct au1200fb_device {
146 struct fb_info *fb_info; /* FB driver info record */ 146 struct fb_info *fb_info; /* FB driver info record */
147 struct au1200fb_platdata *pd; 147 struct au1200fb_platdata *pd;
148 148
149 int plane; 149 int plane;
150 unsigned char* fb_mem; /* FrameBuffer memory map */ 150 unsigned char* fb_mem; /* FrameBuffer memory map */
151 unsigned int fb_len; 151 unsigned int fb_len;
152 dma_addr_t fb_phys; 152 dma_addr_t fb_phys;
153 }; 153 };
154 154
155 /********************************************************************/ 155 /********************************************************************/
156 156
157 /* LCD controller restrictions */ 157 /* LCD controller restrictions */
158 #define AU1200_LCD_MAX_XRES 1280 158 #define AU1200_LCD_MAX_XRES 1280
159 #define AU1200_LCD_MAX_YRES 1024 159 #define AU1200_LCD_MAX_YRES 1024
160 #define AU1200_LCD_MAX_BPP 32 160 #define AU1200_LCD_MAX_BPP 32
161 #define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */ 161 #define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
162 #define AU1200_LCD_NBR_PALETTE_ENTRIES 256 162 #define AU1200_LCD_NBR_PALETTE_ENTRIES 256
163 163
164 /* Default number of visible screen buffer to allocate */ 164 /* Default number of visible screen buffer to allocate */
165 #define AU1200FB_NBR_VIDEO_BUFFERS 1 165 #define AU1200FB_NBR_VIDEO_BUFFERS 1
166 166
167 /* Default maximum number of fb devices to create */ 167 /* Default maximum number of fb devices to create */
168 #define MAX_DEVICE_COUNT 4 168 #define MAX_DEVICE_COUNT 4
169 169
170 /* Default window configuration entry to use (see windows[]) */ 170 /* Default window configuration entry to use (see windows[]) */
171 #define DEFAULT_WINDOW_INDEX 2 171 #define DEFAULT_WINDOW_INDEX 2
172 172
173 /********************************************************************/ 173 /********************************************************************/
174 174
175 static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT]; 175 static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
176 static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR; 176 static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
177 static int device_count = MAX_DEVICE_COUNT; 177 static int device_count = MAX_DEVICE_COUNT;
178 static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */ 178 static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */
179 static int panel_index = 2; /* default is zero */ 179 static int panel_index = 2; /* default is zero */
180 static struct window_settings *win; 180 static struct window_settings *win;
181 static struct panel_settings *panel; 181 static struct panel_settings *panel;
182 static int noblanking = 1; 182 static int noblanking = 1;
183 static int nohwcursor = 0; 183 static int nohwcursor = 0;
184 184
185 struct window_settings { 185 struct window_settings {
186 unsigned char name[64]; 186 unsigned char name[64];
187 uint32 mode_backcolor; 187 uint32 mode_backcolor;
188 uint32 mode_colorkey; 188 uint32 mode_colorkey;
189 uint32 mode_colorkeymsk; 189 uint32 mode_colorkeymsk;
190 struct { 190 struct {
191 int xres; 191 int xres;
192 int yres; 192 int yres;
193 int xpos; 193 int xpos;
194 int ypos; 194 int ypos;
195 uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */ 195 uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
196 uint32 mode_winenable; 196 uint32 mode_winenable;
197 } w[4]; 197 } w[4];
198 }; 198 };
199 199
200 #if defined(__BIG_ENDIAN) 200 #if defined(__BIG_ENDIAN)
201 #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00 201 #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
202 #else 202 #else
203 #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01 203 #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
204 #endif 204 #endif
205 205
206 /* 206 /*
207 * Default window configurations 207 * Default window configurations
208 */ 208 */
209 static struct window_settings windows[] = { 209 static struct window_settings windows[] = {
210 { /* Index 0 */ 210 { /* Index 0 */
211 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", 211 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
212 /* mode_backcolor */ 0x006600ff, 212 /* mode_backcolor */ 0x006600ff,
213 /* mode_colorkey,msk*/ 0, 0, 213 /* mode_colorkey,msk*/ 0, 0,
214 { 214 {
215 { 215 {
216 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 216 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
217 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 217 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
218 LCD_WINCTRL1_PO_16BPP, 218 LCD_WINCTRL1_PO_16BPP,
219 /* mode_winenable*/ LCD_WINENABLE_WEN0, 219 /* mode_winenable*/ LCD_WINENABLE_WEN0,
220 }, 220 },
221 { 221 {
222 /* xres, yres, xpos, ypos */ 100, 100, 100, 100, 222 /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
223 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 223 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
224 LCD_WINCTRL1_PO_16BPP | 224 LCD_WINCTRL1_PO_16BPP |
225 LCD_WINCTRL1_PIPE, 225 LCD_WINCTRL1_PIPE,
226 /* mode_winenable*/ LCD_WINENABLE_WEN1, 226 /* mode_winenable*/ LCD_WINENABLE_WEN1,
227 }, 227 },
228 { 228 {
229 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 229 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
230 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 230 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
231 LCD_WINCTRL1_PO_16BPP, 231 LCD_WINCTRL1_PO_16BPP,
232 /* mode_winenable*/ 0, 232 /* mode_winenable*/ 0,
233 }, 233 },
234 { 234 {
235 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 235 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
236 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 236 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
237 LCD_WINCTRL1_PO_16BPP | 237 LCD_WINCTRL1_PO_16BPP |
238 LCD_WINCTRL1_PIPE, 238 LCD_WINCTRL1_PIPE,
239 /* mode_winenable*/ 0, 239 /* mode_winenable*/ 0,
240 }, 240 },
241 }, 241 },
242 }, 242 },
243 243
244 { /* Index 1 */ 244 { /* Index 1 */
245 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", 245 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
246 /* mode_backcolor */ 0x006600ff, 246 /* mode_backcolor */ 0x006600ff,
247 /* mode_colorkey,msk*/ 0, 0, 247 /* mode_colorkey,msk*/ 0, 0,
248 { 248 {
249 { 249 {
250 /* xres, yres, xpos, ypos */ 320, 240, 5, 5, 250 /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
251 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP | 251 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
252 LCD_WINCTRL1_PO_00, 252 LCD_WINCTRL1_PO_00,
253 /* mode_winenable*/ LCD_WINENABLE_WEN0, 253 /* mode_winenable*/ LCD_WINENABLE_WEN0,
254 }, 254 },
255 { 255 {
256 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 256 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
257 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 257 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
258 | LCD_WINCTRL1_PO_16BPP, 258 | LCD_WINCTRL1_PO_16BPP,
259 /* mode_winenable*/ 0, 259 /* mode_winenable*/ 0,
260 }, 260 },
261 { 261 {
262 /* xres, yres, xpos, ypos */ 100, 100, 0, 0, 262 /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
263 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 263 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
264 LCD_WINCTRL1_PO_16BPP | 264 LCD_WINCTRL1_PO_16BPP |
265 LCD_WINCTRL1_PIPE, 265 LCD_WINCTRL1_PIPE,
266 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, 266 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
267 }, 267 },
268 { 268 {
269 /* xres, yres, xpos, ypos */ 200, 25, 0, 0, 269 /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
270 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 270 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
271 LCD_WINCTRL1_PO_16BPP | 271 LCD_WINCTRL1_PO_16BPP |
272 LCD_WINCTRL1_PIPE, 272 LCD_WINCTRL1_PIPE,
273 /* mode_winenable*/ 0, 273 /* mode_winenable*/ 0,
274 }, 274 },
275 }, 275 },
276 }, 276 },
277 { /* Index 2 */ 277 { /* Index 2 */
278 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", 278 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
279 /* mode_backcolor */ 0x006600ff, 279 /* mode_backcolor */ 0x006600ff,
280 /* mode_colorkey,msk*/ 0, 0, 280 /* mode_colorkey,msk*/ 0, 0,
281 { 281 {
282 { 282 {
283 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 283 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
284 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 284 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
285 LCD_WINCTRL1_PO_16BPP, 285 LCD_WINCTRL1_PO_16BPP,
286 /* mode_winenable*/ LCD_WINENABLE_WEN0, 286 /* mode_winenable*/ LCD_WINENABLE_WEN0,
287 }, 287 },
288 { 288 {
289 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 289 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
290 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 290 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
291 LCD_WINCTRL1_PO_16BPP, 291 LCD_WINCTRL1_PO_16BPP,
292 /* mode_winenable*/ 0, 292 /* mode_winenable*/ 0,
293 }, 293 },
294 { 294 {
295 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 295 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
296 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP | 296 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
297 LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE, 297 LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
298 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, 298 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
299 }, 299 },
300 { 300 {
301 /* xres, yres, xpos, ypos */ 0, 0, 0, 0, 301 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
302 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | 302 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
303 LCD_WINCTRL1_PO_16BPP | 303 LCD_WINCTRL1_PO_16BPP |
304 LCD_WINCTRL1_PIPE, 304 LCD_WINCTRL1_PIPE,
305 /* mode_winenable*/ 0, 305 /* mode_winenable*/ 0,
306 }, 306 },
307 }, 307 },
308 }, 308 },
309 /* Need VGA 640 @ 24bpp, @ 32bpp */ 309 /* Need VGA 640 @ 24bpp, @ 32bpp */
310 /* Need VGA 800 @ 24bpp, @ 32bpp */ 310 /* Need VGA 800 @ 24bpp, @ 32bpp */
311 /* Need VGA 1024 @ 24bpp, @ 32bpp */ 311 /* Need VGA 1024 @ 24bpp, @ 32bpp */
312 }; 312 };
313 313
314 /* 314 /*
315 * Controller configurations for various panels. 315 * Controller configurations for various panels.
316 */ 316 */
317 317
318 struct panel_settings 318 struct panel_settings
319 { 319 {
320 const char name[25]; /* Full name <vendor>_<model> */ 320 const char name[25]; /* Full name <vendor>_<model> */
321 321
322 struct fb_monspecs monspecs; /* FB monitor specs */ 322 struct fb_monspecs monspecs; /* FB monitor specs */
323 323
324 /* panel timings */ 324 /* panel timings */
325 uint32 mode_screen; 325 uint32 mode_screen;
326 uint32 mode_horztiming; 326 uint32 mode_horztiming;
327 uint32 mode_verttiming; 327 uint32 mode_verttiming;
328 uint32 mode_clkcontrol; 328 uint32 mode_clkcontrol;
329 uint32 mode_pwmdiv; 329 uint32 mode_pwmdiv;
330 uint32 mode_pwmhi; 330 uint32 mode_pwmhi;
331 uint32 mode_outmask; 331 uint32 mode_outmask;
332 uint32 mode_fifoctrl; 332 uint32 mode_fifoctrl;
333 uint32 mode_toyclksrc; 333 uint32 mode_toyclksrc;
334 uint32 mode_backlight; 334 uint32 mode_backlight;
335 uint32 mode_auxpll; 335 uint32 mode_auxpll;
336 #define Xres min_xres 336 #define Xres min_xres
337 #define Yres min_yres 337 #define Yres min_yres
338 u32 min_xres; /* Minimum horizontal resolution */ 338 u32 min_xres; /* Minimum horizontal resolution */
339 u32 max_xres; /* Maximum horizontal resolution */ 339 u32 max_xres; /* Maximum horizontal resolution */
340 u32 min_yres; /* Minimum vertical resolution */ 340 u32 min_yres; /* Minimum vertical resolution */
341 u32 max_yres; /* Maximum vertical resolution */ 341 u32 max_yres; /* Maximum vertical resolution */
342 }; 342 };
343 343
344 /********************************************************************/ 344 /********************************************************************/
345 /* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */ 345 /* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
346 346
347 /* List of panels known to work with the AU1200 LCD controller. 347 /* List of panels known to work with the AU1200 LCD controller.
348 * To add a new panel, enter the same specifications as the 348 * To add a new panel, enter the same specifications as the
349 * Generic_TFT one, and MAKE SURE that it doesn't conflicts 349 * Generic_TFT one, and MAKE SURE that it doesn't conflicts
350 * with the controller restrictions. Restrictions are: 350 * with the controller restrictions. Restrictions are:
351 * 351 *
352 * STN color panels: max_bpp <= 12 352 * STN color panels: max_bpp <= 12
353 * STN mono panels: max_bpp <= 4 353 * STN mono panels: max_bpp <= 4
354 * TFT panels: max_bpp <= 16 354 * TFT panels: max_bpp <= 16
355 * max_xres <= 800 355 * max_xres <= 800
356 * max_yres <= 600 356 * max_yres <= 600
357 */ 357 */
358 static struct panel_settings known_lcd_panels[] = 358 static struct panel_settings known_lcd_panels[] =
359 { 359 {
360 [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */ 360 [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
361 .name = "QVGA_320x240", 361 .name = "QVGA_320x240",
362 .monspecs = { 362 .monspecs = {
363 .modedb = NULL, 363 .modedb = NULL,
364 .modedb_len = 0, 364 .modedb_len = 0,
365 .hfmin = 30000, 365 .hfmin = 30000,
366 .hfmax = 70000, 366 .hfmax = 70000,
367 .vfmin = 60, 367 .vfmin = 60,
368 .vfmax = 60, 368 .vfmax = 60,
369 .dclkmin = 6000000, 369 .dclkmin = 6000000,
370 .dclkmax = 28000000, 370 .dclkmax = 28000000,
371 .input = FB_DISP_RGB, 371 .input = FB_DISP_RGB,
372 }, 372 },
373 .mode_screen = LCD_SCREEN_SX_N(320) | 373 .mode_screen = LCD_SCREEN_SX_N(320) |
374 LCD_SCREEN_SY_N(240), 374 LCD_SCREEN_SY_N(240),
375 .mode_horztiming = 0x00c4623b, 375 .mode_horztiming = 0x00c4623b,
376 .mode_verttiming = 0x00502814, 376 .mode_verttiming = 0x00502814,
377 .mode_clkcontrol = 0x00020002, /* /4=24Mhz */ 377 .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
378 .mode_pwmdiv = 0x00000000, 378 .mode_pwmdiv = 0x00000000,
379 .mode_pwmhi = 0x00000000, 379 .mode_pwmhi = 0x00000000,
380 .mode_outmask = 0x00FFFFFF, 380 .mode_outmask = 0x00FFFFFF,
381 .mode_fifoctrl = 0x2f2f2f2f, 381 .mode_fifoctrl = 0x2f2f2f2f,
382 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 382 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
383 .mode_backlight = 0x00000000, 383 .mode_backlight = 0x00000000,
384 .mode_auxpll = 8, /* 96MHz AUXPLL */ 384 .mode_auxpll = 8, /* 96MHz AUXPLL */
385 320, 320, 385 320, 320,
386 240, 240, 386 240, 240,
387 }, 387 },
388 388
389 [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */ 389 [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
390 .name = "VGA_640x480", 390 .name = "VGA_640x480",
391 .monspecs = { 391 .monspecs = {
392 .modedb = NULL, 392 .modedb = NULL,
393 .modedb_len = 0, 393 .modedb_len = 0,
394 .hfmin = 30000, 394 .hfmin = 30000,
395 .hfmax = 70000, 395 .hfmax = 70000,
396 .vfmin = 60, 396 .vfmin = 60,
397 .vfmax = 60, 397 .vfmax = 60,
398 .dclkmin = 6000000, 398 .dclkmin = 6000000,
399 .dclkmax = 28000000, 399 .dclkmax = 28000000,
400 .input = FB_DISP_RGB, 400 .input = FB_DISP_RGB,
401 }, 401 },
402 .mode_screen = 0x13f9df80, 402 .mode_screen = 0x13f9df80,
403 .mode_horztiming = 0x003c5859, 403 .mode_horztiming = 0x003c5859,
404 .mode_verttiming = 0x00741201, 404 .mode_verttiming = 0x00741201,
405 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ 405 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
406 .mode_pwmdiv = 0x00000000, 406 .mode_pwmdiv = 0x00000000,
407 .mode_pwmhi = 0x00000000, 407 .mode_pwmhi = 0x00000000,
408 .mode_outmask = 0x00FFFFFF, 408 .mode_outmask = 0x00FFFFFF,
409 .mode_fifoctrl = 0x2f2f2f2f, 409 .mode_fifoctrl = 0x2f2f2f2f,
410 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 410 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
411 .mode_backlight = 0x00000000, 411 .mode_backlight = 0x00000000,
412 .mode_auxpll = 8, /* 96MHz AUXPLL */ 412 .mode_auxpll = 8, /* 96MHz AUXPLL */
413 640, 480, 413 640, 480,
414 640, 480, 414 640, 480,
415 }, 415 },
416 416
417 [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */ 417 [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
418 .name = "SVGA_800x600", 418 .name = "SVGA_800x600",
419 .monspecs = { 419 .monspecs = {
420 .modedb = NULL, 420 .modedb = NULL,
421 .modedb_len = 0, 421 .modedb_len = 0,
422 .hfmin = 30000, 422 .hfmin = 30000,
423 .hfmax = 70000, 423 .hfmax = 70000,
424 .vfmin = 60, 424 .vfmin = 60,
425 .vfmax = 60, 425 .vfmax = 60,
426 .dclkmin = 6000000, 426 .dclkmin = 6000000,
427 .dclkmax = 28000000, 427 .dclkmax = 28000000,
428 .input = FB_DISP_RGB, 428 .input = FB_DISP_RGB,
429 }, 429 },
430 .mode_screen = 0x18fa5780, 430 .mode_screen = 0x18fa5780,
431 .mode_horztiming = 0x00dc7e77, 431 .mode_horztiming = 0x00dc7e77,
432 .mode_verttiming = 0x00584805, 432 .mode_verttiming = 0x00584805,
433 .mode_clkcontrol = 0x00020000, /* /2=48Mhz */ 433 .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
434 .mode_pwmdiv = 0x00000000, 434 .mode_pwmdiv = 0x00000000,
435 .mode_pwmhi = 0x00000000, 435 .mode_pwmhi = 0x00000000,
436 .mode_outmask = 0x00FFFFFF, 436 .mode_outmask = 0x00FFFFFF,
437 .mode_fifoctrl = 0x2f2f2f2f, 437 .mode_fifoctrl = 0x2f2f2f2f,
438 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 438 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
439 .mode_backlight = 0x00000000, 439 .mode_backlight = 0x00000000,
440 .mode_auxpll = 8, /* 96MHz AUXPLL */ 440 .mode_auxpll = 8, /* 96MHz AUXPLL */
441 800, 800, 441 800, 800,
442 600, 600, 442 600, 600,
443 }, 443 },
444 444
445 [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */ 445 [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
446 .name = "XVGA_1024x768", 446 .name = "XVGA_1024x768",
447 .monspecs = { 447 .monspecs = {
448 .modedb = NULL, 448 .modedb = NULL,
449 .modedb_len = 0, 449 .modedb_len = 0,
450 .hfmin = 30000, 450 .hfmin = 30000,
451 .hfmax = 70000, 451 .hfmax = 70000,
452 .vfmin = 60, 452 .vfmin = 60,
453 .vfmax = 60, 453 .vfmax = 60,
454 .dclkmin = 6000000, 454 .dclkmin = 6000000,
455 .dclkmax = 28000000, 455 .dclkmax = 28000000,
456 .input = FB_DISP_RGB, 456 .input = FB_DISP_RGB,
457 }, 457 },
458 .mode_screen = 0x1ffaff80, 458 .mode_screen = 0x1ffaff80,
459 .mode_horztiming = 0x007d0e57, 459 .mode_horztiming = 0x007d0e57,
460 .mode_verttiming = 0x00740a01, 460 .mode_verttiming = 0x00740a01,
461 .mode_clkcontrol = 0x000A0000, /* /1 */ 461 .mode_clkcontrol = 0x000A0000, /* /1 */
462 .mode_pwmdiv = 0x00000000, 462 .mode_pwmdiv = 0x00000000,
463 .mode_pwmhi = 0x00000000, 463 .mode_pwmhi = 0x00000000,
464 .mode_outmask = 0x00FFFFFF, 464 .mode_outmask = 0x00FFFFFF,
465 .mode_fifoctrl = 0x2f2f2f2f, 465 .mode_fifoctrl = 0x2f2f2f2f,
466 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 466 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
467 .mode_backlight = 0x00000000, 467 .mode_backlight = 0x00000000,
468 .mode_auxpll = 6, /* 72MHz AUXPLL */ 468 .mode_auxpll = 6, /* 72MHz AUXPLL */
469 1024, 1024, 469 1024, 1024,
470 768, 768, 470 768, 768,
471 }, 471 },
472 472
473 [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */ 473 [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
474 .name = "XVGA_1280x1024", 474 .name = "XVGA_1280x1024",
475 .monspecs = { 475 .monspecs = {
476 .modedb = NULL, 476 .modedb = NULL,
477 .modedb_len = 0, 477 .modedb_len = 0,
478 .hfmin = 30000, 478 .hfmin = 30000,
479 .hfmax = 70000, 479 .hfmax = 70000,
480 .vfmin = 60, 480 .vfmin = 60,
481 .vfmax = 60, 481 .vfmax = 60,
482 .dclkmin = 6000000, 482 .dclkmin = 6000000,
483 .dclkmax = 28000000, 483 .dclkmax = 28000000,
484 .input = FB_DISP_RGB, 484 .input = FB_DISP_RGB,
485 }, 485 },
486 .mode_screen = 0x27fbff80, 486 .mode_screen = 0x27fbff80,
487 .mode_horztiming = 0x00cdb2c7, 487 .mode_horztiming = 0x00cdb2c7,
488 .mode_verttiming = 0x00600002, 488 .mode_verttiming = 0x00600002,
489 .mode_clkcontrol = 0x000A0000, /* /1 */ 489 .mode_clkcontrol = 0x000A0000, /* /1 */
490 .mode_pwmdiv = 0x00000000, 490 .mode_pwmdiv = 0x00000000,
491 .mode_pwmhi = 0x00000000, 491 .mode_pwmhi = 0x00000000,
492 .mode_outmask = 0x00FFFFFF, 492 .mode_outmask = 0x00FFFFFF,
493 .mode_fifoctrl = 0x2f2f2f2f, 493 .mode_fifoctrl = 0x2f2f2f2f,
494 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 494 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
495 .mode_backlight = 0x00000000, 495 .mode_backlight = 0x00000000,
496 .mode_auxpll = 10, /* 120MHz AUXPLL */ 496 .mode_auxpll = 10, /* 120MHz AUXPLL */
497 1280, 1280, 497 1280, 1280,
498 1024, 1024, 498 1024, 1024,
499 }, 499 },
500 500
501 [5] = { /* Samsung 1024x768 TFT */ 501 [5] = { /* Samsung 1024x768 TFT */
502 .name = "Samsung_1024x768_TFT", 502 .name = "Samsung_1024x768_TFT",
503 .monspecs = { 503 .monspecs = {
504 .modedb = NULL, 504 .modedb = NULL,
505 .modedb_len = 0, 505 .modedb_len = 0,
506 .hfmin = 30000, 506 .hfmin = 30000,
507 .hfmax = 70000, 507 .hfmax = 70000,
508 .vfmin = 60, 508 .vfmin = 60,
509 .vfmax = 60, 509 .vfmax = 60,
510 .dclkmin = 6000000, 510 .dclkmin = 6000000,
511 .dclkmax = 28000000, 511 .dclkmax = 28000000,
512 .input = FB_DISP_RGB, 512 .input = FB_DISP_RGB,
513 }, 513 },
514 .mode_screen = 0x1ffaff80, 514 .mode_screen = 0x1ffaff80,
515 .mode_horztiming = 0x018cc677, 515 .mode_horztiming = 0x018cc677,
516 .mode_verttiming = 0x00241217, 516 .mode_verttiming = 0x00241217,
517 .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */ 517 .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
518 .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */ 518 .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
519 .mode_pwmhi = 0x03400000, /* SCB 0x0 */ 519 .mode_pwmhi = 0x03400000, /* SCB 0x0 */
520 .mode_outmask = 0x00FFFFFF, 520 .mode_outmask = 0x00FFFFFF,
521 .mode_fifoctrl = 0x2f2f2f2f, 521 .mode_fifoctrl = 0x2f2f2f2f,
522 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 522 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
523 .mode_backlight = 0x00000000, 523 .mode_backlight = 0x00000000,
524 .mode_auxpll = 8, /* 96MHz AUXPLL */ 524 .mode_auxpll = 8, /* 96MHz AUXPLL */
525 1024, 1024, 525 1024, 1024,
526 768, 768, 526 768, 768,
527 }, 527 },
528 528
529 [6] = { /* Toshiba 640x480 TFT */ 529 [6] = { /* Toshiba 640x480 TFT */
530 .name = "Toshiba_640x480_TFT", 530 .name = "Toshiba_640x480_TFT",
531 .monspecs = { 531 .monspecs = {
532 .modedb = NULL, 532 .modedb = NULL,
533 .modedb_len = 0, 533 .modedb_len = 0,
534 .hfmin = 30000, 534 .hfmin = 30000,
535 .hfmax = 70000, 535 .hfmax = 70000,
536 .vfmin = 60, 536 .vfmin = 60,
537 .vfmax = 60, 537 .vfmax = 60,
538 .dclkmin = 6000000, 538 .dclkmin = 6000000,
539 .dclkmax = 28000000, 539 .dclkmax = 28000000,
540 .input = FB_DISP_RGB, 540 .input = FB_DISP_RGB,
541 }, 541 },
542 .mode_screen = LCD_SCREEN_SX_N(640) | 542 .mode_screen = LCD_SCREEN_SX_N(640) |
543 LCD_SCREEN_SY_N(480), 543 LCD_SCREEN_SY_N(480),
544 .mode_horztiming = LCD_HORZTIMING_HPW_N(96) | 544 .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
545 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51), 545 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
546 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | 546 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
547 LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32), 547 LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
548 .mode_clkcontrol = 0x00000000, /* /4=24Mhz */ 548 .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
549 .mode_pwmdiv = 0x8000063f, 549 .mode_pwmdiv = 0x8000063f,
550 .mode_pwmhi = 0x03400000, 550 .mode_pwmhi = 0x03400000,
551 .mode_outmask = 0x00fcfcfc, 551 .mode_outmask = 0x00fcfcfc,
552 .mode_fifoctrl = 0x2f2f2f2f, 552 .mode_fifoctrl = 0x2f2f2f2f,
553 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 553 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
554 .mode_backlight = 0x00000000, 554 .mode_backlight = 0x00000000,
555 .mode_auxpll = 8, /* 96MHz AUXPLL */ 555 .mode_auxpll = 8, /* 96MHz AUXPLL */
556 640, 480, 556 640, 480,
557 640, 480, 557 640, 480,
558 }, 558 },
559 559
560 [7] = { /* Sharp 320x240 TFT */ 560 [7] = { /* Sharp 320x240 TFT */
561 .name = "Sharp_320x240_TFT", 561 .name = "Sharp_320x240_TFT",
562 .monspecs = { 562 .monspecs = {
563 .modedb = NULL, 563 .modedb = NULL,
564 .modedb_len = 0, 564 .modedb_len = 0,
565 .hfmin = 12500, 565 .hfmin = 12500,
566 .hfmax = 20000, 566 .hfmax = 20000,
567 .vfmin = 38, 567 .vfmin = 38,
568 .vfmax = 81, 568 .vfmax = 81,
569 .dclkmin = 4500000, 569 .dclkmin = 4500000,
570 .dclkmax = 6800000, 570 .dclkmax = 6800000,
571 .input = FB_DISP_RGB, 571 .input = FB_DISP_RGB,
572 }, 572 },
573 .mode_screen = LCD_SCREEN_SX_N(320) | 573 .mode_screen = LCD_SCREEN_SX_N(320) |
574 LCD_SCREEN_SY_N(240), 574 LCD_SCREEN_SY_N(240),
575 .mode_horztiming = LCD_HORZTIMING_HPW_N(60) | 575 .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
576 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2), 576 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
577 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | 577 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
578 LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5), 578 LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
579 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/ 579 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
580 .mode_pwmdiv = 0x8000063f, 580 .mode_pwmdiv = 0x8000063f,
581 .mode_pwmhi = 0x03400000, 581 .mode_pwmhi = 0x03400000,
582 .mode_outmask = 0x00fcfcfc, 582 .mode_outmask = 0x00fcfcfc,
583 .mode_fifoctrl = 0x2f2f2f2f, 583 .mode_fifoctrl = 0x2f2f2f2f,
584 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 584 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
585 .mode_backlight = 0x00000000, 585 .mode_backlight = 0x00000000,
586 .mode_auxpll = 8, /* 96MHz AUXPLL */ 586 .mode_auxpll = 8, /* 96MHz AUXPLL */
587 320, 320, 587 320, 320,
588 240, 240, 588 240, 240,
589 }, 589 },
590 590
591 [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */ 591 [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
592 .name = "Toppoly_TD070WGCB2", 592 .name = "Toppoly_TD070WGCB2",
593 .monspecs = { 593 .monspecs = {
594 .modedb = NULL, 594 .modedb = NULL,
595 .modedb_len = 0, 595 .modedb_len = 0,
596 .hfmin = 30000, 596 .hfmin = 30000,
597 .hfmax = 70000, 597 .hfmax = 70000,
598 .vfmin = 60, 598 .vfmin = 60,
599 .vfmax = 60, 599 .vfmax = 60,
600 .dclkmin = 6000000, 600 .dclkmin = 6000000,
601 .dclkmax = 28000000, 601 .dclkmax = 28000000,
602 .input = FB_DISP_RGB, 602 .input = FB_DISP_RGB,
603 }, 603 },
604 .mode_screen = LCD_SCREEN_SX_N(856) | 604 .mode_screen = LCD_SCREEN_SX_N(856) |
605 LCD_SCREEN_SY_N(480), 605 LCD_SCREEN_SY_N(480),
606 .mode_horztiming = LCD_HORZTIMING_HND2_N(43) | 606 .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
607 LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114), 607 LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
608 .mode_verttiming = LCD_VERTTIMING_VND2_N(20) | 608 .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
609 LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4), 609 LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
610 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ 610 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
611 .mode_pwmdiv = 0x8000063f, 611 .mode_pwmdiv = 0x8000063f,
612 .mode_pwmhi = 0x03400000, 612 .mode_pwmhi = 0x03400000,
613 .mode_outmask = 0x00fcfcfc, 613 .mode_outmask = 0x00fcfcfc,
614 .mode_fifoctrl = 0x2f2f2f2f, 614 .mode_fifoctrl = 0x2f2f2f2f,
615 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 615 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
616 .mode_backlight = 0x00000000, 616 .mode_backlight = 0x00000000,
617 .mode_auxpll = 8, /* 96MHz AUXPLL */ 617 .mode_auxpll = 8, /* 96MHz AUXPLL */
618 856, 856, 618 856, 856,
619 480, 480, 619 480, 480,
620 }, 620 },
621 [9] = { 621 [9] = {
622 .name = "DB1300_800x480", 622 .name = "DB1300_800x480",
623 .monspecs = { 623 .monspecs = {
624 .modedb = NULL, 624 .modedb = NULL,
625 .modedb_len = 0, 625 .modedb_len = 0,
626 .hfmin = 30000, 626 .hfmin = 30000,
627 .hfmax = 70000, 627 .hfmax = 70000,
628 .vfmin = 60, 628 .vfmin = 60,
629 .vfmax = 60, 629 .vfmax = 60,
630 .dclkmin = 6000000, 630 .dclkmin = 6000000,
631 .dclkmax = 28000000, 631 .dclkmax = 28000000,
632 .input = FB_DISP_RGB, 632 .input = FB_DISP_RGB,
633 }, 633 },
634 .mode_screen = LCD_SCREEN_SX_N(800) | 634 .mode_screen = LCD_SCREEN_SX_N(800) |
635 LCD_SCREEN_SY_N(480), 635 LCD_SCREEN_SY_N(480),
636 .mode_horztiming = LCD_HORZTIMING_HPW_N(5) | 636 .mode_horztiming = LCD_HORZTIMING_HPW_N(5) |
637 LCD_HORZTIMING_HND1_N(16) | 637 LCD_HORZTIMING_HND1_N(16) |
638 LCD_HORZTIMING_HND2_N(8), 638 LCD_HORZTIMING_HND2_N(8),
639 .mode_verttiming = LCD_VERTTIMING_VPW_N(4) | 639 .mode_verttiming = LCD_VERTTIMING_VPW_N(4) |
640 LCD_VERTTIMING_VND1_N(8) | 640 LCD_VERTTIMING_VND1_N(8) |
641 LCD_VERTTIMING_VND2_N(5), 641 LCD_VERTTIMING_VND2_N(5),
642 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1) | 642 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1) |
643 LCD_CLKCONTROL_IV | 643 LCD_CLKCONTROL_IV |
644 LCD_CLKCONTROL_IH, 644 LCD_CLKCONTROL_IH,
645 .mode_pwmdiv = 0x00000000, 645 .mode_pwmdiv = 0x00000000,
646 .mode_pwmhi = 0x00000000, 646 .mode_pwmhi = 0x00000000,
647 .mode_outmask = 0x00FFFFFF, 647 .mode_outmask = 0x00FFFFFF,
648 .mode_fifoctrl = 0x2f2f2f2f, 648 .mode_fifoctrl = 0x2f2f2f2f,
649 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ 649 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
650 .mode_backlight = 0x00000000, 650 .mode_backlight = 0x00000000,
651 .mode_auxpll = (48/12) * 2, 651 .mode_auxpll = (48/12) * 2,
652 800, 800, 652 800, 800,
653 480, 480, 653 480, 480,
654 }, 654 },
655 }; 655 };
656 656
657 #define NUM_PANELS (ARRAY_SIZE(known_lcd_panels)) 657 #define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
658 658
659 /********************************************************************/ 659 /********************************************************************/
660 660
661 static int winbpp (unsigned int winctrl1) 661 static int winbpp (unsigned int winctrl1)
662 { 662 {
663 int bits = 0; 663 int bits = 0;
664 664
665 /* how many bits are needed for each pixel format */ 665 /* how many bits are needed for each pixel format */
666 switch (winctrl1 & LCD_WINCTRL1_FRM) { 666 switch (winctrl1 & LCD_WINCTRL1_FRM) {
667 case LCD_WINCTRL1_FRM_1BPP: 667 case LCD_WINCTRL1_FRM_1BPP:
668 bits = 1; 668 bits = 1;
669 break; 669 break;
670 case LCD_WINCTRL1_FRM_2BPP: 670 case LCD_WINCTRL1_FRM_2BPP:
671 bits = 2; 671 bits = 2;
672 break; 672 break;
673 case LCD_WINCTRL1_FRM_4BPP: 673 case LCD_WINCTRL1_FRM_4BPP:
674 bits = 4; 674 bits = 4;
675 break; 675 break;
676 case LCD_WINCTRL1_FRM_8BPP: 676 case LCD_WINCTRL1_FRM_8BPP:
677 bits = 8; 677 bits = 8;
678 break; 678 break;
679 case LCD_WINCTRL1_FRM_12BPP: 679 case LCD_WINCTRL1_FRM_12BPP:
680 case LCD_WINCTRL1_FRM_16BPP655: 680 case LCD_WINCTRL1_FRM_16BPP655:
681 case LCD_WINCTRL1_FRM_16BPP565: 681 case LCD_WINCTRL1_FRM_16BPP565:
682 case LCD_WINCTRL1_FRM_16BPP556: 682 case LCD_WINCTRL1_FRM_16BPP556:
683 case LCD_WINCTRL1_FRM_16BPPI1555: 683 case LCD_WINCTRL1_FRM_16BPPI1555:
684 case LCD_WINCTRL1_FRM_16BPPI5551: 684 case LCD_WINCTRL1_FRM_16BPPI5551:
685 case LCD_WINCTRL1_FRM_16BPPA1555: 685 case LCD_WINCTRL1_FRM_16BPPA1555:
686 case LCD_WINCTRL1_FRM_16BPPA5551: 686 case LCD_WINCTRL1_FRM_16BPPA5551:
687 bits = 16; 687 bits = 16;
688 break; 688 break;
689 case LCD_WINCTRL1_FRM_24BPP: 689 case LCD_WINCTRL1_FRM_24BPP:
690 case LCD_WINCTRL1_FRM_32BPP: 690 case LCD_WINCTRL1_FRM_32BPP:
691 bits = 32; 691 bits = 32;
692 break; 692 break;
693 } 693 }
694 694
695 return bits; 695 return bits;
696 } 696 }
697 697
698 static int fbinfo2index (struct fb_info *fb_info) 698 static int fbinfo2index (struct fb_info *fb_info)
699 { 699 {
700 int i; 700 int i;
701 701
702 for (i = 0; i < device_count; ++i) { 702 for (i = 0; i < device_count; ++i) {
703 if (fb_info == _au1200fb_infos[i]) 703 if (fb_info == _au1200fb_infos[i])
704 return i; 704 return i;
705 } 705 }
706 printk("au1200fb: ERROR: fbinfo2index failed!\n"); 706 printk("au1200fb: ERROR: fbinfo2index failed!\n");
707 return -1; 707 return -1;
708 } 708 }
709 709
710 static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, 710 static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
711 int xpos, int ypos) 711 int xpos, int ypos)
712 { 712 {
713 uint32 winctrl0, winctrl1, winenable, fb_offset = 0; 713 uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
714 int xsz, ysz; 714 int xsz, ysz;
715 715
716 /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */ 716 /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
717 717
718 winctrl0 = lcd->window[plane].winctrl0; 718 winctrl0 = lcd->window[plane].winctrl0;
719 winctrl1 = lcd->window[plane].winctrl1; 719 winctrl1 = lcd->window[plane].winctrl1;
720 winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN); 720 winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
721 winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY); 721 winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
722 722
723 /* Check for off-screen adjustments */ 723 /* Check for off-screen adjustments */
724 xsz = win->w[plane].xres; 724 xsz = win->w[plane].xres;
725 ysz = win->w[plane].yres; 725 ysz = win->w[plane].yres;
726 if ((xpos + win->w[plane].xres) > panel->Xres) { 726 if ((xpos + win->w[plane].xres) > panel->Xres) {
727 /* Off-screen to the right */ 727 /* Off-screen to the right */
728 xsz = panel->Xres - xpos; /* off by 1 ??? */ 728 xsz = panel->Xres - xpos; /* off by 1 ??? */
729 /*printk("off screen right\n");*/ 729 /*printk("off screen right\n");*/
730 } 730 }
731 731
732 if ((ypos + win->w[plane].yres) > panel->Yres) { 732 if ((ypos + win->w[plane].yres) > panel->Yres) {
733 /* Off-screen to the bottom */ 733 /* Off-screen to the bottom */
734 ysz = panel->Yres - ypos; /* off by 1 ??? */ 734 ysz = panel->Yres - ypos; /* off by 1 ??? */
735 /*printk("off screen bottom\n");*/ 735 /*printk("off screen bottom\n");*/
736 } 736 }
737 737
738 if (xpos < 0) { 738 if (xpos < 0) {
739 /* Off-screen to the left */ 739 /* Off-screen to the left */
740 xsz = win->w[plane].xres + xpos; 740 xsz = win->w[plane].xres + xpos;
741 fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8); 741 fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
742 xpos = 0; 742 xpos = 0;
743 /*printk("off screen left\n");*/ 743 /*printk("off screen left\n");*/
744 } 744 }
745 745
746 if (ypos < 0) { 746 if (ypos < 0) {
747 /* Off-screen to the top */ 747 /* Off-screen to the top */
748 ysz = win->w[plane].yres + ypos; 748 ysz = win->w[plane].yres + ypos;
749 /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */ 749 /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
750 ypos = 0; 750 ypos = 0;
751 /*printk("off screen top\n");*/ 751 /*printk("off screen top\n");*/
752 } 752 }
753 753
754 /* record settings */ 754 /* record settings */
755 win->w[plane].xpos = xpos; 755 win->w[plane].xpos = xpos;
756 win->w[plane].ypos = ypos; 756 win->w[plane].ypos = ypos;
757 757
758 xsz -= 1; 758 xsz -= 1;
759 ysz -= 1; 759 ysz -= 1;
760 winctrl0 |= (xpos << 21); 760 winctrl0 |= (xpos << 21);
761 winctrl0 |= (ypos << 10); 761 winctrl0 |= (ypos << 10);
762 winctrl1 |= (xsz << 11); 762 winctrl1 |= (xsz << 11);
763 winctrl1 |= (ysz << 0); 763 winctrl1 |= (ysz << 0);
764 764
765 /* Disable the window while making changes, then restore WINEN */ 765 /* Disable the window while making changes, then restore WINEN */
766 winenable = lcd->winenable & (1 << plane); 766 winenable = lcd->winenable & (1 << plane);
767 au_sync(); 767 au_sync();
768 lcd->winenable &= ~(1 << plane); 768 lcd->winenable &= ~(1 << plane);
769 lcd->window[plane].winctrl0 = winctrl0; 769 lcd->window[plane].winctrl0 = winctrl0;
770 lcd->window[plane].winctrl1 = winctrl1; 770 lcd->window[plane].winctrl1 = winctrl1;
771 lcd->window[plane].winbuf0 = 771 lcd->window[plane].winbuf0 =
772 lcd->window[plane].winbuf1 = fbdev->fb_phys; 772 lcd->window[plane].winbuf1 = fbdev->fb_phys;
773 lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ 773 lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
774 lcd->winenable |= winenable; 774 lcd->winenable |= winenable;
775 au_sync(); 775 au_sync();
776 776
777 return 0; 777 return 0;
778 } 778 }
779 779
780 static void au1200_setpanel(struct panel_settings *newpanel, 780 static void au1200_setpanel(struct panel_settings *newpanel,
781 struct au1200fb_platdata *pd) 781 struct au1200fb_platdata *pd)
782 { 782 {
783 /* 783 /*
784 * Perform global setup/init of LCD controller 784 * Perform global setup/init of LCD controller
785 */ 785 */
786 uint32 winenable; 786 uint32 winenable;
787 787
788 /* Make sure all windows disabled */ 788 /* Make sure all windows disabled */
789 winenable = lcd->winenable; 789 winenable = lcd->winenable;
790 lcd->winenable = 0; 790 lcd->winenable = 0;
791 au_sync(); 791 au_sync();
792 /* 792 /*
793 * Ensure everything is disabled before reconfiguring 793 * Ensure everything is disabled before reconfiguring
794 */ 794 */
795 if (lcd->screen & LCD_SCREEN_SEN) { 795 if (lcd->screen & LCD_SCREEN_SEN) {
796 /* Wait for vertical sync period */ 796 /* Wait for vertical sync period */
797 lcd->intstatus = LCD_INT_SS; 797 lcd->intstatus = LCD_INT_SS;
798 while ((lcd->intstatus & LCD_INT_SS) == 0) { 798 while ((lcd->intstatus & LCD_INT_SS) == 0) {
799 au_sync(); 799 au_sync();
800 } 800 }
801 801
802 lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ 802 lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
803 803
804 do { 804 do {
805 lcd->intstatus = lcd->intstatus; /*clear interrupts*/ 805 lcd->intstatus = lcd->intstatus; /*clear interrupts*/
806 au_sync(); 806 au_sync();
807 /*wait for controller to shut down*/ 807 /*wait for controller to shut down*/
808 } while ((lcd->intstatus & LCD_INT_SD) == 0); 808 } while ((lcd->intstatus & LCD_INT_SD) == 0);
809 809
810 /* Call shutdown of current panel (if up) */ 810 /* Call shutdown of current panel (if up) */
811 /* this must occur last, because if an external clock is driving 811 /* this must occur last, because if an external clock is driving
812 the controller, the clock cannot be turned off before first 812 the controller, the clock cannot be turned off before first
813 shutting down the controller. 813 shutting down the controller.
814 */ 814 */
815 if (pd->panel_shutdown) 815 if (pd->panel_shutdown)
816 pd->panel_shutdown(); 816 pd->panel_shutdown();
817 } 817 }
818 818
819 /* Newpanel == NULL indicates a shutdown operation only */ 819 /* Newpanel == NULL indicates a shutdown operation only */
820 if (newpanel == NULL) 820 if (newpanel == NULL)
821 return; 821 return;
822 822
823 panel = newpanel; 823 panel = newpanel;
824 824
825 printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres); 825 printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
826 826
827 /* 827 /*
828 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid) 828 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
829 */ 829 */
830 if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) 830 if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
831 { 831 {
832 uint32 sys_clksrc; 832 uint32 sys_clksrc;
833 au_writel(panel->mode_auxpll, SYS_AUXPLL); 833 au_writel(panel->mode_auxpll, SYS_AUXPLL);
834 sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; 834 sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;
835 sys_clksrc |= panel->mode_toyclksrc; 835 sys_clksrc |= panel->mode_toyclksrc;
836 au_writel(sys_clksrc, SYS_CLKSRC); 836 au_writel(sys_clksrc, SYS_CLKSRC);
837 } 837 }
838 838
839 /* 839 /*
840 * Configure panel timings 840 * Configure panel timings
841 */ 841 */
842 lcd->screen = panel->mode_screen; 842 lcd->screen = panel->mode_screen;
843 lcd->horztiming = panel->mode_horztiming; 843 lcd->horztiming = panel->mode_horztiming;
844 lcd->verttiming = panel->mode_verttiming; 844 lcd->verttiming = panel->mode_verttiming;
845 lcd->clkcontrol = panel->mode_clkcontrol; 845 lcd->clkcontrol = panel->mode_clkcontrol;
846 lcd->pwmdiv = panel->mode_pwmdiv; 846 lcd->pwmdiv = panel->mode_pwmdiv;
847 lcd->pwmhi = panel->mode_pwmhi; 847 lcd->pwmhi = panel->mode_pwmhi;
848 lcd->outmask = panel->mode_outmask; 848 lcd->outmask = panel->mode_outmask;
849 lcd->fifoctrl = panel->mode_fifoctrl; 849 lcd->fifoctrl = panel->mode_fifoctrl;
850 au_sync(); 850 au_sync();
851 851
852 /* fixme: Check window settings to make sure still valid 852 /* fixme: Check window settings to make sure still valid
853 * for new geometry */ 853 * for new geometry */
854 #if 0 854 #if 0
855 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos); 855 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
856 au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos); 856 au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
857 au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos); 857 au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
858 au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos); 858 au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
859 #endif 859 #endif
860 lcd->winenable = winenable; 860 lcd->winenable = winenable;
861 861
862 /* 862 /*
863 * Re-enable screen now that it is configured 863 * Re-enable screen now that it is configured
864 */ 864 */
865 lcd->screen |= LCD_SCREEN_SEN; 865 lcd->screen |= LCD_SCREEN_SEN;
866 au_sync(); 866 au_sync();
867 867
868 /* Call init of panel */ 868 /* Call init of panel */
869 if (pd->panel_init) 869 if (pd->panel_init)
870 pd->panel_init(); 870 pd->panel_init();
871 871
872 /* FIX!!!! not appropriate on panel change!!! Global setup/init */ 872 /* FIX!!!! not appropriate on panel change!!! Global setup/init */
873 lcd->intenable = 0; 873 lcd->intenable = 0;
874 lcd->intstatus = ~0; 874 lcd->intstatus = ~0;
875 lcd->backcolor = win->mode_backcolor; 875 lcd->backcolor = win->mode_backcolor;
876 876
877 /* Setup Color Key - FIX!!! */ 877 /* Setup Color Key - FIX!!! */
878 lcd->colorkey = win->mode_colorkey; 878 lcd->colorkey = win->mode_colorkey;
879 lcd->colorkeymsk = win->mode_colorkeymsk; 879 lcd->colorkeymsk = win->mode_colorkeymsk;
880 880
881 /* Setup HWCursor - FIX!!! Need to support this eventually */ 881 /* Setup HWCursor - FIX!!! Need to support this eventually */
882 lcd->hwc.cursorctrl = 0; 882 lcd->hwc.cursorctrl = 0;
883 lcd->hwc.cursorpos = 0; 883 lcd->hwc.cursorpos = 0;
884 lcd->hwc.cursorcolor0 = 0; 884 lcd->hwc.cursorcolor0 = 0;
885 lcd->hwc.cursorcolor1 = 0; 885 lcd->hwc.cursorcolor1 = 0;
886 lcd->hwc.cursorcolor2 = 0; 886 lcd->hwc.cursorcolor2 = 0;
887 lcd->hwc.cursorcolor3 = 0; 887 lcd->hwc.cursorcolor3 = 0;
888 888
889 889
890 #if 0 890 #if 0
891 #define D(X) printk("%25s: %08X\n", #X, X) 891 #define D(X) printk("%25s: %08X\n", #X, X)
892 D(lcd->screen); 892 D(lcd->screen);
893 D(lcd->horztiming); 893 D(lcd->horztiming);
894 D(lcd->verttiming); 894 D(lcd->verttiming);
895 D(lcd->clkcontrol); 895 D(lcd->clkcontrol);
896 D(lcd->pwmdiv); 896 D(lcd->pwmdiv);
897 D(lcd->pwmhi); 897 D(lcd->pwmhi);
898 D(lcd->outmask); 898 D(lcd->outmask);
899 D(lcd->fifoctrl); 899 D(lcd->fifoctrl);
900 D(lcd->window[0].winctrl0); 900 D(lcd->window[0].winctrl0);
901 D(lcd->window[0].winctrl1); 901 D(lcd->window[0].winctrl1);
902 D(lcd->window[0].winctrl2); 902 D(lcd->window[0].winctrl2);
903 D(lcd->window[0].winbuf0); 903 D(lcd->window[0].winbuf0);
904 D(lcd->window[0].winbuf1); 904 D(lcd->window[0].winbuf1);
905 D(lcd->window[0].winbufctrl); 905 D(lcd->window[0].winbufctrl);
906 D(lcd->window[1].winctrl0); 906 D(lcd->window[1].winctrl0);
907 D(lcd->window[1].winctrl1); 907 D(lcd->window[1].winctrl1);
908 D(lcd->window[1].winctrl2); 908 D(lcd->window[1].winctrl2);
909 D(lcd->window[1].winbuf0); 909 D(lcd->window[1].winbuf0);
910 D(lcd->window[1].winbuf1); 910 D(lcd->window[1].winbuf1);
911 D(lcd->window[1].winbufctrl); 911 D(lcd->window[1].winbufctrl);
912 D(lcd->window[2].winctrl0); 912 D(lcd->window[2].winctrl0);
913 D(lcd->window[2].winctrl1); 913 D(lcd->window[2].winctrl1);
914 D(lcd->window[2].winctrl2); 914 D(lcd->window[2].winctrl2);
915 D(lcd->window[2].winbuf0); 915 D(lcd->window[2].winbuf0);
916 D(lcd->window[2].winbuf1); 916 D(lcd->window[2].winbuf1);
917 D(lcd->window[2].winbufctrl); 917 D(lcd->window[2].winbufctrl);
918 D(lcd->window[3].winctrl0); 918 D(lcd->window[3].winctrl0);
919 D(lcd->window[3].winctrl1); 919 D(lcd->window[3].winctrl1);
920 D(lcd->window[3].winctrl2); 920 D(lcd->window[3].winctrl2);
921 D(lcd->window[3].winbuf0); 921 D(lcd->window[3].winbuf0);
922 D(lcd->window[3].winbuf1); 922 D(lcd->window[3].winbuf1);
923 D(lcd->window[3].winbufctrl); 923 D(lcd->window[3].winbufctrl);
924 D(lcd->winenable); 924 D(lcd->winenable);
925 D(lcd->intenable); 925 D(lcd->intenable);
926 D(lcd->intstatus); 926 D(lcd->intstatus);
927 D(lcd->backcolor); 927 D(lcd->backcolor);
928 D(lcd->winenable); 928 D(lcd->winenable);
929 D(lcd->colorkey); 929 D(lcd->colorkey);
930 D(lcd->colorkeymsk); 930 D(lcd->colorkeymsk);
931 D(lcd->hwc.cursorctrl); 931 D(lcd->hwc.cursorctrl);
932 D(lcd->hwc.cursorpos); 932 D(lcd->hwc.cursorpos);
933 D(lcd->hwc.cursorcolor0); 933 D(lcd->hwc.cursorcolor0);
934 D(lcd->hwc.cursorcolor1); 934 D(lcd->hwc.cursorcolor1);
935 D(lcd->hwc.cursorcolor2); 935 D(lcd->hwc.cursorcolor2);
936 D(lcd->hwc.cursorcolor3); 936 D(lcd->hwc.cursorcolor3);
937 #endif 937 #endif
938 } 938 }
939 939
940 static void au1200_setmode(struct au1200fb_device *fbdev) 940 static void au1200_setmode(struct au1200fb_device *fbdev)
941 { 941 {
942 int plane = fbdev->plane; 942 int plane = fbdev->plane;
943 /* Window/plane setup */ 943 /* Window/plane setup */
944 lcd->window[plane].winctrl1 = ( 0 944 lcd->window[plane].winctrl1 = ( 0
945 | LCD_WINCTRL1_PRI_N(plane) 945 | LCD_WINCTRL1_PRI_N(plane)
946 | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */ 946 | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
947 ) ; 947 ) ;
948 948
949 au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos); 949 au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
950 950
951 lcd->window[plane].winctrl2 = ( 0 951 lcd->window[plane].winctrl2 = ( 0
952 | LCD_WINCTRL2_CKMODE_00 952 | LCD_WINCTRL2_CKMODE_00
953 | LCD_WINCTRL2_DBM 953 | LCD_WINCTRL2_DBM
954 | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length) 954 | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
955 | LCD_WINCTRL2_SCX_1 955 | LCD_WINCTRL2_SCX_1
956 | LCD_WINCTRL2_SCY_1 956 | LCD_WINCTRL2_SCY_1
957 ) ; 957 ) ;
958 lcd->winenable |= win->w[plane].mode_winenable; 958 lcd->winenable |= win->w[plane].mode_winenable;
959 au_sync(); 959 au_sync();
960 } 960 }
961 961
962 962
963 /* Inline helpers */ 963 /* Inline helpers */
964 964
965 /*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/ 965 /*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
966 /*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/ 966 /*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
967 967
968 #define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN) 968 #define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
969 969
970 /* Bitfields format supported by the controller. */ 970 /* Bitfields format supported by the controller. */
971 static struct fb_bitfield rgb_bitfields[][4] = { 971 static struct fb_bitfield rgb_bitfields[][4] = {
972 /* Red, Green, Blue, Transp */ 972 /* Red, Green, Blue, Transp */
973 [LCD_WINCTRL1_FRM_16BPP655 >> 25] = 973 [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
974 { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, 974 { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
975 975
976 [LCD_WINCTRL1_FRM_16BPP565 >> 25] = 976 [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
977 { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, 977 { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
978 978
979 [LCD_WINCTRL1_FRM_16BPP556 >> 25] = 979 [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
980 { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } }, 980 { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
981 981
982 [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] = 982 [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
983 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } }, 983 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
984 984
985 [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] = 985 [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
986 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } }, 986 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
987 987
988 [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] = 988 [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
989 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } }, 989 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
990 990
991 [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] = 991 [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
992 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } }, 992 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
993 993
994 [LCD_WINCTRL1_FRM_24BPP >> 25] = 994 [LCD_WINCTRL1_FRM_24BPP >> 25] =
995 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } }, 995 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
996 996
997 [LCD_WINCTRL1_FRM_32BPP >> 25] = 997 [LCD_WINCTRL1_FRM_32BPP >> 25] =
998 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } }, 998 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
999 }; 999 };
1000 1000
1001 /*-------------------------------------------------------------------------*/ 1001 /*-------------------------------------------------------------------------*/
1002 1002
1003 /* Helpers */ 1003 /* Helpers */
1004 1004
1005 static void au1200fb_update_fbinfo(struct fb_info *fbi) 1005 static void au1200fb_update_fbinfo(struct fb_info *fbi)
1006 { 1006 {
1007 /* FIX!!!! This also needs to take the window pixel format into account!!! */ 1007 /* FIX!!!! This also needs to take the window pixel format into account!!! */
1008 1008
1009 /* Update var-dependent FB info */ 1009 /* Update var-dependent FB info */
1010 if (panel_is_color(panel)) { 1010 if (panel_is_color(panel)) {
1011 if (fbi->var.bits_per_pixel <= 8) { 1011 if (fbi->var.bits_per_pixel <= 8) {
1012 /* palettized */ 1012 /* palettized */
1013 fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR; 1013 fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1014 fbi->fix.line_length = fbi->var.xres_virtual / 1014 fbi->fix.line_length = fbi->var.xres_virtual /
1015 (8/fbi->var.bits_per_pixel); 1015 (8/fbi->var.bits_per_pixel);
1016 } else { 1016 } else {
1017 /* non-palettized */ 1017 /* non-palettized */
1018 fbi->fix.visual = FB_VISUAL_TRUECOLOR; 1018 fbi->fix.visual = FB_VISUAL_TRUECOLOR;
1019 fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8); 1019 fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
1020 } 1020 }
1021 } else { 1021 } else {
1022 /* mono FIX!!! mono 8 and 4 bits */ 1022 /* mono FIX!!! mono 8 and 4 bits */
1023 fbi->fix.visual = FB_VISUAL_MONO10; 1023 fbi->fix.visual = FB_VISUAL_MONO10;
1024 fbi->fix.line_length = fbi->var.xres_virtual / 8; 1024 fbi->fix.line_length = fbi->var.xres_virtual / 8;
1025 } 1025 }
1026 1026
1027 fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual; 1027 fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
1028 print_dbg("line length: %d\n", fbi->fix.line_length); 1028 print_dbg("line length: %d\n", fbi->fix.line_length);
1029 print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel); 1029 print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
1030 } 1030 }
1031 1031
1032 /*-------------------------------------------------------------------------*/ 1032 /*-------------------------------------------------------------------------*/
1033 1033
1034 /* AU1200 framebuffer driver */ 1034 /* AU1200 framebuffer driver */
1035 1035
1036 /* fb_check_var 1036 /* fb_check_var
1037 * Validate var settings with hardware restrictions and modify it if necessary 1037 * Validate var settings with hardware restrictions and modify it if necessary
1038 */ 1038 */
1039 static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, 1039 static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
1040 struct fb_info *fbi) 1040 struct fb_info *fbi)
1041 { 1041 {
1042 struct au1200fb_device *fbdev = fbi->par; 1042 struct au1200fb_device *fbdev = fbi->par;
1043 u32 pixclock; 1043 u32 pixclock;
1044 int screen_size, plane; 1044 int screen_size, plane;
1045 1045
1046 plane = fbdev->plane; 1046 plane = fbdev->plane;
1047 1047
1048 /* Make sure that the mode respect all LCD controller and 1048 /* Make sure that the mode respect all LCD controller and
1049 * panel restrictions. */ 1049 * panel restrictions. */
1050 var->xres = win->w[plane].xres; 1050 var->xres = win->w[plane].xres;
1051 var->yres = win->w[plane].yres; 1051 var->yres = win->w[plane].yres;
1052 1052
1053 /* No need for virtual resolution support */ 1053 /* No need for virtual resolution support */
1054 var->xres_virtual = var->xres; 1054 var->xres_virtual = var->xres;
1055 var->yres_virtual = var->yres; 1055 var->yres_virtual = var->yres;
1056 1056
1057 var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1); 1057 var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
1058 1058
1059 screen_size = var->xres_virtual * var->yres_virtual; 1059 screen_size = var->xres_virtual * var->yres_virtual;
1060 if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8); 1060 if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
1061 else screen_size /= (8/var->bits_per_pixel); 1061 else screen_size /= (8/var->bits_per_pixel);
1062 1062
1063 if (fbdev->fb_len < screen_size) 1063 if (fbdev->fb_len < screen_size)
1064 return -EINVAL; /* Virtual screen is to big, abort */ 1064 return -EINVAL; /* Virtual screen is to big, abort */
1065 1065
1066 /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */ 1066 /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
1067 /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel 1067 /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
1068 * clock can only be obtain by dividing this value by an even integer. 1068 * clock can only be obtain by dividing this value by an even integer.
1069 * Fallback to a slower pixel clock if necessary. */ 1069 * Fallback to a slower pixel clock if necessary. */
1070 pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin); 1070 pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
1071 pixclock = min3(pixclock, fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2); 1071 pixclock = min3(pixclock, fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2);
1072 1072
1073 if (AU1200_LCD_MAX_CLK % pixclock) { 1073 if (AU1200_LCD_MAX_CLK % pixclock) {
1074 int diff = AU1200_LCD_MAX_CLK % pixclock; 1074 int diff = AU1200_LCD_MAX_CLK % pixclock;
1075 pixclock -= diff; 1075 pixclock -= diff;
1076 } 1076 }
1077 1077
1078 var->pixclock = KHZ2PICOS(pixclock/1000); 1078 var->pixclock = KHZ2PICOS(pixclock/1000);
1079 #if 0 1079 #if 0
1080 if (!panel_is_active(panel)) { 1080 if (!panel_is_active(panel)) {
1081 int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1; 1081 int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
1082 1082
1083 if (!panel_is_color(panel) 1083 if (!panel_is_color(panel)
1084 && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) { 1084 && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
1085 /* STN 8bit mono panel support is up to 6MHz pixclock */ 1085 /* STN 8bit mono panel support is up to 6MHz pixclock */
1086 var->pixclock = KHZ2PICOS(6000); 1086 var->pixclock = KHZ2PICOS(6000);
1087 } else if (!pcd) { 1087 } else if (!pcd) {
1088 /* Other STN panel support is up to 12MHz */ 1088 /* Other STN panel support is up to 12MHz */
1089 var->pixclock = KHZ2PICOS(12000); 1089 var->pixclock = KHZ2PICOS(12000);
1090 } 1090 }
1091 } 1091 }
1092 #endif 1092 #endif
1093 /* Set bitfield accordingly */ 1093 /* Set bitfield accordingly */
1094 switch (var->bits_per_pixel) { 1094 switch (var->bits_per_pixel) {
1095 case 16: 1095 case 16:
1096 { 1096 {
1097 /* 16bpp True color. 1097 /* 16bpp True color.
1098 * These must be set to MATCH WINCTRL[FORM] */ 1098 * These must be set to MATCH WINCTRL[FORM] */
1099 int idx; 1099 int idx;
1100 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25; 1100 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1101 var->red = rgb_bitfields[idx][0]; 1101 var->red = rgb_bitfields[idx][0];
1102 var->green = rgb_bitfields[idx][1]; 1102 var->green = rgb_bitfields[idx][1];
1103 var->blue = rgb_bitfields[idx][2]; 1103 var->blue = rgb_bitfields[idx][2];
1104 var->transp = rgb_bitfields[idx][3]; 1104 var->transp = rgb_bitfields[idx][3];
1105 break; 1105 break;
1106 } 1106 }
1107 1107
1108 case 32: 1108 case 32:
1109 { 1109 {
1110 /* 32bpp True color. 1110 /* 32bpp True color.
1111 * These must be set to MATCH WINCTRL[FORM] */ 1111 * These must be set to MATCH WINCTRL[FORM] */
1112 int idx; 1112 int idx;
1113 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25; 1113 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1114 var->red = rgb_bitfields[idx][0]; 1114 var->red = rgb_bitfields[idx][0];
1115 var->green = rgb_bitfields[idx][1]; 1115 var->green = rgb_bitfields[idx][1];
1116 var->blue = rgb_bitfields[idx][2]; 1116 var->blue = rgb_bitfields[idx][2];
1117 var->transp = rgb_bitfields[idx][3]; 1117 var->transp = rgb_bitfields[idx][3];
1118 break; 1118 break;
1119 } 1119 }
1120 default: 1120 default:
1121 print_dbg("Unsupported depth %dbpp", var->bits_per_pixel); 1121 print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
1122 return -EINVAL; 1122 return -EINVAL;
1123 } 1123 }
1124 1124
1125 return 0; 1125 return 0;
1126 } 1126 }
1127 1127
1128 /* fb_set_par 1128 /* fb_set_par
1129 * Set hardware with var settings. This will enable the controller with a 1129 * Set hardware with var settings. This will enable the controller with a
1130 * specific mode, normally validated with the fb_check_var method 1130 * specific mode, normally validated with the fb_check_var method
1131 */ 1131 */
1132 static int au1200fb_fb_set_par(struct fb_info *fbi) 1132 static int au1200fb_fb_set_par(struct fb_info *fbi)
1133 { 1133 {
1134 struct au1200fb_device *fbdev = fbi->par; 1134 struct au1200fb_device *fbdev = fbi->par;
1135 1135
1136 au1200fb_update_fbinfo(fbi); 1136 au1200fb_update_fbinfo(fbi);
1137 au1200_setmode(fbdev); 1137 au1200_setmode(fbdev);
1138 1138
1139 return 0; 1139 return 0;
1140 } 1140 }
1141 1141
1142 /* fb_setcolreg 1142 /* fb_setcolreg
1143 * Set color in LCD palette. 1143 * Set color in LCD palette.
1144 */ 1144 */
1145 static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, 1145 static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
1146 unsigned blue, unsigned transp, struct fb_info *fbi) 1146 unsigned blue, unsigned transp, struct fb_info *fbi)
1147 { 1147 {
1148 volatile u32 *palette = lcd->palette; 1148 volatile u32 *palette = lcd->palette;
1149 u32 value; 1149 u32 value;
1150 1150
1151 if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1)) 1151 if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
1152 return -EINVAL; 1152 return -EINVAL;
1153 1153
1154 if (fbi->var.grayscale) { 1154 if (fbi->var.grayscale) {
1155 /* Convert color to grayscale */ 1155 /* Convert color to grayscale */
1156 red = green = blue = 1156 red = green = blue =
1157 (19595 * red + 38470 * green + 7471 * blue) >> 16; 1157 (19595 * red + 38470 * green + 7471 * blue) >> 16;
1158 } 1158 }
1159 1159
1160 if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) { 1160 if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
1161 /* Place color in the pseudopalette */ 1161 /* Place color in the pseudopalette */
1162 if (regno > 16) 1162 if (regno > 16)
1163 return -EINVAL; 1163 return -EINVAL;
1164 1164
1165 palette = (u32*) fbi->pseudo_palette; 1165 palette = (u32*) fbi->pseudo_palette;
1166 1166
1167 red >>= (16 - fbi->var.red.length); 1167 red >>= (16 - fbi->var.red.length);
1168 green >>= (16 - fbi->var.green.length); 1168 green >>= (16 - fbi->var.green.length);
1169 blue >>= (16 - fbi->var.blue.length); 1169 blue >>= (16 - fbi->var.blue.length);
1170 1170
1171 value = (red << fbi->var.red.offset) | 1171 value = (red << fbi->var.red.offset) |
1172 (green << fbi->var.green.offset)| 1172 (green << fbi->var.green.offset)|
1173 (blue << fbi->var.blue.offset); 1173 (blue << fbi->var.blue.offset);
1174 value &= 0xFFFF; 1174 value &= 0xFFFF;
1175 1175
1176 } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) { 1176 } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
1177 /* COLOR TFT PALLETTIZED (use RGB 565) */ 1177 /* COLOR TFT PALLETTIZED (use RGB 565) */
1178 value = (red & 0xF800)|((green >> 5) & 1178 value = (red & 0xF800)|((green >> 5) &
1179 0x07E0)|((blue >> 11) & 0x001F); 1179 0x07E0)|((blue >> 11) & 0x001F);
1180 value &= 0xFFFF; 1180 value &= 0xFFFF;
1181 1181
1182 } else if (0 /*panel_is_color(fbdev->panel)*/) { 1182 } else if (0 /*panel_is_color(fbdev->panel)*/) {
1183 /* COLOR STN MODE */ 1183 /* COLOR STN MODE */
1184 value = 0x1234; 1184 value = 0x1234;
1185 value &= 0xFFF; 1185 value &= 0xFFF;
1186 } else { 1186 } else {
1187 /* MONOCHROME MODE */ 1187 /* MONOCHROME MODE */
1188 value = (green >> 12) & 0x000F; 1188 value = (green >> 12) & 0x000F;
1189 value &= 0xF; 1189 value &= 0xF;
1190 } 1190 }
1191 1191
1192 palette[regno] = value; 1192 palette[regno] = value;
1193 1193
1194 return 0; 1194 return 0;
1195 } 1195 }
1196 1196
1197 /* fb_blank 1197 /* fb_blank
1198 * Blank the screen. Depending on the mode, the screen will be 1198 * Blank the screen. Depending on the mode, the screen will be
1199 * activated with the backlight color, or desactivated 1199 * activated with the backlight color, or desactivated
1200 */ 1200 */
1201 static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) 1201 static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
1202 { 1202 {
1203 struct au1200fb_device *fbdev = fbi->par; 1203 struct au1200fb_device *fbdev = fbi->par;
1204 1204
1205 /* Short-circuit screen blanking */ 1205 /* Short-circuit screen blanking */
1206 if (noblanking) 1206 if (noblanking)
1207 return 0; 1207 return 0;
1208 1208
1209 switch (blank_mode) { 1209 switch (blank_mode) {
1210 1210
1211 case FB_BLANK_UNBLANK: 1211 case FB_BLANK_UNBLANK:
1212 case FB_BLANK_NORMAL: 1212 case FB_BLANK_NORMAL:
1213 /* printk("turn on panel\n"); */ 1213 /* printk("turn on panel\n"); */
1214 au1200_setpanel(panel, fbdev->pd); 1214 au1200_setpanel(panel, fbdev->pd);
1215 break; 1215 break;
1216 case FB_BLANK_VSYNC_SUSPEND: 1216 case FB_BLANK_VSYNC_SUSPEND:
1217 case FB_BLANK_HSYNC_SUSPEND: 1217 case FB_BLANK_HSYNC_SUSPEND:
1218 case FB_BLANK_POWERDOWN: 1218 case FB_BLANK_POWERDOWN:
1219 /* printk("turn off panel\n"); */ 1219 /* printk("turn off panel\n"); */
1220 au1200_setpanel(NULL, fbdev->pd); 1220 au1200_setpanel(NULL, fbdev->pd);
1221 break; 1221 break;
1222 default: 1222 default:
1223 break; 1223 break;
1224 1224
1225 } 1225 }
1226 1226
1227 /* FB_BLANK_NORMAL is a soft blank */ 1227 /* FB_BLANK_NORMAL is a soft blank */
1228 return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0; 1228 return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
1229 } 1229 }
1230 1230
1231 /* fb_mmap 1231 /* fb_mmap
1232 * Map video memory in user space. We don't use the generic fb_mmap 1232 * Map video memory in user space. We don't use the generic fb_mmap
1233 * method mainly to allow the use of the TLB streaming flag (CCA=6) 1233 * method mainly to allow the use of the TLB streaming flag (CCA=6)
1234 */ 1234 */
1235 static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 1235 static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1236 1236
1237 { 1237 {
1238 unsigned int len; 1238 unsigned int len;
1239 unsigned long start=0, off; 1239 unsigned long start=0, off;
1240 struct au1200fb_device *fbdev = info->par; 1240 struct au1200fb_device *fbdev = info->par;
1241 1241
1242 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { 1242 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
1243 return -EINVAL; 1243 return -EINVAL;
1244 } 1244 }
1245 1245
1246 start = fbdev->fb_phys & PAGE_MASK; 1246 start = fbdev->fb_phys & PAGE_MASK;
1247 len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); 1247 len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
1248 1248
1249 off = vma->vm_pgoff << PAGE_SHIFT; 1249 off = vma->vm_pgoff << PAGE_SHIFT;
1250 1250
1251 if ((vma->vm_end - vma->vm_start + off) > len) { 1251 if ((vma->vm_end - vma->vm_start + off) > len) {
1252 return -EINVAL; 1252 return -EINVAL;
1253 } 1253 }
1254 1254
1255 off += start; 1255 off += start;
1256 vma->vm_pgoff = off >> PAGE_SHIFT; 1256 vma->vm_pgoff = off >> PAGE_SHIFT;
1257 1257
1258 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1258 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1259 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ 1259 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
1260 1260
1261 vma->vm_flags |= VM_IO;
1262
1263 return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1261 return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1264 vma->vm_end - vma->vm_start, 1262 vma->vm_end - vma->vm_start,
1265 vma->vm_page_prot); 1263 vma->vm_page_prot);
1266
1267 return 0;
1268 } 1264 }
1269 1265
1270 static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) 1266 static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
1271 { 1267 {
1272 1268
1273 unsigned int hi1, divider; 1269 unsigned int hi1, divider;
1274 1270
1275 /* SCREEN_SIZE: user cannot reset size, must switch panel choice */ 1271 /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
1276 1272
1277 if (pdata->flags & SCREEN_BACKCOLOR) 1273 if (pdata->flags & SCREEN_BACKCOLOR)
1278 lcd->backcolor = pdata->backcolor; 1274 lcd->backcolor = pdata->backcolor;
1279 1275
1280 if (pdata->flags & SCREEN_BRIGHTNESS) { 1276 if (pdata->flags & SCREEN_BRIGHTNESS) {
1281 1277
1282 // limit brightness pwm duty to >= 30/1600 1278 // limit brightness pwm duty to >= 30/1600
1283 if (pdata->brightness < 30) { 1279 if (pdata->brightness < 30) {
1284 pdata->brightness = 30; 1280 pdata->brightness = 30;
1285 } 1281 }
1286 divider = (lcd->pwmdiv & 0x3FFFF) + 1; 1282 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
1287 hi1 = (lcd->pwmhi >> 16) + 1; 1283 hi1 = (lcd->pwmhi >> 16) + 1;
1288 hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8); 1284 hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
1289 lcd->pwmhi &= 0xFFFF; 1285 lcd->pwmhi &= 0xFFFF;
1290 lcd->pwmhi |= (hi1 << 16); 1286 lcd->pwmhi |= (hi1 << 16);
1291 } 1287 }
1292 1288
1293 if (pdata->flags & SCREEN_COLORKEY) 1289 if (pdata->flags & SCREEN_COLORKEY)
1294 lcd->colorkey = pdata->colorkey; 1290 lcd->colorkey = pdata->colorkey;
1295 1291
1296 if (pdata->flags & SCREEN_MASK) 1292 if (pdata->flags & SCREEN_MASK)
1297 lcd->colorkeymsk = pdata->mask; 1293 lcd->colorkeymsk = pdata->mask;
1298 au_sync(); 1294 au_sync();
1299 } 1295 }
1300 1296
1301 static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) 1297 static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
1302 { 1298 {
1303 unsigned int hi1, divider; 1299 unsigned int hi1, divider;
1304 1300
1305 pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1; 1301 pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
1306 pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1; 1302 pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
1307 1303
1308 pdata->backcolor = lcd->backcolor; 1304 pdata->backcolor = lcd->backcolor;
1309 pdata->colorkey = lcd->colorkey; 1305 pdata->colorkey = lcd->colorkey;
1310 pdata->mask = lcd->colorkeymsk; 1306 pdata->mask = lcd->colorkeymsk;
1311 1307
1312 // brightness 1308 // brightness
1313 hi1 = (lcd->pwmhi >> 16) + 1; 1309 hi1 = (lcd->pwmhi >> 16) + 1;
1314 divider = (lcd->pwmdiv & 0x3FFFF) + 1; 1310 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
1315 pdata->brightness = ((hi1 << 8) / divider) - 1; 1311 pdata->brightness = ((hi1 << 8) / divider) - 1;
1316 au_sync(); 1312 au_sync();
1317 } 1313 }
1318 1314
1319 static void set_window(unsigned int plane, 1315 static void set_window(unsigned int plane,
1320 struct au1200_lcd_window_regs_t *pdata) 1316 struct au1200_lcd_window_regs_t *pdata)
1321 { 1317 {
1322 unsigned int val, bpp; 1318 unsigned int val, bpp;
1323 1319
1324 /* Window control register 0 */ 1320 /* Window control register 0 */
1325 if (pdata->flags & WIN_POSITION) { 1321 if (pdata->flags & WIN_POSITION) {
1326 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX | 1322 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
1327 LCD_WINCTRL0_OY); 1323 LCD_WINCTRL0_OY);
1328 val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX); 1324 val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
1329 val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY); 1325 val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
1330 lcd->window[plane].winctrl0 = val; 1326 lcd->window[plane].winctrl0 = val;
1331 } 1327 }
1332 if (pdata->flags & WIN_ALPHA_COLOR) { 1328 if (pdata->flags & WIN_ALPHA_COLOR) {
1333 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A); 1329 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
1334 val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A); 1330 val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
1335 lcd->window[plane].winctrl0 = val; 1331 lcd->window[plane].winctrl0 = val;
1336 } 1332 }
1337 if (pdata->flags & WIN_ALPHA_MODE) { 1333 if (pdata->flags & WIN_ALPHA_MODE) {
1338 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN); 1334 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
1339 val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN); 1335 val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
1340 lcd->window[plane].winctrl0 = val; 1336 lcd->window[plane].winctrl0 = val;
1341 } 1337 }
1342 1338
1343 /* Window control register 1 */ 1339 /* Window control register 1 */
1344 if (pdata->flags & WIN_PRIORITY) { 1340 if (pdata->flags & WIN_PRIORITY) {
1345 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI); 1341 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
1346 val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI); 1342 val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
1347 lcd->window[plane].winctrl1 = val; 1343 lcd->window[plane].winctrl1 = val;
1348 } 1344 }
1349 if (pdata->flags & WIN_CHANNEL) { 1345 if (pdata->flags & WIN_CHANNEL) {
1350 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE); 1346 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
1351 val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE); 1347 val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
1352 lcd->window[plane].winctrl1 = val; 1348 lcd->window[plane].winctrl1 = val;
1353 } 1349 }
1354 if (pdata->flags & WIN_BUFFER_FORMAT) { 1350 if (pdata->flags & WIN_BUFFER_FORMAT) {
1355 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM); 1351 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
1356 val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM); 1352 val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
1357 lcd->window[plane].winctrl1 = val; 1353 lcd->window[plane].winctrl1 = val;
1358 } 1354 }
1359 if (pdata->flags & WIN_COLOR_ORDER) { 1355 if (pdata->flags & WIN_COLOR_ORDER) {
1360 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO); 1356 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
1361 val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO); 1357 val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
1362 lcd->window[plane].winctrl1 = val; 1358 lcd->window[plane].winctrl1 = val;
1363 } 1359 }
1364 if (pdata->flags & WIN_PIXEL_ORDER) { 1360 if (pdata->flags & WIN_PIXEL_ORDER) {
1365 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO); 1361 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
1366 val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO); 1362 val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
1367 lcd->window[plane].winctrl1 = val; 1363 lcd->window[plane].winctrl1 = val;
1368 } 1364 }
1369 if (pdata->flags & WIN_SIZE) { 1365 if (pdata->flags & WIN_SIZE) {
1370 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX | 1366 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
1371 LCD_WINCTRL1_SZY); 1367 LCD_WINCTRL1_SZY);
1372 val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX); 1368 val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
1373 val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY); 1369 val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
1374 lcd->window[plane].winctrl1 = val; 1370 lcd->window[plane].winctrl1 = val;
1375 /* program buffer line width */ 1371 /* program buffer line width */
1376 bpp = winbpp(val) / 8; 1372 bpp = winbpp(val) / 8;
1377 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX); 1373 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
1378 val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX); 1374 val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
1379 lcd->window[plane].winctrl2 = val; 1375 lcd->window[plane].winctrl2 = val;
1380 } 1376 }
1381 1377
1382 /* Window control register 2 */ 1378 /* Window control register 2 */
1383 if (pdata->flags & WIN_COLORKEY_MODE) { 1379 if (pdata->flags & WIN_COLORKEY_MODE) {
1384 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE); 1380 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
1385 val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE); 1381 val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
1386 lcd->window[plane].winctrl2 = val; 1382 lcd->window[plane].winctrl2 = val;
1387 } 1383 }
1388 if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) { 1384 if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
1389 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM); 1385 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
1390 val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM); 1386 val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
1391 lcd->window[plane].winctrl2 = val; 1387 lcd->window[plane].winctrl2 = val;
1392 } 1388 }
1393 if (pdata->flags & WIN_RAM_ARRAY_MODE) { 1389 if (pdata->flags & WIN_RAM_ARRAY_MODE) {
1394 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM); 1390 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
1395 val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM); 1391 val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
1396 lcd->window[plane].winctrl2 = val; 1392 lcd->window[plane].winctrl2 = val;
1397 } 1393 }
1398 1394
1399 /* Buffer line width programmed with WIN_SIZE */ 1395 /* Buffer line width programmed with WIN_SIZE */
1400 1396
1401 if (pdata->flags & WIN_BUFFER_SCALE) { 1397 if (pdata->flags & WIN_BUFFER_SCALE) {
1402 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX | 1398 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
1403 LCD_WINCTRL2_SCY); 1399 LCD_WINCTRL2_SCY);
1404 val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX); 1400 val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
1405 val |= ((pdata->ysize) & LCD_WINCTRL2_SCY); 1401 val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
1406 lcd->window[plane].winctrl2 = val; 1402 lcd->window[plane].winctrl2 = val;
1407 } 1403 }
1408 1404
1409 if (pdata->flags & WIN_ENABLE) { 1405 if (pdata->flags & WIN_ENABLE) {
1410 val = lcd->winenable; 1406 val = lcd->winenable;
1411 val &= ~(1<<plane); 1407 val &= ~(1<<plane);
1412 val |= (pdata->enable & 1) << plane; 1408 val |= (pdata->enable & 1) << plane;
1413 lcd->winenable = val; 1409 lcd->winenable = val;
1414 } 1410 }
1415 au_sync(); 1411 au_sync();
1416 } 1412 }
1417 1413
1418 static void get_window(unsigned int plane, 1414 static void get_window(unsigned int plane,
1419 struct au1200_lcd_window_regs_t *pdata) 1415 struct au1200_lcd_window_regs_t *pdata)
1420 { 1416 {
1421 /* Window control register 0 */ 1417 /* Window control register 0 */
1422 pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21; 1418 pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
1423 pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10; 1419 pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
1424 pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2; 1420 pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
1425 pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1; 1421 pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
1426 1422
1427 /* Window control register 1 */ 1423 /* Window control register 1 */
1428 pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30; 1424 pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
1429 pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29; 1425 pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
1430 pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25; 1426 pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1431 pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24; 1427 pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
1432 pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22; 1428 pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
1433 pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1; 1429 pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
1434 pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1; 1430 pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
1435 1431
1436 /* Window control register 2 */ 1432 /* Window control register 2 */
1437 pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24; 1433 pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
1438 pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23; 1434 pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
1439 pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; 1435 pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
1440 1436
1441 pdata->enable = (lcd->winenable >> plane) & 1; 1437 pdata->enable = (lcd->winenable >> plane) & 1;
1442 au_sync(); 1438 au_sync();
1443 } 1439 }
1444 1440
1445 static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, 1441 static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
1446 unsigned long arg) 1442 unsigned long arg)
1447 { 1443 {
1448 struct au1200fb_device *fbdev = info->par; 1444 struct au1200fb_device *fbdev = info->par;
1449 int plane; 1445 int plane;
1450 int val; 1446 int val;
1451 1447
1452 plane = fbinfo2index(info); 1448 plane = fbinfo2index(info);
1453 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane); 1449 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
1454 1450
1455 if (cmd == AU1200_LCD_FB_IOCTL) { 1451 if (cmd == AU1200_LCD_FB_IOCTL) {
1456 struct au1200_lcd_iodata_t iodata; 1452 struct au1200_lcd_iodata_t iodata;
1457 1453
1458 if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata))) 1454 if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
1459 return -EFAULT; 1455 return -EFAULT;
1460 1456
1461 print_dbg("FB IOCTL called\n"); 1457 print_dbg("FB IOCTL called\n");
1462 1458
1463 switch (iodata.subcmd) { 1459 switch (iodata.subcmd) {
1464 case AU1200_LCD_SET_SCREEN: 1460 case AU1200_LCD_SET_SCREEN:
1465 print_dbg("AU1200_LCD_SET_SCREEN\n"); 1461 print_dbg("AU1200_LCD_SET_SCREEN\n");
1466 set_global(cmd, &iodata.global); 1462 set_global(cmd, &iodata.global);
1467 break; 1463 break;
1468 1464
1469 case AU1200_LCD_GET_SCREEN: 1465 case AU1200_LCD_GET_SCREEN:
1470 print_dbg("AU1200_LCD_GET_SCREEN\n"); 1466 print_dbg("AU1200_LCD_GET_SCREEN\n");
1471 get_global(cmd, &iodata.global); 1467 get_global(cmd, &iodata.global);
1472 break; 1468 break;
1473 1469
1474 case AU1200_LCD_SET_WINDOW: 1470 case AU1200_LCD_SET_WINDOW:
1475 print_dbg("AU1200_LCD_SET_WINDOW\n"); 1471 print_dbg("AU1200_LCD_SET_WINDOW\n");
1476 set_window(plane, &iodata.window); 1472 set_window(plane, &iodata.window);
1477 break; 1473 break;
1478 1474
1479 case AU1200_LCD_GET_WINDOW: 1475 case AU1200_LCD_GET_WINDOW:
1480 print_dbg("AU1200_LCD_GET_WINDOW\n"); 1476 print_dbg("AU1200_LCD_GET_WINDOW\n");
1481 get_window(plane, &iodata.window); 1477 get_window(plane, &iodata.window);
1482 break; 1478 break;
1483 1479
1484 case AU1200_LCD_SET_PANEL: 1480 case AU1200_LCD_SET_PANEL:
1485 print_dbg("AU1200_LCD_SET_PANEL\n"); 1481 print_dbg("AU1200_LCD_SET_PANEL\n");
1486 if ((iodata.global.panel_choice >= 0) && 1482 if ((iodata.global.panel_choice >= 0) &&
1487 (iodata.global.panel_choice < 1483 (iodata.global.panel_choice <
1488 NUM_PANELS)) 1484 NUM_PANELS))
1489 { 1485 {
1490 struct panel_settings *newpanel; 1486 struct panel_settings *newpanel;
1491 panel_index = iodata.global.panel_choice; 1487 panel_index = iodata.global.panel_choice;
1492 newpanel = &known_lcd_panels[panel_index]; 1488 newpanel = &known_lcd_panels[panel_index];
1493 au1200_setpanel(newpanel, fbdev->pd); 1489 au1200_setpanel(newpanel, fbdev->pd);
1494 } 1490 }
1495 break; 1491 break;
1496 1492
1497 case AU1200_LCD_GET_PANEL: 1493 case AU1200_LCD_GET_PANEL:
1498 print_dbg("AU1200_LCD_GET_PANEL\n"); 1494 print_dbg("AU1200_LCD_GET_PANEL\n");
1499 iodata.global.panel_choice = panel_index; 1495 iodata.global.panel_choice = panel_index;
1500 break; 1496 break;
1501 1497
1502 default: 1498 default:
1503 return -EINVAL; 1499 return -EINVAL;
1504 } 1500 }
1505 1501
1506 val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata)); 1502 val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
1507 if (val) { 1503 if (val) {
1508 print_dbg("error: could not copy %d bytes\n", val); 1504 print_dbg("error: could not copy %d bytes\n", val);
1509 return -EFAULT; 1505 return -EFAULT;
1510 } 1506 }
1511 } 1507 }
1512 1508
1513 return 0; 1509 return 0;
1514 } 1510 }
1515 1511
1516 1512
1517 static struct fb_ops au1200fb_fb_ops = { 1513 static struct fb_ops au1200fb_fb_ops = {
1518 .owner = THIS_MODULE, 1514 .owner = THIS_MODULE,
1519 .fb_check_var = au1200fb_fb_check_var, 1515 .fb_check_var = au1200fb_fb_check_var,
1520 .fb_set_par = au1200fb_fb_set_par, 1516 .fb_set_par = au1200fb_fb_set_par,
1521 .fb_setcolreg = au1200fb_fb_setcolreg, 1517 .fb_setcolreg = au1200fb_fb_setcolreg,
1522 .fb_blank = au1200fb_fb_blank, 1518 .fb_blank = au1200fb_fb_blank,
1523 .fb_fillrect = sys_fillrect, 1519 .fb_fillrect = sys_fillrect,
1524 .fb_copyarea = sys_copyarea, 1520 .fb_copyarea = sys_copyarea,
1525 .fb_imageblit = sys_imageblit, 1521 .fb_imageblit = sys_imageblit,
1526 .fb_read = fb_sys_read, 1522 .fb_read = fb_sys_read,
1527 .fb_write = fb_sys_write, 1523 .fb_write = fb_sys_write,
1528 .fb_sync = NULL, 1524 .fb_sync = NULL,
1529 .fb_ioctl = au1200fb_ioctl, 1525 .fb_ioctl = au1200fb_ioctl,
1530 .fb_mmap = au1200fb_fb_mmap, 1526 .fb_mmap = au1200fb_fb_mmap,
1531 }; 1527 };
1532 1528
1533 /*-------------------------------------------------------------------------*/ 1529 /*-------------------------------------------------------------------------*/
1534 1530
1535 static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) 1531 static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
1536 { 1532 {
1537 /* Nothing to do for now, just clear any pending interrupt */ 1533 /* Nothing to do for now, just clear any pending interrupt */
1538 lcd->intstatus = lcd->intstatus; 1534 lcd->intstatus = lcd->intstatus;
1539 au_sync(); 1535 au_sync();
1540 1536
1541 return IRQ_HANDLED; 1537 return IRQ_HANDLED;
1542 } 1538 }
1543 1539
1544 /*-------------------------------------------------------------------------*/ 1540 /*-------------------------------------------------------------------------*/
1545 1541
1546 /* AU1200 LCD device probe helpers */ 1542 /* AU1200 LCD device probe helpers */
1547 1543
1548 static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) 1544 static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1549 { 1545 {
1550 struct fb_info *fbi = fbdev->fb_info; 1546 struct fb_info *fbi = fbdev->fb_info;
1551 int bpp; 1547 int bpp;
1552 1548
1553 fbi->fbops = &au1200fb_fb_ops; 1549 fbi->fbops = &au1200fb_fb_ops;
1554 1550
1555 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1); 1551 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
1556 1552
1557 /* Copy monitor specs from panel data */ 1553 /* Copy monitor specs from panel data */
1558 /* fixme: we're setting up LCD controller windows, so these dont give a 1554 /* fixme: we're setting up LCD controller windows, so these dont give a
1559 damn as to what the monitor specs are (the panel itself does, but that 1555 damn as to what the monitor specs are (the panel itself does, but that
1560 isn't done here...so maybe need a generic catchall monitor setting??? */ 1556 isn't done here...so maybe need a generic catchall monitor setting??? */
1561 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs)); 1557 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
1562 1558
1563 /* We first try the user mode passed in argument. If that failed, 1559 /* We first try the user mode passed in argument. If that failed,
1564 * or if no one has been specified, we default to the first mode of the 1560 * or if no one has been specified, we default to the first mode of the
1565 * panel list. Note that after this call, var data will be set */ 1561 * panel list. Note that after this call, var data will be set */
1566 if (!fb_find_mode(&fbi->var, 1562 if (!fb_find_mode(&fbi->var,
1567 fbi, 1563 fbi,
1568 NULL, /* drv_info.opt_mode, */ 1564 NULL, /* drv_info.opt_mode, */
1569 fbi->monspecs.modedb, 1565 fbi->monspecs.modedb,
1570 fbi->monspecs.modedb_len, 1566 fbi->monspecs.modedb_len,
1571 fbi->monspecs.modedb, 1567 fbi->monspecs.modedb,
1572 bpp)) { 1568 bpp)) {
1573 1569
1574 print_err("Cannot find valid mode for panel %s", panel->name); 1570 print_err("Cannot find valid mode for panel %s", panel->name);
1575 return -EFAULT; 1571 return -EFAULT;
1576 } 1572 }
1577 1573
1578 fbi->pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL); 1574 fbi->pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL);
1579 if (!fbi->pseudo_palette) { 1575 if (!fbi->pseudo_palette) {
1580 return -ENOMEM; 1576 return -ENOMEM;
1581 } 1577 }
1582 1578
1583 if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { 1579 if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
1584 print_err("Fail to allocate colormap (%d entries)", 1580 print_err("Fail to allocate colormap (%d entries)",
1585 AU1200_LCD_NBR_PALETTE_ENTRIES); 1581 AU1200_LCD_NBR_PALETTE_ENTRIES);
1586 kfree(fbi->pseudo_palette); 1582 kfree(fbi->pseudo_palette);
1587 return -EFAULT; 1583 return -EFAULT;
1588 } 1584 }
1589 1585
1590 strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id)); 1586 strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
1591 fbi->fix.smem_start = fbdev->fb_phys; 1587 fbi->fix.smem_start = fbdev->fb_phys;
1592 fbi->fix.smem_len = fbdev->fb_len; 1588 fbi->fix.smem_len = fbdev->fb_len;
1593 fbi->fix.type = FB_TYPE_PACKED_PIXELS; 1589 fbi->fix.type = FB_TYPE_PACKED_PIXELS;
1594 fbi->fix.xpanstep = 0; 1590 fbi->fix.xpanstep = 0;
1595 fbi->fix.ypanstep = 0; 1591 fbi->fix.ypanstep = 0;
1596 fbi->fix.mmio_start = 0; 1592 fbi->fix.mmio_start = 0;
1597 fbi->fix.mmio_len = 0; 1593 fbi->fix.mmio_len = 0;
1598 fbi->fix.accel = FB_ACCEL_NONE; 1594 fbi->fix.accel = FB_ACCEL_NONE;
1599 1595
1600 fbi->screen_base = (char __iomem *) fbdev->fb_mem; 1596 fbi->screen_base = (char __iomem *) fbdev->fb_mem;
1601 1597
1602 au1200fb_update_fbinfo(fbi); 1598 au1200fb_update_fbinfo(fbi);
1603 1599
1604 return 0; 1600 return 0;
1605 } 1601 }
1606 1602
1607 /*-------------------------------------------------------------------------*/ 1603 /*-------------------------------------------------------------------------*/
1608 1604
1609 1605
1610 static int au1200fb_setup(struct au1200fb_platdata *pd) 1606 static int au1200fb_setup(struct au1200fb_platdata *pd)
1611 { 1607 {
1612 char *options = NULL; 1608 char *options = NULL;
1613 char *this_opt, *endptr; 1609 char *this_opt, *endptr;
1614 int num_panels = ARRAY_SIZE(known_lcd_panels); 1610 int num_panels = ARRAY_SIZE(known_lcd_panels);
1615 int panel_idx = -1; 1611 int panel_idx = -1;
1616 1612
1617 fb_get_options(DRIVER_NAME, &options); 1613 fb_get_options(DRIVER_NAME, &options);
1618 1614
1619 if (!options) 1615 if (!options)
1620 goto out; 1616 goto out;
1621 1617
1622 while ((this_opt = strsep(&options, ",")) != NULL) { 1618 while ((this_opt = strsep(&options, ",")) != NULL) {
1623 /* Panel option - can be panel name, 1619 /* Panel option - can be panel name,
1624 * "bs" for board-switch, or number/index */ 1620 * "bs" for board-switch, or number/index */
1625 if (!strncmp(this_opt, "panel:", 6)) { 1621 if (!strncmp(this_opt, "panel:", 6)) {
1626 int i; 1622 int i;
1627 long int li; 1623 long int li;
1628 char *endptr; 1624 char *endptr;
1629 this_opt += 6; 1625 this_opt += 6;
1630 /* First check for index, which allows 1626 /* First check for index, which allows
1631 * to short circuit this mess */ 1627 * to short circuit this mess */
1632 li = simple_strtol(this_opt, &endptr, 0); 1628 li = simple_strtol(this_opt, &endptr, 0);
1633 if (*endptr == '\0') 1629 if (*endptr == '\0')
1634 panel_idx = (int)li; 1630 panel_idx = (int)li;
1635 else if (strcmp(this_opt, "bs") == 0) 1631 else if (strcmp(this_opt, "bs") == 0)
1636 panel_idx = pd->panel_index(); 1632 panel_idx = pd->panel_index();
1637 else { 1633 else {
1638 for (i = 0; i < num_panels; i++) { 1634 for (i = 0; i < num_panels; i++) {
1639 if (!strcmp(this_opt, 1635 if (!strcmp(this_opt,
1640 known_lcd_panels[i].name)) { 1636 known_lcd_panels[i].name)) {
1641 panel_idx = i; 1637 panel_idx = i;
1642 break; 1638 break;
1643 } 1639 }
1644 } 1640 }
1645 } 1641 }
1646 if ((panel_idx < 0) || (panel_idx >= num_panels)) 1642 if ((panel_idx < 0) || (panel_idx >= num_panels))
1647 print_warn("Panel %s not supported!", this_opt); 1643 print_warn("Panel %s not supported!", this_opt);
1648 else 1644 else
1649 panel_index = panel_idx; 1645 panel_index = panel_idx;
1650 1646
1651 } else if (strncmp(this_opt, "nohwcursor", 10) == 0) 1647 } else if (strncmp(this_opt, "nohwcursor", 10) == 0)
1652 nohwcursor = 1; 1648 nohwcursor = 1;
1653 else if (strncmp(this_opt, "devices:", 8) == 0) { 1649 else if (strncmp(this_opt, "devices:", 8) == 0) {
1654 this_opt += 8; 1650 this_opt += 8;
1655 device_count = simple_strtol(this_opt, &endptr, 0); 1651 device_count = simple_strtol(this_opt, &endptr, 0);
1656 if ((device_count < 0) || 1652 if ((device_count < 0) ||
1657 (device_count > MAX_DEVICE_COUNT)) 1653 (device_count > MAX_DEVICE_COUNT))
1658 device_count = MAX_DEVICE_COUNT; 1654 device_count = MAX_DEVICE_COUNT;
1659 } else if (strncmp(this_opt, "wincfg:", 7) == 0) { 1655 } else if (strncmp(this_opt, "wincfg:", 7) == 0) {
1660 this_opt += 7; 1656 this_opt += 7;
1661 window_index = simple_strtol(this_opt, &endptr, 0); 1657 window_index = simple_strtol(this_opt, &endptr, 0);
1662 if ((window_index < 0) || 1658 if ((window_index < 0) ||
1663 (window_index >= ARRAY_SIZE(windows))) 1659 (window_index >= ARRAY_SIZE(windows)))
1664 window_index = DEFAULT_WINDOW_INDEX; 1660 window_index = DEFAULT_WINDOW_INDEX;
1665 } else if (strncmp(this_opt, "off", 3) == 0) 1661 } else if (strncmp(this_opt, "off", 3) == 0)
1666 return 1; 1662 return 1;
1667 else 1663 else
1668 print_warn("Unsupported option \"%s\"", this_opt); 1664 print_warn("Unsupported option \"%s\"", this_opt);
1669 } 1665 }
1670 1666
1671 out: 1667 out:
1672 return 0; 1668 return 0;
1673 } 1669 }
1674 1670
1675 /* AU1200 LCD controller device driver */ 1671 /* AU1200 LCD controller device driver */
1676 static int au1200fb_drv_probe(struct platform_device *dev) 1672 static int au1200fb_drv_probe(struct platform_device *dev)
1677 { 1673 {
1678 struct au1200fb_device *fbdev; 1674 struct au1200fb_device *fbdev;
1679 struct au1200fb_platdata *pd; 1675 struct au1200fb_platdata *pd;
1680 struct fb_info *fbi = NULL; 1676 struct fb_info *fbi = NULL;
1681 unsigned long page; 1677 unsigned long page;
1682 int bpp, plane, ret, irq; 1678 int bpp, plane, ret, irq;
1683 1679
1684 print_info("" DRIVER_DESC ""); 1680 print_info("" DRIVER_DESC "");
1685 1681
1686 pd = dev->dev.platform_data; 1682 pd = dev->dev.platform_data;
1687 if (!pd) 1683 if (!pd)
1688 return -ENODEV; 1684 return -ENODEV;
1689 1685
1690 /* Setup driver with options */ 1686 /* Setup driver with options */
1691 if (au1200fb_setup(pd)) 1687 if (au1200fb_setup(pd))
1692 return -ENODEV; 1688 return -ENODEV;
1693 1689
1694 /* Point to the panel selected */ 1690 /* Point to the panel selected */
1695 panel = &known_lcd_panels[panel_index]; 1691 panel = &known_lcd_panels[panel_index];
1696 win = &windows[window_index]; 1692 win = &windows[window_index];
1697 1693
1698 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); 1694 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
1699 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); 1695 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
1700 1696
1701 /* shut gcc up */ 1697 /* shut gcc up */
1702 ret = 0; 1698 ret = 0;
1703 fbdev = NULL; 1699 fbdev = NULL;
1704 1700
1705 for (plane = 0; plane < device_count; ++plane) { 1701 for (plane = 0; plane < device_count; ++plane) {
1706 bpp = winbpp(win->w[plane].mode_winctrl1); 1702 bpp = winbpp(win->w[plane].mode_winctrl1);
1707 if (win->w[plane].xres == 0) 1703 if (win->w[plane].xres == 0)
1708 win->w[plane].xres = panel->Xres; 1704 win->w[plane].xres = panel->Xres;
1709 if (win->w[plane].yres == 0) 1705 if (win->w[plane].yres == 0)
1710 win->w[plane].yres = panel->Yres; 1706 win->w[plane].yres = panel->Yres;
1711 1707
1712 fbi = framebuffer_alloc(sizeof(struct au1200fb_device), 1708 fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
1713 &dev->dev); 1709 &dev->dev);
1714 if (!fbi) 1710 if (!fbi)
1715 goto failed; 1711 goto failed;
1716 1712
1717 _au1200fb_infos[plane] = fbi; 1713 _au1200fb_infos[plane] = fbi;
1718 fbdev = fbi->par; 1714 fbdev = fbi->par;
1719 fbdev->fb_info = fbi; 1715 fbdev->fb_info = fbi;
1720 fbdev->pd = pd; 1716 fbdev->pd = pd;
1721 1717
1722 fbdev->plane = plane; 1718 fbdev->plane = plane;
1723 1719
1724 /* Allocate the framebuffer to the maximum screen size */ 1720 /* Allocate the framebuffer to the maximum screen size */
1725 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; 1721 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
1726 1722
1727 fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, 1723 fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev,
1728 PAGE_ALIGN(fbdev->fb_len), 1724 PAGE_ALIGN(fbdev->fb_len),
1729 &fbdev->fb_phys, GFP_KERNEL); 1725 &fbdev->fb_phys, GFP_KERNEL);
1730 if (!fbdev->fb_mem) { 1726 if (!fbdev->fb_mem) {
1731 print_err("fail to allocate frambuffer (size: %dK))", 1727 print_err("fail to allocate frambuffer (size: %dK))",
1732 fbdev->fb_len / 1024); 1728 fbdev->fb_len / 1024);
1733 return -ENOMEM; 1729 return -ENOMEM;
1734 } 1730 }
1735 1731
1736 /* 1732 /*
1737 * Set page reserved so that mmap will work. This is necessary 1733 * Set page reserved so that mmap will work. This is necessary
1738 * since we'll be remapping normal memory. 1734 * since we'll be remapping normal memory.
1739 */ 1735 */
1740 for (page = (unsigned long)fbdev->fb_phys; 1736 for (page = (unsigned long)fbdev->fb_phys;
1741 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys + 1737 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
1742 fbdev->fb_len); 1738 fbdev->fb_len);
1743 page += PAGE_SIZE) { 1739 page += PAGE_SIZE) {
1744 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */ 1740 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
1745 } 1741 }
1746 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); 1742 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
1747 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); 1743 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
1748 1744
1749 /* Init FB data */ 1745 /* Init FB data */
1750 if ((ret = au1200fb_init_fbinfo(fbdev)) < 0) 1746 if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
1751 goto failed; 1747 goto failed;
1752 1748
1753 /* Register new framebuffer */ 1749 /* Register new framebuffer */
1754 ret = register_framebuffer(fbi); 1750 ret = register_framebuffer(fbi);
1755 if (ret < 0) { 1751 if (ret < 0) {
1756 print_err("cannot register new framebuffer"); 1752 print_err("cannot register new framebuffer");
1757 goto failed; 1753 goto failed;
1758 } 1754 }
1759 1755
1760 au1200fb_fb_set_par(fbi); 1756 au1200fb_fb_set_par(fbi);
1761 1757
1762 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) 1758 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
1763 if (plane == 0) 1759 if (plane == 0)
1764 if (fb_prepare_logo(fbi, FB_ROTATE_UR)) { 1760 if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
1765 /* Start display and show logo on boot */ 1761 /* Start display and show logo on boot */
1766 fb_set_cmap(&fbi->cmap, fbi); 1762 fb_set_cmap(&fbi->cmap, fbi);
1767 fb_show_logo(fbi, FB_ROTATE_UR); 1763 fb_show_logo(fbi, FB_ROTATE_UR);
1768 } 1764 }
1769 #endif 1765 #endif
1770 } 1766 }
1771 1767
1772 /* Now hook interrupt too */ 1768 /* Now hook interrupt too */
1773 irq = platform_get_irq(dev, 0); 1769 irq = platform_get_irq(dev, 0);
1774 ret = request_irq(irq, au1200fb_handle_irq, 1770 ret = request_irq(irq, au1200fb_handle_irq,
1775 IRQF_SHARED, "lcd", (void *)dev); 1771 IRQF_SHARED, "lcd", (void *)dev);
1776 if (ret) { 1772 if (ret) {
1777 print_err("fail to request interrupt line %d (err: %d)", 1773 print_err("fail to request interrupt line %d (err: %d)",
1778 irq, ret); 1774 irq, ret);
1779 goto failed; 1775 goto failed;
1780 } 1776 }
1781 1777
1782 platform_set_drvdata(dev, pd); 1778 platform_set_drvdata(dev, pd);
1783 1779
1784 /* Kickstart the panel */ 1780 /* Kickstart the panel */
1785 au1200_setpanel(panel, pd); 1781 au1200_setpanel(panel, pd);
1786 1782
1787 return 0; 1783 return 0;
1788 1784
1789 failed: 1785 failed:
1790 /* NOTE: This only does the current plane/window that failed; others are still active */ 1786 /* NOTE: This only does the current plane/window that failed; others are still active */
1791 if (fbi) { 1787 if (fbi) {
1792 if (fbi->cmap.len != 0) 1788 if (fbi->cmap.len != 0)
1793 fb_dealloc_cmap(&fbi->cmap); 1789 fb_dealloc_cmap(&fbi->cmap);
1794 kfree(fbi->pseudo_palette); 1790 kfree(fbi->pseudo_palette);
1795 } 1791 }
1796 if (plane == 0) 1792 if (plane == 0)
1797 free_irq(AU1200_LCD_INT, (void*)dev); 1793 free_irq(AU1200_LCD_INT, (void*)dev);
1798 return ret; 1794 return ret;
1799 } 1795 }
1800 1796
1801 static int au1200fb_drv_remove(struct platform_device *dev) 1797 static int au1200fb_drv_remove(struct platform_device *dev)
1802 { 1798 {
1803 struct au1200fb_platdata *pd = platform_get_drvdata(dev); 1799 struct au1200fb_platdata *pd = platform_get_drvdata(dev);
1804 struct au1200fb_device *fbdev; 1800 struct au1200fb_device *fbdev;
1805 struct fb_info *fbi; 1801 struct fb_info *fbi;
1806 int plane; 1802 int plane;
1807 1803
1808 /* Turn off the panel */ 1804 /* Turn off the panel */
1809 au1200_setpanel(NULL, pd); 1805 au1200_setpanel(NULL, pd);
1810 1806
1811 for (plane = 0; plane < device_count; ++plane) { 1807 for (plane = 0; plane < device_count; ++plane) {
1812 fbi = _au1200fb_infos[plane]; 1808 fbi = _au1200fb_infos[plane];
1813 fbdev = fbi->par; 1809 fbdev = fbi->par;
1814 1810
1815 /* Clean up all probe data */ 1811 /* Clean up all probe data */
1816 unregister_framebuffer(fbi); 1812 unregister_framebuffer(fbi);
1817 if (fbi->cmap.len != 0) 1813 if (fbi->cmap.len != 0)
1818 fb_dealloc_cmap(&fbi->cmap); 1814 fb_dealloc_cmap(&fbi->cmap);
1819 kfree(fbi->pseudo_palette); 1815 kfree(fbi->pseudo_palette);
1820 1816
1821 framebuffer_release(fbi); 1817 framebuffer_release(fbi);
1822 _au1200fb_infos[plane] = NULL; 1818 _au1200fb_infos[plane] = NULL;
1823 } 1819 }
1824 1820
1825 free_irq(platform_get_irq(dev, 0), (void *)dev); 1821 free_irq(platform_get_irq(dev, 0), (void *)dev);
1826 1822
1827 return 0; 1823 return 0;
1828 } 1824 }
1829 1825
1830 #ifdef CONFIG_PM 1826 #ifdef CONFIG_PM
1831 static int au1200fb_drv_suspend(struct device *dev) 1827 static int au1200fb_drv_suspend(struct device *dev)
1832 { 1828 {
1833 struct au1200fb_platdata *pd = dev_get_drvdata(dev); 1829 struct au1200fb_platdata *pd = dev_get_drvdata(dev);
1834 au1200_setpanel(NULL, pd); 1830 au1200_setpanel(NULL, pd);
1835 1831
1836 lcd->outmask = 0; 1832 lcd->outmask = 0;
1837 au_sync(); 1833 au_sync();
1838 1834
1839 return 0; 1835 return 0;
1840 } 1836 }
1841 1837
1842 static int au1200fb_drv_resume(struct device *dev) 1838 static int au1200fb_drv_resume(struct device *dev)
1843 { 1839 {
1844 struct au1200fb_platdata *pd = dev_get_drvdata(dev); 1840 struct au1200fb_platdata *pd = dev_get_drvdata(dev);
1845 struct fb_info *fbi; 1841 struct fb_info *fbi;
1846 int i; 1842 int i;
1847 1843
1848 /* Kickstart the panel */ 1844 /* Kickstart the panel */
1849 au1200_setpanel(panel, pd); 1845 au1200_setpanel(panel, pd);
1850 1846
1851 for (i = 0; i < device_count; i++) { 1847 for (i = 0; i < device_count; i++) {
1852 fbi = _au1200fb_infos[i]; 1848 fbi = _au1200fb_infos[i];
1853 au1200fb_fb_set_par(fbi); 1849 au1200fb_fb_set_par(fbi);
1854 } 1850 }
1855 1851
1856 return 0; 1852 return 0;
1857 } 1853 }
1858 1854
1859 static const struct dev_pm_ops au1200fb_pmops = { 1855 static const struct dev_pm_ops au1200fb_pmops = {
1860 .suspend = au1200fb_drv_suspend, 1856 .suspend = au1200fb_drv_suspend,
1861 .resume = au1200fb_drv_resume, 1857 .resume = au1200fb_drv_resume,
1862 .freeze = au1200fb_drv_suspend, 1858 .freeze = au1200fb_drv_suspend,
1863 .thaw = au1200fb_drv_resume, 1859 .thaw = au1200fb_drv_resume,
1864 }; 1860 };
1865 1861
1866 #define AU1200FB_PMOPS (&au1200fb_pmops) 1862 #define AU1200FB_PMOPS (&au1200fb_pmops)
1867 1863
1868 #else 1864 #else
1869 #define AU1200FB_PMOPS NULL 1865 #define AU1200FB_PMOPS NULL
1870 #endif /* CONFIG_PM */ 1866 #endif /* CONFIG_PM */
1871 1867
1872 static struct platform_driver au1200fb_driver = { 1868 static struct platform_driver au1200fb_driver = {
1873 .driver = { 1869 .driver = {
1874 .name = "au1200-lcd", 1870 .name = "au1200-lcd",
1875 .owner = THIS_MODULE, 1871 .owner = THIS_MODULE,
1876 .pm = AU1200FB_PMOPS, 1872 .pm = AU1200FB_PMOPS,
1877 }, 1873 },
1878 .probe = au1200fb_drv_probe, 1874 .probe = au1200fb_drv_probe,
1879 .remove = au1200fb_drv_remove, 1875 .remove = au1200fb_drv_remove,
1880 }; 1876 };
1881 1877
1882 /*-------------------------------------------------------------------------*/ 1878 /*-------------------------------------------------------------------------*/
1883 1879
1884 static int __init au1200fb_init(void) 1880 static int __init au1200fb_init(void)
1885 { 1881 {
1886 return platform_driver_register(&au1200fb_driver); 1882 return platform_driver_register(&au1200fb_driver);
1887 } 1883 }
1888 1884
1889 static void __exit au1200fb_cleanup(void) 1885 static void __exit au1200fb_cleanup(void)
1890 { 1886 {
1891 platform_driver_unregister(&au1200fb_driver); 1887 platform_driver_unregister(&au1200fb_driver);
1892 } 1888 }
1893 1889
1894 module_init(au1200fb_init); 1890 module_init(au1200fb_init);
1895 module_exit(au1200fb_cleanup); 1891 module_exit(au1200fb_cleanup);
1896 1892
1897 MODULE_DESCRIPTION(DRIVER_DESC); 1893 MODULE_DESCRIPTION(DRIVER_DESC);
1898 MODULE_LICENSE("GPL"); 1894 MODULE_LICENSE("GPL");
1899 1895