Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / video / sstfb.c
index f732dbb..c44de90 100644 (file)
@@ -32,7 +32,7 @@
 
 -TODO: at one time or another test that the mode is acceptable by the monitor
 -ASK: Can I choose different ordering for the color bitfields (rgba argb ...)
-      wich one should i use ? is there any preferred one ? It seems ARGB is
+      which one should i use ? is there any preferred one ? It seems ARGB is
       the one ...
 -TODO: in  set_var check the validity of timings (hsync vsync)...
 -TODO: check and recheck the use of sst_wait_idle : we don't flush the fifo via
 
 #undef SST_DEBUG
 
-#define SST_DEBUG_REG   0
-#define SST_DEBUG_FUNC  0
-#define SST_DEBUG_VAR   0
-
 /* enable 24/32 bpp functions ? (completely untested!) */
 #undef EN_24_32_BPP
 
@@ -220,26 +216,26 @@ static void sst_dbg_print_write_reg(u32 reg, u32 val) {
 #define dac_i_read(reg)                __dac_i_read(par->mmio_vbase, reg)
 #define dac_i_write(reg,val)   __dac_i_write(par->mmio_vbase, reg, val)
 
-static inline u32 __sst_read(u_long vbase, u32 reg)
+static inline u32 __sst_read(u8 __iomem *vbase, u32 reg)
 {
        u32 ret = readl(vbase + reg);
        sst_dbg_print_read_reg(reg, ret);
        return ret;
 }
 
-static inline void __sst_write(u_long vbase, u32 reg, u32 val)
+static inline void __sst_write(u8 __iomem *vbase, u32 reg, u32 val)
 {
        sst_dbg_print_write_reg(reg, val);
        writel(val, vbase + reg);
 }
 
-static inline void __sst_set_bits(u_long vbase, u32 reg, u32 val)
+static inline void __sst_set_bits(u8 __iomem *vbase, u32 reg, u32 val)
 {
        r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val);
        __sst_write(vbase, reg, __sst_read(vbase, reg) | val);
 }
 
-static inline void __sst_unset_bits(u_long vbase, u32 reg, u32 val)
+static inline void __sst_unset_bits(u8 __iomem *vbase, u32 reg, u32 val)
 {
        r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val);
        __sst_write(vbase, reg, __sst_read(vbase, reg) & ~val);
@@ -254,7 +250,7 @@ static inline void __sst_unset_bits(u_long vbase, u32 reg, u32 val)
 
 #define sst_wait_idle() __sst_wait_idle(par->mmio_vbase)
 
-static int __sst_wait_idle(u_long vbase)
+static int __sst_wait_idle(u8 __iomem *vbase)
 {
        int count = 0;
 
@@ -279,7 +275,7 @@ static int __sst_wait_idle(u_long vbase)
 
 /* dac access */
 /* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
-static u8 __sst_dac_read(u_long vbase, u8 reg)
+static u8 __sst_dac_read(u8 __iomem *vbase, u8 reg)
 {
        u8 ret;
 
@@ -293,7 +289,7 @@ static u8 __sst_dac_read(u_long vbase, u8 reg)
        return ret;
 }
 
-static void __sst_dac_write(u_long vbase, u8 reg, u8 val)
+static void __sst_dac_write(u8 __iomem *vbase, u8 reg, u8 val)
 {
        r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
        reg &= 0x07;
@@ -301,7 +297,7 @@ static void __sst_dac_write(u_long vbase, u8 reg, u8 val)
 }
 
 /* indexed access to ti/att dacs */
-static u32 __dac_i_read(u_long vbase, u8 reg)
+static u32 __dac_i_read(u8 __iomem *vbase, u8 reg)
 {
        u32 ret;
 
@@ -310,7 +306,7 @@ static u32 __dac_i_read(u_long vbase, u8 reg)
        r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);
        return ret;
 }
