Merge branch 'fbdev/stable-updates'
authorPaul Mundt <lethal@linux-sh.org>
Wed, 13 Jul 2011 08:02:12 +0000 (17:02 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 13 Jul 2011 08:02:12 +0000 (17:02 +0900)
46 files changed:
arch/powerpc/platforms/512x/mpc512x_shared.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/sysdev/fsl_soc.h
drivers/staging/xgifb/XGI_main_26.c
drivers/video/68328fb.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/acornfb.c
drivers/video/arkfb.c
drivers/video/atmel_lcdfb.c
drivers/video/aty/radeon_base.c
drivers/video/au1200fb.c
drivers/video/backlight/adp8860_bl.c
drivers/video/backlight/adp8870_bl.c
drivers/video/controlfb.c
drivers/video/da8xx-fb.c
drivers/video/fb-puv3.c
drivers/video/fb_defio.c
drivers/video/fsl-diu-fb.c
drivers/video/g364fb.c
drivers/video/grvga.c [new file with mode: 0644]
drivers/video/gxt4500.c
drivers/video/hgafb.c
drivers/video/imsttfb.c
drivers/video/intelfb/intelfbhw.c
drivers/video/mb862xx/mb862xxfbdrv.c
drivers/video/mx3fb.c
drivers/video/neofb.c
drivers/video/platinumfb.c
drivers/video/pm2fb.c
drivers/video/pm3fb.c
drivers/video/pxa3xx-gcu.c
drivers/video/s3c-fb.c
drivers/video/s3fb.c
drivers/video/savage/savagefb_driver.c
drivers/video/sis/sis_main.c
drivers/video/skeletonfb.c
drivers/video/sm501fb.c
drivers/video/tridentfb.c
drivers/video/valkyriefb.c
drivers/video/vfb.c
drivers/video/vga16fb.c
drivers/video/vt8500lcdfb.c
drivers/video/vt8623fb.c
drivers/video/xilinxfb.c

index e41ebbdb3e123fb8413c89559ff156ac7f89f245..3dc62f907a1ef6aa53ef6b2503d4e5a4147d7b0a 100644 (file)
@@ -66,8 +66,8 @@ struct fsl_diu_shared_fb {
        bool            in_use;
 };
 
-unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
-                                     int monitor_port)
+u32 mpc512x_get_pixel_format(enum fsl_diu_monitor_port port,
+                            unsigned int bits_per_pixel)
 {
        switch (bits_per_pixel) {
        case 32:
@@ -80,11 +80,12 @@ unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
        return 0x00000400;
 }
 
-void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base)
+void mpc512x_set_gamma_table(enum fsl_diu_monitor_port port,
+                            char *gamma_table_base)
 {
 }
 
-void mpc512x_set_monitor_port(int monitor_port)
+void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
 {
 }
 
@@ -182,14 +183,10 @@ void mpc512x_set_pixel_clock(unsigned int pixclock)
        iounmap(ccm);
 }
 
-ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf)
+enum fsl_diu_monitor_port
+mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
-       return sprintf(buf, "0 - 5121 LCD\n");
-}
-
-int mpc512x_set_sysfs_monitor_port(int val)
-{
-       return 0;
+       return FSL_DIU_PORT_DVI;
 }
 
 static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
@@ -332,8 +329,7 @@ void __init mpc512x_setup_diu(void)
        diu_ops.set_gamma_table         = mpc512x_set_gamma_table;
        diu_ops.set_monitor_port        = mpc512x_set_monitor_port;
        diu_ops.set_pixel_clock         = mpc512x_set_pixel_clock;
-       diu_ops.show_monitor_port       = mpc512x_show_monitor_port;
-       diu_ops.set_sysfs_monitor_port  = mpc512x_set_sysfs_monitor_port;
+       diu_ops.valid_monitor_port      = mpc512x_valid_monitor_port;
        diu_ops.release_bootmem         = mpc512x_release_bootmem;
 #endif
 }
index 7eb5c40c069fafb296b436c99241b721be33895f..a13d3cce413c7014453f05e3de670e3210ce3753 100644 (file)
@@ -93,8 +93,8 @@
  * The Area Descriptor is a 32-bit value that determine which bits in each
  * pixel are to be used for each color.
  */
-static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
-       int monitor_port)
+static u32 p1022ds_get_pixel_format(enum fsl_diu_monitor_port port,
+                                   unsigned int bits_per_pixel)
 {
        switch (bits_per_pixel) {
        case 32:
@@ -118,7 +118,8 @@ static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
  * On some boards, the gamma table for some ports may need to be modified.
  * This is not the case on the P1022DS, so we do nothing.
 */
-static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
+static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
+                                   char *gamma_table_base)
 {
 }
 
@@ -126,7 +127,7 @@ static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
  * p1022ds_set_monitor_port: switch the output to a different monitor port
  *
  */
-static void p1022ds_set_monitor_port(int monitor_port)
+static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
 {
        struct device_node *pixis_node;
        u8 __iomem *brdcfg1;
@@ -144,19 +145,21 @@ static void p1022ds_set_monitor_port(int monitor_port)
        }
        brdcfg1 += 9;   /* BRDCFG1 is at offset 9 in the ngPIXIS */
 
-       switch (monitor_port) {
-       case 0: /* DVI */
+       switch (port) {
+       case FSL_DIU_PORT_DVI:
+               printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
                /* Enable the DVI port, disable the DFP and the backlight */
                clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
                             PX_BRDCFG1_DVIEN);
                break;
-       case 1: /* Single link LVDS */
+       case FSL_DIU_PORT_LVDS:
+               printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
                /* Enable the DFP port, disable the DVI and the backlight */
                clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
                             PX_BRDCFG1_DFPEN);
                break;
        default:
-               pr_err("p1022ds: unsupported monitor port %i\n", monitor_port);
+               pr_err("p1022ds: unsupported monitor port %i\n", port);
        }
 }
 
@@ -204,23 +207,18 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
 }
 
 /**
- * p1022ds_show_monitor_port: show the current monitor
- *
- * This function returns a string indicating whether the current monitor is
- * set to DVI or LVDS.
- */
-ssize_t p1022ds_show_monitor_port(int monitor_port, char *buf)
-{
-       return sprintf(buf, "%c0 - DVI\n%c1 - Single link LVDS\n",
-               monitor_port == 0 ? '*' : ' ', monitor_port == 1 ? '*' : ' ');
-}
-
-/**
- * p1022ds_set_sysfs_monitor_port: set the monitor port for sysfs
+ * p1022ds_valid_monitor_port: set the monitor port for sysfs
  */
-int p1022ds_set_sysfs_monitor_port(int val)
+enum fsl_diu_monitor_port
+p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
-       return val < 2 ? val : 0;
+       switch (port) {
+       case FSL_DIU_PORT_DVI:
+       case FSL_DIU_PORT_LVDS:
+               return port;
+       default:
+               return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
+       }
 }
 
 #endif
@@ -295,8 +293,7 @@ static void __init p1022_ds_setup_arch(void)
        diu_ops.set_gamma_table         = p1022ds_set_gamma_table;
        diu_ops.set_monitor_port        = p1022ds_set_monitor_port;
        diu_ops.set_pixel_clock         = p1022ds_set_pixel_clock;
-       diu_ops.show_monitor_port       = p1022ds_show_monitor_port;
-       diu_ops.set_sysfs_monitor_port  = p1022ds_set_sysfs_monitor_port;
+       diu_ops.valid_monitor_port      = p1022ds_valid_monitor_port;
 #endif
 
 #ifdef CONFIG_SMP
index a896511690c24de2962ae02679f723fc0f3f3f59..0d80e9614f31aff45a75853028e7170a2b6d8e08 100644 (file)
@@ -145,10 +145,10 @@ machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
        (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
        (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
 
-unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
-                                               int monitor_port)
+u32 mpc8610hpcd_get_pixel_format(enum fsl_diu_monitor_port port,
+                                unsigned int bits_per_pixel)
 {
-       static const unsigned long pixelformat[][3] = {
+       static const u32 pixelformat[][3] = {
                {
                        MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8),
                        MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0),
@@ -163,7 +163,8 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
        unsigned int arch_monitor;
 
        /* The DVI port is mis-wired on revision 1 of this board. */
-       arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1;
+       arch_monitor =
+               ((*pixis_arch == 0x01) && (port == FSL_DIU_PORT_DVI)) ? 0 : 1;
 
        switch (bits_per_pixel) {
        case 32:
@@ -178,10 +179,11 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
        }
 }
 
-void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
+void mpc8610hpcd_set_gamma_table(enum fsl_diu_monitor_port port,
+                                char *gamma_table_base)
 {
        int i;
-       if (monitor_port == 2) {                /* dual link LVDS */
+       if (port == FSL_DIU_PORT_DLVDS) {
                for (i = 0; i < 256*3; i++)
                        gamma_table_base[i] = (gamma_table_base[i] << 2) |
                                         ((gamma_table_base[i] >> 6) & 0x03);
@@ -192,17 +194,21 @@ void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
 #define PX_BRDCFG0_DLINK       (1 << 4)
 #define PX_BRDCFG0_DIU_MASK    (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK)
 
-void mpc8610hpcd_set_monitor_port(int monitor_port)
+void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port)
 {
-       static const u8 bdcfg[] = {
-               PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK,
-               PX_BRDCFG0_DLINK,
-               0,
-       };
-
-       if (monitor_port < 3)
+       switch (port) {
+       case FSL_DIU_PORT_DVI:
                clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
-                            bdcfg[monitor_port]);
+                            PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK);
+               break;
+       case FSL_DIU_PORT_LVDS:
+               clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
+                            PX_BRDCFG0_DLINK);
+               break;
+       case FSL_DIU_PORT_DLVDS:
+               clrbits8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK);
+               break;
+       }
 }
 
 void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
@@ -273,20 +279,10 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
        iounmap(clkdvdr);
 }
 
-ssize_t mpc8610hpcd_show_monitor_port(int monitor_port, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE,
-                       "%c0 - DVI\n"
-                       "%c1 - Single link LVDS\n"
-                       "%c2 - Dual link LVDS\n",
-                       monitor_port == 0 ? '*' : ' ',
-                       monitor_port == 1 ? '*' : ' ',
-                       monitor_port == 2 ? '*' : ' ');
-}
-
-int mpc8610hpcd_set_sysfs_monitor_port(int val)
+enum fsl_diu_monitor_port
+mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
-       return val < 3 ? val : 0;
+       return port;
 }
 
 #endif
@@ -318,8 +314,7 @@ static void __init mpc86xx_hpcd_setup_arch(void)
        diu_ops.set_gamma_table         = mpc8610hpcd_set_gamma_table;
        diu_ops.set_monitor_port        = mpc8610hpcd_set_monitor_port;
        diu_ops.set_pixel_clock         = mpc8610hpcd_set_pixel_clock;
