Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
0003  *
0004  * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
0005  *
0006  * Contributors (thanks, all!)
0007  *
0008  *  David Eger:
0009  *  Overhaul for Linux 2.6
0010  *
0011  *      Jeff Rugen:
0012  *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
0013  *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
0014  *
0015  *  Geert Uytterhoeven:
0016  *  Excellent code review.
0017  *
0018  *  Lars Hecking:
0019  *  Amiga updates and testing.
0020  *
0021  * Original cirrusfb author:  Frank Neumann
0022  *
0023  * Based on retz3fb.c and cirrusfb.c:
0024  *      Copyright (C) 1997 Jes Sorensen
0025  *      Copyright (C) 1996 Frank Neumann
0026  *
0027  ***************************************************************
0028  *
0029  * Format this code with GNU indent '-kr -i8 -pcs' options.
0030  *
0031  * This file is subject to the terms and conditions of the GNU General Public
0032  * License.  See the file COPYING in the main directory of this archive
0033  * for more details.
0034  *
0035  */
0036 
0037 #include <linux/module.h>
0038 #include <linux/kernel.h>
0039 #include <linux/errno.h>
0040 #include <linux/string.h>
0041 #include <linux/mm.h>
0042 #include <linux/delay.h>
0043 #include <linux/fb.h>
0044 #include <linux/init.h>
0045 
0046 #ifdef CONFIG_ZORRO
0047 #include <linux/zorro.h>
0048 #endif
0049 #ifdef CONFIG_PCI
0050 #include <linux/pci.h>
0051 #endif
0052 #ifdef CONFIG_AMIGA
0053 #include <asm/amigahw.h>
0054 #endif
0055 
0056 #include <video/vga.h>
0057 #include <video/cirrus.h>
0058 
0059 /*****************************************************************
0060  *
0061  * debugging and utility macros
0062  *
0063  */
0064 
0065 /* disable runtime assertions? */
0066 /* #define CIRRUSFB_NDEBUG */
0067 
0068 /* debugging assertions */
0069 #ifndef CIRRUSFB_NDEBUG
0070 #define assert(expr) \
0071     if (!(expr)) { \
0072         printk("Assertion failed! %s,%s,%s,line=%d\n", \
0073         #expr, __FILE__, __func__, __LINE__); \
0074     }
0075 #else
0076 #define assert(expr)
0077 #endif
0078 
0079 #define MB_ (1024 * 1024)
0080 
0081 /*****************************************************************
0082  *
0083  * chipset information
0084  *
0085  */
0086 
0087 /* board types */
0088 enum cirrus_board {
0089     BT_NONE = 0,
0090     BT_SD64,    /* GD5434 */
0091     BT_PICCOLO, /* GD5426 */
0092     BT_PICASSO, /* GD5426 or GD5428 */
0093     BT_SPECTRUM,    /* GD5426 or GD5428 */
0094     BT_PICASSO4,    /* GD5446 */
0095     BT_ALPINE,  /* GD543x/4x */
0096     BT_GD5480,
0097     BT_LAGUNA,  /* GD5462/64 */
0098     BT_LAGUNAB, /* GD5465 */
0099 };
0100 
0101 /*
0102  * per-board-type information, used for enumerating and abstracting
0103  * chip-specific information
0104  * NOTE: MUST be in the same order as enum cirrus_board in order to
0105  * use direct indexing on this array
0106  * NOTE: '__initdata' cannot be used as some of this info
0107  * is required at runtime.  Maybe separate into an init-only and
0108  * a run-time table?
0109  */
0110 static const struct cirrusfb_board_info_rec {
0111     char *name;     /* ASCII name of chipset */
0112     long maxclock[5];       /* maximum video clock */
0113     /* for  1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
0114     bool init_sr07 : 1; /* init SR07 during init_vgachip() */
0115     bool init_sr1f : 1; /* write SR1F during init_vgachip() */
0116     /* construct bit 19 of screen start address */
0117     bool scrn_start_bit19 : 1;
0118 
0119     /* initial SR07 value, then for each mode */
0120     unsigned char sr07;
0121     unsigned char sr07_1bpp;
0122     unsigned char sr07_1bpp_mux;
0123     unsigned char sr07_8bpp;
0124     unsigned char sr07_8bpp_mux;
0125 
0126     unsigned char sr1f; /* SR1F VGA initial register value */
0127 } cirrusfb_board_info[] = {
0128     [BT_SD64] = {
0129         .name           = "CL SD64",
0130         .maxclock       = {
0131             /* guess */
0132             /* the SD64/P4 have a higher max. videoclock */
0133             135100, 135100, 85500, 85500, 0
0134         },
0135         .init_sr07      = true,
0136         .init_sr1f      = true,
0137         .scrn_start_bit19   = true,
0138         .sr07           = 0xF0,
0139         .sr07_1bpp      = 0xF0,
0140         .sr07_1bpp_mux      = 0xF6,
0141         .sr07_8bpp      = 0xF1,
0142         .sr07_8bpp_mux      = 0xF7,
0143         .sr1f           = 0x1E
0144     },
0145     [BT_PICCOLO] = {
0146         .name           = "CL Piccolo",
0147         .maxclock       = {
0148             /* guess */
0149             90000, 90000, 90000, 90000, 90000
0150         },
0151         .init_sr07      = true,
0152         .init_sr1f      = true,
0153         .scrn_start_bit19   = false,
0154         .sr07           = 0x80,
0155         .sr07_1bpp      = 0x80,
0156         .sr07_8bpp      = 0x81,
0157         .sr1f           = 0x22
0158     },
0159     [BT_PICASSO] = {
0160         .name           = "CL Picasso",
0161         .maxclock       = {
0162             /* guess */
0163             90000, 90000, 90000, 90000, 90000
0164         },
0165         .init_sr07      = true,
0166         .init_sr1f      = true,
0167         .scrn_start_bit19   = false,
0168         .sr07           = 0x20,
0169         .sr07_1bpp      = 0x20,
0170         .sr07_8bpp      = 0x21,
0171         .sr1f           = 0x22
0172     },
0173     [BT_SPECTRUM] = {
0174         .name           = "CL Spectrum",
0175         .maxclock       = {
0176             /* guess */
0177             90000, 90000, 90000, 90000, 90000
0178         },
0179         .init_sr07      = true,
0180         .init_sr1f      = true,
0181         .scrn_start_bit19   = false,
0182         .sr07           = 0x80,
0183         .sr07_1bpp      = 0x80,
0184         .sr07_8bpp      = 0x81,
0185         .sr1f           = 0x22
0186     },
0187     [BT_PICASSO4] = {
0188         .name           = "CL Picasso4",
0189         .maxclock       = {
0190             135100, 135100, 85500, 85500, 0
0191         },
0192         .init_sr07      = true,
0193         .init_sr1f      = false,
0194         .scrn_start_bit19   = true,
0195         .sr07           = 0xA0,
0196         .sr07_1bpp      = 0xA0,
0197         .sr07_1bpp_mux      = 0xA6,
0198         .sr07_8bpp      = 0xA1,
0199         .sr07_8bpp_mux      = 0xA7,
0200         .sr1f           = 0
0201     },
0202     [BT_ALPINE] = {
0203         .name           = "CL Alpine",
0204         .maxclock       = {
0205             /* for the GD5430.  GD5446 can do more... */
0206             85500, 85500, 50000, 28500, 0
0207         },
0208         .init_sr07      = true,
0209         .init_sr1f      = true,
0210         .scrn_start_bit19   = true,
0211         .sr07           = 0xA0,
0212         .sr07_1bpp      = 0xA0,
0213         .sr07_1bpp_mux      = 0xA6,
0214         .sr07_8bpp      = 0xA1,
0215         .sr07_8bpp_mux      = 0xA7,
0216         .sr1f           = 0x1C
0217     },
0218     [BT_GD5480] = {
0219         .name           = "CL GD5480",
0220         .maxclock       = {
0221             135100, 200000, 200000, 135100, 135100
0222         },
0223         .init_sr07      = true,
0224         .init_sr1f      = true,
0225         .scrn_start_bit19   = true,
0226         .sr07           = 0x10,
0227         .sr07_1bpp      = 0x11,
0228         .sr07_8bpp      = 0x11,
0229         .sr1f           = 0x1C
0230     },
0231     [BT_LAGUNA] = {
0232         .name           = "CL Laguna",
0233         .maxclock       = {
0234             /* taken from X11 code */
0235             170000, 170000, 170000, 170000, 135100,
0236         },
0237         .init_sr07      = false,
0238         .init_sr1f      = false,
0239         .scrn_start_bit19   = true,
0240     },
0241     [BT_LAGUNAB] = {
0242         .name           = "CL Laguna AGP",
0243         .maxclock       = {
0244             /* taken from X11 code */
0245             170000, 250000, 170000, 170000, 135100,
0246         },
0247         .init_sr07      = false,
0248         .init_sr1f      = false,
0249         .scrn_start_bit19   = true,
0250     }
0251 };
0252 
0253 #ifdef CONFIG_PCI
0254 #define CHIP(id, btype) \
0255     { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
0256 
0257 static struct pci_device_id cirrusfb_pci_table[] = {
0258     CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
0259     CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
0260     CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
0261     CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
0262     CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
0263     CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
0264     CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
0265     CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
0266     CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
0267     CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
0268     CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
0269     { 0, }
0270 };
0271 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
0272 #undef CHIP
0273 #endif /* CONFIG_PCI */
0274 
0275 #ifdef CONFIG_ZORRO
0276 struct zorrocl {
0277     enum cirrus_board type; /* Board type */
0278     u32 regoffset;      /* Offset of registers in first Zorro device */
0279     u32 ramsize;        /* Size of video RAM in first Zorro device */
0280                 /* If zero, use autoprobe on RAM device */
0281     u32 ramoffset;      /* Offset of video RAM in first Zorro device */
0282     zorro_id ramid;     /* Zorro ID of RAM device */
0283     zorro_id ramid2;    /* Zorro ID of optional second RAM device */
0284 };
0285 
0286 static const struct zorrocl zcl_sd64 = {
0287     .type       = BT_SD64,
0288     .ramid      = ZORRO_PROD_HELFRICH_SD64_RAM,
0289 };
0290 
0291 static const struct zorrocl zcl_piccolo = {
0292     .type       = BT_PICCOLO,
0293     .ramid      = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
0294 };
0295 
0296 static const struct zorrocl zcl_picasso = {
0297     .type       = BT_PICASSO,
0298     .ramid      = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
0299 };
0300 
0301 static const struct zorrocl zcl_spectrum = {
0302     .type       = BT_SPECTRUM,
0303     .ramid      = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
0304 };
0305 
0306 static const struct zorrocl zcl_picasso4_z3 = {
0307     .type       = BT_PICASSO4,
0308     .regoffset  = 0x00600000,
0309     .ramsize    = 4 * MB_,
0310     .ramoffset  = 0x01000000,   /* 0x02000000 for 64 MiB boards */
0311 };
0312 
0313 static const struct zorrocl zcl_picasso4_z2 = {
0314     .type       = BT_PICASSO4,
0315     .regoffset  = 0x10000,
0316     .ramid      = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
0317     .ramid2     = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
0318 };
0319 
0320 
0321 static const struct zorro_device_id cirrusfb_zorro_table[] = {
0322     {
0323         .id     = ZORRO_PROD_HELFRICH_SD64_REG,
0324         .driver_data    = (unsigned long)&zcl_sd64,
0325     }, {
0326         .id     = ZORRO_PROD_HELFRICH_PICCOLO_REG,
0327         .driver_data    = (unsigned long)&zcl_piccolo,
0328     }, {
0329         .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
0330         .driver_data    = (unsigned long)&zcl_picasso,
0331     }, {
0332         .id     = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
0333         .driver_data    = (unsigned long)&zcl_spectrum,
0334     }, {
0335         .id     = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
0336         .driver_data    = (unsigned long)&zcl_picasso4_z3,
0337     }, {
0338         .id     = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG,
0339         .driver_data    = (unsigned long)&zcl_picasso4_z2,
0340     },
0341     { 0 }
0342 };
0343 MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
0344 #endif /* CONFIG_ZORRO */
0345 
0346 #ifdef CIRRUSFB_DEBUG
0347 enum cirrusfb_dbg_reg_class {
0348     CRT,
0349     SEQ
0350 };
0351 #endif      /* CIRRUSFB_DEBUG */
0352 
0353 /* info about board */
0354 struct cirrusfb_info {
0355     u8 __iomem *regbase;
0356     u8 __iomem *laguna_mmio;
0357     enum cirrus_board btype;
0358     unsigned char SFR;  /* Shadow of special function register */
0359 
0360     int multiplexing;
0361     int doubleVCLK;
0362     int blank_mode;
0363     u32 pseudo_palette[16];
0364 
0365     void (*unmap)(struct fb_info *info);
0366 };
0367 
0368 static bool noaccel;
0369 static char *mode_option = "640x480@60";
0370 
0371 /****************************************************************************/
0372 /**** BEGIN PROTOTYPES ******************************************************/
0373 
0374 /*--- Interface used by the world ------------------------------------------*/
0375 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
0376                 struct fb_info *info);
0377 
0378 /*--- Internal routines ----------------------------------------------------*/
0379 static void init_vgachip(struct fb_info *info);
0380 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
0381 static void WGen(const struct cirrusfb_info *cinfo,
0382          int regnum, unsigned char val);
0383 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
0384 static void AttrOn(const struct cirrusfb_info *cinfo);
0385 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
0386 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
0387 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
0388 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
0389           unsigned char red, unsigned char green, unsigned char blue);
0390 #if 0
0391 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
0392           unsigned char *red, unsigned char *green,
0393           unsigned char *blue);
0394 #endif
0395 static void cirrusfb_WaitBLT(u8 __iomem *regbase);
0396 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
0397                 u_short curx, u_short cury,
0398                 u_short destx, u_short desty,
0399                 u_short width, u_short height,
0400                 u_short line_length);
0401 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
0402                   u_short x, u_short y,
0403                   u_short width, u_short height,
0404                   u32 fg_color, u32 bg_color,
0405                   u_short line_length, u_char blitmode);
0406 
0407 static void bestclock(long freq, int *nom, int *den, int *div);
0408 
0409 #ifdef CIRRUSFB_DEBUG
0410 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
0411 static void cirrusfb_dbg_print_regs(struct fb_info *info,
0412                     caddr_t regbase,
0413                     enum cirrusfb_dbg_reg_class reg_class, ...);
0414 #endif /* CIRRUSFB_DEBUG */
0415 
0416 /*** END   PROTOTYPES ********************************************************/
0417 /*****************************************************************************/
0418 /*** BEGIN Interface Used by the World ***************************************/
0419 
0420 static inline int is_laguna(const struct cirrusfb_info *cinfo)
0421 {
0422     return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
0423 }
0424 
0425 static int opencount;
0426 
0427 /*--- Open /dev/fbx ---------------------------------------------------------*/
0428 static int cirrusfb_open(struct fb_info *info, int user)
0429 {
0430     if (opencount++ == 0)
0431         switch_monitor(info->par, 1);
0432     return 0;
0433 }
0434 
0435 /*--- Close /dev/fbx --------------------------------------------------------*/
0436 static int cirrusfb_release(struct fb_info *info, int user)
0437 {
0438     if (--opencount == 0)
0439         switch_monitor(info->par, 0);
0440     return 0;
0441 }
0442 
0443 /**** END   Interface used by the World *************************************/
0444 /****************************************************************************/
0445 /**** BEGIN Hardware specific Routines **************************************/
0446 
0447 /* Check if the MCLK is not a better clock source */
0448 static int cirrusfb_check_mclk(struct fb_info *info, long freq)
0449 {
0450     struct cirrusfb_info *cinfo = info->par;
0451     long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
0452 
0453     /* Read MCLK value */
0454     mclk = (14318 * mclk) >> 3;
0455     dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
0456 
0457     /* Determine if we should use MCLK instead of VCLK, and if so, what we
0458      * should divide it by to get VCLK
0459      */
0460 
0461     if (abs(freq - mclk) < 250) {
0462         dev_dbg(info->device, "Using VCLK = MCLK\n");
0463         return 1;
0464     } else if (abs(freq - (mclk / 2)) < 250) {
0465         dev_dbg(info->device, "Using VCLK = MCLK/2\n");
0466         return 2;
0467     }
0468 
0469     return 0;
0470 }
0471 
0472 static int cirrusfb_check_pixclock(struct fb_var_screeninfo *var,
0473                    struct fb_info *info)
0474 {
0475     long freq;
0476     long maxclock;
0477     struct cirrusfb_info *cinfo = info->par;
0478     unsigned maxclockidx = var->bits_per_pixel >> 3;
0479 
0480     /* convert from ps to kHz */
0481     freq = PICOS2KHZ(var->pixclock ? : 1);
0482 
0483     maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
0484     cinfo->multiplexing = 0;
0485 
0486     /* If the frequency is greater than we can support, we might be able
0487      * to use multiplexing for the video mode */
0488     if (freq > maxclock) {
0489         var->pixclock = KHZ2PICOS(maxclock);
0490 
0491         while ((freq = PICOS2KHZ(var->pixclock)) > maxclock)
0492             var->pixclock++;
0493     }
0494     dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
0495 
0496     /*
0497      * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
0498      * pixel clock
0499      */
0500     if (var->bits_per_pixel == 8) {
0501         switch (cinfo->btype) {
0502         case BT_ALPINE:
0503         case BT_SD64:
0504         case BT_PICASSO4:
0505             if (freq > 85500)
0506                 cinfo->multiplexing = 1;
0507             break;
0508         case BT_GD5480:
0509             if (freq > 135100)
0510                 cinfo->multiplexing = 1;
0511             break;
0512 
0513         default:
0514             break;
0515         }
0516     }
0517 
0518     /* If we have a 1MB 5434, we need to put ourselves in a mode where
0519      * the VCLK is double the pixel clock. */
0520     cinfo->doubleVCLK = 0;
0521     if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
0522         var->bits_per_pixel == 16) {
0523         cinfo->doubleVCLK = 1;
0524     }
0525 
0526     return 0;
0527 }
0528 
0529 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
0530                   struct fb_info *info)
0531 {
0532     int yres;
0533     /* memory size in pixels */
0534     unsigned int pixels;
0535     struct cirrusfb_info *cinfo = info->par;
0536 
0537     switch (var->bits_per_pixel) {
0538     case 1:
0539         var->red.offset = 0;
0540         var->red.length = 1;
0541         var->green = var->red;
0542         var->blue = var->red;
0543         break;
0544 
0545     case 8:
0546         var->red.offset = 0;
0547         var->red.length = 8;
0548         var->green = var->red;
0549         var->blue = var->red;
0550         break;
0551 
0552     case 16:
0553         var->red.offset = 11;
0554         var->green.offset = 5;
0555         var->blue.offset = 0;
0556         var->red.length = 5;
0557         var->green.length = 6;
0558         var->blue.length = 5;
0559         break;
0560 
0561     case 24:
0562         var->red.offset = 16;
0563         var->green.offset = 8;
0564         var->blue.offset = 0;
0565         var->red.length = 8;
0566         var->green.length = 8;
0567         var->blue.length = 8;
0568         break;
0569 
0570     default:
0571         dev_dbg(info->device,
0572             "Unsupported bpp size: %d\n", var->bits_per_pixel);
0573         return -EINVAL;
0574     }
0575 
0576     pixels = info->screen_size * 8 / var->bits_per_pixel;
0577     if (var->xres_virtual < var->xres)
0578         var->xres_virtual = var->xres;
0579     /* use highest possible virtual resolution */
0580     if (var->yres_virtual == -1) {
0581         var->yres_virtual = pixels / var->xres_virtual;
0582 
0583         dev_info(info->device,
0584              "virtual resolution set to maximum of %dx%d\n",
0585              var->xres_virtual, var->yres_virtual);
0586     }
0587     if (var->yres_virtual < var->yres)
0588         var->yres_virtual = var->yres;
0589 
0590     if (var->xres_virtual * var->yres_virtual > pixels) {
0591         dev_err(info->device, "mode %dx%dx%d rejected... "
0592               "virtual resolution too high to fit into video memory!\n",
0593             var->xres_virtual, var->yres_virtual,
0594             var->bits_per_pixel);
0595         return -EINVAL;
0596     }
0597 
0598     /* truncate xoffset and yoffset to maximum if too high */
0599     if (var->xoffset > var->xres_virtual - var->xres)
0600         var->xoffset = var->xres_virtual - var->xres - 1;
0601     if (var->yoffset > var->yres_virtual - var->yres)
0602         var->yoffset = var->yres_virtual - var->yres - 1;
0603 
0604     var->red.msb_right =
0605         var->green.msb_right =
0606         var->blue.msb_right =
0607         var->transp.offset =
0608         var->transp.length =
0609         var->transp.msb_right = 0;
0610 
0611     yres = var->yres;
0612     if (var->vmode & FB_VMODE_DOUBLE)
0613         yres *= 2;
0614     else if (var->vmode & FB_VMODE_INTERLACED)
0615         yres = (yres + 1) / 2;
0616 
0617     if (yres >= 1280) {
0618         dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
0619             "special treatment required! (TODO)\n");
0620         return -EINVAL;
0621     }
0622 
0623     if (cirrusfb_check_pixclock(var, info))
0624         return -EINVAL;
0625 
0626     if (!is_laguna(cinfo))
0627         var->accel_flags = FB_ACCELF_TEXT;
0628 
0629     return 0;
0630 }
0631 
0632 static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
0633 {
0634     struct cirrusfb_info *cinfo = info->par;
0635     unsigned char old1f, old1e;
0636 
0637     assert(cinfo != NULL);
0638     old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
0639 
0640     if (div) {
0641         dev_dbg(info->device, "Set %s as pixclock source.\n",
0642             (div == 2) ? "MCLK/2" : "MCLK");
0643         old1f |= 0x40;
0644         old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
0645         if (div == 2)
0646             old1e |= 1;
0647 
0648         vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
0649     }
0650     vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
0651 }
0652 
0653 /*************************************************************************
0654     cirrusfb_set_par_foo()
0655 
0656     actually writes the values for a new video mode into the hardware,
0657 **************************************************************************/
0658 static int cirrusfb_set_par_foo(struct fb_info *info)
0659 {
0660     struct cirrusfb_info *cinfo = info->par;
0661     struct fb_var_screeninfo *var = &info->var;
0662     u8 __iomem *regbase = cinfo->regbase;
0663     unsigned char tmp;
0664     int pitch;
0665     const struct cirrusfb_board_info_rec *bi;
0666     int hdispend, hsyncstart, hsyncend, htotal;
0667     int yres, vdispend, vsyncstart, vsyncend, vtotal;
0668     long freq;
0669     int nom, den, div;
0670     unsigned int control = 0, format = 0, threshold = 0;
0671 
0672     dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
0673            var->xres, var->yres, var->bits_per_pixel);
0674 
0675     switch (var->bits_per_pixel) {
0676     case 1:
0677         info->fix.line_length = var->xres_virtual / 8;
0678         info->fix.visual = FB_VISUAL_MONO10;
0679         break;
0680 
0681     case 8:
0682         info->fix.line_length = var->xres_virtual;
0683         info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
0684         break;
0685 
0686     case 16:
0687     case 24:
0688         info->fix.line_length = var->xres_virtual *
0689                     var->bits_per_pixel >> 3;
0690         info->fix.visual = FB_VISUAL_TRUECOLOR;
0691         break;
0692     }
0693     info->fix.type = FB_TYPE_PACKED_PIXELS;
0694 
0695     init_vgachip(info);
0696 
0697     bi = &cirrusfb_board_info[cinfo->btype];
0698 
0699     hsyncstart = var->xres + var->right_margin;
0700     hsyncend = hsyncstart + var->hsync_len;
0701     htotal = (hsyncend + var->left_margin) / 8;
0702     hdispend = var->xres / 8;
0703     hsyncstart = hsyncstart / 8;
0704     hsyncend = hsyncend / 8;
0705 
0706     vdispend = var->yres;
0707     vsyncstart = vdispend + var->lower_margin;
0708     vsyncend = vsyncstart + var->vsync_len;
0709     vtotal = vsyncend + var->upper_margin;
0710 
0711     if (var->vmode & FB_VMODE_DOUBLE) {
0712         vdispend *= 2;
0713         vsyncstart *= 2;
0714         vsyncend *= 2;
0715         vtotal *= 2;
0716     } else if (var->vmode & FB_VMODE_INTERLACED) {
0717         vdispend = (vdispend + 1) / 2;
0718         vsyncstart = (vsyncstart + 1) / 2;
0719         vsyncend = (vsyncend + 1) / 2;
0720         vtotal = (vtotal + 1) / 2;
0721     }
0722     yres = vdispend;
0723     if (yres >= 1024) {
0724         vtotal /= 2;
0725         vsyncstart /= 2;
0726         vsyncend /= 2;
0727         vdispend /= 2;
0728     }
0729 
0730     vdispend -= 1;
0731     vsyncstart -= 1;
0732     vsyncend -= 1;
0733     vtotal -= 2;
0734 
0735     if (cinfo->multiplexing) {
0736         htotal /= 2;
0737         hsyncstart /= 2;
0738         hsyncend /= 2;
0739         hdispend /= 2;
0740     }
0741 
0742     htotal -= 5;
0743     hdispend -= 1;
0744     hsyncstart += 1;
0745     hsyncend += 1;
0746 
0747     /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
0748     vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);   /* previously: 0x00) */
0749 
0750     /* if debugging is enabled, all parameters get output before writing */
0751     dev_dbg(info->device, "CRT0: %d\n", htotal);
0752     vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
0753 
0754     dev_dbg(info->device, "CRT1: %d\n", hdispend);
0755     vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
0756 
0757     dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
0758     vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
0759 
0760     /*  + 128: Compatible read */
0761     dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
0762     vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
0763          128 + ((htotal + 5) % 32));
0764 
0765     dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
0766     vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
0767 
0768     tmp = hsyncend % 32;
0769     if ((htotal + 5) & 32)
0770         tmp += 128;
0771     dev_dbg(info->device, "CRT5: %d\n", tmp);
0772     vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
0773 
0774     dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
0775     vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
0776 
0777     tmp = 16;       /* LineCompare bit #9 */
0778     if (vtotal & 256)
0779         tmp |= 1;
0780     if (vdispend & 256)
0781         tmp |= 2;
0782     if (vsyncstart & 256)
0783         tmp |= 4;
0784     if ((vdispend + 1) & 256)
0785         tmp |= 8;
0786     if (vtotal & 512)
0787         tmp |= 32;
0788     if (vdispend & 512)
0789         tmp |= 64;
0790     if (vsyncstart & 512)
0791         tmp |= 128;
0792     dev_dbg(info->device, "CRT7: %d\n", tmp);
0793     vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
0794 
0795     tmp = 0x40;     /* LineCompare bit #8 */
0796     if ((vdispend + 1) & 512)
0797         tmp |= 0x20;
0798     if (var->vmode & FB_VMODE_DOUBLE)
0799         tmp |= 0x80;
0800     dev_dbg(info->device, "CRT9: %d\n", tmp);
0801     vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
0802 
0803     dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
0804     vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
0805 
0806     dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
0807     vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
0808 
0809     dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
0810     vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
0811 
0812     dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
0813     vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
0814 
0815     dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
0816     vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
0817 
0818     dev_dbg(info->device, "CRT18: 0xff\n");
0819     vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
0820 
0821     tmp = 0;
0822     if (var->vmode & FB_VMODE_INTERLACED)
0823         tmp |= 1;
0824     if ((htotal + 5) & 64)
0825         tmp |= 16;
0826     if ((htotal + 5) & 128)
0827         tmp |= 32;
0828     if (vtotal & 256)
0829         tmp |= 64;
0830     if (vtotal & 512)
0831         tmp |= 128;
0832 
0833     dev_dbg(info->device, "CRT1a: %d\n", tmp);
0834     vga_wcrt(regbase, CL_CRT1A, tmp);
0835 
0836     freq = PICOS2KHZ(var->pixclock);
0837     if (var->bits_per_pixel == 24)
0838         if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
0839             freq *= 3;
0840     if (cinfo->multiplexing)
0841         freq /= 2;
0842     if (cinfo->doubleVCLK)
0843         freq *= 2;
0844 
0845     bestclock(freq, &nom, &den, &div);
0846 
0847     dev_dbg(info->device, "VCLK freq: %ld kHz  nom: %d  den: %d  div: %d\n",
0848         freq, nom, den, div);
0849 
0850     /* set VCLK0 */
0851     /* hardware RefClock: 14.31818 MHz */
0852     /* formula: VClk = (OSC * N) / (D * (1+P)) */
0853     /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
0854 
0855     if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
0856         cinfo->btype == BT_SD64) {
0857         /* if freq is close to mclk or mclk/2 select mclk
0858          * as clock source
0859          */
0860         int divMCLK = cirrusfb_check_mclk(info, freq);
0861         if (divMCLK)
0862             nom = 0;
0863         cirrusfb_set_mclk_as_source(info, divMCLK);
0864     }
0865     if (is_laguna(cinfo)) {
0866         long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
0867         unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
0868         unsigned short tile_control;
0869 
0870         if (cinfo->btype == BT_LAGUNAB) {
0871             tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
0872             tile_control &= ~0x80;
0873             fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
0874         }
0875 
0876         fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
0877         fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
0878         control = fb_readw(cinfo->laguna_mmio + 0x402);
0879         threshold = fb_readw(cinfo->laguna_mmio + 0xea);
0880         control &= ~0x6800;
0881         format = 0;
0882         threshold &= 0xffc0 & 0x3fbf;
0883     }
0884     if (nom) {
0885         tmp = den << 1;
0886         if (div != 0)
0887             tmp |= 1;
0888         /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
0889         if ((cinfo->btype == BT_SD64) ||
0890             (cinfo->btype == BT_ALPINE) ||
0891             (cinfo->btype == BT_GD5480))
0892             tmp |= 0x80;
0893 
0894         /* Laguna chipset has reversed clock registers */
0895         if (is_laguna(cinfo)) {
0896             vga_wseq(regbase, CL_SEQRE, tmp);
0897             vga_wseq(regbase, CL_SEQR1E, nom);
0898         } else {
0899             vga_wseq(regbase, CL_SEQRE, nom);
0900             vga_wseq(regbase, CL_SEQR1E, tmp);
0901         }
0902     }
0903 
0904     if (yres >= 1024)
0905         /* 1280x1024 */
0906         vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
0907     else
0908         /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
0909          * address wrap, no compat. */
0910         vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
0911 
0912     /* don't know if it would hurt to also program this if no interlaced */
0913     /* mode is used, but I feel better this way.. :-) */
0914     if (var->vmode & FB_VMODE_INTERLACED)
0915         vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
0916     else
0917         vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
0918 
0919     /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
0920     /* enable display memory & CRTC I/O address for color mode */
0921     tmp = 0x03 | 0xc;
0922     if (var->sync & FB_SYNC_HOR_HIGH_ACT)
0923         tmp |= 0x40;
0924     if (var->sync & FB_SYNC_VERT_HIGH_ACT)
0925         tmp |= 0x80;
0926     WGen(cinfo, VGA_MIS_W, tmp);
0927 
0928     /* text cursor on and start line */
0929     vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
0930     /* text cursor end line */
0931     vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
0932 
0933     /******************************************************
0934      *
0935      * 1 bpp
0936      *
0937      */
0938 
0939     /* programming for different color depths */
0940     if (var->bits_per_pixel == 1) {
0941         dev_dbg(info->device, "preparing for 1 bit deep display\n");
0942         vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
0943 
0944         /* SR07 */
0945         switch (cinfo->btype) {
0946         case BT_SD64:
0947         case BT_PICCOLO:
0948         case BT_PICASSO:
0949         case BT_SPECTRUM:
0950         case BT_PICASSO4:
0951         case BT_ALPINE:
0952         case BT_GD5480:
0953             vga_wseq(regbase, CL_SEQR7,
0954                  cinfo->multiplexing ?
0955                     bi->sr07_1bpp_mux : bi->sr07_1bpp);
0956             break;
0957 
0958         case BT_LAGUNA:
0959         case BT_LAGUNAB:
0960             vga_wseq(regbase, CL_SEQR7,
0961                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
0962             break;
0963 
0964         default:
0965             dev_warn(info->device, "unknown Board\n");
0966             break;
0967         }
0968 
0969         /* Extended Sequencer Mode */
0970         switch (cinfo->btype) {
0971 
0972         case BT_PICCOLO:
0973         case BT_SPECTRUM:
0974             /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
0975             vga_wseq(regbase, CL_SEQRF, 0xb0);
0976             break;
0977 
0978         case BT_PICASSO:
0979             /* ## vorher d0 avoid FIFO underruns..? */
0980             vga_wseq(regbase, CL_SEQRF, 0xd0);
0981             break;
0982 
0983         case BT_SD64:
0984         case BT_PICASSO4:
0985         case BT_ALPINE:
0986         case BT_GD5480:
0987         case BT_LAGUNA:
0988         case BT_LAGUNAB:
0989             /* do nothing */
0990             break;
0991 
0992         default:
0993             dev_warn(info->device, "unknown Board\n");
0994             break;
0995         }
0996 
0997         /* pixel mask: pass-through for first plane */
0998         WGen(cinfo, VGA_PEL_MSK, 0x01);
0999         if (cinfo->multiplexing)
1000             /* hidden dac reg: 1280x1024 */
1001             WHDR(cinfo, 0x4a);
1002         else
1003             /* hidden dac: nothing */
1004             WHDR(cinfo, 0);
1005         /* memory mode: odd/even, ext. memory */
1006         vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1007         /* plane mask: only write to first plane */
1008         vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1009     }
1010 
1011     /******************************************************
1012      *
1013      * 8 bpp
1014      *
1015      */
1016 
1017     else if (var->bits_per_pixel == 8) {
1018         dev_dbg(info->device, "preparing for 8 bit deep display\n");
1019         switch (cinfo->btype) {
1020         case BT_SD64:
1021         case BT_PICCOLO:
1022         case BT_PICASSO:
1023         case BT_SPECTRUM:
1024         case BT_PICASSO4:
1025         case BT_ALPINE:
1026         case BT_GD5480:
1027             vga_wseq(regbase, CL_SEQR7,
1028                   cinfo->multiplexing ?
1029                     bi->sr07_8bpp_mux : bi->sr07_8bpp);
1030             break;
1031 
1032         case BT_LAGUNA:
1033         case BT_LAGUNAB:
1034             vga_wseq(regbase, CL_SEQR7,
1035                 vga_rseq(regbase, CL_SEQR7) | 0x01);
1036             threshold |= 0x10;
1037             break;
1038 
1039         default:
1040             dev_warn(info->device, "unknown Board\n");
1041             break;
1042         }
1043 
1044         switch (cinfo->btype) {
1045         case BT_PICCOLO:
1046         case BT_PICASSO:
1047         case BT_SPECTRUM:
1048             /* Fast Page-Mode writes */
1049             vga_wseq(regbase, CL_SEQRF, 0xb0);
1050             break;
1051 
1052         case BT_PICASSO4:
1053 #ifdef CONFIG_ZORRO
1054             /* ### INCOMPLETE!! */
1055             vga_wseq(regbase, CL_SEQRF, 0xb8);
1056 #endif
1057         case BT_ALPINE:
1058         case BT_SD64:
1059         case BT_GD5480:
1060         case BT_LAGUNA:
1061         case BT_LAGUNAB:
1062             /* do nothing */
1063             break;
1064 
1065         default:
1066             dev_warn(info->device, "unknown board\n");
1067             break;
1068         }
1069 
1070         /* mode register: 256 color mode */
1071         vga_wgfx(regbase, VGA_GFX_MODE, 64);
1072         if (cinfo->multiplexing)
1073             /* hidden dac reg: 1280x1024 */
1074             WHDR(cinfo, 0x4a);
1075         else
1076             /* hidden dac: nothing */
1077             WHDR(cinfo, 0);
1078     }
1079 
1080     /******************************************************
1081      *
1082      * 16 bpp
1083      *
1084      */
1085 
1086     else if (var->bits_per_pixel == 16) {
1087         dev_dbg(info->device, "preparing for 16 bit deep display\n");
1088         switch (cinfo->btype) {
1089         case BT_PICCOLO:
1090         case BT_SPECTRUM:
1091             vga_wseq(regbase, CL_SEQR7, 0x87);
1092             /* Fast Page-Mode writes */
1093             vga_wseq(regbase, CL_SEQRF, 0xb0);
1094             break;
1095 
1096         case BT_PICASSO:
1097             vga_wseq(regbase, CL_SEQR7, 0x27);
1098             /* Fast Page-Mode writes */
1099             vga_wseq(regbase, CL_SEQRF, 0xb0);
1100             break;
1101 
1102         case BT_SD64:
1103         case BT_PICASSO4:
1104         case BT_ALPINE:
1105             /* Extended Sequencer Mode: 256c col. mode */
1106             vga_wseq(regbase, CL_SEQR7,
1107                     cinfo->doubleVCLK ? 0xa3 : 0xa7);
1108             break;
1109 
1110         case BT_GD5480:
1111             vga_wseq(regbase, CL_SEQR7, 0x17);
1112             /* We already set SRF and SR1F */
1113             break;
1114 
1115         case BT_LAGUNA:
1116         case BT_LAGUNAB:
1117             vga_wseq(regbase, CL_SEQR7,
1118                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1119             control |= 0x2000;
1120             format |= 0x1400;
1121             threshold |= 0x10;
1122             break;
1123 
1124         default:
1125             dev_warn(info->device, "unknown Board\n");
1126             break;
1127         }
1128 
1129         /* mode register: 256 color mode */
1130         vga_wgfx(regbase, VGA_GFX_MODE, 64);
1131 #ifdef CONFIG_PCI
1132         WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
1133 #elif defined(CONFIG_ZORRO)
1134         /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1135         WHDR(cinfo, 0xa0);  /* hidden dac reg: nothing special */
1136 #endif
1137     }
1138 
1139     /******************************************************
1140      *
1141      * 24 bpp
1142      *
1143      */
1144 
1145     else if (var->bits_per_pixel == 24) {
1146         dev_dbg(info->device, "preparing for 24 bit deep display\n");
1147         switch (cinfo->btype) {
1148         case BT_PICCOLO:
1149         case BT_SPECTRUM:
1150             vga_wseq(regbase, CL_SEQR7, 0x85);
1151             /* Fast Page-Mode writes */
1152             vga_wseq(regbase, CL_SEQRF, 0xb0);
1153             break;
1154 
1155         case BT_PICASSO:
1156             vga_wseq(regbase, CL_SEQR7, 0x25);
1157             /* Fast Page-Mode writes */
1158             vga_wseq(regbase, CL_SEQRF, 0xb0);
1159             break;
1160 
1161         case BT_SD64:
1162         case BT_PICASSO4:
1163         case BT_ALPINE:
1164             /* Extended Sequencer Mode: 256c col. mode */
1165             vga_wseq(regbase, CL_SEQR7, 0xa5);
1166             break;
1167 
1168         case BT_GD5480:
1169             vga_wseq(regbase, CL_SEQR7, 0x15);
1170             /* We already set SRF and SR1F */
1171             break;
1172 
1173         case BT_LAGUNA:
1174         case BT_LAGUNAB:
1175             vga_wseq(regbase, CL_SEQR7,
1176                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1177             control |= 0x4000;
1178             format |= 0x2400;
1179             threshold |= 0x20;
1180             break;
1181 
1182         default:
1183             dev_warn(info->device, "unknown Board\n");
1184             break;
1185         }
1186 
1187         /* mode register: 256 color mode */
1188         vga_wgfx(regbase, VGA_GFX_MODE, 64);
1189         /* hidden dac reg: 8-8-8 mode (24 or 32) */
1190         WHDR(cinfo, 0xc5);
1191     }
1192 
1193     /******************************************************
1194      *
1195      * unknown/unsupported bpp
1196      *
1197      */
1198 
1199     else
1200         dev_err(info->device,
1201             "What's this? requested color depth == %d.\n",
1202             var->bits_per_pixel);
1203 
1204     pitch = info->fix.line_length >> 3;
1205     vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1206     tmp = 0x22;
1207     if (pitch & 0x100)
1208         tmp |= 0x10;    /* offset overflow bit */
1209 
1210     /* screen start addr #16-18, fastpagemode cycles */
1211     vga_wcrt(regbase, CL_CRT1B, tmp);
1212 
1213     /* screen start address bit 19 */
1214     if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1215         vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
1216 
1217     if (is_laguna(cinfo)) {
1218         tmp = 0;
1219         if ((htotal + 5) & 256)
1220             tmp |= 128;
1221         if (hdispend & 256)
1222             tmp |= 64;
1223         if (hsyncstart & 256)
1224             tmp |= 48;
1225         if (vtotal & 1024)
1226             tmp |= 8;
1227         if (vdispend & 1024)
1228             tmp |= 4;
1229         if (vsyncstart & 1024)
1230             tmp |= 3;
1231 
1232         vga_wcrt(regbase, CL_CRT1E, tmp);
1233         dev_dbg(info->device, "CRT1e: %d\n", tmp);
1234     }
1235 
1236     /* pixel panning */
1237     vga_wattr(regbase, CL_AR33, 0);
1238 
1239     /* [ EGS: SetOffset(); ] */
1240     /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1241     AttrOn(cinfo);
1242 
1243     if (is_laguna(cinfo)) {
1244         /* no tiles */
1245         fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1246         fb_writew(format, cinfo->laguna_mmio + 0xc0);
1247         fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1248     }
1249     /* finally, turn on everything - turn off "FullBandwidth" bit */
1250     /* also, set "DotClock%2" bit where requested */
1251     tmp = 0x01;
1252 
1253 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1254     if (var->vmode & FB_VMODE_CLOCK_HALVE)
1255     tmp |= 0x08;
1256 */
1257 
1258     vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1259     dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1260 
1261 #ifdef CIRRUSFB_DEBUG
1262     cirrusfb_dbg_reg_dump(info, NULL);
1263 #endif
1264 
1265     return 0;
1266 }
1267 
1268 /* for some reason incomprehensible to me, cirrusfb requires that you write
1269  * the registers twice for the settings to take..grr. -dte */
1270 static int cirrusfb_set_par(struct fb_info *info)
1271 {
1272     cirrusfb_set_par_foo(info);
1273     return cirrusfb_set_par_foo(info);
1274 }
1275 
1276 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1277                   unsigned blue, unsigned transp,
1278                   struct fb_info *info)
1279 {
1280     struct cirrusfb_info *cinfo = info->par;
1281 
1282     if (regno > 255)
1283         return -EINVAL;
1284 
1285     if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1286         u32 v;
1287         red >>= (16 - info->var.red.length);
1288         green >>= (16 - info->var.green.length);
1289         blue >>= (16 - info->var.blue.length);
1290 
1291         if (regno >= 16)
1292             return 1;
1293         v = (red << info->var.red.offset) |
1294             (green << info->var.green.offset) |
1295             (blue << info->var.blue.offset);
1296 
1297         cinfo->pseudo_palette[regno] = v;
1298         return 0;
1299     }
1300 
1301     if (info->var.bits_per_pixel == 8)
1302         WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1303 
1304     return 0;
1305 
1306 }
1307 
1308 /*************************************************************************
1309     cirrusfb_pan_display()
1310 
1311     performs display panning - provided hardware permits this
1312 **************************************************************************/
1313 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1314                 struct fb_info *info)
1315 {
1316     int xoffset;
1317     unsigned long base;
1318     unsigned char tmp, xpix;
1319     struct cirrusfb_info *cinfo = info->par;
1320 
1321     /* no range checks for xoffset and yoffset,   */
1322     /* as fb_pan_display has already done this */
1323     if (var->vmode & FB_VMODE_YWRAP)
1324         return -EINVAL;
1325 
1326     xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1327 
1328     base = var->yoffset * info->fix.line_length + xoffset;
1329 
1330     if (info->var.bits_per_pixel == 1) {
1331         /* base is already correct */
1332         xpix = (unsigned char) (var->xoffset % 8);
1333     } else {
1334         base /= 4;
1335         xpix = (unsigned char) ((xoffset % 4) * 2);
1336     }
1337 
1338     if (!is_laguna(cinfo))
1339         cirrusfb_WaitBLT(cinfo->regbase);
1340 
1341     /* lower 8 + 8 bits of screen start address */
1342     vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1343     vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1344 
1345     /* 0xf2 is %11110010, exclude tmp bits */
1346     tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1347     /* construct bits 16, 17 and 18 of screen start address */
1348     if (base & 0x10000)
1349         tmp |= 0x01;
1350     if (base & 0x20000)
1351         tmp |= 0x04;
1352     if (base & 0x40000)
1353         tmp |= 0x08;
1354 
1355     vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1356 
1357     /* construct bit 19 of screen start address */
1358     if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
1359         tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
1360         if (is_laguna(cinfo))
1361             tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
1362         else
1363             tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
1364         vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
1365     }
1366 
1367     /* write pixel panning value to AR33; this does not quite work in 8bpp
1368      *
1369      * ### Piccolo..? Will this work?
1370      */
1371     if (info->var.bits_per_pixel == 1)
1372         vga_wattr(cinfo->regbase, CL_AR33, xpix);
1373 
1374     return 0;
1375 }
1376 
1377 static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1378 {
1379     /*
1380      * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1381      * then the caller blanks by setting the CLUT (Color Look Up Table)
1382      * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1383      * failed due to e.g. a video mode which doesn't support it.
1384      * Implements VESA suspend and powerdown modes on hardware that
1385      * supports disabling hsync/vsync:
1386      *   blank_mode == 2: suspend vsync
1387      *   blank_mode == 3: suspend hsync
1388      *   blank_mode == 4: powerdown
1389      */
1390     unsigned char val;
1391     struct cirrusfb_info *cinfo = info->par;
1392     int current_mode = cinfo->blank_mode;
1393 
1394     dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1395 
1396     if (info->state != FBINFO_STATE_RUNNING ||
1397         current_mode == blank_mode) {
1398         dev_dbg(info->device, "EXIT, returning 0\n");
1399         return 0;
1400     }
1401 
1402     /* Undo current */
1403     if (current_mode == FB_BLANK_NORMAL ||
1404         current_mode == FB_BLANK_UNBLANK)
1405         /* clear "FullBandwidth" bit */
1406         val = 0;
1407     else
1408         /* set "FullBandwidth" bit */
1409         val = 0x20;
1410 
1411     val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1412     vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1413 
1414     switch (blank_mode) {
1415     case FB_BLANK_UNBLANK:
1416     case FB_BLANK_NORMAL:
1417         val = 0x00;
1418         break;
1419     case FB_BLANK_VSYNC_SUSPEND:
1420         val = 0x04;
1421         break;
1422     case FB_BLANK_HSYNC_SUSPEND:
1423         val = 0x02;
1424         break;
1425     case FB_BLANK_POWERDOWN:
1426         val = 0x06;
1427         break;
1428     default:
1429         dev_dbg(info->device, "EXIT, returning 1\n");
1430         return 1;
1431     }
1432 
1433     vga_wgfx(cinfo->regbase, CL_GRE, val);
1434 
1435     cinfo->blank_mode = blank_mode;
1436     dev_dbg(info->device, "EXIT, returning 0\n");
1437 
1438     /* Let fbcon do a soft blank for us */
1439     return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1440 }
1441 
1442 /**** END   Hardware specific Routines **************************************/
1443 /****************************************************************************/
1444 /**** BEGIN Internal Routines ***********************************************/
1445 
1446 static void init_vgachip(struct fb_info *info)
1447 {
1448     struct cirrusfb_info *cinfo = info->par;
1449     const struct cirrusfb_board_info_rec *bi;
1450 
1451     assert(cinfo != NULL);
1452 
1453     bi = &cirrusfb_board_info[cinfo->btype];
1454 
1455     /* reset board globally */
1456     switch (cinfo->btype) {
1457     case BT_PICCOLO:
1458         WSFR(cinfo, 0x01);
1459         udelay(500);
1460         WSFR(cinfo, 0x51);
1461         udelay(500);
1462         break;
1463     case BT_PICASSO:
1464         WSFR2(cinfo, 0xff);
1465         udelay(500);
1466         break;
1467     case BT_SD64:
1468     case BT_SPECTRUM:
1469         WSFR(cinfo, 0x1f);
1470         udelay(500);
1471         WSFR(cinfo, 0x4f);
1472         udelay(500);
1473         break;
1474     case BT_PICASSO4:
1475         /* disable flickerfixer */
1476         vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1477         mdelay(100);
1478         /* mode */
1479         vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1480         fallthrough;
1481     case BT_GD5480:
1482         /* from Klaus' NetBSD driver: */
1483         vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1484         fallthrough;
1485     case BT_ALPINE:
1486         /* put blitter into 542x compat */
1487         vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1488         break;
1489 
1490     case BT_LAGUNA:
1491     case BT_LAGUNAB:
1492         /* Nothing to do to reset the board. */
1493         break;
1494 
1495     default:
1496         dev_err(info->device, "Warning: Unknown board type\n");
1497         break;
1498     }
1499 
1500     /* make sure RAM size set by this point */
1501     assert(info->screen_size > 0);
1502 
1503     /* the P4 is not fully initialized here; I rely on it having been */
1504     /* inited under AmigaOS already, which seems to work just fine    */
1505     /* (Klaus advised to do it this way)                  */
1506 
1507     if (cinfo->btype != BT_PICASSO4) {
1508         WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1509         WGen(cinfo, CL_POS102, 0x01);
1510         WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1511 
1512         if (cinfo->btype != BT_SD64)
1513             WGen(cinfo, CL_VSSM2, 0x01);
1514 
1515         /* reset sequencer logic */
1516         vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1517 
1518         /* FullBandwidth (video off) and 8/9 dot clock */
1519         vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1520 
1521         /* "magic cookie" - doesn't make any sense to me.. */
1522 /*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */
1523         /* unlock all extension registers */
1524         vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1525 
1526         switch (cinfo->btype) {
1527         case BT_GD5480:
1528             vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1529             break;
1530         case BT_ALPINE:
1531         case BT_LAGUNA:
1532         case BT_LAGUNAB:
1533             break;
1534         case BT_SD64:
1535 #ifdef CONFIG_ZORRO
1536             vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1537 #endif
1538             break;
1539         default:
1540             vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1541             vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1542             break;
1543         }
1544     }
1545     /* plane mask: nothing */
1546     vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1547     /* character map select: doesn't even matter in gx mode */
1548     vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1549     /* memory mode: chain4, ext. memory */
1550     vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1551 
1552     /* controller-internal base address of video memory */
1553     if (bi->init_sr07)
1554         vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1555 
1556     /*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1557     /* EEPROM control: shouldn't be necessary to write to this at all.. */
1558 
1559     /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1560     vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1561     /* graphics cursor Y position (..."... ) */
1562     vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1563     /* graphics cursor attributes */
1564     vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1565     /* graphics cursor pattern address */
1566     vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1567 
1568     /* writing these on a P4 might give problems..  */
1569     if (cinfo->btype != BT_PICASSO4) {
1570         /* configuration readback and ext. color */
1571         vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1572         /* signature generator */
1573         vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1574     }
1575 
1576     /* Screen A preset row scan: none */
1577     vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1578     /* Text cursor start: disable text cursor */
1579     vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1580     /* Text cursor end: - */
1581     vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1582     /* text cursor location high: 0 */
1583     vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1584     /* text cursor location low: 0 */
1585     vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1586 
1587     /* Underline Row scanline: - */
1588     vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1589     /* ### add 0x40 for text modes with > 30 MHz pixclock */
1590     /* ext. display controls: ext.adr. wrap */
1591     vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1592 
1593     /* Set/Reset registers: - */
1594     vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1595     /* Set/Reset enable: - */
1596     vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1597     /* Color Compare: - */
1598     vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1599     /* Data Rotate: - */
1600     vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1601     /* Read Map Select: - */
1602     vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1603     /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1604     vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1605     /* Miscellaneous: memory map base address, graphics mode */
1606     vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1607     /* Color Don't care: involve all planes */
1608     vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1609     /* Bit Mask: no mask at all */
1610     vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1611 
1612     if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1613         is_laguna(cinfo))
1614         /* (5434 can't have bit 3 set for bitblt) */
1615         vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1616     else
1617     /* Graphics controller mode extensions: finer granularity,
1618      * 8byte data latches
1619      */
1620         vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1621 
1622     vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1623     vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1624     vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1625     /* Background color byte 1: - */
1626     /*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1627     /*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1628 
1629     /* Attribute Controller palette registers: "identity mapping" */
1630     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1631     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1632     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1633     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1634     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1635     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1636     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1637     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1638     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1639     vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1640     vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1641     vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1642     vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1643     vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1644     vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1645     vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1646 
1647     /* Attribute Controller mode: graphics mode */
1648     vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1649     /* Overscan color reg.: reg. 0 */
1650     vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1651     /* Color Plane enable: Enable all 4 planes */
1652     vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1653     /* Color Select: - */
1654     vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1655 
1656     WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1657 
1658     /* BLT Start/status: Blitter reset */
1659     vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1660     /* - " -       : "end-of-reset" */
1661     vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1662 
1663     /* misc... */
1664     WHDR(cinfo, 0); /* Hidden DAC register: - */
1665     return;
1666 }
1667 
1668 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1669 {
1670 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1671     static int IsOn = 0;    /* XXX not ok for multiple boards */
1672 
1673     if (cinfo->btype == BT_PICASSO4)
1674         return;     /* nothing to switch */
1675     if (cinfo->btype == BT_ALPINE)
1676         return;     /* nothing to switch */
1677     if (cinfo->btype == BT_GD5480)
1678         return;     /* nothing to switch */
1679     if (cinfo->btype == BT_PICASSO) {
1680         if ((on && !IsOn) || (!on && IsOn))
1681             WSFR(cinfo, 0xff);
1682         return;
1683     }
1684     if (on) {
1685         switch (cinfo->btype) {
1686         case BT_SD64:
1687             WSFR(cinfo, cinfo->SFR | 0x21);
1688             break;
1689         case BT_PICCOLO:
1690             WSFR(cinfo, cinfo->SFR | 0x28);
1691             break;
1692         case BT_SPECTRUM:
1693             WSFR(cinfo, 0x6f);
1694             break;
1695         default: /* do nothing */ break;
1696         }
1697     } else {
1698         switch (cinfo->btype) {
1699         case BT_SD64:
1700             WSFR(cinfo, cinfo->SFR & 0xde);
1701             break;
1702         case BT_PICCOLO:
1703             WSFR(cinfo, cinfo->SFR & 0xd7);
1704             break;
1705         case BT_SPECTRUM:
1706             WSFR(cinfo, 0x4f);
1707             break;
1708         default: /* do nothing */
1709             break;
1710         }
1711     }
1712 #endif /* CONFIG_ZORRO */
1713 }
1714 
1715 /******************************************/
1716 /* Linux 2.6-style  accelerated functions */
1717 /******************************************/
1718 
1719 static int cirrusfb_sync(struct fb_info *info)
1720 {
1721     struct cirrusfb_info *cinfo = info->par;
1722 
1723     if (!is_laguna(cinfo)) {
1724         while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1725             cpu_relax();
1726     }
1727     return 0;
1728 }
1729 
1730 static void cirrusfb_fillrect(struct fb_info *info,
1731                   const struct fb_fillrect *region)
1732 {
1733     struct fb_fillrect modded;
1734     int vxres, vyres;
1735     struct cirrusfb_info *cinfo = info->par;
1736     int m = info->var.bits_per_pixel;
1737     u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1738         cinfo->pseudo_palette[region->color] : region->color;
1739 
1740     if (info->state != FBINFO_STATE_RUNNING)
1741         return;
1742     if (info->flags & FBINFO_HWACCEL_DISABLED) {
1743         cfb_fillrect(info, region);
1744         return;
1745     }
1746 
1747     vxres = info->var.xres_virtual;
1748     vyres = info->var.yres_virtual;
1749 
1750     memcpy(&modded, region, sizeof(struct fb_fillrect));
1751 
1752     if (!modded.width || !modded.height ||
1753        modded.dx >= vxres || modded.dy >= vyres)
1754         return;
1755 
1756     if (modded.dx + modded.width  > vxres)
1757         modded.width  = vxres - modded.dx;
1758     if (modded.dy + modded.height > vyres)
1759         modded.height = vyres - modded.dy;
1760 
1761     cirrusfb_RectFill(cinfo->regbase,
1762               info->var.bits_per_pixel,
1763               (region->dx * m) / 8, region->dy,
1764               (region->width * m) / 8, region->height,
1765               color, color,
1766               info->fix.line_length, 0x40);
1767 }
1768 
1769 static void cirrusfb_copyarea(struct fb_info *info,
1770                   const struct fb_copyarea *area)
1771 {
1772     struct fb_copyarea modded;
1773     u32 vxres, vyres;
1774     struct cirrusfb_info *cinfo = info->par;
1775     int m = info->var.bits_per_pixel;
1776 
1777     if (info->state != FBINFO_STATE_RUNNING)
1778         return;
1779     if (info->flags & FBINFO_HWACCEL_DISABLED) {
1780         cfb_copyarea(info, area);
1781         return;
1782     }
1783 
1784     vxres = info->var.xres_virtual;
1785     vyres = info->var.yres_virtual;
1786     memcpy(&modded, area, sizeof(struct fb_copyarea));
1787 
1788     if (!modded.width || !modded.height ||
1789        modded.sx >= vxres || modded.sy >= vyres ||
1790        modded.dx >= vxres || modded.dy >= vyres)
1791         return;
1792 
1793     if (modded.sx + modded.width > vxres)
1794         modded.width = vxres - modded.sx;
1795     if (modded.dx + modded.width > vxres)
1796         modded.width = vxres - modded.dx;
1797     if (modded.sy + modded.height > vyres)
1798         modded.height = vyres - modded.sy;
1799     if (modded.dy + modded.height > vyres)
1800         modded.height = vyres - modded.dy;
1801 
1802     cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1803             (area->sx * m) / 8, area->sy,
1804             (area->dx * m) / 8, area->dy,
1805             (area->width * m) / 8, area->height,
1806             info->fix.line_length);
1807 
1808 }
1809 
1810 static void cirrusfb_imageblit(struct fb_info *info,
1811                    const struct fb_image *image)
1812 {
1813     struct cirrusfb_info *cinfo = info->par;
1814     unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1815 
1816     if (info->state != FBINFO_STATE_RUNNING)
1817         return;
1818     /* Alpine/SD64 does not work at 24bpp ??? */
1819     if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1820         cfb_imageblit(info, image);
1821     else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1822           op == 0xc)
1823         cfb_imageblit(info, image);
1824     else {
1825         unsigned size = ((image->width + 7) >> 3) * image->height;
1826         int m = info->var.bits_per_pixel;
1827         u32 fg, bg;
1828 
1829         if (info->var.bits_per_pixel == 8) {
1830             fg = image->fg_color;
1831             bg = image->bg_color;
1832         } else {
1833             fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1834             bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1835         }
1836         if (info->var.bits_per_pixel == 24) {
1837             /* clear background first */
1838             cirrusfb_RectFill(cinfo->regbase,
1839                       info->var.bits_per_pixel,
1840                       (image->dx * m) / 8, image->dy,
1841                       (image->width * m) / 8,
1842                       image->height,
1843                       bg, bg,
1844                       info->fix.line_length, 0x40);
1845         }
1846         cirrusfb_RectFill(cinfo->regbase,
1847                   info->var.bits_per_pixel,
1848                   (image->dx * m) / 8, image->dy,
1849                   (image->width * m) / 8, image->height,
1850                   fg, bg,
1851                   info->fix.line_length, op);
1852         memcpy(info->screen_base, image->data, size);
1853     }
1854 }
1855 
1856 #ifdef CONFIG_PCI
1857 static int release_io_ports;
1858 
1859 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1860  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
1861  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1862  * seem to have. */
1863 static unsigned int cirrusfb_get_memsize(struct fb_info *info,
1864                      u8 __iomem *regbase)
1865 {
1866     unsigned long mem;
1867     struct cirrusfb_info *cinfo = info->par;
1868 
1869     if (is_laguna(cinfo)) {
1870         unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1871 
1872         mem = ((SR14 & 7) + 1) << 20;
1873     } else {
1874         unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1875         switch ((SRF & 0x18)) {
1876         case 0x08:
1877             mem = 512 * 1024;
1878             break;
1879         case 0x10:
1880             mem = 1024 * 1024;
1881             break;
1882         /* 64-bit DRAM data bus width; assume 2MB.
1883          * Also indicates 2MB memory on the 5430.
1884          */
1885         case 0x18:
1886             mem = 2048 * 1024;
1887             break;
1888         default:
1889             dev_warn(info->device, "Unknown memory size!\n");
1890             mem = 1024 * 1024;
1891         }
1892         /* If DRAM bank switching is enabled, there must be
1893          * twice as much memory installed. (4MB on the 5434)
1894          */
1895         if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1896             mem *= 2;
1897     }
1898 
1899     /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1900     return mem;
1901 }
1902 
1903 static void get_pci_addrs(const struct pci_dev *pdev,
1904               unsigned long *display, unsigned long *registers)
1905 {
1906     assert(pdev != NULL);
1907     assert(display != NULL);
1908     assert(registers != NULL);
1909 
1910     *display = 0;
1911     *registers = 0;
1912 
1913     /* This is a best-guess for now */
1914 
1915     if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1916         *display = pci_resource_start(pdev, 1);
1917         *registers = pci_resource_start(pdev, 0);
1918     } else {
1919         *display = pci_resource_start(pdev, 0);
1920         *registers = pci_resource_start(pdev, 1);
1921     }
1922 
1923     assert(*display != 0);
1924 }
1925 
1926 static void cirrusfb_pci_unmap(struct fb_info *info)
1927 {
1928     struct pci_dev *pdev = to_pci_dev(info->device);
1929     struct cirrusfb_info *cinfo = info->par;
1930 
1931     if (cinfo->laguna_mmio == NULL)
1932         iounmap(cinfo->laguna_mmio);
1933     iounmap(info->screen_base);
1934 #if 0 /* if system didn't claim this region, we would... */
1935     release_mem_region(0xA0000, 65535);
1936 #endif
1937     if (release_io_ports)
1938         release_region(0x3C0, 32);
1939     pci_release_regions(pdev);
1940 }
1941 #endif /* CONFIG_PCI */
1942 
1943 #ifdef CONFIG_ZORRO
1944 static void cirrusfb_zorro_unmap(struct fb_info *info)
1945 {
1946     struct cirrusfb_info *cinfo = info->par;
1947     struct zorro_dev *zdev = to_zorro_dev(info->device);
1948 
1949     if (info->fix.smem_start > 16 * MB_)
1950         iounmap(info->screen_base);
1951     if (info->fix.mmio_start > 16 * MB_)
1952         iounmap(cinfo->regbase);
1953 
1954     zorro_release_device(zdev);
1955 }
1956 #endif /* CONFIG_ZORRO */
1957 
1958 /* function table of the above functions */
1959 static const struct fb_ops cirrusfb_ops = {
1960     .owner      = THIS_MODULE,
1961     .fb_open    = cirrusfb_open,
1962     .fb_release = cirrusfb_release,
1963     .fb_setcolreg   = cirrusfb_setcolreg,
1964     .fb_check_var   = cirrusfb_check_var,
1965     .fb_set_par = cirrusfb_set_par,
1966     .fb_pan_display = cirrusfb_pan_display,
1967     .fb_blank   = cirrusfb_blank,
1968     .fb_fillrect    = cirrusfb_fillrect,
1969     .fb_copyarea    = cirrusfb_copyarea,
1970     .fb_sync    = cirrusfb_sync,
1971     .fb_imageblit   = cirrusfb_imageblit,
1972 };
1973 
1974 static int cirrusfb_set_fbinfo(struct fb_info *info)
1975 {
1976     struct cirrusfb_info *cinfo = info->par;
1977     struct fb_var_screeninfo *var = &info->var;
1978 
1979     info->pseudo_palette = cinfo->pseudo_palette;
1980     info->flags = FBINFO_DEFAULT
1981             | FBINFO_HWACCEL_XPAN
1982             | FBINFO_HWACCEL_YPAN
1983             | FBINFO_HWACCEL_FILLRECT
1984             | FBINFO_HWACCEL_IMAGEBLIT
1985             | FBINFO_HWACCEL_COPYAREA;
1986     if (noaccel || is_laguna(cinfo)) {
1987         info->flags |= FBINFO_HWACCEL_DISABLED;
1988         info->fix.accel = FB_ACCEL_NONE;
1989     } else
1990         info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
1991 
1992     info->fbops = &cirrusfb_ops;
1993 
1994     if (cinfo->btype == BT_GD5480) {
1995         if (var->bits_per_pixel == 16)
1996             info->screen_base += 1 * MB_;
1997         if (var->bits_per_pixel == 32)
1998             info->screen_base += 2 * MB_;
1999     }
2000 
2001     /* Fill fix common fields */
2002     strscpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2003         sizeof(info->fix.id));
2004 
2005     /* monochrome: only 1 memory plane */
2006     /* 8 bit and above: Use whole memory area */
2007     info->fix.smem_len   = info->screen_size;
2008     if (var->bits_per_pixel == 1)
2009         info->fix.smem_len /= 4;
2010     info->fix.type_aux   = 0;
2011     info->fix.xpanstep   = 1;
2012     info->fix.ypanstep   = 1;
2013     info->fix.ywrapstep  = 0;
2014 
2015     /* FIXME: map region at 0xB8000 if available, fill in here */
2016     info->fix.mmio_len   = 0;
2017 
2018     fb_alloc_cmap(&info->cmap, 256, 0);
2019 
2020     return 0;
2021 }
2022 
2023 static int cirrusfb_register(struct fb_info *info)
2024 {
2025     struct cirrusfb_info *cinfo = info->par;
2026     int err;
2027 
2028     /* sanity checks */
2029     assert(cinfo->btype != BT_NONE);
2030 
2031     /* set all the vital stuff */
2032     cirrusfb_set_fbinfo(info);
2033 
2034     dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2035 
2036     err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2037     if (!err) {
2038         dev_dbg(info->device, "wrong initial video mode\n");
2039         err = -EINVAL;
2040         goto err_dealloc_cmap;
2041     }
2042 
2043     info->var.activate = FB_ACTIVATE_NOW;
2044 
2045     err = cirrusfb_check_var(&info->var, info);
2046     if (err < 0) {
2047         /* should never happen */
2048         dev_dbg(info->device,
2049             "choking on default var... umm, no good.\n");
2050         goto err_dealloc_cmap;
2051     }
2052 
2053     err = register_framebuffer(info);
2054     if (err < 0) {
2055         dev_err(info->device,
2056             "could not register fb device; err = %d!\n", err);
2057         goto err_dealloc_cmap;
2058     }
2059 
2060     return 0;
2061 
2062 err_dealloc_cmap:
2063     fb_dealloc_cmap(&info->cmap);
2064     return err;
2065 }
2066 
2067 static void cirrusfb_cleanup(struct fb_info *info)
2068 {
2069     struct cirrusfb_info *cinfo = info->par;
2070 
2071     switch_monitor(cinfo, 0);
2072     unregister_framebuffer(info);
2073     fb_dealloc_cmap(&info->cmap);
2074     dev_dbg(info->device, "Framebuffer unregistered\n");
2075     cinfo->unmap(info);
2076     framebuffer_release(info);
2077 }
2078 
2079 #ifdef CONFIG_PCI
2080 static int cirrusfb_pci_register(struct pci_dev *pdev,
2081                  const struct pci_device_id *ent)
2082 {
2083     struct cirrusfb_info *cinfo;
2084     struct fb_info *info;
2085     unsigned long board_addr, board_size;
2086     int ret;
2087 
2088     ret = pci_enable_device(pdev);
2089     if (ret < 0) {
2090         printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2091         goto err_out;
2092     }
2093 
2094     info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2095     if (!info) {
2096         ret = -ENOMEM;
2097         goto err_out;
2098     }
2099 
2100     cinfo = info->par;
2101     cinfo->btype = (enum cirrus_board) ent->driver_data;
2102 
2103     dev_dbg(info->device,
2104         " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2105         (unsigned long long)pdev->resource[0].start,  cinfo->btype);
2106     dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2107         (unsigned long long)pdev->resource[1].start);
2108 
2109     dev_dbg(info->device,
2110         "Attempt to get PCI info for Cirrus Graphics Card\n");
2111     get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2112     /* FIXME: this forces VGA.  alternatives? */
2113     cinfo->regbase = NULL;
2114     cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2115 
2116     dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2117         board_addr, info->fix.mmio_start);
2118 
2119     board_size = (cinfo->btype == BT_GD5480) ?
2120         32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2121 
2122     ret = pci_request_regions(pdev, "cirrusfb");
2123     if (ret < 0) {
2124         dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2125             board_addr);
2126         goto err_release_fb;
2127     }
2128 #if 0 /* if the system didn't claim this region, we would... */
2129     if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2130         dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2131             0xA0000L);
2132         ret = -EBUSY;
2133         goto err_release_regions;
2134     }
2135 #endif
2136     if (request_region(0x3C0, 32, "cirrusfb"))
2137         release_io_ports = 1;
2138 
2139     info->screen_base = ioremap(board_addr, board_size);
2140     if (!info->screen_base) {
2141         ret = -EIO;
2142         goto err_release_legacy;
2143     }
2144 
2145     info->fix.smem_start = board_addr;
2146     info->screen_size = board_size;
2147     cinfo->unmap = cirrusfb_pci_unmap;
2148 
2149     dev_info(info->device,
2150          "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2151          info->screen_size >> 10, board_addr);
2152     pci_set_drvdata(pdev, info);
2153 
2154     ret = cirrusfb_register(info);
2155     if (!ret)
2156         return 0;
2157 
2158     iounmap(info->screen_base);
2159 err_release_legacy:
2160     if (release_io_ports)
2161         release_region(0x3C0, 32);
2162 #if 0
2163     release_mem_region(0xA0000, 65535);
2164 err_release_regions:
2165 #endif
2166     pci_release_regions(pdev);
2167 err_release_fb:
2168     if (cinfo->laguna_mmio != NULL)
2169         iounmap(cinfo->laguna_mmio);
2170     framebuffer_release(info);
2171 err_out:
2172     return ret;
2173 }
2174 
2175 static void cirrusfb_pci_unregister(struct pci_dev *pdev)
2176 {
2177     struct fb_info *info = pci_get_drvdata(pdev);
2178 
2179     cirrusfb_cleanup(info);
2180 }
2181 
2182 static struct pci_driver cirrusfb_pci_driver = {
2183     .name       = "cirrusfb",
2184     .id_table   = cirrusfb_pci_table,
2185     .probe      = cirrusfb_pci_register,
2186     .remove     = cirrusfb_pci_unregister,
2187 };
2188 #endif /* CONFIG_PCI */
2189 
2190 #ifdef CONFIG_ZORRO
2191 static int cirrusfb_zorro_register(struct zorro_dev *z,
2192                    const struct zorro_device_id *ent)
2193 {
2194     struct fb_info *info;
2195     int error;
2196     const struct zorrocl *zcl;
2197     enum cirrus_board btype;
2198     unsigned long regbase, ramsize, rambase;
2199     struct cirrusfb_info *cinfo;
2200 
2201     info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2202     if (!info)
2203         return -ENOMEM;
2204 
2205     zcl = (const struct zorrocl *)ent->driver_data;
2206     btype = zcl->type;
2207     regbase = zorro_resource_start(z) + zcl->regoffset;
2208     ramsize = zcl->ramsize;
2209     if (ramsize) {
2210         rambase = zorro_resource_start(z) + zcl->ramoffset;
2211         if (zorro_resource_len(z) == 64 * MB_) {
2212             /* Quirk for 64 MiB Picasso IV */
2213             rambase += zcl->ramoffset;
2214         }
2215     } else {
2216         struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2217         if (!ram || !zorro_resource_len(ram)) {
2218             dev_err(info->device, "No video RAM found\n");
2219             error = -ENODEV;
2220             goto err_release_fb;
2221         }
2222         rambase = zorro_resource_start(ram);
2223         ramsize = zorro_resource_len(ram);
2224         if (zcl->ramid2 &&
2225             (ram = zorro_find_device(zcl->ramid2, NULL))) {
2226             if (zorro_resource_start(ram) != rambase + ramsize) {
2227                 dev_warn(info->device,
2228                      "Skipping non-contiguous RAM at %pR\n",
2229                      &ram->resource);
2230             } else {
2231                 ramsize += zorro_resource_len(ram);
2232             }
2233         }
2234     }
2235 
2236     dev_info(info->device,
2237          "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2238          cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2239          rambase);
2240 
2241     if (!zorro_request_device(z, "cirrusfb")) {
2242         dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2243         error = -EBUSY;
2244         goto err_release_fb;
2245     }
2246 
2247     cinfo = info->par;
2248     cinfo->btype = btype;
2249 
2250     info->fix.mmio_start = regbase;
2251     cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2252                         : ZTWO_VADDR(regbase);
2253     if (!cinfo->regbase) {
2254         dev_err(info->device, "Cannot map registers\n");
2255         error = -EIO;
2256         goto err_release_dev;
2257     }
2258 
2259     info->fix.smem_start = rambase;
2260     info->screen_size = ramsize;
2261     info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2262                            : ZTWO_VADDR(rambase);
2263     if (!info->screen_base) {
2264         dev_err(info->device, "Cannot map video RAM\n");
2265         error = -EIO;
2266         goto err_unmap_reg;
2267     }
2268 
2269     cinfo->unmap = cirrusfb_zorro_unmap;
2270 
2271     dev_info(info->device,
2272          "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2273          ramsize / MB_, rambase);
2274 
2275     /* MCLK select etc. */
2276     if (cirrusfb_board_info[btype].init_sr1f)
2277         vga_wseq(cinfo->regbase, CL_SEQR1F,
2278              cirrusfb_board_info[btype].sr1f);
2279 
2280     error = cirrusfb_register(info);
2281     if (error) {
2282         dev_err(info->device, "Failed to register device, error %d\n",
2283             error);
2284         goto err_unmap_ram;
2285     }
2286 
2287     zorro_set_drvdata(z, info);
2288     return 0;
2289 
2290 err_unmap_ram:
2291     if (rambase > 16 * MB_)
2292         iounmap(info->screen_base);
2293 
2294 err_unmap_reg:
2295     if (regbase > 16 * MB_)
2296         iounmap(cinfo->regbase);
2297 err_release_dev:
2298     zorro_release_device(z);
2299 err_release_fb:
2300     framebuffer_release(info);
2301     return error;
2302 }
2303 
2304 static void cirrusfb_zorro_unregister(struct zorro_dev *z)
2305 {
2306     struct fb_info *info = zorro_get_drvdata(z);
2307 
2308     cirrusfb_cleanup(info);
2309     zorro_set_drvdata(z, NULL);
2310 }
2311 
2312 static struct zorro_driver cirrusfb_zorro_driver = {
2313     .name       = "cirrusfb",
2314     .id_table   = cirrusfb_zorro_table,
2315     .probe      = cirrusfb_zorro_register,
2316     .remove     = cirrusfb_zorro_unregister,
2317 };
2318 #endif /* CONFIG_ZORRO */
2319 
2320 #ifndef MODULE
2321 static int __init cirrusfb_setup(char *options)
2322 {
2323     char *this_opt;
2324 
2325     if (!options || !*options)
2326         return 0;
2327 
2328     while ((this_opt = strsep(&options, ",")) != NULL) {
2329         if (!*this_opt)
2330             continue;
2331 
2332         if (!strcmp(this_opt, "noaccel"))
2333             noaccel = 1;
2334         else if (!strncmp(this_opt, "mode:", 5))
2335             mode_option = this_opt + 5;
2336         else
2337             mode_option = this_opt;
2338     }
2339     return 0;
2340 }
2341 #endif
2342 
2343     /*
2344      *  Modularization
2345      */
2346 
2347 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2348 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2349 MODULE_LICENSE("GPL");
2350 
2351 static int __init cirrusfb_init(void)
2352 {
2353     int error = 0;
2354 
2355 #ifndef MODULE
2356     char *option = NULL;
2357 
2358     if (fb_get_options("cirrusfb", &option))
2359         return -ENODEV;
2360     cirrusfb_setup(option);
2361 #endif
2362 
2363 #ifdef CONFIG_ZORRO
2364     error |= zorro_register_driver(&cirrusfb_zorro_driver);
2365 #endif
2366 #ifdef CONFIG_PCI
2367     error |= pci_register_driver(&cirrusfb_pci_driver);
2368 #endif
2369     return error;
2370 }
2371 
2372 static void __exit cirrusfb_exit(void)
2373 {
2374 #ifdef CONFIG_PCI
2375     pci_unregister_driver(&cirrusfb_pci_driver);
2376 #endif
2377 #ifdef CONFIG_ZORRO
2378     zorro_unregister_driver(&cirrusfb_zorro_driver);
2379 #endif
2380 }
2381 
2382 module_init(cirrusfb_init);
2383 
2384 module_param(mode_option, charp, 0);
2385 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2386 module_param(noaccel, bool, 0);
2387 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2388 
2389 #ifdef MODULE
2390 module_exit(cirrusfb_exit);
2391 #endif
2392 
2393 /**********************************************************************/
2394 /* about the following functions - I have used the same names for the */
2395 /* functions as Markus Wild did in his Retina driver for NetBSD as    */
2396 /* they just made sense for this purpose. Apart from that, I wrote    */
2397 /* these functions myself.                      */
2398 /**********************************************************************/
2399 
2400 /*** WGen() - write into one of the external/general registers ***/
2401 static void WGen(const struct cirrusfb_info *cinfo,
2402           int regnum, unsigned char val)
2403 {
2404     unsigned long regofs = 0;
2405 
2406     if (cinfo->btype == BT_PICASSO) {
2407         /* Picasso II specific hack */
2408 /*        if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2409           regnum == CL_VSSM2) */
2410         if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2411             regofs = 0xfff;
2412     }
2413 
2414     vga_w(cinfo->regbase, regofs + regnum, val);
2415 }
2416 
2417 /*** RGen() - read out one of the external/general registers ***/
2418 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2419 {
2420     unsigned long regofs = 0;
2421 
2422     if (cinfo->btype == BT_PICASSO) {
2423         /* Picasso II specific hack */
2424 /*        if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2425           regnum == CL_VSSM2) */
2426         if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2427             regofs = 0xfff;
2428     }
2429 
2430     return vga_r(cinfo->regbase, regofs + regnum);
2431 }
2432 
2433 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2434 static void AttrOn(const struct cirrusfb_info *cinfo)
2435 {
2436     assert(cinfo != NULL);
2437 
2438     if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2439         /* if we're just in "write value" mode, write back the */
2440         /* same value as before to not modify anything */
2441         vga_w(cinfo->regbase, VGA_ATT_IW,
2442               vga_r(cinfo->regbase, VGA_ATT_R));
2443     }
2444     /* turn on video bit */
2445 /*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2446     vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2447 
2448     /* dummy write on Reg0 to be on "write index" mode next time */
2449     vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2450 }
2451 
2452 /*** WHDR() - write into the Hidden DAC register ***/
2453 /* as the HDR is the only extension register that requires special treatment
2454  * (the other extension registers are accessible just like the "ordinary"
2455  * registers of their functional group) here is a specialized routine for
2456  * accessing the HDR
2457  */
2458 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2459 {
2460     if (is_laguna(cinfo))
2461         return;
2462     if (cinfo->btype == BT_PICASSO) {
2463         /* Klaus' hint for correct access to HDR on some boards */
2464         /* first write 0 to pixel mask (3c6) */
2465         WGen(cinfo, VGA_PEL_MSK, 0x00);
2466         udelay(200);
2467         /* next read dummy from pixel address (3c8) */
2468         RGen(cinfo, VGA_PEL_IW);
2469         udelay(200);
2470     }
2471     /* now do the usual stuff to access the HDR */
2472 
2473     RGen(cinfo, VGA_PEL_MSK);
2474     udelay(200);
2475     RGen(cinfo, VGA_PEL_MSK);
2476     udelay(200);
2477     RGen(cinfo, VGA_PEL_MSK);
2478     udelay(200);
2479     RGen(cinfo, VGA_PEL_MSK);
2480     udelay(200);
2481 
2482     WGen(cinfo, VGA_PEL_MSK, val);
2483     udelay(200);
2484 
2485     if (cinfo->btype == BT_PICASSO) {
2486         /* now first reset HDR access counter */
2487         RGen(cinfo, VGA_PEL_IW);
2488         udelay(200);
2489 
2490         /* and at the end, restore the mask value */
2491         /* ## is this mask always 0xff? */
2492         WGen(cinfo, VGA_PEL_MSK, 0xff);
2493         udelay(200);
2494     }
2495 }
2496 
2497 /*** WSFR() - write to the "special function register" (SFR) ***/
2498 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2499 {
2500 #ifdef CONFIG_ZORRO
2501     assert(cinfo->regbase != NULL);
2502     cinfo->SFR = val;
2503     z_writeb(val, cinfo->regbase + 0x8000);
2504 #endif
2505 }
2506 
2507 /* The Picasso has a second register for switching the monitor bit */
2508 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2509 {
2510 #ifdef CONFIG_ZORRO
2511     /* writing an arbitrary value to this one causes the monitor switcher */
2512     /* to flip to Amiga display */
2513     assert(cinfo->regbase != NULL);
2514     cinfo->SFR = val;
2515     z_writeb(val, cinfo->regbase + 0x9000);
2516 #endif
2517 }
2518 
2519 /*** WClut - set CLUT entry (range: 0..63) ***/
2520 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2521         unsigned char green, unsigned char blue)
2522 {
2523     unsigned int data = VGA_PEL_D;
2524 
2525     /* address write mode register is not translated.. */
2526     vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2527 
2528     if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2529         cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2530         cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2531         /* but DAC data register IS, at least for Picasso II */
2532         if (cinfo->btype == BT_PICASSO)
2533             data += 0xfff;
2534         vga_w(cinfo->regbase, data, red);
2535         vga_w(cinfo->regbase, data, green);
2536         vga_w(cinfo->regbase, data, blue);
2537     } else {
2538         vga_w(cinfo->regbase, data, blue);
2539         vga_w(cinfo->regbase, data, green);
2540         vga_w(cinfo->regbase, data, red);
2541     }
2542 }
2543 
2544 #if 0
2545 /*** RClut - read CLUT entry (range 0..63) ***/
2546 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2547         unsigned char *green, unsigned char *blue)
2548 {
2549     unsigned int data = VGA_PEL_D;
2550 
2551     vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2552 
2553     if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2554         cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2555         if (cinfo->btype == BT_PICASSO)
2556             data += 0xfff;
2557         *red = vga_r(cinfo->regbase, data);
2558         *green = vga_r(cinfo->regbase, data);
2559         *blue = vga_r(cinfo->regbase, data);
2560     } else {
2561         *blue = vga_r(cinfo->regbase, data);
2562         *green = vga_r(cinfo->regbase, data);
2563         *red = vga_r(cinfo->regbase, data);
2564     }
2565 }
2566 #endif
2567 
2568 /*******************************************************************
2569     cirrusfb_WaitBLT()
2570 
2571     Wait for the BitBLT engine to complete a possible earlier job
2572 *********************************************************************/
2573 
2574 /* FIXME: use interrupts instead */
2575 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2576 {
2577     while (vga_rgfx(regbase, CL_GR31) & 0x08)
2578         cpu_relax();
2579 }
2580 
2581 /*******************************************************************
2582     cirrusfb_BitBLT()
2583 
2584     perform accelerated "scrolling"
2585 ********************************************************************/
2586 
2587 static void cirrusfb_set_blitter(u8 __iomem *regbase,
2588                 u_short nwidth, u_short nheight,
2589                 u_long nsrc, u_long ndest,
2590                 u_short bltmode, u_short line_length)
2591 
2592 {
2593     /* pitch: set to line_length */
2594     /* dest pitch low */
2595     vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2596     /* dest pitch hi */
2597     vga_wgfx(regbase, CL_GR25, line_length >> 8);
2598     /* source pitch low */
2599     vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2600     /* source pitch hi */
2601     vga_wgfx(regbase, CL_GR27, line_length >> 8);
2602 
2603     /* BLT width: actual number of pixels - 1 */
2604     /* BLT width low */
2605     vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2606     /* BLT width hi */
2607     vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2608 
2609     /* BLT height: actual number of lines -1 */
2610     /* BLT height low */
2611     vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2612     /* BLT width hi */
2613     vga_wgfx(regbase, CL_GR23, nheight >> 8);
2614 
2615     /* BLT destination */
2616     /* BLT dest low */
2617     vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2618     /* BLT dest mid */
2619     vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2620     /* BLT dest hi */
2621     vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2622 
2623     /* BLT source */
2624     /* BLT src low */
2625     vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2626     /* BLT src mid */
2627     vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2628     /* BLT src hi */
2629     vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2630 
2631     /* BLT mode */
2632     vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2633 
2634     /* BLT ROP: SrcCopy */
2635     vga_wgfx(regbase, CL_GR32, 0x0d);   /* BLT ROP */
2636 
2637     /* and finally: GO! */
2638     vga_wgfx(regbase, CL_GR31, 0x02);   /* BLT Start/status */
2639 }
2640 
2641 /*******************************************************************
2642     cirrusfb_BitBLT()
2643 
2644     perform accelerated "scrolling"
2645 ********************************************************************/
2646 
2647 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2648                 u_short curx, u_short cury,
2649                 u_short destx, u_short desty,
2650                 u_short width, u_short height,
2651                 u_short line_length)
2652 {
2653     u_short nwidth = width - 1;
2654     u_short nheight = height - 1;
2655     u_long nsrc, ndest;
2656     u_char bltmode;
2657 
2658     bltmode = 0x00;
2659     /* if source adr < dest addr, do the Blt backwards */
2660     if (cury <= desty) {
2661         if (cury == desty) {
2662             /* if src and dest are on the same line, check x */
2663             if (curx < destx)
2664                 bltmode |= 0x01;
2665         } else
2666             bltmode |= 0x01;
2667     }
2668     /* standard case: forward blitting */
2669     nsrc = (cury * line_length) + curx;
2670     ndest = (desty * line_length) + destx;
2671     if (bltmode) {
2672         /* this means start addresses are at the end,
2673          * counting backwards
2674          */
2675         nsrc += nheight * line_length + nwidth;
2676         ndest += nheight * line_length + nwidth;
2677     }
2678 
2679     cirrusfb_WaitBLT(regbase);
2680 
2681     cirrusfb_set_blitter(regbase, nwidth, nheight,
2682                 nsrc, ndest, bltmode, line_length);
2683 }
2684 
2685 /*******************************************************************
2686     cirrusfb_RectFill()
2687 
2688     perform accelerated rectangle fill
2689 ********************************************************************/
2690 
2691 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2692              u_short x, u_short y, u_short width, u_short height,
2693              u32 fg_color, u32 bg_color, u_short line_length,
2694              u_char blitmode)
2695 {
2696     u_long ndest = (y * line_length) + x;
2697     u_char op;
2698 
2699     cirrusfb_WaitBLT(regbase);
2700 
2701     /* This is a ColorExpand Blt, using the */
2702     /* same color for foreground and background */
2703     vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2704     vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2705 
2706     op = 0x80;
2707     if (bits_per_pixel >= 16) {
2708         vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2709         vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2710         op = 0x90;
2711     }
2712     if (bits_per_pixel >= 24) {
2713         vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2714         vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2715         op = 0xa0;
2716     }
2717     if (bits_per_pixel == 32) {
2718         vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2719         vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2720         op = 0xb0;
2721     }
2722     cirrusfb_set_blitter(regbase, width - 1, height - 1,
2723                 0, ndest, op | blitmode, line_length);
2724 }
2725 
2726 /**************************************************************************
2727  * bestclock() - determine closest possible clock lower(?) than the
2728  * desired pixel clock
2729  **************************************************************************/
2730 static void bestclock(long freq, int *nom, int *den, int *div)
2731 {
2732     int n, d;
2733     long h, diff;
2734 
2735     assert(nom != NULL);
2736     assert(den != NULL);
2737     assert(div != NULL);
2738 
2739     *nom = 0;
2740     *den = 0;
2741     *div = 0;
2742 
2743     if (freq < 8000)
2744         freq = 8000;
2745 
2746     diff = freq;
2747 
2748     for (n = 32; n < 128; n++) {
2749         int s = 0;
2750 
2751         d = (14318 * n) / freq;
2752         if ((d >= 7) && (d <= 63)) {
2753             int temp = d;
2754 
2755             if (temp > 31) {
2756                 s = 1;
2757                 temp >>= 1;
2758             }
2759             h = ((14318 * n) / temp) >> s;
2760             h = h > freq ? h - freq : freq - h;
2761             if (h < diff) {
2762                 diff = h;
2763                 *nom = n;
2764                 *den = temp;
2765                 *div = s;
2766             }
2767         }
2768         d++;
2769         if ((d >= 7) && (d <= 63)) {
2770             if (d > 31) {
2771                 s = 1;
2772                 d >>= 1;
2773             }
2774             h = ((14318 * n) / d) >> s;
2775             h = h > freq ? h - freq : freq - h;
2776             if (h < diff) {
2777                 diff = h;
2778                 *nom = n;
2779                 *den = d;
2780                 *div = s;
2781             }
2782         }
2783     }
2784 }
2785 
2786 /* -------------------------------------------------------------------------
2787  *
2788  * debugging functions
2789  *
2790  * -------------------------------------------------------------------------
2791  */
2792 
2793 #ifdef CIRRUSFB_DEBUG
2794 
2795 /*
2796  * cirrusfb_dbg_print_regs
2797  * @regbase: If using newmmio, the newmmio base address, otherwise %NULL
2798  * @reg_class: type of registers to read: %CRT, or %SEQ
2799  *
2800  * DESCRIPTION:
2801  * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2802  * old-style I/O ports are queried for information, otherwise MMIO is
2803  * used at the given @base address to query the information.
2804  */
2805 
2806 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2807                     caddr_t regbase,
2808                     enum cirrusfb_dbg_reg_class reg_class, ...)
2809 {
2810     va_list list;
2811     unsigned char val = 0;
2812     unsigned reg;
2813     char *name;
2814 
2815     va_start(list, reg_class);
2816 
2817     name = va_arg(list, char *);
2818     while (name != NULL) {
2819         reg = va_arg(list, int);
2820 
2821         switch (reg_class) {
2822         case CRT:
2823             val = vga_rcrt(regbase, (unsigned char) reg);
2824             break;
2825         case SEQ:
2826             val = vga_rseq(regbase, (unsigned char) reg);
2827             break;
2828         default:
2829             /* should never occur */
2830             assert(false);
2831             break;
2832         }
2833 
2834         dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2835 
2836         name = va_arg(list, char *);
2837     }
2838 
2839     va_end(list);
2840 }
2841 
2842 /*
2843  * cirrusfb_dbg_reg_dump
2844  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2845  *
2846  * DESCRIPTION:
2847  * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2848  * old-style I/O ports are queried for information, otherwise MMIO is
2849  * used at the given @base address to query the information.
2850  */
2851 
2852 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2853 {
2854     dev_dbg(info->device, "VGA CRTC register dump:\n");
2855 
2856     cirrusfb_dbg_print_regs(info, regbase, CRT,
2857                "CR00", 0x00,
2858                "CR01", 0x01,
2859                "CR02", 0x02,
2860                "CR03", 0x03,
2861                "CR04", 0x04,
2862                "CR05", 0x05,
2863                "CR06", 0x06,
2864                "CR07", 0x07,
2865                "CR08", 0x08,
2866                "CR09", 0x09,
2867                "CR0A", 0x0A,
2868                "CR0B", 0x0B,
2869                "CR0C", 0x0C,
2870                "CR0D", 0x0D,
2871                "CR0E", 0x0E,
2872                "CR0F", 0x0F,
2873                "CR10", 0x10,
2874                "CR11", 0x11,
2875                "CR12", 0x12,
2876                "CR13", 0x13,
2877                "CR14", 0x14,
2878                "CR15", 0x15,
2879                "CR16", 0x16,
2880                "CR17", 0x17,
2881                "CR18", 0x18,
2882                "CR22", 0x22,
2883                "CR24", 0x24,
2884                "CR26", 0x26,
2885                "CR2D", 0x2D,
2886                "CR2E", 0x2E,
2887                "CR2F", 0x2F,
2888                "CR30", 0x30,
2889                "CR31", 0x31,
2890                "CR32", 0x32,
2891                "CR33", 0x33,
2892                "CR34", 0x34,
2893                "CR35", 0x35,
2894                "CR36", 0x36,
2895                "CR37", 0x37,
2896                "CR38", 0x38,
2897                "CR39", 0x39,
2898                "CR3A", 0x3A,
2899                "CR3B", 0x3B,
2900                "CR3C", 0x3C,
2901                "CR3D", 0x3D,
2902                "CR3E", 0x3E,
2903                "CR3F", 0x3F,
2904                NULL);
2905 
2906     dev_dbg(info->device, "\n");
2907 
2908     dev_dbg(info->device, "VGA SEQ register dump:\n");
2909 
2910     cirrusfb_dbg_print_regs(info, regbase, SEQ,
2911                "SR00", 0x00,
2912                "SR01", 0x01,
2913                "SR02", 0x02,
2914                "SR03", 0x03,
2915                "SR04", 0x04,
2916                "SR08", 0x08,
2917                "SR09", 0x09,
2918                "SR0A", 0x0A,
2919                "SR0B", 0x0B,
2920                "SR0D", 0x0D,
2921                "SR10", 0x10,
2922                "SR11", 0x11,
2923                "SR12", 0x12,
2924                "SR13", 0x13,
2925                "SR14", 0x14,
2926                "SR15", 0x15,
2927                "SR16", 0x16,
2928                "SR17", 0x17,
2929                "SR18", 0x18,
2930                "SR19", 0x19,
2931                "SR1A", 0x1A,
2932                "SR1B", 0x1B,
2933                "SR1C", 0x1C,
2934                "SR1D", 0x1D,
2935                "SR1E", 0x1E,
2936                "SR1F", 0x1F,
2937                NULL);
2938 
2939     dev_dbg(info->device, "\n");
2940 }
2941 
2942 #endif              /* CIRRUSFB_DEBUG */
2943