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