diff options
-rw-r--r-- | drivers/video/pxafb.c | 280 |
1 files changed, 144 insertions, 136 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 02787a43002f..6e6128c51d03 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -57,13 +57,18 @@ | |||
57 | #include "pxafb.h" | 57 | #include "pxafb.h" |
58 | 58 | ||
59 | /* Bits which should not be set in machine configuration structures */ | 59 | /* Bits which should not be set in machine configuration structures */ |
60 | #define LCCR0_INVALID_CONFIG_MASK (LCCR0_OUM|LCCR0_BM|LCCR0_QDM|LCCR0_DIS|LCCR0_EFM|LCCR0_IUM|LCCR0_SFM|LCCR0_LDM|LCCR0_ENB) | 60 | #define LCCR0_INVALID_CONFIG_MASK (LCCR0_OUM | LCCR0_BM | LCCR0_QDM |\ |
61 | #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP) | 61 | LCCR0_DIS | LCCR0_EFM | LCCR0_IUM |\ |
62 | LCCR0_SFM | LCCR0_LDM | LCCR0_ENB) | ||
63 | |||
64 | #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP | LCCR3_VSP |\ | ||
65 | LCCR3_PCD | LCCR3_BPP) | ||
62 | 66 | ||
63 | static void (*pxafb_backlight_power)(int); | 67 | static void (*pxafb_backlight_power)(int); |
64 | static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); | 68 | static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); |
65 | 69 | ||
66 | static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *); | 70 | static int pxafb_activate_var(struct fb_var_screeninfo *var, |
71 | struct pxafb_info *); | ||
67 | static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); | 72 | static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); |
68 | 73 | ||
69 | #ifdef CONFIG_FB_PXA_PARAMETERS | 74 | #ifdef CONFIG_FB_PXA_PARAMETERS |
@@ -79,10 +84,12 @@ static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state) | |||
79 | /* | 84 | /* |
80 | * We need to handle two requests being made at the same time. | 85 | * We need to handle two requests being made at the same time. |
81 | * There are two important cases: | 86 | * There are two important cases: |
82 | * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) | 87 | * 1. When we are changing VT (C_REENABLE) while unblanking |
83 | * We must perform the unblanking, which will do our REENABLE for us. | 88 | * (C_ENABLE) We must perform the unblanking, which will |
84 | * 2. When we are blanking, but immediately unblank before we have | 89 | * do our REENABLE for us. |
85 | * blanked. We do the "REENABLE" thing here as well, just to be sure. | 90 | * 2. When we are blanking, but immediately unblank before |
91 | * we have blanked. We do the "REENABLE" thing here as | ||
92 | * well, just to be sure. | ||
86 | */ | 93 | */ |
87 | if (fbi->task_state == C_ENABLE && state == C_REENABLE) | 94 | if (fbi->task_state == C_ENABLE && state == C_REENABLE) |
88 | state = (u_int) -1; | 95 | state = (u_int) -1; |
@@ -129,13 +136,13 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, | |||
129 | val = ((red << 8) & 0x00f80000); | 136 | val = ((red << 8) & 0x00f80000); |
130 | val |= ((green >> 0) & 0x0000fc00); | 137 | val |= ((green >> 0) & 0x0000fc00); |
131 | val |= ((blue >> 8) & 0x000000f8); | 138 | val |= ((blue >> 8) & 0x000000f8); |
132 | ((u32*)(fbi->palette_cpu))[regno] = val; | 139 | ((u32 *)(fbi->palette_cpu))[regno] = val; |
133 | break; | 140 | break; |
134 | case LCCR4_PAL_FOR_2: | 141 | case LCCR4_PAL_FOR_2: |
135 | val = ((red << 8) & 0x00fc0000); | 142 | val = ((red << 8) & 0x00fc0000); |
136 | val |= ((green >> 0) & 0x0000fc00); | 143 | val |= ((green >> 0) & 0x0000fc00); |
137 | val |= ((blue >> 8) & 0x000000fc); | 144 | val |= ((blue >> 8) & 0x000000fc); |
138 | ((u32*)(fbi->palette_cpu))[regno] = val; | 145 | ((u32 *)(fbi->palette_cpu))[regno] = val; |
139 | break; | 146 | break; |
140 | } | 147 | } |
141 | 148 | ||
@@ -203,15 +210,15 @@ pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
203 | */ | 210 | */ |
204 | static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var) | 211 | static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var) |
205 | { | 212 | { |
206 | int ret = 0; | 213 | int ret = 0; |
207 | switch (var->bits_per_pixel) { | 214 | switch (var->bits_per_pixel) { |
208 | case 1: ret = LCCR3_1BPP; break; | 215 | case 1: ret = LCCR3_1BPP; break; |
209 | case 2: ret = LCCR3_2BPP; break; | 216 | case 2: ret = LCCR3_2BPP; break; |
210 | case 4: ret = LCCR3_4BPP; break; | 217 | case 4: ret = LCCR3_4BPP; break; |
211 | case 8: ret = LCCR3_8BPP; break; | 218 | case 8: ret = LCCR3_8BPP; break; |
212 | case 16: ret = LCCR3_16BPP; break; | 219 | case 16: ret = LCCR3_16BPP; break; |
213 | } | 220 | } |
214 | return ret; | 221 | return ret; |
215 | } | 222 | } |
216 | 223 | ||
217 | #ifdef CONFIG_CPU_FREQ | 224 | #ifdef CONFIG_CPU_FREQ |
@@ -223,31 +230,32 @@ static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var) | |||
223 | */ | 230 | */ |
224 | static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var) | 231 | static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var) |
225 | { | 232 | { |
226 | /* | 233 | /* |
227 | * Period = pixclock * bits_per_byte * bytes_per_transfer | 234 | * Period = pixclock * bits_per_byte * bytes_per_transfer |
228 | * / memory_bits_per_pixel; | 235 | * / memory_bits_per_pixel; |
229 | */ | 236 | */ |
230 | return var->pixclock * 8 * 16 / var->bits_per_pixel; | 237 | return var->pixclock * 8 * 16 / var->bits_per_pixel; |
231 | } | 238 | } |
232 | |||
233 | extern unsigned int get_clk_frequency_khz(int info); | ||
234 | #endif | 239 | #endif |
235 | 240 | ||
236 | /* | 241 | /* |
237 | * Select the smallest mode that allows the desired resolution to be | 242 | * Select the smallest mode that allows the desired resolution to be |
238 | * displayed. If desired parameters can be rounded up. | 243 | * displayed. If desired parameters can be rounded up. |
239 | */ | 244 | */ |
240 | static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struct fb_var_screeninfo *var) | 245 | static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, |
246 | struct fb_var_screeninfo *var) | ||
241 | { | 247 | { |
242 | struct pxafb_mode_info *mode = NULL; | 248 | struct pxafb_mode_info *mode = NULL; |
243 | struct pxafb_mode_info *modelist = mach->modes; | 249 | struct pxafb_mode_info *modelist = mach->modes; |
244 | unsigned int best_x = 0xffffffff, best_y = 0xffffffff; | 250 | unsigned int best_x = 0xffffffff, best_y = 0xffffffff; |
245 | unsigned int i; | 251 | unsigned int i; |
246 | 252 | ||
247 | for (i = 0 ; i < mach->num_modes ; i++) { | 253 | for (i = 0; i < mach->num_modes; i++) { |
248 | if (modelist[i].xres >= var->xres && modelist[i].yres >= var->yres && | 254 | if (modelist[i].xres >= var->xres && |
249 | modelist[i].xres < best_x && modelist[i].yres < best_y && | 255 | modelist[i].yres >= var->yres && |
250 | modelist[i].bpp >= var->bits_per_pixel ) { | 256 | modelist[i].xres < best_x && |
257 | modelist[i].yres < best_y && | ||
258 | modelist[i].bpp >= var->bits_per_pixel) { | ||
251 | best_x = modelist[i].xres; | 259 | best_x = modelist[i].xres; |
252 | best_y = modelist[i].yres; | 260 | best_y = modelist[i].yres; |
253 | mode = &modelist[i]; | 261 | mode = &modelist[i]; |
@@ -257,7 +265,8 @@ static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struc | |||
257 | return mode; | 265 | return mode; |
258 | } | 266 | } |
259 | 267 | ||
260 | static void pxafb_setmode(struct fb_var_screeninfo *var, struct pxafb_mode_info *mode) | 268 | static void pxafb_setmode(struct fb_var_screeninfo *var, |
269 | struct pxafb_mode_info *mode) | ||
261 | { | 270 | { |
262 | var->xres = mode->xres; | 271 | var->xres = mode->xres; |
263 | var->yres = mode->yres; | 272 | var->yres = mode->yres; |
@@ -315,19 +324,20 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
315 | var->yres_virtual = | 324 | var->yres_virtual = |
316 | max(var->yres_virtual, var->yres); | 325 | max(var->yres_virtual, var->yres); |
317 | 326 | ||
318 | /* | 327 | /* |
319 | * Setup the RGB parameters for this display. | 328 | * Setup the RGB parameters for this display. |
320 | * | 329 | * |
321 | * The pixel packing format is described on page 7-11 of the | 330 | * The pixel packing format is described on page 7-11 of the |
322 | * PXA2XX Developer's Manual. | 331 | * PXA2XX Developer's Manual. |
323 | */ | 332 | */ |
324 | if (var->bits_per_pixel == 16) { | 333 | if (var->bits_per_pixel == 16) { |
325 | var->red.offset = 11; var->red.length = 5; | 334 | var->red.offset = 11; var->red.length = 5; |
326 | var->green.offset = 5; var->green.length = 6; | 335 | var->green.offset = 5; var->green.length = 6; |
327 | var->blue.offset = 0; var->blue.length = 5; | 336 | var->blue.offset = 0; var->blue.length = 5; |
328 | var->transp.offset = var->transp.length = 0; | 337 | var->transp.offset = var->transp.length = 0; |
329 | } else { | 338 | } else { |
330 | var->red.offset = var->green.offset = var->blue.offset = var->transp.offset = 0; | 339 | var->red.offset = var->green.offset = 0; |
340 | var->blue.offset = var->transp.offset = 0; | ||
331 | var->red.length = 8; | 341 | var->red.length = 8; |
332 | var->green.length = 8; | 342 | var->green.length = 8; |
333 | var->blue.length = 8; | 343 | var->blue.length = 8; |
@@ -346,7 +356,7 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
346 | static inline void pxafb_set_truecolor(u_int is_true_color) | 356 | static inline void pxafb_set_truecolor(u_int is_true_color) |
347 | { | 357 | { |
348 | pr_debug("pxafb: true_color = %d\n", is_true_color); | 358 | pr_debug("pxafb: true_color = %d\n", is_true_color); |
349 | // do your machine-specific setup if needed | 359 | /* do your machine-specific setup if needed */ |
350 | } | 360 | } |
351 | 361 | ||
352 | /* | 362 | /* |
@@ -379,7 +389,8 @@ static int pxafb_set_par(struct fb_info *info) | |||
379 | if (var->bits_per_pixel == 16) | 389 | if (var->bits_per_pixel == 16) |
380 | fbi->palette_size = 0; | 390 | fbi->palette_size = 0; |
381 | else | 391 | else |
382 | fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel; | 392 | fbi->palette_size = var->bits_per_pixel == 1 ? |
393 | 4 : 1 << var->bits_per_pixel; | ||
383 | 394 | ||
384 | if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) | 395 | if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) |
385 | palette_mem_size = fbi->palette_size * sizeof(u16); | 396 | palette_mem_size = fbi->palette_size * sizeof(u16); |
@@ -460,11 +471,11 @@ static int pxafb_blank(int blank, struct fb_info *info) | |||
460 | pxafb_setpalettereg(i, 0, 0, 0, 0, info); | 471 | pxafb_setpalettereg(i, 0, 0, 0, 0, info); |
461 | 472 | ||
462 | pxafb_schedule_work(fbi, C_DISABLE); | 473 | pxafb_schedule_work(fbi, C_DISABLE); |
463 | //TODO if (pxafb_blank_helper) pxafb_blank_helper(blank); | 474 | /* TODO if (pxafb_blank_helper) pxafb_blank_helper(blank); */ |
464 | break; | 475 | break; |
465 | 476 | ||
466 | case FB_BLANK_UNBLANK: | 477 | case FB_BLANK_UNBLANK: |
467 | //TODO if (pxafb_blank_helper) pxafb_blank_helper(blank); | 478 | /* TODO if (pxafb_blank_helper) pxafb_blank_helper(blank); */ |
468 | if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || | 479 | if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || |
469 | fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) | 480 | fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) |
470 | fb_set_cmap(&fbi->fb.cmap, info); | 481 | fb_set_cmap(&fbi->fb.cmap, info); |
@@ -529,7 +540,8 @@ static struct fb_ops pxafb_ops = { | |||
529 | * | 540 | * |
530 | * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below. | 541 | * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below. |
531 | */ | 542 | */ |
532 | static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock) | 543 | static inline unsigned int get_pcd(struct pxafb_info *fbi, |
544 | unsigned int pixclock) | ||
533 | { | 545 | { |
534 | unsigned long long pcd; | 546 | unsigned long long pcd; |
535 | 547 | ||
@@ -555,7 +567,7 @@ static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd) | |||
555 | unsigned long htime; | 567 | unsigned long htime; |
556 | 568 | ||
557 | if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) { | 569 | if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) { |
558 | fbi->hsync_time=0; | 570 | fbi->hsync_time = 0; |
559 | return; | 571 | return; |
560 | } | 572 | } |
561 | 573 | ||
@@ -578,10 +590,11 @@ EXPORT_SYMBOL(pxafb_get_hsync_time); | |||
578 | 590 | ||
579 | /* | 591 | /* |
580 | * pxafb_activate_var(): | 592 | * pxafb_activate_var(): |
581 | * Configures LCD Controller based on entries in var parameter. Settings are | 593 | * Configures LCD Controller based on entries in var parameter. |
582 | * only written to the controller if changes were made. | 594 | * Settings are only written to the controller if changes were made. |
583 | */ | 595 | */ |
584 | static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *fbi) | 596 | static int pxafb_activate_var(struct fb_var_screeninfo *var, |
597 | struct pxafb_info *fbi) | ||
585 | { | 598 | { |
586 | struct pxafb_lcd_reg new_regs; | 599 | struct pxafb_lcd_reg new_regs; |
587 | u_long flags; | 600 | u_long flags; |
@@ -598,10 +611,10 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * | |||
598 | pr_debug("var: pixclock=%d pcd=%d\n", var->pixclock, pcd); | 611 | pr_debug("var: pixclock=%d pcd=%d\n", var->pixclock, pcd); |
599 | 612 | ||
600 | #if DEBUG_VAR | 613 | #if DEBUG_VAR |
601 | if (var->xres < 16 || var->xres > 1024) | 614 | if (var->xres < 16 || var->xres > 1024) |
602 | printk(KERN_ERR "%s: invalid xres %d\n", | 615 | printk(KERN_ERR "%s: invalid xres %d\n", |
603 | fbi->fb.fix.id, var->xres); | 616 | fbi->fb.fix.id, var->xres); |
604 | switch(var->bits_per_pixel) { | 617 | switch (var->bits_per_pixel) { |
605 | case 1: | 618 | case 1: |
606 | case 2: | 619 | case 2: |
607 | case 4: | 620 | case 4: |
@@ -613,19 +626,19 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * | |||
613 | fbi->fb.fix.id, var->bits_per_pixel); | 626 | fbi->fb.fix.id, var->bits_per_pixel); |
614 | break; | 627 | break; |
615 | } | 628 | } |
616 | if (var->hsync_len < 1 || var->hsync_len > 64) | 629 | if (var->hsync_len < 1 || var->hsync_len > 64) |
617 | printk(KERN_ERR "%s: invalid hsync_len %d\n", | 630 | printk(KERN_ERR "%s: invalid hsync_len %d\n", |
618 | fbi->fb.fix.id, var->hsync_len); | 631 | fbi->fb.fix.id, var->hsync_len); |
619 | if (var->left_margin < 1 || var->left_margin > 255) | 632 | if (var->left_margin < 1 || var->left_margin > 255) |
620 | printk(KERN_ERR "%s: invalid left_margin %d\n", | 633 | printk(KERN_ERR "%s: invalid left_margin %d\n", |
621 | fbi->fb.fix.id, var->left_margin); | 634 | fbi->fb.fix.id, var->left_margin); |
622 | if (var->right_margin < 1 || var->right_margin > 255) | 635 | if (var->right_margin < 1 || var->right_margin > 255) |
623 | printk(KERN_ERR "%s: invalid right_margin %d\n", | 636 | printk(KERN_ERR "%s: invalid right_margin %d\n", |
624 | fbi->fb.fix.id, var->right_margin); | 637 | fbi->fb.fix.id, var->right_margin); |
625 | if (var->yres < 1 || var->yres > 1024) | 638 | if (var->yres < 1 || var->yres > 1024) |
626 | printk(KERN_ERR "%s: invalid yres %d\n", | 639 | printk(KERN_ERR "%s: invalid yres %d\n", |
627 | fbi->fb.fix.id, var->yres); | 640 | fbi->fb.fix.id, var->yres); |
628 | if (var->vsync_len < 1 || var->vsync_len > 64) | 641 | if (var->vsync_len < 1 || var->vsync_len > 64) |
629 | printk(KERN_ERR "%s: invalid vsync_len %d\n", | 642 | printk(KERN_ERR "%s: invalid vsync_len %d\n", |
630 | fbi->fb.fix.id, var->vsync_len); | 643 | fbi->fb.fix.id, var->vsync_len); |
631 | if (var->upper_margin < 0 || var->upper_margin > 255) | 644 | if (var->upper_margin < 0 || var->upper_margin > 255) |
@@ -638,7 +651,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * | |||
638 | 651 | ||
639 | new_regs.lccr0 = fbi->lccr0 | | 652 | new_regs.lccr0 = fbi->lccr0 | |
640 | (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | | 653 | (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | |
641 | LCCR0_QDM | LCCR0_BM | LCCR0_OUM); | 654 | LCCR0_QDM | LCCR0_BM | LCCR0_OUM); |
642 | 655 | ||
643 | new_regs.lccr1 = | 656 | new_regs.lccr1 = |
644 | LCCR1_DisWdth(var->xres) + | 657 | LCCR1_DisWdth(var->xres) + |
@@ -662,8 +675,10 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * | |||
662 | 675 | ||
663 | new_regs.lccr3 = fbi->lccr3 | | 676 | new_regs.lccr3 = fbi->lccr3 | |
664 | pxafb_bpp_to_lccr3(var) | | 677 | pxafb_bpp_to_lccr3(var) | |
665 | (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | | 678 | (var->sync & FB_SYNC_HOR_HIGH_ACT ? |
666 | (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); | 679 | LCCR3_HorSnchH : LCCR3_HorSnchL) | |
680 | (var->sync & FB_SYNC_VERT_HIGH_ACT ? | ||
681 | LCCR3_VrtSnchH : LCCR3_VrtSnchL); | ||
667 | 682 | ||
668 | if (pcd) | 683 | if (pcd) |
669 | new_regs.lccr3 |= LCCR3_PixClkDiv(pcd); | 684 | new_regs.lccr3 |= LCCR3_PixClkDiv(pcd); |
@@ -677,9 +692,12 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * | |||
677 | local_irq_save(flags); | 692 | local_irq_save(flags); |
678 | 693 | ||
679 | /* setup dma descriptors */ | 694 | /* setup dma descriptors */ |
680 | fbi->dmadesc_fblow_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 3*16); | 695 | fbi->dmadesc_fblow_cpu = (struct pxafb_dma_descriptor *) |
681 | fbi->dmadesc_fbhigh_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 2*16); | 696 | ((unsigned int)fbi->palette_cpu - 3*16); |
682 | fbi->dmadesc_palette_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 1*16); | 697 | fbi->dmadesc_fbhigh_cpu = (struct pxafb_dma_descriptor *) |
698 | ((unsigned int)fbi->palette_cpu - 2*16); | ||
699 | fbi->dmadesc_palette_cpu = (struct pxafb_dma_descriptor *) | ||
700 | ((unsigned int)fbi->palette_cpu - 1*16); | ||
683 | 701 | ||
684 | fbi->dmadesc_fblow_dma = fbi->palette_dma - 3*16; | 702 | fbi->dmadesc_fblow_dma = fbi->palette_dma - 3*16; |
685 | fbi->dmadesc_fbhigh_dma = fbi->palette_dma - 2*16; | 703 | fbi->dmadesc_fbhigh_dma = fbi->palette_dma - 2*16; |
@@ -716,32 +734,12 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * | |||
716 | /* init it to something, even though we won't be using it */ | 734 | /* init it to something, even though we won't be using it */ |
717 | fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma; | 735 | fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma; |
718 | } else { | 736 | } else { |
737 | /* flips back and forth between pal and fbhigh */ | ||
719 | fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma; | 738 | fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma; |
720 | fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma; | 739 | fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma; |
721 | fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */ | 740 | fbi->fdadr0 = fbi->dmadesc_palette_dma; |
722 | } | 741 | } |
723 | 742 | ||
724 | #if 0 | ||
725 | pr_debug("fbi->dmadesc_fblow_cpu = 0x%p\n", fbi->dmadesc_fblow_cpu); | ||
726 | pr_debug("fbi->dmadesc_fbhigh_cpu = 0x%p\n", fbi->dmadesc_fbhigh_cpu); | ||
727 | pr_debug("fbi->dmadesc_palette_cpu = 0x%p\n", fbi->dmadesc_palette_cpu); | ||
728 | pr_debug("fbi->dmadesc_fblow_dma = 0x%x\n", fbi->dmadesc_fblow_dma); | ||
729 | pr_debug("fbi->dmadesc_fbhigh_dma = 0x%x\n", fbi->dmadesc_fbhigh_dma); | ||
730 | pr_debug("fbi->dmadesc_palette_dma = 0x%x\n", fbi->dmadesc_palette_dma); | ||
731 | |||
732 | pr_debug("fbi->dmadesc_fblow_cpu->fdadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fdadr); | ||
733 | pr_debug("fbi->dmadesc_fbhigh_cpu->fdadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fdadr); | ||
734 | pr_debug("fbi->dmadesc_palette_cpu->fdadr = 0x%x\n", fbi->dmadesc_palette_cpu->fdadr); | ||
735 | |||
736 | pr_debug("fbi->dmadesc_fblow_cpu->fsadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fsadr); | ||
737 | pr_debug("fbi->dmadesc_fbhigh_cpu->fsadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fsadr); | ||
738 | pr_debug("fbi->dmadesc_palette_cpu->fsadr = 0x%x\n", fbi->dmadesc_palette_cpu->fsadr); | ||
739 | |||
740 | pr_debug("fbi->dmadesc_fblow_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fblow_cpu->ldcmd); | ||
741 | pr_debug("fbi->dmadesc_fbhigh_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fbhigh_cpu->ldcmd); | ||
742 | pr_debug("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd); | ||
743 | #endif | ||
744 | |||
745 | fbi->reg_lccr0 = new_regs.lccr0; | 743 | fbi->reg_lccr0 = new_regs.lccr0; |
746 | fbi->reg_lccr1 = new_regs.lccr1; | 744 | fbi->reg_lccr1 = new_regs.lccr1; |
747 | fbi->reg_lccr2 = new_regs.lccr2; | 745 | fbi->reg_lccr2 = new_regs.lccr2; |
@@ -773,8 +771,8 @@ static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on) | |||
773 | { | 771 | { |
774 | pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff"); | 772 | pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff"); |
775 | 773 | ||
776 | if (pxafb_backlight_power) | 774 | if (pxafb_backlight_power) |
777 | pxafb_backlight_power(on); | 775 | pxafb_backlight_power(on); |
778 | } | 776 | } |
779 | 777 | ||
780 | static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on) | 778 | static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on) |
@@ -788,11 +786,11 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on) | |||
788 | static void pxafb_setup_gpio(struct pxafb_info *fbi) | 786 | static void pxafb_setup_gpio(struct pxafb_info *fbi) |
789 | { | 787 | { |
790 | int gpio, ldd_bits; | 788 | int gpio, ldd_bits; |
791 | unsigned int lccr0 = fbi->lccr0; | 789 | unsigned int lccr0 = fbi->lccr0; |
792 | 790 | ||
793 | /* | 791 | /* |
794 | * setup is based on type of panel supported | 792 | * setup is based on type of panel supported |
795 | */ | 793 | */ |
796 | 794 | ||
797 | /* 4 bit interface */ | 795 | /* 4 bit interface */ |
798 | if ((lccr0 & LCCR0_CMS) == LCCR0_Mono && | 796 | if ((lccr0 & LCCR0_CMS) == LCCR0_Mono && |
@@ -801,21 +799,25 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi) | |||
801 | ldd_bits = 4; | 799 | ldd_bits = 4; |
802 | 800 | ||
803 | /* 8 bit interface */ | 801 | /* 8 bit interface */ |
804 | else if (((lccr0 & LCCR0_CMS) == LCCR0_Mono && | 802 | else if (((lccr0 & LCCR0_CMS) == LCCR0_Mono && |
805 | ((lccr0 & LCCR0_SDS) == LCCR0_Dual || (lccr0 & LCCR0_DPD) == LCCR0_8PixMono)) || | 803 | ((lccr0 & LCCR0_SDS) == LCCR0_Dual || |
806 | ((lccr0 & LCCR0_CMS) == LCCR0_Color && | 804 | (lccr0 & LCCR0_DPD) == LCCR0_8PixMono)) || |
807 | (lccr0 & LCCR0_PAS) == LCCR0_Pas && (lccr0 & LCCR0_SDS) == LCCR0_Sngl)) | 805 | ((lccr0 & LCCR0_CMS) == LCCR0_Color && |
806 | (lccr0 & LCCR0_PAS) == LCCR0_Pas && | ||
807 | (lccr0 & LCCR0_SDS) == LCCR0_Sngl)) | ||
808 | ldd_bits = 8; | 808 | ldd_bits = 8; |
809 | 809 | ||
810 | /* 16 bit interface */ | 810 | /* 16 bit interface */ |
811 | else if ((lccr0 & LCCR0_CMS) == LCCR0_Color && | 811 | else if ((lccr0 & LCCR0_CMS) == LCCR0_Color && |
812 | ((lccr0 & LCCR0_SDS) == LCCR0_Dual || (lccr0 & LCCR0_PAS) == LCCR0_Act)) | 812 | ((lccr0 & LCCR0_SDS) == LCCR0_Dual || |
813 | (lccr0 & LCCR0_PAS) == LCCR0_Act)) | ||
813 | ldd_bits = 16; | 814 | ldd_bits = 16; |
814 | 815 | ||
815 | else { | 816 | else { |
816 | printk(KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n"); | 817 | printk(KERN_ERR "pxafb_setup_gpio: unable to determine " |
818 | "bits per pixel\n"); | ||
817 | return; | 819 | return; |
818 | } | 820 | } |
819 | 821 | ||
820 | for (gpio = 58; ldd_bits; gpio++, ldd_bits--) | 822 | for (gpio = 58; ldd_bits; gpio++, ldd_bits--) |
821 | pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT); | 823 | pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT); |
@@ -921,7 +923,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) | |||
921 | */ | 923 | */ |
922 | if (old_state != C_DISABLE && old_state != C_DISABLE_PM) { | 924 | if (old_state != C_DISABLE && old_state != C_DISABLE_PM) { |
923 | fbi->state = state; | 925 | fbi->state = state; |
924 | //TODO __pxafb_lcd_power(fbi, 0); | 926 | /* TODO __pxafb_lcd_power(fbi, 0); */ |
925 | pxafb_disable_controller(fbi); | 927 | pxafb_disable_controller(fbi); |
926 | } | 928 | } |
927 | break; | 929 | break; |
@@ -948,7 +950,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) | |||
948 | if (old_state == C_DISABLE_CLKCHANGE) { | 950 | if (old_state == C_DISABLE_CLKCHANGE) { |
949 | fbi->state = C_ENABLE; | 951 | fbi->state = C_ENABLE; |
950 | pxafb_enable_controller(fbi); | 952 | pxafb_enable_controller(fbi); |
951 | //TODO __pxafb_lcd_power(fbi, 1); | 953 | /* TODO __pxafb_lcd_power(fbi, 1); */ |
952 | } | 954 | } |
953 | break; | 955 | break; |
954 | 956 | ||
@@ -1019,7 +1021,7 @@ static int | |||
1019 | pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) | 1021 | pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) |
1020 | { | 1022 | { |
1021 | struct pxafb_info *fbi = TO_INF(nb, freq_transition); | 1023 | struct pxafb_info *fbi = TO_INF(nb, freq_transition); |
1022 | //TODO struct cpufreq_freqs *f = data; | 1024 | /* TODO struct cpufreq_freqs *f = data; */ |
1023 | u_int pcd; | 1025 | u_int pcd; |
1024 | 1026 | ||
1025 | switch (val) { | 1027 | switch (val) { |
@@ -1030,7 +1032,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) | |||
1030 | case CPUFREQ_POSTCHANGE: | 1032 | case CPUFREQ_POSTCHANGE: |
1031 | pcd = get_pcd(fbi, fbi->fb.var.pixclock); | 1033 | pcd = get_pcd(fbi, fbi->fb.var.pixclock); |
1032 | set_hsync_time(fbi, pcd); | 1034 | set_hsync_time(fbi, pcd); |
1033 | fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); | 1035 | fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | |
1036 | LCCR3_PixClkDiv(pcd); | ||
1034 | set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); | 1037 | set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); |
1035 | break; | 1038 | break; |
1036 | } | 1039 | } |
@@ -1050,18 +1053,8 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) | |||
1050 | pr_debug("min dma period: %d ps, " | 1053 | pr_debug("min dma period: %d ps, " |
1051 | "new clock %d kHz\n", pxafb_display_dma_period(var), | 1054 | "new clock %d kHz\n", pxafb_display_dma_period(var), |
1052 | policy->max); | 1055 | policy->max); |
1053 | // TODO: fill in min/max values | 1056 | /* TODO: fill in min/max values */ |
1054 | break; | 1057 | break; |
1055 | #if 0 | ||
1056 | case CPUFREQ_NOTIFY: | ||
1057 | printk(KERN_ERR "%s: got CPUFREQ_NOTIFY\n", __FUNCTION__); | ||
1058 | do {} while(0); | ||
1059 | /* todo: panic if min/max values aren't fulfilled | ||
1060 | * [can't really happen unless there's a bug in the | ||
1061 | * CPU policy verification process * | ||
1062 | */ | ||
1063 | break; | ||
1064 | #endif | ||
1065 | } | 1058 | } |
1066 | return 0; | 1059 | return 0; |
1067 | } | 1060 | } |
@@ -1131,9 +1124,11 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi) | |||
1131 | else | 1124 | else |
1132 | palette_mem_size = fbi->palette_size * sizeof(u32); | 1125 | palette_mem_size = fbi->palette_size * sizeof(u32); |
1133 | 1126 | ||
1134 | pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size); | 1127 | pr_debug("pxafb: palette_mem_size = 0x%08lx\n", |
1128 | palette_mem_size); | ||
1135 | 1129 | ||
1136 | fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); | 1130 | fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE |
1131 | - palette_mem_size); | ||
1137 | fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; | 1132 | fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; |
1138 | } | 1133 | } |
1139 | 1134 | ||
@@ -1188,14 +1183,14 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) | |||
1188 | 1183 | ||
1189 | pxafb_setmode(&fbi->fb.var, mode); | 1184 | pxafb_setmode(&fbi->fb.var, mode); |
1190 | 1185 | ||
1191 | fbi->cmap_inverse = inf->cmap_inverse; | 1186 | fbi->cmap_inverse = inf->cmap_inverse; |
1192 | fbi->cmap_static = inf->cmap_static; | 1187 | fbi->cmap_static = inf->cmap_static; |
1193 | 1188 | ||
1194 | fbi->lccr0 = inf->lccr0; | 1189 | fbi->lccr0 = inf->lccr0; |
1195 | fbi->lccr3 = inf->lccr3; | 1190 | fbi->lccr3 = inf->lccr3; |
1196 | fbi->lccr4 = inf->lccr4; | 1191 | fbi->lccr4 = inf->lccr4; |
1197 | fbi->state = C_STARTUP; | 1192 | fbi->state = C_STARTUP; |
1198 | fbi->task_state = (u_char)-1; | 1193 | fbi->task_state = (u_char)-1; |
1199 | 1194 | ||
1200 | for (i = 0; i < inf->num_modes; i++) { | 1195 | for (i = 0; i < inf->num_modes; i++) { |
1201 | smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8; | 1196 | smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8; |
@@ -1211,7 +1206,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) | |||
1211 | } | 1206 | } |
1212 | 1207 | ||
1213 | #ifdef CONFIG_FB_PXA_PARAMETERS | 1208 | #ifdef CONFIG_FB_PXA_PARAMETERS |
1214 | static int parse_opt_mode(struct device *dev, const char *this_opt) | 1209 | static int __init parse_opt_mode(struct device *dev, const char *this_opt) |
1215 | { | 1210 | { |
1216 | struct pxafb_mach_info *inf = dev->platform_data; | 1211 | struct pxafb_mach_info *inf = dev->platform_data; |
1217 | 1212 | ||
@@ -1270,7 +1265,7 @@ done: | |||
1270 | return 0; | 1265 | return 0; |
1271 | } | 1266 | } |
1272 | 1267 | ||
1273 | static int parse_opt(struct device *dev, char *this_opt) | 1268 | static int __init parse_opt(struct device *dev, char *this_opt) |
1274 | { | 1269 | { |
1275 | struct pxafb_mach_info *inf = dev->platform_data; | 1270 | struct pxafb_mach_info *inf = dev->platform_data; |
1276 | struct pxafb_mode_info *mode = &inf->modes[0]; | 1271 | struct pxafb_mode_info *mode = &inf->modes[0]; |
@@ -1409,31 +1404,40 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1409 | #endif | 1404 | #endif |
1410 | 1405 | ||
1411 | #ifdef DEBUG_VAR | 1406 | #ifdef DEBUG_VAR |
1412 | /* Check for various illegal bit-combinations. Currently only | 1407 | /* Check for various illegal bit-combinations. Currently only |
1413 | * a warning is given. */ | 1408 | * a warning is given. */ |
1414 | 1409 | ||
1415 | if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) | 1410 | if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) |
1416 | dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n", | 1411 | dev_warn(&dev->dev, "machine LCCR0 setting contains " |
1417 | inf->lccr0 & LCCR0_INVALID_CONFIG_MASK); | 1412 | "illegal bits: %08x\n", |
1418 | if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK) | 1413 | inf->lccr0 & LCCR0_INVALID_CONFIG_MASK); |
1419 | dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n", | 1414 | if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK) |
1420 | inf->lccr3 & LCCR3_INVALID_CONFIG_MASK); | 1415 | dev_warn(&dev->dev, "machine LCCR3 setting contains " |
1421 | if (inf->lccr0 & LCCR0_DPD && | 1416 | "illegal bits: %08x\n", |
1417 | inf->lccr3 & LCCR3_INVALID_CONFIG_MASK); | ||
1418 | if (inf->lccr0 & LCCR0_DPD && | ||
1422 | ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas || | 1419 | ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas || |
1423 | (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || | 1420 | (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || |
1424 | (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono)) | 1421 | (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono)) |
1425 | dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is only valid in passive mono" | 1422 | dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is " |
1426 | " single panel mode\n"); | 1423 | "only valid in passive mono" |
1427 | if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act && | 1424 | " single panel mode\n"); |
1425 | if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act && | ||
1428 | (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual) | 1426 | (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual) |
1429 | dev_warn(&dev->dev, "Dual panel only valid in passive mode\n"); | 1427 | dev_warn(&dev->dev, "Dual panel only valid in passive mode\n"); |
1430 | if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas && | 1428 | if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas && |
1431 | (inf->modes->upper_margin || inf->modes->lower_margin)) | 1429 | (inf->modes->upper_margin || inf->modes->lower_margin)) |
1432 | dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n"); | 1430 | dev_warn(&dev->dev, "Upper and lower margins must be 0 in " |
1431 | "passive mode\n"); | ||
1433 | #endif | 1432 | #endif |
1434 | 1433 | ||
1435 | dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->modes->xres, inf->modes->yres, inf->modes->bpp); | 1434 | dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n", |
1436 | if (inf->modes->xres == 0 || inf->modes->yres == 0 || inf->modes->bpp == 0) { | 1435 | inf->modes->xres, |
1436 | inf->modes->yres, | ||
1437 | inf->modes->bpp); | ||
1438 | if (inf->modes->xres == 0 || | ||
1439 | inf->modes->yres == 0 || | ||
1440 | inf->modes->bpp == 0) { | ||
1437 | dev_err(&dev->dev, "Invalid resolution or bit depth\n"); | 1441 | dev_err(&dev->dev, "Invalid resolution or bit depth\n"); |
1438 | ret = -EINVAL; | 1442 | ret = -EINVAL; |
1439 | goto failed; | 1443 | goto failed; |
@@ -1442,8 +1446,9 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1442 | pxafb_lcd_power = inf->pxafb_lcd_power; | 1446 | pxafb_lcd_power = inf->pxafb_lcd_power; |
1443 | fbi = pxafb_init_fbinfo(&dev->dev); | 1447 | fbi = pxafb_init_fbinfo(&dev->dev); |
1444 | if (!fbi) { | 1448 | if (!fbi) { |
1449 | /* only reason for pxafb_init_fbinfo to fail is kmalloc */ | ||
1445 | dev_err(&dev->dev, "Failed to initialize framebuffer device\n"); | 1450 | dev_err(&dev->dev, "Failed to initialize framebuffer device\n"); |
1446 | ret = -ENOMEM; // only reason for pxafb_init_fbinfo to fail is kmalloc | 1451 | ret = -ENOMEM; |
1447 | goto failed; | 1452 | goto failed; |
1448 | } | 1453 | } |
1449 | 1454 | ||
@@ -1473,19 +1478,22 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1473 | 1478 | ||
1474 | ret = register_framebuffer(&fbi->fb); | 1479 | ret = register_framebuffer(&fbi->fb); |
1475 | if (ret < 0) { | 1480 | if (ret < 0) { |
1476 | dev_err(&dev->dev, "Failed to register framebuffer device: %d\n", ret); | 1481 | dev_err(&dev->dev, |
1482 | "Failed to register framebuffer device: %d\n", ret); | ||
1477 | goto failed; | 1483 | goto failed; |
1478 | } | 1484 | } |
1479 | 1485 | ||
1480 | #ifdef CONFIG_PM | 1486 | #ifdef CONFIG_PM |
1481 | // TODO | 1487 | /* TODO */ |
1482 | #endif | 1488 | #endif |
1483 | 1489 | ||
1484 | #ifdef CONFIG_CPU_FREQ | 1490 | #ifdef CONFIG_CPU_FREQ |
1485 | fbi->freq_transition.notifier_call = pxafb_freq_transition; | 1491 | fbi->freq_transition.notifier_call = pxafb_freq_transition; |
1486 | fbi->freq_policy.notifier_call = pxafb_freq_policy; | 1492 | fbi->freq_policy.notifier_call = pxafb_freq_policy; |
1487 | cpufreq_register_notifier(&fbi->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); | 1493 | cpufreq_register_notifier(&fbi->freq_transition, |
1488 | cpufreq_register_notifier(&fbi->freq_policy, CPUFREQ_POLICY_NOTIFIER); | 1494 | CPUFREQ_TRANSITION_NOTIFIER); |
1495 | cpufreq_register_notifier(&fbi->freq_policy, | ||
1496 | CPUFREQ_POLICY_NOTIFIER); | ||
1489 | #endif | 1497 | #endif |
1490 | 1498 | ||
1491 | /* | 1499 | /* |