-       diu_ops.show_monitor_port       = mpc8610hpcd_show_monitor_port;
-       diu_ops.set_sysfs_monitor_port  = mpc8610hpcd_set_sysfs_monitor_port;
+       diu_ops.valid_monitor_port      = mpc8610hpcd_valid_monitor_port;
 #endif
 
        pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
index 53609489a62b844fd1d3dd445051dc4653d5db5e..064bc70891349e5c3afa07cf6443f45663f2e727 100644 (file)
@@ -22,15 +22,24 @@ struct device_node;
 extern void fsl_rstcr_restart(char *cmd);
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
+
+/* The different ports that the DIU can be connected to */
+enum fsl_diu_monitor_port {
+       FSL_DIU_PORT_DVI,       /* DVI */
+       FSL_DIU_PORT_LVDS,      /* Single-link LVDS */
+       FSL_DIU_PORT_DLVDS      /* Dual-link LVDS */
+};
+
 struct platform_diu_data_ops {
-       unsigned int (*get_pixel_format) (unsigned int bits_per_pixel,
-               int monitor_port);
-       void (*set_gamma_table) (int monitor_port, char *gamma_table_base);
-       void (*set_monitor_port) (int monitor_port);
-       void (*set_pixel_clock) (unsigned int pixclock);
-       ssize_t (*show_monitor_port) (int monitor_port, char *buf);
-       int (*set_sysfs_monitor_port) (int val);
-       void (*release_bootmem) (void);
+       u32 (*get_pixel_format)(enum fsl_diu_monitor_port port,
+               unsigned int bpp);
+       void (*set_gamma_table)(enum fsl_diu_monitor_port port,
+               char *gamma_table_base);
+       void (*set_monitor_port)(enum fsl_diu_monitor_port port);
+       void (*set_pixel_clock)(unsigned int pixclock);
+       enum fsl_diu_monitor_port (*valid_monitor_port)
+               (enum fsl_diu_monitor_port port);
+       void (*release_bootmem)(void);
 };
 
 extern struct platform_diu_data_ops diu_ops;
index cadec2ad0d3240ca858b1822ab50733d425b51fa..e92f6fa67dcbffbf46cdbf5980b699ed9303d82f 100644 (file)
@@ -1365,26 +1365,16 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 }
 
 #ifdef XGIFB_PAN
-static int XGIfb_pan_var(struct fb_var_screeninfo *var)
+static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        unsigned int base;
 
        /* printk("Inside pan_var"); */
 
-       if (var->xoffset > (var->xres_virtual - var->xres)) {
-               /* printk("Pan: xo: %d xv %d xr %d\n",
-                       var->xoffset, var->xres_virtual, var->xres); */
-               return -EINVAL;
-       }
-       if (var->yoffset > (var->yres_virtual - var->yres)) {
-               /* printk("Pan: yo: %d yv %d yr %d\n",
-                       var->yoffset, var->yres_virtual, var->yres); */
-               return -EINVAL;
-       }
-       base = var->yoffset * var->xres_virtual + var->xoffset;
+       base = var->yoffset * info->var.xres_virtual + var->xoffset;
 
        /* calculate base bpp dep. */
-       switch (var->bits_per_pixel) {
+       switch (info->var.bits_per_pixel) {
        case 16:
                base >>= 1;
                break;
@@ -1682,9 +1672,9 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
 
        /* printk("\nInside pan_display:\n"); */
 
-       if (var->xoffset > (var->xres_virtual - var->xres))
+       if (var->xoffset > (info->var.xres_virtual - info->var.xres))
                return -EINVAL;
-       if (var->yoffset > (var->yres_virtual - var->yres))
+       if (var->yoffset > (info->var.yres_virtual - info->var.yres))
                return -EINVAL;
 
        if (var->vmode & FB_VMODE_YWRAP) {
@@ -1697,7 +1687,7 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
                                                > info->var.yres_virtual)
                        return -EINVAL;
        }
-       err = XGIfb_pan_var(var);
+       err = XGIfb_pan_var(var, info);
        if (err < 0)
                return err;
 
index 75a39eab70c38e291363473074ff8373dcf30135..a425d65d5ba2d5d2e66f513f5dfcfa29b62de186 100644 (file)
@@ -378,8 +378,8 @@ static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
                    || var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual ||
-                   var->yoffset + var->yres > info->var.yres_virtual)
+               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+                   var->yoffset + info->var.yres > info->var.yres_virtual)
                        return -EINVAL;
        }
        info->var.xoffset = var->xoffset;
index 549b960667c81b5bcbff1145550a28630038c374..e087fc2207e7b9f6cbe9a868a8fee620bec366d8 100644 (file)
@@ -259,6 +259,15 @@ config FB_TILEBLITTING
 comment "Frame buffer hardware drivers"
        depends on FB
 
+config FB_GRVGA
+       tristate "Aeroflex Gaisler framebuffer support"
+       depends on FB && SPARC
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       ---help---
+       This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
 config FB_CIRRUS
        tristate "Cirrus Logic support"
        depends on FB && (ZORRO || PCI)
@@ -1756,9 +1765,10 @@ config FB_AU1100
 config FB_AU1200
        bool "Au1200 LCD Driver"
        depends on (FB = y) && MIPS && SOC_AU1200
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_SYS_FOPS
        help
          This is the framebuffer driver for the AMD Au1200 SOC.  It can drive
          various panels and CRTs by passing in kernel cmd line option
index 8b83129e209ca0f943a3d624e29930a679aec110..43079108bb16695d02052b6452e123f84a8beab7 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
+obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)             += pm3fb.o
 
index 6183a57eb69d8b913abcde29af3bbdb24714e725..b303f17150654a8a4d0237f41977421a29cd715b 100644 (file)
@@ -850,9 +850,10 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        u_int y_bottom = var->yoffset;
 
        if (!(var->vmode & FB_VMODE_YWRAP))
-               y_bottom += var->yres;
+               y_bottom += info->var.yres;
 
-       BUG_ON(y_bottom > var->yres_virtual);
+       if (y_bottom > info->var.yres_virtual)
+               return -EINVAL;
 
        acornfb_update_dma(info, var);
 
index 8686429cbdf07b57af8564849ad64b7a8624ff16..555dd4c64f5be24a1a13986f84fe19360f1d9102 100644 (file)
@@ -908,13 +908,14 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
        unsigned int offset;
 
        /* Calculate the offset */
-       if (var->bits_per_pixel == 0) {
-               offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
+       if (info->var.bits_per_pixel == 0) {
+               offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
+                      + (var->xoffset / 2);
                offset = offset >> 2;
        } else {
                offset = (var->yoffset * info->fix.line_length) +
-                        (var->xoffset * var->bits_per_pixel / 8);
-               offset = offset >> ((var->bits_per_pixel == 4) ? 2 : 3);
+                        (var->xoffset * info->var.bits_per_pixel / 8);
+               offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 3);
        }
 
        /* Set the offset */
index 4484c721f0f9b1ce6a160b5d7e450d0245b2e772..8b5d7552bb6583568a86bcb969019ef2a1c7df84 100644 (file)
@@ -39,7 +39,8 @@
                                         | FBINFO_HWACCEL_YPAN)
 
 static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
-                                       struct fb_var_screeninfo *var)
+                                       struct fb_var_screeninfo *var,
+                                       struct fb_info *info)
 {
 
 }
@@ -50,14 +51,16 @@ static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
                                        | FBINFO_HWACCEL_YPAN)
 
 static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
-                                    struct fb_var_screeninfo *var)
+                                    struct fb_var_screeninfo *var,
+                                    struct fb_info *info)
 {
        u32 dma2dcfg;
        u32 pixeloff;
 
-       pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
+       pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
 
-       dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
+       dma2dcfg = (info-var.xres_virtual - info->var.xres)
+                * info->var.bits_per_pixel / 8;
        dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
        lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
 
@@ -249,14 +252,14 @@ static void atmel_lcdfb_update_dma(struct fb_info *info,
        unsigned long dma_addr;
 
        dma_addr = (fix->smem_start + var->yoffset * fix->line_length
-                   + var->xoffset * var->bits_per_pixel / 8);
+                   + var->xoffset * info->var.bits_per_pixel / 8);
 
        dma_addr &= ~3UL;
 
        /* Set framebuffer DMA base address and pixel offset */
        lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
 
-       atmel_lcdfb_update_dma2d(sinfo, var);
+       atmel_lcdfb_update_dma2d(sinfo, var, info);
 }
 
 static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
index 32f8cf6200a7533ce7bce35a4896fcdb4ff7946b..150684882ef74fce86d33ea2ed14bad9afa5df5b 100644 (file)
@@ -845,16 +845,16 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
 {
         struct radeonfb_info *rinfo = info->par;
 
-        if ((var->xoffset + var->xres > var->xres_virtual)
-           || (var->yoffset + var->yres > var->yres_virtual))
-               return -EINVAL;
+       if ((var->xoffset + info->var.xres > info->var.xres_virtual)
+           || (var->yoffset + info->var.yres > info->var.yres_virtual))
+               return -EINVAL;
                 
         if (rinfo->asleep)
                return 0;
 
        radeon_fifo_wait(2);
-        OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
-                            * var->bits_per_pixel / 8) & ~7);
+       OUTREG(CRTC_OFFSET, (var->yoffset * info->fix.line_length +
+                            var->xoffset * info->var.bits_per_pixel / 8) & ~7);
         return 0;
 }
 
index 5dff32ac8044be8de287c7e4c156dd0c577eb3c8..ed5dcdb29cf7ba232571a868a7fdb506c7ba9be1 100644 (file)
 #include <asm/mach-au1x00/au1000.h>
 #include "au1200fb.h"
 
-#ifdef CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
-#ifndef CONFIG_FB_AU1200_DEVS
-#define CONFIG_FB_AU1200_DEVS 4
-#endif
-
 #define DRIVER_NAME "au1200fb"
 #define DRIVER_DESC "LCD controller driver for AU1200 processors"
 
