X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fpxafb.c;h=0a860dd8879c6ded6e33f1aa317560822b4e1d58;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=bfa3f8b58d2ac90e3738387f036c46e572c0a073;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index bfa3f8b58..0a860dd88 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -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<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