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 / cirrusfb.c
index 82c26b1..1103010 100644 (file)
@@ -60,8 +60,8 @@
 #include <asm/amigahw.h>
 #endif
 #ifdef CONFIG_PPC_PREP
-#include <asm/processor.h>
-#define isPReP (_machine == _MACH_prep)
+#include <asm/machdep.h>
+#define isPReP (machine_is(prep))
 #else
 #define isPReP 0
 #endif
@@ -275,20 +275,20 @@ static const struct cirrusfb_board_info_rec {
 
 #ifdef CONFIG_PCI
 #define CHIP(id, btype) \
-       { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
+       { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
 
 static struct pci_device_id cirrusfb_pci_table[] = {
-       CHIP( CIRRUS_5436,      BT_ALPINE ),
-       CHIP( CIRRUS_5434_8,    BT_ALPINE ),
-       CHIP( CIRRUS_5434_4,    BT_ALPINE ),
-       CHIP( CIRRUS_5430,      BT_ALPINE ), /* GD-5440 has identical id */
-       CHIP( CIRRUS_7543,      BT_ALPINE ),
-       CHIP( CIRRUS_7548,      BT_ALPINE ),
-       CHIP( CIRRUS_5480,      BT_GD5480 ), /* MacPicasso probably */
-       CHIP( CIRRUS_5446,      BT_PICASSO4 ), /* Picasso 4 is a GD5446 */
-       CHIP( CIRRUS_5462,      BT_LAGUNA ), /* CL Laguna */
-       CHIP( CIRRUS_5464,      BT_LAGUNA ), /* CL Laguna 3D */
-       CHIP( CIRRUS_5465,      BT_LAGUNA ), /* CL Laguna 3DA*/
+       CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */
+       CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
@@ -391,9 +391,9 @@ typedef enum {
 struct cirrusfb_info {
        struct fb_info *info;
 
-       caddr_t fbmem;
-       caddr_t regbase;
-       caddr_t mem;
+       u8 __iomem *fbmem;
+       u8 __iomem *regbase;
+       u8 __iomem *mem;
        unsigned long size;
        cirrusfb_board_t btype;
        unsigned char SFR;      /* Shadow of special function register */
@@ -404,7 +404,7 @@ struct cirrusfb_info {
        struct cirrusfb_regs currentmode;
        int blank_mode;
 
-       u32     pseudo_palette[17];
+       u32     pseudo_palette[16];
        struct { u8 red, green, blue, pad; } palette[256];
 
 #ifdef CONFIG_ZORRO
@@ -515,23 +515,25 @@ static const struct {
 
 
 /*--- Interface used by the world ------------------------------------------*/
-int cirrusfb_init (void);
-int cirrusfb_setup (char *options);
-
-int cirrusfb_open (struct fb_info *info, int user);
-int cirrusfb_release (struct fb_info *info, int user);
-int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-                       unsigned blue, unsigned transp,
-                       struct fb_info *info);
-int cirrusfb_check_var (struct fb_var_screeninfo *var,
-                       struct fb_info *info);
-int cirrusfb_set_par (struct fb_info *info);
-int cirrusfb_pan_display (struct fb_var_screeninfo *var,
-                         struct fb_info *info);
-int cirrusfb_blank (int blank_mode, struct fb_info *info);
-void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region);
-void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image);
+static int cirrusfb_init (void);
+#ifndef MODULE
+static int cirrusfb_setup (char *options);
+#endif
+
+static int cirrusfb_open (struct fb_info *info, int user);
+static int cirrusfb_release (struct fb_info *info, int user);
+static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+                              unsigned blue, unsigned transp,
+                              struct fb_info *info);
+static int cirrusfb_check_var (struct fb_var_screeninfo *var,
+                              struct fb_info *info);
+static int cirrusfb_set_par (struct fb_info *info);
+static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
+                                struct fb_info *info);
+static int cirrusfb_blank (int blank_mode, struct fb_info *info);
+static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region);
+static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image);
 
 /* function table of the above functions */
 static struct fb_ops cirrusfb_ops = {
@@ -546,7 +548,6 @@ static struct fb_ops cirrusfb_ops = {
        .fb_fillrect    = cirrusfb_fillrect,
        .fb_copyarea    = cirrusfb_copyarea,
        .fb_imageblit   = cirrusfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /*--- Hardware Specific Routines -------------------------------------------*/
@@ -571,13 +572,13 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c
                   unsigned char *green,
                   unsigned char *blue);
 #endif
-static void cirrusfb_WaitBLT (caddr_t regbase);
-static void cirrusfb_BitBLT (caddr_t regbase, int bits_per_pixel,
+static void cirrusfb_WaitBLT (u8 __iomem *regbase);
+static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
                             u_short curx, u_short cury,
                             u_short destx, u_short desty,
                             u_short width, u_short height,
                             u_short line_length);
-static void cirrusfb_RectFill (caddr_t regbase, int bits_per_pixel,
+static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
                               u_short x, u_short y,
                               u_short width, u_short height,
                               u_char color, u_short line_length);
@@ -600,7 +601,7 @@ static void cirrusfb_dbg_print_byte (const char *name, unsigned char val);
 static int opencount = 0;
 
 /*--- Open /dev/fbx ---------------------------------------------------------*/
-int cirrusfb_open (struct fb_info *info, int user)
+static int cirrusfb_open (struct fb_info *info, int user)
 {
        if (opencount++ == 0)
                switch_monitor (info->par, 1);
@@ -608,7 +609,7 @@ int cirrusfb_open (struct fb_info *info, int user)
 }
 
 /*--- Close /dev/fbx --------------------------------------------------------*/
-int cirrusfb_release (struct fb_info *info, int user)
+static int cirrusfb_release (struct fb_info *info, int user)
 {
        if (--opencount == 0)
                switch_monitor (info->par, 0);
@@ -660,8 +661,8 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
        return mclk;
 }
 
-int cirrusfb_check_var(struct fb_var_screeninfo *var,
-                      struct fb_info *info)
+static int cirrusfb_check_var(struct fb_var_screeninfo *var,
+                             struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
        int nom, den;           /* translyting from pixels->bytes */
@@ -752,6 +753,12 @@ int cirrusfb_check_var(struct fb_var_screeninfo *var,
 
        switch (var->bits_per_pixel) {
        case 1:
+               var->red.offset = 0;
+               var->red.length = 1;
+               var->green.offset = 0;
+               var->green.length = 1;
+               var->blue.offset = 0;
+               var->blue.length = 1;
                break;
 
        case 8:
@@ -1010,7 +1017,7 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
        struct cirrusfb_info *cinfo = info->par;
        struct fb_var_screeninfo *var = &info->var;
        struct cirrusfb_regs regs;
-       caddr_t regbase = cinfo->regbase;
+       u8 __iomem *regbase = cinfo->regbase;
        unsigned char tmp;
        int offset = 0, err;
        const struct cirrusfb_board_info_rec *bi;
@@ -1567,15 +1574,15 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
 
 /* for some reason incomprehensible to me, cirrusfb requires that you write
  * the registers twice for the settings to take..grr. -dte */
-int cirrusfb_set_par (struct fb_info *info)
+static int cirrusfb_set_par (struct fb_info *info)
 {
        cirrusfb_set_par_foo (info);
        return cirrusfb_set_par_foo (info);
 }
 
-int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-                       unsigned blue, unsigned transp,
-                       struct fb_info *info)
+static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+                              unsigned blue, unsigned transp,
+                              struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
 
@@ -1596,14 +1603,14 @@ int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
 
                switch (info->var.bits_per_pixel) {
                        case 8:
-                               ((u8*)(info->pseudo_palette))[regno] = v;
+                               cinfo->pseudo_palette[regno] = v;
                                break;
                        case 16:
-                               ((u16*)(info->pseudo_palette))[regno] = v;
+                               cinfo->pseudo_palette[regno] = v;
                                break;
                        case 24:
                        case 32:
-                               ((u32*)(info->pseudo_palette))[regno] = v;
+                               cinfo->pseudo_palette[regno] = v;
                                break;
                }
                return 0;
@@ -1626,8 +1633,8 @@ int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
 
        performs display panning - provided hardware permits this
 **************************************************************************/
-int cirrusfb_pan_display (struct fb_var_screeninfo *var,
-                         struct fb_info *info)
+static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
+                                struct fb_info *info)
 {
        int xoffset = 0;
        int yoffset = 0;
@@ -1696,7 +1703,7 @@ int cirrusfb_pan_display (struct fb_var_screeninfo *var,
 }
 
 
-int cirrusfb_blank (int blank_mode, struct fb_info *info)
+static int cirrusfb_blank (int blank_mode, struct fb_info *info)
 {
        /*
         *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
@@ -1721,7 +1728,8 @@ int cirrusfb_blank (int blank_mode, struct fb_info *info)
        }
 
        /* Undo current */
-       if (current_mode != VESA_NO_BLANKING) {
+       if (current_mode == FB_BLANK_NORMAL ||
+           current_mode == FB_BLANK_UNBLANK) {
                /* unblank the screen */
                val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE);
                vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);      /* clear "FullBandwidth" bit */
@@ -1730,22 +1738,23 @@ int cirrusfb_blank (int blank_mode, struct fb_info *info)
        }
 
        /* set new */
-       if(blank_mode != VESA_NO_BLANKING) {
+       if(blank_mode > FB_BLANK_NORMAL) {
                /* blank the screen */
                val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE);
                vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);      /* set "FullBandwidth" bit */
        }
 
        switch (blank_mode) {
-       case VESA_NO_BLANKING:
+       case FB_BLANK_UNBLANK:
+       case FB_BLANK_NORMAL:
                break;
-       case VESA_VSYNC_SUSPEND:
+       case FB_BLANK_VSYNC_SUSPEND:
                vga_wgfx (cinfo->regbase, CL_GRE, 0x04);
                break;
-       case VESA_HSYNC_SUSPEND:
+       case FB_BLANK_HSYNC_SUSPEND:
                vga_wgfx (cinfo->regbase, CL_GRE, 0x02);
                break;
-       case VESA_POWERDOWN:
+       case FB_BLANK_POWERDOWN:
                vga_wgfx (cinfo->regbase, CL_GRE, 0x06);
                break;
        default:
@@ -1755,7 +1764,9 @@ int cirrusfb_blank (int blank_mode, struct fb_info *info)
 
        cinfo->blank_mode = blank_mode;
        DPRINTK ("EXIT, returning 0\n");
-       return 0;
+
+       /* Let fbcon do a soft blank for us */
+       return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
 }
 /**** END   Hardware specific Routines **************************************/
 /****************************************************************************/
@@ -2009,24 +2020,27 @@ static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo,
                                   const struct fb_fillrect *region)
 {
        int m; /* bytes per pixel */
+       u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+               cinfo->pseudo_palette[region->color] : region->color;
+
        if(cinfo->info->var.bits_per_pixel == 1) {
                cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
                                  region->dx / 8, region->dy,
                                  region->width / 8, region->height,
-                                 region->color,
+                                 color,
                                  cinfo->currentmode.line_length);
        } else {
                m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
                cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
                                  region->dx * m, region->dy,
                                  region->width * m, region->height,
-                                 region->color,
+                                 color,
                                  cinfo->currentmode.line_length);
        }
        return;
 }
 