@@ -150,7 +142,7 @@ struct au1200_lcd_iodata_t {
 
 /* Private, per-framebuffer management information (independent of the panel itself) */
 struct au1200fb_device {
-       struct fb_info fb_info;                 /* FB driver info record */
+       struct fb_info *fb_info;                /* FB driver info record */
 
        int                                     plane;
        unsigned char*          fb_mem;         /* FrameBuffer memory map */
@@ -158,7 +150,6 @@ struct au1200fb_device {
        dma_addr_t              fb_phys;
 };
 
-static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
 /********************************************************************/
 
 /* LCD controller restrictions */
@@ -171,10 +162,18 @@ static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
 /* Default number of visible screen buffer to allocate */
 #define AU1200FB_NBR_VIDEO_BUFFERS 1
 
+/* Default maximum number of fb devices to create */
+#define MAX_DEVICE_COUNT       4
+
+/* Default window configuration entry to use (see windows[]) */
+#define DEFAULT_WINDOW_INDEX   2
+
 /********************************************************************/
 
+static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
 static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
-static int window_index = 2; /* default is zero */
+static int device_count = MAX_DEVICE_COUNT;
+static int window_index = DEFAULT_WINDOW_INDEX;        /* default is zero */
 static int panel_index = 2; /* default is zero */
 static struct window_settings *win;
 static struct panel_settings *panel;
@@ -205,12 +204,6 @@ struct window_settings {
 extern int board_au1200fb_panel_init (void);
 extern int board_au1200fb_panel_shutdown (void);
 
-#ifdef CONFIG_PM
-int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
-               au1xxx_request_t request, void *data);
-au1xxx_power_dev_t *LCD_pm_dev;
-#endif
-
 /*
  * Default window configurations
  */
@@ -652,25 +645,6 @@ static struct panel_settings known_lcd_panels[] =
 
 /********************************************************************/
 
-#ifdef CONFIG_PM
-static int set_brightness(unsigned int brightness)
-{
-       unsigned int hi1, divider;
-
-       /* limit brightness pwm duty to >= 30/1600 */
-       if (brightness < 30) {
-               brightness = 30;
-       }
-       divider = (lcd->pwmdiv & 0x3FFFF) + 1;
-       hi1 = (lcd->pwmhi >> 16) + 1;
-       hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
-       lcd->pwmhi &= 0xFFFF;
-       lcd->pwmhi |= (hi1 << 16);
-
-       return brightness;
-}
-#endif /* CONFIG_PM */
-
 static int winbpp (unsigned int winctrl1)
 {
        int bits = 0;
@@ -712,8 +686,8 @@ static int fbinfo2index (struct fb_info *fb_info)
 {
        int i;
 
-       for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
-               if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
+       for (i = 0; i < device_count; ++i) {
+               if (fb_info == _au1200fb_infos[i])
                        return i;
        }
        printk("au1200fb: ERROR: fbinfo2index failed!\n");
@@ -962,7 +936,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev)
        lcd->window[plane].winctrl2 = ( 0
                | LCD_WINCTRL2_CKMODE_00
                | LCD_WINCTRL2_DBM
-               | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
+               | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
                | LCD_WINCTRL2_SCX_1
                | LCD_WINCTRL2_SCY_1
                ) ;
@@ -1050,7 +1024,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi)
 static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
        struct fb_info *fbi)
 {
-       struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
+       struct au1200fb_device *fbdev = fbi->par;
        u32 pixclock;
        int screen_size, plane;
 
@@ -1142,7 +1116,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
  */
 static int au1200fb_fb_set_par(struct fb_info *fbi)
 {
-       struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
+       struct au1200fb_device *fbdev = fbi->par;
 
        au1200fb_update_fbinfo(fbi);
        au1200_setmode(fbdev);
@@ -1246,11 +1220,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        unsigned int len;
        unsigned long start=0, off;
-       struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
-
-#ifdef CONFIG_PM
-       au1xxx_pm_access(LCD_pm_dev);
-#endif
+       struct au1200fb_device *fbdev = info->par;
 
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
                return -EINVAL;
@@ -1461,10 +1431,6 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
        int plane;
        int val;
 
-#ifdef CONFIG_PM
-       au1xxx_pm_access(LCD_pm_dev);
-#endif
-
        plane = fbinfo2index(info);
        print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
 
@@ -1536,9 +1502,11 @@ static struct fb_ops au1200fb_fb_ops = {
        .fb_set_par     = au1200fb_fb_set_par,
        .fb_setcolreg   = au1200fb_fb_setcolreg,
        .fb_blank       = au1200fb_fb_blank,
-       .fb_fillrect    = cfb_fillrect,
-       .fb_copyarea    = cfb_copyarea,
-       .fb_imageblit   = cfb_imageblit,
+       .fb_fillrect    = sys_fillrect,
+       .fb_copyarea    = sys_copyarea,
+       .fb_imageblit   = sys_imageblit,
+       .fb_read        = fb_sys_read,
+       .fb_write       = fb_sys_write,
        .fb_sync        = NULL,
        .fb_ioctl       = au1200fb_ioctl,
        .fb_mmap        = au1200fb_fb_mmap,
@@ -1561,10 +1529,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
 
 static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
 {
-       struct fb_info *fbi = &fbdev->fb_info;
+       struct fb_info *fbi = fbdev->fb_info;
        int bpp;
 
-       memset(fbi, 0, sizeof(struct fb_info));
        fbi->fbops = &au1200fb_fb_ops;
 
        bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
@@ -1623,24 +1590,36 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
 
 /* AU1200 LCD controller device driver */
 
-static int au1200fb_drv_probe(struct platform_device *dev)
+static int __devinit au1200fb_drv_probe(struct platform_device *dev)
 {
        struct au1200fb_device *fbdev;
+       struct fb_info *fbi = NULL;
        unsigned long page;
-       int bpp, plane, ret;
+       int bpp, plane, ret, irq;
 
-       if (!dev)
-               return -EINVAL;
+       /* shut gcc up */
+       ret = 0;
+       fbdev = NULL;
+
+       /* Kickstart the panel */
+       au1200_setpanel(panel);
 
-       for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
+       for (plane = 0; plane < device_count; ++plane) {
                bpp = winbpp(win->w[plane].mode_winctrl1);
                if (win->w[plane].xres == 0)
                        win->w[plane].xres = panel->Xres;
                if (win->w[plane].yres == 0)
                        win->w[plane].yres = panel->Yres;
 
-               fbdev = &_au1200fb_devices[plane];
-               memset(fbdev, 0, sizeof(struct au1200fb_device));
+               fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
+                                       &dev->dev);
+               if (!fbi)
+                       goto failed;
+
+               _au1200fb_infos[plane] = fbi;
+               fbdev = fbi->par;
+               fbdev->fb_info = fbi;
+
                fbdev->plane = plane;
 
                /* Allocate the framebuffer to the maximum screen size */
@@ -1673,30 +1652,31 @@ static int au1200fb_drv_probe(struct platform_device *dev)
                        goto failed;
 
                /* Register new framebuffer */
-               if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
+               ret = register_framebuffer(fbi);
+               if (ret < 0) {
                        print_err("cannot register new framebuffer");
                        goto failed;
                }
 
-               au1200fb_fb_set_par(&fbdev->fb_info);
+               au1200fb_fb_set_par(fbi);
 
 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
                if (plane == 0)
-                       if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
+                       if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
                                /* Start display and show logo on boot */
-                               fb_set_cmap(&fbdev->fb_info.cmap,
-                                               &fbdev->fb_info);
-
-                               fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
+                               fb_set_cmap(&fbi->cmap, fbi);
+                               fb_show_logo(fbi, FB_ROTATE_UR);
                        }
 #endif
        }
 
        /* Now hook interrupt too */
-       if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
-                         IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) {
+       irq = platform_get_irq(dev, 0);
+       ret = request_irq(irq, au1200fb_handle_irq,
+                         IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev);
+       if (ret) {
                print_err("fail to request interrupt line %d (err: %d)",
-                         AU1200_LCD_INT, ret);
+                         irq, ret);
                goto failed;
        }
 
@@ -1705,84 +1685,108 @@ static int au1200fb_drv_probe(struct platform_device *dev)
 failed:
        /* NOTE: This only does the current plane/window that failed; others are still active */
        if (fbdev->fb_mem)
-               dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
+               dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
                                fbdev->fb_mem, fbdev->fb_phys);
-       if (fbdev->fb_info.cmap.len != 0)
-               fb_dealloc_cmap(&fbdev->fb_info.cmap);
-       if (fbdev->fb_info.pseudo_palette)
-               kfree(fbdev->fb_info.pseudo_palette);
+       if (fbi) {
+               if (fbi->cmap.len != 0)
+                       fb_dealloc_cmap(&fbi->cmap);
+               kfree(fbi->pseudo_palette);
+       }
        if (plane == 0)
                free_irq(AU1200_LCD_INT, (void*)dev);
        return ret;
 }
 
-static int au1200fb_drv_remove(struct platform_device *dev)
+static int __devexit au1200fb_drv_remove(struct platform_device *dev)
 {
        struct au1200fb_device *fbdev;
+       struct fb_info *fbi;
        int plane;
 
-       if (!dev)
-               return -ENODEV;
-
        /* Turn off the panel */
        au1200_setpanel(NULL);
 
-       for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
-       {
-               fbdev = &_au1200fb_devices[plane];
+       for (plane = 0; plane < device_count; ++plane)  {
+               fbi = _au1200fb_infos[plane];
+               fbdev = fbi->par;
 
                /* Clean up all probe data */
-               unregister_framebuffer(&fbdev->fb_info);
+               unregister_framebuffer(fbi);
                if (fbdev->fb_mem)
                        dma_free_noncoherent(&dev->dev,
                                        PAGE_ALIGN(fbdev->fb_len),
                                        fbdev->fb_mem, fbdev->fb_phys);
-               if (fbdev->fb_info.cmap.len != 0)
-                       fb_dealloc_cmap(&fbdev->fb_info.cmap);
-               if (fbdev->fb_info.pseudo_palette)
-                       kfree(fbdev->fb_info.pseudo_palette);
+               if (fbi->cmap.len != 0)
+                       fb_dealloc_cmap(&fbi->cmap);
+               kfree(fbi->pseudo_palette);
+
+               framebuffer_release(fbi);
+               _au1200fb_infos[plane] = NULL;
        }
 
-       free_irq(AU1200_LCD_INT, (void *)dev);
+       free_irq(platform_get_irq(dev, 0), (void *)dev);
 
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
+static int au1200fb_drv_suspend(struct device *dev)
 {
-       /* TODO */
+       au1200_setpanel(NULL);
+
+       lcd->outmask = 0;
+       au_sync();
+
        return 0;
 }
 
-static int au1200fb_drv_resume(struct platform_device *dev)
+static int au1200fb_drv_resume(struct device *dev)
 {
-       /* TODO */
+       struct fb_info *fbi;
+       int i;
+
+       /* Kickstart the panel */
+       au1200_setpanel(panel);
+
+       for (i = 0; i < device_count; i++) {
+               fbi = _au1200fb_infos[i];
+               au1200fb_fb_set_par(fbi);
+       }
+
        return 0;
 }
+
+static const struct dev_pm_ops au1200fb_pmops = {
+       .suspend        = au1200fb_drv_suspend,
+       .resume         = au1200fb_drv_resume,
+       .freeze         = au1200fb_drv_suspend,
+       .thaw           = au1200fb_drv_resume,
+};
+
+#define AU1200FB_PMOPS (&au1200fb_pmops)
+
+#else
+#define AU1200FB_PMOPS NULL
 #endif /* CONFIG_PM */
 
 static struct platform_driver au1200fb_driver = {
        .driver = {
-               .name           = "au1200-lcd",
-               .owner          = THIS_MODULE,
+               .name   = "au1200-lcd",
+               .owner  = THIS_MODULE,
+               .pm     = AU1200FB_PMOPS,
        },
        .probe          = au1200fb_drv_probe,
-       .remove         = au1200fb_drv_remove,
-#ifdef CONFIG_PM
-       .suspend        = au1200fb_drv_suspend,
-       .resume         = au1200fb_drv_resume,
-#endif
+       .remove         = __devexit_p(au1200fb_drv_remove),
 };
 
 /*-------------------------------------------------------------------------*/
 
 /* Kernel driver */
 
-static void au1200fb_setup(void)
+static int au1200fb_setup(void)
 {
-       charoptions = NULL;
-       char* this_opt;
+       char *options = NULL;
+       char *this_opt, *endptr;
        int num_panels = ARRAY_SIZE(known_lcd_panels);
        int panel_idx = -1;
 
@@ -1827,70 +1831,42 @@ static void au1200fb_setup(void)
                                nohwcursor = 1;
                        }
 
-                       /* Unsupported option */
-                       else {
-                               print_warn("Unsupported option \"%s\"", this_opt);
+                       else if (strncmp(this_opt, "devices:", 8) == 0) {
+                               this_opt += 8;
+                               device_count = simple_strtol(this_opt,
+                                                            &endptr, 0);
+                               if ((device_count < 0) ||
+                                   (device_count > MAX_DEVICE_COUNT))
+                                       device_count = MAX_DEVICE_COUNT;
                        }
-               }
-       }
-}
 
-#ifdef CONFIG_PM
-static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
-               au1xxx_request_t request, void *data) {
-       int retval = -1;
-       unsigned int d = 0;
-       unsigned int brightness = 0;
-
-       if (request == AU1XXX_PM_SLEEP) {
-               board_au1200fb_panel_shutdown();
-       }
-       else if (request == AU1XXX_PM_WAKEUP) {
-               if(dev->prev_state == SLEEP_STATE)
-               {
-                       int plane;
-                       au1200_setpanel(panel);
-                       for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)         {
-                               struct au1200fb_device *fbdev;
-                               fbdev = &_au1200fb_devices[plane];
-                               au1200fb_fb_set_par(&fbdev->fb_info);
+                       else if (strncmp(this_opt, "wincfg:", 7) == 0) {
+                               this_opt += 7;
+                               window_index = simple_strtol(this_opt,
+                                                            &endptr, 0);
+                               if ((window_index < 0) ||
+                                   (window_index >= ARRAY_SIZE(windows)))
+                                       window_index = DEFAULT_WINDOW_INDEX;
                        }
-               }
 
-               d = *((unsigned int*)data);
-               if(d <=10) brightness = 26;
-               else if(d<=20) brightness = 51;
-               else if(d<=30) brightness = 77;
-               else if(d<=40) brightness = 102;
-               else if(d<=50) brightness = 128;
-               else if(d<=60) brightness = 153;
-               else if(d<=70) brightness = 179;
-               else if(d<=80) brightness = 204;
-               else if(d<=90) brightness = 230;
-               else brightness = 255;
-               set_brightness(brightness);
-       } else if (request == AU1XXX_PM_GETSTATUS) {
-               return dev->cur_state;
-       } else if (request == AU1XXX_PM_ACCESS) {
-               if (dev->cur_state != SLEEP_STATE)
-                       return retval;
-               else {
-                       au1200_setpanel(panel);
+                       else if (strncmp(this_opt, "off", 3) == 0)
+                               return 1;
+                       /* Unsupported option */
+                       else {
+                               print_warn("Unsupported option \"%s\"", this_opt);
+                       }
                }
-       } else if (request == AU1XXX_PM_IDLE) {
-       } else if (request == AU1XXX_PM_CLEANUP) {
        }
-
-       return retval;
+       return 0;
 }
