[xburst] jz4740_fb: Do not disable lcd clock during blanking. Only during
[15.05/openwrt.git] / target / linux / pxa / patches-2.6.21 / 043-pxafb-18bpp-mode.patch
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;
11          }
12          return ret;
13  }
14 @@ -204,11 +208,12 @@ static int pxafb_bpp_to_lccr3(struct fb_
15   */
16  static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var)
17  {
18 -       /*
19 -        * Period = pixclock * bits_per_byte * bytes_per_transfer
20 -        *              / memory_bits_per_pixel;
21 -        */
22 -       return var->pixclock * 8 * 16 / var->bits_per_pixel;
23 +       /*
24 +        * Period = pixclock * bits_per_byte * bytes_per_transfer
25 +        *              / memory_bits_per_pixel;
26 +        */
27 +       struct pxafb_mach_info *inf = fbi->dev->platform_data;
28 +       return var->pixclock * 8 * 16 / (var->nonstd ? var->nonstd : var->bits_per_pixel);
29  }
30  
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;
56         } else {
57                 var->red.offset = var->green.offset = var->blue.offset = var->transp.offset = 0;
58                 var->red.length   = 8;
59 @@ -342,7 +367,7 @@ static int pxafb_set_par(struct fb_info 
60  
61         pr_debug("pxafb: set_par\n");
62  
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;
70         }
71  
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;
77 +
78 +       if (var->bits_per_pixel >= 16)
79                 fbi->palette_size = 0;
80         else
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 
83          */
84         pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
85  
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);
89         else
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_
92         case 8:
93         case 16:
94                 break;
95 +       case 18:
96 +       case 19:
97 +       case 24:
98 +       case 25:
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);
102 +               break;
103         default:
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;
109  
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
116                 return;
117          }
118  
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);
122 +
123 +       switch(fbi->fb.var.bits_per_pixel)
124 +       {
125 +               case 25:
126 +               case 24:
127 +               case 19:
128 +               case 18:
129 +                       pxa_gpio_mode(GPIO86_LDD_16_MD);
130 +                       pxa_gpio_mode(GPIO87_LDD_17_MD);
131 +               default: break;
132 +       }
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;
139  
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;
147  
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;
153         }
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;
163                         int i;
164                         for (i = namelen-1; i >= 0; i--) {
165                                 switch (name[i]) {
166 +                               case '/':
167 +                                       if (!nonstd_specified) {
168 +                                               nonstd = simple_strtoul(&name[i+1], NULL, 0);
169 +                                               nonstd_specified = 1;
170 +                                       } else
171 +                                               goto done;
172 +                                       break;
173                                 case '-':
174                                         namelen = i;
175                                         if (!bpp_specified && !yres_specified) {
176 @@ -1227,12 +1279,29 @@ static int __init pxafb_parse_options(st
177                         }
178                         if (bpp_specified)
179                                 switch (bpp) {
180 +                               case 18:
181 +                               case 19:
182 +                               case 24:
183 +                               case 25:
184 +                                       if(nonstd_specified && (((bpp == 18 || bpp == 19) && nonstd == 24) || nonstd == 32))
185 +                                       {
186 +                                               inf->modes[0].nonstd = nonstd;
187 +                                               dev_info(dev, "overriding nonstd pixel packing: %d\n",nonstd);
188 +                                       } else {
189 +                                               dev_err(dev, "Depth %d requires nonstd to be specified\n",bpp);
190 +                                               break;
191 +                                       }
192                                 case 1:
193                                 case 2:
194                                 case 4:
195                                 case 8:
196                                 case 16:
197                                         inf->modes[0].bpp = bpp;
198 +                                       if(nonstd_specified) {
199 +                                               dev_err(dev, "Depth %d requires nonstd to *not* be specified\n",bpp);
200 +                                       } else {
201 +                                               inf->modes[0].nonstd = 0;
202 +                                       }
203                                         dev_info(dev, "overriding bit depth: %d\n", bpp);
204                                         break;
205                                 default:
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))
236  
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 {
242         u_short         xres;
243         u_short         yres;
244  
245 +       /* bpp is the path-to-screen bits per pixel, not the in-memory storage required */
246         u_char          bpp;
247         u_char          hsync_len;
248         u_char          left_margin;
249 @@ -36,7 +37,9 @@ struct pxafb_mode_info {
250         u_char          sync;
251  
252         u_int           cmap_greyscale:1,
253 -                       unused:31;
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 */
256 +                       unused:23;
257  };
258  
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
263         .pixclock       = 110000,
264         .xres           = 480,
265         .yres           = 272,
266 -       .bpp            = 16,
267 +       .bpp            = 18,
268 +       .nonstd         = 24,
269         .hsync_len      = 41,
270         .left_margin    = 2,
271         .right_margin   = 2,
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
276 -       .bpp            = 16,
277 +       .bpp            = 18,
278 +       .nonstd         = 24,
279         .sync           = 0, // Hsync and Vsync both active low
280  };
281  
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;
286         case 16:
287                 return 0x0001000100010001ul*pixel;
288 +       case 18:
289 +       case 19:
290         case 24:
291 +       case 25:
292                 return 0x0000000001000001ul*pixel;
293         case 32:
294                 return 0x0000000100000001ul*pixel;
295 @@ -87,7 +90,10 @@ pixel_to_pat( u32 bpp, u32 pixel)
296                 return 0x00001001ul*pixel;
297         case 16:
298                 return 0x00010001ul*pixel;
299 +       case 18:
300 +       case 19:
301         case 24:
302 +       case 25:
303                 return 0x00000001ul*pixel;
304         case 32:
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;
313         int dst_idx, left;
314  
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 
327                                   u32 start_index,
328                                   u32 pitch_index)
329  {
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, 
337                                   u32 bgcolor) 
338  {
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)
346  {
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;
352         u8 __iomem *dst1;
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);
363  
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));
372                 }
373         } else {
374                 while (height--) {
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;
383                 }
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)
387  
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,
392                 info->var.yres,
393 -               info->var.bits_per_pixel);
394 +               info->var.bits_per_pixel,
395 +               info->var.nonstd ? info->var.nonstd : info->var.bits_per_pixel);
396  
397  #ifdef CONFIG_ATARI
398         if (MACH_IS_ATARI) {
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
404  
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
412 +                       BPP == 18,19,24,25
413  
414  pixclock:PIXCLOCK
415         Pixel clock in picoseconds