-void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
+static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
 {
        struct cirrusfb_info *cinfo = info->par;
        struct fb_fillrect modded;
@@ -2076,7 +2090,7 @@ static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo,
 }
 
 
-void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
        struct cirrusfb_info *cinfo = info->par;
        struct fb_copyarea modded;
@@ -2111,7 +2125,7 @@ void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        cirrusfb_prim_copyarea(cinfo, &modded);
 }
 
-void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct cirrusfb_info *cinfo = info->par;
 
@@ -2143,7 +2157,7 @@ static int release_io_ports = 0;
  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
  * seem to have. */
-static unsigned int cirrusfb_get_memsize (caddr_t regbase)
+static unsigned int cirrusfb_get_memsize (u8 __iomem *regbase)
 {
        unsigned long mem;
        unsigned char SRF;
@@ -2240,7 +2254,6 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
        struct fb_info *info = cinfo->info;
        struct fb_var_screeninfo *var = &info->var;
 
-       info->currcon = -1;
        info->par = cinfo;
        info->pseudo_palette = cinfo->pseudo_palette;
        info->flags = FBINFO_DEFAULT
@@ -2388,7 +2401,7 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
                get_prep_addrs (&board_addr, &cinfo->fbregs_phys);
 #endif
                /* PReP dies if we ioremap the IO registers, but it works w/out... */
-               cinfo->regbase = (char *) cinfo->fbregs_phys;
+               cinfo->regbase = (char __iomem *) cinfo->fbregs_phys;
        } else {
                DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
                get_pci_addrs (pdev, &board_addr, &cinfo->fbregs_phys);
@@ -2450,7 +2463,7 @@ err_out:
        return ret;
 }
 
