1 Index: linux-2.6.21.7/drivers/video/pxafb.c
2 ===================================================================
3 --- linux-2.6.21.7.orig/drivers/video/pxafb.c
4 +++ linux-2.6.21.7/drivers/video/pxafb.c
5 @@ -191,6 +191,10 @@ static int pxafb_bpp_to_lccr3(struct fb_
6 case 4: ret = LCCR3_4BPP; break;
7 case 8: ret = LCCR3_8BPP; break;
8 case 16: ret = LCCR3_16BPP; break;
9 + case 18: ret = (var->nonstd == 24 ? LCCR3_18BPP_PACKED : LCCR3_18BPP); break;
10 + case 19: ret = (var->nonstd == 24 ? LCCR3_19BPP_PACKED : LCCR3_19BPP); break;
11 + case 24: ret = LCCR3_24BPP; break;
12 + case 25: ret = LCCR3_25BPP; break;
16 @@ -204,11 +208,12 @@ static int pxafb_bpp_to_lccr3(struct fb_
18 static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var)
21 - * Period = pixclock * bits_per_byte * bytes_per_transfer
22 - * / memory_bits_per_pixel;
24 - return var->pixclock * 8 * 16 / var->bits_per_pixel;
26 + * Period = pixclock * bits_per_byte * bytes_per_transfer
27 + * / memory_bits_per_pixel;
29 + struct pxafb_mach_info *inf = fbi->dev->platform_data;
30 + return var->pixclock * 8 * 16 / (var->nonstd ? var->nonstd : var->bits_per_pixel);
33 extern unsigned int get_clk_frequency_khz(int info);
34 @@ -307,6 +312,26 @@ static int pxafb_check_var(struct fb_var
35 var->green.offset = 5; var->green.length = 6;
36 var->blue.offset = 0; var->blue.length = 5;
37 var->transp.offset = var->transp.length = 0;
38 + } else if (var->bits_per_pixel == 18) {
39 + var->transp.offset = var->transp.length = 0;
40 + var->red.offset = 12; var->red.length=6;
41 + var->green.offset = 6; var->green.length=6;
42 + var->blue.offset = 0; var->blue.length=6;
43 + } else if (var->bits_per_pixel == 19) {
44 + var->transp.offset = 18; var->transp.length = 1;
45 + var->red.offset = 12; var->red.length=6;
46 + var->green.offset = 6; var->green.length=6;
47 + var->blue.offset = 0; var->blue.length=6;
48 + } else if (var->bits_per_pixel == 24) {
49 + var->transp.offset = var->transp.length = 0;
50 + var->red.offset = 16; var->red.length=8;
51 + var->green.offset = 8; var->green.length=8;
52 + var->blue.offset = 0; var->blue.length=8;
53 + } else if (var->bits_per_pixel == 25) {
54 + var->transp.offset = 18; var->transp.length = 1;
55 + var->red.offset = 16; var->red.length=8;
56 + var->green.offset = 8; var->green.length=8;
57 + var->blue.offset = 0; var->blue.length=8;
59 var->red.offset = var->green.offset = var->blue.offset = var->transp.offset = 0;
61 @@ -342,7 +367,7 @@ static int pxafb_set_par(struct fb_info
63 pr_debug("pxafb: set_par\n");
65 - if (var->bits_per_pixel == 16)
66 + if (var->bits_per_pixel >= 16)
67 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
68 else if (!fbi->cmap_static)
69 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
70 @@ -355,9 +380,10 @@ static int pxafb_set_par(struct fb_info
71 fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
74 - fbi->fb.fix.line_length = var->xres_virtual *
75 - var->bits_per_pixel / 8;
76 - if (var->bits_per_pixel == 16)
77 + fbi->fb.fix.line_length = var->xres_virtual *
78 + (var->nonstd ? var->nonstd : var->bits_per_pixel) / 8;
80 + if (var->bits_per_pixel >= 16)
81 fbi->palette_size = 0;
83 fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
84 @@ -374,7 +400,7 @@ static int pxafb_set_par(struct fb_info
86 pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
88 - if (fbi->fb.var.bits_per_pixel == 16)
89 + if (fbi->fb.var.bits_per_pixel >= 16)
90 fb_dealloc_cmap(&fbi->fb.cmap);
92 fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
93 @@ -584,6 +610,14 @@ static int pxafb_activate_var(struct fb_
101 + if(var->nonstd) break;
102 + printk(KERN_ERR "%s: must specify nonstd when bit depth==%d\n",
103 + fbi->fb.fix.id, var->bits_per_pixel);
106 printk(KERN_ERR "%s: invalid bit depth %d\n",
107 fbi->fb.fix.id, var->bits_per_pixel);
108 @@ -679,7 +713,7 @@ static int pxafb_activate_var(struct fb_
109 fbi->dmadesc_palette_cpu->fidr = 0;
110 fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
112 - if (var->bits_per_pixel == 16) {
113 + if (var->bits_per_pixel >= 16) {
114 /* palette shouldn't be loaded in true-color mode */
115 fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
116 fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
117 @@ -785,8 +819,19 @@ static void pxafb_setup_gpio(struct pxaf
121 - for (gpio = 58; ldd_bits; gpio++, ldd_bits--)
122 + for (gpio = 58; min(ldd_bits,16); gpio++, ldd_bits--)
123 pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT);
125 + switch(fbi->fb.var.bits_per_pixel)
131 + pxa_gpio_mode(GPIO86_LDD_16_MD);
132 + pxa_gpio_mode(GPIO87_LDD_17_MD);
135 pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
136 pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
137 pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
138 @@ -1135,7 +1180,7 @@ static struct pxafb_info * __init pxafb_
139 fbi->fb.fix.ywrapstep = 0;
140 fbi->fb.fix.accel = FB_ACCEL_NONE;
142 - fbi->fb.var.nonstd = 0;
143 + fbi->fb.var.nonstd = mode->nonstd;
144 fbi->fb.var.activate = FB_ACTIVATE_NOW;
145 fbi->fb.var.height = -1;
146 fbi->fb.var.width = -1;
147 @@ -1161,7 +1206,7 @@ static struct pxafb_info * __init pxafb_
148 fbi->task_state = (u_char)-1;
150 for (i = 0; i < inf->num_modes; i++) {
151 - smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
152 + smemlen = mode[i].xres * mode[i].yres * (mode[i].nonstd ? mode[i].nonstd : mode[i].bpp) / 8;
153 if (smemlen > fbi->fb.fix.smem_len)
154 fbi->fb.fix.smem_len = smemlen;
156 @@ -1189,12 +1234,19 @@ static int __init pxafb_parse_options(st
157 if (!strncmp(this_opt, "mode:", 5)) {
158 const char *name = this_opt+5;
159 unsigned int namelen = strlen(name);
160 - int res_specified = 0, bpp_specified = 0;
161 - unsigned int xres = 0, yres = 0, bpp = 0;
162 + int res_specified = 0, bpp_specified = 0, nonstd_specified = 0;
163 + unsigned int xres = 0, yres = 0, bpp = 0, nonstd = 0;
164 int yres_specified = 0;
166 for (i = namelen-1; i >= 0; i--) {
169 + if (!nonstd_specified) {
170 + nonstd = simple_strtoul(&name[i+1], NULL, 0);
171 + nonstd_specified = 1;
177 if (!bpp_specified && !yres_specified) {
178 @@ -1227,12 +1279,29 @@ static int __init pxafb_parse_options(st
186 + if(nonstd_specified && (((bpp == 18 || bpp == 19) && nonstd == 24) || nonstd == 32))
188 + inf->modes[0].nonstd = nonstd;
189 + dev_info(dev, "overriding nonstd pixel packing: %d\n",nonstd);
191 + dev_err(dev, "Depth %d requires nonstd to be specified\n",bpp);
199 inf->modes[0].bpp = bpp;
200 + if(nonstd_specified) {
201 + dev_err(dev, "Depth %d requires nonstd to *not* be specified\n",bpp);
203 + inf->modes[0].nonstd = 0;
205 dev_info(dev, "overriding bit depth: %d\n", bpp);
208 Index: linux-2.6.21.7/include/asm-arm/arch-pxa/pxa-regs.h
209 ===================================================================
210 --- linux-2.6.21.7.orig/include/asm-arm/arch-pxa/pxa-regs.h
211 +++ linux-2.6.21.7/include/asm-arm/arch-pxa/pxa-regs.h
212 @@ -1323,6 +1323,8 @@
213 #define GPIO83_NSTXD 83 /* NSSP transmit */
214 #define GPIO84_NSRXD 84 /* NSSP receive */
215 #define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */
216 +#define GPIO86_LDD_16 86 /* LCD data pin 16 */
217 +#define GPIO87_LDD_17 87 /* LCD data pin 17 */
218 #define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */
219 #define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */
220 #define GPIO105_nPCE_2 105 /* Card Enable for Card Space (PXA27x) */
221 @@ -1468,6 +1470,8 @@
222 #define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT)
223 #define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN)
224 #define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT)
225 +#define GPIO86_LDD_16_MD (86 | GPIO_ALT_FN_2_OUT)
226 +#define GPIO87_LDD_17_MD (87 | GPIO_ALT_FN_2_OUT)
227 #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT)
228 #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT)
229 #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT)
230 @@ -1878,6 +1882,12 @@
231 #define LCCR3_4BPP (2 << 24)
232 #define LCCR3_8BPP (3 << 24)
233 #define LCCR3_16BPP (4 << 24)
234 +#define LCCR3_18BPP (5 << 24)
235 +#define LCCR3_18BPP_PACKED (6 << 24)
236 +#define LCCR3_19BPP (7 << 24)
237 +#define LCCR3_19BPP_PACKED (1 << 29)
238 +#define LCCR3_24BPP ((1 << 29) | (1 << 24))
239 +#define LCCR3_25BPP ((1 << 29) | (2 << 24))
241 #define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */
242 #define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */
243 Index: linux-2.6.21.7/include/asm-arm/arch-pxa/pxafb.h
244 ===================================================================
245 --- linux-2.6.21.7.orig/include/asm-arm/arch-pxa/pxafb.h
246 +++ linux-2.6.21.7/include/asm-arm/arch-pxa/pxafb.h
247 @@ -25,6 +25,7 @@ struct pxafb_mode_info {
251 + /* bpp is the path-to-screen bits per pixel, not the in-memory storage required */
255 @@ -36,7 +37,9 @@ struct pxafb_mode_info {
258 u_int cmap_greyscale:1,
260 + nonstd:8, /* nonstd represents the in-memory bits per pixel
261 + ie 24 or 32 for 18/19bpp mode, or 32 for 24/25bpp mode */
265 struct pxafb_mach_info {
266 Index: linux-2.6.21.7/arch/arm/mach-pxa/gumstix.c
267 ===================================================================
268 --- linux-2.6.21.7.orig/arch/arm/mach-pxa/gumstix.c
269 +++ linux-2.6.21.7/arch/arm/mach-pxa/gumstix.c
270 @@ -146,7 +146,8 @@ static struct pxafb_mode_info gumstix_fb
280 @@ -174,7 +175,8 @@ static struct pxafb_mode_info gumstix_fb
281 .vsync_len = 10, // VLW from datasheet: 10 typ
282 .upper_margin = 2, // VBP - VLW from datasheet: 12 - 10 = 2
283 .lower_margin = 4, // VFP from datasheet: 4 typ
287 .sync = 0, // Hsync and Vsync both active low
290 Index: linux-2.6.21.7/drivers/video/cfbfillrect.c
291 ===================================================================
292 --- linux-2.6.21.7.orig/drivers/video/cfbfillrect.c
293 +++ linux-2.6.21.7/drivers/video/cfbfillrect.c
294 @@ -62,7 +62,10 @@ pixel_to_pat( u32 bpp, u32 pixel)
295 return 0x0001001001001001ul*pixel;
297 return 0x0001000100010001ul*pixel;
302 return 0x0000000001000001ul*pixel;
304 return 0x0000000100000001ul*pixel;
305 @@ -87,7 +90,10 @@ pixel_to_pat( u32 bpp, u32 pixel)
306 return 0x00001001ul*pixel;
308 return 0x00010001ul*pixel;
313 return 0x00000001ul*pixel;
315 return 0x00000001ul*pixel;
316 @@ -346,7 +352,7 @@ void cfb_fillrect(struct fb_info *p, con
317 unsigned long pat, fg;
318 unsigned long width = rect->width, height = rect->height;
319 int bits = BITS_PER_LONG, bytes = bits >> 3;
320 - u32 bpp = p->var.bits_per_pixel;
321 + u32 bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
322 unsigned long __iomem *dst;
325 Index: linux-2.6.21.7/drivers/video/cfbimgblt.c
326 ===================================================================
327 --- linux-2.6.21.7.orig/drivers/video/cfbimgblt.c
328 +++ linux-2.6.21.7/drivers/video/cfbimgblt.c
329 @@ -83,7 +83,7 @@ static inline void color_imageblit(const
330 /* Draw the penguin */
331 u32 __iomem *dst, *dst2;
332 u32 color = 0, val, shift;
333 - int i, n, bpp = p->var.bits_per_pixel;
334 + int i, n, bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
335 u32 null_bits = 32 - bpp;
336 u32 *palette = (u32 *) p->pseudo_palette;
337 const u8 *src = image->data;
338 @@ -140,7 +140,7 @@ static inline void slow_imageblit(const
342 - u32 shift, color = 0, bpp = p->var.bits_per_pixel;
343 + u32 shift, color = 0, bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
344 u32 __iomem *dst, *dst2;
345 u32 val, pitch = p->fix.line_length;
346 u32 null_bits = 32 - bpp;
347 @@ -213,7 +213,7 @@ static inline void fast_imageblit(const
348 u8 __iomem *dst1, u32 fgcolor,
351 - u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
352 + u32 fgx = fgcolor, bgx = bgcolor, bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
353 u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
354 u32 bit_mask, end_mask, eorx, shift;
355 const char *s = image->data, *src;
356 @@ -262,7 +262,7 @@ static inline void fast_imageblit(const
357 void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
359 u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
360 - u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
361 + u32 bpl = sizeof(u32), bpp = (p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
362 u32 width = image->width;
363 u32 dx = image->dx, dy = image->dy;
365 Index: linux-2.6.21.7/drivers/video/cfbcopyarea.c
366 ===================================================================
367 --- linux-2.6.21.7.orig/drivers/video/cfbcopyarea.c
368 +++ linux-2.6.21.7/drivers/video/cfbcopyarea.c
369 @@ -365,8 +365,8 @@ void cfb_copyarea(struct fb_info *p, con
370 dst = src = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
371 dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
372 // add offset of source and target area
373 - dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
374 - src_idx += sy*bits_per_line + sx*p->var.bits_per_pixel;
375 + dst_idx += dy*bits_per_line + dx*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
376 + src_idx += sy*bits_per_line + sx*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel);
378 if (p->fbops->fb_sync)
379 p->fbops->fb_sync(p);
380 @@ -380,7 +380,7 @@ void cfb_copyarea(struct fb_info *p, con
381 src += src_idx >> (ffs(bits) - 1);
382 src_idx &= (bytes - 1);
383 bitcpy_rev(dst, dst_idx, src, src_idx, bits,
384 - width*p->var.bits_per_pixel);
385 + width*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel));
389 @@ -389,7 +389,7 @@ void cfb_copyarea(struct fb_info *p, con
390 src += src_idx >> (ffs(bits) - 1);
391 src_idx &= (bytes - 1);
392 bitcpy(dst, dst_idx, src, src_idx, bits,
393 - width*p->var.bits_per_pixel);
394 + width*(p->var.nonstd ? p->var.nonstd : p->var.bits_per_pixel));
395 dst_idx += bits_per_line;
396 src_idx += bits_per_line;
398 Index: linux-2.6.21.7/drivers/video/console/fbcon.c
399 ===================================================================
400 --- linux-2.6.21.7.orig/drivers/video/console/fbcon.c
401 +++ linux-2.6.21.7/drivers/video/console/fbcon.c
402 @@ -983,9 +983,10 @@ static const char *fbcon_startup(void)
404 DPRINTK("mode: %s\n", info->fix.id);
405 DPRINTK("visual: %d\n", info->fix.visual);
406 - DPRINTK("res: %dx%d-%d\n", info->var.xres,
407 + DPRINTK("res: %dx%d-%d(%d)\n", info->var.xres,
409 - info->var.bits_per_pixel);
410 + info->var.bits_per_pixel,
411 + info->var.nonstd ? info->var.nonstd : info->var.bits_per_pixel);
415 Index: linux-2.6.21.7/Documentation/fb/pxafb.txt
416 ===================================================================
417 --- linux-2.6.21.7.orig/Documentation/fb/pxafb.txt
418 +++ linux-2.6.21.7/Documentation/fb/pxafb.txt
419 @@ -9,11 +9,13 @@ For example:
420 or on the kernel command line
421 video=pxafb:mode:640x480-8,passive
423 -mode:XRESxYRES[-BPP]
424 +mode:XRESxYRES[-BPP[/PACKING]]
425 XRES == LCCR1_PPL + 1
426 YRES == LLCR2_LPP + 1
427 The resolution of the display in pixels
428 BPP == The bit depth. Valid values are 1, 2, 4, 8 and 16.
429 + PACKING == The in-memory bits per pixel. Valid values are 24, 32 when
433 Pixel clock in picoseconds