fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / video / tridentfb.c
index aea0e05..55e8aa4 100644 (file)
@@ -15,7 +15,6 @@
  *     TGUI acceleration       
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/fb.h>
 #include <linux/init.h>
@@ -31,14 +30,14 @@ struct tridentfb_par {
        void __iomem * io_virt; //iospace virtual memory address
 };
 
-unsigned char eng_oper;                //engine operation...
+static unsigned char eng_oper;         //engine operation...
 static struct fb_ops tridentfb_ops;
 
 static struct tridentfb_par default_par;
 
 /* FIXME:kmalloc these 3 instead */
 static struct fb_info fb_info;
-static int pseudo_pal[16];
+static u32 pseudo_pal[16];
 
 
 static struct fb_var_screeninfo default_var;
@@ -76,22 +75,22 @@ static int memdiff;
 static int nativex;
 
 
-MODULE_PARM(mode,"s");
-MODULE_PARM(bpp,"i");
-MODULE_PARM(center,"i");
-MODULE_PARM(stretch,"i");
-MODULE_PARM(noaccel,"i");
-MODULE_PARM(memsize,"i");
-MODULE_PARM(memdiff,"i");
-MODULE_PARM(nativex,"i");
-MODULE_PARM(fp,"i");
-MODULE_PARM(crt,"i");
+module_param(mode, charp, 0);
+module_param(bpp, int, 0);
+module_param(center, int, 0);
+module_param(stretch, int, 0);
+module_param(noaccel, int, 0);
+module_param(memsize, int, 0);
+module_param(memdiff, int, 0);
+module_param(nativex, int, 0);
+module_param(fp, int, 0);
+module_param(crt, int, 0);
 
 
 static int chip3D;
 static int chipcyber;
 
-int is3Dchip(int id)
+static int is3Dchip(int id)
 {
        return  ((id == BLADE3D) || (id == CYBERBLADEE4) ||
                 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
@@ -104,7 +103,7 @@ int is3Dchip(int id)
                 (id == CYBERBLADEXPAi1));
 }
 
-int iscyber(int id)
+static int iscyber(int id)
 {
        switch (id) {
                case CYBER9388:         
@@ -454,13 +453,16 @@ static struct accel_switch accel_image = {
 static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr)
 {
        int bpp = info->var.bits_per_pixel;
-       int col;
+       int col = 0;
        
        switch (bpp) {
                default:
-               case 8: col = fr->color;
+               case 8: col |= fr->color;
+                       col |= col << 8;
+                       col |= col << 16;
                        break;
-               case 16: col = ((u16 *)(info->pseudo_palette))[fr->color];
+               case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
+                       
                         break;
                case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
                         break;
@@ -523,13 +525,6 @@ static inline void writeAttr(int reg, unsigned char val)
        t_outb(val, 0x3C0);
 }
 
-static inline unsigned char readAttr(int reg)
-{
-       readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A);     //flip-flop to index
-       t_outb(reg, 0x3C0);
-       return t_inb(0x3C1);
-}
-
 static inline void write3CE(int reg, unsigned char val)
 {
        t_outb(reg, 0x3CE);
@@ -555,7 +550,7 @@ static inline void enable_mmio(void)
 #define crtc_unlock()  write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
 
 /*  Return flat panel's maximum x resolution */
-static int __init get_nativex(void)
+static int __devinit get_nativex(void)
 {
        int x,y,tmp;
 
@@ -662,7 +657,7 @@ static void set_number_of_lines(int lines)
  * If we see that FP is active we assume we have one.
  * Otherwise we have a CRT display.User can override.
  */
-static unsigned int __init get_displaytype(void)
+static unsigned int __devinit get_displaytype(void)
 {
        if (fp)
                return DISPLAY_FP;
@@ -672,7 +667,7 @@ static unsigned int __init get_displaytype(void)
 }
 
 /* Try detecting the video memory size */
-static unsigned int __init get_memsize(void)
+static unsigned int __devinit get_memsize(void)
 {
        unsigned char tmp, tmp2;
        unsigned int k;
@@ -889,8 +884,9 @@ static int tridentfb_set_par(struct fb_info *info)
 
        write3X4(GraphEngReg, 0x80);    //enable GE for text acceleration
 
-//     if (info->var.accel_flags & FB_ACCELF_TEXT)
-//FIXME                acc->init_accel(info->var.xres,bpp);
+#ifdef CONFIG_FB_TRIDENT_ACCEL 
+       acc->init_accel(info->var.xres,bpp);
+#endif
        
        switch (bpp) {
                case 8:  tmp = 0x00; break;
@@ -907,7 +903,7 @@ static int tridentfb_set_par(struct fb_info *info)
        write3X4(DRAMControl, tmp);     //both IO,linear enable
 
        write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
-       write3X4(Performance,0x20);
+       write3X4(Performance,0x92);
        write3X4(PCIReg,0x07);          //MMIO & PCI read and write burst enable
 
        /* convert from picoseconds to MHz */
@@ -988,12 +984,14 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
                t_outb(green>>10,0x3C9);
                t_outb(blue>>10,0x3C9);
 
-       } else
-       if (bpp == 16)                  /* RGB 565 */
-                       ((u16*)info->pseudo_palette)[regno] = (red & 0xF800) |
-                       ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
-       else
-       if (bpp == 32)          /* ARGB 8888 */
+       } else if (bpp == 16) { /* RGB 565 */
+               u32 col;
+
+               col = (red & 0xF800) | ((green & 0xFC00) >> 5) |
+                       ((blue & 0xF800) >> 11);
+               col |= col << 16;       
+               ((u32 *)(info->pseudo_palette))[regno] = col;
+       } else if (bpp == 32)           /* ARGB 8888 */
                ((u32*)info->pseudo_palette)[regno] =
                        ((transp & 0xFF00) <<16)        |
                        ((red & 0xFF00) << 8)           |
@@ -1017,22 +1015,24 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
        DPMSCont = read3CE(PowerStatus) & 0xFC;
        switch (blank_mode)
        {
-       case VESA_NO_BLANKING:
+       case FB_BLANK_UNBLANK:
                /* Screen: On, HSync: On, VSync: On */
+       case FB_BLANK_NORMAL:
+               /* Screen: Off, HSync: On, VSync: On */
                PMCont |= 0x03;
                DPMSCont |= 0x00;
                break;
-       case VESA_HSYNC_SUSPEND:
+       case FB_BLANK_HSYNC_SUSPEND:
                /* Screen: Off, HSync: Off, VSync: On */
                PMCont |= 0x02;
                DPMSCont |= 0x01;
                break;
-       case VESA_VSYNC_SUSPEND:
+       case FB_BLANK_VSYNC_SUSPEND:
                /* Screen: Off, HSync: On, VSync: Off */
                PMCont |= 0x02;
                DPMSCont |= 0x02;
                break;
-       case VESA_POWERDOWN:
+       case FB_BLANK_POWERDOWN:
                /* Screen: Off, HSync: Off, VSync: Off */
                PMCont |= 0x00;
                DPMSCont |= 0x03;
@@ -1044,7 +1044,9 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
        t_outb(PMCont,0x83C6);
 
        debug("exit\n");
-       return 0;
+
+       /* let fbcon do a softblank for us */
+       return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
 }
 
 static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id)
@@ -1058,6 +1060,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
 
        chip_id = id->device;
 
+       if(chip_id == CYBERBLADEi1)
+               output("*** Please do use cyblafb, Cyberblade/i1 support "
+                      "will soon be removed from tridentfb!\n");
+
+
        /* If PCI id is 0x9660 then further detect chip type */
        
        if (chip_id == TGUI9660) {
@@ -1123,7 +1130,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
        
        if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
                debug("request_mem_region failed!\n");
-               return -1;
+               err = -1;
+               goto out_unmap;
        }
 
        fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
@@ -1132,7 +1140,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
        if (!fb_info.screen_base) {
                release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
                debug("ioremap failed\n");
-               return -1;
+               err = -1;
+               goto out_unmap;
        }
 
        output("%s board found\n", pci_name(dev));
@@ -1155,8 +1164,10 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
 #endif
        fb_info.pseudo_palette = pseudo_pal;
 
-       if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp))
-               return -EINVAL;
+       if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) {
+               err = -EINVAL;
+               goto out_unmap;
+       }
        fb_alloc_cmap(&fb_info.cmap,256,0);
        if (defaultaccel && acc)
                default_var.accel_flags |= FB_ACCELF_TEXT;