-static void __dac_i_write(u_long vbase, u8 reg,u8 val)
+static void __dac_i_write(u8 __iomem *vbase, u8 reg,u8 val)
 {
        r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);
        __sst_dac_write(vbase, DACREG_ADDR_I, reg);
@@ -386,7 +382,7 @@ static void sstfb_clear_screen(struct fb_info *info)
 static int sstfb_check_var(struct fb_var_screeninfo *var,
                struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int hSyncOff   = var->xres + var->right_margin + var->left_margin;
        int vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
        int vBackPorch = var->left_margin, yDim = var->yres;
@@ -546,7 +542,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
  */
 static int sstfb_set_par(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
        struct pci_dev *sst_dev = par->dev;
        unsigned int freq;
@@ -752,13 +748,14 @@ static int sstfb_set_par(struct fb_info *info)
 static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                            u_int transp, struct fb_info *info)
 {
+       struct sstfb_par *par = info->par;
        u32 col;
 
        f_dddprintk("sstfb_setcolreg\n");
        f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n",
                    regno, red, green, blue, transp);
-       if (regno >= 16)
-               return -EINVAL;
+       if (regno > 15)
+               return 0;
 
        red    >>= (16 - info->var.red.length);
        green  >>= (16 - info->var.green.length);
@@ -769,15 +766,14 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
            | (blue  << info->var.blue.offset)
            | (transp << info->var.transp.offset);
        
-       ((u32 *)info->pseudo_palette)[regno] = col;
+       par->palette[regno] = col;
 
        return 0;
 }
 
-static int sstfb_ioctl(struct inode *inode, struct file *file,
-                       u_int cmd, u_long arg, struct fb_info *info )
+static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        struct pci_dev *sst_dev = par->dev;
        u32 fbiinit0, tmp, val;
        u_long p;
