aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/imxfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/imxfb.c')
-rw-r--r--drivers/video/imxfb.c66
1 files changed, 55 insertions, 11 deletions
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index d58c68cd456e..bd1cb75cd14b 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -14,7 +14,6 @@
14 * linux-arm-kernel@lists.arm.linux.org.uk 14 * linux-arm-kernel@lists.arm.linux.org.uk
15 */ 15 */
16 16
17
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
@@ -44,7 +43,12 @@
44 43
45#define LCDC_SIZE 0x04 44#define LCDC_SIZE 0x04
46#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) 45#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20)
46
47#ifdef CONFIG_ARCH_MX1
47#define SIZE_YMAX(y) ((y) & 0x1ff) 48#define SIZE_YMAX(y) ((y) & 0x1ff)
49#else
50#define SIZE_YMAX(y) ((y) & 0x3ff)
51#endif
48 52
49#define LCDC_VPW 0x08 53#define LCDC_VPW 0x08
50#define VPW_VPW(x) ((x) & 0x3ff) 54#define VPW_VPW(x) ((x) & 0x3ff)
@@ -54,7 +58,12 @@
54#define CPOS_CC0 (1<<30) 58#define CPOS_CC0 (1<<30)
55#define CPOS_OP (1<<28) 59#define CPOS_OP (1<<28)
56#define CPOS_CXP(x) (((x) & 3ff) << 16) 60#define CPOS_CXP(x) (((x) & 3ff) << 16)
61
62#ifdef CONFIG_ARCH_MX1
57#define CPOS_CYP(y) ((y) & 0x1ff) 63#define CPOS_CYP(y) ((y) & 0x1ff)
64#else
65#define CPOS_CYP(y) ((y) & 0x3ff)
66#endif
58 67
59#define LCDC_LCWHB 0x10 68#define LCDC_LCWHB 0x10
60#define LCWHB_BK_EN (1<<31) 69#define LCWHB_BK_EN (1<<31)
@@ -63,9 +72,16 @@
63#define LCWHB_BD(x) ((x) & 0xff) 72#define LCWHB_BD(x) ((x) & 0xff)
64 73
65#define LCDC_LCHCC 0x14 74#define LCDC_LCHCC 0x14
75
76#ifdef CONFIG_ARCH_MX1
66#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11) 77#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11)
67#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5) 78#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5)
68#define LCHCC_CUR_COL_B(b) ((b) & 0x1f) 79#define LCHCC_CUR_COL_B(b) ((b) & 0x1f)
80#else
81#define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12)
82#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6)
83#define LCHCC_CUR_COL_B(b) ((b) & 0x3f)
84#endif
69 85
70#define LCDC_PCR 0x18 86#define LCDC_PCR 0x18
71 87
@@ -92,7 +108,13 @@
92/* bit fields in imxfb.h */ 108/* bit fields in imxfb.h */
93 109
94#define LCDC_RMCR 0x34 110#define LCDC_RMCR 0x34
111
112#ifdef CONFIG_ARCH_MX1
95#define RMCR_LCDC_EN (1<<1) 113#define RMCR_LCDC_EN (1<<1)
114#else
115#define RMCR_LCDC_EN 0
116#endif
117
96#define RMCR_SELF_REF (1<<0) 118#define RMCR_SELF_REF (1<<0)
97 119
98#define LCDC_LCDICR 0x38 120#define LCDC_LCDICR 0x38
@@ -159,6 +181,17 @@ struct imxfb_info {
159#define MIN_XRES 64 181#define MIN_XRES 64
160#define MIN_YRES 64 182#define MIN_YRES 64
161 183
184/* Actually this really is 18bit support, the lowest 2 bits of each colour
185 * are unused in hardware. We claim to have 24bit support to make software
186 * like X work, which does not support 18bit.
187 */
188static struct imxfb_rgb def_rgb_18 = {
189 .red = {.offset = 16, .length = 8,},
190 .green = {.offset = 8, .length = 8,},
191 .blue = {.offset = 0, .length = 8,},
192 .transp = {.offset = 0, .length = 0,},
193};
194
162static struct imxfb_rgb def_rgb_16_tft = { 195static struct imxfb_rgb def_rgb_16_tft = {
163 .red = {.offset = 11, .length = 5,}, 196 .red = {.offset = 11, .length = 5,},
164 .green = {.offset = 5, .length = 6,}, 197 .green = {.offset = 5, .length = 6,},
@@ -286,6 +319,9 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
286 319
287 pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); 320 pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
288 switch (var->bits_per_pixel) { 321 switch (var->bits_per_pixel) {
322 case 32:
323 rgb = &def_rgb_18;
324 break;
289 case 16: 325 case 16:
290 default: 326 default:
291 if (readl(fbi->regs + LCDC_PCR) & PCR_TFT) 327 if (readl(fbi->regs + LCDC_PCR) & PCR_TFT)
@@ -327,9 +363,7 @@ static int imxfb_set_par(struct fb_info *info)
327 struct imxfb_info *fbi = info->par; 363 struct imxfb_info *fbi = info->par;
328 struct fb_var_screeninfo *var = &info->var; 364 struct fb_var_screeninfo *var = &info->var;
329 365
330 pr_debug("set_par\n"); 366 if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32)
331
332 if (var->bits_per_pixel == 16)
333 info->fix.visual = FB_VISUAL_TRUECOLOR; 367 info->fix.visual = FB_VISUAL_TRUECOLOR;
334 else if (!fbi->cmap_static) 368 else if (!fbi->cmap_static)
335 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 369 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -354,10 +388,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
354{ 388{
355 pr_debug("Enabling LCD controller\n"); 389 pr_debug("Enabling LCD controller\n");
356 390
357 /* initialize LCDC */
358 writel(readl(fbi->regs + LCDC_RMCR) & ~RMCR_LCDC_EN,
359 fbi->regs + LCDC_RMCR); /* just to be safe... */
360
361 writel(fbi->screen_dma, fbi->regs + LCDC_SSA); 391 writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
362 392
363 /* physical screen start address */ 393 /* physical screen start address */
@@ -465,9 +495,9 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
465 info->fix.id, var->lower_margin); 495 info->fix.id, var->lower_margin);
466#endif 496#endif
467 497
468 writel(HCR_H_WIDTH(var->hsync_len) | 498 writel(HCR_H_WIDTH(var->hsync_len - 1) |
469 HCR_H_WAIT_1(var->right_margin) | 499 HCR_H_WAIT_1(var->right_margin - 1) |
470 HCR_H_WAIT_2(var->left_margin), 500 HCR_H_WAIT_2(var->left_margin - 3),
471 fbi->regs + LCDC_HCR); 501 fbi->regs + LCDC_HCR);
472 502
473 writel(VCR_V_WIDTH(var->vsync_len) | 503 writel(VCR_V_WIDTH(var->vsync_len) |
@@ -650,6 +680,12 @@ static int __init imxfb_probe(struct platform_device *pdev)
650 info->fix.smem_start = fbi->screen_dma; 680 info->fix.smem_start = fbi->screen_dma;
651 } 681 }
652 682
683 if (pdata->init) {
684 ret = pdata->init(fbi->pdev);
685 if (ret)
686 goto failed_platform_init;
687 }
688
653 /* 689 /*
654 * This makes sure that our colour bitfield 690 * This makes sure that our colour bitfield
655 * descriptors are correctly initialised. 691 * descriptors are correctly initialised.
@@ -674,6 +710,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
674failed_register: 710failed_register:
675 fb_dealloc_cmap(&info->cmap); 711 fb_dealloc_cmap(&info->cmap);
676failed_cmap: 712failed_cmap:
713 if (pdata->exit)
714 pdata->exit(fbi->pdev);
715failed_platform_init:
677 if (!pdata->fixed_screen_cpu) 716 if (!pdata->fixed_screen_cpu)
678 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, 717 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
679 fbi->map_dma); 718 fbi->map_dma);
@@ -691,6 +730,7 @@ failed_init:
691 730
692static int __devexit imxfb_remove(struct platform_device *pdev) 731static int __devexit imxfb_remove(struct platform_device *pdev)
693{ 732{
733 struct imx_fb_platform_data *pdata;
694 struct fb_info *info = platform_get_drvdata(pdev); 734 struct fb_info *info = platform_get_drvdata(pdev);
695 struct imxfb_info *fbi = info->par; 735 struct imxfb_info *fbi = info->par;
696 struct resource *res; 736 struct resource *res;
@@ -701,6 +741,10 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
701 741
702 unregister_framebuffer(info); 742 unregister_framebuffer(info);
703 743
744 pdata = pdev->dev.platform_data;
745 if (pdata->exit)
746 pdata->exit(fbi->pdev);
747
704 fb_dealloc_cmap(&info->cmap); 748 fb_dealloc_cmap(&info->cmap);
705 kfree(info->pseudo_palette); 749 kfree(info->pseudo_palette);
706 framebuffer_release(info); 750 framebuffer_release(info);