@@ -1164,14 +1175,23 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
                default_var.accel_flags &= ~FB_ACCELF_TEXT;
        default_var.activate |= FB_ACTIVATE_NOW;
        fb_info.var = default_var;
+       fb_info.device = &dev->dev;
        if (register_framebuffer(&fb_info) < 0) {
-               output("Could not register Trident framebuffer\n");
-               return -EINVAL;
+               printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
+               err = -EINVAL;
+               goto out_unmap;
        }
        output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
           fb_info.node, fb_info.fix.id,default_var.xres,
           default_var.yres,default_var.bits_per_pixel);
        return 0;
+
+out_unmap:
+       if (default_par.io_virt)
+               iounmap(default_par.io_virt);
+       if (fb_info.screen_base)
+               iounmap(fb_info.screen_base);
+       return err;
 }
 
 static void __devexit trident_pci_remove(struct pci_dev * dev)
@@ -1218,33 +1238,13 @@ static struct pci_driver tridentfb_pci_driver = {
        .remove         = __devexit_p(trident_pci_remove)
 };
 
-int tridentfb_setup(char *options);
-
-int __init tridentfb_init(void)
-{
-#ifndef MODULE
-       char *option = NULL;
-
-       if (fb_get_options("tridentfb", &option))
-               return -ENODEV;
-       tridentfb_setup(option);
-#endif
-       output("Trident framebuffer %s initializing\n", VERSION);
-       return pci_module_init(&tridentfb_pci_driver);
-}
-
-void __exit tridentfb_exit(void)
-{
-       pci_unregister_driver(&tridentfb_pci_driver);
-}
-
-
 /*
  * Parse user specified options (`video=trident:')
  * example:
  *     video=trident:800x600,bpp=16,noaccel
  */
-int tridentfb_setup(char *options)
+#ifndef MODULE
+static int tridentfb_setup(char *options)
 {
        char * opt;
        if (!options || !*options)
@@ -1274,6 +1274,25 @@ int tridentfb_setup(char *options)
        }
        return 0;
 }
+#endif
+
+static int __init tridentfb_init(void)
+{
+#ifndef MODULE
+       char *option = NULL;
+
+       if (fb_get_options("tridentfb", &option))
+               return -ENODEV;
+       tridentfb_setup(option);
+#endif
+       output("Trident framebuffer %s initializing\n", VERSION);
+       return pci_register_driver(&tridentfb_pci_driver);
+}
+
+static void __exit tridentfb_exit(void)
+{
+       pci_unregister_driver(&tridentfb_pci_driver);
+}
 
 static struct fb_ops tridentfb_ops = {
        .owner  = THIS_MODULE,
@@ -1285,7 +1304,6 @@ static struct fb_ops tridentfb_ops = {
        .fb_fillrect = tridentfb_fillrect,
        .fb_copyarea= tridentfb_copyarea,
        .fb_imageblit = cfb_imageblit,
-       .fb_cursor = soft_cursor,
 };
 
 module_init(tridentfb_init);