@@ -834,7 +830,7 @@ static int sstfb_ioctl(struct inode *inode, struct file *file,
 #if 0
 static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u32 stride = info->fix.line_length;
    
        if (!IS_VOODOO2(par))
@@ -859,7 +855,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
  */
 static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u32 stride = info->fix.line_length;
 
        if (!IS_VOODOO2(par))
@@ -886,7 +882,7 @@ static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
  */
 static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
 {
-       u_long fbbase_virt = (u_long) info->screen_base;
+       u8 __iomem *fbbase_virt = info->screen_base;
 
        /* force memsize */
        if ((mem >= 1 ) &&  (mem <= 4)) {
@@ -929,7 +925,7 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
 
 static int __devinit sst_detect_att(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int i, mir, dir;
 
        for (i=0; i<3; i++) {
@@ -954,7 +950,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
 
 static int __devinit sst_detect_ti(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int i, mir, dir;
 
        for (i = 0; i<3; i++) {
@@ -990,7 +986,7 @@ static int __devinit sst_detect_ti(struct fb_info *info)
  */
 static int __devinit sst_detect_ics(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int m_clk0_1, m_clk0_7, m_clk1_b;
        int n_clk0_1, n_clk0_7, n_clk1_b;
        int i;
@@ -1027,7 +1023,7 @@ static int __devinit sst_detect_ics(struct fb_info *info)
 static int sst_set_pll_att_ti(struct fb_info *info, 
                const struct pll_timing *t, const int clock)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u8 cr0, cc;
 
        /* enable indexed mode */
@@ -1081,7 +1077,7 @@ static int sst_set_pll_att_ti(struct fb_info *info,
 static int sst_set_pll_ics(struct fb_info *info,
                const struct pll_timing *t, const int clock)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u8 pll_ctrl;
 
        sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
@@ -1118,7 +1114,7 @@ static int sst_set_pll_ics(struct fb_info *info,
 
 static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u8 cr0;
 
        sst_dac_write(DACREG_WMA, 0);   /* backdoor */
@@ -1153,7 +1149,7 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
 
 static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
 
        switch(bpp) {
        case 16:
@@ -1198,10 +1194,11 @@ static struct dac_switch dacs[] __devinitdata = {
 static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *par)
 {
        int i, ret = 0;
-       
-       for (i=0; i<sizeof(dacs)/sizeof(dacs[0]); i++) {
+
+       for (i = 0; i < ARRAY_SIZE(dacs); i++) {
                ret = dacs[i].detect(info);
-               if (ret) break;
+               if (ret)
+                       break;
        }
        if (!ret)
                return 0;
@@ -1312,7 +1309,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
 
 static void  __devexit sst_shutdown(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        struct pci_dev *dev = par->dev;
        struct pll_timing gfx_timings;
        int Fout;
@@ -1342,8 +1339,8 @@ static void  __devexit sst_shutdown(struct fb_info *info)
 /*
  * Interface to the world
  */
-
-int  __init sstfb_setup(char *options)
+#ifndef MODULE
+static int  __init sstfb_setup(char *options)
 {
        char *this_opt;
 
@@ -1376,6 +1373,7 @@ int  __init sstfb_setup(char *options)
        }
        return 0;
 }
+#endif
 
 static struct fb_ops sstfb_ops = {
        .owner          = THIS_MODULE,
@@ -1385,7 +1383,6 @@ static struct fb_ops sstfb_ops = {
        .fb_fillrect    = cfb_fillrect, /* sstfb_fillrect */
        .fb_copyarea    = cfb_copyarea, /* sstfb_copyarea */
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = sstfb_ioctl,
 };
 
@@ -1398,12 +1395,6 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        struct sst_spec *spec;
        int err;
 
-       struct all_info {
-               struct fb_info info;
-               struct sstfb_par par;
-               u32 pseudo_palette[16];
-       } *all;
-       
        /* Enable device in PCI config. */
        if ((err=pci_enable_device(pdev))) {
                eprintk("cannot enable device\n");
@@ -1411,14 +1402,13 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        }
 
        /* Allocate the fb and par structures.  */
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all)
+       info = framebuffer_alloc(sizeof(struct sstfb_par), &pdev->dev);
+       if (!info)
                return -ENOMEM;
-       memset(all, 0, sizeof(*all));
-       pci_set_drvdata(pdev, all);
+
+       pci_set_drvdata(pdev, info);
        
-       info = &all->info;
-       par  = info->par = &all->par;
+       par  = info->par;
        fix  = &info->fix;
        
        par->type = id->driver_data;
@@ -1442,7 +1432,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
                goto fail_fb_mem;
        }
 
-       par->mmio_vbase = (u_long) ioremap_nocache(fix->mmio_start,
+       par->mmio_vbase = ioremap_nocache(fix->mmio_start,
                                        fix->mmio_len);
        if (!par->mmio_vbase) {
                eprintk("cannot remap register area %#lx\n",
@@ -1473,10 +1463,9 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        f_ddprintk("membase_phys: %#lx\n", fix->smem_start);
        f_ddprintk("fbbase_virt: %p\n", info->screen_base);
 
-       info->flags     = FBINFO_FLAG_DEFAULT;
+       info->flags     = FBINFO_DEFAULT;
        info->fbops     = &sstfb_ops;
-       info->currcon   = -1;
-       info->pseudo_palette = &all->pseudo_palette;
+       info->pseudo_palette = par->palette;
 
        fix->type       = FB_TYPE_PACKED_PIXELS;
        fix->visual     = FB_VISUAL_TRUECOLOR;
@@ -1507,6 +1496,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        fb_alloc_cmap(&info->cmap, 256, 0);
 
        /* register fb */
+       info->device = &pdev->dev;
        if (register_framebuffer(info) < 0) {
                eprintk("can't register framebuffer.\n");
                goto fail;
@@ -1525,13 +1515,13 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
 fail:
        iounmap(info->screen_base);
 fail_fb_remap:
-       iounmap((void *)par->mmio_vbase);
+       iounmap(par->mmio_vbase);
 fail_mmio_remap:
        release_mem_region(fix->smem_start, 0x400000);
 fail_fb_mem:
        release_mem_region(fix->mmio_start, info->fix.mmio_len);
 fail_mmio_mem:
-       kfree(info);
+       framebuffer_release(info);
        return -ENXIO;  /* no voodoo detected */
 }
 
@@ -1541,15 +1531,15 @@ static void __devexit sstfb_remove(struct pci_dev *pdev)
        struct fb_info *info;
 
        info = pci_get_drvdata(pdev);
-       par = (struct sstfb_par *) info->par;
+       par = info->par;
        
        sst_shutdown(info);
        unregister_framebuffer(info);
        iounmap(info->screen_base);
-       iounmap((void*)par->mmio_vbase);
+       iounmap(par->mmio_vbase);
        release_mem_region(info->fix.smem_start, 0x400000);
        release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
-       kfree(info);
+       framebuffer_release(info);
 }
 
 
@@ -1569,15 +1559,24 @@ static struct pci_driver sstfb_driver = {
 };
 
 
-int __devinit sstfb_init(void)
+static int __devinit sstfb_init(void)
 {
-       return pci_module_init(&sstfb_driver);
+#ifndef MODULE
+       char *option = NULL;
+
+       if (fb_get_options("sstfb", &option))
+               return -ENODEV;
+       sstfb_setup(option);
+#endif
+       return pci_register_driver(&sstfb_driver);
 }
 
-void __devexit sstfb_exit(void)
+#ifdef MODULE
+static void __devexit sstfb_exit(void)
 {
        pci_unregister_driver(&sstfb_driver);
 }
+#endif
 
 
 /*
@@ -1606,9 +1605,9 @@ static int sstfb_dump_regs(struct fb_info *info)
                {FBZMODE,"fbzmode"},
        };
 
-       const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]);
-       const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]);
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       const int pci_s = ARRAY_SIZE(pci_regs);
+       const int sst_s = ARRAY_SIZE(sst_regs);
+       struct sstfb_par *par = info->par;
        struct pci_dev *dev = par->dev;
        u32 pci_res[pci_s];
        u32 sst_res[sst_s];
@@ -1636,10 +1635,10 @@ static int sstfb_dump_regs(struct fb_info *info)
 
 static void sstfb_fillrect_softw( struct fb_info *info, const struct fb_fillrect *rect)
 {
-       unsigned long fbbase_virt = (unsigned long) info->screen_base;
+       u8 __iomem *fbbase_virt = info->screen_base;
        int x, y, w = info->var.bits_per_pixel == 16 ? 2 : 4;
        u32 color = rect->color, height = rect->height;
-       unsigned long p;
+       u8 __iomem *p;
        
        if (w==2) color |= color<<16;
        for (y=rect->dy; height; y++, height--) {
@@ -1693,9 +1692,9 @@ static void sstfb_drawdebugimage(struct fb_info *info)
        sstfb_drawrect_XY(info, 250, 250, 120, 100, 0xf800, idx);
 }
 
+module_init(sstfb_init);
 
 #ifdef MODULE
-module_init(sstfb_init);
 module_exit(sstfb_exit);
 #endif
 
@@ -1703,14 +1702,14 @@ MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
 MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(mem, "i");
+module_param(mem, int, 0);
 MODULE_PARM_DESC(mem, "Size of frame buffer memory in MB (1, 2, 4 MB, default=autodetect)");
-MODULE_PARM(vgapass, "i");
+module_param(vgapass, bool, 0);
 MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough mode (0 or 1) (default=0)");
-MODULE_PARM(clipping , "i");
+module_param(clipping, bool, 0);
 MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
-MODULE_PARM(gfxclk , "i");
+module_param(gfxclk, int, 0);
 MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
-MODULE_PARM(slowpci, "i");
+module_param(slowpci, bool, 0);
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");