Lines Matching +full:sync +full:- +full:on +full:- +full:green +full:- +full:active

5  *  Copyright (C) 2004 Jean-Frederic Clere.
8 * Based on sa1100fb.c Copyright (C) 1999 Eric A. Thomas
10 * Based on acornfb.c Copyright (C) Russell King.
18 * Please direct your questions and comments on this driver to the following
21 * linux-arm-kernel@lists.arm.linux.org.uk
23 * Add support for overlay1 and overlay2 based on pxafb_overlay.c:
31 * Copyright (C) 2006-2008 Marvell International Ltd.
50 #include <linux/dma-mapping.h>
67 #include <linux/platform_data/video-pxafb.h>
75 #include "pxa3xx-regs.h"
98 return __raw_readl(fbi->mmio_base + off); in lcd_readl()
104 __raw_writel(val, fbi->mmio_base + off); in lcd_writel()
122 if (fbi->task_state == C_ENABLE && state == C_REENABLE) in pxafb_schedule_work()
123 state = (u_int) -1; in pxafb_schedule_work()
124 if (fbi->task_state == C_DISABLE && state == C_ENABLE) in pxafb_schedule_work()
127 if (state != (u_int)-1) { in pxafb_schedule_work()
128 fbi->task_state = state; in pxafb_schedule_work()
129 schedule_work(&fbi->task); in pxafb_schedule_work()
137 chan >>= 16 - bf->length; in chan_to_field()
138 return chan << bf->offset; in chan_to_field()
142 pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, in pxafb_setpalettereg() argument
148 if (regno >= fbi->palette_size) in pxafb_setpalettereg()
151 if (fbi->fb.var.grayscale) { in pxafb_setpalettereg()
152 fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff); in pxafb_setpalettereg()
156 switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) { in pxafb_setpalettereg()
159 val |= ((green >> 5) & 0x07e0); in pxafb_setpalettereg()
161 fbi->palette_cpu[regno] = val; in pxafb_setpalettereg()
165 val |= ((green >> 0) & 0x0000fc00); in pxafb_setpalettereg()
167 ((u32 *)(fbi->palette_cpu))[regno] = val; in pxafb_setpalettereg()
171 val |= ((green >> 0) & 0x0000fc00); in pxafb_setpalettereg()
173 ((u32 *)(fbi->palette_cpu))[regno] = val; in pxafb_setpalettereg()
177 val |= ((green >> 0) & 0x0000ff00); in pxafb_setpalettereg()
179 ((u32 *)(fbi->palette_cpu))[regno] = val; in pxafb_setpalettereg()
187 pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, in pxafb_setcolreg() argument
200 if (fbi->cmap_inverse) { in pxafb_setcolreg()
201 red = 0xffff - red; in pxafb_setcolreg()
202 green = 0xffff - green; in pxafb_setcolreg()
203 blue = 0xffff - blue; in pxafb_setcolreg()
210 if (fbi->fb.var.grayscale) in pxafb_setcolreg()
211 red = green = blue = (19595 * red + 38470 * green + in pxafb_setcolreg()
214 switch (fbi->fb.fix.visual) { in pxafb_setcolreg()
217 * 16-bit True Colour. We encode the RGB value in pxafb_setcolreg()
221 u32 *pal = fbi->fb.pseudo_palette; in pxafb_setcolreg()
223 val = chan_to_field(red, &fbi->fb.var.red); in pxafb_setcolreg()
224 val |= chan_to_field(green, &fbi->fb.var.green); in pxafb_setcolreg()
225 val |= chan_to_field(blue, &fbi->fb.var.blue); in pxafb_setcolreg()
234 ret = pxafb_setpalettereg(regno, red, green, blue, trans, info); in pxafb_setcolreg()
244 return var->red.length + var->green.length + in var_to_depth()
245 var->blue.length + var->transp.length; in var_to_depth()
248 /* calculate 4-bit BPP value for LCCR3 and OVLxC1 */
251 int bpp = -EINVAL; in pxafb_var_to_bpp()
253 switch (var->bits_per_pixel) { in pxafb_var_to_bpp()
261 case 18: bpp = 6; break; /* 18-bits/pixel packed */ in pxafb_var_to_bpp()
262 case 19: bpp = 8; break; /* 19-bits/pixel packed */ in pxafb_var_to_bpp()
268 case 18: bpp = 5; break; /* 18-bits/pixel unpacked */ in pxafb_var_to_bpp()
269 case 19: bpp = 7; break; /* 19-bits/pixel unpacked */ in pxafb_var_to_bpp()
299 case 16: lccr3 |= var->transp.length ? LCCR3_PDFOR_3 : 0; break; in pxafb_var_to_lccr3()
301 case 24: lccr3 |= var->transp.length ? LCCR3_PDFOR_2 : LCCR3_PDFOR_3; in pxafb_var_to_lccr3()
311 (v)->transp.offset = (t) ? (r) + (g) + (b) : 0; \
312 (v)->transp.length = (t) ? (t) : 0; \
313 (v)->blue.length = (b); (v)->blue.offset = 0; \
314 (v)->green.length = (g); (v)->green.offset = (b); \
315 (v)->red.length = (r); (v)->red.offset = (b) + (g); \
319 * var->bits_per_pixel and given depth
324 depth = var->bits_per_pixel; in pxafb_set_pixfmt()
326 if (var->bits_per_pixel < 16) { in pxafb_set_pixfmt()
328 var->red.offset = 0; var->red.length = 8; in pxafb_set_pixfmt()
329 var->green.offset = 0; var->green.length = 8; in pxafb_set_pixfmt()
330 var->blue.offset = 0; var->blue.length = 8; in pxafb_set_pixfmt()
331 var->transp.offset = 0; var->transp.length = 8; in pxafb_set_pixfmt()
335 case 16: var->transp.length ? in pxafb_set_pixfmt()
340 case 24: var->transp.length ? in pxafb_set_pixfmt()
360 return var->pixclock * 8 * 16 / var->bits_per_pixel; in pxafb_display_dma_period()
372 struct pxafb_mode_info *modelist = mach->modes; in pxafb_getmode()
376 for (i = 0; i < mach->num_modes; i++) { in pxafb_getmode()
377 if (modelist[i].xres >= var->xres && in pxafb_getmode()
378 modelist[i].yres >= var->yres && in pxafb_getmode()
381 modelist[i].bpp >= var->bits_per_pixel) { in pxafb_getmode()
394 var->xres = mode->xres; in pxafb_setmode()
395 var->yres = mode->yres; in pxafb_setmode()
396 var->bits_per_pixel = mode->bpp; in pxafb_setmode()
397 var->pixclock = mode->pixclock; in pxafb_setmode()
398 var->hsync_len = mode->hsync_len; in pxafb_setmode()
399 var->left_margin = mode->left_margin; in pxafb_setmode()
400 var->right_margin = mode->right_margin; in pxafb_setmode()
401 var->vsync_len = mode->vsync_len; in pxafb_setmode()
402 var->upper_margin = mode->upper_margin; in pxafb_setmode()
403 var->lower_margin = mode->lower_margin; in pxafb_setmode()
404 var->sync = mode->sync; in pxafb_setmode()
405 var->grayscale = mode->cmap_greyscale; in pxafb_setmode()
406 var->transp.length = mode->transparency; in pxafb_setmode()
409 pxafb_set_pixfmt(var, mode->depth); in pxafb_setmode()
417 var->xres = max_t(int, var->xres, MIN_XRES); in pxafb_adjust_timing()
418 var->yres = max_t(int, var->yres, MIN_YRES); in pxafb_adjust_timing()
420 if (!(fbi->lccr0 & LCCR0_LCDT)) { in pxafb_adjust_timing()
421 clamp_val(var->hsync_len, 1, 64); in pxafb_adjust_timing()
422 clamp_val(var->vsync_len, 1, 64); in pxafb_adjust_timing()
423 clamp_val(var->left_margin, 1, 255); in pxafb_adjust_timing()
424 clamp_val(var->right_margin, 1, 255); in pxafb_adjust_timing()
425 clamp_val(var->upper_margin, 1, 255); in pxafb_adjust_timing()
426 clamp_val(var->lower_margin, 1, 255); in pxafb_adjust_timing()
429 /* make sure each line is aligned on word boundary */ in pxafb_adjust_timing()
430 line_length = var->xres * var->bits_per_pixel / 8; in pxafb_adjust_timing()
432 var->xres = line_length * 8 / var->bits_per_pixel; in pxafb_adjust_timing()
435 var->xres_virtual = var->xres; in pxafb_adjust_timing()
437 if (var->accel_flags & FB_ACCELF_TEXT) in pxafb_adjust_timing()
438 var->yres_virtual = fbi->fb.fix.smem_len / line_length; in pxafb_adjust_timing()
440 var->yres_virtual = max(var->yres_virtual, var->yres); in pxafb_adjust_timing()
443 if (var->xres > MAX_XRES || var->yres > MAX_YRES) in pxafb_adjust_timing()
444 return -EINVAL; in pxafb_adjust_timing()
446 if (var->yres > var->yres_virtual) in pxafb_adjust_timing()
447 return -EINVAL; in pxafb_adjust_timing()
455 * if it's too big, return -EINVAL.
464 struct pxafb_mach_info *inf = fbi->inf; in pxafb_check_var()
467 if (inf->fixed_modes) { in pxafb_check_var()
472 return -EINVAL; in pxafb_check_var()
502 struct fb_var_screeninfo *var = &info->var; in pxafb_set_par()
504 if (var->bits_per_pixel >= 16) in pxafb_set_par()
505 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; in pxafb_set_par()
506 else if (!fbi->cmap_static) in pxafb_set_par()
507 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; in pxafb_set_par()
514 fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; in pxafb_set_par()
517 fbi->fb.fix.line_length = var->xres_virtual * in pxafb_set_par()
518 var->bits_per_pixel / 8; in pxafb_set_par()
519 if (var->bits_per_pixel >= 16) in pxafb_set_par()
520 fbi->palette_size = 0; in pxafb_set_par()
522 fbi->palette_size = var->bits_per_pixel == 1 ? in pxafb_set_par()
523 4 : 1 << var->bits_per_pixel; in pxafb_set_par()
525 fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0]; in pxafb_set_par()
527 if (fbi->fb.var.bits_per_pixel >= 16) in pxafb_set_par()
528 fb_dealloc_cmap(&fbi->fb.cmap); in pxafb_set_par()
530 fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0); in pxafb_set_par()
544 if (fbi->state != C_ENABLE) in pxafb_pan_display()
550 memcpy(&newvar, &fbi->fb.var, sizeof(newvar)); in pxafb_pan_display()
551 newvar.xoffset = var->xoffset; in pxafb_pan_display()
552 newvar.yoffset = var->yoffset; in pxafb_pan_display()
554 newvar.vmode |= var->vmode & FB_VMODE_YWRAP; in pxafb_pan_display()
558 if (fbi->lccr0 & LCCR0_SDS) in pxafb_pan_display()
559 lcd_writel(fbi, FBR1, fbi->fdadr[dma + 1] | 0x1); in pxafb_pan_display()
561 lcd_writel(fbi, FBR0, fbi->fdadr[dma] | 0x1); in pxafb_pan_display()
581 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || in pxafb_blank()
582 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) in pxafb_blank()
583 for (i = 0; i < fbi->palette_size; i++) in pxafb_blank()
592 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR || in pxafb_blank()
593 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) in pxafb_blank()
594 fb_set_cmap(&fbi->fb.cmap, info); in pxafb_blank()
613 int size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual; in overlay1fb_setup()
614 unsigned long start = ofb->video_mem_phys; in overlay1fb_setup()
615 setup_frame_dma(ofb->fbi, DMA_OV1, PAL_NONE, start, size); in overlay1fb_setup()
618 /* Depending on the enable status of overlay1/2, the DMA should be
623 int enabled = lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN; in overlay1fb_enable()
624 uint32_t fdadr1 = ofb->fbi->fdadr[DMA_OV1] | (enabled ? 0x1 : 0); in overlay1fb_enable()
626 lcd_writel(ofb->fbi, enabled ? FBR1 : FDADR1, fdadr1); in overlay1fb_enable()
627 lcd_writel(ofb->fbi, OVL1C2, ofb->control[1]); in overlay1fb_enable()
628 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] | OVLxC1_OEN); in overlay1fb_enable()
635 if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)) in overlay1fb_disable()
638 lccr5 = lcd_readl(ofb->fbi, LCCR5); in overlay1fb_disable()
640 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); in overlay1fb_disable()
642 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1)); in overlay1fb_disable()
643 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1)); in overlay1fb_disable()
644 lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3); in overlay1fb_disable()
646 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0) in overlay1fb_disable()
649 lcd_writel(ofb->fbi, LCCR5, lccr5); in overlay1fb_disable()
654 int size, div = 1, pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd); in overlay2fb_setup()
655 unsigned long start[3] = { ofb->video_mem_phys, 0, 0 }; in overlay2fb_setup()
658 size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual; in overlay2fb_setup()
659 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size); in overlay2fb_setup()
661 size = ofb->fb.var.xres_virtual * ofb->fb.var.yres_virtual; in overlay2fb_setup()
669 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size); in overlay2fb_setup()
670 setup_frame_dma(ofb->fbi, DMA_OV2_Cb, -1, start[1], size / div); in overlay2fb_setup()
671 setup_frame_dma(ofb->fbi, DMA_OV2_Cr, -1, start[2], size / div); in overlay2fb_setup()
677 int pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd); in overlay2fb_enable()
678 int enabled = lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN; in overlay2fb_enable()
679 uint32_t fdadr2 = ofb->fbi->fdadr[DMA_OV2_Y] | (enabled ? 0x1 : 0); in overlay2fb_enable()
680 uint32_t fdadr3 = ofb->fbi->fdadr[DMA_OV2_Cb] | (enabled ? 0x1 : 0); in overlay2fb_enable()
681 uint32_t fdadr4 = ofb->fbi->fdadr[DMA_OV2_Cr] | (enabled ? 0x1 : 0); in overlay2fb_enable()
684 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2); in overlay2fb_enable()
686 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2); in overlay2fb_enable()
687 lcd_writel(ofb->fbi, enabled ? FBR3 : FDADR3, fdadr3); in overlay2fb_enable()
688 lcd_writel(ofb->fbi, enabled ? FBR4 : FDADR4, fdadr4); in overlay2fb_enable()
690 lcd_writel(ofb->fbi, OVL2C2, ofb->control[1]); in overlay2fb_enable()
691 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] | OVLxC1_OEN); in overlay2fb_enable()
698 if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN)) in overlay2fb_disable()
701 lccr5 = lcd_readl(ofb->fbi, LCCR5); in overlay2fb_disable()
703 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); in overlay2fb_disable()
705 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2)); in overlay2fb_disable()
706 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2)); in overlay2fb_disable()
707 lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3); in overlay2fb_disable()
708 lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3); in overlay2fb_disable()
709 lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3); in overlay2fb_disable()
711 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0) in overlay2fb_disable()
732 /* no support for framebuffer console on overlay */ in overlayfb_open()
734 return -ENODEV; in overlayfb_open()
736 if (ofb->usage++ == 0) { in overlayfb_open()
739 fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); in overlayfb_open()
750 if (ofb->usage == 1) { in overlayfb_release()
751 ofb->ops->disable(ofb); in overlayfb_release()
752 ofb->fb.var.height = -1; in overlayfb_release()
753 ofb->fb.var.width = -1; in overlayfb_release()
754 ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0; in overlayfb_release()
755 ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0; in overlayfb_release()
757 ofb->usage--; in overlayfb_release()
766 struct fb_var_screeninfo *base_var = &ofb->fbi->fb.var; in overlayfb_check_var()
769 xpos = NONSTD_TO_XPOS(var->nonstd); in overlayfb_check_var()
770 ypos = NONSTD_TO_YPOS(var->nonstd); in overlayfb_check_var()
771 pfor = NONSTD_TO_PFOR(var->nonstd); in overlayfb_check_var()
775 return -EINVAL; in overlayfb_check_var()
777 /* no support for YUV format on overlay1 */ in overlayfb_check_var()
778 if (ofb->id == OVERLAY1 && pfor != 0) in overlayfb_check_var()
779 return -EINVAL; in overlayfb_check_var()
786 return -EINVAL; in overlayfb_check_var()
795 return -EINVAL; in overlayfb_check_var()
798 /* each line must start at a 32-bit word boundary */ in overlayfb_check_var()
800 return -EINVAL; in overlayfb_check_var()
802 /* xres must align on 32-bit word boundary */ in overlayfb_check_var()
803 var->xres = roundup(var->xres * bpp, 32) / bpp; in overlayfb_check_var()
805 if ((xpos + var->xres > base_var->xres) || in overlayfb_check_var()
806 (ypos + var->yres > base_var->yres)) in overlayfb_check_var()
807 return -EINVAL; in overlayfb_check_var()
809 var->xres_virtual = var->xres; in overlayfb_check_var()
810 var->yres_virtual = max(var->yres, var->yres_virtual); in overlayfb_check_var()
816 struct fb_var_screeninfo *var = &ofb->fb.var; in overlayfb_check_video_memory()
817 int pfor = NONSTD_TO_PFOR(var->nonstd); in overlayfb_check_video_memory()
821 case OVERLAY_FORMAT_RGB: bpp = var->bits_per_pixel; break; in overlayfb_check_video_memory()
828 ofb->fb.fix.line_length = var->xres_virtual * bpp / 8; in overlayfb_check_video_memory()
830 size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); in overlayfb_check_video_memory()
832 if (ofb->video_mem) { in overlayfb_check_video_memory()
833 if (ofb->video_mem_size >= size) in overlayfb_check_video_memory()
836 return -EINVAL; in overlayfb_check_video_memory()
842 struct fb_var_screeninfo *var = &info->var; in overlayfb_set_par()
850 xpos = NONSTD_TO_XPOS(var->nonstd); in overlayfb_set_par()
851 ypos = NONSTD_TO_YPOS(var->nonstd); in overlayfb_set_par()
852 pfor = NONSTD_TO_PFOR(var->nonstd); in overlayfb_set_par()
854 ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | in overlayfb_set_par()
856 ofb->control[1] = OVLxC2_XPOS(xpos) | OVLxC2_YPOS(ypos); in overlayfb_set_par()
858 if (ofb->id == OVERLAY2) in overlayfb_set_par()
859 ofb->control[1] |= OVL2C2_PFOR(pfor); in overlayfb_set_par()
861 ofb->ops->setup(ofb); in overlayfb_set_par()
862 ofb->ops->enable(ofb); in overlayfb_set_par()
877 sprintf(ofb->fb.fix.id, "overlay%d", id + 1); in init_pxafb_overlay()
879 ofb->fb.fix.type = FB_TYPE_PACKED_PIXELS; in init_pxafb_overlay()
880 ofb->fb.fix.xpanstep = 0; in init_pxafb_overlay()
881 ofb->fb.fix.ypanstep = 1; in init_pxafb_overlay()
883 ofb->fb.var.activate = FB_ACTIVATE_NOW; in init_pxafb_overlay()
884 ofb->fb.var.height = -1; in init_pxafb_overlay()
885 ofb->fb.var.width = -1; in init_pxafb_overlay()
886 ofb->fb.var.vmode = FB_VMODE_NONINTERLACED; in init_pxafb_overlay()
888 ofb->fb.fbops = &overlay_fb_ops; in init_pxafb_overlay()
889 ofb->fb.node = -1; in init_pxafb_overlay()
890 ofb->fb.pseudo_palette = NULL; in init_pxafb_overlay()
892 ofb->id = id; in init_pxafb_overlay()
893 ofb->ops = &ofb_ops[id]; in init_pxafb_overlay()
894 ofb->usage = 0; in init_pxafb_overlay()
895 ofb->fbi = fbi; in init_pxafb_overlay()
896 init_completion(&ofb->branch_done); in init_pxafb_overlay()
913 ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size), in pxafb_overlay_map_video_memory()
915 if (ofb->video_mem == NULL) in pxafb_overlay_map_video_memory()
916 return -ENOMEM; in pxafb_overlay_map_video_memory()
918 ofb->video_mem_phys = virt_to_phys(ofb->video_mem); in pxafb_overlay_map_video_memory()
919 ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size); in pxafb_overlay_map_video_memory()
921 mutex_lock(&ofb->fb.mm_lock); in pxafb_overlay_map_video_memory()
922 ofb->fb.fix.smem_start = ofb->video_mem_phys; in pxafb_overlay_map_video_memory()
923 ofb->fb.fix.smem_len = pxafb->video_mem_size; in pxafb_overlay_map_video_memory()
924 mutex_unlock(&ofb->fb.mm_lock); in pxafb_overlay_map_video_memory()
926 ofb->fb.screen_base = ofb->video_mem; in pxafb_overlay_map_video_memory()
939 struct pxafb_layer *ofb = &fbi->overlay[i]; in pxafb_overlay_init()
941 ret = register_framebuffer(&ofb->fb); in pxafb_overlay_init()
943 dev_err(fbi->dev, "failed to register overlay %d\n", i); in pxafb_overlay_init()
948 dev_err(fbi->dev, in pxafb_overlay_init()
951 unregister_framebuffer(&ofb->fb); in pxafb_overlay_init()
954 ofb->registered = 1; in pxafb_overlay_init()
971 struct pxafb_layer *ofb = &fbi->overlay[i]; in pxafb_overlay_exit()
972 if (ofb->registered) { in pxafb_overlay_exit()
973 if (ofb->video_mem) in pxafb_overlay_exit()
974 free_pages_exact(ofb->video_mem, in pxafb_overlay_exit()
975 ofb->video_mem_size); in pxafb_overlay_exit()
976 unregister_framebuffer(&ofb->fb); in pxafb_overlay_exit()
991 * -------------
995 * ------------- - 1
1003 * period in picoseconds. Hence PixelClock = 1 / ( pixclock * 10^-12 )
1009 * PCD = (lclk * 10^4 ) * ( pixclock * 10^-12 )
1010 * -------------------------------------- - 1
1013 * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
1021 * (DPC) bit? or perhaps set it based on the various clock in get_pcd()
1023 pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000); in get_pcd()
1041 if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) { in set_hsync_time()
1042 fbi->hsync_time = 0; in set_hsync_time()
1046 htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len); in set_hsync_time()
1048 fbi->hsync_time = htime; in set_hsync_time()
1055 /* If display is blanked/suspended, hsync isn't active */ in pxafb_get_hsync_time()
1056 if (!fbi || (fbi->state != C_ENABLE)) in pxafb_get_hsync_time()
1059 return fbi->hsync_time; in pxafb_get_hsync_time()
1070 return -EINVAL; in setup_frame_dma()
1072 dma_desc = &fbi->dma_buff->dma_desc[dma]; in setup_frame_dma()
1075 dma_desc->fsadr = start; in setup_frame_dma()
1076 dma_desc->fidr = 0; in setup_frame_dma()
1077 dma_desc->ldcmd = size; in setup_frame_dma()
1080 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1081 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1083 pal_desc = &fbi->dma_buff->pal_desc[pal]; in setup_frame_dma()
1086 pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; in setup_frame_dma()
1087 pal_desc->fidr = 0; in setup_frame_dma()
1089 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) in setup_frame_dma()
1090 pal_desc->ldcmd = fbi->palette_size * sizeof(u16); in setup_frame_dma()
1092 pal_desc->ldcmd = fbi->palette_size * sizeof(u32); in setup_frame_dma()
1094 pal_desc->ldcmd |= LDCMD_PAL; in setup_frame_dma()
1097 pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1098 dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off; in setup_frame_dma()
1099 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1109 struct fb_fix_screeninfo *fix = &fbi->fb.fix; in setup_base_frame()
1110 int nbytes, dma, pal, bpp = var->bits_per_pixel; in setup_base_frame()
1116 nbytes = fix->line_length * var->yres; in setup_base_frame()
1117 offset = fix->line_length * var->yoffset + fbi->video_mem_phys; in setup_base_frame()
1119 if (fbi->lccr0 & LCCR0_SDS) { in setup_base_frame()
1133 dma_desc = &fbi->dma_buff->dma_desc[DMA_CMD]; in setup_smart_dma()
1137 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; in setup_smart_dma()
1138 dma_desc->fsadr = fbi->dma_buff_phys + cmd_buff_off; in setup_smart_dma()
1139 dma_desc->fidr = 0; in setup_smart_dma()
1140 dma_desc->ldcmd = fbi->n_smart_cmds * sizeof(uint16_t); in setup_smart_dma()
1142 fbi->fdadr[DMA_CMD] = dma_desc->fdadr; in setup_smart_dma()
1153 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); in pxafb_smart_flush()
1155 /* 1. make it an even number of commands to align on 32-bit boundary in pxafb_smart_flush()
1160 while (fbi->n_smart_cmds & 1) in pxafb_smart_flush()
1161 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_NOOP; in pxafb_smart_flush()
1163 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_INTERRUPT; in pxafb_smart_flush()
1164 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_WAIT_FOR_VSYNC; in pxafb_smart_flush()
1171 /* stop the processor in case it executed "wait for sync" cmd */ in pxafb_smart_flush()
1174 /* don't send interrupts for fifo underruns on channel 6 */ in pxafb_smart_flush()
1177 lcd_writel(fbi, LCCR1, fbi->reg_lccr1); in pxafb_smart_flush()
1178 lcd_writel(fbi, LCCR2, fbi->reg_lccr2); in pxafb_smart_flush()
1179 lcd_writel(fbi, LCCR3, fbi->reg_lccr3); in pxafb_smart_flush()
1180 lcd_writel(fbi, LCCR4, fbi->reg_lccr4); in pxafb_smart_flush()
1181 lcd_writel(fbi, FDADR0, fbi->fdadr[0]); in pxafb_smart_flush()
1182 lcd_writel(fbi, FDADR6, fbi->fdadr[6]); in pxafb_smart_flush()
1185 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); in pxafb_smart_flush()
1187 if (wait_for_completion_timeout(&fbi->command_done, HZ/2) == 0) { in pxafb_smart_flush()
1189 ret = -ETIMEDOUT; in pxafb_smart_flush()
1195 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); in pxafb_smart_flush()
1197 fbi->n_smart_cmds = 0; in pxafb_smart_flush()
1215 if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8) in pxafb_smart_queue()
1218 fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds; in pxafb_smart_queue()
1233 struct pxafb_mach_info *inf = fbi->inf; in setup_smart_timing()
1234 struct pxafb_mode_info *mode = &inf->modes[0]; in setup_smart_timing()
1235 unsigned long lclk = clk_get_rate(fbi->clk); in setup_smart_timing()
1238 t1 = max(mode->a0csrd_set_hld, mode->a0cswr_set_hld); in setup_smart_timing()
1239 t2 = max(mode->rd_pulse_width, mode->wr_pulse_width); in setup_smart_timing()
1240 t3 = mode->op_hold_time; in setup_smart_timing()
1241 t4 = mode->cmd_inh_time; in setup_smart_timing()
1243 fbi->reg_lccr1 = in setup_smart_timing()
1244 LCCR1_DisWdth(var->xres) | in setup_smart_timing()
1249 fbi->reg_lccr2 = LCCR2_DisHght(var->yres); in setup_smart_timing()
1250 fbi->reg_lccr3 = fbi->lccr3 | LCCR3_PixClkDiv(__smart_timing(t4, lclk)); in setup_smart_timing()
1251 fbi->reg_lccr3 |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HSP : 0; in setup_smart_timing()
1252 fbi->reg_lccr3 |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VSP : 0; in setup_smart_timing()
1255 fbi->reg_cmdcr = 1; in setup_smart_timing()
1261 struct pxafb_mach_info *inf = fbi->inf; in pxafb_smart_thread()
1263 if (!inf->smart_update) { in pxafb_smart_thread()
1266 return -EINVAL; in pxafb_smart_thread()
1277 mutex_lock(&fbi->ctrlr_lock); in pxafb_smart_thread()
1279 if (fbi->state == C_ENABLE) { in pxafb_smart_thread()
1280 inf->smart_update(&fbi->fb); in pxafb_smart_thread()
1281 complete(&fbi->refresh_done); in pxafb_smart_thread()
1284 mutex_unlock(&fbi->ctrlr_lock); in pxafb_smart_thread()
1296 if (!(fbi->lccr0 & LCCR0_LCDT)) in pxafb_smart_init()
1299 fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; in pxafb_smart_init()
1300 fbi->n_smart_cmds = 0; in pxafb_smart_init()
1302 init_completion(&fbi->command_done); in pxafb_smart_init()
1303 init_completion(&fbi->refresh_done); in pxafb_smart_init()
1305 fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi, in pxafb_smart_init()
1307 if (IS_ERR(fbi->smart_thread)) { in pxafb_smart_init()
1309 return PTR_ERR(fbi->smart_thread); in pxafb_smart_init()
1321 unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); in setup_parallel_timing()
1323 fbi->reg_lccr1 = in setup_parallel_timing()
1324 LCCR1_DisWdth(var->xres) + in setup_parallel_timing()
1325 LCCR1_HorSnchWdth(var->hsync_len) + in setup_parallel_timing()
1326 LCCR1_BegLnDel(var->left_margin) + in setup_parallel_timing()
1327 LCCR1_EndLnDel(var->right_margin); in setup_parallel_timing()
1333 lines_per_panel = var->yres; in setup_parallel_timing()
1334 if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) in setup_parallel_timing()
1337 fbi->reg_lccr2 = in setup_parallel_timing()
1339 LCCR2_VrtSnchWdth(var->vsync_len) + in setup_parallel_timing()
1340 LCCR2_BegFrmDel(var->upper_margin) + in setup_parallel_timing()
1341 LCCR2_EndFrmDel(var->lower_margin); in setup_parallel_timing()
1343 fbi->reg_lccr3 = fbi->lccr3 | in setup_parallel_timing()
1344 (var->sync & FB_SYNC_HOR_HIGH_ACT ? in setup_parallel_timing()
1346 (var->sync & FB_SYNC_VERT_HIGH_ACT ? in setup_parallel_timing()
1350 fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd); in setup_parallel_timing()
1357 * Configures LCD Controller based on entries in var parameter.
1369 if (fbi->lccr0 & LCCR0_LCDT) in pxafb_activate_var()
1377 fbi->reg_lccr0 = fbi->lccr0 | in pxafb_activate_var()
1381 fbi->reg_lccr3 |= pxafb_var_to_lccr3(var); in pxafb_activate_var()
1383 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK; in pxafb_activate_var()
1384 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); in pxafb_activate_var()
1391 if ((lcd_readl(fbi, LCCR0) != fbi->reg_lccr0) || in pxafb_activate_var()
1392 (lcd_readl(fbi, LCCR1) != fbi->reg_lccr1) || in pxafb_activate_var()
1393 (lcd_readl(fbi, LCCR2) != fbi->reg_lccr2) || in pxafb_activate_var()
1394 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || in pxafb_activate_var()
1395 (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || in pxafb_activate_var()
1396 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || in pxafb_activate_var()
1397 ((fbi->lccr0 & LCCR0_SDS) && in pxafb_activate_var()
1398 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))) in pxafb_activate_var()
1408 * -- rmk
1410 static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on) in __pxafb_backlight_power() argument
1412 pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff"); in __pxafb_backlight_power()
1414 if (fbi->backlight_power) in __pxafb_backlight_power()
1415 fbi->backlight_power(on); in __pxafb_backlight_power()
1418 static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on) in __pxafb_lcd_power() argument
1420 pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff"); in __pxafb_lcd_power()
1422 if (fbi->lcd_power) in __pxafb_lcd_power()
1423 fbi->lcd_power(on, &fbi->fb.var); in __pxafb_lcd_power()
1425 if (fbi->lcd_supply && fbi->lcd_supply_enabled != on) { in __pxafb_lcd_power()
1428 if (on) in __pxafb_lcd_power()
1429 ret = regulator_enable(fbi->lcd_supply); in __pxafb_lcd_power()
1431 ret = regulator_disable(fbi->lcd_supply); in __pxafb_lcd_power()
1435 on ? "enable" : "disable", ret); in __pxafb_lcd_power()
1437 fbi->lcd_supply_enabled = on; in __pxafb_lcd_power()
1444 pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]); in pxafb_enable_controller()
1445 pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]); in pxafb_enable_controller()
1446 pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0); in pxafb_enable_controller()
1447 pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1); in pxafb_enable_controller()
1448 pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2); in pxafb_enable_controller()
1449 pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3); in pxafb_enable_controller()
1452 if (clk_prepare_enable(fbi->clk)) { in pxafb_enable_controller()
1457 if (fbi->lccr0 & LCCR0_LCDT) in pxafb_enable_controller()
1461 lcd_writel(fbi, LCCR4, fbi->reg_lccr4); in pxafb_enable_controller()
1462 lcd_writel(fbi, LCCR3, fbi->reg_lccr3); in pxafb_enable_controller()
1463 lcd_writel(fbi, LCCR2, fbi->reg_lccr2); in pxafb_enable_controller()
1464 lcd_writel(fbi, LCCR1, fbi->reg_lccr1); in pxafb_enable_controller()
1465 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); in pxafb_enable_controller()
1467 lcd_writel(fbi, FDADR0, fbi->fdadr[0]); in pxafb_enable_controller()
1468 if (fbi->lccr0 & LCCR0_SDS) in pxafb_enable_controller()
1469 lcd_writel(fbi, FDADR1, fbi->fdadr[1]); in pxafb_enable_controller()
1470 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); in pxafb_enable_controller()
1478 if (fbi->lccr0 & LCCR0_LCDT) { in pxafb_disable_controller()
1479 wait_for_completion_timeout(&fbi->refresh_done, in pxafb_disable_controller()
1492 wait_for_completion_timeout(&fbi->disable_done, msecs_to_jiffies(200)); in pxafb_disable_controller()
1495 clk_disable_unprepare(fbi->clk); in pxafb_disable_controller()
1510 complete(&fbi->disable_done); in pxafb_handle_irq()
1515 complete(&fbi->command_done); in pxafb_handle_irq()
1523 complete(&fbi->overlay[0].branch_done); in pxafb_handle_irq()
1526 complete(&fbi->overlay[1].branch_done); in pxafb_handle_irq()
1543 mutex_lock(&fbi->ctrlr_lock); in set_ctrlr_state()
1545 old_state = fbi->state; in set_ctrlr_state()
1560 fbi->state = state; in set_ctrlr_state()
1572 fbi->state = state; in set_ctrlr_state()
1586 fbi->state = C_ENABLE; in set_ctrlr_state()
1594 * Re-enable the controller only if it was already in set_ctrlr_state()
1608 * Re-enable the controller after PM. This is not in set_ctrlr_state()
1609 * perfect - think about the case where we were doing in set_ctrlr_state()
1610 * a clock change, and we suspended half-way through. in set_ctrlr_state()
1619 * turn on the backlight. in set_ctrlr_state()
1622 fbi->state = C_ENABLE; in set_ctrlr_state()
1629 mutex_unlock(&fbi->ctrlr_lock); in set_ctrlr_state()
1640 u_int state = xchg(&fbi->task_state, -1); in pxafb_task()
1651 * TODO: Determine why f->new != 10*get_lclk_frequency_10khz()
1663 if (!(fbi->overlay[0].usage || fbi->overlay[1].usage)) in pxafb_freq_transition()
1669 pcd = get_pcd(fbi, fbi->fb.var.pixclock); in pxafb_freq_transition()
1671 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | in pxafb_freq_transition()
1709 int size = PAGE_ALIGN(fbi->video_mem_size); in pxafb_init_video_memory()
1711 fbi->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); in pxafb_init_video_memory()
1712 if (fbi->video_mem == NULL) in pxafb_init_video_memory()
1713 return -ENOMEM; in pxafb_init_video_memory()
1715 fbi->video_mem_phys = virt_to_phys(fbi->video_mem); in pxafb_init_video_memory()
1716 fbi->video_mem_size = size; in pxafb_init_video_memory()
1718 fbi->fb.fix.smem_start = fbi->video_mem_phys; in pxafb_init_video_memory()
1719 fbi->fb.fix.smem_len = fbi->video_mem_size; in pxafb_init_video_memory()
1720 fbi->fb.screen_base = fbi->video_mem; in pxafb_init_video_memory()
1722 return fbi->video_mem ? 0 : -ENOMEM; in pxafb_init_video_memory()
1728 unsigned int lcd_conn = inf->lcd_conn; in pxafb_decode_mach_info()
1732 fbi->cmap_inverse = inf->cmap_inverse; in pxafb_decode_mach_info()
1733 fbi->cmap_static = inf->cmap_static; in pxafb_decode_mach_info()
1734 fbi->lccr4 = inf->lccr4; in pxafb_decode_mach_info()
1738 fbi->lccr0 = LCCR0_CMS; in pxafb_decode_mach_info()
1741 fbi->lccr0 = LCCR0_CMS | LCCR0_SDS; in pxafb_decode_mach_info()
1744 fbi->lccr0 = 0; in pxafb_decode_mach_info()
1747 fbi->lccr0 = LCCR0_SDS; in pxafb_decode_mach_info()
1750 fbi->lccr0 = LCCR0_PAS; in pxafb_decode_mach_info()
1753 fbi->lccr0 = LCCR0_LCDT | LCCR0_PAS; in pxafb_decode_mach_info()
1757 fbi->lccr0 = inf->lccr0; in pxafb_decode_mach_info()
1758 fbi->lccr3 = inf->lccr3; in pxafb_decode_mach_info()
1763 fbi->lccr0 |= LCCR0_DPD; in pxafb_decode_mach_info()
1765 fbi->lccr0 |= (lcd_conn & LCD_ALTERNATE_MAPPING) ? LCCR0_LDDALT : 0; in pxafb_decode_mach_info()
1767 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff); in pxafb_decode_mach_info()
1768 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0; in pxafb_decode_mach_info()
1769 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0; in pxafb_decode_mach_info()
1772 pxafb_setmode(&fbi->fb.var, &inf->modes[0]); in pxafb_decode_mach_info()
1779 for (i = 0, m = &inf->modes[0]; i < inf->num_modes; i++, m++) in pxafb_decode_mach_info()
1780 fbi->video_mem_size = max_t(size_t, fbi->video_mem_size, in pxafb_decode_mach_info()
1781 m->xres * m->yres * m->bpp / 8); in pxafb_decode_mach_info()
1783 if (inf->video_mem_size > fbi->video_mem_size) in pxafb_decode_mach_info()
1784 fbi->video_mem_size = inf->video_mem_size; in pxafb_decode_mach_info()
1786 if (video_mem_size > fbi->video_mem_size) in pxafb_decode_mach_info()
1787 fbi->video_mem_size = video_mem_size; in pxafb_decode_mach_info()
1800 return ERR_PTR(-ENOMEM); in pxafb_init_fbinfo()
1802 fbi->dev = dev; in pxafb_init_fbinfo()
1803 fbi->inf = inf; in pxafb_init_fbinfo()
1805 fbi->clk = devm_clk_get(dev, NULL); in pxafb_init_fbinfo()
1806 if (IS_ERR(fbi->clk)) in pxafb_init_fbinfo()
1807 return ERR_CAST(fbi->clk); in pxafb_init_fbinfo()
1809 strcpy(fbi->fb.fix.id, PXA_NAME); in pxafb_init_fbinfo()
1811 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; in pxafb_init_fbinfo()
1812 fbi->fb.fix.type_aux = 0; in pxafb_init_fbinfo()
1813 fbi->fb.fix.xpanstep = 0; in pxafb_init_fbinfo()
1814 fbi->fb.fix.ypanstep = 1; in pxafb_init_fbinfo()
1815 fbi->fb.fix.ywrapstep = 0; in pxafb_init_fbinfo()
1816 fbi->fb.fix.accel = FB_ACCEL_NONE; in pxafb_init_fbinfo()
1818 fbi->fb.var.nonstd = 0; in pxafb_init_fbinfo()
1819 fbi->fb.var.activate = FB_ACTIVATE_NOW; in pxafb_init_fbinfo()
1820 fbi->fb.var.height = -1; in pxafb_init_fbinfo()
1821 fbi->fb.var.width = -1; in pxafb_init_fbinfo()
1822 fbi->fb.var.accel_flags = FB_ACCELF_TEXT; in pxafb_init_fbinfo()
1823 fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; in pxafb_init_fbinfo()
1825 fbi->fb.fbops = &pxafb_ops; in pxafb_init_fbinfo()
1826 fbi->fb.node = -1; in pxafb_init_fbinfo()
1830 fbi->fb.pseudo_palette = addr; in pxafb_init_fbinfo()
1832 fbi->state = C_STARTUP; in pxafb_init_fbinfo()
1833 fbi->task_state = (u_char)-1; in pxafb_init_fbinfo()
1838 /* place overlay(s) on top of base */ in pxafb_init_fbinfo()
1840 fbi->lccr0 |= LCCR0_OUC; in pxafb_init_fbinfo()
1843 init_waitqueue_head(&fbi->ctrlr_wait); in pxafb_init_fbinfo()
1844 INIT_WORK(&fbi->task, pxafb_task); in pxafb_init_fbinfo()
1845 mutex_init(&fbi->ctrlr_lock); in pxafb_init_fbinfo()
1846 init_completion(&fbi->disable_done); in pxafb_init_fbinfo()
1861 for (i = namelen-1; i >= 0; i--) { in parse_opt_mode()
1863 case '-': in parse_opt_mode()
1891 inf->modes[0].xres = xres; inf->modes[0].yres = yres; in parse_opt_mode()
1900 inf->modes[0].bpp = bpp; in parse_opt_mode()
1905 return -EINVAL; in parse_opt_mode()
1913 struct pxafb_mode_info *mode = &inf->modes[0]; in parse_opt()
1923 mode->pixclock = simple_strtoul(this_opt+9, NULL, 0); in parse_opt()
1924 sprintf(s, "pixclock: %ld\n", mode->pixclock); in parse_opt()
1926 mode->left_margin = simple_strtoul(this_opt+5, NULL, 0); in parse_opt()
1927 sprintf(s, "left: %u\n", mode->left_margin); in parse_opt()
1929 mode->right_margin = simple_strtoul(this_opt+6, NULL, 0); in parse_opt()
1930 sprintf(s, "right: %u\n", mode->right_margin); in parse_opt()
1932 mode->upper_margin = simple_strtoul(this_opt+6, NULL, 0); in parse_opt()
1933 sprintf(s, "upper: %u\n", mode->upper_margin); in parse_opt()
1935 mode->lower_margin = simple_strtoul(this_opt+6, NULL, 0); in parse_opt()
1936 sprintf(s, "lower: %u\n", mode->lower_margin); in parse_opt()
1938 mode->hsync_len = simple_strtoul(this_opt+9, NULL, 0); in parse_opt()
1939 sprintf(s, "hsynclen: %u\n", mode->hsync_len); in parse_opt()
1941 mode->vsync_len = simple_strtoul(this_opt+9, NULL, 0); in parse_opt()
1942 sprintf(s, "vsynclen: %u\n", mode->vsync_len); in parse_opt()
1945 sprintf(s, "hsync: Active Low\n"); in parse_opt()
1946 mode->sync &= ~FB_SYNC_HOR_HIGH_ACT; in parse_opt()
1948 sprintf(s, "hsync: Active High\n"); in parse_opt()
1949 mode->sync |= FB_SYNC_HOR_HIGH_ACT; in parse_opt()
1953 sprintf(s, "vsync: Active Low\n"); in parse_opt()
1954 mode->sync &= ~FB_SYNC_VERT_HIGH_ACT; in parse_opt()
1956 sprintf(s, "vsync: Active High\n"); in parse_opt()
1957 mode->sync |= FB_SYNC_VERT_HIGH_ACT; in parse_opt()
1962 inf->lccr3 &= ~LCCR3_DPC; in parse_opt()
1965 inf->lccr3 |= LCCR3_DPC; in parse_opt()
1969 sprintf(s, "output enable: active low\n"); in parse_opt()
1970 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL; in parse_opt()
1972 sprintf(s, "output enable: active high\n"); in parse_opt()
1973 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH; in parse_opt()
1978 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg; in parse_opt()
1981 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg; in parse_opt()
1984 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color; in parse_opt()
1986 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Mono; in parse_opt()
1987 } else if (!strncmp(this_opt, "active", 6)) { in parse_opt()
1988 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Act; in parse_opt()
1990 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Pas; in parse_opt()
1992 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Sngl; in parse_opt()
1994 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Dual; in parse_opt()
1996 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_4PixMono; in parse_opt()
1998 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_8PixMono; in parse_opt()
2001 return -EINVAL; in parse_opt()
2038 return -ENODEV; in pxafb_setup_options()
2058 /* Check for various illegal bit-combinations. Currently only
2062 if (inf->lcd_conn) in pxafb_check_options()
2065 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) in pxafb_check_options()
2068 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK); in pxafb_check_options()
2069 if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK) in pxafb_check_options()
2072 inf->lccr3 & LCCR3_INVALID_CONFIG_MASK); in pxafb_check_options()
2073 if (inf->lccr0 & LCCR0_DPD && in pxafb_check_options()
2074 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas || in pxafb_check_options()
2075 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || in pxafb_check_options()
2076 (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono)) in pxafb_check_options()
2080 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act && in pxafb_check_options()
2081 (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual) in pxafb_check_options()
2083 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas && in pxafb_check_options()
2084 (inf->modes->upper_margin || inf->modes->lower_margin)) in pxafb_check_options()
2094 "unknown", "mono-stn", "mono-dstn", "color-stn", "color-dstn",
2095 "color-tft", "smart-panel", NULL
2103 int i, ret = -EINVAL; in of_get_pxafb_display()
2106 ret = of_property_read_string(disp, "lcd-type", &s); in of_get_pxafb_display()
2108 s = "color-tft"; in of_get_pxafb_display()
2110 i = match_string(lcd_types, -1, s); in of_get_pxafb_display()
2112 dev_err(dev, "lcd-type %s is unknown\n", s); in of_get_pxafb_display()
2115 info->lcd_conn |= LCD_CONN_TYPE(i); in of_get_pxafb_display()
2116 info->lcd_conn |= LCD_CONN_WIDTH(bus_width); in of_get_pxafb_display()
2120 return -EINVAL; in of_get_pxafb_display()
2122 ret = -ENOMEM; in of_get_pxafb_display()
2123 info->modes = devm_kcalloc(dev, timings->num_timings, in of_get_pxafb_display()
2124 sizeof(info->modes[0]), in of_get_pxafb_display()
2126 if (!info->modes) in of_get_pxafb_display()
2128 info->num_modes = timings->num_timings; in of_get_pxafb_display()
2130 for (i = 0; i < timings->num_timings; i++) { in of_get_pxafb_display()
2138 info->lcd_conn |= LCD_PCLK_EDGE_RISE; in of_get_pxafb_display()
2140 info->lcd_conn |= LCD_PCLK_EDGE_FALL; in of_get_pxafb_display()
2142 info->lcd_conn |= LCD_BIAS_ACTIVE_HIGH; in of_get_pxafb_display()
2144 info->lcd_conn |= LCD_BIAS_ACTIVE_LOW; in of_get_pxafb_display()
2146 info->modes[i].sync |= FB_SYNC_HOR_HIGH_ACT; in of_get_pxafb_display()
2148 info->modes[i].sync |= FB_SYNC_VERT_HIGH_ACT; in of_get_pxafb_display()
2150 info->modes[i].pixclock = 1000000000UL / (vm.pixelclock / 1000); in of_get_pxafb_display()
2151 info->modes[i].xres = vm.hactive; in of_get_pxafb_display()
2152 info->modes[i].yres = vm.vactive; in of_get_pxafb_display()
2153 info->modes[i].hsync_len = vm.hsync_len; in of_get_pxafb_display()
2154 info->modes[i].left_margin = vm.hback_porch; in of_get_pxafb_display()
2155 info->modes[i].right_margin = vm.hfront_porch; in of_get_pxafb_display()
2156 info->modes[i].vsync_len = vm.vsync_len; in of_get_pxafb_display()
2157 info->modes[i].upper_margin = vm.vback_porch; in of_get_pxafb_display()
2158 info->modes[i].lower_margin = vm.vfront_porch; in of_get_pxafb_display()
2174 np = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); in of_get_pxafb_mode_info()
2177 return -EINVAL; in of_get_pxafb_mode_info()
2179 ret = of_property_read_u32(np, "bus-width", &bus_width); in of_get_pxafb_mode_info()
2181 dev_err(dev, "no bus-width specified: %d\n", ret); in of_get_pxafb_mode_info()
2190 return -EINVAL; in of_get_pxafb_mode_info()
2198 for (i = 0; i < info->num_modes; i++) in of_get_pxafb_mode_info()
2199 info->modes[i].bpp = bus_width; in of_get_pxafb_mode_info()
2209 if (!dev->of_node) in of_pxafb_of_mach_info()
2213 return ERR_PTR(-ENOMEM); in of_pxafb_of_mach_info()
2219 * On purpose, neither lccrX registers nor video memory size can be in of_pxafb_of_mach_info()
2220 * specified through device-tree, they are considered more a debug hack in of_pxafb_of_mach_info()
2238 dev_dbg(&dev->dev, "pxafb_probe\n"); in pxafb_probe()
2240 ret = -ENOMEM; in pxafb_probe()
2241 pdata = dev_get_platdata(&dev->dev); in pxafb_probe()
2242 inf = devm_kmalloc(&dev->dev, sizeof(*inf), GFP_KERNEL); in pxafb_probe()
2248 inf->modes = in pxafb_probe()
2249 devm_kmalloc_array(&dev->dev, pdata->num_modes, in pxafb_probe()
2250 sizeof(inf->modes[0]), GFP_KERNEL); in pxafb_probe()
2251 if (!inf->modes) in pxafb_probe()
2253 for (i = 0; i < inf->num_modes; i++) in pxafb_probe()
2254 inf->modes[i] = pdata->modes[i]; in pxafb_probe()
2256 inf = of_pxafb_of_mach_info(&dev->dev); in pxafb_probe()
2262 ret = pxafb_parse_options(&dev->dev, g_options, inf); in pxafb_probe()
2266 pxafb_check_options(&dev->dev, inf); in pxafb_probe()
2268 dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n", in pxafb_probe()
2269 inf->modes->xres, in pxafb_probe()
2270 inf->modes->yres, in pxafb_probe()
2271 inf->modes->bpp); in pxafb_probe()
2272 if (inf->modes->xres == 0 || in pxafb_probe()
2273 inf->modes->yres == 0 || in pxafb_probe()
2274 inf->modes->bpp == 0) { in pxafb_probe()
2275 dev_err(&dev->dev, "Invalid resolution or bit depth\n"); in pxafb_probe()
2276 ret = -EINVAL; in pxafb_probe()
2280 fbi = pxafb_init_fbinfo(&dev->dev, inf); in pxafb_probe()
2282 dev_err(&dev->dev, "Failed to initialize framebuffer device\n"); in pxafb_probe()
2287 if (cpu_is_pxa3xx() && inf->acceleration_enabled) in pxafb_probe()
2288 fbi->fb.fix.accel = FB_ACCEL_PXA3XX; in pxafb_probe()
2290 fbi->backlight_power = inf->pxafb_backlight_power; in pxafb_probe()
2291 fbi->lcd_power = inf->pxafb_lcd_power; in pxafb_probe()
2293 fbi->lcd_supply = devm_regulator_get_optional(&dev->dev, "lcd"); in pxafb_probe()
2294 if (IS_ERR(fbi->lcd_supply)) { in pxafb_probe()
2295 if (PTR_ERR(fbi->lcd_supply) == -EPROBE_DEFER) in pxafb_probe()
2296 return -EPROBE_DEFER; in pxafb_probe()
2298 fbi->lcd_supply = NULL; in pxafb_probe()
2301 fbi->mmio_base = devm_platform_ioremap_resource(dev, 0); in pxafb_probe()
2302 if (IS_ERR(fbi->mmio_base)) { in pxafb_probe()
2303 dev_err(&dev->dev, "failed to get I/O memory\n"); in pxafb_probe()
2304 ret = PTR_ERR(fbi->mmio_base); in pxafb_probe()
2308 fbi->dma_buff_size = PAGE_ALIGN(sizeof(struct pxafb_dma_buff)); in pxafb_probe()
2309 fbi->dma_buff = dma_alloc_coherent(fbi->dev, fbi->dma_buff_size, in pxafb_probe()
2310 &fbi->dma_buff_phys, GFP_KERNEL); in pxafb_probe()
2311 if (fbi->dma_buff == NULL) { in pxafb_probe()
2312 dev_err(&dev->dev, "failed to allocate memory for DMA\n"); in pxafb_probe()
2313 ret = -ENOMEM; in pxafb_probe()
2319 dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret); in pxafb_probe()
2320 ret = -ENOMEM; in pxafb_probe()
2326 ret = -ENODEV; in pxafb_probe()
2330 ret = devm_request_irq(&dev->dev, irq, pxafb_handle_irq, 0, "LCD", fbi); in pxafb_probe()
2332 dev_err(&dev->dev, "request_irq failed: %d\n", ret); in pxafb_probe()
2333 ret = -EBUSY; in pxafb_probe()
2339 dev_err(&dev->dev, "failed to initialize smartpanel\n"); in pxafb_probe()
2347 ret = pxafb_check_var(&fbi->fb.var, &fbi->fb); in pxafb_probe()
2349 dev_err(&dev->dev, "failed to get suitable mode\n"); in pxafb_probe()
2353 ret = pxafb_set_par(&fbi->fb); in pxafb_probe()
2355 dev_err(&dev->dev, "Failed to set parameters\n"); in pxafb_probe()
2361 ret = register_framebuffer(&fbi->fb); in pxafb_probe()
2363 dev_err(&dev->dev, in pxafb_probe()
2371 fbi->freq_transition.notifier_call = pxafb_freq_transition; in pxafb_probe()
2372 cpufreq_register_notifier(&fbi->freq_transition, in pxafb_probe()
2384 if (fbi->fb.cmap.len) in pxafb_probe()
2385 fb_dealloc_cmap(&fbi->fb.cmap); in pxafb_probe()
2387 free_pages_exact(fbi->video_mem, fbi->video_mem_size); in pxafb_probe()
2389 dma_free_coherent(&dev->dev, fbi->dma_buff_size, in pxafb_probe()
2390 fbi->dma_buff, fbi->dma_buff_phys); in pxafb_probe()
2403 info = &fbi->fb; in pxafb_remove()
2406 cancel_work_sync(&fbi->task); in pxafb_remove()
2411 if (fbi->fb.cmap.len) in pxafb_remove()
2412 fb_dealloc_cmap(&fbi->fb.cmap); in pxafb_remove()
2414 free_pages_exact(fbi->video_mem, fbi->video_mem_size); in pxafb_remove()
2416 dma_free_coherent(&dev->dev, fbi->dma_buff_size, fbi->dma_buff, in pxafb_remove()
2417 fbi->dma_buff_phys); in pxafb_remove()
2421 { .compatible = "marvell,pxa270-lcdc", },
2422 { .compatible = "marvell,pxa300-lcdc", },
2423 { .compatible = "marvell,pxa2xx-lcdc", },
2432 .name = "pxa2xx-fb",
2443 return -EINVAL; in pxafb_init()