linux/drivers/video/fbdev/cirrusfb.c
<<
>>
Prefs
   1/*
   2 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
   3 *
   4 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
   5 *
   6 * Contributors (thanks, all!)
   7 *
   8 *      David Eger:
   9 *      Overhaul for Linux 2.6
  10 *
  11 *      Jeff Rugen:
  12 *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
  13 *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
  14 *
  15 *      Geert Uytterhoeven:
  16 *      Excellent code review.
  17 *
  18 *      Lars Hecking:
  19 *      Amiga updates and testing.
  20 *
  21 * Original cirrusfb author:  Frank Neumann
  22 *
  23 * Based on retz3fb.c and cirrusfb.c:
  24 *      Copyright (C) 1997 Jes Sorensen
  25 *      Copyright (C) 1996 Frank Neumann
  26 *
  27 ***************************************************************
  28 *
  29 * Format this code with GNU indent '-kr -i8 -pcs' options.
  30 *
  31 * This file is subject to the terms and conditions of the GNU General Public
  32 * License.  See the file COPYING in the main directory of this archive
  33 * for more details.
  34 *
  35 */
  36
  37#include <linux/module.h>
  38#include <linux/kernel.h>
  39#include <linux/errno.h>
  40#include <linux/string.h>
  41#include <linux/mm.h>
  42#include <linux/delay.h>
  43#include <linux/fb.h>
  44#include <linux/init.h>
  45
  46#ifdef CONFIG_ZORRO
  47#include <linux/zorro.h>
  48#endif
  49#ifdef CONFIG_PCI
  50#include <linux/pci.h>
  51#endif
  52#ifdef CONFIG_AMIGA
  53#include <asm/amigahw.h>
  54#endif
  55
  56#include <video/vga.h>
  57#include <video/cirrus.h>
  58
  59/*****************************************************************
  60 *
  61 * debugging and utility macros
  62 *
  63 */
  64
  65/* disable runtime assertions? */
  66/* #define CIRRUSFB_NDEBUG */
  67
  68/* debugging assertions */
  69#ifndef CIRRUSFB_NDEBUG
  70#define assert(expr) \
  71        if (!(expr)) { \
  72                printk("Assertion failed! %s,%s,%s,line=%d\n", \
  73                #expr, __FILE__, __func__, __LINE__); \
  74        }
  75#else
  76#define assert(expr)
  77#endif
  78
  79#define MB_ (1024 * 1024)
  80
  81/*****************************************************************
  82 *
  83 * chipset information
  84 *
  85 */
  86
  87/* board types */
  88enum cirrus_board {
  89        BT_NONE = 0,
  90        BT_SD64,        /* GD5434 */
  91        BT_PICCOLO,     /* GD5426 */
  92        BT_PICASSO,     /* GD5426 or GD5428 */
  93        BT_SPECTRUM,    /* GD5426 or GD5428 */
  94        BT_PICASSO4,    /* GD5446 */
  95        BT_ALPINE,      /* GD543x/4x */
  96        BT_GD5480,
  97        BT_LAGUNA,      /* GD5462/64 */
  98        BT_LAGUNAB,     /* GD5465 */
  99};
 100
 101/*
 102 * per-board-type information, used for enumerating and abstracting
 103 * chip-specific information
 104 * NOTE: MUST be in the same order as enum cirrus_board in order to
 105 * use direct indexing on this array
 106 * NOTE: '__initdata' cannot be used as some of this info
 107 * is required at runtime.  Maybe separate into an init-only and
 108 * a run-time table?
 109 */
 110static const struct cirrusfb_board_info_rec {
 111        char *name;             /* ASCII name of chipset */
 112        long maxclock[5];               /* maximum video clock */
 113        /* for  1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
 114        bool init_sr07 : 1; /* init SR07 during init_vgachip() */
 115        bool init_sr1f : 1; /* write SR1F during init_vgachip() */
 116        /* construct bit 19 of screen start address */
 117        bool scrn_start_bit19 : 1;
 118
 119        /* initial SR07 value, then for each mode */
 120        unsigned char sr07;
 121        unsigned char sr07_1bpp;
 122        unsigned char sr07_1bpp_mux;
 123        unsigned char sr07_8bpp;
 124        unsigned char sr07_8bpp_mux;
 125
 126        unsigned char sr1f;     /* SR1F VGA initial register value */
 127} cirrusfb_board_info[] = {
 128        [BT_SD64] = {
 129                .name                   = "CL SD64",
 130                .maxclock               = {
 131                        /* guess */
 132                        /* the SD64/P4 have a higher max. videoclock */
 133                        135100, 135100, 85500, 85500, 0
 134                },
 135                .init_sr07              = true,
 136                .init_sr1f              = true,
 137                .scrn_start_bit19       = true,
 138                .sr07                   = 0xF0,
 139                .sr07_1bpp              = 0xF0,
 140                .sr07_1bpp_mux          = 0xF6,
 141                .sr07_8bpp              = 0xF1,
 142                .sr07_8bpp_mux          = 0xF7,
 143                .sr1f                   = 0x1E
 144        },
 145        [BT_PICCOLO] = {
 146                .name                   = "CL Piccolo",
 147                .maxclock               = {
 148                        /* guess */
 149                        90000, 90000, 90000, 90000, 90000
 150                },
 151                .init_sr07              = true,
 152                .init_sr1f              = true,
 153                .scrn_start_bit19       = false,
 154                .sr07                   = 0x80,
 155                .sr07_1bpp              = 0x80,
 156                .sr07_8bpp              = 0x81,
 157                .sr1f                   = 0x22
 158        },
 159        [BT_PICASSO] = {
 160                .name                   = "CL Picasso",
 161                .maxclock               = {
 162                        /* guess */
 163                        90000, 90000, 90000, 90000, 90000
 164                },
 165                .init_sr07              = true,
 166                .init_sr1f              = true,
 167                .scrn_start_bit19       = false,
 168                .sr07                   = 0x20,
 169                .sr07_1bpp              = 0x20,
 170                .sr07_8bpp              = 0x21,
 171                .sr1f                   = 0x22
 172        },
 173        [BT_SPECTRUM] = {
 174                .name                   = "CL Spectrum",
 175                .maxclock               = {
 176                        /* guess */
 177                        90000, 90000, 90000, 90000, 90000
 178                },
 179                .init_sr07              = true,
 180                .init_sr1f              = true,
 181                .scrn_start_bit19       = false,
 182                .sr07                   = 0x80,
 183                .sr07_1bpp              = 0x80,
 184                .sr07_8bpp              = 0x81,
 185                .sr1f                   = 0x22
 186        },
 187        [BT_PICASSO4] = {
 188                .name                   = "CL Picasso4",
 189                .maxclock               = {
 190                        135100, 135100, 85500, 85500, 0
 191                },
 192                .init_sr07              = true,
 193                .init_sr1f              = false,
 194                .scrn_start_bit19       = true,
 195                .sr07                   = 0xA0,
 196                .sr07_1bpp              = 0xA0,
 197                .sr07_1bpp_mux          = 0xA6,
 198                .sr07_8bpp              = 0xA1,
 199                .sr07_8bpp_mux          = 0xA7,
 200                .sr1f                   = 0
 201        },
 202        [BT_ALPINE] = {
 203                .name                   = "CL Alpine",
 204                .maxclock               = {
 205                        /* for the GD5430.  GD5446 can do more... */
 206                        85500, 85500, 50000, 28500, 0
 207                },
 208                .init_sr07              = true,
 209                .init_sr1f              = true,
 210                .scrn_start_bit19       = true,
 211                .sr07                   = 0xA0,
 212                .sr07_1bpp              = 0xA0,
 213                .sr07_1bpp_mux          = 0xA6,
 214                .sr07_8bpp              = 0xA1,
 215                .sr07_8bpp_mux          = 0xA7,
 216                .sr1f                   = 0x1C
 217        },
 218        [BT_GD5480] = {
 219                .name                   = "CL GD5480",
 220                .maxclock               = {
 221                        135100, 200000, 200000, 135100, 135100
 222                },
 223                .init_sr07              = true,
 224                .init_sr1f              = true,
 225                .scrn_start_bit19       = true,
 226                .sr07                   = 0x10,
 227                .sr07_1bpp              = 0x11,
 228                .sr07_8bpp              = 0x11,
 229                .sr1f                   = 0x1C
 230        },
 231        [BT_LAGUNA] = {
 232                .name                   = "CL Laguna",
 233                .maxclock               = {
 234                        /* taken from X11 code */
 235                        170000, 170000, 170000, 170000, 135100,
 236                },
 237                .init_sr07              = false,
 238                .init_sr1f              = false,
 239                .scrn_start_bit19       = true,
 240        },
 241        [BT_LAGUNAB] = {
 242                .name                   = "CL Laguna AGP",
 243                .maxclock               = {
 244                        /* taken from X11 code */
 245                        170000, 250000, 170000, 170000, 135100,
 246                },
 247                .init_sr07              = false,
 248                .init_sr1f              = false,
 249                .scrn_start_bit19       = true,
 250        }
 251};
 252
 253#ifdef CONFIG_PCI
 254#define CHIP(id, btype) \
 255        { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
 256
 257static struct pci_device_id cirrusfb_pci_table[] = {
 258        CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
 259        CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
 260        CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
 261        CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
 262        CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
 263        CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
 264        CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
 265        CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
 266        CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
 267        CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
 268        CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
 269        { 0, }
 270};
 271MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
 272#undef CHIP
 273#endif /* CONFIG_PCI */
 274
 275#ifdef CONFIG_ZORRO
 276struct zorrocl {
 277        enum cirrus_board type; /* Board type */
 278        u32 regoffset;          /* Offset of registers in first Zorro device */
 279        u32 ramsize;            /* Size of video RAM in first Zorro device */
 280                                /* If zero, use autoprobe on RAM device */
 281        u32 ramoffset;          /* Offset of video RAM in first Zorro device */
 282        zorro_id ramid;         /* Zorro ID of RAM device */
 283        zorro_id ramid2;        /* Zorro ID of optional second RAM device */
 284};
 285
 286static const struct zorrocl zcl_sd64 = {
 287        .type           = BT_SD64,
 288        .ramid          = ZORRO_PROD_HELFRICH_SD64_RAM,
 289};
 290
 291static const struct zorrocl zcl_piccolo = {
 292        .type           = BT_PICCOLO,
 293        .ramid          = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
 294};
 295
 296static const struct zorrocl zcl_picasso = {
 297        .type           = BT_PICASSO,
 298        .ramid          = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
 299};
 300
 301static const struct zorrocl zcl_spectrum = {
 302        .type           = BT_SPECTRUM,
 303        .ramid          = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
 304};
 305
 306static const struct zorrocl zcl_picasso4_z3 = {
 307        .type           = BT_PICASSO4,
 308        .regoffset      = 0x00600000,
 309        .ramsize        = 4 * MB_,
 310        .ramoffset      = 0x01000000,   /* 0x02000000 for 64 MiB boards */
 311};
 312
 313static const struct zorrocl zcl_picasso4_z2 = {
 314        .type           = BT_PICASSO4,
 315        .regoffset      = 0x10000,
 316        .ramid          = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
 317        .ramid2         = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
 318};
 319
 320
 321static const struct zorro_device_id cirrusfb_zorro_table[] = {
 322        {
 323                .id             = ZORRO_PROD_HELFRICH_SD64_REG,
 324                .driver_data    = (unsigned long)&zcl_sd64,
 325        }, {
 326                .id             = ZORRO_PROD_HELFRICH_PICCOLO_REG,
 327                .driver_data    = (unsigned long)&zcl_piccolo,
 328        }, {
 329                .id     = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
 330                .driver_data    = (unsigned long)&zcl_picasso,
 331        }, {
 332                .id             = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
 333                .driver_data    = (unsigned long)&zcl_spectrum,
 334        }, {
 335                .id             = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
 336                .driver_data    = (unsigned long)&zcl_picasso4_z3,
 337        }, {
 338                .id             = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG,
 339                .driver_data    = (unsigned long)&zcl_picasso4_z2,
 340        },
 341        { 0 }
 342};
 343MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
 344#endif /* CONFIG_ZORRO */
 345
 346#ifdef CIRRUSFB_DEBUG
 347enum cirrusfb_dbg_reg_class {
 348        CRT,
 349        SEQ
 350};
 351#endif          /* CIRRUSFB_DEBUG */
 352
 353/* info about board */
 354struct cirrusfb_info {
 355        u8 __iomem *regbase;
 356        u8 __iomem *laguna_mmio;
 357        enum cirrus_board btype;
 358        unsigned char SFR;      /* Shadow of special function register */
 359
 360        int multiplexing;
 361        int doubleVCLK;
 362        int blank_mode;
 363        u32 pseudo_palette[16];
 364
 365        void (*unmap)(struct fb_info *info);
 366};
 367
 368static bool noaccel;
 369static char *mode_option = "640x480@60";
 370
 371/****************************************************************************/
 372/**** BEGIN PROTOTYPES ******************************************************/
 373
 374/*--- Interface used by the world ------------------------------------------*/
 375static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
 376                                struct fb_info *info);
 377
 378/*--- Internal routines ----------------------------------------------------*/
 379static void init_vgachip(struct fb_info *info);
 380static void switch_monitor(struct cirrusfb_info *cinfo, int on);
 381static void WGen(const struct cirrusfb_info *cinfo,
 382                 int regnum, unsigned char val);
 383static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
 384static void AttrOn(const struct cirrusfb_info *cinfo);
 385static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
 386static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
 387static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
 388static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
 389                  unsigned char red, unsigned char green, unsigned char blue);
 390#if 0
 391static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
 392                  unsigned char *red, unsigned char *green,
 393                  unsigned char *blue);
 394#endif
 395static void cirrusfb_WaitBLT(u8 __iomem *regbase);
 396static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
 397                            u_short curx, u_short cury,
 398                            u_short destx, u_short desty,
 399                            u_short width, u_short height,
 400                            u_short line_length);
 401static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
 402                              u_short x, u_short y,
 403                              u_short width, u_short height,
 404                              u32 fg_color, u32 bg_color,
 405                              u_short line_length, u_char blitmode);
 406
 407static void bestclock(long freq, int *nom, int *den, int *div);
 408
 409#ifdef CIRRUSFB_DEBUG
 410static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
 411static void cirrusfb_dbg_print_regs(struct fb_info *info,
 412                                    caddr_t regbase,
 413                                    enum cirrusfb_dbg_reg_class reg_class, ...);
 414#endif /* CIRRUSFB_DEBUG */
 415
 416/*** END   PROTOTYPES ********************************************************/
 417/*****************************************************************************/
 418/*** BEGIN Interface Used by the World ***************************************/
 419
 420static inline int is_laguna(const struct cirrusfb_info *cinfo)
 421{
 422        return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
 423}
 424
 425static int opencount;
 426
 427/*--- Open /dev/fbx ---------------------------------------------------------*/
 428static int cirrusfb_open(struct fb_info *info, int user)
 429{
 430        if (opencount++ == 0)
 431                switch_monitor(info->par, 1);
 432        return 0;
 433}
 434
 435/*--- Close /dev/fbx --------------------------------------------------------*/
 436static int cirrusfb_release(struct fb_info *info, int user)
 437{
 438        if (--opencount == 0)
 439                switch_monitor(info->par, 0);
 440        return 0;
 441}
 442
 443/**** END   Interface used by the World *************************************/
 444/****************************************************************************/
 445/**** BEGIN Hardware specific Routines **************************************/
 446
 447/* Check if the MCLK is not a better clock source */
 448static int cirrusfb_check_mclk(struct fb_info *info, long freq)
 449{
 450        struct cirrusfb_info *cinfo = info->par;
 451        long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
 452
 453        /* Read MCLK value */
 454        mclk = (14318 * mclk) >> 3;
 455        dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
 456
 457        /* Determine if we should use MCLK instead of VCLK, and if so, what we
 458         * should divide it by to get VCLK
 459         */
 460
 461        if (abs(freq - mclk) < 250) {
 462                dev_dbg(info->device, "Using VCLK = MCLK\n");
 463                return 1;
 464        } else if (abs(freq - (mclk / 2)) < 250) {
 465                dev_dbg(info->device, "Using VCLK = MCLK/2\n");
 466                return 2;
 467        }
 468
 469        return 0;
 470}
 471
 472static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
 473                                   struct fb_info *info)
 474{
 475        long freq;
 476        long maxclock;
 477        struct cirrusfb_info *cinfo = info->par;
 478        unsigned maxclockidx = var->bits_per_pixel >> 3;
 479
 480        /* convert from ps to kHz */
 481        freq = PICOS2KHZ(var->pixclock);
 482
 483        dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
 484
 485        maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
 486        cinfo->multiplexing = 0;
 487
 488        /* If the frequency is greater than we can support, we might be able
 489         * to use multiplexing for the video mode */
 490        if (freq > maxclock) {
 491                dev_err(info->device,
 492                        "Frequency greater than maxclock (%ld kHz)\n",
 493                        maxclock);
 494                return -EINVAL;
 495        }
 496        /*
 497         * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
 498         * pixel clock
 499         */
 500        if (var->bits_per_pixel == 8) {
 501                switch (cinfo->btype) {
 502                case BT_ALPINE:
 503                case BT_SD64:
 504                case BT_PICASSO4:
 505                        if (freq > 85500)
 506                                cinfo->multiplexing = 1;
 507                        break;
 508                case BT_GD5480:
 509                        if (freq > 135100)
 510                                cinfo->multiplexing = 1;
 511                        break;
 512
 513                default:
 514                        break;
 515                }
 516        }
 517
 518        /* If we have a 1MB 5434, we need to put ourselves in a mode where
 519         * the VCLK is double the pixel clock. */
 520        cinfo->doubleVCLK = 0;
 521        if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
 522            var->bits_per_pixel == 16) {
 523                cinfo->doubleVCLK = 1;
 524        }
 525
 526        return 0;
 527}
 528
 529static int cirrusfb_check_var(struct fb_var_screeninfo *var,
 530                              struct fb_info *info)
 531{
 532        int yres;
 533        /* memory size in pixels */
 534        unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
 535        struct cirrusfb_info *cinfo = info->par;
 536
 537        switch (var->bits_per_pixel) {
 538        case 1:
 539                var->red.offset = 0;
 540                var->red.length = 1;
 541                var->green = var->red;
 542                var->blue = var->red;
 543                break;
 544
 545        case 8:
 546                var->red.offset = 0;
 547                var->red.length = 8;
 548                var->green = var->red;
 549                var->blue = var->red;
 550                break;
 551
 552        case 16:
 553                var->red.offset = 11;
 554                var->green.offset = 5;
 555                var->blue.offset = 0;
 556                var->red.length = 5;
 557                var->green.length = 6;
 558                var->blue.length = 5;
 559                break;
 560
 561        case 24:
 562                var->red.offset = 16;
 563                var->green.offset = 8;
 564                var->blue.offset = 0;
 565                var->red.length = 8;
 566                var->green.length = 8;
 567                var->blue.length = 8;
 568                break;
 569
 570        default:
 571                dev_dbg(info->device,
 572                        "Unsupported bpp size: %d\n", var->bits_per_pixel);
 573                return -EINVAL;
 574        }
 575
 576        if (var->xres_virtual < var->xres)
 577                var->xres_virtual = var->xres;
 578        /* use highest possible virtual resolution */
 579        if (var->yres_virtual == -1) {
 580                var->yres_virtual = pixels / var->xres_virtual;
 581
 582                dev_info(info->device,
 583                         "virtual resolution set to maximum of %dx%d\n",
 584                         var->xres_virtual, var->yres_virtual);
 585        }
 586        if (var->yres_virtual < var->yres)
 587                var->yres_virtual = var->yres;
 588
 589        if (var->xres_virtual * var->yres_virtual > pixels) {
 590                dev_err(info->device, "mode %dx%dx%d rejected... "
 591                      "virtual resolution too high to fit into video memory!\n",
 592                        var->xres_virtual, var->yres_virtual,
 593                        var->bits_per_pixel);
 594                return -EINVAL;
 595        }
 596
 597        /* truncate xoffset and yoffset to maximum if too high */
 598        if (var->xoffset > var->xres_virtual - var->xres)
 599                var->xoffset = var->xres_virtual - var->xres - 1;
 600        if (var->yoffset > var->yres_virtual - var->yres)
 601                var->yoffset = var->yres_virtual - var->yres - 1;
 602
 603        var->red.msb_right =
 604            var->green.msb_right =
 605            var->blue.msb_right =
 606            var->transp.offset =
 607            var->transp.length =
 608            var->transp.msb_right = 0;
 609
 610        yres = var->yres;
 611        if (var->vmode & FB_VMODE_DOUBLE)
 612                yres *= 2;
 613        else if (var->vmode & FB_VMODE_INTERLACED)
 614                yres = (yres + 1) / 2;
 615
 616        if (yres >= 1280) {
 617                dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
 618                        "special treatment required! (TODO)\n");
 619                return -EINVAL;
 620        }
 621
 622        if (cirrusfb_check_pixclock(var, info))
 623                return -EINVAL;
 624
 625        if (!is_laguna(cinfo))
 626                var->accel_flags = FB_ACCELF_TEXT;
 627
 628        return 0;
 629}
 630
 631static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
 632{
 633        struct cirrusfb_info *cinfo = info->par;
 634        unsigned char old1f, old1e;
 635
 636        assert(cinfo != NULL);
 637        old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
 638
 639        if (div) {
 640                dev_dbg(info->device, "Set %s as pixclock source.\n",
 641                        (div == 2) ? "MCLK/2" : "MCLK");
 642                old1f |= 0x40;
 643                old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
 644                if (div == 2)
 645                        old1e |= 1;
 646
 647                vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
 648        }
 649        vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
 650}
 651
 652/*************************************************************************
 653        cirrusfb_set_par_foo()
 654
 655        actually writes the values for a new video mode into the hardware,
 656**************************************************************************/
 657static int cirrusfb_set_par_foo(struct fb_info *info)
 658{
 659        struct cirrusfb_info *cinfo = info->par;
 660        struct fb_var_screeninfo *var = &info->var;
 661        u8 __iomem *regbase = cinfo->regbase;
 662        unsigned char tmp;
 663        int pitch;
 664        const struct cirrusfb_board_info_rec *bi;
 665        int hdispend, hsyncstart, hsyncend, htotal;
 666        int yres, vdispend, vsyncstart, vsyncend, vtotal;
 667        long freq;
 668        int nom, den, div;
 669        unsigned int control = 0, format = 0, threshold = 0;
 670
 671        dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
 672               var->xres, var->yres, var->bits_per_pixel);
 673
 674        switch (var->bits_per_pixel) {
 675        case 1:
 676                info->fix.line_length = var->xres_virtual / 8;
 677                info->fix.visual = FB_VISUAL_MONO10;
 678                break;
 679
 680        case 8:
 681                info->fix.line_length = var->xres_virtual;
 682                info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 683                break;
 684
 685        case 16:
 686        case 24:
 687                info->fix.line_length = var->xres_virtual *
 688                                        var->bits_per_pixel >> 3;
 689                info->fix.visual = FB_VISUAL_TRUECOLOR;
 690                break;
 691        }
 692        info->fix.type = FB_TYPE_PACKED_PIXELS;
 693
 694        init_vgachip(info);
 695
 696        bi = &cirrusfb_board_info[cinfo->btype];
 697
 698        hsyncstart = var->xres + var->right_margin;
 699        hsyncend = hsyncstart + var->hsync_len;
 700        htotal = (hsyncend + var->left_margin) / 8;
 701        hdispend = var->xres / 8;
 702        hsyncstart = hsyncstart / 8;
 703        hsyncend = hsyncend / 8;
 704
 705        vdispend = var->yres;
 706        vsyncstart = vdispend + var->lower_margin;
 707        vsyncend = vsyncstart + var->vsync_len;
 708        vtotal = vsyncend + var->upper_margin;
 709
 710        if (var->vmode & FB_VMODE_DOUBLE) {
 711                vdispend *= 2;
 712                vsyncstart *= 2;
 713                vsyncend *= 2;
 714                vtotal *= 2;
 715        } else if (var->vmode & FB_VMODE_INTERLACED) {
 716                vdispend = (vdispend + 1) / 2;
 717                vsyncstart = (vsyncstart + 1) / 2;
 718                vsyncend = (vsyncend + 1) / 2;
 719                vtotal = (vtotal + 1) / 2;
 720        }
 721        yres = vdispend;
 722        if (yres >= 1024) {
 723                vtotal /= 2;
 724                vsyncstart /= 2;
 725                vsyncend /= 2;
 726                vdispend /= 2;
 727        }
 728
 729        vdispend -= 1;
 730        vsyncstart -= 1;
 731        vsyncend -= 1;
 732        vtotal -= 2;
 733
 734        if (cinfo->multiplexing) {
 735                htotal /= 2;
 736                hsyncstart /= 2;
 737                hsyncend /= 2;
 738                hdispend /= 2;
 739        }
 740
 741        htotal -= 5;
 742        hdispend -= 1;
 743        hsyncstart += 1;
 744        hsyncend += 1;
 745
 746        /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
 747        vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);   /* previously: 0x00) */
 748
 749        /* if debugging is enabled, all parameters get output before writing */
 750        dev_dbg(info->device, "CRT0: %d\n", htotal);
 751        vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
 752
 753        dev_dbg(info->device, "CRT1: %d\n", hdispend);
 754        vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
 755
 756        dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
 757        vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
 758
 759        /*  + 128: Compatible read */
 760        dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
 761        vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
 762                 128 + ((htotal + 5) % 32));
 763
 764        dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
 765        vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
 766
 767        tmp = hsyncend % 32;
 768        if ((htotal + 5) & 32)
 769                tmp += 128;
 770        dev_dbg(info->device, "CRT5: %d\n", tmp);
 771        vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
 772
 773        dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
 774        vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
 775
 776        tmp = 16;               /* LineCompare bit #9 */
 777        if (vtotal & 256)
 778                tmp |= 1;
 779        if (vdispend & 256)
 780                tmp |= 2;
 781        if (vsyncstart & 256)
 782                tmp |= 4;
 783        if ((vdispend + 1) & 256)
 784                tmp |= 8;
 785        if (vtotal & 512)
 786                tmp |= 32;
 787        if (vdispend & 512)
 788                tmp |= 64;
 789        if (vsyncstart & 512)
 790                tmp |= 128;
 791        dev_dbg(info->device, "CRT7: %d\n", tmp);
 792        vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
 793
 794        tmp = 0x40;             /* LineCompare bit #8 */
 795        if ((vdispend + 1) & 512)
 796                tmp |= 0x20;
 797        if (var->vmode & FB_VMODE_DOUBLE)
 798                tmp |= 0x80;
 799        dev_dbg(info->device, "CRT9: %d\n", tmp);
 800        vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
 801
 802        dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
 803        vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
 804
 805        dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
 806        vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
 807
 808        dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
 809        vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
 810
 811        dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
 812        vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
 813
 814        dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
 815        vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
 816
 817        dev_dbg(info->device, "CRT18: 0xff\n");
 818        vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
 819
 820        tmp = 0;
 821        if (var->vmode & FB_VMODE_INTERLACED)
 822                tmp |= 1;
 823        if ((htotal + 5) & 64)
 824                tmp |= 16;
 825        if ((htotal + 5) & 128)
 826                tmp |= 32;
 827        if (vtotal & 256)
 828                tmp |= 64;
 829        if (vtotal & 512)
 830                tmp |= 128;
 831
 832        dev_dbg(info->device, "CRT1a: %d\n", tmp);
 833        vga_wcrt(regbase, CL_CRT1A, tmp);
 834
 835        freq = PICOS2KHZ(var->pixclock);
 836        if (var->bits_per_pixel == 24)
 837                if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
 838                        freq *= 3;
 839        if (cinfo->multiplexing)
 840                freq /= 2;
 841        if (cinfo->doubleVCLK)
 842                freq *= 2;
 843
 844        bestclock(freq, &nom, &den, &div);
 845
 846        dev_dbg(info->device, "VCLK freq: %ld kHz  nom: %d  den: %d  div: %d\n",
 847                freq, nom, den, div);
 848
 849        /* set VCLK0 */
 850        /* hardware RefClock: 14.31818 MHz */
 851        /* formula: VClk = (OSC * N) / (D * (1+P)) */
 852        /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
 853
 854        if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
 855            cinfo->btype == BT_SD64) {
 856                /* if freq is close to mclk or mclk/2 select mclk
 857                 * as clock source
 858                 */
 859                int divMCLK = cirrusfb_check_mclk(info, freq);
 860                if (divMCLK)
 861                        nom = 0;
 862                cirrusfb_set_mclk_as_source(info, divMCLK);
 863        }
 864        if (is_laguna(cinfo)) {
 865                long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
 866                unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
 867                unsigned short tile_control;
 868
 869                if (cinfo->btype == BT_LAGUNAB) {
 870                        tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
 871                        tile_control &= ~0x80;
 872                        fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
 873                }
 874
 875                fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
 876                fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
 877                control = fb_readw(cinfo->laguna_mmio + 0x402);
 878                threshold = fb_readw(cinfo->laguna_mmio + 0xea);
 879                control &= ~0x6800;
 880                format = 0;
 881                threshold &= 0xffc0 & 0x3fbf;
 882        }
 883        if (nom) {
 884                tmp = den << 1;
 885                if (div != 0)
 886                        tmp |= 1;
 887                /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
 888                if ((cinfo->btype == BT_SD64) ||
 889                    (cinfo->btype == BT_ALPINE) ||
 890                    (cinfo->btype == BT_GD5480))
 891                        tmp |= 0x80;
 892
 893                /* Laguna chipset has reversed clock registers */
 894                if (is_laguna(cinfo)) {
 895                        vga_wseq(regbase, CL_SEQRE, tmp);
 896                        vga_wseq(regbase, CL_SEQR1E, nom);
 897                } else {
 898                        vga_wseq(regbase, CL_SEQRE, nom);
 899                        vga_wseq(regbase, CL_SEQR1E, tmp);
 900                }
 901        }
 902
 903        if (yres >= 1024)
 904                /* 1280x1024 */
 905                vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
 906        else
 907                /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
 908                 * address wrap, no compat. */
 909                vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
 910
 911        /* don't know if it would hurt to also program this if no interlaced */
 912        /* mode is used, but I feel better this way.. :-) */
 913        if (var->vmode & FB_VMODE_INTERLACED)
 914                vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
 915        else
 916                vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
 917
 918        /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
 919        /* enable display memory & CRTC I/O address for color mode */
 920        tmp = 0x03 | 0xc;
 921        if (var->sync & FB_SYNC_HOR_HIGH_ACT)
 922                tmp |= 0x40;
 923        if (var->sync & FB_SYNC_VERT_HIGH_ACT)
 924                tmp |= 0x80;
 925        WGen(cinfo, VGA_MIS_W, tmp);
 926
 927        /* text cursor on and start line */
 928        vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
 929        /* text cursor end line */
 930        vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
 931
 932        /******************************************************
 933         *
 934         * 1 bpp
 935         *
 936         */
 937
 938        /* programming for different color depths */
 939        if (var->bits_per_pixel == 1) {
 940                dev_dbg(info->device, "preparing for 1 bit deep display\n");
 941                vga_wgfx(regbase, VGA_GFX_MODE, 0);     /* mode register */
 942
 943                /* SR07 */
 944                switch (cinfo->btype) {
 945                case BT_SD64:
 946                case BT_PICCOLO:
 947                case BT_PICASSO:
 948                case BT_SPECTRUM:
 949                case BT_PICASSO4:
 950                case BT_ALPINE:
 951                case BT_GD5480:
 952                        vga_wseq(regbase, CL_SEQR7,
 953                                 cinfo->multiplexing ?
 954                                        bi->sr07_1bpp_mux : bi->sr07_1bpp);
 955                        break;
 956
 957                case BT_LAGUNA:
 958                case BT_LAGUNAB:
 959                        vga_wseq(regbase, CL_SEQR7,
 960                                vga_rseq(regbase, CL_SEQR7) & ~0x01);
 961                        break;
 962
 963                default:
 964                        dev_warn(info->device, "unknown Board\n");
 965                        break;
 966                }
 967
 968                /* Extended Sequencer Mode */
 969                switch (cinfo->btype) {
 970
 971                case BT_PICCOLO:
 972                case BT_SPECTRUM:
 973                        /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
 974                        vga_wseq(regbase, CL_SEQRF, 0xb0);
 975                        break;
 976
 977                case BT_PICASSO:
 978                        /* ## vorher d0 avoid FIFO underruns..? */
 979                        vga_wseq(regbase, CL_SEQRF, 0xd0);
 980                        break;
 981
 982                case BT_SD64:
 983                case BT_PICASSO4:
 984                case BT_ALPINE:
 985                case BT_GD5480:
 986                case BT_LAGUNA:
 987                case BT_LAGUNAB:
 988                        /* do nothing */
 989                        break;
 990
 991                default:
 992                        dev_warn(info->device, "unknown Board\n");
 993                        break;
 994                }
 995
 996                /* pixel mask: pass-through for first plane */
 997                WGen(cinfo, VGA_PEL_MSK, 0x01);
 998                if (cinfo->multiplexing)
 999                        /* hidden dac reg: 1280x1024 */
1000                        WHDR(cinfo, 0x4a);
1001                else
1002                        /* hidden dac: nothing */
1003                        WHDR(cinfo, 0);
1004                /* memory mode: odd/even, ext. memory */
1005                vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1006                /* plane mask: only write to first plane */
1007                vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1008        }
1009
1010        /******************************************************
1011         *
1012         * 8 bpp
1013         *
1014         */
1015
1016        else if (var->bits_per_pixel == 8) {
1017                dev_dbg(info->device, "preparing for 8 bit deep display\n");
1018                switch (cinfo->btype) {
1019                case BT_SD64:
1020                case BT_PICCOLO:
1021                case BT_PICASSO:
1022                case BT_SPECTRUM:
1023                case BT_PICASSO4:
1024                case BT_ALPINE:
1025                case BT_GD5480:
1026                        vga_wseq(regbase, CL_SEQR7,
1027                                  cinfo->multiplexing ?
1028                                        bi->sr07_8bpp_mux : bi->sr07_8bpp);
1029                        break;
1030
1031                case BT_LAGUNA:
1032                case BT_LAGUNAB:
1033                        vga_wseq(regbase, CL_SEQR7,
1034                                vga_rseq(regbase, CL_SEQR7) | 0x01);
1035                        threshold |= 0x10;
1036                        break;
1037
1038                default:
1039                        dev_warn(info->device, "unknown Board\n");
1040                        break;
1041                }
1042
1043                switch (cinfo->btype) {
1044                case BT_PICCOLO:
1045                case BT_PICASSO:
1046                case BT_SPECTRUM:
1047                        /* Fast Page-Mode writes */
1048                        vga_wseq(regbase, CL_SEQRF, 0xb0);
1049                        break;
1050
1051                case BT_PICASSO4:
1052#ifdef CONFIG_ZORRO
1053                        /* ### INCOMPLETE!! */
1054                        vga_wseq(regbase, CL_SEQRF, 0xb8);
1055#endif
1056                case BT_ALPINE:
1057                case BT_SD64:
1058                case BT_GD5480:
1059                case BT_LAGUNA:
1060                case BT_LAGUNAB:
1061                        /* do nothing */
1062                        break;
1063
1064                default:
1065                        dev_warn(info->device, "unknown board\n");
1066                        break;
1067                }
1068
1069                /* mode register: 256 color mode */
1070                vga_wgfx(regbase, VGA_GFX_MODE, 64);
1071                if (cinfo->multiplexing)
1072                        /* hidden dac reg: 1280x1024 */
1073                        WHDR(cinfo, 0x4a);
1074                else
1075                        /* hidden dac: nothing */
1076                        WHDR(cinfo, 0);
1077        }
1078
1079        /******************************************************
1080         *
1081         * 16 bpp
1082         *
1083         */
1084
1085        else if (var->bits_per_pixel == 16) {
1086                dev_dbg(info->device, "preparing for 16 bit deep display\n");
1087                switch (cinfo->btype) {
1088                case BT_PICCOLO:
1089                case BT_SPECTRUM:
1090                        vga_wseq(regbase, CL_SEQR7, 0x87);
1091                        /* Fast Page-Mode writes */
1092                        vga_wseq(regbase, CL_SEQRF, 0xb0);
1093                        break;
1094
1095                case BT_PICASSO:
1096                        vga_wseq(regbase, CL_SEQR7, 0x27);
1097                        /* Fast Page-Mode writes */
1098                        vga_wseq(regbase, CL_SEQRF, 0xb0);
1099                        break;
1100
1101                case BT_SD64:
1102                case BT_PICASSO4:
1103                case BT_ALPINE:
1104                        /* Extended Sequencer Mode: 256c col. mode */
1105                        vga_wseq(regbase, CL_SEQR7,
1106                                        cinfo->doubleVCLK ? 0xa3 : 0xa7);
1107                        break;
1108
1109                case BT_GD5480:
1110                        vga_wseq(regbase, CL_SEQR7, 0x17);
1111                        /* We already set SRF and SR1F */
1112                        break;
1113
1114                case BT_LAGUNA:
1115                case BT_LAGUNAB:
1116                        vga_wseq(regbase, CL_SEQR7,
1117                                vga_rseq(regbase, CL_SEQR7) & ~0x01);
1118                        control |= 0x2000;
1119                        format |= 0x1400;
1120                        threshold |= 0x10;
1121                        break;
1122
1123                default:
1124                        dev_warn(info->device, "unknown Board\n");
1125                        break;
1126                }
1127
1128                /* mode register: 256 color mode */
1129                vga_wgfx(regbase, VGA_GFX_MODE, 64);
1130#ifdef CONFIG_PCI
1131                WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
1132#elif defined(CONFIG_ZORRO)
1133                /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1134                WHDR(cinfo, 0xa0);      /* hidden dac reg: nothing special */
1135#endif
1136        }
1137
1138        /******************************************************
1139         *
1140         * 24 bpp
1141         *
1142         */
1143
1144        else if (var->bits_per_pixel == 24) {
1145                dev_dbg(info->device, "preparing for 24 bit deep display\n");
1146                switch (cinfo->btype) {
1147                case BT_PICCOLO:
1148                case BT_SPECTRUM:
1149                        vga_wseq(regbase, CL_SEQR7, 0x85);
1150                        /* Fast Page-Mode writes */
1151                        vga_wseq(regbase, CL_SEQRF, 0xb0);
1152                        break;
1153
1154                case BT_PICASSO:
1155                        vga_wseq(regbase, CL_SEQR7, 0x25);
1156                        /* Fast Page-Mode writes */
1157                        vga_wseq(regbase, CL_SEQRF, 0xb0);
1158                        break;
1159
1160                case BT_SD64:
1161                case BT_PICASSO4:
1162                case BT_ALPINE:
1163                        /* Extended Sequencer Mode: 256c col. mode */
1164                        vga_wseq(regbase, CL_SEQR7, 0xa5);
1165                        break;
1166
1167                case BT_GD5480:
1168                        vga_wseq(regbase, CL_SEQR7, 0x15);
1169                        /* We already set SRF and SR1F */
1170                        break;
1171
1172                case BT_LAGUNA:
1173                case BT_LAGUNAB:
1174                        vga_wseq(regbase, CL_SEQR7,
1175                                vga_rseq(regbase, CL_SEQR7) & ~0x01);
1176                        control |= 0x4000;
1177                        format |= 0x2400;
1178                        threshold |= 0x20;
1179                        break;
1180
1181                default:
1182                        dev_warn(info->device, "unknown Board\n");
1183                        break;
1184                }
1185
1186                /* mode register: 256 color mode */
1187                vga_wgfx(regbase, VGA_GFX_MODE, 64);
1188                /* hidden dac reg: 8-8-8 mode (24 or 32) */
1189                WHDR(cinfo, 0xc5);
1190        }
1191
1192        /******************************************************
1193         *
1194         * unknown/unsupported bpp
1195         *
1196         */
1197
1198        else
1199                dev_err(info->device,
1200                        "What's this? requested color depth == %d.\n",
1201                        var->bits_per_pixel);
1202
1203        pitch = info->fix.line_length >> 3;
1204        vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1205        tmp = 0x22;
1206        if (pitch & 0x100)
1207                tmp |= 0x10;    /* offset overflow bit */
1208
1209        /* screen start addr #16-18, fastpagemode cycles */
1210        vga_wcrt(regbase, CL_CRT1B, tmp);
1211
1212        /* screen start address bit 19 */
1213        if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1214                vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
1215
1216        if (is_laguna(cinfo)) {
1217                tmp = 0;
1218                if ((htotal + 5) & 256)
1219                        tmp |= 128;
1220                if (hdispend & 256)
1221                        tmp |= 64;
1222                if (hsyncstart & 256)
1223                        tmp |= 48;
1224                if (vtotal & 1024)
1225                        tmp |= 8;
1226                if (vdispend & 1024)
1227                        tmp |= 4;
1228                if (vsyncstart & 1024)
1229                        tmp |= 3;
1230
1231                vga_wcrt(regbase, CL_CRT1E, tmp);
1232                dev_dbg(info->device, "CRT1e: %d\n", tmp);
1233        }
1234
1235        /* pixel panning */
1236        vga_wattr(regbase, CL_AR33, 0);
1237
1238        /* [ EGS: SetOffset(); ] */
1239        /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1240        AttrOn(cinfo);
1241
1242        if (is_laguna(cinfo)) {
1243                /* no tiles */
1244                fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1245                fb_writew(format, cinfo->laguna_mmio + 0xc0);
1246                fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1247        }
1248        /* finally, turn on everything - turn off "FullBandwidth" bit */
1249        /* also, set "DotClock%2" bit where requested */
1250        tmp = 0x01;
1251
1252/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1253    if (var->vmode & FB_VMODE_CLOCK_HALVE)
1254        tmp |= 0x08;
1255*/
1256
1257        vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1258        dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1259
1260#ifdef CIRRUSFB_DEBUG
1261        cirrusfb_dbg_reg_dump(info, NULL);
1262#endif
1263
1264        return 0;
1265}
1266
1267/* for some reason incomprehensible to me, cirrusfb requires that you write
1268 * the registers twice for the settings to take..grr. -dte */
1269static int cirrusfb_set_par(struct fb_info *info)
1270{
1271        cirrusfb_set_par_foo(info);
1272        return cirrusfb_set_par_foo(info);
1273}
1274
1275static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1276                              unsigned blue, unsigned transp,
1277                              struct fb_info *info)
1278{
1279        struct cirrusfb_info *cinfo = info->par;
1280
1281        if (regno > 255)
1282                return -EINVAL;
1283
1284        if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1285                u32 v;
1286                red >>= (16 - info->var.red.length);
1287                green >>= (16 - info->var.green.length);
1288                blue >>= (16 - info->var.blue.length);
1289
1290                if (regno >= 16)
1291                        return 1;
1292                v = (red << info->var.red.offset) |
1293                    (green << info->var.green.offset) |
1294                    (blue << info->var.blue.offset);
1295
1296                cinfo->pseudo_palette[regno] = v;
1297                return 0;
1298        }
1299
1300        if (info->var.bits_per_pixel == 8)
1301                WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1302
1303        return 0;
1304
1305}
1306
1307/*************************************************************************
1308        cirrusfb_pan_display()
1309
1310        performs display panning - provided hardware permits this
1311**************************************************************************/
1312static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1313                                struct fb_info *info)
1314{
1315        int xoffset;
1316        unsigned long base;
1317        unsigned char tmp, xpix;
1318        struct cirrusfb_info *cinfo = info->par;
1319
1320        /* no range checks for xoffset and yoffset,   */
1321        /* as fb_pan_display has already done this */
1322        if (var->vmode & FB_VMODE_YWRAP)
1323                return -EINVAL;
1324
1325        xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1326
1327        base = var->yoffset * info->fix.line_length + xoffset;
1328
1329        if (info->var.bits_per_pixel == 1) {
1330                /* base is already correct */
1331                xpix = (unsigned char) (var->xoffset % 8);
1332        } else {
1333                base /= 4;
1334                xpix = (unsigned char) ((xoffset % 4) * 2);
1335        }
1336
1337        if (!is_laguna(cinfo))
1338                cirrusfb_WaitBLT(cinfo->regbase);
1339
1340        /* lower 8 + 8 bits of screen start address */
1341        vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1342        vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1343
1344        /* 0xf2 is %11110010, exclude tmp bits */
1345        tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1346        /* construct bits 16, 17 and 18 of screen start address */
1347        if (base & 0x10000)
1348                tmp |= 0x01;
1349        if (base & 0x20000)
1350                tmp |= 0x04;
1351        if (base & 0x40000)
1352                tmp |= 0x08;
1353
1354        vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1355
1356        /* construct bit 19 of screen start address */
1357        if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
1358                tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
1359                if (is_laguna(cinfo))
1360                        tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
1361                else
1362                        tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
1363                vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
1364        }
1365
1366        /* write pixel panning value to AR33; this does not quite work in 8bpp
1367         *
1368         * ### Piccolo..? Will this work?
1369         */
1370        if (info->var.bits_per_pixel == 1)
1371                vga_wattr(cinfo->regbase, CL_AR33, xpix);
1372
1373        return 0;
1374}
1375
1376static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1377{
1378        /*
1379         * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1380         * then the caller blanks by setting the CLUT (Color Look Up Table)
1381         * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1382         * failed due to e.g. a video mode which doesn't support it.
1383         * Implements VESA suspend and powerdown modes on hardware that
1384         * supports disabling hsync/vsync:
1385         *   blank_mode == 2: suspend vsync
1386         *   blank_mode == 3: suspend hsync
1387         *   blank_mode == 4: powerdown
1388         */
1389        unsigned char val;
1390        struct cirrusfb_info *cinfo = info->par;
1391        int current_mode = cinfo->blank_mode;
1392
1393        dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1394
1395        if (info->state != FBINFO_STATE_RUNNING ||
1396            current_mode == blank_mode) {
1397                dev_dbg(info->device, "EXIT, returning 0\n");
1398                return 0;
1399        }
1400
1401        /* Undo current */
1402        if (current_mode == FB_BLANK_NORMAL ||
1403            current_mode == FB_BLANK_UNBLANK)
1404                /* clear "FullBandwidth" bit */
1405                val = 0;
1406        else
1407                /* set "FullBandwidth" bit */
1408                val = 0x20;
1409
1410        val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1411        vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1412
1413        switch (blank_mode) {
1414        case FB_BLANK_UNBLANK:
1415        case FB_BLANK_NORMAL:
1416                val = 0x00;
1417                break;
1418        case FB_BLANK_VSYNC_SUSPEND:
1419                val = 0x04;
1420                break;
1421        case FB_BLANK_HSYNC_SUSPEND:
1422                val = 0x02;
1423                break;
1424        case FB_BLANK_POWERDOWN:
1425                val = 0x06;
1426                break;
1427        default:
1428                dev_dbg(info->device, "EXIT, returning 1\n");
1429                return 1;
1430        }
1431
1432        vga_wgfx(cinfo->regbase, CL_GRE, val);
1433
1434        cinfo->blank_mode = blank_mode;
1435        dev_dbg(info->device, "EXIT, returning 0\n");
1436
1437        /* Let fbcon do a soft blank for us */
1438        return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1439}
1440
1441/**** END   Hardware specific Routines **************************************/
1442/****************************************************************************/
1443/**** BEGIN Internal Routines ***********************************************/
1444
1445static void init_vgachip(struct fb_info *info)
1446{
1447        struct cirrusfb_info *cinfo = info->par;
1448        const struct cirrusfb_board_info_rec *bi;
1449
1450        assert(cinfo != NULL);
1451
1452        bi = &cirrusfb_board_info[cinfo->btype];
1453
1454        /* reset board globally */
1455        switch (cinfo->btype) {
1456        case BT_PICCOLO:
1457                WSFR(cinfo, 0x01);
1458                udelay(500);
1459                WSFR(cinfo, 0x51);
1460                udelay(500);
1461                break;
1462        case BT_PICASSO:
1463                WSFR2(cinfo, 0xff);
1464                udelay(500);
1465                break;
1466        case BT_SD64:
1467        case BT_SPECTRUM:
1468                WSFR(cinfo, 0x1f);
1469                udelay(500);
1470                WSFR(cinfo, 0x4f);
1471                udelay(500);
1472                break;
1473        case BT_PICASSO4:
1474                /* disable flickerfixer */
1475                vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1476                mdelay(100);
1477                /* mode */
1478                vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1479                fallthrough;
1480        case BT_GD5480:
1481                /* from Klaus' NetBSD driver: */
1482                vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1483                fallthrough;
1484        case BT_ALPINE:
1485                /* put blitter into 542x compat */
1486                vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1487                break;
1488
1489        case BT_LAGUNA:
1490        case BT_LAGUNAB:
1491                /* Nothing to do to reset the board. */
1492                break;
1493
1494        default:
1495                dev_err(info->device, "Warning: Unknown board type\n");
1496                break;
1497        }
1498
1499        /* make sure RAM size set by this point */
1500        assert(info->screen_size > 0);
1501
1502        /* the P4 is not fully initialized here; I rely on it having been */
1503        /* inited under AmigaOS already, which seems to work just fine    */
1504        /* (Klaus advised to do it this way)                          */
1505
1506        if (cinfo->btype != BT_PICASSO4) {
1507                WGen(cinfo, CL_VSSM, 0x10);     /* EGS: 0x16 */
1508                WGen(cinfo, CL_POS102, 0x01);
1509                WGen(cinfo, CL_VSSM, 0x08);     /* EGS: 0x0e */
1510
1511                if (cinfo->btype != BT_SD64)
1512                        WGen(cinfo, CL_VSSM2, 0x01);
1513
1514                /* reset sequencer logic */
1515                vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1516
1517                /* FullBandwidth (video off) and 8/9 dot clock */
1518                vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1519
1520                /* "magic cookie" - doesn't make any sense to me.. */
1521/*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */
1522                /* unlock all extension registers */
1523                vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1524
1525                switch (cinfo->btype) {
1526                case BT_GD5480:
1527                        vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1528                        break;
1529                case BT_ALPINE:
1530                case BT_LAGUNA:
1531                case BT_LAGUNAB:
1532                        break;
1533                case BT_SD64:
1534#ifdef CONFIG_ZORRO
1535                        vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1536#endif
1537                        break;
1538                default:
1539                        vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1540                        vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1541                        break;
1542                }
1543        }
1544        /* plane mask: nothing */
1545        vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1546        /* character map select: doesn't even matter in gx mode */
1547        vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1548        /* memory mode: chain4, ext. memory */
1549        vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1550
1551        /* controller-internal base address of video memory */
1552        if (bi->init_sr07)
1553                vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1554
1555        /*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1556        /* EEPROM control: shouldn't be necessary to write to this at all.. */
1557
1558        /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1559        vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1560        /* graphics cursor Y position (..."... ) */
1561        vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1562        /* graphics cursor attributes */
1563        vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1564        /* graphics cursor pattern address */
1565        vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1566
1567        /* writing these on a P4 might give problems..  */
1568        if (cinfo->btype != BT_PICASSO4) {
1569                /* configuration readback and ext. color */
1570                vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1571                /* signature generator */
1572                vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1573        }
1574
1575        /* Screen A preset row scan: none */
1576        vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1577        /* Text cursor start: disable text cursor */
1578        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1579        /* Text cursor end: - */
1580        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1581        /* text cursor location high: 0 */
1582        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1583        /* text cursor location low: 0 */
1584        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1585
1586        /* Underline Row scanline: - */
1587        vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1588        /* ### add 0x40 for text modes with > 30 MHz pixclock */
1589        /* ext. display controls: ext.adr. wrap */
1590        vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1591
1592        /* Set/Reset registers: - */
1593        vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1594        /* Set/Reset enable: - */
1595        vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1596        /* Color Compare: - */
1597        vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1598        /* Data Rotate: - */
1599        vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1600        /* Read Map Select: - */
1601        vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1602        /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1603        vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1604        /* Miscellaneous: memory map base address, graphics mode */
1605        vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1606        /* Color Don't care: involve all planes */
1607        vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1608        /* Bit Mask: no mask at all */
1609        vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1610
1611        if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1612            is_laguna(cinfo))
1613                /* (5434 can't have bit 3 set for bitblt) */
1614                vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1615        else
1616        /* Graphics controller mode extensions: finer granularity,
1617         * 8byte data latches
1618         */
1619                vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1620
1621        vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1622        vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1623        vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1624        /* Background color byte 1: - */
1625        /*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1626        /*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1627
1628        /* Attribute Controller palette registers: "identity mapping" */
1629        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1630        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1631        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1632        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1633        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1634        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1635        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1636        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1637        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1638        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1639        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1640        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1641        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1642        vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1643        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1644        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1645
1646        /* Attribute Controller mode: graphics mode */
1647        vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1648        /* Overscan color reg.: reg. 0 */
1649        vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1650        /* Color Plane enable: Enable all 4 planes */
1651        vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1652        /* Color Select: - */
1653        vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1654
1655        WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1656
1657        /* BLT Start/status: Blitter reset */
1658        vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1659        /* - " -           : "end-of-reset" */
1660        vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1661
1662        /* misc... */
1663        WHDR(cinfo, 0); /* Hidden DAC register: - */
1664        return;
1665}
1666
1667static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1668{
1669#ifdef CONFIG_ZORRO /* only works on Zorro boards */
1670        static int IsOn = 0;    /* XXX not ok for multiple boards */
1671
1672        if (cinfo->btype == BT_PICASSO4)
1673                return;         /* nothing to switch */
1674        if (cinfo->btype == BT_ALPINE)
1675                return;         /* nothing to switch */
1676        if (cinfo->btype == BT_GD5480)
1677                return;         /* nothing to switch */
1678        if (cinfo->btype == BT_PICASSO) {
1679                if ((on && !IsOn) || (!on && IsOn))
1680                        WSFR(cinfo, 0xff);
1681                return;
1682        }
1683        if (on) {
1684                switch (cinfo->btype) {
1685                case BT_SD64:
1686                        WSFR(cinfo, cinfo->SFR | 0x21);
1687                        break;
1688                case BT_PICCOLO:
1689                        WSFR(cinfo, cinfo->SFR | 0x28);
1690                        break;
1691                case BT_SPECTRUM:
1692                        WSFR(cinfo, 0x6f);
1693                        break;
1694                default: /* do nothing */ break;
1695                }
1696        } else {
1697                switch (cinfo->btype) {
1698                case BT_SD64:
1699                        WSFR(cinfo, cinfo->SFR & 0xde);
1700                        break;
1701                case BT_PICCOLO:
1702                        WSFR(cinfo, cinfo->SFR & 0xd7);
1703                        break;
1704                case BT_SPECTRUM:
1705                        WSFR(cinfo, 0x4f);
1706                        break;
1707                default: /* do nothing */
1708                        break;
1709                }
1710        }
1711#endif /* CONFIG_ZORRO */
1712}
1713
1714/******************************************/
1715/* Linux 2.6-style  accelerated functions */
1716/******************************************/
1717
1718static int cirrusfb_sync(struct fb_info *info)
1719{
1720        struct cirrusfb_info *cinfo = info->par;
1721
1722        if (!is_laguna(cinfo)) {
1723                while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1724                        cpu_relax();
1725        }
1726        return 0;
1727}
1728
1729static void cirrusfb_fillrect(struct fb_info *info,
1730                              const struct fb_fillrect *region)
1731{
1732        struct fb_fillrect modded;
1733        int vxres, vyres;
1734        struct cirrusfb_info *cinfo = info->par;
1735        int m = info->var.bits_per_pixel;
1736        u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1737                cinfo->pseudo_palette[region->color] : region->color;
1738
1739        if (info->state != FBINFO_STATE_RUNNING)
1740                return;
1741        if (info->flags & FBINFO_HWACCEL_DISABLED) {
1742                cfb_fillrect(info, region);
1743                return;
1744        }
1745
1746        vxres = info->var.xres_virtual;
1747        vyres = info->var.yres_virtual;
1748
1749        memcpy(&modded, region, sizeof(struct fb_fillrect));
1750
1751        if (!modded.width || !modded.height ||
1752           modded.dx >= vxres || modded.dy >= vyres)
1753                return;
1754
1755        if (modded.dx + modded.width  > vxres)
1756                modded.width  = vxres - modded.dx;
1757        if (modded.dy + modded.height > vyres)
1758                modded.height = vyres - modded.dy;
1759
1760        cirrusfb_RectFill(cinfo->regbase,
1761                          info->var.bits_per_pixel,
1762                          (region->dx * m) / 8, region->dy,
1763                          (region->width * m) / 8, region->height,
1764                          color, color,
1765                          info->fix.line_length, 0x40);
1766}
1767
1768static void cirrusfb_copyarea(struct fb_info *info,
1769                              const struct fb_copyarea *area)
1770{
1771        struct fb_copyarea modded;
1772        u32 vxres, vyres;
1773        struct cirrusfb_info *cinfo = info->par;
1774        int m = info->var.bits_per_pixel;
1775
1776        if (info->state != FBINFO_STATE_RUNNING)
1777                return;
1778        if (info->flags & FBINFO_HWACCEL_DISABLED) {
1779                cfb_copyarea(info, area);
1780                return;
1781        }
1782
1783        vxres = info->var.xres_virtual;
1784        vyres = info->var.yres_virtual;
1785        memcpy(&modded, area, sizeof(struct fb_copyarea));
1786
1787        if (!modded.width || !modded.height ||
1788           modded.sx >= vxres || modded.sy >= vyres ||
1789           modded.dx >= vxres || modded.dy >= vyres)
1790                return;
1791
1792        if (modded.sx + modded.width > vxres)
1793                modded.width = vxres - modded.sx;
1794        if (modded.dx + modded.width > vxres)
1795                modded.width = vxres - modded.dx;
1796        if (modded.sy + modded.height > vyres)
1797                modded.height = vyres - modded.sy;
1798        if (modded.dy + modded.height > vyres)
1799                modded.height = vyres - modded.dy;
1800
1801        cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1802                        (area->sx * m) / 8, area->sy,
1803                        (area->dx * m) / 8, area->dy,
1804                        (area->width * m) / 8, area->height,
1805                        info->fix.line_length);
1806
1807}
1808
1809static void cirrusfb_imageblit(struct fb_info *info,
1810                               const struct fb_image *image)
1811{
1812        struct cirrusfb_info *cinfo = info->par;
1813        unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1814
1815        if (info->state != FBINFO_STATE_RUNNING)
1816                return;
1817        /* Alpine/SD64 does not work at 24bpp ??? */
1818        if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1819                cfb_imageblit(info, image);
1820        else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1821                  op == 0xc)
1822                cfb_imageblit(info, image);
1823        else {
1824                unsigned size = ((image->width + 7) >> 3) * image->height;
1825                int m = info->var.bits_per_pixel;
1826                u32 fg, bg;
1827
1828                if (info->var.bits_per_pixel == 8) {
1829                        fg = image->fg_color;
1830                        bg = image->bg_color;
1831                } else {
1832                        fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1833                        bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1834                }
1835                if (info->var.bits_per_pixel == 24) {
1836                        /* clear background first */
1837                        cirrusfb_RectFill(cinfo->regbase,
1838                                          info->var.bits_per_pixel,
1839                                          (image->dx * m) / 8, image->dy,
1840                                          (image->width * m) / 8,
1841                                          image->height,
1842                                          bg, bg,
1843                                          info->fix.line_length, 0x40);
1844                }
1845                cirrusfb_RectFill(cinfo->regbase,
1846                                  info->var.bits_per_pixel,
1847                                  (image->dx * m) / 8, image->dy,
1848                                  (image->width * m) / 8, image->height,
1849                                  fg, bg,
1850                                  info->fix.line_length, op);
1851                memcpy(info->screen_base, image->data, size);
1852        }
1853}
1854
1855#ifdef CONFIG_PCI
1856static int release_io_ports;
1857
1858/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1859 * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
1860 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1861 * seem to have. */
1862static unsigned int cirrusfb_get_memsize(struct fb_info *info,
1863                                         u8 __iomem *regbase)
1864{
1865        unsigned long mem;
1866        struct cirrusfb_info *cinfo = info->par;
1867
1868        if (is_laguna(cinfo)) {
1869                unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1870
1871                mem = ((SR14 & 7) + 1) << 20;
1872        } else {
1873                unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1874                switch ((SRF & 0x18)) {
1875                case 0x08:
1876                        mem = 512 * 1024;
1877                        break;
1878                case 0x10:
1879                        mem = 1024 * 1024;
1880                        break;
1881                /* 64-bit DRAM data bus width; assume 2MB.
1882                 * Also indicates 2MB memory on the 5430.
1883                 */
1884                case 0x18:
1885                        mem = 2048 * 1024;
1886                        break;
1887                default:
1888                        dev_warn(info->device, "Unknown memory size!\n");
1889                        mem = 1024 * 1024;
1890                }
1891                /* If DRAM bank switching is enabled, there must be
1892                 * twice as much memory installed. (4MB on the 5434)
1893                 */
1894                if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1895                        mem *= 2;
1896        }
1897
1898        /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1899        return mem;
1900}
1901
1902static void get_pci_addrs(const struct pci_dev *pdev,
1903                          unsigned long *display, unsigned long *registers)
1904{
1905        assert(pdev != NULL);
1906        assert(display != NULL);
1907        assert(registers != NULL);
1908
1909        *display = 0;
1910        *registers = 0;
1911
1912        /* This is a best-guess for now */
1913
1914        if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1915                *display = pci_resource_start(pdev, 1);
1916                *registers = pci_resource_start(pdev, 0);
1917        } else {
1918                *display = pci_resource_start(pdev, 0);
1919                *registers = pci_resource_start(pdev, 1);
1920        }
1921
1922        assert(*display != 0);
1923}
1924
1925static void cirrusfb_pci_unmap(struct fb_info *info)
1926{
1927        struct pci_dev *pdev = to_pci_dev(info->device);
1928        struct cirrusfb_info *cinfo = info->par;
1929
1930        if (cinfo->laguna_mmio == NULL)
1931                iounmap(cinfo->laguna_mmio);
1932        iounmap(info->screen_base);
1933#if 0 /* if system didn't claim this region, we would... */
1934        release_mem_region(0xA0000, 65535);
1935#endif
1936        if (release_io_ports)
1937                release_region(0x3C0, 32);
1938        pci_release_regions(pdev);
1939}
1940#endif /* CONFIG_PCI */
1941
1942#ifdef CONFIG_ZORRO
1943static void cirrusfb_zorro_unmap(struct fb_info *info)
1944{
1945        struct cirrusfb_info *cinfo = info->par;
1946        struct zorro_dev *zdev = to_zorro_dev(info->device);
1947
1948        if (info->fix.smem_start > 16 * MB_)
1949                iounmap(info->screen_base);
1950        if (info->fix.mmio_start > 16 * MB_)
1951                iounmap(cinfo->regbase);
1952
1953        zorro_release_device(zdev);
1954}
1955#endif /* CONFIG_ZORRO */
1956
1957/* function table of the above functions */
1958static const struct fb_ops cirrusfb_ops = {
1959        .owner          = THIS_MODULE,
1960        .fb_open        = cirrusfb_open,
1961        .fb_release     = cirrusfb_release,
1962        .fb_setcolreg   = cirrusfb_setcolreg,
1963        .fb_check_var   = cirrusfb_check_var,
1964        .fb_set_par     = cirrusfb_set_par,
1965        .fb_pan_display = cirrusfb_pan_display,
1966        .fb_blank       = cirrusfb_blank,
1967        .fb_fillrect    = cirrusfb_fillrect,
1968        .fb_copyarea    = cirrusfb_copyarea,
1969        .fb_sync        = cirrusfb_sync,
1970        .fb_imageblit   = cirrusfb_imageblit,
1971};
1972
1973static int cirrusfb_set_fbinfo(struct fb_info *info)
1974{
1975        struct cirrusfb_info *cinfo = info->par;
1976        struct fb_var_screeninfo *var = &info->var;
1977
1978        info->pseudo_palette = cinfo->pseudo_palette;
1979        info->flags = FBINFO_DEFAULT
1980                    | FBINFO_HWACCEL_XPAN
1981                    | FBINFO_HWACCEL_YPAN
1982                    | FBINFO_HWACCEL_FILLRECT
1983                    | FBINFO_HWACCEL_IMAGEBLIT
1984                    | FBINFO_HWACCEL_COPYAREA;
1985        if (noaccel || is_laguna(cinfo)) {
1986                info->flags |= FBINFO_HWACCEL_DISABLED;
1987                info->fix.accel = FB_ACCEL_NONE;
1988        } else
1989                info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
1990
1991        info->fbops = &cirrusfb_ops;
1992
1993        if (cinfo->btype == BT_GD5480) {
1994                if (var->bits_per_pixel == 16)
1995                        info->screen_base += 1 * MB_;
1996                if (var->bits_per_pixel == 32)
1997                        info->screen_base += 2 * MB_;
1998        }
1999
2000        /* Fill fix common fields */
2001        strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2002                sizeof(info->fix.id));
2003
2004        /* monochrome: only 1 memory plane */
2005        /* 8 bit and above: Use whole memory area */
2006        info->fix.smem_len   = info->screen_size;
2007        if (var->bits_per_pixel == 1)
2008                info->fix.smem_len /= 4;
2009        info->fix.type_aux   = 0;
2010        info->fix.xpanstep   = 1;
2011        info->fix.ypanstep   = 1;
2012        info->fix.ywrapstep  = 0;
2013
2014        /* FIXME: map region at 0xB8000 if available, fill in here */
2015        info->fix.mmio_len   = 0;
2016
2017        fb_alloc_cmap(&info->cmap, 256, 0);
2018
2019        return 0;
2020}
2021
2022static int cirrusfb_register(struct fb_info *info)
2023{
2024        struct cirrusfb_info *cinfo = info->par;
2025        int err;
2026
2027        /* sanity checks */
2028        assert(cinfo->btype != BT_NONE);
2029
2030        /* set all the vital stuff */
2031        cirrusfb_set_fbinfo(info);
2032
2033        dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2034
2035        err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2036        if (!err) {
2037                dev_dbg(info->device, "wrong initial video mode\n");
2038                err = -EINVAL;
2039                goto err_dealloc_cmap;
2040        }
2041
2042        info->var.activate = FB_ACTIVATE_NOW;
2043
2044        err = cirrusfb_check_var(&info->var, info);
2045        if (err < 0) {
2046                /* should never happen */
2047                dev_dbg(info->device,
2048                        "choking on default var... umm, no good.\n");
2049                goto err_dealloc_cmap;
2050        }
2051
2052        err = register_framebuffer(info);
2053        if (err < 0) {
2054                dev_err(info->device,
2055                        "could not register fb device; err = %d!\n", err);
2056                goto err_dealloc_cmap;
2057        }
2058
2059        return 0;
2060
2061err_dealloc_cmap:
2062        fb_dealloc_cmap(&info->cmap);
2063        return err;
2064}
2065
2066static void cirrusfb_cleanup(struct fb_info *info)
2067{
2068        struct cirrusfb_info *cinfo = info->par;
2069
2070        switch_monitor(cinfo, 0);
2071        unregister_framebuffer(info);
2072        fb_dealloc_cmap(&info->cmap);
2073        dev_dbg(info->device, "Framebuffer unregistered\n");
2074        cinfo->unmap(info);
2075        framebuffer_release(info);
2076}
2077
2078#ifdef CONFIG_PCI
2079static int cirrusfb_pci_register(struct pci_dev *pdev,
2080                                 const struct pci_device_id *ent)
2081{
2082        struct cirrusfb_info *cinfo;
2083        struct fb_info *info;
2084        unsigned long board_addr, board_size;
2085        int ret;
2086
2087        ret = pci_enable_device(pdev);
2088        if (ret < 0) {
2089                printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2090                goto err_out;
2091        }
2092
2093        info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2094        if (!info) {
2095                ret = -ENOMEM;
2096                goto err_out;
2097        }
2098
2099        cinfo = info->par;
2100        cinfo->btype = (enum cirrus_board) ent->driver_data;
2101
2102        dev_dbg(info->device,
2103                " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2104                (unsigned long long)pdev->resource[0].start,  cinfo->btype);
2105        dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2106                (unsigned long long)pdev->resource[1].start);
2107
2108        dev_dbg(info->device,
2109                "Attempt to get PCI info for Cirrus Graphics Card\n");
2110        get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2111        /* FIXME: this forces VGA.  alternatives? */
2112        cinfo->regbase = NULL;
2113        cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2114
2115        dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2116                board_addr, info->fix.mmio_start);
2117
2118        board_size = (cinfo->btype == BT_GD5480) ?
2119                32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2120
2121        ret = pci_request_regions(pdev, "cirrusfb");
2122        if (ret < 0) {
2123                dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2124                        board_addr);
2125                goto err_release_fb;
2126        }
2127#if 0 /* if the system didn't claim this region, we would... */
2128        if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2129                dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2130                        0xA0000L);
2131                ret = -EBUSY;
2132                goto err_release_regions;
2133        }
2134#endif
2135        if (request_region(0x3C0, 32, "cirrusfb"))
2136                release_io_ports = 1;
2137
2138        info->screen_base = ioremap(board_addr, board_size);
2139        if (!info->screen_base) {
2140                ret = -EIO;
2141                goto err_release_legacy;
2142        }
2143
2144        info->fix.smem_start = board_addr;
2145        info->screen_size = board_size;
2146        cinfo->unmap = cirrusfb_pci_unmap;
2147
2148        dev_info(info->device,
2149                 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2150                 info->screen_size >> 10, board_addr);
2151        pci_set_drvdata(pdev, info);
2152
2153        ret = cirrusfb_register(info);
2154        if (!ret)
2155                return 0;
2156
2157        iounmap(info->screen_base);
2158err_release_legacy:
2159        if (release_io_ports)
2160                release_region(0x3C0, 32);
2161#if 0
2162        release_mem_region(0xA0000, 65535);
2163err_release_regions:
2164#endif
2165        pci_release_regions(pdev);
2166err_release_fb:
2167        if (cinfo->laguna_mmio != NULL)
2168                iounmap(cinfo->laguna_mmio);
2169        framebuffer_release(info);
2170err_out:
2171        return ret;
2172}
2173
2174static void cirrusfb_pci_unregister(struct pci_dev *pdev)
2175{
2176        struct fb_info *info = pci_get_drvdata(pdev);
2177
2178        cirrusfb_cleanup(info);
2179}
2180
2181static struct pci_driver cirrusfb_pci_driver = {
2182        .name           = "cirrusfb",
2183        .id_table       = cirrusfb_pci_table,
2184        .probe          = cirrusfb_pci_register,
2185        .remove         = cirrusfb_pci_unregister,
2186#ifdef CONFIG_PM
2187#if 0
2188        .suspend        = cirrusfb_pci_suspend,
2189        .resume         = cirrusfb_pci_resume,
2190#endif
2191#endif
2192};
2193#endif /* CONFIG_PCI */
2194
2195#ifdef CONFIG_ZORRO
2196static int cirrusfb_zorro_register(struct zorro_dev *z,
2197                                   const struct zorro_device_id *ent)
2198{
2199        struct fb_info *info;
2200        int error;
2201        const struct zorrocl *zcl;
2202        enum cirrus_board btype;
2203        unsigned long regbase, ramsize, rambase;
2204        struct cirrusfb_info *cinfo;
2205
2206        info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2207        if (!info)
2208                return -ENOMEM;
2209
2210        zcl = (const struct zorrocl *)ent->driver_data;
2211        btype = zcl->type;
2212        regbase = zorro_resource_start(z) + zcl->regoffset;
2213        ramsize = zcl->ramsize;
2214        if (ramsize) {
2215                rambase = zorro_resource_start(z) + zcl->ramoffset;
2216                if (zorro_resource_len(z) == 64 * MB_) {
2217                        /* Quirk for 64 MiB Picasso IV */
2218                        rambase += zcl->ramoffset;
2219                }
2220        } else {
2221                struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2222                if (!ram || !zorro_resource_len(ram)) {
2223                        dev_err(info->device, "No video RAM found\n");
2224                        error = -ENODEV;
2225                        goto err_release_fb;
2226                }
2227                rambase = zorro_resource_start(ram);
2228                ramsize = zorro_resource_len(ram);
2229                if (zcl->ramid2 &&
2230                    (ram = zorro_find_device(zcl->ramid2, NULL))) {
2231                        if (zorro_resource_start(ram) != rambase + ramsize) {
2232                                dev_warn(info->device,
2233                                         "Skipping non-contiguous RAM at %pR\n",
2234                                         &ram->resource);
2235                        } else {
2236                                ramsize += zorro_resource_len(ram);
2237                        }
2238                }
2239        }
2240
2241        dev_info(info->device,
2242                 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2243                 cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2244                 rambase);
2245
2246        if (!zorro_request_device(z, "cirrusfb")) {
2247                dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2248                error = -EBUSY;
2249                goto err_release_fb;
2250        }
2251
2252        cinfo = info->par;
2253        cinfo->btype = btype;
2254
2255        info->fix.mmio_start = regbase;
2256        cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2257                                            : ZTWO_VADDR(regbase);
2258        if (!cinfo->regbase) {
2259                dev_err(info->device, "Cannot map registers\n");
2260                error = -EIO;
2261                goto err_release_dev;
2262        }
2263
2264        info->fix.smem_start = rambase;
2265        info->screen_size = ramsize;
2266        info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2267                                               : ZTWO_VADDR(rambase);
2268        if (!info->screen_base) {
2269                dev_err(info->device, "Cannot map video RAM\n");
2270                error = -EIO;
2271                goto err_unmap_reg;
2272        }
2273
2274        cinfo->unmap = cirrusfb_zorro_unmap;
2275
2276        dev_info(info->device,
2277                 "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2278                 ramsize / MB_, rambase);
2279
2280        /* MCLK select etc. */
2281        if (cirrusfb_board_info[btype].init_sr1f)
2282                vga_wseq(cinfo->regbase, CL_SEQR1F,
2283                         cirrusfb_board_info[btype].sr1f);
2284
2285        error = cirrusfb_register(info);
2286        if (error) {
2287                dev_err(info->device, "Failed to register device, error %d\n",
2288                        error);
2289                goto err_unmap_ram;
2290        }
2291
2292        zorro_set_drvdata(z, info);
2293        return 0;
2294
2295err_unmap_ram:
2296        if (rambase > 16 * MB_)
2297                iounmap(info->screen_base);
2298
2299err_unmap_reg:
2300        if (regbase > 16 * MB_)
2301                iounmap(cinfo->regbase);
2302err_release_dev:
2303        zorro_release_device(z);
2304err_release_fb:
2305        framebuffer_release(info);
2306        return error;
2307}
2308
2309void cirrusfb_zorro_unregister(struct zorro_dev *z)
2310{
2311        struct fb_info *info = zorro_get_drvdata(z);
2312
2313        cirrusfb_cleanup(info);
2314        zorro_set_drvdata(z, NULL);
2315}
2316
2317static struct zorro_driver cirrusfb_zorro_driver = {
2318        .name           = "cirrusfb",
2319        .id_table       = cirrusfb_zorro_table,
2320        .probe          = cirrusfb_zorro_register,
2321        .remove         = cirrusfb_zorro_unregister,
2322};
2323#endif /* CONFIG_ZORRO */
2324
2325#ifndef MODULE
2326static int __init cirrusfb_setup(char *options)
2327{
2328        char *this_opt;
2329
2330        if (!options || !*options)
2331                return 0;
2332
2333        while ((this_opt = strsep(&options, ",")) != NULL) {
2334                if (!*this_opt)
2335                        continue;
2336
2337                if (!strcmp(this_opt, "noaccel"))
2338                        noaccel = 1;
2339                else if (!strncmp(this_opt, "mode:", 5))
2340                        mode_option = this_opt + 5;
2341                else
2342                        mode_option = this_opt;
2343        }
2344        return 0;
2345}
2346#endif
2347
2348    /*
2349     *  Modularization
2350     */
2351
2352MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2353MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2354MODULE_LICENSE("GPL");
2355
2356static int __init cirrusfb_init(void)
2357{
2358        int error = 0;
2359
2360#ifndef MODULE
2361        char *option = NULL;
2362
2363        if (fb_get_options("cirrusfb", &option))
2364                return -ENODEV;
2365        cirrusfb_setup(option);
2366#endif
2367
2368#ifdef CONFIG_ZORRO
2369        error |= zorro_register_driver(&cirrusfb_zorro_driver);
2370#endif
2371#ifdef CONFIG_PCI
2372        error |= pci_register_driver(&cirrusfb_pci_driver);
2373#endif
2374        return error;
2375}
2376
2377static void __exit cirrusfb_exit(void)
2378{
2379#ifdef CONFIG_PCI
2380        pci_unregister_driver(&cirrusfb_pci_driver);
2381#endif
2382#ifdef CONFIG_ZORRO
2383        zorro_unregister_driver(&cirrusfb_zorro_driver);
2384#endif
2385}
2386
2387module_init(cirrusfb_init);
2388
2389module_param(mode_option, charp, 0);
2390MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2391module_param(noaccel, bool, 0);
2392MODULE_PARM_DESC(noaccel, "Disable acceleration");
2393
2394#ifdef MODULE
2395module_exit(cirrusfb_exit);
2396#endif
2397
2398/**********************************************************************/
2399/* about the following functions - I have used the same names for the */
2400/* functions as Markus Wild did in his Retina driver for NetBSD as    */
2401/* they just made sense for this purpose. Apart from that, I wrote    */
2402/* these functions myself.                                          */
2403/**********************************************************************/
2404
2405/*** WGen() - write into one of the external/general registers ***/
2406static void WGen(const struct cirrusfb_info *cinfo,
2407                  int regnum, unsigned char val)
2408{
2409        unsigned long regofs = 0;
2410
2411        if (cinfo->btype == BT_PICASSO) {
2412                /* Picasso II specific hack */
2413/*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2414                  regnum == CL_VSSM2) */
2415                if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2416                        regofs = 0xfff;
2417        }
2418
2419        vga_w(cinfo->regbase, regofs + regnum, val);
2420}
2421
2422/*** RGen() - read out one of the external/general registers ***/
2423static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2424{
2425        unsigned long regofs = 0;
2426
2427        if (cinfo->btype == BT_PICASSO) {
2428                /* Picasso II specific hack */
2429/*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2430                  regnum == CL_VSSM2) */
2431                if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2432                        regofs = 0xfff;
2433        }
2434
2435        return vga_r(cinfo->regbase, regofs + regnum);
2436}
2437
2438/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2439static void AttrOn(const struct cirrusfb_info *cinfo)
2440{
2441        assert(cinfo != NULL);
2442
2443        if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2444                /* if we're just in "write value" mode, write back the */
2445                /* same value as before to not modify anything */
2446                vga_w(cinfo->regbase, VGA_ATT_IW,
2447                      vga_r(cinfo->regbase, VGA_ATT_R));
2448        }
2449        /* turn on video bit */
2450/*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2451        vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2452
2453        /* dummy write on Reg0 to be on "write index" mode next time */
2454        vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2455}
2456
2457/*** WHDR() - write into the Hidden DAC register ***/
2458/* as the HDR is the only extension register that requires special treatment
2459 * (the other extension registers are accessible just like the "ordinary"
2460 * registers of their functional group) here is a specialized routine for
2461 * accessing the HDR
2462 */
2463static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2464{
2465        unsigned char dummy;
2466
2467        if (is_laguna(cinfo))
2468                return;
2469        if (cinfo->btype == BT_PICASSO) {
2470                /* Klaus' hint for correct access to HDR on some boards */
2471                /* first write 0 to pixel mask (3c6) */
2472                WGen(cinfo, VGA_PEL_MSK, 0x00);
2473                udelay(200);
2474                /* next read dummy from pixel address (3c8) */
2475                dummy = RGen(cinfo, VGA_PEL_IW);
2476                udelay(200);
2477        }
2478        /* now do the usual stuff to access the HDR */
2479
2480        dummy = RGen(cinfo, VGA_PEL_MSK);
2481        udelay(200);
2482        dummy = RGen(cinfo, VGA_PEL_MSK);
2483        udelay(200);
2484        dummy = RGen(cinfo, VGA_PEL_MSK);
2485        udelay(200);
2486        dummy = RGen(cinfo, VGA_PEL_MSK);
2487        udelay(200);
2488
2489        WGen(cinfo, VGA_PEL_MSK, val);
2490        udelay(200);
2491
2492        if (cinfo->btype == BT_PICASSO) {
2493                /* now first reset HDR access counter */
2494                dummy = RGen(cinfo, VGA_PEL_IW);
2495                udelay(200);
2496
2497                /* and at the end, restore the mask value */
2498                /* ## is this mask always 0xff? */
2499                WGen(cinfo, VGA_PEL_MSK, 0xff);
2500                udelay(200);
2501        }
2502}
2503
2504/*** WSFR() - write to the "special function register" (SFR) ***/
2505static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2506{
2507#ifdef CONFIG_ZORRO
2508        assert(cinfo->regbase != NULL);
2509        cinfo->SFR = val;
2510        z_writeb(val, cinfo->regbase + 0x8000);
2511#endif
2512}
2513
2514/* The Picasso has a second register for switching the monitor bit */
2515static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2516{
2517#ifdef CONFIG_ZORRO
2518        /* writing an arbitrary value to this one causes the monitor switcher */
2519        /* to flip to Amiga display */
2520        assert(cinfo->regbase != NULL);
2521        cinfo->SFR = val;
2522        z_writeb(val, cinfo->regbase + 0x9000);
2523#endif
2524}
2525
2526/*** WClut - set CLUT entry (range: 0..63) ***/
2527static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2528            unsigned char green, unsigned char blue)
2529{
2530        unsigned int data = VGA_PEL_D;
2531
2532        /* address write mode register is not translated.. */
2533        vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2534
2535        if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2536            cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2537            cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2538                /* but DAC data register IS, at least for Picasso II */
2539                if (cinfo->btype == BT_PICASSO)
2540                        data += 0xfff;
2541                vga_w(cinfo->regbase, data, red);
2542                vga_w(cinfo->regbase, data, green);
2543                vga_w(cinfo->regbase, data, blue);
2544        } else {
2545                vga_w(cinfo->regbase, data, blue);
2546                vga_w(cinfo->regbase, data, green);
2547                vga_w(cinfo->regbase, data, red);
2548        }
2549}
2550
2551#if 0
2552/*** RClut - read CLUT entry (range 0..63) ***/
2553static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2554            unsigned char *green, unsigned char *blue)
2555{
2556        unsigned int data = VGA_PEL_D;
2557
2558        vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2559
2560        if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2561            cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2562                if (cinfo->btype == BT_PICASSO)
2563                        data += 0xfff;
2564                *red = vga_r(cinfo->regbase, data);
2565                *green = vga_r(cinfo->regbase, data);
2566                *blue = vga_r(cinfo->regbase, data);
2567        } else {
2568                *blue = vga_r(cinfo->regbase, data);
2569                *green = vga_r(cinfo->regbase, data);
2570                *red = vga_r(cinfo->regbase, data);
2571        }
2572}
2573#endif
2574
2575/*******************************************************************
2576        cirrusfb_WaitBLT()
2577
2578        Wait for the BitBLT engine to complete a possible earlier job
2579*********************************************************************/
2580
2581/* FIXME: use interrupts instead */
2582static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2583{
2584        while (vga_rgfx(regbase, CL_GR31) & 0x08)
2585                cpu_relax();
2586}
2587
2588/*******************************************************************
2589        cirrusfb_BitBLT()
2590
2591        perform accelerated "scrolling"
2592********************************************************************/
2593
2594static void cirrusfb_set_blitter(u8 __iomem *regbase,
2595                            u_short nwidth, u_short nheight,
2596                            u_long nsrc, u_long ndest,
2597                            u_short bltmode, u_short line_length)
2598
2599{
2600        /* pitch: set to line_length */
2601        /* dest pitch low */
2602        vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2603        /* dest pitch hi */
2604        vga_wgfx(regbase, CL_GR25, line_length >> 8);
2605        /* source pitch low */
2606        vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2607        /* source pitch hi */
2608        vga_wgfx(regbase, CL_GR27, line_length >> 8);
2609
2610        /* BLT width: actual number of pixels - 1 */
2611        /* BLT width low */
2612        vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2613        /* BLT width hi */
2614        vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2615
2616        /* BLT height: actual number of lines -1 */
2617        /* BLT height low */
2618        vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2619        /* BLT width hi */
2620        vga_wgfx(regbase, CL_GR23, nheight >> 8);
2621
2622        /* BLT destination */
2623        /* BLT dest low */
2624        vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2625        /* BLT dest mid */
2626        vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2627        /* BLT dest hi */
2628        vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2629
2630        /* BLT source */
2631        /* BLT src low */
2632        vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2633        /* BLT src mid */
2634        vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2635        /* BLT src hi */
2636        vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2637
2638        /* BLT mode */
2639        vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2640
2641        /* BLT ROP: SrcCopy */
2642        vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2643
2644        /* and finally: GO! */
2645        vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2646}
2647
2648/*******************************************************************
2649        cirrusfb_BitBLT()
2650
2651        perform accelerated "scrolling"
2652********************************************************************/
2653
2654static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2655                            u_short curx, u_short cury,
2656                            u_short destx, u_short desty,
2657                            u_short width, u_short height,
2658                            u_short line_length)
2659{
2660        u_short nwidth = width - 1;
2661        u_short nheight = height - 1;
2662        u_long nsrc, ndest;
2663        u_char bltmode;
2664
2665        bltmode = 0x00;
2666        /* if source adr < dest addr, do the Blt backwards */
2667        if (cury <= desty) {
2668                if (cury == desty) {
2669                        /* if src and dest are on the same line, check x */
2670                        if (curx < destx)
2671                                bltmode |= 0x01;
2672                } else
2673                        bltmode |= 0x01;
2674        }
2675        /* standard case: forward blitting */
2676        nsrc = (cury * line_length) + curx;
2677        ndest = (desty * line_length) + destx;
2678        if (bltmode) {
2679                /* this means start addresses are at the end,
2680                 * counting backwards
2681                 */
2682                nsrc += nheight * line_length + nwidth;
2683                ndest += nheight * line_length + nwidth;
2684        }
2685
2686        cirrusfb_WaitBLT(regbase);
2687
2688        cirrusfb_set_blitter(regbase, nwidth, nheight,
2689                            nsrc, ndest, bltmode, line_length);
2690}
2691
2692/*******************************************************************
2693        cirrusfb_RectFill()
2694
2695        perform accelerated rectangle fill
2696********************************************************************/
2697
2698static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2699                     u_short x, u_short y, u_short width, u_short height,
2700                     u32 fg_color, u32 bg_color, u_short line_length,
2701                     u_char blitmode)
2702{
2703        u_long ndest = (y * line_length) + x;
2704        u_char op;
2705
2706        cirrusfb_WaitBLT(regbase);
2707
2708        /* This is a ColorExpand Blt, using the */
2709        /* same color for foreground and background */
2710        vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2711        vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2712
2713        op = 0x80;
2714        if (bits_per_pixel >= 16) {
2715                vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2716                vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2717                op = 0x90;
2718        }
2719        if (bits_per_pixel >= 24) {
2720                vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2721                vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2722                op = 0xa0;
2723        }
2724        if (bits_per_pixel == 32) {
2725                vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2726                vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2727                op = 0xb0;
2728        }
2729        cirrusfb_set_blitter(regbase, width - 1, height - 1,
2730                            0, ndest, op | blitmode, line_length);
2731}
2732
2733/**************************************************************************
2734 * bestclock() - determine closest possible clock lower(?) than the
2735 * desired pixel clock
2736 **************************************************************************/
2737static void bestclock(long freq, int *nom, int *den, int *div)
2738{
2739        int n, d;
2740        long h, diff;
2741
2742        assert(nom != NULL);
2743        assert(den != NULL);
2744        assert(div != NULL);
2745
2746        *nom = 0;
2747        *den = 0;
2748        *div = 0;
2749
2750        if (freq < 8000)
2751                freq = 8000;
2752
2753        diff = freq;
2754
2755        for (n = 32; n < 128; n++) {
2756                int s = 0;
2757
2758                d = (14318 * n) / freq;
2759                if ((d >= 7) && (d <= 63)) {
2760                        int temp = d;
2761
2762                        if (temp > 31) {
2763                                s = 1;
2764                                temp >>= 1;
2765                        }
2766                        h = ((14318 * n) / temp) >> s;
2767                        h = h > freq ? h - freq : freq - h;
2768                        if (h < diff) {
2769                                diff = h;
2770                                *nom = n;
2771                                *den = temp;
2772                                *div = s;
2773                        }
2774                }
2775                d++;
2776                if ((d >= 7) && (d <= 63)) {
2777                        if (d > 31) {
2778                                s = 1;
2779                                d >>= 1;
2780                        }
2781                        h = ((14318 * n) / d) >> s;
2782                        h = h > freq ? h - freq : freq - h;
2783                        if (h < diff) {
2784                                diff = h;
2785                                *nom = n;
2786                                *den = d;
2787                                *div = s;
2788                        }
2789                }
2790        }
2791}
2792
2793/* -------------------------------------------------------------------------
2794 *
2795 * debugging functions
2796 *
2797 * -------------------------------------------------------------------------
2798 */
2799
2800#ifdef CIRRUSFB_DEBUG
2801
2802/**
2803 * cirrusfb_dbg_print_regs
2804 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2805 * @reg_class: type of registers to read: %CRT, or %SEQ
2806 *
2807 * DESCRIPTION:
2808 * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2809 * old-style I/O ports are queried for information, otherwise MMIO is
2810 * used at the given @base address to query the information.
2811 */
2812
2813static void cirrusfb_dbg_print_regs(struct fb_info *info,
2814                                    caddr_t regbase,
2815                                    enum cirrusfb_dbg_reg_class reg_class, ...)
2816{
2817        va_list list;
2818        unsigned char val = 0;
2819        unsigned reg;
2820        char *name;
2821
2822        va_start(list, reg_class);
2823
2824        name = va_arg(list, char *);
2825        while (name != NULL) {
2826                reg = va_arg(list, int);
2827
2828                switch (reg_class) {
2829                case CRT:
2830                        val = vga_rcrt(regbase, (unsigned char) reg);
2831                        break;
2832                case SEQ:
2833                        val = vga_rseq(regbase, (unsigned char) reg);
2834                        break;
2835                default:
2836                        /* should never occur */
2837                        assert(false);
2838                        break;
2839                }
2840
2841                dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2842
2843                name = va_arg(list, char *);
2844        }
2845
2846        va_end(list);
2847}
2848
2849/**
2850 * cirrusfb_dbg_reg_dump
2851 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2852 *
2853 * DESCRIPTION:
2854 * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2855 * old-style I/O ports are queried for information, otherwise MMIO is
2856 * used at the given @base address to query the information.
2857 */
2858
2859static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2860{
2861        dev_dbg(info->device, "VGA CRTC register dump:\n");
2862
2863        cirrusfb_dbg_print_regs(info, regbase, CRT,
2864                           "CR00", 0x00,
2865                           "CR01", 0x01,
2866                           "CR02", 0x02,
2867                           "CR03", 0x03,
2868                           "CR04", 0x04,
2869                           "CR05", 0x05,
2870                           "CR06", 0x06,
2871                           "CR07", 0x07,
2872                           "CR08", 0x08,
2873                           "CR09", 0x09,
2874                           "CR0A", 0x0A,
2875                           "CR0B", 0x0B,
2876                           "CR0C", 0x0C,
2877                           "CR0D", 0x0D,
2878                           "CR0E", 0x0E,
2879                           "CR0F", 0x0F,
2880                           "CR10", 0x10,
2881                           "CR11", 0x11,
2882                           "CR12", 0x12,
2883                           "CR13", 0x13,
2884                           "CR14", 0x14,
2885                           "CR15", 0x15,
2886                           "CR16", 0x16,
2887                           "CR17", 0x17,
2888                           "CR18", 0x18,
2889                           "CR22", 0x22,
2890                           "CR24", 0x24,
2891                           "CR26", 0x26,
2892                           "CR2D", 0x2D,
2893                           "CR2E", 0x2E,
2894                           "CR2F", 0x2F,
2895                           "CR30", 0x30,
2896                           "CR31", 0x31,
2897                           "CR32", 0x32,
2898                           "CR33", 0x33,
2899                           "CR34", 0x34,
2900                           "CR35", 0x35,
2901                           "CR36", 0x36,
2902                           "CR37", 0x37,
2903                           "CR38", 0x38,
2904                           "CR39", 0x39,
2905                           "CR3A", 0x3A,
2906                           "CR3B", 0x3B,
2907                           "CR3C", 0x3C,
2908                           "CR3D", 0x3D,
2909                           "CR3E", 0x3E,
2910                           "CR3F", 0x3F,
2911                           NULL);
2912
2913        dev_dbg(info->device, "\n");
2914
2915        dev_dbg(info->device, "VGA SEQ register dump:\n");
2916
2917        cirrusfb_dbg_print_regs(info, regbase, SEQ,
2918                           "SR00", 0x00,
2919                           "SR01", 0x01,
2920                           "SR02", 0x02,
2921                           "SR03", 0x03,
2922                           "SR04", 0x04,
2923                           "SR08", 0x08,
2924                           "SR09", 0x09,
2925                           "SR0A", 0x0A,
2926                           "SR0B", 0x0B,
2927                           "SR0D", 0x0D,
2928                           "SR10", 0x10,
2929                           "SR11", 0x11,
2930                           "SR12", 0x12,
2931                           "SR13", 0x13,
2932                           "SR14", 0x14,
2933                           "SR15", 0x15,
2934                           "SR16", 0x16,
2935                           "SR17", 0x17,
2936                           "SR18", 0x18,
2937                           "SR19", 0x19,
2938                           "SR1A", 0x1A,
2939                           "SR1B", 0x1B,
2940                           "SR1C", 0x1C,
2941                           "SR1D", 0x1D,
2942                           "SR1E", 0x1E,
2943                           "SR1F", 0x1F,
2944                           NULL);
2945
2946        dev_dbg(info->device, "\n");
2947}
2948
2949#endif                          /* CIRRUSFB_DEBUG */
2950
2951