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