1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/kernel.h>
38#include <linux/sched.h>
39#include <linux/errno.h>
40#include <linux/string.h>
41#include <linux/interrupt.h>
42#include <linux/slab.h>
43#include <linux/mm.h>
44#include <linux/fb.h>
45#include <linux/delay.h>
46#include <linux/init.h>
47#include <linux/ioport.h>
48#include <linux/cpufreq.h>
49#include <linux/platform_device.h>
50#include <linux/dma-mapping.h>
51#include <linux/clk.h>
52#include <linux/err.h>
53#include <linux/completion.h>
54#include <linux/mutex.h>
55#include <linux/kthread.h>
56#include <linux/freezer.h>
57
58#include <mach/hardware.h>
59#include <asm/io.h>
60#include <asm/irq.h>
61#include <asm/div64.h>
62#include <mach/bitfield.h>
63#include <mach/pxafb.h>
64
65
66
67
68#define DEBUG_VAR 1
69
70#include "pxafb.h"
71
72
73#define LCCR0_INVALID_CONFIG_MASK (LCCR0_OUM | LCCR0_BM | LCCR0_QDM |\
74 LCCR0_DIS | LCCR0_EFM | LCCR0_IUM |\
75 LCCR0_SFM | LCCR0_LDM | LCCR0_ENB)
76
77#define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP | LCCR3_VSP |\
78 LCCR3_PCD | LCCR3_BPP(0xf))
79
80static int pxafb_activate_var(struct fb_var_screeninfo *var,
81 struct pxafb_info *);
82static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
83static void setup_base_frame(struct pxafb_info *fbi, int branch);
84static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
85 unsigned long offset, size_t size);
86
87static unsigned long video_mem_size = 0;
88
89static inline unsigned long
90lcd_readl(struct pxafb_info *fbi, unsigned int off)
91{
92 return __raw_readl(fbi->mmio_base + off);
93}
94
95static inline void
96lcd_writel(struct pxafb_info *fbi, unsigned int off, unsigned long val)
97{
98 __raw_writel(val, fbi->mmio_base + off);
99}
100
101static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state)
102{
103 unsigned long flags;
104
105 local_irq_save(flags);
106
107
108
109
110
111
112
113
114
115
116 if (fbi->task_state == C_ENABLE && state == C_REENABLE)
117 state = (u_int) -1;
118 if (fbi->task_state == C_DISABLE && state == C_ENABLE)
119 state = C_REENABLE;
120
121 if (state != (u_int)-1) {
122 fbi->task_state = state;
123 schedule_work(&fbi->task);
124 }
125 local_irq_restore(flags);
126}
127
128static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
129{
130 chan &= 0xffff;
131 chan >>= 16 - bf->length;
132 return chan << bf->offset;
133}
134
135static int
136pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
137 u_int trans, struct fb_info *info)
138{
139 struct pxafb_info *fbi = (struct pxafb_info *)info;
140 u_int val;
141
142 if (regno >= fbi->palette_size)
143 return 1;
144
145 if (fbi->fb.var.grayscale) {
146 fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff);
147 return 0;
148 }
149
150 switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) {
151 case LCCR4_PAL_FOR_0:
152 val = ((red >> 0) & 0xf800);
153 val |= ((green >> 5) & 0x07e0);
154 val |= ((blue >> 11) & 0x001f);
155 fbi->palette_cpu[regno] = val;
156 break;
157 case LCCR4_PAL_FOR_1:
158 val = ((red << 8) & 0x00f80000);
159 val |= ((green >> 0) & 0x0000fc00);
160 val |= ((blue >> 8) & 0x000000f8);
161 ((u32 *)(fbi->palette_cpu))[regno] = val;
162 break;
163 case LCCR4_PAL_FOR_2:
164 val = ((red << 8) & 0x00fc0000);
165 val |= ((green >> 0) & 0x0000fc00);
166 val |= ((blue >> 8) & 0x000000fc);
167 ((u32 *)(fbi->palette_cpu))[regno] = val;
168 break;
169 case LCCR4_PAL_FOR_3:
170 val = ((red << 8) & 0x00ff0000);
171 val |= ((green >> 0) & 0x0000ff00);
172 val |= ((blue >> 8) & 0x000000ff);
173 ((u32 *)(fbi->palette_cpu))[regno] = val;
174 break;
175 }
176
177 return 0;
178}
179
180static int
181pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
182 u_int trans, struct fb_info *info)
183{
184 struct pxafb_info *fbi = (struct pxafb_info *)info;
185 unsigned int val;
186 int ret = 1;
187
188
189
190
191
192
193
194 if (fbi->cmap_inverse) {
195 red = 0xffff - red;
196 green = 0xffff - green;
197 blue = 0xffff - blue;
198 }
199
200
201
202
203
204 if (fbi->fb.var.grayscale)
205 red = green = blue = (19595 * red + 38470 * green +
206 7471 * blue) >> 16;
207
208 switch (fbi->fb.fix.visual) {
209 case FB_VISUAL_TRUECOLOR:
210
211
212
213
214 if (regno < 16) {
215 u32 *pal = fbi->fb.pseudo_palette;
216
217 val = chan_to_field(red, &fbi->fb.var.red);
218 val |= chan_to_field(green, &fbi->fb.var.green);
219 val |= chan_to_field(blue, &fbi->fb.var.blue);
220
221 pal[regno] = val;
222 ret = 0;
223 }
224 break;
225
226 case FB_VISUAL_STATIC_PSEUDOCOLOR:
227 case FB_VISUAL_PSEUDOCOLOR:
228 ret = pxafb_setpalettereg(regno, red, green, blue, trans, info);
229 break;
230 }
231
232 return ret;
233}
234
235
236static inline int var_to_depth(struct fb_var_screeninfo *var)
237{
238 return var->red.length + var->green.length +
239 var->blue.length + var->transp.length;
240}
241
242
243static int pxafb_var_to_bpp(struct fb_var_screeninfo *var)
244{
245 int bpp = -EINVAL;
246
247 switch (var->bits_per_pixel) {
248 case 1: bpp = 0; break;
249 case 2: bpp = 1; break;
250 case 4: bpp = 2; break;
251 case 8: bpp = 3; break;
252 case 16: bpp = 4; break;
253 case 24:
254 switch (var_to_depth(var)) {
255 case 18: bpp = 6; break;
256 case 19: bpp = 8; break;
257 case 24: bpp = 9; break;
258 }
259 break;
260 case 32:
261 switch (var_to_depth(var)) {
262 case 18: bpp = 5; break;
263 case 19: bpp = 7; break;
264 case 25: bpp = 10; break;
265 }
266 break;
267 }
268 return bpp;
269}
270
271
272
273
274
275
276
277
278
279
280
281
282static uint32_t pxafb_var_to_lccr3(struct fb_var_screeninfo *var)
283{
284 int bpp = pxafb_var_to_bpp(var);
285 uint32_t lccr3;
286
287 if (bpp < 0)
288 return 0;
289
290 lccr3 = LCCR3_BPP(bpp);
291
292 switch (var_to_depth(var)) {
293 case 16: lccr3 |= var->transp.length ? LCCR3_PDFOR_3 : 0; break;
294 case 18: lccr3 |= LCCR3_PDFOR_3; break;
295 case 24: lccr3 |= var->transp.length ? LCCR3_PDFOR_2 : LCCR3_PDFOR_3;
296 break;
297 case 19:
298 case 25: lccr3 |= LCCR3_PDFOR_0; break;
299 }
300 return lccr3;
301}
302
303#define SET_PIXFMT(v, r, g, b, t) \
304({ \
305 (v)->transp.offset = (t) ? (r) + (g) + (b) : 0; \
306 (v)->transp.length = (t) ? (t) : 0; \
307 (v)->blue.length = (b); (v)->blue.offset = 0; \
308 (v)->green.length = (g); (v)->green.offset = (b); \
309 (v)->red.length = (r); (v)->red.offset = (b) + (g); \
310})
311
312
313
314
315static void pxafb_set_pixfmt(struct fb_var_screeninfo *var, int depth)
316{
317 if (depth == 0)
318 depth = var->bits_per_pixel;
319
320 if (var->bits_per_pixel < 16) {
321
322 var->red.offset = 0; var->red.length = 8;
323 var->green.offset = 0; var->green.length = 8;
324 var->blue.offset = 0; var->blue.length = 8;
325 var->transp.offset = 0; var->transp.length = 8;
326 }
327
328 switch (depth) {
329 case 16: var->transp.length ?
330 SET_PIXFMT(var, 5, 5, 5, 1) :
331 SET_PIXFMT(var, 5, 6, 5, 0); break;
332 case 18: SET_PIXFMT(var, 6, 6, 6, 0); break;
333 case 19: SET_PIXFMT(var, 6, 6, 6, 1); break;
334 case 24: var->transp.length ?
335 SET_PIXFMT(var, 8, 8, 7, 1) :
336 SET_PIXFMT(var, 8, 8, 8, 0); break;
337 case 25: SET_PIXFMT(var, 8, 8, 8, 1); break;
338 }
339}
340
341#ifdef CONFIG_CPU_FREQ
342
343
344
345
346
347
348static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var)
349{
350
351
352
353
354 return var->pixclock * 8 * 16 / var->bits_per_pixel;
355}
356#endif
357
358
359
360
361
362static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach,
363 struct fb_var_screeninfo *var)
364{
365 struct pxafb_mode_info *mode = NULL;
366 struct pxafb_mode_info *modelist = mach->modes;
367 unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
368 unsigned int i;
369
370 for (i = 0; i < mach->num_modes; i++) {
371 if (modelist[i].xres >= var->xres &&
372 modelist[i].yres >= var->yres &&
373 modelist[i].xres < best_x &&
374 modelist[i].yres < best_y &&
375 modelist[i].bpp >= var->bits_per_pixel) {
376 best_x = modelist[i].xres;
377 best_y = modelist[i].yres;
378 mode = &modelist[i];
379 }
380 }
381
382 return mode;
383}
384
385static void pxafb_setmode(struct fb_var_screeninfo *var,
386 struct pxafb_mode_info *mode)
387{
388 var->xres = mode->xres;
389 var->yres = mode->yres;
390 var->bits_per_pixel = mode->bpp;
391 var->pixclock = mode->pixclock;
392 var->hsync_len = mode->hsync_len;
393 var->left_margin = mode->left_margin;
394 var->right_margin = mode->right_margin;
395 var->vsync_len = mode->vsync_len;
396 var->upper_margin = mode->upper_margin;
397 var->lower_margin = mode->lower_margin;
398 var->sync = mode->sync;
399 var->grayscale = mode->cmap_greyscale;
400
401
402 pxafb_set_pixfmt(var, mode->depth);
403}
404
405static int pxafb_adjust_timing(struct pxafb_info *fbi,
406 struct fb_var_screeninfo *var)
407{
408 int line_length;
409
410 var->xres = max_t(int, var->xres, MIN_XRES);
411 var->yres = max_t(int, var->yres, MIN_YRES);
412
413 if (!(fbi->lccr0 & LCCR0_LCDT)) {
414 clamp_val(var->hsync_len, 1, 64);
415 clamp_val(var->vsync_len, 1, 64);
416 clamp_val(var->left_margin, 1, 255);
417 clamp_val(var->right_margin, 1, 255);
418 clamp_val(var->upper_margin, 1, 255);
419 clamp_val(var->lower_margin, 1, 255);
420 }
421
422
423 line_length = var->xres * var->bits_per_pixel / 8;
424 line_length = ALIGN(line_length, 4);
425 var->xres = line_length * 8 / var->bits_per_pixel;
426
427
428 var->xres_virtual = var->xres;
429
430 if (var->accel_flags & FB_ACCELF_TEXT)
431 var->yres_virtual = fbi->fb.fix.smem_len / line_length;
432 else
433 var->yres_virtual = max(var->yres_virtual, var->yres);
434
435
436 if (var->xres > MAX_XRES || var->yres > MAX_YRES)
437 return -EINVAL;
438
439 if (var->yres > var->yres_virtual)
440 return -EINVAL;
441
442 return 0;
443}
444
445
446
447
448
449
450
451
452
453
454static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
455{
456 struct pxafb_info *fbi = (struct pxafb_info *)info;
457 struct pxafb_mach_info *inf = fbi->dev->platform_data;
458 int err;
459
460 if (inf->fixed_modes) {
461 struct pxafb_mode_info *mode;
462
463 mode = pxafb_getmode(inf, var);
464 if (!mode)
465 return -EINVAL;
466 pxafb_setmode(var, mode);
467 }
468
469
470 err = pxafb_var_to_bpp(var);
471 if (err < 0)
472 return err;
473
474 pxafb_set_pixfmt(var, var_to_depth(var));
475
476 err = pxafb_adjust_timing(fbi, var);
477 if (err)
478 return err;
479
480#ifdef CONFIG_CPU_FREQ
481 pr_debug("pxafb: dma period = %d ps\n",
482 pxafb_display_dma_period(var));
483#endif
484
485 return 0;
486}
487
488
489
490
491
492static int pxafb_set_par(struct fb_info *info)
493{
494 struct pxafb_info *fbi = (struct pxafb_info *)info;
495 struct fb_var_screeninfo *var = &info->var;
496
497 if (var->bits_per_pixel >= 16)
498 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
499 else if (!fbi->cmap_static)
500 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
501 else {
502
503
504
505
506
507 fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
508 }
509
510 fbi->fb.fix.line_length = var->xres_virtual *
511 var->bits_per_pixel / 8;
512 if (var->bits_per_pixel >= 16)
513 fbi->palette_size = 0;
514 else
515 fbi->palette_size = var->bits_per_pixel == 1 ?
516 4 : 1 << var->bits_per_pixel;
517
518 fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0];
519
520 if (fbi->fb.var.bits_per_pixel >= 16)
521 fb_dealloc_cmap(&fbi->fb.cmap);
522 else
523 fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
524
525 pxafb_activate_var(var, fbi);
526
527 return 0;
528}
529
530static int pxafb_pan_display(struct fb_var_screeninfo *var,
531 struct fb_info *info)
532{
533 struct pxafb_info *fbi = (struct pxafb_info *)info;
534 int dma = DMA_MAX + DMA_BASE;
535
536 if (fbi->state != C_ENABLE)
537 return 0;
538
539 setup_base_frame(fbi, 1);
540
541 if (fbi->lccr0 & LCCR0_SDS)
542 lcd_writel(fbi, FBR1, fbi->fdadr[dma + 1] | 0x1);
543
544 lcd_writel(fbi, FBR0, fbi->fdadr[dma] | 0x1);
545 return 0;
546}
547
548
549
550
551
552
553
554static int pxafb_blank(int blank, struct fb_info *info)
555{
556 struct pxafb_info *fbi = (struct pxafb_info *)info;
557 int i;
558
559 switch (blank) {
560 case FB_BLANK_POWERDOWN:
561 case FB_BLANK_VSYNC_SUSPEND:
562 case FB_BLANK_HSYNC_SUSPEND:
563 case FB_BLANK_NORMAL:
564 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
565 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
566 for (i = 0; i < fbi->palette_size; i++)
567 pxafb_setpalettereg(i, 0, 0, 0, 0, info);
568
569 pxafb_schedule_work(fbi, C_DISABLE);
570
571 break;
572
573 case FB_BLANK_UNBLANK:
574
575 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
576 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
577 fb_set_cmap(&fbi->fb.cmap, info);
578 pxafb_schedule_work(fbi, C_ENABLE);
579 }
580 return 0;
581}
582
583static struct fb_ops pxafb_ops = {
584 .owner = THIS_MODULE,
585 .fb_check_var = pxafb_check_var,
586 .fb_set_par = pxafb_set_par,
587 .fb_pan_display = pxafb_pan_display,
588 .fb_setcolreg = pxafb_setcolreg,
589 .fb_fillrect = cfb_fillrect,
590 .fb_copyarea = cfb_copyarea,
591 .fb_imageblit = cfb_imageblit,
592 .fb_blank = pxafb_blank,
593};
594
595#ifdef CONFIG_FB_PXA_OVERLAY
596static void overlay1fb_setup(struct pxafb_layer *ofb)
597{
598 int size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual;
599 unsigned long start = ofb->video_mem_phys;
600 setup_frame_dma(ofb->fbi, DMA_OV1, PAL_NONE, start, size);
601}
602
603
604
605
606static void overlay1fb_enable(struct pxafb_layer *ofb)
607{
608 int enabled = lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN;
609 uint32_t fdadr1 = ofb->fbi->fdadr[DMA_OV1] | (enabled ? 0x1 : 0);
610
611 lcd_writel(ofb->fbi, enabled ? FBR1 : FDADR1, fdadr1);
612 lcd_writel(ofb->fbi, OVL1C2, ofb->control[1]);
613 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] | OVLxC1_OEN);
614}
615
616static void overlay1fb_disable(struct pxafb_layer *ofb)
617{
618 uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
619
620 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
621
622 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
623 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));
624 lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
625
626 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
627 pr_warning("%s: timeout disabling overlay1\n", __func__);
628
629 lcd_writel(ofb->fbi, LCCR5, lccr5);
630}
631
632static void overlay2fb_setup(struct pxafb_layer *ofb)
633{
634 int size, div = 1, pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd);
635 unsigned long start[3] = { ofb->video_mem_phys, 0, 0 };
636
637 if (pfor == OVERLAY_FORMAT_RGB || pfor == OVERLAY_FORMAT_YUV444_PACKED) {
638 size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual;
639 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size);
640 } else {
641 size = ofb->fb.var.xres_virtual * ofb->fb.var.yres_virtual;
642 switch (pfor) {
643 case OVERLAY_FORMAT_YUV444_PLANAR: div = 1; break;
644 case OVERLAY_FORMAT_YUV422_PLANAR: div = 2; break;
645 case OVERLAY_FORMAT_YUV420_PLANAR: div = 4; break;
646 }
647 start[1] = start[0] + size;
648 start[2] = start[1] + size / div;
649 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size);
650 setup_frame_dma(ofb->fbi, DMA_OV2_Cb, -1, start[1], size / div);
651 setup_frame_dma(ofb->fbi, DMA_OV2_Cr, -1, start[2], size / div);
652 }
653}
654
655static void overlay2fb_enable(struct pxafb_layer *ofb)
656{
657 int pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd);
658 int enabled = lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN;
659 uint32_t fdadr2 = ofb->fbi->fdadr[DMA_OV2_Y] | (enabled ? 0x1 : 0);
660 uint32_t fdadr3 = ofb->fbi->fdadr[DMA_OV2_Cb] | (enabled ? 0x1 : 0);
661 uint32_t fdadr4 = ofb->fbi->fdadr[DMA_OV2_Cr] | (enabled ? 0x1 : 0);
662
663 if (pfor == OVERLAY_FORMAT_RGB || pfor == OVERLAY_FORMAT_YUV444_PACKED)
664 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2);
665 else {
666 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2);
667 lcd_writel(ofb->fbi, enabled ? FBR3 : FDADR3, fdadr3);
668 lcd_writel(ofb->fbi, enabled ? FBR4 : FDADR4, fdadr4);
669 }
670 lcd_writel(ofb->fbi, OVL2C2, ofb->control[1]);
671 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] | OVLxC1_OEN);
672}
673
674static void overlay2fb_disable(struct pxafb_layer *ofb)
675{
676 uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
677
678 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
679
680 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
681 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));
682 lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);
683 lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);
684 lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
685
686 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
687 pr_warning("%s: timeout disabling overlay2\n", __func__);
688}
689
690static struct pxafb_layer_ops ofb_ops[] = {
691 [0] = {
692 .enable = overlay1fb_enable,
693 .disable = overlay1fb_disable,
694 .setup = overlay1fb_setup,
695 },
696 [1] = {
697 .enable = overlay2fb_enable,
698 .disable = overlay2fb_disable,
699 .setup = overlay2fb_setup,
700 },
701};
702
703static int overlayfb_open(struct fb_info *info, int user)
704{
705 struct pxafb_layer *ofb = (struct pxafb_layer *)info;
706
707
708 if (user == 0)
709 return -ENODEV;
710
711
712 if (atomic_inc_and_test(&ofb->usage))
713 return -EBUSY;
714
715
716 fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
717 return 0;
718}
719
720static int overlayfb_release(struct fb_info *info, int user)
721{
722 struct pxafb_layer *ofb = (struct pxafb_layer*) info;
723
724 atomic_dec(&ofb->usage);
725 ofb->ops->disable(ofb);
726
727 free_pages_exact(ofb->video_mem, ofb->video_mem_size);
728 ofb->video_mem = NULL;
729 ofb->video_mem_size = 0;
730 return 0;
731}
732
733static int overlayfb_check_var(struct fb_var_screeninfo *var,
734 struct fb_info *info)
735{
736 struct pxafb_layer *ofb = (struct pxafb_layer *)info;
737 struct fb_var_screeninfo *base_var = &ofb->fbi->fb.var;
738 int xpos, ypos, pfor, bpp;
739
740 xpos = NONSTD_TO_XPOS(var->nonstd);
741 ypos = NONSTD_TO_XPOS(var->nonstd);
742 pfor = NONSTD_TO_PFOR(var->nonstd);
743
744 bpp = pxafb_var_to_bpp(var);
745 if (bpp < 0)
746 return -EINVAL;
747
748
749 if (ofb->id == OVERLAY1 && pfor != 0)
750 return -EINVAL;
751
752
753 switch (pfor) {
754 case OVERLAY_FORMAT_RGB:
755 bpp = pxafb_var_to_bpp(var);
756 if (bpp < 0)
757 return -EINVAL;
758
759 pxafb_set_pixfmt(var, var_to_depth(var));
760 break;
761 case OVERLAY_FORMAT_YUV444_PACKED: bpp = 24; break;
762 case OVERLAY_FORMAT_YUV444_PLANAR: bpp = 8; break;
763 case OVERLAY_FORMAT_YUV422_PLANAR: bpp = 4; break;
764 case OVERLAY_FORMAT_YUV420_PLANAR: bpp = 2; break;
765 default:
766 return -EINVAL;
767 }
768
769
770 if ((xpos * bpp) % 32)
771 return -EINVAL;
772
773
774 var->xres = roundup(var->xres * bpp, 32) / bpp;
775
776 if ((xpos + var->xres > base_var->xres) ||
777 (ypos + var->yres > base_var->yres))
778 return -EINVAL;
779
780 var->xres_virtual = var->xres;
781 var->yres_virtual = max(var->yres, var->yres_virtual);
782 return 0;
783}
784
785static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
786{
787 struct fb_var_screeninfo *var = &ofb->fb.var;
788 int pfor = NONSTD_TO_PFOR(var->nonstd);
789 int size, bpp = 0;
790
791 switch (pfor) {
792 case OVERLAY_FORMAT_RGB: bpp = var->bits_per_pixel; break;
793 case OVERLAY_FORMAT_YUV444_PACKED: bpp = 24; break;
794 case OVERLAY_FORMAT_YUV444_PLANAR: bpp = 24; break;
795 case OVERLAY_FORMAT_YUV422_PLANAR: bpp = 16; break;
796 case OVERLAY_FORMAT_YUV420_PLANAR: bpp = 12; break;
797 }
798
799 ofb->fb.fix.line_length = var->xres_virtual * bpp / 8;
800
801 size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
802
803
804 if (ofb->video_mem) {
805 if (ofb->video_mem_size >= size)
806 return 0;
807
808 free_pages_exact(ofb->video_mem, ofb->video_mem_size);
809 }
810
811 ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
812 if (ofb->video_mem == NULL)
813 return -ENOMEM;
814
815 ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
816 ofb->video_mem_size = size;
817
818 mutex_lock(&ofb->fb.mm_lock);
819 ofb->fb.fix.smem_start = ofb->video_mem_phys;
820 ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual;
821 mutex_unlock(&ofb->fb.mm_lock);
822 ofb->fb.screen_base = ofb->video_mem;
823 return 0;
824}
825
826static int overlayfb_set_par(struct fb_info *info)
827{
828 struct pxafb_layer *ofb = (struct pxafb_layer *)info;
829 struct fb_var_screeninfo *var = &info->var;
830 int xpos, ypos, pfor, bpp, ret;
831
832 ret = overlayfb_map_video_memory(ofb);
833 if (ret)
834 return ret;
835
836 bpp = pxafb_var_to_bpp(var);
837 xpos = NONSTD_TO_XPOS(var->nonstd);
838 ypos = NONSTD_TO_XPOS(var->nonstd);
839 pfor = NONSTD_TO_PFOR(var->nonstd);
840
841 ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
842 OVLxC1_BPP(bpp);
843 ofb->control[1] = OVLxC2_XPOS(xpos) | OVLxC2_YPOS(ypos);
844
845 if (ofb->id == OVERLAY2)
846 ofb->control[1] |= OVL2C2_PFOR(pfor);
847
848 ofb->ops->setup(ofb);
849 ofb->ops->enable(ofb);
850 return 0;
851}
852
853static struct fb_ops overlay_fb_ops = {
854 .owner = THIS_MODULE,
855 .fb_open = overlayfb_open,
856 .fb_release = overlayfb_release,
857 .fb_check_var = overlayfb_check_var,
858 .fb_set_par = overlayfb_set_par,
859};
860
861static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
862 struct pxafb_layer *ofb, int id)
863{
864 sprintf(ofb->fb.fix.id, "overlay%d", id + 1);
865
866 ofb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
867 ofb->fb.fix.xpanstep = 0;
868 ofb->fb.fix.ypanstep = 1;
869
870 ofb->fb.var.activate = FB_ACTIVATE_NOW;
871 ofb->fb.var.height = -1;
872 ofb->fb.var.width = -1;
873 ofb->fb.var.vmode = FB_VMODE_NONINTERLACED;
874
875 ofb->fb.fbops = &overlay_fb_ops;
876 ofb->fb.flags = FBINFO_FLAG_DEFAULT;
877 ofb->fb.node = -1;
878 ofb->fb.pseudo_palette = NULL;
879
880 ofb->id = id;
881 ofb->ops = &ofb_ops[id];
882 atomic_set(&ofb->usage, 0);
883 ofb->fbi = fbi;
884 init_completion(&ofb->branch_done);
885}
886
887static inline int pxafb_overlay_supported(void)
888{
889 if (cpu_is_pxa27x() || cpu_is_pxa3xx())
890 return 1;
891
892 return 0;
893}
894
895static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
896{
897 int i, ret;
898
899 if (!pxafb_overlay_supported())
900 return 0;
901
902 for (i = 0; i < 2; i++) {
903 init_pxafb_overlay(fbi, &fbi->overlay[i], i);
904 ret = register_framebuffer(&fbi->overlay[i].fb);
905 if (ret) {
906 dev_err(fbi->dev, "failed to register overlay %d\n", i);
907 return ret;
908 }
909 }
910
911
912 lcd_writel(fbi, LCCR5, ~0);
913
914
915 fbi->lccr0 |= LCCR0_OUC;
916 pr_info("PXA Overlay driver loaded successfully!\n");
917 return 0;
918}
919
920static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
921{
922 int i;
923
924 if (!pxafb_overlay_supported())
925 return;
926
927 for (i = 0; i < 2; i++)
928 unregister_framebuffer(&fbi->overlay[i].fb);
929}
930#else
931static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
932static inline void pxafb_overlay_exit(struct pxafb_info *fbi) {}
933#endif
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965static inline unsigned int get_pcd(struct pxafb_info *fbi,
966 unsigned int pixclock)
967{
968 unsigned long long pcd;
969
970
971
972
973 pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000);
974 pcd *= pixclock;
975 do_div(pcd, 100000000 * 2);
976
977
978 return (unsigned int)pcd;
979}
980
981
982
983
984
985
986
987static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
988{
989 unsigned long htime;
990
991 if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
992 fbi->hsync_time = 0;
993 return;
994 }
995
996 htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len);
997
998 fbi->hsync_time = htime;
999}
1000
1001unsigned long pxafb_get_hsync_time(struct device *dev)
1002{
1003 struct pxafb_info *fbi = dev_get_drvdata(dev);
1004
1005
1006 if (!fbi || (fbi->state != C_ENABLE))
1007 return 0;
1008
1009 return fbi->hsync_time;
1010}
1011EXPORT_SYMBOL(pxafb_get_hsync_time);
1012
1013static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
1014 unsigned long start, size_t size)
1015{
1016 struct pxafb_dma_descriptor *dma_desc, *pal_desc;
1017 unsigned int dma_desc_off, pal_desc_off;
1018
1019 if (dma < 0 || dma >= DMA_MAX * 2)
1020 return -EINVAL;
1021
1022 dma_desc = &fbi->dma_buff->dma_desc[dma];
1023 dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[dma]);
1024
1025 dma_desc->fsadr = start;
1026 dma_desc->fidr = 0;
1027 dma_desc->ldcmd = size;
1028
1029 if (pal < 0 || pal >= PAL_MAX * 2) {
1030 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
1031 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
1032 } else {
1033 pal_desc = &fbi->dma_buff->pal_desc[pal];
1034 pal_desc_off = offsetof(struct pxafb_dma_buff, pal_desc[pal]);
1035
1036 pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE;
1037 pal_desc->fidr = 0;
1038
1039 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
1040 pal_desc->ldcmd = fbi->palette_size * sizeof(u16);
1041 else
1042 pal_desc->ldcmd = fbi->palette_size * sizeof(u32);
1043
1044 pal_desc->ldcmd |= LDCMD_PAL;
1045
1046
1047 pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
1048 dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off;
1049 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
1050 }
1051
1052 return 0;
1053}
1054
1055static void setup_base_frame(struct pxafb_info *fbi, int branch)
1056{
1057 struct fb_var_screeninfo *var = &fbi->fb.var;
1058 struct fb_fix_screeninfo *fix = &fbi->fb.fix;
1059 int nbytes, dma, pal, bpp = var->bits_per_pixel;
1060 unsigned long offset;
1061
1062 dma = DMA_BASE + (branch ? DMA_MAX : 0);
1063 pal = (bpp >= 16) ? PAL_NONE : PAL_BASE + (branch ? PAL_MAX : 0);
1064
1065 nbytes = fix->line_length * var->yres;
1066 offset = fix->line_length * var->yoffset + fbi->video_mem_phys;
1067
1068 if (fbi->lccr0 & LCCR0_SDS) {
1069 nbytes = nbytes / 2;
1070 setup_frame_dma(fbi, dma + 1, PAL_NONE, offset + nbytes, nbytes);
1071 }
1072
1073 setup_frame_dma(fbi, dma, pal, offset, nbytes);
1074}
1075
1076#ifdef CONFIG_FB_PXA_SMARTPANEL
1077static int setup_smart_dma(struct pxafb_info *fbi)
1078{
1079 struct pxafb_dma_descriptor *dma_desc;
1080 unsigned long dma_desc_off, cmd_buff_off;
1081
1082 dma_desc = &fbi->dma_buff->dma_desc[DMA_CMD];
1083 dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[DMA_CMD]);
1084 cmd_buff_off = offsetof(struct pxafb_dma_buff, cmd_buff);
1085
1086 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
1087 dma_desc->fsadr = fbi->dma_buff_phys + cmd_buff_off;
1088 dma_desc->fidr = 0;
1089 dma_desc->ldcmd = fbi->n_smart_cmds * sizeof(uint16_t);
1090
1091 fbi->fdadr[DMA_CMD] = dma_desc->fdadr;
1092 return 0;
1093}
1094
1095int pxafb_smart_flush(struct fb_info *info)
1096{
1097 struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb);
1098 uint32_t prsr;
1099 int ret = 0;
1100
1101
1102 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1103
1104
1105
1106
1107
1108
1109 while (fbi->n_smart_cmds & 1)
1110 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_NOOP;
1111
1112 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_INTERRUPT;
1113 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_WAIT_FOR_VSYNC;
1114 setup_smart_dma(fbi);
1115
1116
1117 prsr = lcd_readl(fbi, PRSR) | PRSR_ST_OK | PRSR_CON_NT;
1118 lcd_writel(fbi, PRSR, prsr);
1119
1120
1121 lcd_writel(fbi, CMDCR, 0x0001);
1122
1123
1124 lcd_writel(fbi, LCCR5, LCCR5_IUM(6));
1125
1126 lcd_writel(fbi, LCCR1, fbi->reg_lccr1);
1127 lcd_writel(fbi, LCCR2, fbi->reg_lccr2);
1128 lcd_writel(fbi, LCCR3, fbi->reg_lccr3);
1129 lcd_writel(fbi, LCCR4, fbi->reg_lccr4);
1130 lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
1131 lcd_writel(fbi, FDADR6, fbi->fdadr[6]);
1132
1133
1134 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
1135
1136 if (wait_for_completion_timeout(&fbi->command_done, HZ/2) == 0) {
1137 pr_warning("%s: timeout waiting for command done\n",
1138 __func__);
1139 ret = -ETIMEDOUT;
1140 }
1141
1142
1143 prsr = lcd_readl(fbi, PRSR) & ~(PRSR_ST_OK | PRSR_CON_NT);
1144 lcd_writel(fbi, PRSR, prsr);
1145 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1146 lcd_writel(fbi, FDADR6, 0);
1147 fbi->n_smart_cmds = 0;
1148 return ret;
1149}
1150
1151int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int n_cmds)
1152{
1153 int i;
1154 struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb);
1155
1156 for (i = 0; i < n_cmds; i++, cmds++) {
1157
1158 if ((*cmds & 0xff00) == SMART_CMD_DELAY) {
1159 pxafb_smart_flush(info);
1160 mdelay(*cmds & 0xff);
1161 continue;
1162 }
1163
1164
1165 if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8)
1166 pxafb_smart_flush(info);
1167
1168 fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds;
1169 }
1170
1171 return 0;
1172}
1173
1174static unsigned int __smart_timing(unsigned time_ns, unsigned long lcd_clk)
1175{
1176 unsigned int t = (time_ns * (lcd_clk / 1000000) / 1000);
1177 return (t == 0) ? 1 : t;
1178}
1179
1180static void setup_smart_timing(struct pxafb_info *fbi,
1181 struct fb_var_screeninfo *var)
1182{
1183 struct pxafb_mach_info *inf = fbi->dev->platform_data;
1184 struct pxafb_mode_info *mode = &inf->modes[0];
1185 unsigned long lclk = clk_get_rate(fbi->clk);
1186 unsigned t1, t2, t3, t4;
1187
1188 t1 = max(mode->a0csrd_set_hld, mode->a0cswr_set_hld);
1189 t2 = max(mode->rd_pulse_width, mode->wr_pulse_width);
1190 t3 = mode->op_hold_time;
1191 t4 = mode->cmd_inh_time;
1192
1193 fbi->reg_lccr1 =
1194 LCCR1_DisWdth(var->xres) |
1195 LCCR1_BegLnDel(__smart_timing(t1, lclk)) |
1196 LCCR1_EndLnDel(__smart_timing(t2, lclk)) |
1197 LCCR1_HorSnchWdth(__smart_timing(t3, lclk));
1198
1199 fbi->reg_lccr2 = LCCR2_DisHght(var->yres);
1200 fbi->reg_lccr3 = fbi->lccr3 | LCCR3_PixClkDiv(__smart_timing(t4, lclk));
1201 fbi->reg_lccr3 |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HSP : 0;
1202 fbi->reg_lccr3 |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VSP : 0;
1203
1204
1205 fbi->reg_cmdcr = 1;
1206}
1207
1208static int pxafb_smart_thread(void *arg)
1209{
1210 struct pxafb_info *fbi = arg;
1211 struct pxafb_mach_info *inf = fbi->dev->platform_data;
1212
1213 if (!fbi || !inf->smart_update) {
1214 pr_err("%s: not properly initialized, thread terminated\n",
1215 __func__);
1216 return -EINVAL;
1217 }
1218
1219 pr_debug("%s(): task starting\n", __func__);
1220
1221 set_freezable();
1222 while (!kthread_should_stop()) {
1223
1224 if (try_to_freeze())
1225 continue;
1226
1227 mutex_lock(&fbi->ctrlr_lock);
1228
1229 if (fbi->state == C_ENABLE) {
1230 inf->smart_update(&fbi->fb);
1231 complete(&fbi->refresh_done);
1232 }
1233
1234 mutex_unlock(&fbi->ctrlr_lock);
1235
1236 set_current_state(TASK_INTERRUPTIBLE);
1237 schedule_timeout(30 * HZ / 1000);
1238 }
1239
1240 pr_debug("%s(): task ending\n", __func__);
1241 return 0;
1242}
1243
1244static int pxafb_smart_init(struct pxafb_info *fbi)
1245{
1246 if (!(fbi->lccr0 & LCCR0_LCDT))
1247 return 0;
1248
1249 fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff;
1250 fbi->n_smart_cmds = 0;
1251
1252 init_completion(&fbi->command_done);
1253 init_completion(&fbi->refresh_done);
1254
1255 fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi,
1256 "lcd_refresh");
1257 if (IS_ERR(fbi->smart_thread)) {
1258 pr_err("%s: unable to create kernel thread\n", __func__);
1259 return PTR_ERR(fbi->smart_thread);
1260 }
1261
1262 return 0;
1263}
1264#else
1265int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int n_cmds)
1266{
1267 return 0;
1268}
1269
1270int pxafb_smart_flush(struct fb_info *info)
1271{
1272 return 0;
1273}
1274
1275static inline int pxafb_smart_init(struct pxafb_info *fbi) { return 0; }
1276#endif
1277
1278static void setup_parallel_timing(struct pxafb_info *fbi,
1279 struct fb_var_screeninfo *var)
1280{
1281 unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
1282
1283 fbi->reg_lccr1 =
1284 LCCR1_DisWdth(var->xres) +
1285 LCCR1_HorSnchWdth(var->hsync_len) +
1286 LCCR1_BegLnDel(var->left_margin) +
1287 LCCR1_EndLnDel(var->right_margin);
1288
1289
1290
1291
1292
1293 lines_per_panel = var->yres;
1294 if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
1295 lines_per_panel /= 2;
1296
1297 fbi->reg_lccr2 =
1298 LCCR2_DisHght(lines_per_panel) +
1299 LCCR2_VrtSnchWdth(var->vsync_len) +
1300 LCCR2_BegFrmDel(var->upper_margin) +
1301 LCCR2_EndFrmDel(var->lower_margin);
1302
1303 fbi->reg_lccr3 = fbi->lccr3 |
1304 (var->sync & FB_SYNC_HOR_HIGH_ACT ?
1305 LCCR3_HorSnchH : LCCR3_HorSnchL) |
1306 (var->sync & FB_SYNC_VERT_HIGH_ACT ?
1307 LCCR3_VrtSnchH : LCCR3_VrtSnchL);
1308
1309 if (pcd) {
1310 fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd);
1311 set_hsync_time(fbi, pcd);
1312 }
1313}
1314
1315
1316
1317
1318
1319
1320static int pxafb_activate_var(struct fb_var_screeninfo *var,
1321 struct pxafb_info *fbi)
1322{
1323 u_long flags;
1324
1325
1326 local_irq_save(flags);
1327
1328#ifdef CONFIG_FB_PXA_SMARTPANEL
1329 if (fbi->lccr0 & LCCR0_LCDT)
1330 setup_smart_timing(fbi, var);
1331 else
1332#endif
1333 setup_parallel_timing(fbi, var);
1334
1335 setup_base_frame(fbi, 0);
1336
1337 fbi->reg_lccr0 = fbi->lccr0 |
1338 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
1339 LCCR0_QDM | LCCR0_BM | LCCR0_OUM);
1340
1341 fbi->reg_lccr3 |= pxafb_var_to_lccr3(var);
1342
1343 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
1344 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
1345 local_irq_restore(flags);
1346
1347
1348
1349
1350
1351 if ((lcd_readl(fbi, LCCR0) != fbi->reg_lccr0) ||
1352 (lcd_readl(fbi, LCCR1) != fbi->reg_lccr1) ||
1353 (lcd_readl(fbi, LCCR2) != fbi->reg_lccr2) ||
1354 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
1355 (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
1356 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
1357 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
1358 pxafb_schedule_work(fbi, C_REENABLE);
1359
1360 return 0;
1361}
1362
1363
1364
1365
1366
1367
1368
1369static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on)
1370{
1371 pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff");
1372
1373 if (fbi->backlight_power)
1374 fbi->backlight_power(on);
1375}
1376
1377static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
1378{
1379 pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
1380
1381 if (fbi->lcd_power)
1382 fbi->lcd_power(on, &fbi->fb.var);
1383}
1384
1385static void pxafb_enable_controller(struct pxafb_info *fbi)
1386{
1387 pr_debug("pxafb: Enabling LCD controller\n");
1388 pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]);
1389 pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]);
1390 pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0);
1391 pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1);
1392 pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
1393 pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
1394
1395
1396 clk_enable(fbi->clk);
1397
1398 if (fbi->lccr0 & LCCR0_LCDT)
1399 return;
1400
1401
1402 lcd_writel(fbi, LCCR4, fbi->reg_lccr4);
1403 lcd_writel(fbi, LCCR3, fbi->reg_lccr3);
1404 lcd_writel(fbi, LCCR2, fbi->reg_lccr2);
1405 lcd_writel(fbi, LCCR1, fbi->reg_lccr1);
1406 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1407
1408 lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
1409 lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
1410 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
1411}
1412
1413static void pxafb_disable_controller(struct pxafb_info *fbi)
1414{
1415 uint32_t lccr0;
1416
1417#ifdef CONFIG_FB_PXA_SMARTPANEL
1418 if (fbi->lccr0 & LCCR0_LCDT) {
1419 wait_for_completion_timeout(&fbi->refresh_done,
1420 200 * HZ / 1000);
1421 return;
1422 }
1423#endif
1424
1425
1426 lcd_writel(fbi, LCSR, 0xffffffff);
1427
1428 lccr0 = lcd_readl(fbi, LCCR0) & ~LCCR0_LDM;
1429 lcd_writel(fbi, LCCR0, lccr0);
1430 lcd_writel(fbi, LCCR0, lccr0 | LCCR0_DIS);
1431
1432 wait_for_completion_timeout(&fbi->disable_done, 200 * HZ / 1000);
1433
1434
1435 clk_disable(fbi->clk);
1436}
1437
1438
1439
1440
1441static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)
1442{
1443 struct pxafb_info *fbi = dev_id;
1444 unsigned int lccr0, lcsr;
1445
1446 lcsr = lcd_readl(fbi, LCSR);
1447 if (lcsr & LCSR_LDD) {
1448 lccr0 = lcd_readl(fbi, LCCR0);
1449 lcd_writel(fbi, LCCR0, lccr0 | LCCR0_LDM);
1450 complete(&fbi->disable_done);
1451 }
1452
1453#ifdef CONFIG_FB_PXA_SMARTPANEL
1454 if (lcsr & LCSR_CMD_INT)
1455 complete(&fbi->command_done);
1456#endif
1457 lcd_writel(fbi, LCSR, lcsr);
1458
1459#ifdef CONFIG_FB_PXA_OVERLAY
1460 {
1461 unsigned int lcsr1 = lcd_readl(fbi, LCSR1);
1462 if (lcsr1 & LCSR1_BS(1))
1463 complete(&fbi->overlay[0].branch_done);
1464
1465 if (lcsr1 & LCSR1_BS(2))
1466 complete(&fbi->overlay[1].branch_done);
1467
1468 lcd_writel(fbi, LCSR1, lcsr1);
1469 }
1470#endif
1471 return IRQ_HANDLED;
1472}
1473
1474
1475
1476
1477
1478
1479static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
1480{
1481 u_int old_state;
1482
1483 mutex_lock(&fbi->ctrlr_lock);
1484
1485 old_state = fbi->state;
1486
1487
1488
1489
1490 if (old_state == C_STARTUP && state == C_REENABLE)
1491 state = C_ENABLE;
1492
1493 switch (state) {
1494 case C_DISABLE_CLKCHANGE:
1495
1496
1497
1498
1499 if (old_state != C_DISABLE && old_state != C_DISABLE_PM) {
1500 fbi->state = state;
1501
1502 pxafb_disable_controller(fbi);
1503 }
1504 break;
1505
1506 case C_DISABLE_PM:
1507 case C_DISABLE:
1508
1509
1510
1511 if (old_state != C_DISABLE) {
1512 fbi->state = state;
1513 __pxafb_backlight_power(fbi, 0);
1514 __pxafb_lcd_power(fbi, 0);
1515 if (old_state != C_DISABLE_CLKCHANGE)
1516 pxafb_disable_controller(fbi);
1517 }
1518 break;
1519
1520 case C_ENABLE_CLKCHANGE:
1521
1522
1523
1524
1525 if (old_state == C_DISABLE_CLKCHANGE) {
1526 fbi->state = C_ENABLE;
1527 pxafb_enable_controller(fbi);
1528
1529 }
1530 break;
1531
1532 case C_REENABLE:
1533
1534
1535
1536
1537
1538 if (old_state == C_ENABLE) {
1539 __pxafb_lcd_power(fbi, 0);
1540 pxafb_disable_controller(fbi);
1541 pxafb_enable_controller(fbi);
1542 __pxafb_lcd_power(fbi, 1);
1543 }
1544 break;
1545
1546 case C_ENABLE_PM:
1547
1548
1549
1550
1551
1552 if (old_state != C_DISABLE_PM)
1553 break;
1554
1555
1556 case C_ENABLE:
1557
1558
1559
1560
1561 if (old_state != C_ENABLE) {
1562 fbi->state = C_ENABLE;
1563 pxafb_enable_controller(fbi);
1564 __pxafb_lcd_power(fbi, 1);
1565 __pxafb_backlight_power(fbi, 1);
1566 }
1567 break;
1568 }
1569 mutex_unlock(&fbi->ctrlr_lock);
1570}
1571
1572
1573
1574
1575
1576static void pxafb_task(struct work_struct *work)
1577{
1578 struct pxafb_info *fbi =
1579 container_of(work, struct pxafb_info, task);
1580 u_int state = xchg(&fbi->task_state, -1);
1581
1582 set_ctrlr_state(fbi, state);
1583}
1584
1585#ifdef CONFIG_CPU_FREQ
1586
1587
1588
1589
1590
1591
1592
1593static int
1594pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
1595{
1596 struct pxafb_info *fbi = TO_INF(nb, freq_transition);
1597
1598 u_int pcd;
1599
1600 switch (val) {
1601 case CPUFREQ_PRECHANGE:
1602 set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
1603 break;
1604
1605 case CPUFREQ_POSTCHANGE:
1606 pcd = get_pcd(fbi, fbi->fb.var.pixclock);
1607 set_hsync_time(fbi, pcd);
1608 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) |
1609 LCCR3_PixClkDiv(pcd);
1610 set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
1611 break;
1612 }
1613 return 0;
1614}
1615
1616static int
1617pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
1618{
1619 struct pxafb_info *fbi = TO_INF(nb, freq_policy);
1620 struct fb_var_screeninfo *var = &fbi->fb.var;
1621 struct cpufreq_policy *policy = data;
1622
1623 switch (val) {
1624 case CPUFREQ_ADJUST:
1625 case CPUFREQ_INCOMPATIBLE:
1626 pr_debug("min dma period: %d ps, "
1627 "new clock %d kHz\n", pxafb_display_dma_period(var),
1628 policy->max);
1629
1630 break;
1631 }
1632 return 0;
1633}
1634#endif
1635
1636#ifdef CONFIG_PM
1637
1638
1639
1640
1641static int pxafb_suspend(struct device *dev)
1642{
1643 struct pxafb_info *fbi = dev_get_drvdata(dev);
1644
1645 set_ctrlr_state(fbi, C_DISABLE_PM);
1646 return 0;
1647}
1648
1649static int pxafb_resume(struct device *dev)
1650{
1651 struct pxafb_info *fbi = dev_get_drvdata(dev);
1652
1653 set_ctrlr_state(fbi, C_ENABLE_PM);
1654 return 0;
1655}
1656
1657static struct dev_pm_ops pxafb_pm_ops = {
1658 .suspend = pxafb_suspend,
1659 .resume = pxafb_resume,
1660};
1661#endif
1662
1663static int __devinit pxafb_init_video_memory(struct pxafb_info *fbi)
1664{
1665 int size = PAGE_ALIGN(fbi->video_mem_size);
1666
1667 fbi->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
1668 if (fbi->video_mem == NULL)
1669 return -ENOMEM;
1670
1671 fbi->video_mem_phys = virt_to_phys(fbi->video_mem);
1672 fbi->video_mem_size = size;
1673
1674 fbi->fb.fix.smem_start = fbi->video_mem_phys;
1675 fbi->fb.fix.smem_len = fbi->video_mem_size;
1676 fbi->fb.screen_base = fbi->video_mem;
1677
1678 return fbi->video_mem ? 0 : -ENOMEM;
1679}
1680
1681static void pxafb_decode_mach_info(struct pxafb_info *fbi,
1682 struct pxafb_mach_info *inf)
1683{
1684 unsigned int lcd_conn = inf->lcd_conn;
1685 struct pxafb_mode_info *m;
1686 int i;
1687
1688 fbi->cmap_inverse = inf->cmap_inverse;
1689 fbi->cmap_static = inf->cmap_static;
1690 fbi->lccr4 = inf->lccr4;
1691
1692 switch (lcd_conn & LCD_TYPE_MASK) {
1693 case LCD_TYPE_MONO_STN:
1694 fbi->lccr0 = LCCR0_CMS;
1695 break;
1696 case LCD_TYPE_MONO_DSTN:
1697 fbi->lccr0 = LCCR0_CMS | LCCR0_SDS;
1698 break;
1699 case LCD_TYPE_COLOR_STN:
1700 fbi->lccr0 = 0;
1701 break;
1702 case LCD_TYPE_COLOR_DSTN:
1703 fbi->lccr0 = LCCR0_SDS;
1704 break;
1705 case LCD_TYPE_COLOR_TFT:
1706 fbi->lccr0 = LCCR0_PAS;
1707 break;
1708 case LCD_TYPE_SMART_PANEL:
1709 fbi->lccr0 = LCCR0_LCDT | LCCR0_PAS;
1710 break;
1711 default:
1712
1713 fbi->lccr0 = inf->lccr0;
1714 fbi->lccr3 = inf->lccr3;
1715 goto decode_mode;
1716 }
1717
1718 if (lcd_conn == LCD_MONO_STN_8BPP)
1719 fbi->lccr0 |= LCCR0_DPD;
1720
1721 fbi->lccr0 |= (lcd_conn & LCD_ALTERNATE_MAPPING) ? LCCR0_LDDALT : 0;
1722
1723 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff);
1724 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
1725 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0;
1726
1727decode_mode:
1728 pxafb_setmode(&fbi->fb.var, &inf->modes[0]);
1729
1730
1731
1732
1733
1734
1735 for (i = 0, m = &inf->modes[0]; i < inf->num_modes; i++, m++)
1736 fbi->video_mem_size = max_t(size_t, fbi->video_mem_size,
1737 m->xres * m->yres * m->bpp / 8);
1738
1739 if (inf->video_mem_size > fbi->video_mem_size)
1740 fbi->video_mem_size = inf->video_mem_size;
1741
1742 if (video_mem_size > fbi->video_mem_size)
1743 fbi->video_mem_size = video_mem_size;
1744}
1745
1746static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
1747{
1748 struct pxafb_info *fbi;
1749 void *addr;
1750 struct pxafb_mach_info *inf = dev->platform_data;
1751
1752
1753 fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
1754 if (!fbi)
1755 return NULL;
1756
1757 memset(fbi, 0, sizeof(struct pxafb_info));
1758 fbi->dev = dev;
1759
1760 fbi->clk = clk_get(dev, NULL);
1761 if (IS_ERR(fbi->clk)) {
1762 kfree(fbi);
1763 return NULL;
1764 }
1765
1766 strcpy(fbi->fb.fix.id, PXA_NAME);
1767
1768 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
1769 fbi->fb.fix.type_aux = 0;
1770 fbi->fb.fix.xpanstep = 0;
1771 fbi->fb.fix.ypanstep = 1;
1772 fbi->fb.fix.ywrapstep = 0;
1773 fbi->fb.fix.accel = FB_ACCEL_NONE;
1774
1775 fbi->fb.var.nonstd = 0;
1776 fbi->fb.var.activate = FB_ACTIVATE_NOW;
1777 fbi->fb.var.height = -1;
1778 fbi->fb.var.width = -1;
1779 fbi->fb.var.accel_flags = FB_ACCELF_TEXT;
1780 fbi->fb.var.vmode = FB_VMODE_NONINTERLACED;
1781
1782 fbi->fb.fbops = &pxafb_ops;
1783 fbi->fb.flags = FBINFO_DEFAULT;
1784 fbi->fb.node = -1;
1785
1786 addr = fbi;
1787 addr = addr + sizeof(struct pxafb_info);
1788 fbi->fb.pseudo_palette = addr;
1789
1790 fbi->state = C_STARTUP;
1791 fbi->task_state = (u_char)-1;
1792
1793 pxafb_decode_mach_info(fbi, inf);
1794
1795 init_waitqueue_head(&fbi->ctrlr_wait);
1796 INIT_WORK(&fbi->task, pxafb_task);
1797 mutex_init(&fbi->ctrlr_lock);
1798 init_completion(&fbi->disable_done);
1799
1800 return fbi;
1801}
1802
1803#ifdef CONFIG_FB_PXA_PARAMETERS
1804static int __devinit parse_opt_mode(struct device *dev, const char *this_opt)
1805{
1806 struct pxafb_mach_info *inf = dev->platform_data;
1807
1808 const char *name = this_opt+5;
1809 unsigned int namelen = strlen(name);
1810 int res_specified = 0, bpp_specified = 0;
1811 unsigned int xres = 0, yres = 0, bpp = 0;
1812 int yres_specified = 0;
1813 int i;
1814 for (i = namelen-1; i >= 0; i--) {
1815 switch (name[i]) {
1816 case '-':
1817 namelen = i;
1818 if (!bpp_specified && !yres_specified) {
1819 bpp = simple_strtoul(&name[i+1], NULL, 0);
1820 bpp_specified = 1;
1821 } else
1822 goto done;
1823 break;
1824 case 'x':
1825 if (!yres_specified) {
1826 yres = simple_strtoul(&name[i+1], NULL, 0);
1827 yres_specified = 1;
1828 } else
1829 goto done;
1830 break;
1831 case '0' ... '9':
1832 break;
1833 default:
1834 goto done;
1835 }
1836 }
1837 if (i < 0 && yres_specified) {
1838 xres = simple_strtoul(name, NULL, 0);
1839 res_specified = 1;
1840 }
1841done:
1842 if (res_specified) {
1843 dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
1844 inf->modes[0].xres = xres; inf->modes[0].yres = yres;
1845 }
1846 if (bpp_specified)
1847 switch (bpp) {
1848 case 1:
1849 case 2:
1850 case 4:
1851 case 8:
1852 case 16:
1853 inf->modes[0].bpp = bpp;
1854 dev_info(dev, "overriding bit depth: %d\n", bpp);
1855 break;
1856 default:
1857 dev_err(dev, "Depth %d is not valid\n", bpp);
1858 return -EINVAL;
1859 }
1860 return 0;
1861}
1862
1863static int __devinit parse_opt(struct device *dev, char *this_opt)
1864{
1865 struct pxafb_mach_info *inf = dev->platform_data;
1866 struct pxafb_mode_info *mode = &inf->modes[0];
1867 char s[64];
1868
1869 s[0] = '\0';
1870
1871 if (!strncmp(this_opt, "vmem:", 5)) {
1872 video_mem_size = memparse(this_opt + 5, NULL);
1873 } else if (!strncmp(this_opt, "mode:", 5)) {
1874 return parse_opt_mode(dev, this_opt);
1875 } else if (!strncmp(this_opt, "pixclock:", 9)) {
1876 mode->pixclock = simple_strtoul(this_opt+9, NULL, 0);
1877 sprintf(s, "pixclock: %ld\n", mode->pixclock);
1878 } else if (!strncmp(this_opt, "left:", 5)) {
1879 mode->left_margin = simple_strtoul(this_opt+5, NULL, 0);
1880 sprintf(s, "left: %u\n", mode->left_margin);
1881 } else if (!strncmp(this_opt, "right:", 6)) {
1882 mode->right_margin = simple_strtoul(this_opt+6, NULL, 0);
1883 sprintf(s, "right: %u\n", mode->right_margin);
1884 } else if (!strncmp(this_opt, "upper:", 6)) {
1885 mode->upper_margin = simple_strtoul(this_opt+6, NULL, 0);
1886 sprintf(s, "upper: %u\n", mode->upper_margin);
1887 } else if (!strncmp(this_opt, "lower:", 6)) {
1888 mode->lower_margin = simple_strtoul(this_opt+6, NULL, 0);
1889 sprintf(s, "lower: %u\n", mode->lower_margin);
1890 } else if (!strncmp(this_opt, "hsynclen:", 9)) {
1891 mode->hsync_len = simple_strtoul(this_opt+9, NULL, 0);
1892 sprintf(s, "hsynclen: %u\n", mode->hsync_len);
1893 } else if (!strncmp(this_opt, "vsynclen:", 9)) {
1894 mode->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
1895 sprintf(s, "vsynclen: %u\n", mode->vsync_len);
1896 } else if (!strncmp(this_opt, "hsync:", 6)) {
1897 if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
1898 sprintf(s, "hsync: Active Low\n");
1899 mode->sync &= ~FB_SYNC_HOR_HIGH_ACT;
1900 } else {
1901 sprintf(s, "hsync: Active High\n");
1902 mode->sync |= FB_SYNC_HOR_HIGH_ACT;
1903 }
1904 } else if (!strncmp(this_opt, "vsync:", 6)) {
1905 if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
1906 sprintf(s, "vsync: Active Low\n");
1907 mode->sync &= ~FB_SYNC_VERT_HIGH_ACT;
1908 } else {
1909 sprintf(s, "vsync: Active High\n");
1910 mode->sync |= FB_SYNC_VERT_HIGH_ACT;
1911 }
1912 } else if (!strncmp(this_opt, "dpc:", 4)) {
1913 if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
1914 sprintf(s, "double pixel clock: false\n");
1915 inf->lccr3 &= ~LCCR3_DPC;
1916 } else {
1917 sprintf(s, "double pixel clock: true\n");
1918 inf->lccr3 |= LCCR3_DPC;
1919 }
1920 } else if (!strncmp(this_opt, "outputen:", 9)) {
1921 if (simple_strtoul(this_opt+9, NULL, 0) == 0) {
1922 sprintf(s, "output enable: active low\n");
1923 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
1924 } else {
1925 sprintf(s, "output enable: active high\n");
1926 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
1927 }
1928 } else if (!strncmp(this_opt, "pixclockpol:", 12)) {
1929 if (simple_strtoul(this_opt+12, NULL, 0) == 0) {
1930 sprintf(s, "pixel clock polarity: falling edge\n");
1931 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
1932 } else {
1933 sprintf(s, "pixel clock polarity: rising edge\n");
1934 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
1935 }
1936 } else if (!strncmp(this_opt, "color", 5)) {
1937 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
1938 } else if (!strncmp(this_opt, "mono", 4)) {
1939 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Mono;
1940 } else if (!strncmp(this_opt, "active", 6)) {
1941 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Act;
1942 } else if (!strncmp(this_opt, "passive", 7)) {
1943 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Pas;
1944 } else if (!strncmp(this_opt, "single", 6)) {
1945 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Sngl;
1946 } else if (!strncmp(this_opt, "dual", 4)) {
1947 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Dual;
1948 } else if (!strncmp(this_opt, "4pix", 4)) {
1949 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_4PixMono;
1950 } else if (!strncmp(this_opt, "8pix", 4)) {
1951 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_8PixMono;
1952 } else {
1953 dev_err(dev, "unknown option: %s\n", this_opt);
1954 return -EINVAL;
1955 }
1956
1957 if (s[0] != '\0')
1958 dev_info(dev, "override %s", s);
1959
1960 return 0;
1961}
1962
1963static int __devinit pxafb_parse_options(struct device *dev, char *options)
1964{
1965 char *this_opt;
1966 int ret;
1967
1968 if (!options || !*options)
1969 return 0;
1970
1971 dev_dbg(dev, "options are \"%s\"\n", options ? options : "null");
1972
1973
1974 while ((this_opt = strsep(&options, ",")) != NULL) {
1975 ret = parse_opt(dev, this_opt);
1976 if (ret)
1977 return ret;
1978 }
1979 return 0;
1980}
1981
1982static char g_options[256] __devinitdata = "";
1983
1984#ifndef MODULE
1985static int __init pxafb_setup_options(void)
1986{
1987 char *options = NULL;
1988
1989 if (fb_get_options("pxafb", &options))
1990 return -ENODEV;
1991
1992 if (options)
1993 strlcpy(g_options, options, sizeof(g_options));
1994
1995 return 0;
1996}
1997#else
1998#define pxafb_setup_options() (0)
1999
2000module_param_string(options, g_options, sizeof(g_options), 0);
2001MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
2002#endif
2003
2004#else
2005#define pxafb_parse_options(...) (0)
2006#define pxafb_setup_options() (0)
2007#endif
2008
2009#ifdef DEBUG_VAR
2010
2011
2012static void __devinit pxafb_check_options(struct device *dev,
2013 struct pxafb_mach_info *inf)
2014{
2015 if (inf->lcd_conn)
2016 return;
2017
2018 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
2019 dev_warn(dev, "machine LCCR0 setting contains "
2020 "illegal bits: %08x\n",
2021 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
2022 if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
2023 dev_warn(dev, "machine LCCR3 setting contains "
2024 "illegal bits: %08x\n",
2025 inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
2026 if (inf->lccr0 & LCCR0_DPD &&
2027 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
2028 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
2029 (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
2030 dev_warn(dev, "Double Pixel Data (DPD) mode is "
2031 "only valid in passive mono"
2032 " single panel mode\n");
2033 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
2034 (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
2035 dev_warn(dev, "Dual panel only valid in passive mode\n");
2036 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
2037 (inf->modes->upper_margin || inf->modes->lower_margin))
2038 dev_warn(dev, "Upper and lower margins must be 0 in "
2039 "passive mode\n");
2040}
2041#else
2042#define pxafb_check_options(...) do {} while (0)
2043#endif
2044
2045static int __devinit pxafb_probe(struct platform_device *dev)
2046{
2047 struct pxafb_info *fbi;
2048 struct pxafb_mach_info *inf;
2049 struct resource *r;
2050 int irq, ret;
2051
2052 dev_dbg(&dev->dev, "pxafb_probe\n");
2053
2054 inf = dev->dev.platform_data;
2055 ret = -ENOMEM;
2056 fbi = NULL;
2057 if (!inf)
2058 goto failed;
2059
2060 ret = pxafb_parse_options(&dev->dev, g_options);
2061 if (ret < 0)
2062 goto failed;
2063
2064 pxafb_check_options(&dev->dev, inf);
2065
2066 dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",
2067 inf->modes->xres,
2068 inf->modes->yres,
2069 inf->modes->bpp);
2070 if (inf->modes->xres == 0 ||
2071 inf->modes->yres == 0 ||
2072 inf->modes->bpp == 0) {
2073 dev_err(&dev->dev, "Invalid resolution or bit depth\n");
2074 ret = -EINVAL;
2075 goto failed;
2076 }
2077
2078 fbi = pxafb_init_fbinfo(&dev->dev);
2079 if (!fbi) {
2080
2081 dev_err(&dev->dev, "Failed to initialize framebuffer device\n");
2082 ret = -ENOMEM;
2083 goto failed;
2084 }
2085
2086 if (cpu_is_pxa3xx() && inf->acceleration_enabled)
2087 fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
2088
2089 fbi->backlight_power = inf->pxafb_backlight_power;
2090 fbi->lcd_power = inf->pxafb_lcd_power;
2091
2092 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
2093 if (r == NULL) {
2094 dev_err(&dev->dev, "no I/O memory resource defined\n");
2095 ret = -ENODEV;
2096 goto failed_fbi;
2097 }
2098
2099 r = request_mem_region(r->start, resource_size(r), dev->name);
2100 if (r == NULL) {
2101 dev_err(&dev->dev, "failed to request I/O memory\n");
2102 ret = -EBUSY;
2103 goto failed_fbi;
2104 }
2105
2106 fbi->mmio_base = ioremap(r->start, resource_size(r));
2107 if (fbi->mmio_base == NULL) {
2108 dev_err(&dev->dev, "failed to map I/O memory\n");
2109 ret = -EBUSY;
2110 goto failed_free_res;
2111 }
2112
2113 fbi->dma_buff_size = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));
2114 fbi->dma_buff = dma_alloc_coherent(fbi->dev, fbi->dma_buff_size,
2115 &fbi->dma_buff_phys, GFP_KERNEL);
2116 if (fbi->dma_buff == NULL) {
2117 dev_err(&dev->dev, "failed to allocate memory for DMA\n");
2118 ret = -ENOMEM;
2119 goto failed_free_io;
2120 }
2121
2122 ret = pxafb_init_video_memory(fbi);
2123 if (ret) {
2124 dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret);
2125 ret = -ENOMEM;
2126 goto failed_free_dma;
2127 }
2128
2129 irq = platform_get_irq(dev, 0);
2130 if (irq < 0) {
2131 dev_err(&dev->dev, "no IRQ defined\n");
2132 ret = -ENODEV;
2133 goto failed_free_mem;
2134 }
2135
2136 ret = request_irq(irq, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi);
2137 if (ret) {
2138 dev_err(&dev->dev, "request_irq failed: %d\n", ret);
2139 ret = -EBUSY;
2140 goto failed_free_mem;
2141 }
2142
2143 ret = pxafb_smart_init(fbi);
2144 if (ret) {
2145 dev_err(&dev->dev, "failed to initialize smartpanel\n");
2146 goto failed_free_irq;
2147 }
2148
2149
2150
2151
2152
2153 ret = pxafb_check_var(&fbi->fb.var, &fbi->fb);
2154 if (ret) {
2155 dev_err(&dev->dev, "failed to get suitable mode\n");
2156 goto failed_free_irq;
2157 }
2158
2159 ret = pxafb_set_par(&fbi->fb);
2160 if (ret) {
2161 dev_err(&dev->dev, "Failed to set parameters\n");
2162 goto failed_free_irq;
2163 }
2164
2165 platform_set_drvdata(dev, fbi);
2166
2167 ret = register_framebuffer(&fbi->fb);
2168 if (ret < 0) {
2169 dev_err(&dev->dev,
2170 "Failed to register framebuffer device: %d\n", ret);
2171 goto failed_free_cmap;
2172 }
2173
2174 pxafb_overlay_init(fbi);
2175
2176#ifdef CONFIG_CPU_FREQ
2177 fbi->freq_transition.notifier_call = pxafb_freq_transition;
2178 fbi->freq_policy.notifier_call = pxafb_freq_policy;
2179 cpufreq_register_notifier(&fbi->freq_transition,
2180 CPUFREQ_TRANSITION_NOTIFIER);
2181 cpufreq_register_notifier(&fbi->freq_policy,
2182 CPUFREQ_POLICY_NOTIFIER);
2183#endif
2184
2185
2186
2187
2188 set_ctrlr_state(fbi, C_ENABLE);
2189
2190 return 0;
2191
2192failed_free_cmap:
2193 if (fbi->fb.cmap.len)
2194 fb_dealloc_cmap(&fbi->fb.cmap);
2195failed_free_irq:
2196 free_irq(irq, fbi);
2197failed_free_mem:
2198 free_pages_exact(fbi->video_mem, fbi->video_mem_size);
2199failed_free_dma:
2200 dma_free_coherent(&dev->dev, fbi->dma_buff_size,
2201 fbi->dma_buff, fbi->dma_buff_phys);
2202failed_free_io:
2203 iounmap(fbi->mmio_base);
2204failed_free_res:
2205 release_mem_region(r->start, resource_size(r));
2206failed_fbi:
2207 clk_put(fbi->clk);
2208 platform_set_drvdata(dev, NULL);
2209 kfree(fbi);
2210failed:
2211 return ret;
2212}
2213
2214static int __devexit pxafb_remove(struct platform_device *dev)
2215{
2216 struct pxafb_info *fbi = platform_get_drvdata(dev);
2217 struct resource *r;
2218 int irq;
2219 struct fb_info *info;
2220
2221 if (!fbi)
2222 return 0;
2223
2224 info = &fbi->fb;
2225
2226 pxafb_overlay_exit(fbi);
2227 unregister_framebuffer(info);
2228
2229 pxafb_disable_controller(fbi);
2230
2231 if (fbi->fb.cmap.len)
2232 fb_dealloc_cmap(&fbi->fb.cmap);
2233
2234 irq = platform_get_irq(dev, 0);
2235 free_irq(irq, fbi);
2236
2237 free_pages_exact(fbi->video_mem, fbi->video_mem_size);
2238
2239 dma_free_writecombine(&dev->dev, fbi->dma_buff_size,
2240 fbi->dma_buff, fbi->dma_buff_phys);
2241
2242 iounmap(fbi->mmio_base);
2243
2244 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
2245 release_mem_region(r->start, resource_size(r));
2246
2247 clk_put(fbi->clk);
2248 kfree(fbi);
2249
2250 return 0;
2251}
2252
2253static struct platform_driver pxafb_driver = {
2254 .probe = pxafb_probe,
2255 .remove = __devexit_p(pxafb_remove),
2256 .driver = {
2257 .owner = THIS_MODULE,
2258 .name = "pxa2xx-fb",
2259#ifdef CONFIG_PM
2260 .pm = &pxafb_pm_ops,
2261#endif
2262 },
2263};
2264
2265static int __init pxafb_init(void)
2266{
2267 if (pxafb_setup_options())
2268 return -EINVAL;
2269
2270 return platform_driver_register(&pxafb_driver);
2271}
2272
2273static void __exit pxafb_exit(void)
2274{
2275 platform_driver_unregister(&pxafb_driver);
2276}
2277
2278module_init(pxafb_init);
2279module_exit(pxafb_exit);
2280
2281MODULE_DESCRIPTION("loadable framebuffer driver for PXA");
2282MODULE_LICENSE("GPL");
2283