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