[ARM] 3848/1: pxafb: Add option of fixing video modes and spitz QVGA mode support
authorRichard Purdie <rpurdie@net.rmk.(none)>
Wed, 20 Sep 2006 21:54:21 +0000 (22:54 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 2 Oct 2006 12:33:37 +0000 (13:33 +0100)
Add the ability to have pxafb use only certain fixed video modes
(selected on a per platform basis). This is useful on production
hardware such as the Zaurus cxx00 models where the valid modes are
known in advance and any other modes could result in hardware damage.

Following this, add support for the cxx00 QVGA mode. Mode information
is passed to the lcd_power call to allowing the panel drivers to
configure the display hardware accordingly (corgi_lcd already contains
the functionality for the cxx00 panel).

This mirrors the setup already used by w100fb.

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
13 files changed:
arch/arm/mach-pxa/corgi_lcd.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/trizeps4.c
drivers/video/pxafb.c
drivers/video/pxafb.h
include/asm-arm/arch-pxa/pxafb.h
include/asm-arm/arch-pxa/spitz.h

index 6dbcaf114ad782a00907b15672f9ae60aff0dfea..d7815491b752cb3e344bff363cb023c2adf7ea8c 100644 (file)
@@ -431,10 +431,10 @@ struct platform_device corgifb_device = {
 
 #include <asm/arch/pxafb.h>
 
-void spitz_lcd_power(int on)
+void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
 {
        if (on)
-               lcdtg_hw_init(480);
+               lcdtg_hw_init(var->xres);
        else
                lcdtg_suspend();
 }
index 5efa84749f374fae50ade0adfcb67c5b8bacf494..45fb2c3bcf828f3812adf0b95675d77256487c05 100644 (file)
@@ -204,13 +204,6 @@ static struct platform_device udc_device = {
        }
 };
 
-static struct pxafb_mach_info pxa_fb_info;
-
-void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info)
-{
-       memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info));
-}
-
 static struct resource pxafb_resources[] = {
        [0] = {
                .start  = 0x44000000,
@@ -230,7 +223,6 @@ static struct platform_device pxafb_device = {
        .name           = "pxa2xx-fb",
        .id             = -1,
        .dev            = {
-               .platform_data  = &pxa_fb_info,
                .dma_mask       = &fb_dma_mask,
                .coherent_dma_mask = 0xffffffff,
        },
@@ -238,6 +230,11 @@ static struct platform_device pxafb_device = {
        .resource       = pxafb_resources,
 };
 
+void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+{
+       pxafb_device.dev.platform_data = info;
+}
+
 void __init set_pxa_fb_parent(struct device *parent_dev)
 {
        pxafb_device.dev.parent = parent_dev;
index 6914d22bc20fbfb0b19c8eba67f48e0e85ef83ad..3e4b0ab71c66bbe40530ef03935d29126b3942e8 100644 (file)
@@ -82,7 +82,7 @@ static void idp_vlcd(int on)
        }
 }
 
-static void idp_lcd_power(int on)
+static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
 {
        if (on) {
                IDP_CPLD_LCD |= (1<<0);
@@ -99,7 +99,7 @@ static void idp_lcd_power(int on)
        idp_vlcd(on);
 }
 
-static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+static struct pxafb_mode_info sharp_lm8v31_mode = {
        .pixclock       = 270000,
        .xres           = 640,
        .yres           = 480,
@@ -112,6 +112,11 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
        .lower_margin   = 0,
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+       .modes          = &sharp_lm8v31_mode,
+       .num_modes      = 1,
        .cmap_inverse   = 0,
        .cmap_static    = 0,
        .lccr0          = LCCR0_SDS,
index 12479ae26db2addc8c4bcd5f1a11a40d563f24e4..eff2a91b2565ee8b46d3673c6bbe5d12759e2c1f 100644 (file)
@@ -248,7 +248,7 @@ static void lpd270_backlight_power(int on)
 }
 
 /* 5.7" TFT QVGA (LoLo display number 1) */
-static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
+static struct pxafb_mode_info sharp_lq057q3dc02_mode = {
        .pixclock               = 150000,
        .xres                   = 320,
        .yres                   = 240,
@@ -260,13 +260,18 @@ static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
        .upper_margin           = 0x08,
        .lower_margin           = 0x14,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq057q3dc02 = {
+       .modes                  = &sharp_lq057q3dc02_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 12.1" TFT SVGA (LoLo display number 2) */
-static struct pxafb_mach_info sharp_lq121s1dg31 __initdata = {
+static struct pxafb_mode_info sharp_lq121s1dg31_mode = {
        .pixclock               = 50000,
        .xres                   = 800,
        .yres                   = 600,
@@ -278,13 +283,18 @@ static struct pxafb_mach_info sharp_lq121s1dg31 __initdata = {
        .upper_margin           = 0x14,
        .lower_margin           = 0x0a,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq121s1dg31 = {
+       .modes                  = &sharp_lq121s1dg31_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 3.6" TFT QVGA (LoLo display number 3) */
-static struct pxafb_mach_info sharp_lq036q1da01 __initdata = {
+static struct pxafb_mode_info sharp_lq036q1da01_mode = {
        .pixclock               = 150000,
        .xres                   = 320,
        .yres                   = 240,
@@ -296,13 +306,18 @@ static struct pxafb_mach_info sharp_lq036q1da01 __initdata = {
        .upper_margin           = 0x03,
        .lower_margin           = 0x03,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq036q1da01 = {
+       .modes                  = &sharp_lq036q1da01_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 6.4" TFT VGA (LoLo display number 5) */
-static struct pxafb_mach_info sharp_lq64d343 __initdata = {
+static struct pxafb_mode_info sharp_lq64d343_mode = {
        .pixclock               = 25000,
        .xres                   = 640,
        .yres                   = 480,
@@ -314,13 +329,18 @@ static struct pxafb_mach_info sharp_lq64d343 __initdata = {
        .upper_margin           = 0x22,
        .lower_margin           = 0x00,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq64d343 = {
+       .modes                  = &sharp_lq64d343_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 10.4" TFT VGA (LoLo display number 7) */
-static struct pxafb_mach_info sharp_lq10d368 __initdata = {
+static struct pxafb_mode_info sharp_lq10d368_mode = {
        .pixclock               = 25000,
        .xres                   = 640,
        .yres                   = 480,
@@ -332,13 +352,18 @@ static struct pxafb_mach_info sharp_lq10d368 __initdata = {
        .upper_margin           = 0x22,
        .lower_margin           = 0x00,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq10d368 = {
+       .modes                  = &sharp_lq10d368_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 3.5" TFT QVGA (LoLo display number 8) */
-static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
+static struct pxafb_mode_info sharp_lq035q7db02_20_mode = {
        .pixclock               = 150000,
        .xres                   = 240,
        .yres                   = 320,
@@ -350,6 +375,11 @@ static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
        .upper_margin           = 0x05,
        .lower_margin           = 0x14,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq035q7db02_20 = {
+       .modes                  = &sharp_lq035q7db02_20_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
index 83ff5cee64d935d27396564f78721ff90b2d582b..157cf47cbe6655e239cb7a0c78abe15b4df88788 100644 (file)
@@ -352,7 +352,7 @@ static struct platform_device *devices[] __initdata = {
        &pxa_ssp,
 };
 
-static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+static struct pxafb_mode_info sharp_lm8v31_mode = {
        .pixclock       = 270000,
        .xres           = 640,
        .yres           = 480,
@@ -365,6 +365,11 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
        .lower_margin   = 0,
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+       .modes          = &sharp_lm8v31_mode,
+       .num_modes      = 1,
        .cmap_inverse   = 0,
        .cmap_static    = 0,
        .lccr0          = LCCR0_SDS,
index a7e9b96f258a4b34e9a209dca6b2f7ddb69e8228..7ba0447d6fa3dfbbb160f3c98e88daa97565dba9 100644 (file)
@@ -279,7 +279,7 @@ static void mainstone_backlight_power(int on)
        }
 }
 
-static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
        .pixclock               = 50000,
        .xres                   = 640,
        .yres                   = 480,
@@ -291,12 +291,9 @@ static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
        .upper_margin           = 0,
        .lower_margin           = 0,
        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
-       .lccr0                  = LCCR0_Act,
-       .lccr3                  = LCCR3_PCP,
-       .pxafb_backlight_power  = mainstone_backlight_power,
 };
 
-static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
        .pixclock               = 110000,
        .xres                   = 240,
        .yres                   = 320,
@@ -308,6 +305,10 @@ static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
        .upper_margin           = 1,
        .lower_margin           = 10,
        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info mainstone_pxafb_info = {
+       .num_modes              = 1,
        .lccr0                  = LCCR0_Act,
        .lccr3                  = LCCR3_PCP,
        .pxafb_backlight_power  = mainstone_backlight_power,
@@ -448,9 +449,11 @@ static void __init mainstone_init(void)
        /* reading Mainstone's "Virtual Configuration Register"
           might be handy to select LCD type here */
        if (0)
-               set_pxa_fb_info(&toshiba_ltm04c380k);
+               mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
        else
-               set_pxa_fb_info(&toshiba_ltm035a776c);
+               mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
+
+       set_pxa_fb_info(&mainstone_pxafb_info);
 
        pxa_set_mci_info(&mainstone_mci_platform_data);
        pxa_set_ficp_info(&mainstone_ficp_platform_data);
index 6dbff6d9480172fe0f9209f32587e03a7f56cc26..5e8c098ca13986125b15927bc9b8d2dc0eff1c52 100644 (file)
@@ -296,27 +296,25 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
 
 
 /* PXAFB device */
-static struct pxafb_mach_info poodle_fb_info __initdata = {
+static struct pxafb_mode_info poodle_fb_mode = {
        .pixclock       = 144700,
-
        .xres           = 320,
        .yres           = 240,
        .bpp            = 16,
-
        .hsync_len      = 7,
        .left_margin    = 11,
        .right_margin   = 30,
-
        .vsync_len      = 2,
        .upper_margin   = 2,
        .lower_margin   = 0,
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
 
+static struct pxafb_mach_info poodle_fb_info = {
+       .modes          = &poodle_fb_mode,
+       .num_modes      = 1,
        .lccr0          = LCCR0_Act | LCCR0_Sngl | LCCR0_Color,
        .lccr3          = 0,
-
-       .pxafb_backlight_power  = NULL,
-       .pxafb_lcd_power        = NULL,
 };
 
 static struct platform_device *devices[] __initdata = {
index 1c32a9310dc27abe5aa43d54d24a7bfdc2a50b62..401cdb850fbc2f014eec92a2a307290b99425eca 100644 (file)
@@ -407,21 +407,42 @@ static struct pxaficp_platform_data spitz_ficp_platform_data = {
 /*
  * Spitz PXA Framebuffer
  */
-static struct pxafb_mach_info spitz_pxafb_info __initdata = {
-        .pixclock       = 19231,
-        .xres           = 480,
-        .yres           = 640,
-        .bpp            = 16,
-        .hsync_len      = 40,
-        .left_margin    = 46,
-        .right_margin   = 125,
-        .vsync_len      = 3,
-        .upper_margin   = 1,
-        .lower_margin   = 0,
-        .sync           = 0,
-        .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
-        .lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
-        .pxafb_lcd_power = spitz_lcd_power,
+
+static struct pxafb_mode_info spitz_pxafb_modes[] = {
+{
+       .pixclock       = 19231,
+       .xres           = 480,
+       .yres           = 640,
+       .bpp            = 16,
+       .hsync_len      = 40,
+       .left_margin    = 46,
+       .right_margin   = 125,
+       .vsync_len      = 3,
+       .upper_margin   = 1,
+       .lower_margin   = 0,
+       .sync           = 0,
+},{
+       .pixclock       = 134617,
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+       .hsync_len      = 20,
+       .left_margin    = 20,
+       .right_margin   = 46,
+       .vsync_len      = 2,
+       .upper_margin   = 1,
+       .lower_margin   = 0,
+       .sync           = 0,
+},
+};
+
+static struct pxafb_mach_info spitz_pxafb_info = {
+       .modes          = &spitz_pxafb_modes[0],
+       .num_modes      = 2,
+       .fixed_modes    = 1,
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
+       .lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
+       .pxafb_lcd_power = spitz_lcd_power,
 };
 
 
index 7c3007df1bd6e22be0c009dd796b5cf69bb89f11..910571e9a190cba0597219ce523c7c97a7525e7d 100644 (file)
@@ -368,7 +368,7 @@ static struct map_desc trizeps4_io_desc[] __initdata = {
        }
 };
 
-static struct pxafb_mach_info sharp_lcd __initdata = {
+static struct pxafb_mode_info sharp_lcd_mode = {
     .pixclock          = 78000,
     .xres              = 640,
     .yres              = 480,
@@ -381,6 +381,11 @@ static struct pxafb_mach_info sharp_lcd __initdata = {
     .lower_margin      = 0,
     .sync              = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
     .cmap_greyscale    = 0,
+};
+
+static struct pxafb_mach_info sharp_lcd = {
+    .modes             = &sharp_lcd_mode,
+    .num_modes = 1,
     .cmap_inverse      = 0,
     .cmap_static       = 0,
     .lccr0             = LCCR0_Color | LCCR0_Pas | LCCR0_Dual,
index bbb07106cd54b1b50f2a3de7cf769590a7a56536..3bc5da4a57ca5caeca7046b89cb7b1dbd412a5e0 100644 (file)
@@ -59,7 +59,7 @@
 #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP)
 
 static void (*pxafb_backlight_power)(int);
-static void (*pxafb_lcd_power)(int);
+static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *);
 static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
@@ -213,6 +213,48 @@ static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var)
 extern unsigned int get_clk_frequency_khz(int info);
 #endif
 
+/*
+ * Select the smallest mode that allows the desired resolution to be
+ * displayed. If desired parameters can be rounded up.
+ */
+static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struct fb_var_screeninfo *var)
+{
+       struct pxafb_mode_info *mode = NULL;
+       struct pxafb_mode_info *modelist = mach->modes;
+       unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
+       unsigned int i;
+
+       for (i = 0 ; i < mach->num_modes ; i++) {
+               if (modelist[i].xres >= var->xres && modelist[i].yres >= var->yres &&
+                               modelist[i].xres < best_x && modelist[i].yres < best_y &&
+                               modelist[i].bpp >= var->bits_per_pixel ) {
+                       best_x = modelist[i].xres;
+                       best_y = modelist[i].yres;
+                       mode = &modelist[i];
+               }
+       }
+
+       return mode;
+}
+
+static void pxafb_setmode(struct fb_var_screeninfo *var, struct pxafb_mode_info *mode)
+{
+       var->xres               = mode->xres;
+       var->yres               = mode->yres;
+       var->bits_per_pixel     = mode->bpp;
+       var->pixclock           = mode->pixclock;
+       var->hsync_len          = mode->hsync_len;
+       var->left_margin        = mode->left_margin;
+       var->right_margin       = mode->right_margin;
+       var->vsync_len          = mode->vsync_len;
+       var->upper_margin       = mode->upper_margin;
+       var->lower_margin       = mode->lower_margin;
+       var->sync               = mode->sync;
+       var->grayscale          = mode->cmap_greyscale;
+       var->xres_virtual       = var->xres;
+       var->yres_virtual       = var->yres;
+}
+
 /*
  *  pxafb_check_var():
  *    Get the video params out of 'var'. If a value doesn't fit, round it up,
@@ -225,15 +267,29 @@ extern unsigned int get_clk_frequency_khz(int info);
 static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct pxafb_info *fbi = (struct pxafb_info *)info;
+       struct pxafb_mach_info *inf = fbi->dev->platform_data;
 
        if (var->xres < MIN_XRES)
                var->xres = MIN_XRES;
        if (var->yres < MIN_YRES)
                var->yres = MIN_YRES;
-       if (var->xres > fbi->max_xres)
-               return -EINVAL;
-       if (var->yres > fbi->max_yres)
-               return -EINVAL;
+
+       if (inf->fixed_modes) {
+               struct pxafb_mode_info *mode;
+
+               mode = pxafb_getmode(inf, var);
+               if (!mode)
+                       return -EINVAL;
+               pxafb_setmode(var, mode);
+       } else {
+               if (var->xres > inf->modes->xres)
+                       return -EINVAL;
+               if (var->yres > inf->modes->yres)
+                       return -EINVAL;
+               if (var->bits_per_pixel > inf->modes->bpp)
+                       return -EINVAL;
+       }
+
        var->xres_virtual =
                max(var->xres_virtual, var->xres);
        var->yres_virtual =
@@ -693,7 +749,7 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
        pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
 
        if (pxafb_lcd_power)
-               pxafb_lcd_power(on);
+               pxafb_lcd_power(on, &fbi->fb.var);
 }
 
 static void pxafb_setup_gpio(struct pxafb_info *fbi)
@@ -869,9 +925,11 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
                 * registers.
                 */
                if (old_state == C_ENABLE) {
+                       __pxafb_lcd_power(fbi, 0);
                        pxafb_disable_controller(fbi);
                        pxafb_setup_gpio(fbi);
                        pxafb_enable_controller(fbi);
+                       __pxafb_lcd_power(fbi, 1);
                }
                break;
 
@@ -1049,6 +1107,8 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        struct pxafb_info *fbi;
        void *addr;
        struct pxafb_mach_info *inf = dev->platform_data;
+       struct pxafb_mode_info *mode = inf->modes;
+       int i, smemlen;
 
        /* Alloc the pxafb_info and pseudo_palette in one step */
        fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1082,31 +1142,21 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        addr = addr + sizeof(struct pxafb_info);
        fbi->fb.pseudo_palette  = addr;
 
-       fbi->max_xres                   = inf->xres;
-       fbi->fb.var.xres                = inf->xres;
-       fbi->fb.var.xres_virtual        = inf->xres;
-       fbi->max_yres                   = inf->yres;
-       fbi->fb.var.yres                = inf->yres;
-       fbi->fb.var.yres_virtual        = inf->yres;
-       fbi->max_bpp                    = inf->bpp;
-       fbi->fb.var.bits_per_pixel      = inf->bpp;
-       fbi->fb.var.pixclock            = inf->pixclock;
-       fbi->fb.var.hsync_len           = inf->hsync_len;
-       fbi->fb.var.left_margin         = inf->left_margin;
-       fbi->fb.var.right_margin        = inf->right_margin;
-       fbi->fb.var.vsync_len           = inf->vsync_len;
-       fbi->fb.var.upper_margin        = inf->upper_margin;
-       fbi->fb.var.lower_margin        = inf->lower_margin;
-       fbi->fb.var.sync                = inf->sync;
-       fbi->fb.var.grayscale           = inf->cmap_greyscale;
+       pxafb_setmode(&fbi->fb.var, mode);
+
        fbi->cmap_inverse               = inf->cmap_inverse;
        fbi->cmap_static                = inf->cmap_static;
+
        fbi->lccr0                      = inf->lccr0;
        fbi->lccr3                      = inf->lccr3;
        fbi->state                      = C_STARTUP;
        fbi->task_state                 = (u_char)-1;
-       fbi->fb.fix.smem_len            = fbi->max_xres * fbi->max_yres *
-                                         fbi->max_bpp / 8;
+
+       for (i = 0; i < inf->num_modes; i++) {
+               smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
+               if (smemlen > fbi->fb.fix.smem_len)
+                       fbi->fb.fix.smem_len = smemlen;
+       }
 
        init_waitqueue_head(&fbi->ctrlr_wait);
        INIT_WORK(&fbi->task, pxafb_task, fbi);
@@ -1307,12 +1357,12 @@ int __init pxafb_probe(struct platform_device *dev)
            (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                 dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
         if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
-             (inf->upper_margin || inf->lower_margin))
+             (inf->modes->upper_margin || inf->modes->lower_margin))
                 dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n");
 #endif
 
-       dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->xres, inf->yres, inf->bpp);
-       if (inf->xres == 0 || inf->yres == 0 || inf->bpp == 0) {
+       dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->modes->xres, inf->modes->yres, inf->modes->bpp);
+       if (inf->modes->xres == 0 || inf->modes->yres == 0 || inf->modes->bpp == 0) {
                dev_err(&dev->dev, "Invalid resolution or bit depth\n");
                ret = -EINVAL;
                goto failed;
index 47f41f70db7a042c821ddc65832529487364f26b..7499a1c4bf790c9ecf51ba7093878080284facb6 100644 (file)
@@ -41,10 +41,6 @@ struct pxafb_info {
        struct fb_info          fb;
        struct device           *dev;
 
-       u_int                   max_bpp;
-       u_int                   max_xres;
-       u_int                   max_yres;
-
        /*
         * These are the addresses we mapped
         * the framebuffer memory region to.
index aba9b30f42490cbcfe6aab1e090662755cf0b913..81c3928d608c8182dae4d266d67ad247f119e845 100644 (file)
  *  published by the Free Software Foundation.
  */
 
+#include <linux/fb.h>
+
 /*
  * This structure describes the machine which we are running on.
  * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine
  * of linux/drivers/video/pxafb.c
  */
-struct pxafb_mach_info {
+struct pxafb_mode_info {
        u_long          pixclock;
 
        u_short         xres;
@@ -34,6 +36,14 @@ struct pxafb_mach_info {
        u_char          sync;
 
        u_int           cmap_greyscale:1,
+                       unused:31;
+};
+
+struct pxafb_mach_info {
+       struct pxafb_mode_info *modes;
+       unsigned int num_modes;
+
+       u_int           fixed_modes:1,
                        cmap_inverse:1,
                        cmap_static:1,
                        unused:29;
@@ -62,7 +72,7 @@ struct pxafb_mach_info {
        u_int           lccr3;
 
        void (*pxafb_backlight_power)(int);
-       void (*pxafb_lcd_power)(int);
+       void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 };
 void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
index 62e1fe4d025f96a6f527d09e4a8ed20e705333fa..4953dd324d4d1e51630c48bce3d15eaf05a3a426 100644 (file)
@@ -15,6 +15,8 @@
 #define __ASM_ARCH_SPITZ_H  1
 #endif
 
+#include <linux/fb.h>
+
 /* Spitz/Akita GPIOs */
 
 #define SPITZ_GPIO_KEY_INT         (0) /* Key Interrupt */
@@ -155,4 +157,4 @@ extern struct platform_device spitzscoop2_device;
 extern struct platform_device spitzssp_device;
 extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
 
-extern void spitz_lcd_power(int on);
+extern void spitz_lcd_power(int on, struct fb_var_screeninfo *var);