]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/video/imxfb.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[karo-tx-linux.git] / drivers / video / imxfb.c
index 1bccf5ad0c7da91b37a8363099d2dedc880b41b2..d58c68cd456eda0c9aea90c5f566cfab06fc4cdf 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/video/imxfb.c
- *
  *  Freescale i.MX Frame Buffer device driver
  *
  *  Copyright (C) 2004 Sascha Hauer, Pengutronix
@@ -40,8 +38,6 @@
  */
 #define DEBUG_VAR 1
 
-#include "imxfb.h"
-
 #define DRIVER_NAME "imx-fb"
 
 #define LCDC_SSA       0x00
 #define LCDISR_EOF     (1<<1)
 #define LCDISR_BOF     (1<<0)
 
-static struct imxfb_rgb def_rgb_16 = {
-       .red    = { .offset = 8,  .length = 4, },
-       .green  = { .offset = 4,  .length = 4, },
-       .blue   = { .offset = 0,  .length = 4, },
-       .transp = { .offset = 0,  .length = 0, },
+/*
+ * These are the bitfields for each
+ * display depth that we support.
+ */
+struct imxfb_rgb {
+       struct fb_bitfield      red;
+       struct fb_bitfield      green;
+       struct fb_bitfield      blue;
+       struct fb_bitfield      transp;
+};
+
+struct imxfb_info {
+       struct platform_device  *pdev;
+       void __iomem            *regs;
+
+       u_int                   max_bpp;
+       u_int                   max_xres;
+       u_int                   max_yres;
+
+       /*
+        * These are the addresses we mapped
+        * the framebuffer memory region to.
+        */
+       dma_addr_t              map_dma;
+       u_char                  *map_cpu;
+       u_int                   map_size;
+
+       u_char                  *screen_cpu;
+       dma_addr_t              screen_dma;
+       u_int                   palette_size;
+
+       dma_addr_t              dbar1;
+       dma_addr_t              dbar2;
+
+       u_int                   pcr;
+       u_int                   pwmr;
+       u_int                   lscr1;
+       u_int                   dmacr;
+       u_int                   cmap_inverse:1,
+                               cmap_static:1,
+                               unused:30;
+
+       void (*lcd_power)(int);
+       void (*backlight_power)(int);
+};
+
+#define IMX_NAME       "IMX"
+
+/*
+ * Minimum X and Y resolutions
+ */
+#define MIN_XRES       64
+#define MIN_YRES       64
+
+static struct imxfb_rgb def_rgb_16_tft = {
+       .red    = {.offset = 11, .length = 5,},
+       .green  = {.offset = 5, .length = 6,},
+       .blue   = {.offset = 0, .length = 5,},
+       .transp = {.offset = 0, .length = 0,},
+};
+
+static struct imxfb_rgb def_rgb_16_stn = {
+       .red    = {.offset = 8, .length = 4,},
+       .green  = {.offset = 4, .length = 4,},
+       .blue   = {.offset = 0, .length = 4,},
+       .transp = {.offset = 0, .length = 0,},
 };
 
 static struct imxfb_rgb def_rgb_8 = {
-       .red    = { .offset = 0,  .length = 8, },
-       .green  = { .offset = 0,  .length = 8, },
-       .blue   = { .offset = 0,  .length = 8, },
-       .transp = { .offset = 0,  .length = 0, },
+       .red    = {.offset = 0, .length = 8,},
+       .green  = {.offset = 0, .length = 8,},
+       .blue   = {.offset = 0, .length = 8,},
+       .transp = {.offset = 0, .length = 0,},
 };
 
-static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
+static int imxfb_activate_var(struct fb_var_screeninfo *var,
+               struct fb_info *info);
 
 static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
 {
@@ -132,9 +190,8 @@ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
        return chan << bf->offset;
 }
 
-static int
-imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
-                      u_int trans, struct fb_info *info)
+static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
+               u_int trans, struct fb_info *info)
 {
        struct imxfb_info *fbi = info->par;
        u_int val, ret = 1;
@@ -151,8 +208,7 @@ imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
        return ret;
 }
 
