diff options
Diffstat (limited to 'target/linux/pxa/patches-2.6.21/043-pxafb-18bpp-mode.patch')
-rw-r--r-- | target/linux/pxa/patches-2.6.21/043-pxafb-18bpp-mode.patch | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/target/linux/pxa/patches-2.6.21/043-pxafb-18bpp-mode.patch b/target/linux/pxa/patches-2.6.21/043-pxafb-18bpp-mode.patch new file mode 100644 index 0000000..e39564b --- /dev/null +++ b/target/linux/pxa/patches-2.6.21/043-pxafb-18bpp-mode.patch @@ -0,0 +1,433 @@ +Index: linux-2.6.21gum/drivers/video/pxafb.c +=================================================================== +--- linux-2.6.21gum.orig/drivers/video/pxafb.c ++++ linux-2.6.21gum/drivers/video/pxafb.c +@@ -191,6 +191,10 @@ static int pxafb_bpp_to_lccr3(struct fb_ + case 4: ret = LCCR3_4BPP; break; + case 8: ret = LCCR3_8BPP; break; + case 16: ret = LCCR3_16BPP; break; ++ case 18: ret = (var->nonstd == 24 ? LCCR3_18BPP_PACKED : LCCR3_18BPP); break; ++ case 19: ret = (var->nonstd == 24 ? LCCR3_19BPP_PACKED : LCCR3_19BPP); break; ++ case 24: ret = LCCR3_24BPP; break; ++ case 25: ret = LCCR3_25BPP; break; + } + return ret; + } +@@ -204,11 +208,12 @@ static int pxafb_bpp_to_lccr3(struct fb_ + */ + static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var) + { +- /* +- * Period = pixclock * bits_per_byte * bytes_per_transfer +- * / memory_bits_per_pixel; +- */ +- return var->pixclock * 8 * 16 / var->bits_per_pixel; ++ /* ++ * Period = pixclock * bits_per_byte * bytes_per_transfer ++ * / memory_bits_per_pixel; ++ */ ++ struct pxafb_mach_info *inf = fbi->dev->platform_data; ++ return var->pixclock * 8 * 16 / (var->nonstd ? var->nonstd : var->bits_per_pixel); + } + + extern unsigned int get_clk_frequency_khz(int info); +@@ -307,6 +312,26 @@ static int pxafb_check_var(struct fb_var + 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 == 18) { ++ 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; ++ } else if (var->bits_per_pixel == 19) { ++ 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; ++ } else if (var->bits_per_pixel == 24) { ++ 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; ++ } else if (var->bits_per_pixel == 25) { ++ var->transp.offset = 18; 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; + } else { + var->red.offset = var->green.offset = var->blue.offset = var->transp.offset = 0; + var->red.length = 8; +@@ -342,7 +367,7 @@ static int pxafb_set_par(struct fb_info + + pr_debug("pxafb: set_par\n"); + +- 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; +@@ -355,9 +380,10 @@ static int pxafb_set_par(struct fb_info + fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; + } + +- fbi->fb.fix.line_length = var->xres_virtual * +- var->bits_per_pixel / 8; +- if (var->bits_per_pixel == 16) ++ fbi->fb.fix.line_length = var->xres_virtual * ++ (var->nonstd ? var->nonstd : var->bits_per_pixel) / 8; ++ ++ 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; +@@ -374,7 +400,7 @@ static int pxafb_set_par(struct fb_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); +@@ -584,6 +610,14 @@ static int pxafb_activate_var(struct fb_ + case 8: + case 16: + break; ++ case 18: ++ case 19: ++ case 24: ++ case 25: ++ if(var->nonstd) break; ++ printk(KERN_ERR "%s: must specify nonstd when bit depth==%d\n", ++ fbi->fb.fix.id, var->bits_per_pixel); ++ break; + default: + printk(KERN_ERR "%s: invalid bit depth %d\n", + fbi->fb.fix.id, var->bits_per_pixel); +@@ -679,7 +713,7 @@ static int pxafb_activate_var(struct fb_ + fbi->dmadesc_palette_cpu->fidr = 0; + fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL; + +- if (var->bits_per_pixel == 16) { ++ 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 */ +@@ -785,8 +819,19 @@ static void pxafb_setup_gpio(struct pxaf + return; + } + +- for (gpio = 58; ldd_bits; gpio++, ldd_bits--) ++ for (gpio = 58; min(ldd_bits,16); gpio++, ldd_bits--) + pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT); ++ ++ switch(fbi->fb.var.bits_per_pixel) ++ { ++ case 25: ++ case 24: ++ case 19: ++ case 18: ++ pxa_gpio_mode(GPIO86_LDD_16_MD); ++ pxa_gpio_mode(GPIO87_LDD_17_MD); ++ default: break; ++ } + pxa_gpio_mode(GPIO74_LCD_FCLK_MD); + pxa_gpio_mode(GPIO75_LCD_LCLK_MD); + pxa_gpio_mode(GPIO76_LCD_PCLK_MD); +@@ -1135,7 +1180,7 @@ static struct pxafb_info * __init pxafb_ + fbi->fb.fix.ywrapstep = 0; + fbi->fb.fix.accel = FB_ACCEL_NONE; + +- fbi->fb.var.nonstd = 0; ++ fbi->fb.var.nonstd = mode->nonstd; + fbi->fb.var.activate = FB_ACTIVATE_NOW; + fbi->fb.var.height = -1; + fbi->fb.var.width = -1; +@@ -1161,7 +1206,7 @@ static struct pxafb_info * __init pxafb_ + fbi->task_state = (u_char)-1; + + for (i = 0; i < inf->num_modes; i++) { +- smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8; ++ smemlen = mode[i].xres * mode[i].yres * (mode[i].nonstd ? mode[i].nonstd : mode[i].bpp) / 8; + if (smemlen > fbi->fb.fix.smem_len) + fbi->fb.fix.smem_len = smemlen; + } +@@ -1189,12 +1234,19 @@ static int __init pxafb_parse_options(st + if (!strncmp(this_opt, "mode:", 5)) { + const char *name = this_opt+5; + unsigned int namelen = strlen(name); +- int res_specified = 0, bpp_specified = 0; +- unsigned int xres = 0, yres = 0, bpp = 0; ++ int res_specified = 0, bpp_specified = 0, nonstd_specified = 0; ++ unsigned int xres = 0, yres = 0, bpp = 0, nonstd = 0; + int yres_specified = 0; + int i; + for (i = namelen-1; i >= 0; i--) { + switch (name[i]) { ++ case '/': ++ if (!nonstd_specified) { ++ nonstd = simple_strtoul(&name[i+1], NULL, 0); ++ nonstd_specified = 1; ++ } else ++ goto done; ++ break; + case '-': + namelen = i; + if (!bpp_specified && !yres_specified) { +@@ -1227,12 +1279,29 @@ static int __init pxafb_parse_options(st + } + if (bpp_specified) + switch (bpp) { ++ case 18: ++ case 19: ++ case 24: ++ case 25: ++ if(nonstd_specified && (((bpp == 18 || bpp == 19) && nonstd == 24) || nonstd == 32)) ++ { ++ inf->modes[0].nonstd = nonstd; ++ dev_info(dev, "overriding nonstd pixel packing: %d\n",nonstd); ++ } else { ++ dev_err(dev, "Depth %d requires nonstd to be specified\n",bpp); ++ break; ++ } + case 1: + case 2: + case 4: + case 8: + case 16: + inf->modes[0].bpp = bpp; ++ if(nonstd_specified) { ++ dev_err(dev, "Depth %d requires nonstd to *not* be specified\n",bpp); ++ } else { ++ inf->modes[0].nonstd = 0; ++ } + dev_info(dev, "overriding bit depth: %d\n", bpp); + break; + default: +Index: linux-2.6.21gum/include/asm-arm/arch-pxa/pxa-regs.h +=================================================================== +--- linux-2.6.21gum.orig/include/asm-arm/arch-pxa/pxa-regs.h ++++ linux-2.6.21gum/include/asm-arm/arch-pxa/pxa-regs.h +@@ -1323,6 +1323,8 @@ + #define GPIO83_NSTXD 83 /* NSSP transmit */ + #define GPIO84_NSRXD 84 /* NSSP receive */ + #define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ ++#define GPIO86_LDD_16 86 /* LCD data pin 16 */ ++#define GPIO87_LDD_17 87 /* LCD data pin 17 */ + #define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ + #define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ + #define GPIO105_nPCE_2 105 /* Card Enable for Card Space (PXA27x) */ +@@ -1468,6 +1470,8 @@ + #define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) + #define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) + #define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) ++#define GPIO86_LDD_16_MD (86 | GPIO_ALT_FN_2_OUT) ++#define GPIO87_LDD_17_MD (87 | GPIO_ALT_FN_2_OUT) + #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) + #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) + #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) +@@ -1878,6 +1882,12 @@ + #define LCCR3_4BPP (2 << 24) + #define LCCR3_8BPP (3 << 24) + #define LCCR3_16BPP (4 << 24) ++#define LCCR3_18BPP (5 << 24) ++#define LCCR3_18BPP_PACKED (6 << 24) ++#define LCCR3_19BPP (7 << 24) ++#define LCCR3_19BPP_PACKED (1 << 29) ++#define LCCR3_24BPP ((1 << 29) | (1 << 24)) ++#define LCCR3_25BPP ((1 << 29) | (2 << 24)) + + #define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ + #define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */ +Index: linux-2.6.21gum/include/asm-arm/arch-pxa/pxafb.h +=================================================================== +--- linux-2.6.21gum.orig/include/asm-arm/arch-pxa/pxafb.h ++++ linux-2.6.21gum/include/asm-arm/arch-pxa/pxafb.h +@@ -25,6 +25,7 @@ struct pxafb_mode_info { + u_short xres; + u_short yres; + ++ /* bpp is the path-to-screen bits per pixel, not the in-memory storage required */ + u_char bpp; + u_char hsync_len; + u_char left_margin; +@@ -36,7 +37,9 @@ struct pxafb_mode_info { + u_char sync; + + u_int cmap_greyscale:1, +- unused:31; ++ nonstd:8, /* nonstd represents the in-memory bits per pixel ++ ie 24 or 32 for 18/19bpp mode, or 32 for 24/25bpp mode */ ++ unused:23; + }; + + struct pxafb_mach_info { +Index: linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c +=================================================================== +--- linux-2.6.21gum.orig/arch/arm/mach-pxa/gumstix.c ++++ linux-2.6.21gum/arch/arm/mach-pxa/gumstix.c +@@ -146,7 +146,8 @@ static struct pxafb_mode_info gumstix_fb + .pixclock = 110000, + .xres = 480, + .yres = 272, +- .bpp = 16, ++ .bpp = 18, ++ .nonstd = 24, + .hsync_len = 41, + .left_margin = 2, + .right_margin = 2, +@@ -174,7 +175,8 @@ static struct pxafb_mode_info gumstix_fb + .vsync_len = 10, // VLW from datasheet: 10 typ + .upper_margin = 2, // VBP - VLW from datasheet: 12 - 10 = 2 + .lower_margin = 4, // VFP from datasheet: 4 typ +- .bpp = 16, ++ .bpp = 18, ++ .nonstd = 24, + .sync = 0, // Hsync and Vsync both active low + }; + +Index: linux-2.6.21gum/drivers/video/cfbfillrect.c +=================================================================== +--- linux-2.6.21gum.orig/drivers/video/cfbfillrect.c ++++ linux-2.6.21gum/drivers/video/cfbfillrect.c +@@ -62,7 +62,10 @@ pixel_to_pat( u32 bpp, u32 pixel) + return 0x0001001001001001ul*pixel; + case 16: + return 0x0001000100010001ul*pixel; ++ case 18: ++ case 19: + case 24: ++ case 25: + return 0x0000000001000001ul*pixel; + case 32: + return 0x0000000100000001ul*pixel; +@@ -87,7 +90,10 @@ pixel_to_pat( u32 bpp, u32 pixel) + return 0x00001001ul*pixel; + case 16: + return 0x00010001ul*pixel; ++ case 18: ++ case 19: + case 24: ++ case 25: + return 0x00000001ul*pixel; + case 32: + return 0x00000001ul*pixel; +@@ -346,7 +352,7 @@ void cfb_fillrect(struct fb_info *p, con + unsigned long pat, fg; + unsigned long width = rect->width, height = rect->height; + int bits = BITS_PER_LONG, bytes = bits >> 3; +- u32 bpp = p->var.bits_per_pixel; ++ u32 bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); + unsigned long __iomem *dst; + int dst_idx, left; + +Index: linux-2.6.21gum/drivers/video/cfbimgblt.c +=================================================================== +--- linux-2.6.21gum.orig/drivers/video/cfbimgblt.c ++++ linux-2.6.21gum/drivers/video/cfbimgblt.c +@@ -83,7 +83,7 @@ static inline void color_imageblit(const + /* Draw the penguin */ + u32 __iomem *dst, *dst2; + u32 color = 0, val, shift; +- int i, n, bpp = p->var.bits_per_pixel; ++ int i, n, bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); + u32 null_bits = 32 - bpp; + u32 *palette = (u32 *) p->pseudo_palette; + const u8 *src = image->data; +@@ -140,7 +140,7 @@ static inline void slow_imageblit(const + u32 start_index, + u32 pitch_index) + { +- u32 shift, color = 0, bpp = p->var.bits_per_pixel; ++ u32 shift, color = 0, bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); + u32 __iomem *dst, *dst2; + u32 val, pitch = p->fix.line_length; + u32 null_bits = 32 - bpp; +@@ -213,7 +213,7 @@ static inline void fast_imageblit(const + u8 __iomem *dst1, u32 fgcolor, + u32 bgcolor) + { +- u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; ++ u32 fgx = fgcolor, bgx = bgcolor, bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); + u32 ppw = 32/bpp, spitch = (image->width + 7)/8; + u32 bit_mask, end_mask, eorx, shift; + const char *s = image->data, *src; +@@ -262,7 +262,7 @@ static inline void fast_imageblit(const + void cfb_imageblit(struct fb_info *p, const struct fb_image *image) + { + u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; +- u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; ++ u32 bpl = sizeof(u32), bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); + u32 width = image->width; + u32 dx = image->dx, dy = image->dy; + u8 __iomem *dst1; +Index: linux-2.6.21gum/drivers/video/cfbcopyarea.c +=================================================================== +--- linux-2.6.21gum.orig/drivers/video/cfbcopyarea.c ++++ linux-2.6.21gum/drivers/video/cfbcopyarea.c +@@ -365,8 +365,8 @@ void cfb_copyarea(struct fb_info *p, con + dst = src = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1)); + dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1)); + // add offset of source and target area +- dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel; +- src_idx += sy*bits_per_line + sx*p->var.bits_per_pixel; ++ dst_idx += dy*bits_per_line + dx*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); ++ src_idx += sy*bits_per_line + sx*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel); + + if (p->fbops->fb_sync) + p->fbops->fb_sync(p); +@@ -380,7 +380,7 @@ void cfb_copyarea(struct fb_info *p, con + src += src_idx >> (ffs(bits) - 1); + src_idx &= (bytes - 1); + bitcpy_rev(dst, dst_idx, src, src_idx, bits, +- width*p->var.bits_per_pixel); ++ width*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel)); + } + } else { + while (height--) { +@@ -389,7 +389,7 @@ void cfb_copyarea(struct fb_info *p, con + src += src_idx >> (ffs(bits) - 1); + src_idx &= (bytes - 1); + bitcpy(dst, dst_idx, src, src_idx, bits, +- width*p->var.bits_per_pixel); ++ width*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel)); + dst_idx += bits_per_line; + src_idx += bits_per_line; + } +Index: linux-2.6.21gum/drivers/video/console/fbcon.c +=================================================================== +--- linux-2.6.21gum.orig/drivers/video/console/fbcon.c ++++ linux-2.6.21gum/drivers/video/console/fbcon.c +@@ -983,9 +983,10 @@ static const char *fbcon_startup(void) + + DPRINTK("mode: %s\n", info->fix.id); + DPRINTK("visual: %d\n", info->fix.visual); +- DPRINTK("res: %dx%d-%d\n", info->var.xres, ++ DPRINTK("res: %dx%d-%d(%d)\n", info->var.xres, + info->var.yres, +- info->var.bits_per_pixel); ++ info->var.bits_per_pixel, ++ info->var.nonstd ? info->var.nonstd : info->var.bits_per_pixel); + + #ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { +Index: linux-2.6.21gum/Documentation/fb/pxafb.txt +=================================================================== +--- linux-2.6.21gum.orig/Documentation/fb/pxafb.txt ++++ linux-2.6.21gum/Documentation/fb/pxafb.txt +@@ -9,11 +9,13 @@ For example: + or on the kernel command line + video=pxafb:mode:640x480-8,passive + +-mode:XRESxYRES[-BPP] ++mode:XRESxYRES[-BPP[/PACKING]] + XRES == LCCR1_PPL + 1 + YRES == LLCR2_LPP + 1 + The resolution of the display in pixels + BPP == The bit depth. Valid values are 1, 2, 4, 8 and 16. ++ PACKING == The in-memory bits per pixel. Valid values are 24, 32 when ++ BPP == 18,19,24,25 + + pixclock:PIXCLOCK + Pixel clock in picoseconds |