-#endif
 
 static int __init au1200fb_init(void)
 {
        print_info("" DRIVER_DESC "");
 
        /* Setup driver with options */
-       au1200fb_setup();
+       if (au1200fb_setup())
+               return -ENODEV;
 
        /* Point to the panel selected */
        panel = &known_lcd_panels[panel_index];
@@ -1899,17 +1875,6 @@ static int __init au1200fb_init(void)
        printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
        printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
 
-       /* Kickstart the panel, the framebuffers/windows come soon enough */
-       au1200_setpanel(panel);
-
-       #ifdef CONFIG_PM
-       LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
-       if ( LCD_pm_dev == NULL)
-               printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
-       else
-               printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
-       #endif
-
        return platform_driver_register(&au1200fb_driver);
 }
 
index d2a96a421ffda737048ea7e30169ecfbb9a71d65..24a6dfd21b35f377d16e50426d3bef6cd95f6306 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pm.h>
index 05a8832bb3eb360d2d835e5281323d978d078500..383c4c364b5fd3d92c9469852b0cf156f4b9a5b6 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pm.h>
index c225dcce89e78f083f0e02c60b3064b29d001748..f6944019cb66e6745d266c54fb49f79123d50af0 100644 (file)
@@ -550,7 +550,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
 
 
 /*
- * Parse user speficied options (`video=controlfb:')
+ * Parse user specified options (`video=controlfb:')
  */
 static void __init control_setup(char *options)
 {
index fcdac872522d66702e0035bfda682ae189547eec..217c05f745416a81442702cb5857851dcbb58e2d 100644 (file)
@@ -35,6 +35,9 @@
 
 #define DRIVER_NAME "da8xx_lcdc"
 
+#define LCD_VERSION_1  1
+#define LCD_VERSION_2  2
+
 /* LCD Status Register */
 #define LCD_END_OF_FRAME1              BIT(9)
 #define LCD_END_OF_FRAME0              BIT(8)
@@ -49,7 +52,9 @@
 #define LCD_DMA_BURST_4                        0x2
 #define LCD_DMA_BURST_8                        0x3
 #define LCD_DMA_BURST_16               0x4
-#define LCD_END_OF_FRAME_INT_ENA       BIT(2)
+#define LCD_V1_END_OF_FRAME_INT_ENA    BIT(2)
+#define LCD_V2_END_OF_FRAME0_INT_ENA   BIT(8)
+#define LCD_V2_END_OF_FRAME1_INT_ENA   BIT(9)
 #define LCD_DUAL_FRAME_BUFFER_ENABLE   BIT(0)
 
 /* LCD Control Register */
 #define LCD_MONO_8BIT_MODE             BIT(9)
 #define LCD_RASTER_ORDER               BIT(8)
 #define LCD_TFT_MODE                   BIT(7)
-#define LCD_UNDERFLOW_INT_ENA          BIT(6)
-#define LCD_PL_ENABLE                  BIT(4)
+#define LCD_V1_UNDERFLOW_INT_ENA       BIT(6)
+#define LCD_V2_UNDERFLOW_INT_ENA       BIT(5)
+#define LCD_V1_PL_INT_ENA              BIT(4)
+#define LCD_V2_PL_INT_ENA              BIT(6)
 #define LCD_MONOCHROME_MODE            BIT(1)
 #define LCD_RASTER_ENABLE              BIT(0)
 #define LCD_TFT_ALT_ENABLE             BIT(23)
 #define LCD_STN_565_ENABLE             BIT(24)
+#define LCD_V2_DMA_CLK_EN              BIT(2)
+#define LCD_V2_LIDD_CLK_EN             BIT(1)
+#define LCD_V2_CORE_CLK_EN             BIT(0)
+#define LCD_V2_LPP_B10                 26
 
 /* LCD Raster Timing 2 Register */
 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)     ((x) << 16)
@@ -82,6 +93,7 @@
 #define LCD_INVERT_FRAME_CLOCK                 BIT(20)
 
 /* LCD Block */
+#define  LCD_PID_REG                           0x0
 #define  LCD_CTRL_REG                          0x4
 #define  LCD_STAT_REG                          0x8
 #define  LCD_RASTER_CTRL_REG                   0x28
 #define  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG       0x4C
 #define  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG    0x50
 
+/* Interrupt Registers available only in Version 2 */
+#define  LCD_RAW_STAT_REG                      0x58
+#define  LCD_MASKED_STAT_REG                   0x5c
+#define  LCD_INT_ENABLE_SET_REG                        0x60
+#define  LCD_INT_ENABLE_CLR_REG                        0x64
+#define  LCD_END_OF_INT_IND_REG                        0x68
+
+/* Clock registers available only on Version 2 */
+#define  LCD_CLK_ENABLE_REG                    0x6c
+#define  LCD_CLK_RESET_REG                     0x70
+
 #define LCD_NUM_BUFFERS        2
 
 #define WSI_TIMEOUT    50
 
 static resource_size_t da8xx_fb_reg_base;
 static struct resource *lcdc_regs;
+static unsigned int lcd_revision;
+static irq_handler_t lcdc_irq_handler;
 
 static inline unsigned int lcdc_read(unsigned int addr)
 {
@@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
        u32 end;
        u32 reg_ras;
        u32 reg_dma;
+       u32 reg_int;
 
        /* init reg to clear PLM (loading mode) fields */
        reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
@@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
                end      = par->dma_end;
 
                reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
-               reg_dma |= LCD_END_OF_FRAME_INT_ENA;
+               if (lcd_revision == LCD_VERSION_1) {
+                       reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
+               } else {
+                       reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+                               LCD_V2_END_OF_FRAME0_INT_ENA |
+                               LCD_V2_END_OF_FRAME1_INT_ENA;
+                       lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+               }
                reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
 
                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
@@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
                end      = start + par->palette_sz - 1;
 
                reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
-               reg_ras |= LCD_PL_ENABLE;
+
+               if (lcd_revision == LCD_VERSION_1) {
+                       reg_ras |= LCD_V1_PL_INT_ENA;
+               } else {
+                       reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+                               LCD_V2_PL_INT_ENA;
+                       lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+               }
 
                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
                lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
@@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
 static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 {
        u32 reg;
+       u32 reg_int;
 
        reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
                                                LCD_MONO_8BIT_MODE |
@@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
        }
 
        /* enable additional interrupts here */
-       reg |= LCD_UNDERFLOW_INT_ENA;
+       if (lcd_revision == LCD_VERSION_1) {
+               reg |= LCD_V1_UNDERFLOW_INT_ENA;
+       } else {
+               reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+                       LCD_V2_UNDERFLOW_INT_ENA;
+               lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+       }
 
        lcdc_write(reg, LCD_RASTER_CTRL_REG);
 
@@ -511,6 +558,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
        /* DMA has to be disabled */
        lcdc_write(0, LCD_DMA_CTRL_REG);
        lcdc_write(0, LCD_RASTER_CTRL_REG);
+
+       if (lcd_revision == LCD_VERSION_2)
+               lcdc_write(0, LCD_INT_ENABLE_SET_REG);
 }
 
 static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
