VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / video / pxafb.c
index bfa3f8b..0a860dd 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/mach-types.h>
 #include <asm/uaccess.h>
 #include <asm/arch/bitfield.h>
 #include <asm/arch/pxafb.h>
@@ -109,10 +108,13 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
        u_int val, ret = 1;
 
        if (regno < fbi->palette_size) {
-               val  = ((red   >>  0) & 0xf800);
-               val |= ((green >>  5) & 0x07e0);
-               val |= ((blue  >> 11) & 0x001f);
-
+               if (fbi->fb.var.grayscale) {
+                       val = ((blue >> 8) & 0x00ff);
+               } else {
+                       val  = ((red   >>  0) & 0xf800);
+                       val |= ((green >>  5) & 0x07e0);
+                       val |= ((blue  >> 11) & 0x001f);
+               }
                fbi->palette_cpu[regno] = val;
                ret = 0;
        }
@@ -150,7 +152,7 @@ pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
        switch (fbi->fb.fix.visual) {
        case FB_VISUAL_TRUECOLOR:
                /*
-                * 12 or 16-bit True Colour.  We encode the RGB value
+                * 16-bit True Colour.  We encode the RGB value
                 * according to the RGB bitfield information.
                 */
                if (regno < 16) {
@@ -242,7 +244,7 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
         * The pixel packing format is described on page 7-11 of the
         * PXA2XX Developer's Manual.
          */
-       if ( var->bits_per_pixel == 16 ) {
+       if (var->bits_per_pixel == 16) {
                var->red.offset   = 11; var->red.length   = 5;
                var->green.offset = 5;  var->green.length = 6;
                var->blue.offset  = 0;  var->blue.length  = 5;
@@ -297,7 +299,10 @@ static int pxafb_set_par(struct fb_info *info)
 
        fbi->fb.fix.line_length = var->xres_virtual *
                                  var->bits_per_pixel / 8;
-       fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
+       if (var->bits_per_pixel == 16)
+               fbi->palette_size = 0;
+       else
+               fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
 
        palette_mem_size = fbi->palette_size * sizeof(u16);
 
@@ -311,6 +316,11 @@ static int pxafb_set_par(struct fb_info *info)
         */
        pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
 
+       if (fbi->fb.var.bits_per_pixel == 16)
+               fb_dealloc_cmap(&fbi->fb.cmap);
+       else
+               fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
+
        pxafb_activate_var(var, fbi);
 
        return 0;
@@ -349,7 +359,7 @@ static int pxafb_set_par(struct fb_info *info)
 /*
  * pxafb_blank():
  *     Blank the display by setting all palette values to zero.  Note, the
- *     12 and 16 bpp modes don't really use the palette, so this will not
+ *     16 bpp mode does not really use the palette, so this will not
  *      blank the display in all modes.
  */
 static int pxafb_blank(int blank, struct fb_info *info)
@@ -376,7 +386,7 @@ static int pxafb_blank(int blank, struct fb_info *info)
                //TODO if (pxafb_blank_helper) pxafb_blank_helper(blank);
                if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
                    fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
-                       fb_set_cmap(&fbi->fb.cmap, 1, info);
+                       fb_set_cmap(&fbi->fb.cmap, info);
                pxafb_schedule_work(fbi, C_ENABLE);
        }
        return 0;
@@ -514,7 +524,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
         * the YRES parameter.
         */
        lines_per_panel = var->yres;
-       if (fbi->lccr0 & LCCR0_SDS)
+       if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                lines_per_panel /= 2;
 
        new_regs.lccr2 =
@@ -566,20 +576,16 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
        fbi->dmadesc_palette_cpu->fidr  = 0;
        fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
 
-       if( var->bits_per_pixel < 12)
-       {
-               /* assume any mode with <12 bpp is palette driven */
-               fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
-               fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
-               fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
-       }
-       else
-       {
+       if (var->bits_per_pixel == 16) {
                /* palette shouldn't be loaded in true-color mode */
                fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
                fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
                /* init it to something, even though we won't be using it */
                fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma;
+       } else {
+               fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
+               fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
+               fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
        }
 
 #if 0
@@ -696,7 +702,7 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
        }
 
        else {
-               printk( KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
+               printk(KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
         }
 }
 
@@ -1010,7 +1016,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        struct pxafb_mach_info *inf = dev->platform_data;
 
        /* Alloc the pxafb_info and pseudo_palette in one step */
-       fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 17, GFP_KERNEL);
+       fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
        if (!fbi)
                return NULL;
 
@@ -1123,11 +1129,11 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                res_specified = 1;
                        }
                done:
-                       if ( res_specified ) {
-                               dev_info(dev, "overriding resolution: %dx%x\n", xres, yres);
+                       if (res_specified) {
+                               dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
                                inf->xres = xres; inf->yres = yres;
                        }
-                       if ( bpp_specified )
+                       if (bpp_specified)
                                switch (bpp) {
                                case 1:
                                case 2:
@@ -1142,7 +1148,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                }
                 } else if (!strncmp(this_opt, "pixclock:", 9)) {
                         inf->pixclock = simple_strtoul(this_opt+9, NULL, 0);
-                       dev_info(dev, "override pixclock: %u\n", inf->pixclock);
+                       dev_info(dev, "override pixclock: %ld\n", inf->pixclock);
                 } else if (!strncmp(this_opt, "left:", 5)) {
                         inf->left_margin = simple_strtoul(this_opt+5, NULL, 0);
                        dev_info(dev, "override left: %u\n", inf->left_margin);
@@ -1162,7 +1168,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                         inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
                        dev_info(dev, "override vsynclen: %u\n", inf->vsync_len);
                 } else if (!strncmp(this_opt, "hsync:", 6)) {
-                        if ( simple_strtoul(this_opt+6, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
                                dev_info(dev, "override hsync: Active Low\n");
                                inf->sync &= ~FB_SYNC_HOR_HIGH_ACT;
                        } else {
@@ -1170,7 +1176,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                inf->sync |= FB_SYNC_HOR_HIGH_ACT;
                        }
                 } else if (!strncmp(this_opt, "vsync:", 6)) {
-                        if ( simple_strtoul(this_opt+6, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
                                dev_info(dev, "override vsync: Active Low\n");
                                inf->sync &= ~FB_SYNC_VERT_HIGH_ACT;
                        } else {
@@ -1178,7 +1184,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                inf->sync |= FB_SYNC_VERT_HIGH_ACT;
                        }
                 } else if (!strncmp(this_opt, "dpc:", 4)) {
-                        if ( simple_strtoul(this_opt+4, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
                                dev_info(dev, "override double pixel clock: false\n");
                                inf->lccr3 &= ~LCCR3_DPC;
                        } else {
@@ -1186,20 +1192,20 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                inf->lccr3 |= LCCR3_DPC;
                        }
                 } else if (!strncmp(this_opt, "outputen:", 9)) {
-                        if ( simple_strtoul(this_opt+9, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+9, NULL, 0) == 0) {
                                dev_info(dev, "override output enable: active low\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_OEP ) | LCCR3_OutEnL;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
                        } else {
                                dev_info(dev, "override output enable: active high\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_OEP ) | LCCR3_OutEnH;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
                        }
                 } else if (!strncmp(this_opt, "pixclockpol:", 12)) {
-                        if ( simple_strtoul(this_opt+12, NULL, 0) == 0 ) {
+                        if (simple_strtoul(this_opt+12, NULL, 0) == 0) {
                                dev_info(dev, "override pixel clock polarity: falling edge\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_PCP ) | LCCR3_PixFlEdg;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
                        } else {
                                dev_info(dev, "override pixel clock polarity: rising edge\n");
-                               inf->lccr3 = ( inf->lccr3 & ~LCCR3_PCP ) | LCCR3_PixRsEdg;
+                               inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
                        }
                 } else if (!strncmp(this_opt, "color", 5)) {
                        inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
@@ -1231,7 +1237,6 @@ int __init pxafb_probe(struct device *dev)
 {
        struct pxafb_info *fbi;
        struct pxafb_mach_info *inf;
-       unsigned long flags;
        int ret;
 
        dev_dbg(dev, "pxafb_probe\n");
@@ -1244,7 +1249,7 @@ int __init pxafb_probe(struct device *dev)
 
 #ifdef CONFIG_FB_PXA_PARAMETERS
        ret = pxafb_parse_options(dev, g_options);
-       if ( ret < 0 )
+       if (ret < 0)
                goto failed;
 #endif
 
@@ -1252,23 +1257,23 @@ int __init pxafb_probe(struct device *dev)
         /* Check for various illegal bit-combinations. Currently only
         * a warning is given. */
 
-        if ( inf->lccr0 & LCCR0_INVALID_CONFIG_MASK )
+        if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
                 dev_warn(dev, "machine LCCR0 setting contains illegal bits: %08x\n",
                         inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
-        if ( inf->lccr3 & LCCR3_INVALID_CONFIG_MASK )
+        if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
                 dev_warn(dev, "machine LCCR3 setting contains illegal bits: %08x\n",
                         inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
-        if ( inf->lccr0 & LCCR0_DPD &&
-             ( ( inf->lccr0 & LCCR0_PAS ) != LCCR0_Pas ||
-               ( inf->lccr0 & LCCR0_SDS ) != LCCR0_Sngl ||
-               ( inf->lccr0 & LCCR0_CMS ) != LCCR0_Mono ) )
+        if (inf->lccr0 & LCCR0_DPD &&
+           ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
+            (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
+            (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
                 dev_warn(dev, "Double Pixel Data (DPD) mode is only valid in passive mono"
                         " single panel mode\n");
-        if ( (inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
-             ( inf->lccr0 & LCCR0_SDS ) == LCCR0_Dual )
+        if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
+           (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                 dev_warn(dev, "Dual panel only valid in passive mode\n");
-        if ( (inf->lccr0 & LCCR0_PAS ) == LCCR0_Pas &&
-             (inf->upper_margin || inf->lower_margin) )
+        if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
+             (inf->upper_margin || inf->lower_margin))
                 dev_warn(dev, "Upper and lower margins must be 0 in passive mode\n");
 #endif
 
@@ -1295,9 +1300,7 @@ int __init pxafb_probe(struct device *dev)
                goto failed;
        }
        /* enable LCD controller clock */
-       local_irq_save(flags);
-       CKEN |= CKEN16_LCD;
-       local_irq_restore(flags);
+       pxa_set_cken(CKEN16_LCD, 1);
 
        ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi);
        if (ret) {
@@ -1347,7 +1350,7 @@ failed:
 }
 
 static struct device_driver pxafb_driver = {
-       .name           = "pxafb",
+       .name           = "pxa2xx-fb",
        .bus            = &platform_bus_type,
        .probe          = pxafb_probe,
 #ifdef CONFIG_PM