diff options
Diffstat (limited to 'drivers/video/pxafb.c')
-rw-r--r-- | drivers/video/pxafb.c | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3682bbd7e50..5cc1b807372 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -227,6 +227,22 @@ static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var) case 4: ret = LCCR3_4BPP; break; case 8: ret = LCCR3_8BPP; break; case 16: ret = LCCR3_16BPP; break; + case 24: + switch (var->red.length + var->green.length + + var->blue.length + var->transp.length) { + case 18: ret = LCCR3_18BPP_P | LCCR3_PDFOR_3; break; + case 19: ret = LCCR3_19BPP_P; break; + } + break; + case 32: + switch (var->red.length + var->green.length + + var->blue.length + var->transp.length) { + case 18: ret = LCCR3_18BPP | LCCR3_PDFOR_3; break; + case 19: ret = LCCR3_19BPP; break; + case 24: ret = LCCR3_24BPP | LCCR3_PDFOR_3; break; + case 25: ret = LCCR3_25BPP; break; + } + break; } return ret; } @@ -345,6 +361,41 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->green.offset = 5; var->green.length = 6; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = var->transp.length = 0; + } else if (var->bits_per_pixel > 16) { + struct pxafb_mode_info *mode; + + mode = pxafb_getmode(inf, var); + if (!mode) + return -EINVAL; + + switch (mode->depth) { + case 18: /* RGB666 */ + var->transp.offset = var->transp.length = 0; + var->red.offset = 12; var->red.length = 6; + var->green.offset = 6; var->green.length = 6; + var->blue.offset = 0; var->blue.length = 6; + break; + case 19: /* RGBT666 */ + var->transp.offset = 18; var->transp.length = 1; + var->red.offset = 12; var->red.length = 6; + var->green.offset = 6; var->green.length = 6; + var->blue.offset = 0; var->blue.length = 6; + break; + case 24: /* RGB888 */ + var->transp.offset = var->transp.length = 0; + var->red.offset = 16; var->red.length = 8; + var->green.offset = 8; var->green.length = 8; + var->blue.offset = 0; var->blue.length = 8; + break; + case 25: /* RGBT888 */ + var->transp.offset = 24; var->transp.length = 1; + var->red.offset = 16; var->red.length = 8; + var->green.offset = 8; var->green.length = 8; + var->blue.offset = 0; var->blue.length = 8; + break; + default: + return -EINVAL; + } } else { var->red.offset = var->green.offset = 0; var->blue.offset = var->transp.offset = 0; @@ -376,7 +427,7 @@ static int pxafb_set_par(struct fb_info *info) struct pxafb_info *fbi = (struct pxafb_info *)info; struct fb_var_screeninfo *var = &info->var; - if (var->bits_per_pixel == 16) + if (var->bits_per_pixel >= 16) fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; else if (!fbi->cmap_static) fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -391,7 +442,7 @@ static int pxafb_set_par(struct fb_info *info) fbi->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; - if (var->bits_per_pixel == 16) + if (var->bits_per_pixel >= 16) fbi->palette_size = 0; else fbi->palette_size = var->bits_per_pixel == 1 ? @@ -404,7 +455,7 @@ 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) + 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); @@ -573,8 +624,8 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; } else { - pal_desc = &fbi->dma_buff->pal_desc[dma]; - pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]); + pal_desc = &fbi->dma_buff->pal_desc[pal]; + pal_desc_off = offsetof(struct pxafb_dma_buff, pal_desc[pal]); pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; pal_desc->fidr = 0; @@ -831,6 +882,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, case 4: case 8: case 16: + case 24: + case 32: break; default: printk(KERN_ERR "%s: invalid bit depth %d\n", @@ -968,6 +1021,11 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi) for (gpio = 58; ldd_bits; gpio++, ldd_bits--) pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT); + /* 18 bit interface */ + if (fbi->fb.var.bits_per_pixel > 16) { + pxa_gpio_mode(86 | GPIO_ALT_FN_2_OUT); + pxa_gpio_mode(87 | GPIO_ALT_FN_2_OUT); + } pxa_gpio_mode(GPIO74_LCD_FCLK_MD); pxa_gpio_mode(GPIO75_LCD_LCLK_MD); pxa_gpio_mode(GPIO76_LCD_PCLK_MD); @@ -1276,6 +1334,8 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi) fbi->dma_buff_phys = fbi->map_dma; fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; + pr_debug("pxafb: palette_mem_size = 0x%08lx\n", fbi->palette_size*sizeof(u16)); + #ifdef CONFIG_FB_PXA_SMARTPANEL fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; fbi->n_smart_cmds = 0; @@ -1351,7 +1411,6 @@ 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; /* Alloc the pxafb_info and pseudo_palette in one step */ fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); |