@@ -523,6 +573,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
        /* Configure the LCD clock divisor. */
        lcdc_write(LCD_CLK_DIVISOR(div) |
                        (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
+
+       if (lcd_revision == LCD_VERSION_2)
+               lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
+                               LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+
 }
 
 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -583,7 +638,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
        return 0;
 }
 
-static irqreturn_t lcdc_irq_handler(int irq, void *arg)
+/* IRQ handler for version 2 of LCDC */
+static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
+{
+       struct da8xx_fb_par *par = arg;
+       u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
+       u32 reg_int;
+
+       if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
+               lcd_disable_raster();
+               lcdc_write(stat, LCD_MASKED_STAT_REG);
+               lcd_enable_raster();
+       } else if (stat & LCD_PL_LOAD_DONE) {
+               /*
+                * Must disable raster before changing state of any control bit.
+                * And also must be disabled before clearing the PL loading
+                * interrupt via the following write to the status register. If
+                * this is done after then one gets multiple PL done interrupts.
+                */
+               lcd_disable_raster();
+
+               lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+               /* Disable PL completion inerrupt */
+               reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
+                      (LCD_V2_PL_INT_ENA);
+               lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
+
+               /* Setup and start data loading mode */
+               lcd_blit(LOAD_DATA, par);
+       } else {
+               lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+               if (stat & LCD_END_OF_FRAME0) {
+                       lcdc_write(par->dma_start,
+                                  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+                       lcdc_write(par->dma_end,
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
+               }
+
+               if (stat & LCD_END_OF_FRAME1) {
+                       lcdc_write(par->dma_start,
+                                  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+                       lcdc_write(par->dma_end,
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
+               }
+       }
+
+       lcdc_write(0, LCD_END_OF_INT_IND_REG);
+       return IRQ_HANDLED;
+}
+
+/* IRQ handler for version 1 LCDC */
+static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
 {
        struct da8xx_fb_par *par = arg;
        u32 stat = lcdc_read(LCD_STAT_REG);
@@ -606,7 +717,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
 
                /* Disable PL completion inerrupt */
                reg_ras  = lcdc_read(LCD_RASTER_CTRL_REG);
-               reg_ras &= ~LCD_PL_ENABLE;
+               reg_ras &= ~LCD_V1_PL_INT_ENA;
                lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
 
                /* Setup and start data loading mode */
@@ -877,8 +988,8 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
 
                        start   = fix->smem_start +
                                new_var.yoffset * fix->line_length +
-                               new_var.xoffset * var->bits_per_pixel / 8;
-                       end     = start + var->yres * fix->line_length - 1;
+                               new_var.xoffset * fbi->var.bits_per_pixel / 8;
+                       end     = start + fbi->var.yres * fix->line_length - 1;
                        par->dma_start  = start;
                        par->dma_end    = end;
                }
@@ -945,6 +1056,22 @@ static int __devinit fb_probe(struct platform_device *device)
        if (ret)
                goto err_clk_put;
 
+       /* Determine LCD IP Version */
+       switch (lcdc_read(LCD_PID_REG)) {
+       case 0x4C100102:
+               lcd_revision = LCD_VERSION_1;
+               break;
+       case 0x4F200800:
+               lcd_revision = LCD_VERSION_2;
+               break;
+       default:
+               dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
+                               "defaulting to LCD revision 1\n",
+                               lcdc_read(LCD_PID_REG));
+               lcd_revision = LCD_VERSION_1;
+               break;
+       }
+
        for (i = 0, lcdc_info = known_lcd_panels;
                i < ARRAY_SIZE(known_lcd_panels);
                i++, lcdc_info++) {
@@ -1085,7 +1212,13 @@ static int __devinit fb_probe(struct platform_device *device)
        }
 #endif
 
-       ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+       if (lcd_revision == LCD_VERSION_1)
+               lcdc_irq_handler = lcdc_irq_handler_rev01;
+       else
+               lcdc_irq_handler = lcdc_irq_handler_rev02;
+
+       ret = request_irq(par->irq, lcdc_irq_handler, 0,
+                       DRIVER_NAME, par);
        if (ret)
                goto irq_freq;
        return 0;
index 27f2c57e06e9f0225f8132f5a93ce7022ba81183..60a787fa32cfe97ddc8cdbb2999492e4da99144d 100644 (file)
@@ -624,8 +624,8 @@ static int unifb_pan_display(struct fb_var_screeninfo *var,
                    || var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual ||
-                   var->yoffset + var->yres > info->var.yres_virtual)
+               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+                   var->yoffset + info->var.yres > info->var.yres_virtual)
                        return -EINVAL;
        }
        info->var.xoffset = var->xoffset;
index 804000183c5e8900e69aa6c1748efa106e312690..a79c0dedfbd466147bad92735c297205a2895108 100644 (file)
@@ -216,8 +216,7 @@ void fb_deferred_io_cleanup(struct fb_info *info)
        int i;
 
        BUG_ON(!fbdefio);
-       cancel_delayed_work(&info->deferred_work);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&info->deferred_work);
 
        /* clear out the mapping that we setup */
        for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
index 0acc7d65aeaade67e5ce3d1188d030d5d842d159..0f1933b5459659c98ed56dabc6848954ad557fb5 100644 (file)
@@ -31,8 +31,6 @@
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
 
-#include <linux/of_platform.h>
-
 #include <sysdev/fsl_soc.h>
 #include <linux/fsl-diu-fb.h>
 #include "edid.h"
