aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 21:17:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 21:17:02 -0400
commit9e4db1c3eed55c22328d8022c2c80adb3093833f (patch)
tree9643545e6bd182f1d3e19942f590a6a1e3198320 /drivers/video
parentde8856d2c11f562c60ed9340a83db4a4f829a6e6 (diff)
parentaae528d9a8ad79d4b21b1b723abc9447fdb0d200 (diff)
Merge branch 'platforms' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM platform updates from Russell King: "This covers platform stuff for platforms I have a direct interest in (iow, I have the hardware). Essentially: - as we no longer support any other Acorn platforms other than RiscPC anymore, we can collect all that code into mach-rpc. - convert Acorn expansion card stuff to use IRQ allocation functions, and get rid of NO_IRQ from there. - cleanups to the ebsa110 platform to move some private stuff out of its header files. - large amount of SA11x0 updates: - conversion of private DMA implementation to DMA engine support (this actually gives us greater flexibility in drivers over the old API.) - re-worked ucb1x00 updates - convert to genirq, remove sa11x0 dependencies, fix various minor issues - move platform specific sa11x0 framebuffer data into platform files in arch/arm instead of keeping this in the driver itself - update sa11x0 IrDA driver for DMA engine, and allow it to use DMA for SIR transmissions as well as FIR - rework sa1111 support for genirq, and irq allocation - fix sa1111 IRQ support so it works again - use sparse IRQ support After this, I have one more pull request remaining from my current set, which I think is going to be the most problematical as it generates 8 conflicts." Fixed up the trivial conflict in arch/arm/mach-rpc/Makefile as per Russell. * 'platforms' of git://git.linaro.org/people/rmk/linux-arm: (125 commits) ARM: 7343/1: sa11x0: convert to sparse IRQ ARM: 7342/2: sa1100: prepare for sparse irq conversion ARM: 7341/1: input: prepare jornada720 keyboard and ts for sa11x0 sparse irq ARM: 7340/1: rtc: sa1100: include mach/irqs.h instead of asm/irq.h ARM: sa11x0: remove unused DMA controller definitions ARM: sa11x0: remove old SoC private DMA driver USB: sa1111: add hcd .reset method USB: sa1111: add OHCI shutdown methods USB: sa1111: reorganize ohci-sa1111.c USB: sa1111: get rid of nasty printk(KERN_DEBUG "%s: ...", __FILE__) USB: sa1111: sparse and checkpatch cleanups ARM: sa11x0: don't static map sa1111 ARM: sa1111: use dev_err() rather than printk() ARM: sa1111: cleanup sub-device registration and unregistration ARM: sa1111: only setup DMA for DMA capable devices ARM: sa1111: register sa1111 devices with dmabounce in bus notifier ARM: sa1111: move USB interface register definitions to ohci-sa1111.c ARM: sa1111: move PCMCIA interface register definitions to sa1111_generic.c ARM: sa1111: move PS/2 interface register definitions to sa1111p2.c ARM: sa1111: delete unused physical GPIO register definitions ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/sa1100fb.c493
-rw-r--r--drivers/video/sa1100fb.h76
2 files changed, 154 insertions, 415 deletions
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 98d55d0e2da5..b6325848ad61 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -173,282 +173,48 @@
173#include <linux/init.h> 173#include <linux/init.h>
174#include <linux/ioport.h> 174#include <linux/ioport.h>
175#include <linux/cpufreq.h> 175#include <linux/cpufreq.h>
176#include <linux/gpio.h>
176#include <linux/platform_device.h> 177#include <linux/platform_device.h>
177#include <linux/dma-mapping.h> 178#include <linux/dma-mapping.h>
178#include <linux/mutex.h> 179#include <linux/mutex.h>
179#include <linux/io.h> 180#include <linux/io.h>
180 181
182#include <video/sa1100fb.h>
183
181#include <mach/hardware.h> 184#include <mach/hardware.h>
182#include <asm/mach-types.h> 185#include <asm/mach-types.h>
183#include <mach/assabet.h>
184#include <mach/shannon.h> 186#include <mach/shannon.h>
185 187
186/* 188/*
187 * debugging?
188 */
189#define DEBUG 0
190/*
191 * Complain if VAR is out of range. 189 * Complain if VAR is out of range.
192 */ 190 */
193#define DEBUG_VAR 1 191#define DEBUG_VAR 1
194 192
195#undef ASSABET_PAL_VIDEO
196
197#include "sa1100fb.h" 193#include "sa1100fb.h"
198 194
199extern void (*sa1100fb_backlight_power)(int on); 195static const struct sa1100fb_rgb rgb_4 = {
200extern void (*sa1100fb_lcd_power)(int on);
201
202static struct sa1100fb_rgb rgb_4 = {
203 .red = { .offset = 0, .length = 4, }, 196 .red = { .offset = 0, .length = 4, },
204 .green = { .offset = 0, .length = 4, }, 197 .green = { .offset = 0, .length = 4, },
205 .blue = { .offset = 0, .length = 4, }, 198 .blue = { .offset = 0, .length = 4, },
206 .transp = { .offset = 0, .length = 0, }, 199 .transp = { .offset = 0, .length = 0, },
207}; 200};
208 201
209static struct sa1100fb_rgb rgb_8 = { 202static const struct sa1100fb_rgb rgb_8 = {
210 .red = { .offset = 0, .length = 8, }, 203 .red = { .offset = 0, .length = 8, },
211 .green = { .offset = 0, .length = 8, }, 204 .green = { .offset = 0, .length = 8, },
212 .blue = { .offset = 0, .length = 8, }, 205 .blue = { .offset = 0, .length = 8, },
213 .transp = { .offset = 0, .length = 0, }, 206 .transp = { .offset = 0, .length = 0, },
214}; 207};
215 208
216static struct sa1100fb_rgb def_rgb_16 = { 209static const struct sa1100fb_rgb def_rgb_16 = {
217 .red = { .offset = 11, .length = 5, }, 210 .red = { .offset = 11, .length = 5, },
218 .green = { .offset = 5, .length = 6, }, 211 .green = { .offset = 5, .length = 6, },
219 .blue = { .offset = 0, .length = 5, }, 212 .blue = { .offset = 0, .length = 5, },
220 .transp = { .offset = 0, .length = 0, }, 213 .transp = { .offset = 0, .length = 0, },
221}; 214};
222 215
223#ifdef CONFIG_SA1100_ASSABET
224#ifndef ASSABET_PAL_VIDEO
225/*
226 * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually
227 * takes an RGB666 signal, but we provide it with an RGB565 signal
228 * instead (def_rgb_16).
229 */
230static struct sa1100fb_mach_info lq039q2ds54_info __initdata = {
231 .pixclock = 171521, .bpp = 16,
232 .xres = 320, .yres = 240,
233
234 .hsync_len = 5, .vsync_len = 1,
235 .left_margin = 61, .upper_margin = 3,
236 .right_margin = 9, .lower_margin = 0,
237
238 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
239
240 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
241 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
242};
243#else
244static struct sa1100fb_mach_info pal_info __initdata = {
245 .pixclock = 67797, .bpp = 16,
246 .xres = 640, .yres = 512,
247
248 .hsync_len = 64, .vsync_len = 6,
249 .left_margin = 125, .upper_margin = 70,
250 .right_margin = 115, .lower_margin = 36,
251
252 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
253 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
254};
255#endif
256#endif
257
258#ifdef CONFIG_SA1100_H3600
259static struct sa1100fb_mach_info h3600_info __initdata = {
260 .pixclock = 174757, .bpp = 16,
261 .xres = 320, .yres = 240,
262
263 .hsync_len = 3, .vsync_len = 3,
264 .left_margin = 12, .upper_margin = 10,
265 .right_margin = 17, .lower_margin = 1,
266
267 .cmap_static = 1,
268
269 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
270 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
271};
272
273static struct sa1100fb_rgb h3600_rgb_16 = {
274 .red = { .offset = 12, .length = 4, },
275 .green = { .offset = 7, .length = 4, },
276 .blue = { .offset = 1, .length = 4, },
277 .transp = { .offset = 0, .length = 0, },
278};
279#endif
280
281#ifdef CONFIG_SA1100_H3100
282static struct sa1100fb_mach_info h3100_info __initdata = {
283 .pixclock = 406977, .bpp = 4,
284 .xres = 320, .yres = 240,
285
286 .hsync_len = 26, .vsync_len = 41,
287 .left_margin = 4, .upper_margin = 0,
288 .right_margin = 4, .lower_margin = 0,
289
290 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
291 .cmap_greyscale = 1,
292 .cmap_inverse = 1,
293
294 .lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
295 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
296};
297#endif
298
299#ifdef CONFIG_SA1100_COLLIE
300static struct sa1100fb_mach_info collie_info __initdata = {
301 .pixclock = 171521, .bpp = 16,
302 .xres = 320, .yres = 240,
303
304 .hsync_len = 5, .vsync_len = 1,
305 .left_margin = 11, .upper_margin = 2,
306 .right_margin = 30, .lower_margin = 0,
307
308 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
309
310 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
311 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
312};
313#endif
314
315#ifdef LART_GREY_LCD
316static struct sa1100fb_mach_info lart_grey_info __initdata = {
317 .pixclock = 150000, .bpp = 4,
318 .xres = 320, .yres = 240,
319
320 .hsync_len = 1, .vsync_len = 1,
321 .left_margin = 4, .upper_margin = 0,
322 .right_margin = 2, .lower_margin = 0,
323
324 .cmap_greyscale = 1,
325 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
326
327 .lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
328 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
329};
330#endif
331#ifdef LART_COLOR_LCD
332static struct sa1100fb_mach_info lart_color_info __initdata = {
333 .pixclock = 150000, .bpp = 16,
334 .xres = 320, .yres = 240,
335
336 .hsync_len = 2, .vsync_len = 3,
337 .left_margin = 69, .upper_margin = 14,
338 .right_margin = 8, .lower_margin = 4,
339
340 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
341 .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
342};
343#endif
344#ifdef LART_VIDEO_OUT
345static struct sa1100fb_mach_info lart_video_info __initdata = {
346 .pixclock = 39721, .bpp = 16,
347 .xres = 640, .yres = 480,
348
349 .hsync_len = 95, .vsync_len = 2,
350 .left_margin = 40, .upper_margin = 32,
351 .right_margin = 24, .lower_margin = 11,
352
353 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
354
355 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
356 .lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
357};
358#endif
359
360#ifdef LART_KIT01_LCD
361static struct sa1100fb_mach_info lart_kit01_info __initdata = {
362 .pixclock = 63291, .bpp = 16,
363 .xres = 640, .yres = 480,
364
365 .hsync_len = 64, .vsync_len = 3,
366 .left_margin = 122, .upper_margin = 45,
367 .right_margin = 10, .lower_margin = 10,
368
369 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
370 .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg
371};
372#endif
373
374#ifdef CONFIG_SA1100_SHANNON
375static struct sa1100fb_mach_info shannon_info __initdata = {
376 .pixclock = 152500, .bpp = 8,
377 .xres = 640, .yres = 480,
378
379 .hsync_len = 4, .vsync_len = 3,
380 .left_margin = 2, .upper_margin = 0,
381 .right_margin = 1, .lower_margin = 0,
382
383 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
384
385 .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
386 .lccr3 = LCCR3_ACBsDiv(512),
387};
388#endif
389
390 216
391 217
392static struct sa1100fb_mach_info * __init
393sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
394{
395 struct sa1100fb_mach_info *inf = NULL;
396
397 /*
398 * R G B T
399 * default {11,5}, { 5,6}, { 0,5}, { 0,0}
400 * h3600 {12,4}, { 7,4}, { 1,4}, { 0,0}
401 * freebird { 8,4}, { 4,4}, { 0,4}, {12,4}
402 */
403#ifdef CONFIG_SA1100_ASSABET
404 if (machine_is_assabet()) {
405#ifndef ASSABET_PAL_VIDEO
406 inf = &lq039q2ds54_info;
407#else
408 inf = &pal_info;
409#endif
410 }
411#endif
412#ifdef CONFIG_SA1100_H3100
413 if (machine_is_h3100()) {
414 inf = &h3100_info;
415 }
416#endif
417#ifdef CONFIG_SA1100_H3600
418 if (machine_is_h3600()) {
419 inf = &h3600_info;
420 fbi->rgb[RGB_16] = &h3600_rgb_16;
421 }
422#endif
423#ifdef CONFIG_SA1100_COLLIE
424 if (machine_is_collie()) {
425 inf = &collie_info;
426 }
427#endif
428#ifdef CONFIG_SA1100_LART
429 if (machine_is_lart()) {
430#ifdef LART_GREY_LCD
431 inf = &lart_grey_info;
432#endif
433#ifdef LART_COLOR_LCD
434 inf = &lart_color_info;
435#endif
436#ifdef LART_VIDEO_OUT
437 inf = &lart_video_info;
438#endif
439#ifdef LART_KIT01_LCD
440 inf = &lart_kit01_info;
441#endif
442 }
443#endif
444#ifdef CONFIG_SA1100_SHANNON
445 if (machine_is_shannon()) {
446 inf = &shannon_info;
447 }
448#endif
449 return inf;
450}
451
452static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *); 218static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *);
453static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state); 219static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state);
454 220
@@ -533,7 +299,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
533 * is what you poke into the framebuffer to produce the 299 * is what you poke into the framebuffer to produce the
534 * colour you requested. 300 * colour you requested.
535 */ 301 */
536 if (fbi->cmap_inverse) { 302 if (fbi->inf->cmap_inverse) {
537 red = 0xffff - red; 303 red = 0xffff - red;
538 green = 0xffff - green; 304 green = 0xffff - green;
539 blue = 0xffff - blue; 305 blue = 0xffff - blue;
@@ -607,14 +373,14 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
607 var->xres = MIN_XRES; 373 var->xres = MIN_XRES;
608 if (var->yres < MIN_YRES) 374 if (var->yres < MIN_YRES)
609 var->yres = MIN_YRES; 375 var->yres = MIN_YRES;
610 if (var->xres > fbi->max_xres) 376 if (var->xres > fbi->inf->xres)
611 var->xres = fbi->max_xres; 377 var->xres = fbi->inf->xres;
612 if (var->yres > fbi->max_yres) 378 if (var->yres > fbi->inf->yres)
613 var->yres = fbi->max_yres; 379 var->yres = fbi->inf->yres;
614 var->xres_virtual = max(var->xres_virtual, var->xres); 380 var->xres_virtual = max(var->xres_virtual, var->xres);
615 var->yres_virtual = max(var->yres_virtual, var->yres); 381 var->yres_virtual = max(var->yres_virtual, var->yres);
616 382
617 DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); 383 dev_dbg(fbi->dev, "var->bits_per_pixel=%d\n", var->bits_per_pixel);
618 switch (var->bits_per_pixel) { 384 switch (var->bits_per_pixel) {
619 case 4: 385 case 4:
620 rgbidx = RGB_4; 386 rgbidx = RGB_4;
@@ -638,16 +404,16 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
638 var->blue = fbi->rgb[rgbidx]->blue; 404 var->blue = fbi->rgb[rgbidx]->blue;
639 var->transp = fbi->rgb[rgbidx]->transp; 405 var->transp = fbi->rgb[rgbidx]->transp;
640 406
641 DPRINTK("RGBT length = %d:%d:%d:%d\n", 407 dev_dbg(fbi->dev, "RGBT length = %d:%d:%d:%d\n",
642 var->red.length, var->green.length, var->blue.length, 408 var->red.length, var->green.length, var->blue.length,
643 var->transp.length); 409 var->transp.length);
644 410
645 DPRINTK("RGBT offset = %d:%d:%d:%d\n", 411 dev_dbg(fbi->dev, "RGBT offset = %d:%d:%d:%d\n",
646 var->red.offset, var->green.offset, var->blue.offset, 412 var->red.offset, var->green.offset, var->blue.offset,
647 var->transp.offset); 413 var->transp.offset);
648 414
649#ifdef CONFIG_CPU_FREQ 415#ifdef CONFIG_CPU_FREQ
650 printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n", 416 dev_dbg(fbi->dev, "dma period = %d ps, clock = %d kHz\n",
651 sa1100fb_display_dma_period(var), 417 sa1100fb_display_dma_period(var),
652 cpufreq_get(smp_processor_id())); 418 cpufreq_get(smp_processor_id()));
653#endif 419#endif
@@ -655,22 +421,10 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
655 return 0; 421 return 0;
656} 422}
657 423
658static inline void sa1100fb_set_truecolor(u_int is_true_color) 424static void sa1100fb_set_visual(struct sa1100fb_info *fbi, u32 visual)
659{ 425{
660 if (machine_is_assabet()) { 426 if (fbi->inf->set_visual)
661#if 1 // phase 4 or newer Assabet's 427 fbi->inf->set_visual(visual);
662 if (is_true_color)
663 ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
664 else
665 ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
666#else
667 // older Assabet's
668 if (is_true_color)
669 ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
670 else
671 ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
672#endif
673 }
674} 428}
675 429
676/* 430/*
@@ -683,11 +437,11 @@ static int sa1100fb_set_par(struct fb_info *info)
683 struct fb_var_screeninfo *var = &info->var; 437 struct fb_var_screeninfo *var = &info->var;
684 unsigned long palette_mem_size; 438 unsigned long palette_mem_size;
685 439
686 DPRINTK("set_par\n"); 440 dev_dbg(fbi->dev, "set_par\n");
687 441
688 if (var->bits_per_pixel == 16) 442 if (var->bits_per_pixel == 16)
689 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; 443 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
690 else if (!fbi->cmap_static) 444 else if (!fbi->inf->cmap_static)
691 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; 445 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
692 else { 446 else {
693 /* 447 /*
@@ -704,7 +458,7 @@ static int sa1100fb_set_par(struct fb_info *info)
704 458
705 palette_mem_size = fbi->palette_size * sizeof(u16); 459 palette_mem_size = fbi->palette_size * sizeof(u16);
706 460
707 DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); 461 dev_dbg(fbi->dev, "palette_mem_size = 0x%08lx\n", palette_mem_size);
708 462
709 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); 463 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
710 fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; 464 fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
@@ -712,7 +466,7 @@ static int sa1100fb_set_par(struct fb_info *info)
712 /* 466 /*
713 * Set (any) board control register to handle new color depth 467 * Set (any) board control register to handle new color depth
714 */ 468 */
715 sa1100fb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR); 469 sa1100fb_set_visual(fbi, fbi->fb.fix.visual);
716 sa1100fb_activate_var(var, fbi); 470 sa1100fb_activate_var(var, fbi);
717 471
718 return 0; 472 return 0;
@@ -728,7 +482,7 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
728 /* 482 /*
729 * Make sure the user isn't doing something stupid. 483 * Make sure the user isn't doing something stupid.
730 */ 484 */
731 if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->cmap_static)) 485 if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->inf->cmap_static))
732 return -EINVAL; 486 return -EINVAL;
733 487
734 return gen_set_cmap(cmap, kspc, con, info); 488 return gen_set_cmap(cmap, kspc, con, info);
@@ -775,7 +529,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
775 struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; 529 struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
776 int i; 530 int i;
777 531
778 DPRINTK("sa1100fb_blank: blank=%d\n", blank); 532 dev_dbg(fbi->dev, "sa1100fb_blank: blank=%d\n", blank);
779 533
780 switch (blank) { 534 switch (blank) {
781 case FB_BLANK_POWERDOWN: 535 case FB_BLANK_POWERDOWN:
@@ -863,43 +617,43 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
863 u_int half_screen_size, yres, pcd; 617 u_int half_screen_size, yres, pcd;
864 u_long flags; 618 u_long flags;
865 619
866 DPRINTK("Configuring SA1100 LCD\n"); 620 dev_dbg(fbi->dev, "Configuring SA1100 LCD\n");
867 621
868 DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n", 622 dev_dbg(fbi->dev, "var: xres=%d hslen=%d lm=%d rm=%d\n",
869 var->xres, var->hsync_len, 623 var->xres, var->hsync_len,
870 var->left_margin, var->right_margin); 624 var->left_margin, var->right_margin);
871 DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n", 625 dev_dbg(fbi->dev, "var: yres=%d vslen=%d um=%d bm=%d\n",
872 var->yres, var->vsync_len, 626 var->yres, var->vsync_len,
873 var->upper_margin, var->lower_margin); 627 var->upper_margin, var->lower_margin);
874 628
875#if DEBUG_VAR 629#if DEBUG_VAR
876 if (var->xres < 16 || var->xres > 1024) 630 if (var->xres < 16 || var->xres > 1024)
877 printk(KERN_ERR "%s: invalid xres %d\n", 631 dev_err(fbi->dev, "%s: invalid xres %d\n",
878 fbi->fb.fix.id, var->xres); 632 fbi->fb.fix.id, var->xres);
879 if (var->hsync_len < 1 || var->hsync_len > 64) 633 if (var->hsync_len < 1 || var->hsync_len > 64)
880 printk(KERN_ERR "%s: invalid hsync_len %d\n", 634 dev_err(fbi->dev, "%s: invalid hsync_len %d\n",
881 fbi->fb.fix.id, var->hsync_len); 635 fbi->fb.fix.id, var->hsync_len);
882 if (var->left_margin < 1 || var->left_margin > 255) 636 if (var->left_margin < 1 || var->left_margin > 255)
883 printk(KERN_ERR "%s: invalid left_margin %d\n", 637 dev_err(fbi->dev, "%s: invalid left_margin %d\n",
884 fbi->fb.fix.id, var->left_margin); 638 fbi->fb.fix.id, var->left_margin);
885 if (var->right_margin < 1 || var->right_margin > 255) 639 if (var->right_margin < 1 || var->right_margin > 255)
886 printk(KERN_ERR "%s: invalid right_margin %d\n", 640 dev_err(fbi->dev, "%s: invalid right_margin %d\n",
887 fbi->fb.fix.id, var->right_margin); 641 fbi->fb.fix.id, var->right_margin);
888 if (var->yres < 1 || var->yres > 1024) 642 if (var->yres < 1 || var->yres > 1024)
889 printk(KERN_ERR "%s: invalid yres %d\n", 643 dev_err(fbi->dev, "%s: invalid yres %d\n",
890 fbi->fb.fix.id, var->yres); 644 fbi->fb.fix.id, var->yres);
891 if (var->vsync_len < 1 || var->vsync_len > 64) 645 if (var->vsync_len < 1 || var->vsync_len > 64)
892 printk(KERN_ERR "%s: invalid vsync_len %d\n", 646 dev_err(fbi->dev, "%s: invalid vsync_len %d\n",
893 fbi->fb.fix.id, var->vsync_len); 647 fbi->fb.fix.id, var->vsync_len);
894 if (var->upper_margin < 0 || var->upper_margin > 255) 648 if (var->upper_margin < 0 || var->upper_margin > 255)
895 printk(KERN_ERR "%s: invalid upper_margin %d\n", 649 dev_err(fbi->dev, "%s: invalid upper_margin %d\n",
896 fbi->fb.fix.id, var->upper_margin); 650 fbi->fb.fix.id, var->upper_margin);
897 if (var->lower_margin < 0 || var->lower_margin > 255) 651 if (var->lower_margin < 0 || var->lower_margin > 255)
898 printk(KERN_ERR "%s: invalid lower_margin %d\n", 652 dev_err(fbi->dev, "%s: invalid lower_margin %d\n",
899 fbi->fb.fix.id, var->lower_margin); 653 fbi->fb.fix.id, var->lower_margin);
900#endif 654#endif
901 655
902 new_regs.lccr0 = fbi->lccr0 | 656 new_regs.lccr0 = fbi->inf->lccr0 |
903 LCCR0_LEN | LCCR0_LDM | LCCR0_BAM | 657 LCCR0_LEN | LCCR0_LDM | LCCR0_BAM |
904 LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0); 658 LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0);
905 659
@@ -914,7 +668,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
914 * the YRES parameter. 668 * the YRES parameter.
915 */ 669 */
916 yres = var->yres; 670 yres = var->yres;
917 if (fbi->lccr0 & LCCR0_Dual) 671 if (fbi->inf->lccr0 & LCCR0_Dual)
918 yres /= 2; 672 yres /= 2;
919 673
920 new_regs.lccr2 = 674 new_regs.lccr2 =
@@ -924,14 +678,14 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
924 LCCR2_EndFrmDel(var->lower_margin); 678 LCCR2_EndFrmDel(var->lower_margin);
925 679
926 pcd = get_pcd(var->pixclock, cpufreq_get(0)); 680 pcd = get_pcd(var->pixclock, cpufreq_get(0));
927 new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->lccr3 | 681 new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->inf->lccr3 |
928 (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | 682 (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
929 (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); 683 (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
930 684
931 DPRINTK("nlccr0 = 0x%08lx\n", new_regs.lccr0); 685 dev_dbg(fbi->dev, "nlccr0 = 0x%08lx\n", new_regs.lccr0);
932 DPRINTK("nlccr1 = 0x%08lx\n", new_regs.lccr1); 686 dev_dbg(fbi->dev, "nlccr1 = 0x%08lx\n", new_regs.lccr1);
933 DPRINTK("nlccr2 = 0x%08lx\n", new_regs.lccr2); 687 dev_dbg(fbi->dev, "nlccr2 = 0x%08lx\n", new_regs.lccr2);
934 DPRINTK("nlccr3 = 0x%08lx\n", new_regs.lccr3); 688 dev_dbg(fbi->dev, "nlccr3 = 0x%08lx\n", new_regs.lccr3);
935 689
936 half_screen_size = var->bits_per_pixel; 690 half_screen_size = var->bits_per_pixel;
937 half_screen_size = half_screen_size * var->xres * var->yres / 16; 691 half_screen_size = half_screen_size * var->xres * var->yres / 16;
@@ -951,9 +705,12 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
951 * Only update the registers if the controller is enabled 705 * Only update the registers if the controller is enabled
952 * and something has changed. 706 * and something has changed.
953 */ 707 */
954 if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) || 708 if (readl_relaxed(fbi->base + LCCR0) != fbi->reg_lccr0 ||
955 (LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) || 709 readl_relaxed(fbi->base + LCCR1) != fbi->reg_lccr1 ||
956 (DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2)) 710 readl_relaxed(fbi->base + LCCR2) != fbi->reg_lccr2 ||
711 readl_relaxed(fbi->base + LCCR3) != fbi->reg_lccr3 ||
712 readl_relaxed(fbi->base + DBAR1) != fbi->dbar1 ||
713 readl_relaxed(fbi->base + DBAR2) != fbi->dbar2)
957 sa1100fb_schedule_work(fbi, C_REENABLE); 714 sa1100fb_schedule_work(fbi, C_REENABLE);
958 715
959 return 0; 716 return 0;
@@ -967,18 +724,18 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
967 */ 724 */
968static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on) 725static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on)
969{ 726{
970 DPRINTK("backlight o%s\n", on ? "n" : "ff"); 727 dev_dbg(fbi->dev, "backlight o%s\n", on ? "n" : "ff");
971 728
972 if (sa1100fb_backlight_power) 729 if (fbi->inf->backlight_power)
973 sa1100fb_backlight_power(on); 730 fbi->inf->backlight_power(on);
974} 731}
975 732
976static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on) 733static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on)
977{ 734{
978 DPRINTK("LCD power o%s\n", on ? "n" : "ff"); 735 dev_dbg(fbi->dev, "LCD power o%s\n", on ? "n" : "ff");
979 736
980 if (sa1100fb_lcd_power) 737 if (fbi->inf->lcd_power)
981 sa1100fb_lcd_power(on); 738 fbi->inf->lcd_power(on);
982} 739}
983 740
984static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) 741static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
@@ -1008,14 +765,25 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
1008 } 765 }
1009 766
1010 if (mask) { 767 if (mask) {
768 unsigned long flags;
769
770 /*
771 * SA-1100 requires the GPIO direction register set
772 * appropriately for the alternate function. Hence
773 * we set it here via bitmask rather than excessive
774 * fiddling via the GPIO subsystem - and even then
775 * we'll still have to deal with GAFR.
776 */
777 local_irq_save(flags);
1011 GPDR |= mask; 778 GPDR |= mask;
1012 GAFR |= mask; 779 GAFR |= mask;
780 local_irq_restore(flags);
1013 } 781 }
1014} 782}
1015 783
1016static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) 784static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
1017{ 785{
1018 DPRINTK("Enabling LCD controller\n"); 786 dev_dbg(fbi->dev, "Enabling LCD controller\n");
1019 787
1020 /* 788 /*
1021 * Make sure the mode bits are present in the first palette entry 789 * Make sure the mode bits are present in the first palette entry
@@ -1024,43 +792,46 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
1024 fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var); 792 fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var);
1025 793
1026 /* Sequence from 11.7.10 */ 794 /* Sequence from 11.7.10 */
1027 LCCR3 = fbi->reg_lccr3; 795 writel_relaxed(fbi->reg_lccr3, fbi->base + LCCR3);
1028 LCCR2 = fbi->reg_lccr2; 796 writel_relaxed(fbi->reg_lccr2, fbi->base + LCCR2);
1029 LCCR1 = fbi->reg_lccr1; 797 writel_relaxed(fbi->reg_lccr1, fbi->base + LCCR1);
1030 LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN; 798 writel_relaxed(fbi->reg_lccr0 & ~LCCR0_LEN, fbi->base + LCCR0);
1031 DBAR1 = fbi->dbar1; 799 writel_relaxed(fbi->dbar1, fbi->base + DBAR1);
1032 DBAR2 = fbi->dbar2; 800 writel_relaxed(fbi->dbar2, fbi->base + DBAR2);
1033 LCCR0 |= LCCR0_LEN; 801 writel_relaxed(fbi->reg_lccr0 | LCCR0_LEN, fbi->base + LCCR0);
1034 802
1035 if (machine_is_shannon()) { 803 if (machine_is_shannon())
1036 GPDR |= SHANNON_GPIO_DISP_EN; 804 gpio_set_value(SHANNON_GPIO_DISP_EN, 1);
1037 GPSR |= SHANNON_GPIO_DISP_EN; 805
1038 } 806 dev_dbg(fbi->dev, "DBAR1: 0x%08x\n", readl_relaxed(fbi->base + DBAR1));
1039 807 dev_dbg(fbi->dev, "DBAR2: 0x%08x\n", readl_relaxed(fbi->base + DBAR2));
1040 DPRINTK("DBAR1 = 0x%08x\n", DBAR1); 808 dev_dbg(fbi->dev, "LCCR0: 0x%08x\n", readl_relaxed(fbi->base + LCCR0));
1041 DPRINTK("DBAR2 = 0x%08x\n", DBAR2); 809 dev_dbg(fbi->dev, "LCCR1: 0x%08x\n", readl_relaxed(fbi->base + LCCR1));
1042 DPRINTK("LCCR0 = 0x%08x\n", LCCR0); 810 dev_dbg(fbi->dev, "LCCR2: 0x%08x\n", readl_relaxed(fbi->base + LCCR2));
1043 DPRINTK("LCCR1 = 0x%08x\n", LCCR1); 811 dev_dbg(fbi->dev, "LCCR3: 0x%08x\n", readl_relaxed(fbi->base + LCCR3));
1044 DPRINTK("LCCR2 = 0x%08x\n", LCCR2);
1045 DPRINTK("LCCR3 = 0x%08x\n", LCCR3);
1046} 812}
1047 813
1048static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) 814static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
1049{ 815{
1050 DECLARE_WAITQUEUE(wait, current); 816 DECLARE_WAITQUEUE(wait, current);
817 u32 lccr0;
1051 818
1052 DPRINTK("Disabling LCD controller\n"); 819 dev_dbg(fbi->dev, "Disabling LCD controller\n");
1053 820
1054 if (machine_is_shannon()) { 821 if (machine_is_shannon())
1055 GPCR |= SHANNON_GPIO_DISP_EN; 822 gpio_set_value(SHANNON_GPIO_DISP_EN, 0);
1056 }
1057 823
1058 set_current_state(TASK_UNINTERRUPTIBLE); 824 set_current_state(TASK_UNINTERRUPTIBLE);
1059 add_wait_queue(&fbi->ctrlr_wait, &wait); 825 add_wait_queue(&fbi->ctrlr_wait, &wait);
1060 826
1061 LCSR = 0xffffffff; /* Clear LCD Status Register */ 827 /* Clear LCD Status Register */
1062 LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ 828 writel_relaxed(~0, fbi->base + LCSR);
1063 LCCR0 &= ~LCCR0_LEN; /* Disable LCD Controller */ 829
830 lccr0 = readl_relaxed(fbi->base + LCCR0);
831 lccr0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
832 writel_relaxed(lccr0, fbi->base + LCCR0);
833 lccr0 &= ~LCCR0_LEN; /* Disable LCD Controller */
834 writel_relaxed(lccr0, fbi->base + LCCR0);
1064 835
1065 schedule_timeout(20 * HZ / 1000); 836 schedule_timeout(20 * HZ / 1000);
1066 remove_wait_queue(&fbi->ctrlr_wait, &wait); 837 remove_wait_queue(&fbi->ctrlr_wait, &wait);
@@ -1072,14 +843,15 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
1072static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id) 843static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id)
1073{ 844{
1074 struct sa1100fb_info *fbi = dev_id; 845 struct sa1100fb_info *fbi = dev_id;
1075 unsigned int lcsr = LCSR; 846 unsigned int lcsr = readl_relaxed(fbi->base + LCSR);
1076 847
1077 if (lcsr & LCSR_LDD) { 848 if (lcsr & LCSR_LDD) {
1078 LCCR0 |= LCCR0_LDM; 849 u32 lccr0 = readl_relaxed(fbi->base + LCCR0) | LCCR0_LDM;
850 writel_relaxed(lccr0, fbi->base + LCCR0);
1079 wake_up(&fbi->ctrlr_wait); 851 wake_up(&fbi->ctrlr_wait);
1080 } 852 }
1081 853
1082 LCSR = lcsr; 854 writel_relaxed(lcsr, fbi->base + LCSR);
1083 return IRQ_HANDLED; 855 return IRQ_HANDLED;
1084} 856}
1085 857
@@ -1268,7 +1040,7 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
1268 switch (val) { 1040 switch (val) {
1269 case CPUFREQ_ADJUST: 1041 case CPUFREQ_ADJUST:
1270 case CPUFREQ_INCOMPATIBLE: 1042 case CPUFREQ_INCOMPATIBLE:
1271 printk(KERN_DEBUG "min dma period: %d ps, " 1043 dev_dbg(fbi->dev, "min dma period: %d ps, "
1272 "new clock %d kHz\n", sa1100fb_min_dma_period(fbi), 1044 "new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
1273 policy->max); 1045 policy->max);
1274 /* todo: fill in min/max values */ 1046 /* todo: fill in min/max values */
@@ -1318,7 +1090,7 @@ static int sa1100fb_resume(struct platform_device *dev)
1318 * cache. Once this area is remapped, all virtual memory 1090 * cache. Once this area is remapped, all virtual memory
1319 * access to the video memory should occur at the new region. 1091 * access to the video memory should occur at the new region.
1320 */ 1092 */
1321static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) 1093static int __devinit sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
1322{ 1094{
1323 /* 1095 /*
1324 * We reserve one page for the palette, plus the size 1096 * We reserve one page for the palette, plus the size
@@ -1344,7 +1116,7 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
1344} 1116}
1345 1117
1346/* Fake monspecs to fill in fbinfo structure */ 1118/* Fake monspecs to fill in fbinfo structure */
1347static struct fb_monspecs monspecs __initdata = { 1119static struct fb_monspecs monspecs __devinitdata = {
1348 .hfmin = 30000, 1120 .hfmin = 30000,
1349 .hfmax = 70000, 1121 .hfmax = 70000,
1350 .vfmin = 50, 1122 .vfmin = 50,
@@ -1352,10 +1124,11 @@ static struct fb_monspecs monspecs __initdata = {
1352}; 1124};
1353 1125
1354 1126
1355static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) 1127static struct sa1100fb_info * __devinit sa1100fb_init_fbinfo(struct device *dev)
1356{ 1128{
1357 struct sa1100fb_mach_info *inf; 1129 struct sa1100fb_mach_info *inf = dev->platform_data;
1358 struct sa1100fb_info *fbi; 1130 struct sa1100fb_info *fbi;
1131 unsigned i;
1359 1132
1360 fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16, 1133 fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16,
1361 GFP_KERNEL); 1134 GFP_KERNEL);
@@ -1390,8 +1163,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
1390 fbi->rgb[RGB_8] = &rgb_8; 1163 fbi->rgb[RGB_8] = &rgb_8;
1391 fbi->rgb[RGB_16] = &def_rgb_16; 1164 fbi->rgb[RGB_16] = &def_rgb_16;
1392 1165
1393 inf = sa1100fb_get_machine_info(fbi);
1394
1395 /* 1166 /*
1396 * People just don't seem to get this. We don't support 1167 * People just don't seem to get this. We don't support
1397 * anything but correct entries now, so panic if someone 1168 * anything but correct entries now, so panic if someone
@@ -1402,13 +1173,10 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
1402 panic("sa1100fb error: invalid LCCR3 fields set or zero " 1173 panic("sa1100fb error: invalid LCCR3 fields set or zero "
1403 "pixclock."); 1174 "pixclock.");
1404 1175
1405 fbi->max_xres = inf->xres;
1406 fbi->fb.var.xres = inf->xres; 1176 fbi->fb.var.xres = inf->xres;
1407 fbi->fb.var.xres_virtual = inf->xres; 1177 fbi->fb.var.xres_virtual = inf->xres;
1408 fbi->max_yres = inf->yres;
1409 fbi->fb.var.yres = inf->yres; 1178 fbi->fb.var.yres = inf->yres;
1410 fbi->fb.var.yres_virtual = inf->yres; 1179 fbi->fb.var.yres_virtual = inf->yres;
1411 fbi->max_bpp = inf->bpp;
1412 fbi->fb.var.bits_per_pixel = inf->bpp; 1180 fbi->fb.var.bits_per_pixel = inf->bpp;
1413 fbi->fb.var.pixclock = inf->pixclock; 1181 fbi->fb.var.pixclock = inf->pixclock;
1414 fbi->fb.var.hsync_len = inf->hsync_len; 1182 fbi->fb.var.hsync_len = inf->hsync_len;
@@ -1419,14 +1187,16 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
1419 fbi->fb.var.lower_margin = inf->lower_margin; 1187 fbi->fb.var.lower_margin = inf->lower_margin;
1420 fbi->fb.var.sync = inf->sync; 1188 fbi->fb.var.sync = inf->sync;
1421 fbi->fb.var.grayscale = inf->cmap_greyscale; 1189 fbi->fb.var.grayscale = inf->cmap_greyscale;
1422 fbi->cmap_inverse = inf->cmap_inverse;
1423 fbi->cmap_static = inf->cmap_static;
1424 fbi->lccr0 = inf->lccr0;
1425 fbi->lccr3 = inf->lccr3;
1426 fbi->state = C_STARTUP; 1190 fbi->state = C_STARTUP;
1427 fbi->task_state = (u_char)-1; 1191 fbi->task_state = (u_char)-1;
1428 fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * 1192 fbi->fb.fix.smem_len = inf->xres * inf->yres *
1429 fbi->max_bpp / 8; 1193 inf->bpp / 8;
1194 fbi->inf = inf;
1195
1196 /* Copy the RGB bitfield overrides */
1197 for (i = 0; i < NR_RGB; i++)
1198 if (inf->rgb[i])
1199 fbi->rgb[i] = inf->rgb[i];
1430 1200
1431 init_waitqueue_head(&fbi->ctrlr_wait); 1201 init_waitqueue_head(&fbi->ctrlr_wait);
1432 INIT_WORK(&fbi->task, sa1100fb_task); 1202 INIT_WORK(&fbi->task, sa1100fb_task);
@@ -1438,13 +1208,20 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
1438static int __devinit sa1100fb_probe(struct platform_device *pdev) 1208static int __devinit sa1100fb_probe(struct platform_device *pdev)
1439{ 1209{
1440 struct sa1100fb_info *fbi; 1210 struct sa1100fb_info *fbi;
1211 struct resource *res;
1441 int ret, irq; 1212 int ret, irq;
1442 1213
1214 if (!pdev->dev.platform_data) {
1215 dev_err(&pdev->dev, "no platform LCD data\n");
1216 return -EINVAL;
1217 }
1218
1219 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1443 irq = platform_get_irq(pdev, 0); 1220 irq = platform_get_irq(pdev, 0);
1444 if (irq < 0) 1221 if (irq < 0 || !res)
1445 return -EINVAL; 1222 return -EINVAL;
1446 1223
1447 if (!request_mem_region(0xb0100000, 0x10000, "LCD")) 1224 if (!request_mem_region(res->start, resource_size(res), "LCD"))
1448 return -EBUSY; 1225 return -EBUSY;
1449 1226
1450 fbi = sa1100fb_init_fbinfo(&pdev->dev); 1227 fbi = sa1100fb_init_fbinfo(&pdev->dev);
@@ -1452,6 +1229,10 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
1452 if (!fbi) 1229 if (!fbi)
1453 goto failed; 1230 goto failed;
1454 1231
1232 fbi->base = ioremap(res->start, resource_size(res));
1233 if (!fbi->base)
1234 goto failed;
1235
1455 /* Initialize video memory */ 1236 /* Initialize video memory */
1456 ret = sa1100fb_map_video_memory(fbi); 1237 ret = sa1100fb_map_video_memory(fbi);
1457 if (ret) 1238 if (ret)
@@ -1459,14 +1240,16 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
1459 1240
1460 ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi); 1241 ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi);
1461 if (ret) { 1242 if (ret) {
1462 printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); 1243 dev_err(&pdev->dev, "request_irq failed: %d\n", ret);
1463 goto failed; 1244 goto failed;
1464 } 1245 }
1465 1246
1466#ifdef ASSABET_PAL_VIDEO 1247 if (machine_is_shannon()) {
1467 if (machine_is_assabet()) 1248 ret = gpio_request_one(SHANNON_GPIO_DISP_EN,
1468 ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); 1249 GPIOF_OUT_INIT_LOW, "display enable");
1469#endif 1250 if (ret)
1251 goto err_free_irq;
1252 }
1470 1253
1471 /* 1254 /*
1472 * This makes sure that our colour bitfield 1255 * This makes sure that our colour bitfield
@@ -1478,7 +1261,7 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
1478 1261
1479 ret = register_framebuffer(&fbi->fb); 1262 ret = register_framebuffer(&fbi->fb);
1480 if (ret < 0) 1263 if (ret < 0)
1481 goto err_free_irq; 1264 goto err_reg_fb;
1482 1265
1483#ifdef CONFIG_CPU_FREQ 1266#ifdef CONFIG_CPU_FREQ
1484 fbi->freq_transition.notifier_call = sa1100fb_freq_transition; 1267 fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
@@ -1490,12 +1273,17 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
1490 /* This driver cannot be unloaded at the moment */ 1273 /* This driver cannot be unloaded at the moment */
1491 return 0; 1274 return 0;
1492 1275
1276 err_reg_fb:
1277 if (machine_is_shannon())
1278 gpio_free(SHANNON_GPIO_DISP_EN);
1493 err_free_irq: 1279 err_free_irq:
1494 free_irq(irq, fbi); 1280 free_irq(irq, fbi);
1495 failed: 1281 failed:
1282 if (fbi)
1283 iounmap(fbi->base);
1496 platform_set_drvdata(pdev, NULL); 1284 platform_set_drvdata(pdev, NULL);
1497 kfree(fbi); 1285 kfree(fbi);
1498 release_mem_region(0xb0100000, 0x10000); 1286 release_mem_region(res->start, resource_size(res));
1499 return ret; 1287 return ret;
1500} 1288}
1501 1289
@@ -1505,6 +1293,7 @@ static struct platform_driver sa1100fb_driver = {
1505 .resume = sa1100fb_resume, 1293 .resume = sa1100fb_resume,
1506 .driver = { 1294 .driver = {
1507 .name = "sa11x0-fb", 1295 .name = "sa11x0-fb",
1296 .owner = THIS_MODULE,
1508 }, 1297 },
1509}; 1298};
1510 1299
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index 1c3b459865d8..fc5d4292fad6 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -10,44 +10,15 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12 12
13/* 13#define LCCR0 0x0000 /* LCD Control Reg. 0 */
14 * These are the bitfields for each 14#define LCSR 0x0004 /* LCD Status Reg. */
15 * display depth that we support. 15#define DBAR1 0x0010 /* LCD DMA Base Address Reg. channel 1 */
16 */ 16#define DCAR1 0x0014 /* LCD DMA Current Address Reg. channel 1 */
17struct sa1100fb_rgb { 17#define DBAR2 0x0018 /* LCD DMA Base Address Reg. channel 2 */
18 struct fb_bitfield red; 18#define DCAR2 0x001C /* LCD DMA Current Address Reg. channel 2 */
19 struct fb_bitfield green; 19#define LCCR1 0x0020 /* LCD Control Reg. 1 */
20 struct fb_bitfield blue; 20#define LCCR2 0x0024 /* LCD Control Reg. 2 */
21 struct fb_bitfield transp; 21#define LCCR3 0x0028 /* LCD Control Reg. 3 */
22};
23
24/*
25 * This structure describes the machine which we are running on.
26 */
27struct sa1100fb_mach_info {
28 u_long pixclock;
29
30 u_short xres;
31 u_short yres;
32
33 u_char bpp;
34 u_char hsync_len;
35 u_char left_margin;
36 u_char right_margin;
37
38 u_char vsync_len;
39 u_char upper_margin;
40 u_char lower_margin;
41 u_char sync;
42
43 u_int cmap_greyscale:1,
44 cmap_inverse:1,
45 cmap_static:1,
46 unused:29;
47
48 u_int lccr0;
49 u_int lccr3;
50};
51 22
52/* Shadows for LCD controller registers */ 23/* Shadows for LCD controller registers */
53struct sa1100fb_lcd_reg { 24struct sa1100fb_lcd_reg {
@@ -57,19 +28,11 @@ struct sa1100fb_lcd_reg {
57 unsigned long lccr3; 28 unsigned long lccr3;
58}; 29};
59 30
60#define RGB_4 (0)
61#define RGB_8 (1)
62#define RGB_16 (2)
63#define NR_RGB 3
64
65struct sa1100fb_info { 31struct sa1100fb_info {
66 struct fb_info fb; 32 struct fb_info fb;
67 struct device *dev; 33 struct device *dev;
68 struct sa1100fb_rgb *rgb[NR_RGB]; 34 const struct sa1100fb_rgb *rgb[NR_RGB];
69 35 void __iomem *base;
70 u_int max_bpp;
71 u_int max_xres;
72 u_int max_yres;
73 36
74 /* 37 /*
75 * These are the addresses we mapped 38 * These are the addresses we mapped
@@ -88,12 +51,6 @@ struct sa1100fb_info {
88 dma_addr_t dbar1; 51 dma_addr_t dbar1;
89 dma_addr_t dbar2; 52 dma_addr_t dbar2;
90 53
91 u_int lccr0;
92 u_int lccr3;
93 u_int cmap_inverse:1,
94 cmap_static:1,
95 unused:30;
96
97 u_int reg_lccr0; 54 u_int reg_lccr0;
98 u_int reg_lccr1; 55 u_int reg_lccr1;
99 u_int reg_lccr2; 56 u_int reg_lccr2;
@@ -109,6 +66,8 @@ struct sa1100fb_info {
109 struct notifier_block freq_transition; 66 struct notifier_block freq_transition;
110 struct notifier_block freq_policy; 67 struct notifier_block freq_policy;
111#endif 68#endif
69
70 const struct sa1100fb_mach_info *inf;
112}; 71};
113 72
114#define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member) 73#define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member)
@@ -130,15 +89,6 @@ struct sa1100fb_info {
130#define SA1100_NAME "SA1100" 89#define SA1100_NAME "SA1100"
131 90
132/* 91/*
133 * Debug macros
134 */
135#if DEBUG
136# define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ## args)
137#else
138# define DPRINTK(fmt, args...)
139#endif
140
141/*
142 * Minimum X and Y resolutions 92 * Minimum X and Y resolutions
143 */ 93 */
144#define MIN_XRES 64 94#define MIN_XRES 64