-void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
+static void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
 {
        struct fb_info *info = pci_get_drvdata(pdev);
        DPRINTK ("ENTER\n");
@@ -2596,15 +2609,23 @@ static struct zorro_driver cirrusfb_zorro_driver = {
 };
 #endif /* CONFIG_ZORRO */
 
-int __init cirrusfb_init(void)
+static int __init cirrusfb_init(void)
 {
        int error = 0;
 
+#ifndef MODULE
+       char *option = NULL;
+
+       if (fb_get_options("cirrusfb", &option))
+               return -ENODEV;
+       cirrusfb_setup(option);
+#endif
+
 #ifdef CONFIG_ZORRO
-       error |= zorro_module_init(&cirrusfb_zorro_driver);
+       error |= zorro_register_driver(&cirrusfb_zorro_driver);
 #endif
 #ifdef CONFIG_PCI
-       error |= pci_module_init(&cirrusfb_pci_driver);
+       error |= pci_register_driver(&cirrusfb_pci_driver);
 #endif
        return error;
 }
@@ -2612,7 +2633,7 @@ int __init cirrusfb_init(void)
 
 
 #ifndef MODULE
-int __init cirrusfb_setup(char *options) {
+static int __init cirrusfb_setup(char *options) {
        char *this_opt, s[32];
        int i;
 
@@ -2647,7 +2668,7 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
 MODULE_LICENSE("GPL");
 
-void __exit cirrusfb_exit (void)
+static void __exit cirrusfb_exit (void)
 {
 #ifdef CONFIG_PCI
        pci_unregister_driver(&cirrusfb_pci_driver);
@@ -2657,8 +2678,9 @@ void __exit cirrusfb_exit (void)
 #endif
 }
 
-#ifdef MODULE
 module_init(cirrusfb_init);
+
+#ifdef MODULE
 module_exit(cirrusfb_exit);
 #endif
 
@@ -2850,7 +2872,7 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c
 *********************************************************************/
 
 /* FIXME: use interrupts instead */
-static void cirrusfb_WaitBLT (caddr_t regbase)
+static void cirrusfb_WaitBLT (u8 __iomem *regbase)
 {
        /* now busy-wait until we're done */
        while (vga_rgfx (regbase, CL_GR31) & 0x08)
@@ -2863,7 +2885,7 @@ static void cirrusfb_WaitBLT (caddr_t regbase)
        perform accelerated "scrolling"
 ********************************************************************/
 
-static void cirrusfb_BitBLT (caddr_t regbase, int bits_per_pixel,
+static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
                             u_short curx, u_short cury, u_short destx, u_short desty,
                             u_short width, u_short height, u_short line_length)
 {
@@ -2954,7 +2976,7 @@ static void cirrusfb_BitBLT (caddr_t regbase, int bits_per_pixel,
        perform accelerated rectangle fill
 ********************************************************************/
 
-static void cirrusfb_RectFill (caddr_t regbase, int bits_per_pixel,
+static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
                     u_short x, u_short y, u_short width, u_short height,
                     u_char color, u_short line_length)
 {