-static int
-imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                   u_int trans, struct fb_info *info)
 {
        struct imxfb_info *fbi = info->par;
@@ -212,11 +268,10 @@ imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
  *    bitfields, horizontal timing, vertical timing.
  */
-static int
-imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct imxfb_info *fbi = info->par;
-       int rgbidx;
+       struct imxfb_rgb *rgb;
 
        if (var->xres < MIN_XRES)
                var->xres = MIN_XRES;
@@ -232,23 +287,25 @@ imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
        switch (var->bits_per_pixel) {
        case 16:
-               rgbidx = RGB_16;
+       default:
+               if (readl(fbi->regs + LCDC_PCR) & PCR_TFT)
+                       rgb = &def_rgb_16_tft;
+               else
+                       rgb = &def_rgb_16_stn;
                break;
        case 8:
-               rgbidx = RGB_8;
+               rgb = &def_rgb_8;
                break;
-       default:
-               rgbidx = RGB_16;
        }
 
        /*
         * Copy the RGB parameters for this display
         * from the machine specific parameters.
         */
-       var->red    = fbi->rgb[rgbidx]->red;
-       var->green  = fbi->rgb[rgbidx]->green;
-       var->blue   = fbi->rgb[rgbidx]->blue;
-       var->transp = fbi->rgb[rgbidx]->transp;
+       var->red    = rgb->red;
+       var->green  = rgb->green;
+       var->blue   = rgb->blue;
+       var->transp = rgb->transp;
 
        pr_debug("RGBT length = %d:%d:%d:%d\n",
                var->red.length, var->green.length, var->blue.length,
@@ -285,8 +342,7 @@ static int imxfb_set_par(struct fb_info *info)
                info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
        }
 
-       info->fix.line_length = var->xres_virtual *
-                                 var->bits_per_pixel / 8;
+       info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
        fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
 
        imxfb_activate_var(var, info);
@@ -317,9 +373,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
 
        writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
 
-       if(fbi->backlight_power)
+       if (fbi->backlight_power)
                fbi->backlight_power(1);
-       if(fbi->lcd_power)
+       if (fbi->lcd_power)
                fbi->lcd_power(1);
 }
 
