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()
615 int size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual; in overlay1fb_setup()
616 unsigned long start = ofb->video_mem_phys; in overlay1fb_setup()
617 setup_frame_dma(ofb->fbi, DMA_OV1, PAL_NONE, start, size); in overlay1fb_setup()
620 /* Depending on the enable status of overlay1/2, the DMA should be
625 int enabled = lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN; in overlay1fb_enable()
626 uint32_t fdadr1 = ofb->fbi->fdadr[DMA_OV1] | (enabled ? 0x1 : 0); in overlay1fb_enable()
628 lcd_writel(ofb->fbi, enabled ? FBR1 : FDADR1, fdadr1); in overlay1fb_enable()
629 lcd_writel(ofb->fbi, OVL1C2, ofb->control[1]); in overlay1fb_enable()
630 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] | OVLxC1_OEN); in overlay1fb_enable()
637 if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)) in overlay1fb_disable()
640 lccr5 = lcd_readl(ofb->fbi, LCCR5); in overlay1fb_disable()
642 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); in overlay1fb_disable()
644 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1)); in overlay1fb_disable()
645 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1)); in overlay1fb_disable()
646 lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3); in overlay1fb_disable()
648 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0) in overlay1fb_disable()
651 lcd_writel(ofb->fbi, LCCR5, lccr5); in overlay1fb_disable()
656 int size, div = 1, pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd); in overlay2fb_setup()
657 unsigned long start[3] = { ofb->video_mem_phys, 0, 0 }; in overlay2fb_setup()
660 size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual; in overlay2fb_setup()
661 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size); in overlay2fb_setup()
663 size = ofb->fb.var.xres_virtual * ofb->fb.var.yres_virtual; in overlay2fb_setup()
671 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size); in overlay2fb_setup()
672 setup_frame_dma(ofb->fbi, DMA_OV2_Cb, -1, start[1], size / div); in overlay2fb_setup()
673 setup_frame_dma(ofb->fbi, DMA_OV2_Cr, -1, start[2], size / div); in overlay2fb_setup()
679 int pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd); in overlay2fb_enable()
680 int enabled = lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN; in overlay2fb_enable()
681 uint32_t fdadr2 = ofb->fbi->fdadr[DMA_OV2_Y] | (enabled ? 0x1 : 0); in overlay2fb_enable()
682 uint32_t fdadr3 = ofb->fbi->fdadr[DMA_OV2_Cb] | (enabled ? 0x1 : 0); in overlay2fb_enable()
683 uint32_t fdadr4 = ofb->fbi->fdadr[DMA_OV2_Cr] | (enabled ? 0x1 : 0); in overlay2fb_enable()
686 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2); in overlay2fb_enable()
688 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2); in overlay2fb_enable()
689 lcd_writel(ofb->fbi, enabled ? FBR3 : FDADR3, fdadr3); in overlay2fb_enable()
690 lcd_writel(ofb->fbi, enabled ? FBR4 : FDADR4, fdadr4); in overlay2fb_enable()
692 lcd_writel(ofb->fbi, OVL2C2, ofb->control[1]); in overlay2fb_enable()
693 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] | OVLxC1_OEN); in overlay2fb_enable()
700 if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN)) in overlay2fb_disable()
703 lccr5 = lcd_readl(ofb->fbi, LCCR5); in overlay2fb_disable()
705 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); in overlay2fb_disable()
707 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2)); in overlay2fb_disable()
708 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2)); in overlay2fb_disable()
709 lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3); in overlay2fb_disable()
710 lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3); in overlay2fb_disable()
711 lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3); in overlay2fb_disable()
713 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0) in overlay2fb_disable()
734 /* no support for framebuffer console on overlay */ in overlayfb_open()
736 return -ENODEV; in overlayfb_open()
738 if (ofb->usage++ == 0) { in overlayfb_open()
741 fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); in overlayfb_open()
752 if (ofb->usage == 1) { in overlayfb_release()
753 ofb->ops->disable(ofb); in overlayfb_release()
754 ofb->fb.var.height = -1; in overlayfb_release()
755 ofb->fb.var.width = -1; in overlayfb_release()
756 ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0; in overlayfb_release()
757 ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0; in overlayfb_release()
759 ofb->usage--; in overlayfb_release()
768 struct fb_var_screeninfo *base_var = &ofb->fbi->fb.var; in overlayfb_check_var()
771 xpos = NONSTD_TO_XPOS(var->nonstd); in overlayfb_check_var()
772 ypos = NONSTD_TO_YPOS(var->nonstd); in overlayfb_check_var()
773 pfor = NONSTD_TO_PFOR(var->nonstd); in overlayfb_check_var()
777 return -EINVAL; in overlayfb_check_var()
779 /* no support for YUV format on overlay1 */ in overlayfb_check_var()
780 if (ofb->id == OVERLAY1 && pfor != 0) in overlayfb_check_var()
781 return -EINVAL; in overlayfb_check_var()
788 return -EINVAL; in overlayfb_check_var()
797 return -EINVAL; in overlayfb_check_var()
800 /* each line must start at a 32-bit word boundary */ in overlayfb_check_var()
802 return -EINVAL; in overlayfb_check_var()
804 /* xres must align on 32-bit word boundary */ in overlayfb_check_var()
805 var->xres = roundup(var->xres * bpp, 32) / bpp; in overlayfb_check_var()
807 if ((xpos + var->xres > base_var->xres) || in overlayfb_check_var()
808 (ypos + var->yres > base_var->yres)) in overlayfb_check_var()
809 return -EINVAL; in overlayfb_check_var()
811 var->xres_virtual = var->xres; in overlayfb_check_var()
812 var->yres_virtual = max(var->yres, var->yres_virtual); in overlayfb_check_var()
818 struct fb_var_screeninfo *var = &ofb->fb.var; in overlayfb_check_video_memory()
819 int pfor = NONSTD_TO_PFOR(var->nonstd); in overlayfb_check_video_memory()
823 case OVERLAY_FORMAT_RGB: bpp = var->bits_per_pixel; break; in overlayfb_check_video_memory()
830 ofb->fb.fix.line_length = var->xres_virtual * bpp / 8; in overlayfb_check_video_memory()
832 size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); in overlayfb_check_video_memory()
834 if (ofb->video_mem) { in overlayfb_check_video_memory()
835 if (ofb->video_mem_size >= size) in overlayfb_check_video_memory()
838 return -EINVAL; in overlayfb_check_video_memory()
844 struct fb_var_screeninfo *var = &info->var; in overlayfb_set_par()
852 xpos = NONSTD_TO_XPOS(var->nonstd); in overlayfb_set_par()
853 ypos = NONSTD_TO_YPOS(var->nonstd); in overlayfb_set_par()
854 pfor = NONSTD_TO_PFOR(var->nonstd); in overlayfb_set_par()
856 ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | in overlayfb_set_par()
858 ofb->control[1] = OVLxC2_XPOS(xpos) | OVLxC2_YPOS(ypos); in overlayfb_set_par()
860 if (ofb->id == OVERLAY2) in overlayfb_set_par()
861 ofb->control[1] |= OVL2C2_PFOR(pfor); in overlayfb_set_par()
863 ofb->ops->setup(ofb); in overlayfb_set_par()
864 ofb->ops->enable(ofb); in overlayfb_set_par()
879 sprintf(ofb->fb.fix.id, "overlay%d", id + 1); in init_pxafb_overlay()
881 ofb->fb.fix.type = FB_TYPE_PACKED_PIXELS; in init_pxafb_overlay()
882 ofb->fb.fix.xpanstep = 0; in init_pxafb_overlay()
883 ofb->fb.fix.ypanstep = 1; in init_pxafb_overlay()
885 ofb->fb.var.activate = FB_ACTIVATE_NOW; in init_pxafb_overlay()
886 ofb->fb.var.height = -1; in init_pxafb_overlay()
887 ofb->fb.var.width = -1; in init_pxafb_overlay()
888 ofb->fb.var.vmode = FB_VMODE_NONINTERLACED; in init_pxafb_overlay()
890 ofb->fb.fbops = &overlay_fb_ops; in init_pxafb_overlay()
891 ofb->fb.flags = FBINFO_FLAG_DEFAULT; in init_pxafb_overlay()
892 ofb->fb.node = -1; in init_pxafb_overlay()
893 ofb->fb.pseudo_palette = NULL; in init_pxafb_overlay()
895 ofb->id = id; in init_pxafb_overlay()
896 ofb->ops = &ofb_ops[id]; in init_pxafb_overlay()
897 ofb->usage = 0; in init_pxafb_overlay()
898 ofb->fbi = fbi; in init_pxafb_overlay()
899 init_completion(&ofb->branch_done); in init_pxafb_overlay()
916 ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size), in pxafb_overlay_map_video_memory()
918 if (ofb->video_mem == NULL) in pxafb_overlay_map_video_memory()
919 return -ENOMEM; in pxafb_overlay_map_video_memory()
921 ofb->video_mem_phys = virt_to_phys(ofb->video_mem); in pxafb_overlay_map_video_memory()
922 ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size); in pxafb_overlay_map_video_memory()
924 mutex_lock(&ofb->fb.mm_lock); in pxafb_overlay_map_video_memory()
925 ofb->fb.fix.smem_start = ofb->video_mem_phys; in pxafb_overlay_map_video_memory()
926 ofb->fb.fix.smem_len = pxafb->video_mem_size; in pxafb_overlay_map_video_memory()
927 mutex_unlock(&ofb->fb.mm_lock); in pxafb_overlay_map_video_memory()
929 ofb->fb.screen_base = ofb->video_mem; in pxafb_overlay_map_video_memory()
942 struct pxafb_layer *ofb = &fbi->overlay[i]; in pxafb_overlay_init()
944 ret = register_framebuffer(&ofb->fb); in pxafb_overlay_init()
946 dev_err(fbi->dev, "failed to register overlay %d\n", i); in pxafb_overlay_init()
951 dev_err(fbi->dev, in pxafb_overlay_init()
954 unregister_framebuffer(&ofb->fb); in pxafb_overlay_init()
957 ofb->registered = 1; in pxafb_overlay_init()
974 struct pxafb_layer *ofb = &fbi->overlay[i]; in pxafb_overlay_exit()
975 if (ofb->registered) { in pxafb_overlay_exit()
976 if (ofb->video_mem) in pxafb_overlay_exit()
977 free_pages_exact(ofb->video_mem, in pxafb_overlay_exit()
978 ofb->video_mem_size); in pxafb_overlay_exit()
979 unregister_framebuffer(&ofb->fb); in pxafb_overlay_exit()
994 * -------------
998 * ------------- - 1
1006 * period in picoseconds. Hence PixelClock = 1 / ( pixclock * 10^-12 )
1012 * PCD = (lclk * 10^4 ) * ( pixclock * 10^-12 )
1013 * -------------------------------------- - 1
1016 * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
1024 * (DPC) bit? or perhaps set it based on the various clock in get_pcd()
1026 pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000); in get_pcd()
1044 if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) { in set_hsync_time()
1045 fbi->hsync_time = 0; in set_hsync_time()
1049 htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len); in set_hsync_time()
1051 fbi->hsync_time = htime; in set_hsync_time()
1058 /* If display is blanked/suspended, hsync isn't active */ in pxafb_get_hsync_time()
1059 if (!fbi || (fbi->state != C_ENABLE)) in pxafb_get_hsync_time()
1062 return fbi->hsync_time; in pxafb_get_hsync_time()
1073 return -EINVAL; in setup_frame_dma()
1075 dma_desc = &fbi->dma_buff->dma_desc[dma]; in setup_frame_dma()
1078 dma_desc->fsadr = start; in setup_frame_dma()
1079 dma_desc->fidr = 0; in setup_frame_dma()
1080 dma_desc->ldcmd = size; in setup_frame_dma()
1083 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1084 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1086 pal_desc = &fbi->dma_buff->pal_desc[pal]; in setup_frame_dma()
1089 pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; in setup_frame_dma()
1090 pal_desc->fidr = 0; in setup_frame_dma()
1092 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0) in setup_frame_dma()
1093 pal_desc->ldcmd = fbi->palette_size * sizeof(u16); in setup_frame_dma()
1095 pal_desc->ldcmd = fbi->palette_size * sizeof(u32); in setup_frame_dma()
1097 pal_desc->ldcmd |= LDCMD_PAL; in setup_frame_dma()
1100 pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1101 dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off; in setup_frame_dma()
1102 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; in setup_frame_dma()
1112 struct fb_fix_screeninfo *fix = &fbi->fb.fix; in setup_base_frame()
1113 int nbytes, dma, pal, bpp = var->bits_per_pixel; in setup_base_frame()
1119 nbytes = fix->line_length * var->yres; in setup_base_frame()
1120 offset = fix->line_length * var->yoffset + fbi->video_mem_phys; in setup_base_frame()
1122 if (fbi->lccr0 & LCCR0_SDS) { in setup_base_frame()
1136 dma_desc = &fbi->dma_buff->dma_desc[DMA_CMD]; in setup_smart_dma()
1140 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; in setup_smart_dma()
1141 dma_desc->fsadr = fbi->dma_buff_phys + cmd_buff_off; in setup_smart_dma()
1142 dma_desc->fidr = 0; in setup_smart_dma()
1143 dma_desc->ldcmd = fbi->n_smart_cmds * sizeof(uint16_t); in setup_smart_dma()
1145 fbi->fdadr[DMA_CMD] = dma_desc->fdadr; in setup_smart_dma()
1156 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); in pxafb_smart_flush()
1158 /* 1. make it an even number of commands to align on 32-bit boundary in pxafb_smart_flush()
1163 while (fbi->n_smart_cmds & 1) in pxafb_smart_flush()
1164 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_NOOP; in pxafb_smart_flush()
1166 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_INTERRUPT; in pxafb_smart_flush()
1167 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_WAIT_FOR_VSYNC; in pxafb_smart_flush()
1174 /* stop the processor in case it executed "wait for sync" cmd */ in pxafb_smart_flush()
1177 /* don't send interrupts for fifo underruns on channel 6 */ in pxafb_smart_flush()
1180 lcd_writel(fbi, LCCR1, fbi->reg_lccr1); in pxafb_smart_flush()
1181 lcd_writel(fbi, LCCR2, fbi->reg_lccr2); in pxafb_smart_flush()
1182 lcd_writel(fbi, LCCR3, fbi->reg_lccr3); in pxafb_smart_flush()
1183 lcd_writel(fbi, LCCR4, fbi->reg_lccr4); in pxafb_smart_flush()
1184 lcd_writel(fbi, FDADR0, fbi->fdadr[0]); in pxafb_smart_flush()
1185 lcd_writel(fbi, FDADR6, fbi->fdadr[6]); in pxafb_smart_flush()
1188 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); in pxafb_smart_flush()
1190 if (wait_for_completion_timeout(&fbi->command_done, HZ/2) == 0) { in pxafb_smart_flush()
1192 ret = -ETIMEDOUT; in pxafb_smart_flush()
1198 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); in pxafb_smart_flush()
1200 fbi->n_smart_cmds = 0; in pxafb_smart_flush()
1218 if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8) in pxafb_smart_queue()
1221 fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds; in pxafb_smart_queue()
1236 struct pxafb_mach_info *inf = fbi->inf; in setup_smart_timing()
1237 struct pxafb_mode_info *mode = &inf->modes[0]; in setup_smart_timing()
1238 unsigned long lclk = clk_get_rate(fbi->clk); in setup_smart_timing()
1241 t1 = max(mode->a0csrd_set_hld, mode->a0cswr_set_hld); in setup_smart_timing()
1242 t2 = max(mode->rd_pulse_width, mode->wr_pulse_width); in setup_smart_timing()
1243 t3 = mode->op_hold_time; in setup_smart_timing()
1244 t4 = mode->cmd_inh_time; in setup_smart_timing()
1246 fbi->reg_lccr1 = in setup_smart_timing()
1247 LCCR1_DisWdth(var->xres) | in setup_smart_timing()
1252 fbi->reg_lccr2 = LCCR2_DisHght(var->yres); in setup_smart_timing()
1253 fbi->reg_lccr3 = fbi->lccr3 | LCCR3_PixClkDiv(__smart_timing(t4, lclk)); in setup_smart_timing()
1254 fbi->reg_lccr3 |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HSP : 0; in setup_smart_timing()
1255 fbi->reg_lccr3 |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VSP : 0; in setup_smart_timing()
1258 fbi->reg_cmdcr = 1; in setup_smart_timing()
1264 struct pxafb_mach_info *inf = fbi->inf; in pxafb_smart_thread()
1266 if (!inf->smart_update) { in pxafb_smart_thread()
1269 return -EINVAL; in pxafb_smart_thread()
1280 mutex_lock(&fbi->ctrlr_lock); in pxafb_smart_thread()
1282 if (fbi->state == C_ENABLE) { in pxafb_smart_thread()
1283 inf->smart_update(&fbi->fb); in pxafb_smart_thread()
1284 complete(&fbi->refresh_done); in pxafb_smart_thread()
1287 mutex_unlock(&fbi->ctrlr_lock); in pxafb_smart_thread()
1299 if (!(fbi->lccr0 & LCCR0_LCDT)) in pxafb_smart_init()
1302 fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; in pxafb_smart_init()
1303 fbi->n_smart_cmds = 0; in pxafb_smart_init()
1305 init_completion(&fbi->command_done); in pxafb_smart_init()
1306 init_completion(&fbi->refresh_done); in pxafb_smart_init()
1308 fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi, in pxafb_smart_init()
1310 if (IS_ERR(fbi->smart_thread)) { in pxafb_smart_init()
1312 return PTR_ERR(fbi->smart_thread); in pxafb_smart_init()
1324 unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); in setup_parallel_timing()
1326 fbi->reg_lccr1 = in setup_parallel_timing()
1327 LCCR1_DisWdth(var->xres) + in setup_parallel_timing()
1328 LCCR1_HorSnchWdth(var->hsync_len) + in setup_parallel_timing()
1329 LCCR1_BegLnDel(var->left_margin) + in setup_parallel_timing()
1330 LCCR1_EndLnDel(var->right_margin); in setup_parallel_timing()
1336 lines_per_panel = var->yres; in setup_parallel_timing()
1337 if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) in setup_parallel_timing()
1340 fbi->reg_lccr2 = in setup_parallel_timing()
1342 LCCR2_VrtSnchWdth(var->vsync_len) + in setup_parallel_timing()
1343 LCCR2_BegFrmDel(var->upper_margin) + in setup_parallel_timing()
1344 LCCR2_EndFrmDel(var->lower_margin); in setup_parallel_timing()
1346 fbi->reg_lccr3 = fbi->lccr3 | in setup_parallel_timing()
1347 (var->sync & FB_SYNC_HOR_HIGH_ACT ? in setup_parallel_timing()
1349 (var->sync & FB_SYNC_VERT_HIGH_ACT ? in setup_parallel_timing()
1353 fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd); in setup_parallel_timing()
1360 * Configures LCD Controller based on entries in var parameter.
1372 if (fbi->lccr0 & LCCR0_LCDT) in pxafb_activate_var()
1380 fbi->reg_lccr0 = fbi->lccr0 | in pxafb_activate_var()
1384 fbi->reg_lccr3 |= pxafb_var_to_lccr3(var); in pxafb_activate_var()
1386 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK; in pxafb_activate_var()
1387 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); in pxafb_activate_var()
1394 if ((lcd_readl(fbi, LCCR0) != fbi->reg_lccr0) || in pxafb_activate_var()
1395 (lcd_readl(fbi, LCCR1) != fbi->reg_lccr1) || in pxafb_activate_var()
1396 (lcd_readl(fbi, LCCR2) != fbi->reg_lccr2) || in pxafb_activate_var()
1397 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || in pxafb_activate_var()
1398 (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || in pxafb_activate_var()
1399 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || in pxafb_activate_var()
1400 ((fbi->lccr0 & LCCR0_SDS) && in pxafb_activate_var()
1401 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))) in pxafb_activate_var()
1411 * -- rmk
1413 static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on) in __pxafb_backlight_power() argument
1415 pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff"); in __pxafb_backlight_power()
1417 if (fbi->backlight_power) in __pxafb_backlight_power()
1418 fbi->backlight_power(on); in __pxafb_backlight_power()
1421 static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on) in __pxafb_lcd_power() argument
1423 pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff"); in __pxafb_lcd_power()
1425 if (fbi->lcd_power) in __pxafb_lcd_power()
1426 fbi->lcd_power(on, &fbi->fb.var); in __pxafb_lcd_power()
1428 if (fbi->lcd_supply && fbi->lcd_supply_enabled != on) { in __pxafb_lcd_power()
1431 if (on) in __pxafb_lcd_power()
1432 ret = regulator_enable(fbi->lcd_supply); in __pxafb_lcd_power()
1434 ret = regulator_disable(fbi->lcd_supply); in __pxafb_lcd_power()
1438 on ? "enable" : "disable", ret); in __pxafb_lcd_power()
1440 fbi->lcd_supply_enabled = on; in __pxafb_lcd_power()
1447 pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]); in pxafb_enable_controller()
1448 pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]); in pxafb_enable_controller()
1449 pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0); in pxafb_enable_controller()
1450 pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1); in pxafb_enable_controller()
1451 pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2); in pxafb_enable_controller()
1452 pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3); in pxafb_enable_controller()
1455 if (clk_prepare_enable(fbi->clk)) { in pxafb_enable_controller()
1460 if (fbi->lccr0 & LCCR0_LCDT) in pxafb_enable_controller()
1464 lcd_writel(fbi, LCCR4, fbi->reg_lccr4); in pxafb_enable_controller()
1465 lcd_writel(fbi, LCCR3, fbi->reg_lccr3); in pxafb_enable_controller()
1466 lcd_writel(fbi, LCCR2, fbi->reg_lccr2); in pxafb_enable_controller()
1467 lcd_writel(fbi, LCCR1, fbi->reg_lccr1); in pxafb_enable_controller()
1468 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); in pxafb_enable_controller()
1470 lcd_writel(fbi, FDADR0, fbi->fdadr[0]); in pxafb_enable_controller()
1471 if (fbi->lccr0 & LCCR0_SDS) in pxafb_enable_controller()
1472 lcd_writel(fbi, FDADR1, fbi->fdadr[1]); in pxafb_enable_controller()
1473 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); in pxafb_enable_controller()
1481 if (fbi->lccr0 & LCCR0_LCDT) { in pxafb_disable_controller()
1482 wait_for_completion_timeout(&fbi->refresh_done, in pxafb_disable_controller()
1495 wait_for_completion_timeout(&fbi->disable_done, msecs_to_jiffies(200)); in pxafb_disable_controller()
1498 clk_disable_unprepare(fbi->clk); in pxafb_disable_controller()
1513 complete(&fbi->disable_done); in pxafb_handle_irq()
1518 complete(&fbi->command_done); in pxafb_handle_irq()
1526 complete(&fbi->overlay[0].branch_done); in pxafb_handle_irq()
1529 complete(&fbi->overlay[1].branch_done); in pxafb_handle_irq()
1546 mutex_lock(&fbi->ctrlr_lock); in set_ctrlr_state()
1548 old_state = fbi->state; in set_ctrlr_state()
1563 fbi->state = state; in set_ctrlr_state()
1575 fbi->state = state; in set_ctrlr_state()
1589 fbi->state = C_ENABLE; in set_ctrlr_state()
1597 * Re-enable the controller only if it was already in set_ctrlr_state()
1611 * Re-enable the controller after PM. This is not in set_ctrlr_state()
1612 * perfect - think about the case where we were doing in set_ctrlr_state()
1613 * a clock change, and we suspended half-way through. in set_ctrlr_state()
1622 * turn on the backlight. in set_ctrlr_state()
1625 fbi->state = C_ENABLE; in set_ctrlr_state()
1632 mutex_unlock(&fbi->ctrlr_lock); in set_ctrlr_state()
1643 u_int state = xchg(&fbi->task_state, -1); in pxafb_task()
1654 * TODO: Determine why f->new != 10*get_lclk_frequency_10khz()
1666 if (!(fbi->overlay[0].usage || fbi->overlay[1].usage)) in pxafb_freq_transition()
1672 pcd = get_pcd(fbi, fbi->fb.var.pixclock); in pxafb_freq_transition()
1674 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | in pxafb_freq_transition()
1712 int size = PAGE_ALIGN(fbi->video_mem_size); in pxafb_init_video_memory()
1714 fbi->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); in pxafb_init_video_memory()
1715 if (fbi->video_mem == NULL) in pxafb_init_video_memory()
1716 return -ENOMEM; in pxafb_init_video_memory()
1718 fbi->video_mem_phys = virt_to_phys(fbi->video_mem); in pxafb_init_video_memory()
1719 fbi->video_mem_size = size; in pxafb_init_video_memory()
1721 fbi->fb.fix.smem_start = fbi->video_mem_phys; in pxafb_init_video_memory()
1722 fbi->fb.fix.smem_len = fbi->video_mem_size; in pxafb_init_video_memory()
1723 fbi->fb.screen_base = fbi->video_mem; in pxafb_init_video_memory()
1725 return fbi->video_mem ? 0 : -ENOMEM; in pxafb_init_video_memory()
1731 unsigned int lcd_conn = inf->lcd_conn; in pxafb_decode_mach_info()
1735 fbi->cmap_inverse = inf->cmap_inverse; in pxafb_decode_mach_info()
1736 fbi->cmap_static = inf->cmap_static; in pxafb_decode_mach_info()
1737 fbi->lccr4 = inf->lccr4; in pxafb_decode_mach_info()
1741 fbi->lccr0 = LCCR0_CMS; in pxafb_decode_mach_info()
1744 fbi->lccr0 = LCCR0_CMS | LCCR0_SDS; in pxafb_decode_mach_info()
1747 fbi->lccr0 = 0; in pxafb_decode_mach_info()
1750 fbi->lccr0 = LCCR0_SDS; in pxafb_decode_mach_info()
1753 fbi->lccr0 = LCCR0_PAS; in pxafb_decode_mach_info()
1756 fbi->lccr0 = LCCR0_LCDT | LCCR0_PAS; in pxafb_decode_mach_info()
1760 fbi->lccr0 = inf->lccr0; in pxafb_decode_mach_info()
1761 fbi->lccr3 = inf->lccr3; in pxafb_decode_mach_info()
1766 fbi->lccr0 |= LCCR0_DPD; in pxafb_decode_mach_info()
1768 fbi->lccr0 |= (lcd_conn & LCD_ALTERNATE_MAPPING) ? LCCR0_LDDALT : 0; in pxafb_decode_mach_info()
1770 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff); in pxafb_decode_mach_info()
1771 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0; in pxafb_decode_mach_info()
1772 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0; in pxafb_decode_mach_info()
1775 pxafb_setmode(&fbi->fb.var, &inf->modes[0]); in pxafb_decode_mach_info()
1782 for (i = 0, m = &inf->modes[0]; i < inf->num_modes; i++, m++) in pxafb_decode_mach_info()
1783 fbi->video_mem_size = max_t(size_t, fbi->video_mem_size, in pxafb_decode_mach_info()
1784 m->xres * m->yres * m->bpp / 8); in pxafb_decode_mach_info()
1786 if (inf->video_mem_size > fbi->video_mem_size) in pxafb_decode_mach_info()
1787 fbi->video_mem_size = inf->video_mem_size; in pxafb_decode_mach_info()
1789 if (video_mem_size > fbi->video_mem_size) in pxafb_decode_mach_info()
1790 fbi->video_mem_size = video_mem_size; in pxafb_decode_mach_info()
1803 return ERR_PTR(-ENOMEM); in pxafb_init_fbinfo()
1805 fbi->dev = dev; in pxafb_init_fbinfo()
1806 fbi->inf = inf; in pxafb_init_fbinfo()
1808 fbi->clk = devm_clk_get(dev, NULL); in pxafb_init_fbinfo()
1809 if (IS_ERR(fbi->clk)) in pxafb_init_fbinfo()
1810 return ERR_CAST(fbi->clk); in pxafb_init_fbinfo()
1812 strcpy(fbi->fb.fix.id, PXA_NAME); in pxafb_init_fbinfo()
1814 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; in pxafb_init_fbinfo()
1815 fbi->fb.fix.type_aux = 0; in pxafb_init_fbinfo()
1816 fbi->fb.fix.xpanstep = 0; in pxafb_init_fbinfo()
1817 fbi->fb.fix.ypanstep = 1; in pxafb_init_fbinfo()
1818 fbi->fb.fix.ywrapstep = 0; in pxafb_init_fbinfo()
1819 fbi->fb.fix.accel = FB_ACCEL_NONE; in pxafb_init_fbinfo()
1821 fbi->fb.var.nonstd = 0; in pxafb_init_fbinfo()
1822 fbi->fb.var.activate = FB_ACTIVATE_NOW; in pxafb_init_fbinfo()
1823 fbi->fb.var.height = -1; in pxafb_init_fbinfo()
1824 fbi->fb.var.width = -1; in pxafb_init_fbinfo()
1825 fbi->fb.var.accel_flags = FB_ACCELF_TEXT; in pxafb_init_fbinfo()
1826 fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; in pxafb_init_fbinfo()
1828 fbi->fb.fbops = &pxafb_ops; in pxafb_init_fbinfo()
1829 fbi->fb.flags = FBINFO_DEFAULT; in pxafb_init_fbinfo()
1830 fbi->fb.node = -1; in pxafb_init_fbinfo()
1834 fbi->fb.pseudo_palette = addr; in pxafb_init_fbinfo()
1836 fbi->state = C_STARTUP; in pxafb_init_fbinfo()
1837 fbi->task_state = (u_char)-1; in pxafb_init_fbinfo()
1842 /* place overlay(s) on top of base */ in pxafb_init_fbinfo()
1844 fbi->lccr0 |= LCCR0_OUC; in pxafb_init_fbinfo()
1847 init_waitqueue_head(&fbi->ctrlr_wait); in pxafb_init_fbinfo()
1848 INIT_WORK(&fbi->task, pxafb_task); in pxafb_init_fbinfo()
1849 mutex_init(&fbi->ctrlr_lock); in pxafb_init_fbinfo()
1850 init_completion(&fbi->disable_done); in pxafb_init_fbinfo()
1865 for (i = namelen-1; i >= 0; i--) { in parse_opt_mode()
1867 case '-': in parse_opt_mode()
1895 inf->modes[0].xres = xres; inf->modes[0].yres = yres; in parse_opt_mode()
1904 inf->modes[0].bpp = bpp; in parse_opt_mode()
1909 return -EINVAL; in parse_opt_mode()
1917 struct pxafb_mode_info *mode = &inf->modes[0]; in parse_opt()
1927 mode->pixclock = simple_strtoul(this_opt+9, NULL, 0); in parse_opt()
1928 sprintf(s, "pixclock: %ld\n", mode->pixclock); in parse_opt()
1930 mode->left_margin = simple_strtoul(this_opt+5, NULL, 0); in parse_opt()
1931 sprintf(s, "left: %u\n", mode->left_margin); in parse_opt()
1933 mode->right_margin = simple_strtoul(this_opt+6, NULL, 0); in parse_opt()
1934 sprintf(s, "right: %u\n", mode->right_margin); in parse_opt()
1936 mode->upper_margin = simple_strtoul(this_opt+6, NULL, 0); in parse_opt()
1937 sprintf(s, "upper: %u\n", mode->upper_margin); in parse_opt()
1939 mode->lower_margin = simple_strtoul(this_opt+6, NULL, 0); in parse_opt()
1940 sprintf(s, "lower: %u\n", mode->lower_margin); in parse_opt()
1942 mode->hsync_len = simple_strtoul(this_opt+9, NULL, 0); in parse_opt()
1943 sprintf(s, "hsynclen: %u\n", mode->hsync_len); in parse_opt()
1945 mode->vsync_len = simple_strtoul(this_opt+9, NULL, 0); in parse_opt()
1946 sprintf(s, "vsynclen: %u\n", mode->vsync_len); in parse_opt()
1949 sprintf(s, "hsync: Active Low\n"); in parse_opt()
1950 mode->sync &= ~FB_SYNC_HOR_HIGH_ACT; in parse_opt()
1952 sprintf(s, "hsync: Active High\n"); in parse_opt()
1953 mode->sync |= FB_SYNC_HOR_HIGH_ACT; in parse_opt()
1957 sprintf(s, "vsync: Active Low\n"); in parse_opt()
1958 mode->sync &= ~FB_SYNC_VERT_HIGH_ACT; in parse_opt()
1960 sprintf(s, "vsync: Active High\n"); in parse_opt()
1961 mode->sync |= FB_SYNC_VERT_HIGH_ACT; in parse_opt()
1966 inf->lccr3 &= ~LCCR3_DPC; in parse_opt()
1969 inf->lccr3 |= LCCR3_DPC; in parse_opt()
1973 sprintf(s, "output enable: active low\n"); in parse_opt()
1974 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL; in parse_opt()
1976 sprintf(s, "output enable: active high\n"); in parse_opt()
1977 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH; in parse_opt()
1982 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg; in parse_opt()
1985 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg; in parse_opt()
1988 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color; in parse_opt()
1990 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Mono; in parse_opt()
1991 } else if (!strncmp(this_opt, "active", 6)) { in parse_opt()
1992 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Act; in parse_opt()
1994 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Pas; in parse_opt()
1996 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Sngl; in parse_opt()
1998 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Dual; in parse_opt()
2000 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_4PixMono; in parse_opt()
2002 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_8PixMono; in parse_opt()
2005 return -EINVAL; in parse_opt()
2042 return -ENODEV; in pxafb_setup_options()
2062 /* Check for various illegal bit-combinations. Currently only
2066 if (inf->lcd_conn) in pxafb_check_options()
2069 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) in pxafb_check_options()
2072 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK); in pxafb_check_options()
2073 if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK) in pxafb_check_options()
2076 inf->lccr3 & LCCR3_INVALID_CONFIG_MASK); in pxafb_check_options()
2077 if (inf->lccr0 & LCCR0_DPD && in pxafb_check_options()
2078 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas || in pxafb_check_options()
2079 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || in pxafb_check_options()
2080 (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono)) in pxafb_check_options()
2084 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act && in pxafb_check_options()
2085 (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual) in pxafb_check_options()
2087 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas && in pxafb_check_options()
2088 (inf->modes->upper_margin || inf->modes->lower_margin)) in pxafb_check_options()
2098 "unknown", "mono-stn", "mono-dstn", "color-stn", "color-dstn",
2099 "color-tft", "smart-panel", NULL
2107 int i, ret = -EINVAL; in of_get_pxafb_display()
2110 ret = of_property_read_string(disp, "lcd-type", &s); in of_get_pxafb_display()
2112 s = "color-tft"; in of_get_pxafb_display()
2114 i = match_string(lcd_types, -1, s); in of_get_pxafb_display()
2116 dev_err(dev, "lcd-type %s is unknown\n", s); in of_get_pxafb_display()
2119 info->lcd_conn |= LCD_CONN_TYPE(i); in of_get_pxafb_display()
2120 info->lcd_conn |= LCD_CONN_WIDTH(bus_width); in of_get_pxafb_display()
2124 return -EINVAL; in of_get_pxafb_display()
2126 ret = -ENOMEM; in of_get_pxafb_display()
2127 info->modes = devm_kcalloc(dev, timings->num_timings, in of_get_pxafb_display()
2128 sizeof(info->modes[0]), in of_get_pxafb_display()
2130 if (!info->modes) in of_get_pxafb_display()
2132 info->num_modes = timings->num_timings; in of_get_pxafb_display()
2134 for (i = 0; i < timings->num_timings; i++) { in of_get_pxafb_display()
2142 info->lcd_conn |= LCD_PCLK_EDGE_RISE; in of_get_pxafb_display()
2144 info->lcd_conn |= LCD_PCLK_EDGE_FALL; in of_get_pxafb_display()
2146 info->lcd_conn |= LCD_BIAS_ACTIVE_HIGH; in of_get_pxafb_display()
2148 info->lcd_conn |= LCD_BIAS_ACTIVE_LOW; in of_get_pxafb_display()
2150 info->modes[i].sync |= FB_SYNC_HOR_HIGH_ACT; in of_get_pxafb_display()
2152 info->modes[i].sync |= FB_SYNC_VERT_HIGH_ACT; in of_get_pxafb_display()
2154 info->modes[i].pixclock = 1000000000UL / (vm.pixelclock / 1000); in of_get_pxafb_display()
2155 info->modes[i].xres = vm.hactive; in of_get_pxafb_display()
2156 info->modes[i].yres = vm.vactive; in of_get_pxafb_display()
2157 info->modes[i].hsync_len = vm.hsync_len; in of_get_pxafb_display()
2158 info->modes[i].left_margin = vm.hback_porch; in of_get_pxafb_display()
2159 info->modes[i].right_margin = vm.hfront_porch; in of_get_pxafb_display()
2160 info->modes[i].vsync_len = vm.vsync_len; in of_get_pxafb_display()
2161 info->modes[i].upper_margin = vm.vback_porch; in of_get_pxafb_display()
2162 info->modes[i].lower_margin = vm.vfront_porch; in of_get_pxafb_display()
2178 np = of_graph_get_next_endpoint(dev->of_node, NULL); in of_get_pxafb_mode_info()
2181 return -EINVAL; in of_get_pxafb_mode_info()
2183 ret = of_property_read_u32(np, "bus-width", &bus_width); in of_get_pxafb_mode_info()
2185 dev_err(dev, "no bus-width specified: %d\n", ret); in of_get_pxafb_mode_info()
2194 return -EINVAL; in of_get_pxafb_mode_info()
2202 for (i = 0; i < info->num_modes; i++) in of_get_pxafb_mode_info()
2203 info->modes[i].bpp = bus_width; in of_get_pxafb_mode_info()
2213 if (!dev->of_node) in of_pxafb_of_mach_info()
2217 return ERR_PTR(-ENOMEM); in of_pxafb_of_mach_info()
2223 * On purpose, neither lccrX registers nor video memory size can be in of_pxafb_of_mach_info()
2224 * specified through device-tree, they are considered more a debug hack in of_pxafb_of_mach_info()
2242 dev_dbg(&dev->dev, "pxafb_probe\n"); in pxafb_probe()
2244 ret = -ENOMEM; in pxafb_probe()
2245 pdata = dev_get_platdata(&dev->dev); in pxafb_probe()
2246 inf = devm_kmalloc(&dev->dev, sizeof(*inf), GFP_KERNEL); in pxafb_probe()
2252 inf->modes = in pxafb_probe()
2253 devm_kmalloc_array(&dev->dev, pdata->num_modes, in pxafb_probe()
2254 sizeof(inf->modes[0]), GFP_KERNEL); in pxafb_probe()
2255 if (!inf->modes) in pxafb_probe()
2257 for (i = 0; i < inf->num_modes; i++) in pxafb_probe()
2258 inf->modes[i] = pdata->modes[i]; in pxafb_probe()
2260 inf = of_pxafb_of_mach_info(&dev->dev); in pxafb_probe()
2266 ret = pxafb_parse_options(&dev->dev, g_options, inf); in pxafb_probe()
2270 pxafb_check_options(&dev->dev, inf); in pxafb_probe()
2272 dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n", in pxafb_probe()
2273 inf->modes->xres, in pxafb_probe()
2274 inf->modes->yres, in pxafb_probe()
2275 inf->modes->bpp); in pxafb_probe()
2276 if (inf->modes->xres == 0 || in pxafb_probe()
2277 inf->modes->yres == 0 || in pxafb_probe()
2278 inf->modes->bpp == 0) { in pxafb_probe()
2279 dev_err(&dev->dev, "Invalid resolution or bit depth\n"); in pxafb_probe()
2280 ret = -EINVAL; in pxafb_probe()
2284 fbi = pxafb_init_fbinfo(&dev->dev, inf); in pxafb_probe()
2286 dev_err(&dev->dev, "Failed to initialize framebuffer device\n"); in pxafb_probe()
2291 if (cpu_is_pxa3xx() && inf->acceleration_enabled) in pxafb_probe()
2292 fbi->fb.fix.accel = FB_ACCEL_PXA3XX; in pxafb_probe()
2294 fbi->backlight_power = inf->pxafb_backlight_power; in pxafb_probe()
2295 fbi->lcd_power = inf->pxafb_lcd_power; in pxafb_probe()
2297 fbi->lcd_supply = devm_regulator_get_optional(&dev->dev, "lcd"); in pxafb_probe()
2298 if (IS_ERR(fbi->lcd_supply)) { in pxafb_probe()
2299 if (PTR_ERR(fbi->lcd_supply) == -EPROBE_DEFER) in pxafb_probe()
2300 return -EPROBE_DEFER; in pxafb_probe()
2302 fbi->lcd_supply = NULL; in pxafb_probe()
2305 fbi->mmio_base = devm_platform_ioremap_resource(dev, 0); in pxafb_probe()
2306 if (IS_ERR(fbi->mmio_base)) { in pxafb_probe()
2307 dev_err(&dev->dev, "failed to get I/O memory\n"); in pxafb_probe()
2308 ret = PTR_ERR(fbi->mmio_base); in pxafb_probe()
2312 fbi->dma_buff_size = PAGE_ALIGN(sizeof(struct pxafb_dma_buff)); in pxafb_probe()
2313 fbi->dma_buff = dma_alloc_coherent(fbi->dev, fbi->dma_buff_size, in pxafb_probe()
2314 &fbi->dma_buff_phys, GFP_KERNEL); in pxafb_probe()
2315 if (fbi->dma_buff == NULL) { in pxafb_probe()
2316 dev_err(&dev->dev, "failed to allocate memory for DMA\n"); in pxafb_probe()
2317 ret = -ENOMEM; in pxafb_probe()
2323 dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret); in pxafb_probe()
2324 ret = -ENOMEM; in pxafb_probe()
2330 dev_err(&dev->dev, "no IRQ defined\n"); in pxafb_probe()
2331 ret = -ENODEV; in pxafb_probe()
2335 ret = devm_request_irq(&dev->dev, irq, pxafb_handle_irq, 0, "LCD", fbi); in pxafb_probe()
2337 dev_err(&dev->dev, "request_irq failed: %d\n", ret); in pxafb_probe()
2338 ret = -EBUSY; in pxafb_probe()
2344 dev_err(&dev->dev, "failed to initialize smartpanel\n"); in pxafb_probe()
2352 ret = pxafb_check_var(&fbi->fb.var, &fbi->fb); in pxafb_probe()
2354 dev_err(&dev->dev, "failed to get suitable mode\n"); in pxafb_probe()
2358 ret = pxafb_set_par(&fbi->fb); in pxafb_probe()
2360 dev_err(&dev->dev, "Failed to set parameters\n"); in pxafb_probe()
2366 ret = register_framebuffer(&fbi->fb); in pxafb_probe()
2368 dev_err(&dev->dev, in pxafb_probe()
2376 fbi->freq_transition.notifier_call = pxafb_freq_transition; in pxafb_probe()
2377 cpufreq_register_notifier(&fbi->freq_transition, in pxafb_probe()
2389 if (fbi->fb.cmap.len) in pxafb_probe()
2390 fb_dealloc_cmap(&fbi->fb.cmap); in pxafb_probe()
2392 free_pages_exact(fbi->video_mem, fbi->video_mem_size); in pxafb_probe()
2394 dma_free_coherent(&dev->dev, fbi->dma_buff_size, in pxafb_probe()
2395 fbi->dma_buff, fbi->dma_buff_phys); in pxafb_probe()
2408 info = &fbi->fb; in pxafb_remove()
2415 if (fbi->fb.cmap.len) in pxafb_remove()
2416 fb_dealloc_cmap(&fbi->fb.cmap); in pxafb_remove()
2418 free_pages_exact(fbi->video_mem, fbi->video_mem_size); in pxafb_remove()
2420 dma_free_coherent(&dev->dev, fbi->dma_buff_size, fbi->dma_buff, in pxafb_remove()
2421 fbi->dma_buff_phys); in pxafb_remove()
2427 { .compatible = "marvell,pxa270-lcdc", },
2428 { .compatible = "marvell,pxa300-lcdc", },
2429 { .compatible = "marvell,pxa2xx-lcdc", },
2438 .name = "pxa2xx-fb",
2449 return -EINVAL; in pxafb_init()