@@ -183,7 +181,8 @@ static struct fb_videomode __devinitdata fsl_diu_mode_db[] = {
 
 static char *fb_mode = "1024x768-32@60";
 static unsigned long default_bpp = 32;
-static int monitor_port;
+static enum fsl_diu_monitor_port monitor_port;
+static char *monitor_string;
 
 #if defined(CONFIG_NOT_COHERENT_CACHE)
 static u8 *coherence_data;
@@ -201,7 +200,7 @@ struct fsl_diu_data {
        void *dummy_aoi_virt;
        unsigned int irq;
        int fb_enabled;
-       int monitor_port;
+       enum fsl_diu_monitor_port monitor_port;
 };
 
 struct mfb_info {
@@ -281,6 +280,37 @@ static struct diu_hw dr = {
 
 static struct diu_pool pool;
 
+/**
+ * fsl_diu_name_to_port - convert a port name to a monitor port enum
+ *
+ * Takes the name of a monitor port ("dvi", "lvds", or "dlvds") and returns
+ * the enum fsl_diu_monitor_port that corresponds to that string.
+ *
+ * For compatibility with older versions, a number ("0", "1", or "2") is also
+ * supported.
+ *
+ * If the string is unknown, DVI is assumed.
+ *
+ * If the particular port is not supported by the platform, another port
+ * (platform-specific) is chosen instead.
+ */
+static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
+{
+       enum fsl_diu_monitor_port port = FSL_DIU_PORT_DVI;
+       unsigned long val;
+
+       if (s) {
+               if (!strict_strtoul(s, 10, &val) && (val <= 2))
+                       port = (enum fsl_diu_monitor_port) val;
+               else if (strncmp(s, "lvds", 4) == 0)
+                       port = FSL_DIU_PORT_LVDS;
+               else if (strncmp(s, "dlvds", 5) == 0)
+                       port = FSL_DIU_PORT_DLVDS;
+       }
+
+       return diu_ops.valid_monitor_port(port);
+}
+
 /**
  * fsl_diu_alloc - allocate memory for the DIU
  * @size: number of bytes to allocate
@@ -831,9 +861,8 @@ static int fsl_diu_set_par(struct fb_info *info)
                }
        }
 
-       ad->pix_fmt =
-               diu_ops.get_pixel_format(var->bits_per_pixel,
-                                        machine_data->monitor_port);
+       ad->pix_fmt = diu_ops.get_pixel_format(machine_data->monitor_port,
+                                              var->bits_per_pixel);
        ad->addr    = cpu_to_le32(info->fix.smem_start);
        ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
                                var->xres_virtual) | mfbi->g_alpha;
@@ -1439,16 +1468,12 @@ static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
 static ssize_t store_monitor(struct device *device,
        struct device_attribute *attr, const char *buf, size_t count)
 {
-       int old_monitor_port;
-       unsigned long val;
+       enum fsl_diu_monitor_port old_monitor_port;
        struct fsl_diu_data *machine_data =
                container_of(attr, struct fsl_diu_data, dev_attr);
 
-       if (strict_strtoul(buf, 10, &val))
-               return 0;
-
        old_monitor_port = machine_data->monitor_port;
-       machine_data->monitor_port = diu_ops.set_sysfs_monitor_port(val);
+       machine_data->monitor_port = fsl_diu_name_to_port(buf);
 
        if (old_monitor_port != machine_data->monitor_port) {
                /* All AOIs need adjust pixel format
@@ -1468,7 +1493,17 @@ static ssize_t show_monitor(struct device *device,
 {
        struct fsl_diu_data *machine_data =
                container_of(attr, struct fsl_diu_data, dev_attr);
-       return diu_ops.show_monitor_port(machine_data->monitor_port, buf);
+
+       switch (machine_data->monitor_port) {
+       case FSL_DIU_PORT_DVI:
+               return sprintf(buf, "DVI\n");
+       case FSL_DIU_PORT_LVDS:
+               return sprintf(buf, "Single-link LVDS\n");
+       case FSL_DIU_PORT_DLVDS:
+               return sprintf(buf, "Dual-link LVDS\n");
+       }
+
+       return 0;
 }
 
 static int __devinit fsl_diu_probe(struct platform_device *ofdev)
@@ -1692,8 +1727,7 @@ static int __init fsl_diu_setup(char *options)
                if (!*opt)
                        continue;
                if (!strncmp(opt, "monitor=", 8)) {
-                       if (!strict_strtoul(opt + 8, 10, &val) && (val <= 2))
-                               monitor_port = val;
+                       monitor_port = fsl_diu_name_to_port(opt + 8);
                } else if (!strncmp(opt, "bpp=", 4)) {
                        if (!strict_strtoul(opt + 4, 10, &val))
                                default_bpp = val;
@@ -1746,6 +1780,8 @@ static int __init fsl_diu_init(void)
        if (fb_get_options("fslfb", &option))
                return -ENODEV;
        fsl_diu_setup(option);
+#else
+       monitor_port = fsl_diu_name_to_port(monitor_string);
 #endif
        printk(KERN_INFO "Freescale DIU driver\n");
 
@@ -1812,7 +1848,7 @@ MODULE_PARM_DESC(mode,
        "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
 module_param_named(bpp, default_bpp, ulong, 0);
 MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
-module_param_named(monitor, monitor_port, int, 0);
-MODULE_PARM_DESC(monitor,
-       "Specify the monitor port (0, 1 or 2) if supported by the platform");
+module_param_named(monitor, monitor_string, charp, 0);
+MODULE_PARM_DESC(monitor, "Specify the monitor port "
+       "(\"dvi\", \"lvds\", or \"dlvds\") if supported by the platform");
 
index d662317d85e30fb01782b29f0bb681d327b766df..223896cc5f7d66713f98db315ada5ab364fc7d2b 100644 (file)
@@ -149,10 +149,11 @@ int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 static int g364fb_pan_display(struct fb_var_screeninfo *var, 
                              struct fb_info *info)
 {
-       if (var->xoffset || var->yoffset + var->yres > var->yres_virtual)
+       if (var->xoffset ||
+           var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
 
-       *(unsigned int *) TOP_REG = var->yoffset * var->xres;
+       *(unsigned int *) TOP_REG = var->yoffset * info->var.xres;
        return 0;
 }
 
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
new file mode 100644 (file)
index 0000000..f37e025
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+ * Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
+ *
+ * 2011 (c) Aeroflex Gaisler AB
+ *
+ * Full documentation of the core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+
+struct grvga_regs {
+       u32 status;             /* 0x00 */
+       u32 video_length;       /* 0x04 */
+       u32 front_porch;        /* 0x08 */
+       u32 sync_length;        /* 0x0C */
+       u32 line_length;        /* 0x10 */
+       u32 fb_pos;             /* 0x14 */
+       u32 clk_vector[4];      /* 0x18 */
+       u32 clut;               /* 0x20 */
+};
+
+struct grvga_par {
+       struct grvga_regs *regs;
+       u32 color_palette[16];  /* 16 entry pseudo palette used by fbcon in true color mode */
+       int clk_sel;
+       int fb_alloced;         /* = 1 if framebuffer is allocated in main memory */
+};
+
+
+static const struct fb_videomode grvga_modedb[] = {
+    {
+       /* 640x480 @ 60 Hz */
+       NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
+       0, FB_VMODE_NONINTERLACED
+    }, {
+       /* 800x600 @ 60 Hz */
+       NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
+       0, FB_VMODE_NONINTERLACED
+    }, {
+       /* 800x600 @ 72 Hz */
+       NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
+       0, FB_VMODE_NONINTERLACED
+    }, {
+       /* 1024x768 @ 60 Hz */
+       NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
+       0, FB_VMODE_NONINTERLACED
+    }
+ };
+
+static struct fb_fix_screeninfo grvga_fix __initdata = {
+       .id =           "AG SVGACTRL",
+       .type =         FB_TYPE_PACKED_PIXELS,
+       .visual =       FB_VISUAL_PSEUDOCOLOR,
+       .xpanstep =     0,
+       .ypanstep =     1,
+       .ywrapstep =    0,
+       .accel =        FB_ACCEL_NONE,
+};
+
+static int grvga_check_var(struct fb_var_screeninfo *var,
+                          struct fb_info *info)
+{
+       struct grvga_par *par = info->par;
+       int i;
+
+       if (!var->xres)
+               var->xres = 1;
+       if (!var->yres)
+               var->yres = 1;
+       if (var->bits_per_pixel <= 8)
+               var->bits_per_pixel = 8;
+       else if (var->bits_per_pixel <= 16)
+               var->bits_per_pixel = 16;
+       else if (var->bits_per_pixel <= 24)
+               var->bits_per_pixel = 24;
+       else if (var->bits_per_pixel <= 32)
+               var->bits_per_pixel = 32;
+       else
+               return -EINVAL;
+
+       var->xres_virtual = var->xres;
+       var->yres_virtual = 2*var->yres;
+
+       if (info->fix.smem_len) {
+               if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
+                       return -ENOMEM;
+       }
+
+       /* Which clocks that are available can be read out in these registers */
+       for (i = 0; i <= 3 ; i++) {
+               if (var->pixclock == par->regs->clk_vector[i])
+                       break;
+       }
+       if (i <= 3)
+               par->clk_sel = i;
+       else
+               return -EINVAL;
+
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               var->red   = (struct fb_bitfield) {0, 8, 0};      /* offset, length, msb-right */
+               var->green = (struct fb_bitfield) {0, 8, 0};
+               var->blue  = (struct fb_bitfield) {0, 8, 0};
+               var->transp = (struct fb_bitfield) {0, 0, 0};
+               break;
+       case 16:
+               var->red   = (struct fb_bitfield) {11, 5, 0};
+               var->green = (struct fb_bitfield) {5, 6, 0};
+               var->blue  = (struct fb_bitfield) {0, 5, 0};
+               var->transp = (struct fb_bitfield) {0, 0, 0};
+               break;
+       case 24:
+       case 32:
+               var->red   = (struct fb_bitfield) {16, 8, 0};
+               var->green = (struct fb_bitfield) {8, 8, 0};
+               var->blue  = (struct fb_bitfield) {0, 8, 0};
+               var->transp = (struct fb_bitfield) {24, 8, 0};
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int grvga_set_par(struct fb_info *info)
+{
+
+       u32 func = 0;
+       struct grvga_par *par = info->par;
+
+       __raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
+                    &par->regs->video_length);
+
+       __raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
+                    &par->regs->front_porch);
+
+       __raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
+                    &par->regs->sync_length);
+
+       __raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
+                    (info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
+                    &par->regs->line_length);
+
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+               func = 1;
+               break;
+       case 16:
+               info->fix.visual = FB_VISUAL_TRUECOLOR;
+               func = 2;
+               break;
+       case 24:
+       case 32:
+               info->fix.visual = FB_VISUAL_TRUECOLOR;
+               func = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       __raw_writel((par->clk_sel << 6) | (func << 4) | 1,
+                    &par->regs->status);
+
+       info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
+       return 0;
+}
+
+static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
+{
+       struct grvga_par *par;
+       par = info->par;
+
+       if (regno >= 256)       /* Size of CLUT */
+               return -EINVAL;
+
+       if (info->var.grayscale) {
+               /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+               red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+       }
+
+
+
+#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
+
+       red    = CNVT_TOHW(red,   info->var.red.length);
+       green  = CNVT_TOHW(green, info->var.green.length);
+       blue   = CNVT_TOHW(blue,  info->var.blue.length);
+       transp = CNVT_TOHW(transp, info->var.transp.length);
+
+#undef CNVT_TOHW
+
+       /* In PSEUDOCOLOR we use the hardware CLUT */
+       if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
+               __raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
+                            &par->regs->clut);
+
+       /* Truecolor uses the pseudo palette */
+       else if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+               u32 v;
+               if (regno >= 16)
+                       return -EINVAL;
+
+
+               v =     (red    << info->var.red.offset)   |
+                       (green  << info->var.green.offset) |
+                       (blue   << info->var.blue.offset)  |
+                       (transp << info->var.transp.offset);
+
+               ((u32 *) (info->pseudo_palette))[regno] = v;
+       }
+       return 0;
+}
+
+static int grvga_pan_display(struct fb_var_screeninfo *var,
+                            struct fb_info *info)
+{
+       struct grvga_par *par = info->par;
+       struct fb_fix_screeninfo *fix = &info->fix;
+       u32 base_addr;
+
+       if (var->xoffset != 0)
+               return -EINVAL;
+
+       base_addr = fix->smem_start + (var->yoffset * fix->line_length);
+       base_addr &= ~3UL;
+
+       /* Set framebuffer base address  */
+       __raw_writel(base_addr,
+                    &par->regs->fb_pos);
+
+       return 0;
+}
+
+static struct fb_ops grvga_ops = {
+       .owner          = THIS_MODULE,
+       .fb_check_var   = grvga_check_var,
+       .fb_set_par     = grvga_set_par,
+       .fb_setcolreg   = grvga_setcolreg,
+       .fb_pan_display = grvga_pan_display,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit
+};
+
+static int __init grvga_parse_custom(char *options,
+                                    struct fb_var_screeninfo *screendata)
+{
+       char *this_opt;
+       int count = 0;
+       if (!options || !*options)
+               return -1;
+
+       while ((this_opt = strsep(&options, " ")) != NULL) {
+               if (!*this_opt)
+                       continue;
+
+               switch (count) {
+               case 0:
+                       screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 1:
+                       screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 2:
+                       screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 3:
+                       screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 4:
+                       screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 5:
+                       screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 6:
+                       screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 7:
+                       screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 8:
+                       screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 9:
+                       screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               default:
+                       return -1;
+               }
+       }
+       screendata->activate  = FB_ACTIVATE_NOW;
+       screendata->vmode     = FB_VMODE_NONINTERLACED;
+       return 0;
+}
+
+static int __devinit grvga_probe(struct platform_device *dev)
+{
+       struct fb_info *info;
+       int retval = -ENOMEM;
+       unsigned long virtual_start;
+       unsigned long grvga_fix_addr = 0;
+       unsigned long physical_start = 0;
+       unsigned long grvga_mem_size = 0;
+       struct grvga_par *par = NULL;
+       char *options = NULL, *mode_opt = NULL;
+
+       info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
+       if (!info) {
+               dev_err(&dev->dev, "framebuffer_alloc failed\n");
+               return -ENOMEM;
+       }
+
+       /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
+        *
+        * If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
+        * If address is left out, we allocate memory,
+        * if size is left out we only allocate enough to support the given mode.
+        */
+       if (fb_get_options("grvga", &options)) {
+               retval = -ENODEV;
+               goto err;
+       }
+
+       if (!options || !*options)
+               options =  "640x480-8@60";
+
+       while (1) {
+               char *this_opt = strsep(&options, ",");
+
+               if (!this_opt)
+                       break;
+
+               if (!strncmp(this_opt, "custom", 6)) {
+                       if (grvga_parse_custom(this_opt, &info->var) < 0) {
+                               dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
+                               retval = -EINVAL;
+                               goto err1;
+                       }
+               } else if (!strncmp(this_opt, "addr", 4))
+                       grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
+               else if (!strncmp(this_opt, "size", 4))
+                       grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
+               else
+                       mode_opt = this_opt;
+       }
+
+       par = info->par;
+       info->fbops = &grvga_ops;
+       info->fix = grvga_fix;
+       info->pseudo_palette = par->color_palette;
+       info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
+       info->fix.smem_len = grvga_mem_size;
+
+       if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
+               dev_err(&dev->dev, "registers already mapped\n");
+               retval = -EBUSY;
+               goto err;
+       }
+
+       par->regs = of_ioremap(&dev->resource[0], 0,
+                              resource_size(&dev->resource[0]),
+                              "grlib-svgactrl regs");
+
+       if (!par->regs) {
+               dev_err(&dev->dev, "failed to map registers\n");
+               retval = -ENOMEM;
+               goto err1;
+       }
+
+       retval = fb_alloc_cmap(&info->cmap, 256, 0);
+       if (retval < 0) {
+               dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
+               retval = -ENOMEM;
+               goto err2;
+       }
+
+       if (mode_opt) {
+               retval = fb_find_mode(&info->var, info, mode_opt,
+                                     grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
+               if (!retval || retval == 4) {
+                       retval = -EINVAL;
+                       goto err3;
+               }
+       }
+
+       if (!grvga_mem_size)
+               grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
+
+       if (grvga_fix_addr) {
+               /* Got framebuffer base address from argument list */
+
+               physical_start = grvga_fix_addr;
+
+               if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
+                       dev_err(&dev->dev, "failed to request memory region\n");
+                       retval = -ENOMEM;
+                       goto err3;
+               }
+
+               virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
+
+               if (!virtual_start) {
+                       dev_err(&dev->dev, "error mapping framebuffer memory\n");
+                       retval = -ENOMEM;
+                       goto err4;
+               }
+       } else {        /* Allocate frambuffer memory */
+
+               unsigned long page;
+
+               virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
+                                                                get_order(grvga_mem_size));
+               if (!virtual_start) {
+                       dev_err(&dev->dev,
+                               "unable to allocate framebuffer memory (%lu bytes)\n",
+                               grvga_mem_size);
+                       retval = -ENOMEM;
+                       goto err3;
+               }
+
+               physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
+
+               /* Set page reserved so that mmap will work. This is necessary
+                * since we'll be remapping normal memory.
+                */
+               for (page = virtual_start;
+                    page < PAGE_ALIGN(virtual_start + grvga_mem_size);
+                    page += PAGE_SIZE) {
+                       SetPageReserved(virt_to_page(page));
+               }
+
+               par->fb_alloced = 1;
+       }
+
+       memset((unsigned long *) virtual_start, 0, grvga_mem_size);
+
+       info->screen_base = (char __iomem *) virtual_start;
+       info->fix.smem_start = physical_start;
+       info->fix.smem_len   = grvga_mem_size;
+
+       dev_set_drvdata(&dev->dev, info);
+
+       dev_info(&dev->dev,
+                "Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
+                info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
+                grvga_mem_size >> 10, info->screen_base);
+
+       retval = register_framebuffer(info);
+       if (retval < 0) {
+               dev_err(&dev->dev, "failed to register framebuffer\n");
+               goto err4;
+       }
+
+       __raw_writel(physical_start, &par->regs->fb_pos);
+       __raw_writel(__raw_readl(&par->regs->status) | 1,  /* Enable framebuffer */
+                    &par->regs->status);
+
+       return 0;
+
+err4:
+       dev_set_drvdata(&dev->dev, NULL);
+       if (grvga_fix_addr) {
+               release_mem_region(physical_start, grvga_mem_size);
+               iounmap((void *)virtual_start);
+       } else
+               kfree((void *)virtual_start);
+err3:
+       fb_dealloc_cmap(&info->cmap);
+err2:
+       of_iounmap(&dev->resource[0], par->regs,
+                  resource_size(&dev->resource[0]));
+err1:
+       release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
+err:
+       framebuffer_release(info);
+
+       return retval;
+}
+
+static int __devexit grvga_remove(struct platform_device *device)
+{
+       struct fb_info *info = dev_get_drvdata(&device->dev);
+       struct grvga_par *par = info->par;
+
+       if (info) {
+               unregister_framebuffer(info);
+               fb_dealloc_cmap(&info->cmap);
+
+               of_iounmap(&device->resource[0], par->regs,
+                          resource_size(&device->resource[0]));
+               release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
+
+               if (!par->fb_alloced) {
+                       release_mem_region(info->fix.smem_start, info->fix.smem_len);
+                       iounmap(info->screen_base);
+               } else
+                       kfree((void *)info->screen_base);
+
+               framebuffer_release(info);
+               dev_set_drvdata(&device->dev, NULL);
+       }
+
+       return 0;
+}
+
+static struct of_device_id svgactrl_of_match[] = {
+       {
+               .name = "GAISLER_SVGACTRL",
+       },
+       {
+               .name = "01_063",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, svgactrl_of_match);
+
+static struct platform_driver grvga_driver = {
+       .driver = {
+               .name = "grlib-svgactrl",
+               .owner = THIS_MODULE,
+               .of_match_table = svgactrl_of_match,
+       },
+       .probe          = grvga_probe,
+       .remove         = __devexit_p(grvga_remove),
+};
+
+
+static int __init grvga_init(void)
+{
+       return platform_driver_register(&grvga_driver);
+}
+
+static void __exit grvga_exit(void)
+{
+       platform_driver_unregister(&grvga_driver);
+}
+
+module_init(grvga_init);
+module_exit(grvga_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Aeroflex Gaisler");
+MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");
index 896e53dea906178a30f951e4460b76b462c51b66..0fad23f810a32035faffd0fcd7e0256426947b58 100644 (file)
@@ -543,8 +543,8 @@ static int gxt4500_pan_display(struct fb_var_screeninfo *var,
 
        if (var->xoffset & 7)
                return -EINVAL;
-       if (var->xoffset + var->xres > var->xres_virtual ||
-           var->yoffset + var->yres > var->yres_virtual)
+       if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+           var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
 
        writereg(par, REFRESH_START, (var->xoffset << 16) | var->yoffset);
index 4052718eefaa09215a8706501eb9e6e47a339857..4394389caf68d8e8ffa40c5d19e2eec3970d76eb 100644 (file)
@@ -422,8 +422,8 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
                    var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual
-                || var->yoffset + var->yres > info->var.yres_virtual
+               if (var->xoffset + info->var.xres > info->var.xres_virtual
+                || var->yoffset + info->var.yres > info->var.yres_virtual
                 || var->yoffset % 8)
                        return -EINVAL;
        }
index efb2c10656b0a89aa88d23276d47926805bbb4b2..8149356471e443af26d5a4e2cb97c818bfaf9c7f 100644 (file)
@@ -749,7 +749,7 @@ set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct imstt_par *par = info->par;
        __u32 off = var->yoffset * (info->fix.line_length >> 3)
-                   + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
+                   + ((var->xoffset * (info->var.bits_per_pixel >> 3)) >> 3);
        write_reg_le32(par->dc_regs, SSR, off);
 }
 
index 38065cf94ac4cf5dbaf195233871712af4607ab6..fbad61da359f796b579ae74b1dc01a78d888d4a9 100644 (file)
@@ -390,12 +390,12 @@ int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        xoffset = ROUND_DOWN_TO(var->xoffset, 8);
        yoffset = var->yoffset;
 
-       if ((xoffset + var->xres > var->xres_virtual) ||
-           (yoffset + var->yres > var->yres_virtual))
+       if ((xoffset + info->var.xres > info->var.xres_virtual) ||
+           (yoffset + info->var.yres > info->var.yres_virtual))
                return -EINVAL;
 
        offset = (yoffset * dinfo->pitch) +
-                (xoffset * var->bits_per_pixel) / 8;
+                (xoffset * info->var.bits_per_pixel) / 8;
 
        offset += dinfo->fb.offset << 12;
 
index f70bd63b01871223d74a2930bdd4823c27a120d7..2191de0bb309f070f7b364f2bfd0fee464164ae4 100644 (file)
@@ -278,7 +278,7 @@ static int mb862xxfb_pan(struct fb_var_screeninfo *var,
        reg = pack(var->yoffset, var->xoffset);
        outreg(disp, GC_L0WY_L0WX, reg);
 
-       reg = pack(var->yres_virtual, var->xres_virtual);
+       reg = pack(info->var.yres_virtual, info->var.xres_virtual);
        outreg(disp, GC_L0WH_L0WW, reg);
        return 0;
 }
index 7e3a490e8d76d882555f58a752242360a6ed948b..bd768588cf10c8dca7a77fbf76c7564817bea5b4 100644 (file)
@@ -1062,15 +1062,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
        y_bottom = var->yoffset;
 
        if (!(var->vmode & FB_VMODE_YWRAP))
-               y_bottom += var->yres;
+               y_bottom += fbi->var.yres;
 
        if (y_bottom > fbi->var.yres_virtual)
                return -EINVAL;
 
        mutex_lock(&mx3_fbi->mutex);
 
-       offset = (var->yoffset * var->xres_virtual + var->xoffset) *
-               (var->bits_per_pixel / 8);
+       offset = var->yoffset * fbi->fix.line_length
+              + var->xoffset * (fbi->var.bits_per_pixel / 8);
        base = fbi->fix.smem_start + offset;
 
        dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
index 588527a254c27ead542b906d7f4045aa6aff1955..feea7b1dc3860a3f28965995d9aa24968cb7312d 100644 (file)
@@ -1185,8 +1185,8 @@ static int neofb_pan_display(struct fb_var_screeninfo *var,
 
        DBG("neofb_update_start");
 
-       Base = (var->yoffset * var->xres_virtual + var->xoffset) >> 2;
-       Base *= (var->bits_per_pixel + 7) / 8;
+       Base = (var->yoffset * info->var.xres_virtual + var->xoffset) >> 2;
+       Base *= (info->var.bits_per_pixel + 7) / 8;
 
        neoUnlock();
 
index ef532d9d3c99d9376e8c5c260eda261f46c203c5..a0d0c3d625b95bf3fa3e22218bf04dbd8d3c2336 100644 (file)
@@ -490,7 +490,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
 
 
 /* 
- * Parse user speficied options (`video=platinumfb:')
+ * Parse user specified options (`video=platinumfb:')
  */
 static int __init platinumfb_setup(char *options)
 {
index 27f93aab6ddc008d3c61e59667993b4004a0a49a..dc7bfa91e57ab1c87bc6b2b0e4d405b050895c9a 100644 (file)
@@ -973,8 +973,8 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
 {
        struct pm2fb_par *p = info->par;
        u32 base;
-       u32 depth = (var->bits_per_pixel + 7) & ~7;
-       u32 xres = (var->xres + 31) & ~31;
+       u32 depth = (info->var.bits_per_pixel + 7) & ~7;
+       u32 xres = (info->var.xres + 31) & ~31;
 
        depth = (depth > 32) ? 32 : depth;
        base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
@@ -1773,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
 
 #ifndef MODULE
 /**
- * Parse user speficied options.
+ * Parse user specified options.
  *
  * This is, comma-separated options following `video=pm2fb:'.
  */
index 6666f45a2f8ce56e03f8ecb962caad73e5b7abdd..6632ee5ecb7e1243d2e6afc177a4a71eb6a5b6ec 100644 (file)
@@ -1147,9 +1147,9 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
                                 struct fb_info *info)
 {
        struct pm3_par *par = info->par;
-       const u32 xres = (var->xres + 31) & ~31;
+       const u32 xres = (info->var.xres + 31) & ~31;
 
-       par->base = pm3fb_shift_bpp(var->bits_per_pixel,
+       par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
                                        (var->yoffset * xres)
                                        + var->xoffset);
        PM3_WAIT(par, 1);
@@ -1525,7 +1525,7 @@ static int __init pm3fb_setup(char *options)
 {
        char *this_opt;
 
-       /* Parse user speficied options (`video=pm3fb:') */
+       /* Parse user specified options (`video=pm3fb:') */
        if (!options || !*options)
                return 0;
 
index 0283c7021090d05661a3cdf9c0724f986364530f..d8de5577d3cf203d0de12ef461fb53a1c9b47dc9 100644 (file)
@@ -31,8 +31,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
-
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/miscdevice.h>
index 4aecf213c9be46cb1f37ee38d231aabcf9d089d3..fd9f20df912fef09c3be039d666edef150f8295d 100644 (file)
@@ -883,7 +883,7 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
                }
        }
        /* Offset in bytes to the end of the displayed area */
-       end_boff = start_boff + var->yres * info->fix.line_length;
+       end_boff = start_boff + info->var.yres * info->fix.line_length;
 
        /* Temporarily turn off per-vsync update from shadow registers until
         * both start and end addresses are updated to prevent corruption */
index 4ca5d0c8fe84a6501ca6ef4f31898c0babac2725..946a949f4c7d44cba635432f92c7591a54b773ab 100644 (file)
@@ -1019,12 +1019,13 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        unsigned int offset;
 
        /* Calculate the offset */
-       if (var->bits_per_pixel == 0) {
-               offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
+       if (info->var.bits_per_pixel == 0) {
+               offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
+                      + (var->xoffset / 2);
                offset = offset >> 2;
        } else {
                offset = (var->yoffset * info->fix.line_length) +
-                        (var->xoffset * var->bits_per_pixel / 8);
+                        (var->xoffset * info->var.bits_per_pixel / 8);
                offset = offset >> 2;
        }
 
@@ -1504,7 +1505,7 @@ static struct pci_driver s3fb_pci_driver = {
        .resume         = s3_pci_resume,
 };
 
-/* Parse user speficied options */
+/* Parse user specified options */
 
 #ifndef MODULE
 static int  __init s3fb_setup(char *options)
index 4de541ca9c52c14d38cb95762ba86034e71d59fd..beb495044b240e5b2edc3f98656845756279e80c 100644 (file)
@@ -1477,15 +1477,9 @@ static void savagefb_set_par_int(struct savagefb_par  *par, struct savage_reg *r
        vgaHWProtect(par, 0);
 }
 
-static void savagefb_update_start(struct savagefb_par      *par,
-                                 struct fb_var_screeninfo *var)
+static void savagefb_update_start(struct savagefb_par *par, int base)
 {
-       int base;
-
-       base = ((var->yoffset * var->xres_virtual + (var->xoffset & ~1))
-               * ((var->bits_per_pixel+7) / 8)) >> 2;
-
-       /* now program the start address registers */
+       /* program the start address registers */
        vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
        vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
        vga_out8(0x3d4, 0x69, par);
@@ -1550,8 +1544,12 @@ static int savagefb_pan_display(struct fb_var_screeninfo *var,
                                struct fb_info           *info)
 {
        struct savagefb_par *par = info->par;
+       int base;
+
+       base = (var->yoffset * info->fix.line_length
+            + (var->xoffset & ~1) * ((info->var.bits_per_pixel+7) / 8)) >> 2;
 
-       savagefb_update_start(par, var);
+       savagefb_update_start(par, base);
        return 0;
 }
 
index 75259845933deb53ab030a2067bb52e69259f673..078ca2167d6f9754a3fc9ad26582643b82e34c8a 100644 (file)
@@ -1333,19 +1333,14 @@ sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
 }
 
 static int
-sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+sisfb_pan_var(struct sis_video_info *ivideo, struct fb_info *info,
+             struct fb_var_screeninfo *var)
 {
-       if(var->xoffset > (var->xres_virtual - var->xres)) {
-               return -EINVAL;
-       }
-       if(var->yoffset > (var->yres_virtual - var->yres)) {
-               return -EINVAL;
-       }
-
-       ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;
+       ivideo->current_base = var->yoffset * info->var.xres_virtual
+                            + var->xoffset;
 
        /* calculate base bpp dep. */
-       switch(var->bits_per_pixel) {
+       switch (info->var.bits_per_pixel) {
        case 32:
                break;
        case 16:
@@ -1635,20 +1630,15 @@ sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        int err;
 
-       if(var->xoffset > (var->xres_virtual - var->xres))
-               return -EINVAL;
-
-       if(var->yoffset > (var->yres_virtual - var->yres))
-               return -EINVAL;
-
-       if(var->vmode & FB_VMODE_YWRAP)
+       if (var->vmode & FB_VMODE_YWRAP)
                return -EINVAL;
 
-       if(var->xoffset + info->var.xres > info->var.xres_virtual ||
-          var->yoffset + info->var.yres > info->var.yres_virtual)
+       if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+           var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
 
-       if((err = sisfb_pan_var(ivideo, var)) < 0)
+       err = sisfb_pan_var(ivideo, info, var);
+       if (err < 0)
                return err;
 
        info->var.xoffset = var->xoffset;
index 89158bc71da2b3ea982d355c2e6ee0dfeaee7244..30f7a815a62bc0f36813a644ad1819d210958ca5 100644 (file)
@@ -989,7 +989,7 @@ static struct platform_device *xxxfb_device;
  */
 int __init xxxfb_setup(char *options)
 {
-    /* Parse user speficied options (`video=xxxfb:') */
+    /* Parse user specified options (`video=xxxfb:') */
 }
 #endif /* MODULE */
 
index 6294dca955005988f384fbf0bdae104f43c8037d..a78254cf8e83eb971db5bd7f6cb499745a6741f6 100644 (file)
@@ -582,7 +582,7 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
 {
        struct sm501fb_par  *par = info->par;
        struct sm501fb_info *fbi = par->info;
-       unsigned int bytes_pixel = var->bits_per_pixel / 8;
+       unsigned int bytes_pixel = info->var.bits_per_pixel / 8;
        unsigned long reg;
        unsigned long xoffs;
 
@@ -614,10 +614,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
        struct sm501fb_info *fbi = par->info;
        unsigned long reg;
 
-       reg = var->xoffset | (var->xres_virtual << 16);
+       reg = var->xoffset | (info->var.xres_virtual << 16);
        smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
 
-       reg = var->yoffset | (var->yres_virtual << 16);
+       reg = var->yoffset | (info->var.yres_virtual << 16);
        smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
 
        sm501fb_sync_regs(fbi);
index c6c77562839d9663cef133f9b23e0d1607a5d2c8..34cf019bba44b64dc9c5a09ec4683efac8ff262c 100644 (file)
@@ -987,8 +987,8 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var,
        unsigned int offset;
 
        debug("enter\n");
-       offset = (var->xoffset + (var->yoffset * var->xres_virtual))
-               * var->bits_per_pixel / 32;
+       offset = (var->xoffset + (var->yoffset * info->var.xres_virtual))
+               * info->var.bits_per_pixel / 32;
        set_screen_start(par, offset);
        debug("exit\n");
        return 0;
index 6b52bf65f0b57fc3ddced265a76a8ce5b03b0f6e..3f5a041601dafd77a6088096f6d5dab6331461d1 100644 (file)
@@ -555,7 +555,7 @@ static int __init valkyrie_init_info(struct fb_info *info,
 
 
 /*
- * Parse user speficied options (`video=valkyriefb:')
+ * Parse user specified options (`video=valkyriefb:')
  */
 int __init valkyriefb_setup(char *options)
 {
index bc67251f1a2f1d0e3662d4bec1f46f91bd2884d8..bf2f78065cf97d8d0bcdf492087244946783e99c 100644 (file)
@@ -395,8 +395,8 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
                    || var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual ||
-                   var->yoffset + var->yres > info->var.yres_virtual)
+               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+                   var->yoffset + info->var.yres > info->var.yres_virtual)
                        return -EINVAL;
        }
        info->var.xoffset = var->xoffset;
index 305c975b1787ea0628d600d2ac89c89cd0afdee9..0267acd8dc832690e3f02709a9e99361a8979805 100644 (file)
@@ -207,7 +207,7 @@ static void vga16fb_pan_var(struct fb_info *info,
         * granularity if someone supports xoffset in bit resolution */
        vga_io_r(VGA_IS1_RC);           /* reset flip-flop */
        vga_io_w(VGA_ATT_IW, VGA_ATC_PEL);
-       if (var->bits_per_pixel == 8)
+       if (info->var.bits_per_pixel == 8)
                vga_io_w(VGA_ATT_IW, (xoffset & 3) << 1);
        else
                vga_io_w(VGA_ATT_IW, xoffset & 7);
index 0e120d67eb65074eb0f337ff9d29e10cdae134a3..c13c246be9a56ddd68b398e00f123937517c80fa 100644 (file)
@@ -210,8 +210,8 @@ static int vt8500lcd_pan_display(struct fb_var_screeninfo *var,
        struct vt8500lcd_info *fbi = to_vt8500lcd_info(info);
 
        writel((1 << 31)
-               | (((var->xres_virtual - var->xres) * pixlen / 4) << 20)
-               | (off >> 2), fbi->regbase + 0x20);
+            | (((info->var.xres_virtual - info->var.xres) * pixlen / 4) << 20)
+            | (off >> 2), fbi->regbase + 0x20);
        return 0;
 }
 
index f9b3e3dc24219fcdabcf9235a95720292c107c12..4e74d262cf3e9f338c1eb0cb46a5835794a532d3 100644 (file)
@@ -620,13 +620,14 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
        unsigned int offset;
 
        /* Calculate the offset */
-       if (var->bits_per_pixel == 0) {
-               offset = (var->yoffset / 16) * var->xres_virtual + var->xoffset;
+       if (info->var.bits_per_pixel == 0) {
+               offset = (var->yoffset / 16) * info->var.xres_virtual
+                      + var->xoffset;
                offset = offset >> 3;
        } else {
                offset = (var->yoffset * info->fix.line_length) +
-                        (var->xoffset * var->bits_per_pixel / 8);
-               offset = offset >> ((var->bits_per_pixel == 4) ? 2 : 1);
+                        (var->xoffset * info->var.bits_per_pixel / 8);
+               offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 1);
        }
 
        /* Set the offset */
index 77dea015ff69a7524261296ea91ed33975b338a9..fcb6cd90f64d8ade134626076a622ac4a2a16118 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>