@@ -327,9 +383,9 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
 {
        pr_debug("Disabling LCD controller\n");
 
-       if(fbi->backlight_power)
+       if (fbi->backlight_power)
                fbi->backlight_power(0);
-       if(fbi->lcd_power)
+       if (fbi->lcd_power)
                fbi->lcd_power(0);
 
        writel(0, fbi->regs + LCDC_RMCR);
@@ -410,13 +466,13 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
 #endif
 
        writel(HCR_H_WIDTH(var->hsync_len) |
-               HCR_H_WAIT_1(var->left_margin) |
-               HCR_H_WAIT_2(var->right_margin),
+               HCR_H_WAIT_1(var->right_margin) |
+               HCR_H_WAIT_2(var->left_margin),
                fbi->regs + LCDC_HCR);
 
        writel(VCR_V_WIDTH(var->vsync_len) |
-               VCR_V_WAIT_1(var->upper_margin) |
-               VCR_V_WAIT_2(var->lower_margin),
+               VCR_V_WAIT_1(var->lower_margin) |
+               VCR_V_WAIT_2(var->upper_margin),
                fbi->regs + LCDC_VCR);
 
        writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
@@ -437,7 +493,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
 static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
 {
        struct imxfb_info *fbi = platform_get_drvdata(dev);
-       pr_debug("%s\n",__func__);
+
+       pr_debug("%s\n", __func__);
 
        imxfb_disable_controller(fbi);
        return 0;
@@ -446,7 +503,8 @@ static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
 static int imxfb_resume(struct platform_device *dev)
 {
        struct imxfb_info *fbi = platform_get_drvdata(dev);
-       pr_debug("%s\n",__func__);
+
+       pr_debug("%s\n", __func__);
 
        imxfb_enable_controller(fbi);
        return 0;
@@ -458,13 +516,13 @@ static int imxfb_resume(struct platform_device *dev)
 
 static int __init imxfb_init_fbinfo(struct platform_device *pdev)
 {
-       struct imxfb_mach_info *inf = pdev->dev.platform_data;
+       struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
        struct fb_info *info = dev_get_drvdata(&pdev->dev);
        struct imxfb_info *fbi = info->par;
 
        pr_debug("%s\n",__func__);
 
-       info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL);
+       info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
        if (!info->pseudo_palette)
                return -ENOMEM;
 
@@ -472,52 +530,50 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
 
        strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
 
-       info->fix.type  = FB_TYPE_PACKED_PIXELS;
+       info->fix.type                  = FB_TYPE_PACKED_PIXELS;
        info->fix.type_aux              = 0;
        info->fix.xpanstep              = 0;
        info->fix.ypanstep              = 0;
        info->fix.ywrapstep             = 0;
-       info->fix.accel = FB_ACCEL_NONE;
+       info->fix.accel                 = FB_ACCEL_NONE;
 
        info->var.nonstd                = 0;
        info->var.activate              = FB_ACTIVATE_NOW;
        info->var.height                = -1;
        info->var.width = -1;
        info->var.accel_flags           = 0;
-       info->var.vmode = FB_VMODE_NONINTERLACED;
+       info->var.vmode                 = FB_VMODE_NONINTERLACED;
 
        info->fbops                     = &imxfb_ops;
-       info->flags                     = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
-
-       fbi->rgb[RGB_16]                = &def_rgb_16;
-       fbi->rgb[RGB_8]                 = &def_rgb_8;
-
-       fbi->max_xres                   = inf->xres;
-       info->var.xres                  = inf->xres;
-       info->var.xres_virtual          = inf->xres;
-       fbi->max_yres                   = inf->yres;
-       info->var.yres                  = inf->yres;
-       info->var.yres_virtual          = inf->yres;
-       fbi->max_bpp                    = inf->bpp;
-       info->var.bits_per_pixel        = inf->bpp;
-       info->var.nonstd                = inf->nonstd;
-       info->var.pixclock              = inf->pixclock;
-       info->var.hsync_len             = inf->hsync_len;
-       info->var.left_margin           = inf->left_margin;
-       info->var.right_margin          = inf->right_margin;
-       info->var.vsync_len             = inf->vsync_len;
-       info->var.upper_margin          = inf->upper_margin;
-       info->var.lower_margin          = inf->lower_margin;
-       info->var.sync                  = inf->sync;
-       info->var.grayscale             = inf->cmap_greyscale;
-       fbi->cmap_inverse               = inf->cmap_inverse;
-       fbi->cmap_static                = inf->cmap_static;
-       fbi->pcr                        = inf->pcr;
-       fbi->lscr1                      = inf->lscr1;
-       fbi->dmacr                      = inf->dmacr;
-       fbi->pwmr                       = inf->pwmr;
-       fbi->lcd_power                  = inf->lcd_power;
-       fbi->backlight_power            = inf->backlight_power;
+       info->flags                     = FBINFO_FLAG_DEFAULT |
+                                         FBINFO_READS_FAST;
+
+       fbi->max_xres                   = pdata->xres;
+       info->var.xres                  = pdata->xres;
+       info->var.xres_virtual          = pdata->xres;
+       fbi->max_yres                   = pdata->yres;
+       info->var.yres                  = pdata->yres;
+       info->var.yres_virtual          = pdata->yres;
+       fbi->max_bpp                    = pdata->bpp;
+       info->var.bits_per_pixel        = pdata->bpp;
+       info->var.nonstd                = pdata->nonstd;
+       info->var.pixclock              = pdata->pixclock;
+       info->var.hsync_len             = pdata->hsync_len;
+       info->var.left_margin           = pdata->left_margin;
+       info->var.right_margin          = pdata->right_margin;
+       info->var.vsync_len             = pdata->vsync_len;
+       info->var.upper_margin          = pdata->upper_margin;
+       info->var.lower_margin          = pdata->lower_margin;
+       info->var.sync                  = pdata->sync;
+       info->var.grayscale             = pdata->cmap_greyscale;
+       fbi->cmap_inverse               = pdata->cmap_inverse;
+       fbi->cmap_static                = pdata->cmap_static;
+       fbi->pcr                        = pdata->pcr;
+       fbi->lscr1                      = pdata->lscr1;
+       fbi->dmacr                      = pdata->dmacr;
+       fbi->pwmr                       = pdata->pwmr;
+       fbi->lcd_power                  = pdata->lcd_power;
+       fbi->backlight_power            = pdata->backlight_power;
        info->fix.smem_len              = fbi->max_xres * fbi->max_yres *
                                          fbi->max_bpp / 8;
 
@@ -528,24 +584,24 @@ static int __init imxfb_probe(struct platform_device *pdev)
 {
        struct imxfb_info *fbi;
        struct fb_info *info;
-       struct imxfb_mach_info *inf;
+       struct imx_fb_platform_data *pdata;
        struct resource *res;
        int ret;
 
        printk("i.MX Framebuffer driver\n");
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if(!res)
+       if (!res)
                return -ENODEV;
 
-       inf = pdev->dev.platform_data;
-       if(!inf) {
+       pdata = pdev->dev.platform_data;
+       if (!pdata) {
                dev_err(&pdev->dev,"No platform_data available\n");
                return -ENOMEM;
        }
 
        info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
-       if(!info)
+       if (!info)
                return -ENOMEM;
 
        fbi = info->par;
@@ -553,7 +609,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, info);
 
        ret = imxfb_init_fbinfo(pdev);
-       if( ret < 0 )
+       if (ret < 0)
                goto failed_init;
 
        res = request_mem_region(res->start, resource_size(res),
@@ -569,7 +625,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
                goto failed_ioremap;
        }
 
-       if (!inf->fixed_screen_cpu) {
+       if (!pdata->fixed_screen_cpu) {
                fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
                fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
                                fbi->map_size, &fbi->map_dma, GFP_KERNEL);
@@ -586,8 +642,8 @@ static int __init imxfb_probe(struct platform_device *pdev)
                info->fix.smem_start = fbi->screen_dma;
        } else {
                /* Fixed framebuffer mapping enables location of the screen in eSRAM */
-               fbi->map_cpu = inf->fixed_screen_cpu;
-               fbi->map_dma = inf->fixed_screen_dma;
+               fbi->map_cpu = pdata->fixed_screen_cpu;
+               fbi->map_dma = pdata->fixed_screen_dma;
                info->screen_base = fbi->map_cpu;
                fbi->screen_cpu = fbi->map_cpu;
                fbi->screen_dma = fbi->map_dma;
@@ -600,7 +656,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
         */
        imxfb_check_var(&info->var, info);
 
-       ret = fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
+       ret = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
        if (ret < 0)
                goto failed_cmap;
 
@@ -618,7 +674,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
 failed_register:
        fb_dealloc_cmap(&info->cmap);
 failed_cmap:
-       if (!inf->fixed_screen_cpu)
+       if (!pdata->fixed_screen_cpu)
                dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
                        fbi->map_dma);
 failed_map: