Lines Matching +full:lcdc +full:- +full:supply
5 * Copyright (C) 2004 Jean-Frederic Clere.
21 * linux-arm-kernel@lists.arm.linux.org.uk
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);
104 __raw_writel(val, fbi->mmio_base + off);
122 if (fbi->task_state == C_ENABLE && state == C_REENABLE)
123 state = (u_int) -1;
124 if (fbi->task_state == C_DISABLE && state == C_ENABLE)
127 if (state != (u_int)-1) {
128 fbi->task_state = state;
129 schedule_work(&fbi->task);
137 chan >>= 16 - bf->length;
138 return chan << bf->offset;
148 if (regno >= fbi->palette_size)
151 if (fbi->fb.var.grayscale) {
152 fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff);
156 switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) {
161 fbi->palette_cpu[regno] = val;
167 ((u32 *)(fbi->palette_cpu))[regno] = val;
173 ((u32 *)(fbi->palette_cpu))[regno] = val;
179 ((u32 *)(fbi->palette_cpu))[regno] = val;
200 if (fbi->cmap_inverse) {
201 red = 0xffff - red;
202 green = 0xffff - green;
203 blue = 0xffff - blue;
210 if (fbi->fb.var.grayscale)
214 switch (fbi->fb.fix.visual) {
217 * 16-bit True Colour. We encode the RGB value
221 u32 *pal = fbi->fb.pseudo_palette;
223 val = chan_to_field(red, &fbi->fb.var.red);
224 val |= chan_to_field(green, &fbi->fb.var.green);
225 val |= chan_to_field(blue, &fbi->fb.var.blue);
244 return var->red.length + var->green.length +
245 var->blue.length + var->transp.length;
248 /* calculate 4-bit BPP value for LCCR3 and OVLxC1 */
251 int bpp = -EINVAL;
253 switch (var->bits_per_pixel) {
261 case 18: bpp = 6; break; /* 18-bits/pixel packed */
262 case 19: bpp = 8; break; /* 19-bits/pixel packed */
268 case 18: bpp = 5; break; /* 18-bits/pixel unpacked */
269 case 19: bpp = 7; break; /* 19-bits/pixel unpacked */
299 case 16: lccr3 |= var->transp.length ? LCCR3_PDFOR_3 : 0; break;
301 case 24: lccr3 |= var->transp.length ? LCCR3_PDFOR_2 : LCCR3_PDFOR_3;
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;
326 if (var->bits_per_pixel < 16) {
328 var->red.offset = 0; var->red.length = 8;
329 var->green.offset = 0; var->green.length = 8;
330 var->blue.offset = 0; var->blue.length = 8;
331 var->transp.offset = 0; var->transp.length = 8;
335 case 16: var->transp.length ?
340 case 24: var->transp.length ?
360 return var->pixclock * 8 * 16 / var->bits_per_pixel;
372 struct pxafb_mode_info *modelist = mach->modes;
376 for (i = 0; i < mach->num_modes; i++) {
377 if (modelist[i].xres >= var->xres &&
378 modelist[i].yres >= var->yres &&
381 modelist[i].bpp >= var->bits_per_pixel) {
394 var->xres = mode->xres;
395 var->yres = mode->yres;
396 var->bits_per_pixel = mode->bpp;
397 var->pixclock = mode->pixclock;
398 var->hsync_len = mode->hsync_len;
399 var->left_margin = mode->left_margin;
400 var->right_margin = mode->right_margin;
401 var->vsync_len = mode->vsync_len;
402 var->upper_margin = mode->upper_margin;
403 var->lower_margin = mode->lower_margin;
404 var->sync = mode->sync;
405 var->grayscale = mode->cmap_greyscale;
406 var->transp.length = mode->transparency;
409 pxafb_set_pixfmt(var, mode->depth);
417 var->xres = max_t(int, var->xres, MIN_XRES);
418 var->yres = max_t(int, var->yres, MIN_YRES);
420 if (!(fbi->lccr0 & LCCR0_LCDT)) {
421 clamp_val(var->hsync_len, 1, 64);
422 clamp_val(var->vsync_len, 1, 64);
423 clamp_val(var->left_margin, 1, 255);
424 clamp_val(var->right_margin, 1, 255);
425 clamp_val(var->upper_margin, 1, 255);
426 clamp_val(var->lower_margin, 1, 255);
430 line_length = var->xres * var->bits_per_pixel / 8;
432 var->xres = line_length * 8 / var->bits_per_pixel;
435 var->xres_virtual = var->xres;
437 if (var->accel_flags & FB_ACCELF_TEXT)
438 var->yres_virtual = fbi->fb.fix.smem_len / line_length;
440 var->yres_virtual = max(var->yres_virtual, var->yres);
443 if (var->xres > MAX_XRES || var->yres > MAX_YRES)
444 return -EINVAL;
446 if (var->yres > var->yres_virtual)
447 return -EINVAL;
455 * if it's too big, return -EINVAL.
464 struct pxafb_mach_info *inf = fbi->inf;
467 if (inf->fixed_modes) {
472 return -EINVAL;
502 struct fb_var_screeninfo *var = &info->var;
504 if (var->bits_per_pixel >= 16)
505 fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
506 else if (!fbi->cmap_static)
507 fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
514 fbi->fb.fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
517 fbi->fb.fix.line_length = var->xres_virtual *
518 var->bits_per_pixel / 8;
519 if (var->bits_per_pixel >= 16)
520 fbi->palette_size = 0;
522 fbi->palette_size = var->bits_per_pixel == 1 ?
523 4 : 1 << var->bits_per_pixel;
525 fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0];
527 if (fbi->fb.var.bits_per_pixel >= 16)
528 fb_dealloc_cmap(&fbi->fb.cmap);
530 fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
544 if (fbi->state != C_ENABLE)
550 memcpy(&newvar, &fbi->fb.var, sizeof(newvar));
551 newvar.xoffset = var->xoffset;
552 newvar.yoffset = var->yoffset;
554 newvar.vmode |= var->vmode & FB_VMODE_YWRAP;
558 if (fbi->lccr0 & LCCR0_SDS)
559 lcd_writel(fbi, FBR1, fbi->fdadr[dma + 1] | 0x1);
561 lcd_writel(fbi, FBR0, fbi->fdadr[dma] | 0x1);
581 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
582 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
583 for (i = 0; i < fbi->palette_size; i++)
592 if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
593 fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
594 fb_set_cmap(&fbi->fb.cmap, info);
613 int size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual;
614 unsigned long start = ofb->video_mem_phys;
615 setup_frame_dma(ofb->fbi, DMA_OV1, PAL_NONE, start, size);
623 int enabled = lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN;
624 uint32_t fdadr1 = ofb->fbi->fdadr[DMA_OV1] | (enabled ? 0x1 : 0);
626 lcd_writel(ofb->fbi, enabled ? FBR1 : FDADR1, fdadr1);
627 lcd_writel(ofb->fbi, OVL1C2, ofb->control[1]);
628 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] | OVLxC1_OEN);
635 if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
638 lccr5 = lcd_readl(ofb->fbi, LCCR5);
640 lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
642 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
643 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));
644 lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
646 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
649 lcd_writel(ofb->fbi, LCCR5, lccr5);
654 int size, div = 1, pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd);
655 unsigned long start[3] = { ofb->video_mem_phys, 0, 0 };
658 size = ofb->fb.fix.line_length * ofb->fb.var.yres_virtual;
659 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size);
661 size = ofb->fb.var.xres_virtual * ofb->fb.var.yres_virtual;
669 setup_frame_dma(ofb->fbi, DMA_OV2_Y, -1, start[0], size);
670 setup_frame_dma(ofb->fbi, DMA_OV2_Cb, -1, start[1], size / div);
671 setup_frame_dma(ofb->fbi, DMA_OV2_Cr, -1, start[2], size / div);
677 int pfor = NONSTD_TO_PFOR(ofb->fb.var.nonstd);
678 int enabled = lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN;
679 uint32_t fdadr2 = ofb->fbi->fdadr[DMA_OV2_Y] | (enabled ? 0x1 : 0);
680 uint32_t fdadr3 = ofb->fbi->fdadr[DMA_OV2_Cb] | (enabled ? 0x1 : 0);
681 uint32_t fdadr4 = ofb->fbi->fdadr[DMA_OV2_Cr] | (enabled ? 0x1 : 0);
684 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2);
686 lcd_writel(ofb->fbi, enabled ? FBR2 : FDADR2, fdadr2);
687 lcd_writel(ofb->fbi, enabled ? FBR3 : FDADR3, fdadr3);
688 lcd_writel(ofb->fbi, enabled ? FBR4 : FDADR4, fdadr4);
690 lcd_writel(ofb->fbi, OVL2C2, ofb->control[1]);
691 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] | OVLxC1_OEN);
698 if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
701 lccr5 = lcd_readl(ofb->fbi, LCCR5);
703 lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
705 lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
706 lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));
707 lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);
708 lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);
709 lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
711 if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
734 return -ENODEV;
736 if (ofb->usage++ == 0) {
739 fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
750 if (ofb->usage == 1) {
751 ofb->ops->disable(ofb);
752 ofb->fb.var.height = -1;
753 ofb->fb.var.width = -1;
754 ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
755 ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
757 ofb->usage--;
766 struct fb_var_screeninfo *base_var = &ofb->fbi->fb.var;
769 xpos = NONSTD_TO_XPOS(var->nonstd);
770 ypos = NONSTD_TO_YPOS(var->nonstd);
771 pfor = NONSTD_TO_PFOR(var->nonstd);
775 return -EINVAL;
778 if (ofb->id == OVERLAY1 && pfor != 0)
779 return -EINVAL;
786 return -EINVAL;
795 return -EINVAL;
798 /* each line must start at a 32-bit word boundary */
800 return -EINVAL;
802 /* xres must align on 32-bit word boundary */
803 var->xres = roundup(var->xres * bpp, 32) / bpp;
805 if ((xpos + var->xres > base_var->xres) ||
806 (ypos + var->yres > base_var->yres))
807 return -EINVAL;
809 var->xres_virtual = var->xres;
810 var->yres_virtual = max(var->yres, var->yres_virtual);
816 struct fb_var_screeninfo *var = &ofb->fb.var;
817 int pfor = NONSTD_TO_PFOR(var->nonstd);
821 case OVERLAY_FORMAT_RGB: bpp = var->bits_per_pixel; break;
828 ofb->fb.fix.line_length = var->xres_virtual * bpp / 8;
830 size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
832 if (ofb->video_mem) {
833 if (ofb->video_mem_size >= size)
836 return -EINVAL;
842 struct fb_var_screeninfo *var = &info->var;
850 xpos = NONSTD_TO_XPOS(var->nonstd);
851 ypos = NONSTD_TO_YPOS(var->nonstd);
852 pfor = NONSTD_TO_PFOR(var->nonstd);
854 ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
856 ofb->control[1] = OVLxC2_XPOS(xpos) | OVLxC2_YPOS(ypos);
858 if (ofb->id == OVERLAY2)
859 ofb->control[1] |= OVL2C2_PFOR(pfor);
861 ofb->ops->setup(ofb);
862 ofb->ops->enable(ofb);
877 sprintf(ofb->fb.fix.id, "overlay%d", id + 1);
879 ofb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
880 ofb->fb.fix.xpanstep = 0;
881 ofb->fb.fix.ypanstep = 1;
883 ofb->fb.var.activate = FB_ACTIVATE_NOW;
884 ofb->fb.var.height = -1;
885 ofb->fb.var.width = -1;
886 ofb->fb.var.vmode = FB_VMODE_NONINTERLACED;
888 ofb->fb.fbops = &overlay_fb_ops;
889 ofb->fb.node = -1;
890 ofb->fb.pseudo_palette = NULL;
892 ofb->id = id;
893 ofb->ops = &ofb_ops[id];
894 ofb->usage = 0;
895 ofb->fbi = fbi;
896 init_completion(&ofb->branch_done);
913 ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size),
915 if (ofb->video_mem == NULL)
916 return -ENOMEM;
918 ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
919 ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size);
921 mutex_lock(&ofb->fb.mm_lock);
922 ofb->fb.fix.smem_start = ofb->video_mem_phys;
923 ofb->fb.fix.smem_len = pxafb->video_mem_size;
924 mutex_unlock(&ofb->fb.mm_lock);
926 ofb->fb.screen_base = ofb->video_mem;
939 struct pxafb_layer *ofb = &fbi->overlay[i];
941 ret = register_framebuffer(&ofb->fb);
943 dev_err(fbi->dev, "failed to register overlay %d\n", i);
948 dev_err(fbi->dev,
951 unregister_framebuffer(&ofb->fb);
954 ofb->registered = 1;
971 struct pxafb_layer *ofb = &fbi->overlay[i];
972 if (ofb->registered) {
973 if (ofb->video_mem)
974 free_pages_exact(ofb->video_mem,
975 ofb->video_mem_size);
976 unregister_framebuffer(&ofb->fb);
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.
1023 pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000);
1040 if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
1041 fbi->hsync_time = 0;
1045 htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len);
1047 fbi->hsync_time = htime;
1057 return -EINVAL;
1059 dma_desc = &fbi->dma_buff->dma_desc[dma];
1062 dma_desc->fsadr = start;
1063 dma_desc->fidr = 0;
1064 dma_desc->ldcmd = size;
1067 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
1068 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
1070 pal_desc = &fbi->dma_buff->pal_desc[pal];
1073 pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE;
1074 pal_desc->fidr = 0;
1076 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
1077 pal_desc->ldcmd = fbi->palette_size * sizeof(u16);
1079 pal_desc->ldcmd = fbi->palette_size * sizeof(u32);
1081 pal_desc->ldcmd |= LDCMD_PAL;
1084 pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
1085 dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off;
1086 fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
1096 struct fb_fix_screeninfo *fix = &fbi->fb.fix;
1097 int nbytes, dma, pal, bpp = var->bits_per_pixel;
1103 nbytes = fix->line_length * var->yres;
1104 offset = fix->line_length * var->yoffset + fbi->video_mem_phys;
1106 if (fbi->lccr0 & LCCR0_SDS) {
1120 dma_desc = &fbi->dma_buff->dma_desc[DMA_CMD];
1124 dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
1125 dma_desc->fsadr = fbi->dma_buff_phys + cmd_buff_off;
1126 dma_desc->fidr = 0;
1127 dma_desc->ldcmd = fbi->n_smart_cmds * sizeof(uint16_t);
1129 fbi->fdadr[DMA_CMD] = dma_desc->fdadr;
1140 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1142 /* 1. make it an even number of commands to align on 32-bit boundary
1147 while (fbi->n_smart_cmds & 1)
1148 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_NOOP;
1150 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_INTERRUPT;
1151 fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_WAIT_FOR_VSYNC;
1164 lcd_writel(fbi, LCCR1, fbi->reg_lccr1);
1165 lcd_writel(fbi, LCCR2, fbi->reg_lccr2);
1166 lcd_writel(fbi, LCCR3, fbi->reg_lccr3);
1167 lcd_writel(fbi, LCCR4, fbi->reg_lccr4);
1168 lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
1169 lcd_writel(fbi, FDADR6, fbi->fdadr[6]);
1172 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
1174 if (wait_for_completion_timeout(&fbi->command_done, HZ/2) == 0) {
1176 ret = -ETIMEDOUT;
1182 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1184 fbi->n_smart_cmds = 0;
1202 if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8)
1205 fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds;
1220 struct pxafb_mach_info *inf = fbi->inf;
1221 struct pxafb_mode_info *mode = &inf->modes[0];
1222 unsigned long lclk = clk_get_rate(fbi->clk);
1225 t1 = max(mode->a0csrd_set_hld, mode->a0cswr_set_hld);
1226 t2 = max(mode->rd_pulse_width, mode->wr_pulse_width);
1227 t3 = mode->op_hold_time;
1228 t4 = mode->cmd_inh_time;
1230 fbi->reg_lccr1 =
1231 LCCR1_DisWdth(var->xres) |
1236 fbi->reg_lccr2 = LCCR2_DisHght(var->yres);
1237 fbi->reg_lccr3 = fbi->lccr3 | LCCR3_PixClkDiv(__smart_timing(t4, lclk));
1238 fbi->reg_lccr3 |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HSP : 0;
1239 fbi->reg_lccr3 |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VSP : 0;
1242 fbi->reg_cmdcr = 1;
1248 struct pxafb_mach_info *inf = fbi->inf;
1250 if (!inf->smart_update) {
1253 return -EINVAL;
1264 mutex_lock(&fbi->ctrlr_lock);
1266 if (fbi->state == C_ENABLE) {
1267 inf->smart_update(&fbi->fb);
1268 complete(&fbi->refresh_done);
1271 mutex_unlock(&fbi->ctrlr_lock);
1283 if (!(fbi->lccr0 & LCCR0_LCDT))
1286 fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff;
1287 fbi->n_smart_cmds = 0;
1289 init_completion(&fbi->command_done);
1290 init_completion(&fbi->refresh_done);
1292 fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi,
1294 if (IS_ERR(fbi->smart_thread)) {
1296 return PTR_ERR(fbi->smart_thread);
1308 unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
1310 fbi->reg_lccr1 =
1311 LCCR1_DisWdth(var->xres) +
1312 LCCR1_HorSnchWdth(var->hsync_len) +
1313 LCCR1_BegLnDel(var->left_margin) +
1314 LCCR1_EndLnDel(var->right_margin);
1320 lines_per_panel = var->yres;
1321 if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
1324 fbi->reg_lccr2 =
1326 LCCR2_VrtSnchWdth(var->vsync_len) +
1327 LCCR2_BegFrmDel(var->upper_margin) +
1328 LCCR2_EndFrmDel(var->lower_margin);
1330 fbi->reg_lccr3 = fbi->lccr3 |
1331 (var->sync & FB_SYNC_HOR_HIGH_ACT ?
1333 (var->sync & FB_SYNC_VERT_HIGH_ACT ?
1337 fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd);
1356 if (fbi->lccr0 & LCCR0_LCDT)
1364 fbi->reg_lccr0 = fbi->lccr0 |
1368 fbi->reg_lccr3 |= pxafb_var_to_lccr3(var);
1370 fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
1371 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
1378 if ((lcd_readl(fbi, LCCR0) != fbi->reg_lccr0) ||
1379 (lcd_readl(fbi, LCCR1) != fbi->reg_lccr1) ||
1380 (lcd_readl(fbi, LCCR2) != fbi->reg_lccr2) ||
1381 (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
1382 (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
1383 (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
1384 ((fbi->lccr0 & LCCR0_SDS) &&
1385 (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
1395 * -- rmk
1401 if (fbi->backlight_power)
1402 fbi->backlight_power(on);
1409 if (fbi->lcd_power)
1410 fbi->lcd_power(on, &fbi->fb.var);
1412 if (fbi->lcd_supply && fbi->lcd_supply_enabled != on) {
1416 ret = regulator_enable(fbi->lcd_supply);
1418 ret = regulator_disable(fbi->lcd_supply);
1421 pr_warn("Unable to %s LCD supply regulator: %d\n",
1424 fbi->lcd_supply_enabled = on;
1431 pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]);
1432 pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]);
1433 pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0);
1434 pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1);
1435 pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
1436 pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
1439 if (clk_prepare_enable(fbi->clk)) {
1444 if (fbi->lccr0 & LCCR0_LCDT)
1448 lcd_writel(fbi, LCCR4, fbi->reg_lccr4);
1449 lcd_writel(fbi, LCCR3, fbi->reg_lccr3);
1450 lcd_writel(fbi, LCCR2, fbi->reg_lccr2);
1451 lcd_writel(fbi, LCCR1, fbi->reg_lccr1);
1452 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1454 lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
1455 if (fbi->lccr0 & LCCR0_SDS)
1456 lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
1457 lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
1465 if (fbi->lccr0 & LCCR0_LCDT) {
1466 wait_for_completion_timeout(&fbi->refresh_done,
1479 wait_for_completion_timeout(&fbi->disable_done, msecs_to_jiffies(200));
1482 clk_disable_unprepare(fbi->clk);
1497 complete(&fbi->disable_done);
1502 complete(&fbi->command_done);
1510 complete(&fbi->overlay[0].branch_done);
1513 complete(&fbi->overlay[1].branch_done);
1530 mutex_lock(&fbi->ctrlr_lock);
1532 old_state = fbi->state;
1547 fbi->state = state;
1559 fbi->state = state;
1573 fbi->state = C_ENABLE;
1581 * Re-enable the controller only if it was already
1595 * Re-enable the controller after PM. This is not
1596 * perfect - think about the case where we were doing
1597 * a clock change, and we suspended half-way through.
1609 fbi->state = C_ENABLE;
1616 mutex_unlock(&fbi->ctrlr_lock);
1627 u_int state = xchg(&fbi->task_state, -1);
1638 * TODO: Determine why f->new != 10*get_lclk_frequency_10khz()
1650 if (!(fbi->overlay[0].usage || fbi->overlay[1].usage))
1656 pcd = get_pcd(fbi, fbi->fb.var.pixclock);
1658 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) |
1696 int size = PAGE_ALIGN(fbi->video_mem_size);
1698 fbi->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
1699 if (fbi->video_mem == NULL)
1700 return -ENOMEM;
1702 fbi->video_mem_phys = virt_to_phys(fbi->video_mem);
1703 fbi->video_mem_size = size;
1705 fbi->fb.fix.smem_start = fbi->video_mem_phys;
1706 fbi->fb.fix.smem_len = fbi->video_mem_size;
1707 fbi->fb.screen_base = fbi->video_mem;
1709 return fbi->video_mem ? 0 : -ENOMEM;
1715 unsigned int lcd_conn = inf->lcd_conn;
1719 fbi->cmap_inverse = inf->cmap_inverse;
1720 fbi->cmap_static = inf->cmap_static;
1721 fbi->lccr4 = inf->lccr4;
1725 fbi->lccr0 = LCCR0_CMS;
1728 fbi->lccr0 = LCCR0_CMS | LCCR0_SDS;
1731 fbi->lccr0 = 0;
1734 fbi->lccr0 = LCCR0_SDS;
1737 fbi->lccr0 = LCCR0_PAS;
1740 fbi->lccr0 = LCCR0_LCDT | LCCR0_PAS;
1744 fbi->lccr0 = inf->lccr0;
1745 fbi->lccr3 = inf->lccr3;
1750 fbi->lccr0 |= LCCR0_DPD;
1752 fbi->lccr0 |= (lcd_conn & LCD_ALTERNATE_MAPPING) ? LCCR0_LDDALT : 0;
1754 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff);
1755 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
1756 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0;
1759 pxafb_setmode(&fbi->fb.var, &inf->modes[0]);
1766 for (i = 0, m = &inf->modes[0]; i < inf->num_modes; i++, m++)
1767 fbi->video_mem_size = max_t(size_t, fbi->video_mem_size,
1768 m->xres * m->yres * m->bpp / 8);
1770 if (inf->video_mem_size > fbi->video_mem_size)
1771 fbi->video_mem_size = inf->video_mem_size;
1773 if (video_mem_size > fbi->video_mem_size)
1774 fbi->video_mem_size = video_mem_size;
1787 return ERR_PTR(-ENOMEM);
1789 fbi->dev = dev;
1790 fbi->inf = inf;
1792 fbi->clk = devm_clk_get(dev, NULL);
1793 if (IS_ERR(fbi->clk))
1794 return ERR_CAST(fbi->clk);
1796 strcpy(fbi->fb.fix.id, PXA_NAME);
1798 fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
1799 fbi->fb.fix.type_aux = 0;
1800 fbi->fb.fix.xpanstep = 0;
1801 fbi->fb.fix.ypanstep = 1;
1802 fbi->fb.fix.ywrapstep = 0;
1803 fbi->fb.fix.accel = FB_ACCEL_NONE;
1805 fbi->fb.var.nonstd = 0;
1806 fbi->fb.var.activate = FB_ACTIVATE_NOW;
1807 fbi->fb.var.height = -1;
1808 fbi->fb.var.width = -1;
1809 fbi->fb.var.accel_flags = FB_ACCELF_TEXT;
1810 fbi->fb.var.vmode = FB_VMODE_NONINTERLACED;
1812 fbi->fb.fbops = &pxafb_ops;
1813 fbi->fb.node = -1;
1817 fbi->fb.pseudo_palette = addr;
1819 fbi->state = C_STARTUP;
1820 fbi->task_state = (u_char)-1;
1827 fbi->lccr0 |= LCCR0_OUC;
1830 init_waitqueue_head(&fbi->ctrlr_wait);
1831 INIT_WORK(&fbi->task, pxafb_task);
1832 mutex_init(&fbi->ctrlr_lock);
1833 init_completion(&fbi->disable_done);
1848 for (i = namelen-1; i >= 0; i--) {
1850 case '-':
1878 inf->modes[0].xres = xres; inf->modes[0].yres = yres;
1887 inf->modes[0].bpp = bpp;
1892 return -EINVAL;
1900 struct pxafb_mode_info *mode = &inf->modes[0];
1910 mode->pixclock = simple_strtoul(this_opt+9, NULL, 0);
1911 sprintf(s, "pixclock: %ld\n", mode->pixclock);
1913 mode->left_margin = simple_strtoul(this_opt+5, NULL, 0);
1914 sprintf(s, "left: %u\n", mode->left_margin);
1916 mode->right_margin = simple_strtoul(this_opt+6, NULL, 0);
1917 sprintf(s, "right: %u\n", mode->right_margin);
1919 mode->upper_margin = simple_strtoul(this_opt+6, NULL, 0);
1920 sprintf(s, "upper: %u\n", mode->upper_margin);
1922 mode->lower_margin = simple_strtoul(this_opt+6, NULL, 0);
1923 sprintf(s, "lower: %u\n", mode->lower_margin);
1925 mode->hsync_len = simple_strtoul(this_opt+9, NULL, 0);
1926 sprintf(s, "hsynclen: %u\n", mode->hsync_len);
1928 mode->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
1929 sprintf(s, "vsynclen: %u\n", mode->vsync_len);
1933 mode->sync &= ~FB_SYNC_HOR_HIGH_ACT;
1936 mode->sync |= FB_SYNC_HOR_HIGH_ACT;
1941 mode->sync &= ~FB_SYNC_VERT_HIGH_ACT;
1944 mode->sync |= FB_SYNC_VERT_HIGH_ACT;
1949 inf->lccr3 &= ~LCCR3_DPC;
1952 inf->lccr3 |= LCCR3_DPC;
1957 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
1960 inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
1965 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
1968 inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
1971 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
1973 inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Mono;
1975 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Act;
1977 inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Pas;
1979 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Sngl;
1981 inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Dual;
1983 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_4PixMono;
1985 inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_8PixMono;
1988 return -EINVAL;
2025 return -ENODEV;
2045 /* Check for various illegal bit-combinations. Currently only
2049 if (inf->lcd_conn)
2052 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
2055 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
2056 if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
2059 inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
2060 if (inf->lccr0 & LCCR0_DPD &&
2061 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
2062 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
2063 (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
2067 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
2068 (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
2070 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
2071 (inf->modes->upper_margin || inf->modes->lower_margin))
2081 "unknown", "mono-stn", "mono-dstn", "color-stn", "color-dstn",
2082 "color-tft", "smart-panel", NULL
2090 int i, ret = -EINVAL;
2093 ret = of_property_read_string(disp, "lcd-type", &s);
2095 s = "color-tft";
2097 i = match_string(lcd_types, -1, s);
2099 dev_err(dev, "lcd-type %s is unknown\n", s);
2102 info->lcd_conn |= LCD_CONN_TYPE(i);
2103 info->lcd_conn |= LCD_CONN_WIDTH(bus_width);
2107 return -EINVAL;
2109 ret = -ENOMEM;
2110 info->modes = devm_kcalloc(dev, timings->num_timings,
2111 sizeof(info->modes[0]),
2113 if (!info->modes)
2115 info->num_modes = timings->num_timings;
2117 for (i = 0; i < timings->num_timings; i++) {
2125 info->lcd_conn |= LCD_PCLK_EDGE_RISE;
2127 info->lcd_conn |= LCD_PCLK_EDGE_FALL;
2129 info->lcd_conn |= LCD_BIAS_ACTIVE_HIGH;
2131 info->lcd_conn |= LCD_BIAS_ACTIVE_LOW;
2133 info->modes[i].sync |= FB_SYNC_HOR_HIGH_ACT;
2135 info->modes[i].sync |= FB_SYNC_VERT_HIGH_ACT;
2137 info->modes[i].pixclock = 1000000000UL / (vm.pixelclock / 1000);
2138 info->modes[i].xres = vm.hactive;
2139 info->modes[i].yres = vm.vactive;
2140 info->modes[i].hsync_len = vm.hsync_len;
2141 info->modes[i].left_margin = vm.hback_porch;
2142 info->modes[i].right_margin = vm.hfront_porch;
2143 info->modes[i].vsync_len = vm.vsync_len;
2144 info->modes[i].upper_margin = vm.vback_porch;
2145 info->modes[i].lower_margin = vm.vfront_porch;
2161 np = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
2164 return -EINVAL;
2166 ret = of_property_read_u32(np, "bus-width", &bus_width);
2168 dev_err(dev, "no bus-width specified: %d\n", ret);
2177 return -EINVAL;
2185 for (i = 0; i < info->num_modes; i++)
2186 info->modes[i].bpp = bus_width;
2196 if (!dev->of_node)
2200 return ERR_PTR(-ENOMEM);
2207 * specified through device-tree, they are considered more a debug hack
2225 dev_dbg(&dev->dev, "pxafb_probe\n");
2227 ret = -ENOMEM;
2228 pdata = dev_get_platdata(&dev->dev);
2230 inf = devm_kmemdup(&dev->dev, pdata, sizeof(*pdata), GFP_KERNEL);
2234 inf->modes = devm_kmemdup_array(&dev->dev, pdata->modes, pdata->num_modes,
2235 sizeof(*pdata->modes), GFP_KERNEL);
2236 if (!inf->modes)
2239 inf = of_pxafb_of_mach_info(&dev->dev);
2244 ret = pxafb_parse_options(&dev->dev, g_options, inf);
2248 pxafb_check_options(&dev->dev, inf);
2250 dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",
2251 inf->modes->xres,
2252 inf->modes->yres,
2253 inf->modes->bpp);
2254 if (inf->modes->xres == 0 ||
2255 inf->modes->yres == 0 ||
2256 inf->modes->bpp == 0) {
2257 dev_err(&dev->dev, "Invalid resolution or bit depth\n");
2258 ret = -EINVAL;
2262 fbi = pxafb_init_fbinfo(&dev->dev, inf);
2264 dev_err(&dev->dev, "Failed to initialize framebuffer device\n");
2269 if (cpu_is_pxa3xx() && inf->acceleration_enabled)
2270 fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
2272 fbi->backlight_power = inf->pxafb_backlight_power;
2273 fbi->lcd_power = inf->pxafb_lcd_power;
2275 fbi->lcd_supply = devm_regulator_get_optional(&dev->dev, "lcd");
2276 if (IS_ERR(fbi->lcd_supply)) {
2277 if (PTR_ERR(fbi->lcd_supply) == -EPROBE_DEFER)
2278 return -EPROBE_DEFER;
2280 fbi->lcd_supply = NULL;
2283 fbi->mmio_base = devm_platform_ioremap_resource(dev, 0);
2284 if (IS_ERR(fbi->mmio_base)) {
2285 dev_err(&dev->dev, "failed to get I/O memory\n");
2286 ret = PTR_ERR(fbi->mmio_base);
2290 fbi->dma_buff_size = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));
2291 fbi->dma_buff = dma_alloc_coherent(fbi->dev, fbi->dma_buff_size,
2292 &fbi->dma_buff_phys, GFP_KERNEL);
2293 if (fbi->dma_buff == NULL) {
2294 dev_err(&dev->dev, "failed to allocate memory for DMA\n");
2295 ret = -ENOMEM;
2301 dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret);
2302 ret = -ENOMEM;
2308 ret = -ENODEV;
2312 ret = devm_request_irq(&dev->dev, irq, pxafb_handle_irq, 0, "LCD", fbi);
2314 dev_err(&dev->dev, "request_irq failed: %d\n", ret);
2315 ret = -EBUSY;
2321 dev_err(&dev->dev, "failed to initialize smartpanel\n");
2329 ret = pxafb_check_var(&fbi->fb.var, &fbi->fb);
2331 dev_err(&dev->dev, "failed to get suitable mode\n");
2335 ret = pxafb_set_par(&fbi->fb);
2337 dev_err(&dev->dev, "Failed to set parameters\n");
2343 ret = register_framebuffer(&fbi->fb);
2345 dev_err(&dev->dev,
2353 fbi->freq_transition.notifier_call = pxafb_freq_transition;
2354 cpufreq_register_notifier(&fbi->freq_transition,
2366 if (fbi->fb.cmap.len)
2367 fb_dealloc_cmap(&fbi->fb.cmap);
2369 free_pages_exact(fbi->video_mem, fbi->video_mem_size);
2371 dma_free_coherent(&dev->dev, fbi->dma_buff_size,
2372 fbi->dma_buff, fbi->dma_buff_phys);
2385 info = &fbi->fb;
2388 cancel_work_sync(&fbi->task);
2393 if (fbi->fb.cmap.len)
2394 fb_dealloc_cmap(&fbi->fb.cmap);
2396 free_pages_exact(fbi->video_mem, fbi->video_mem_size);
2398 dma_free_coherent(&dev->dev, fbi->dma_buff_size, fbi->dma_buff,
2399 fbi->dma_buff_phys);
2403 { .compatible = "marvell,pxa270-lcdc", },
2404 { .compatible = "marvell,pxa300-lcdc", },
2405 { .compatible = "marvell,pxa2xx-lcdc", },
2414 .name = "pxa2xx-fb",
2425 return -EINVAL;