linux/drivers/video/cirrusfb.c
<<
>>
Prefs
   1/*
   2 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
   3 *
   4 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
   5 *
   6 * Contributors (thanks, all!)
   7 *
   8 *      David Eger:
   9 *      Overhaul for Linux 2.6
  10 *
  11 *      Jeff Rugen:
  12 *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
  13 *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
  14 *
  15 *      Geert Uytterhoeven:
  16 *      Excellent code review.
  17 *
  18 *      Lars Hecking:
  19 *      Amiga updates and testing.
  20 *
  21 * Original cirrusfb author:  Frank Neumann
  22 *
  23 * Based on retz3fb.c and cirrusfb.c:
  24 *      Copyright (C) 1997 Jes Sorensen
  25 *      Copyright (C) 1996 Frank Neumann
  26 *
  27 ***************************************************************
  28 *
  29 * Format this code with GNU indent '-kr -i8 -pcs' options.
  30 *
  31 * This file is subject to the terms and conditions of the GNU General Public
  32 * License.  See the file COPYING in the main directory of this archive
  33 * for more details.
  34 *
  35 */
  36
  37#include <linux/module.h>
  38#include <linux/kernel.h>
  39#include <linux/errno.h>
  40#include <linux/string.h>
  41#include <linux/mm.h>
  42#include <linux/delay.h>
  43#include <linux/fb.h>
  44#include <linux/init.h>
  45#include <asm/pgtable.h>
  46
  47#ifdef CONFIG_ZORRO
  48#include <linux/zorro.h>
  49#endif
  50#ifdef CONFIG_PCI
  51#include <linux/pci.h>
  52#endif
  53#ifdef CONFIG_AMIGA
  54#include <asm/amigahw.h>
  55#endif
  56#ifdef CONFIG_PPC_PREP
  57#include <asm/machdep.h>
  58#define isPReP machine_is(prep)
  59#else
  60#define isPReP 0
  61#endif
  62
  63#include <video/vga.h>
  64#include <video/cirrus.h>
  65
  66/*****************************************************************
  67 *
  68 * debugging and utility macros
  69 *
  70 */
  71
  72/* disable runtime assertions? */
  73/* #define CIRRUSFB_NDEBUG */
  74
  75/* debugging assertions */
  76#ifndef CIRRUSFB_NDEBUG
  77#define assert(expr) \
  78        if (!(expr)) { \
  79                printk("Assertion failed! %s,%s,%s,line=%d\n", \
  80                #expr, __FILE__, __func__, __LINE__); \
  81        }
  82#else
  83#define assert(expr)
  84#endif
  85
  86#define MB_ (1024 * 1024)
  87
  88/*****************************************************************
  89 *
  90 * chipset information
  91 *
  92 */
  93
  94/* board types */
  95enum cirrus_board {
  96        BT_NONE = 0,
  97        BT_SD64,        /* GD5434 */
  98        BT_PICCOLO,     /* GD5426 */
  99        BT_PICASSO,     /* GD5426 or GD5428 */
 100        BT_SPECTRUM,    /* GD5426 or GD5428 */
 101        BT_PICASSO4,    /* GD5446 */
 102        BT_ALPINE,      /* GD543x/4x */
 103        BT_GD5480,
 104        BT_LAGUNA,      /* GD5462/64 */
 105        BT_LAGUNAB,     /* GD5465 */
 106};
 107
 108/*
 109 * per-board-type information, used for enumerating and abstracting
 110 * chip-specific information
 111 * NOTE: MUST be in the same order as enum cirrus_board in order to
 112 * use direct indexing on this array
 113 * NOTE: '__initdata' cannot be used as some of this info
 114 * is required at runtime.  Maybe separate into an init-only and
 115 * a run-time table?
 116 */
 117static const struct cirrusfb_board_info_rec {
 118        char *name;             /* ASCII name of chipset */
 119        long maxclock[5];               /* maximum video clock */
 120        /* for  1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
 121        bool init_sr07 : 1; /* init SR07 during init_vgachip() */
 122        bool init_sr1f : 1; /* write SR1F during init_vgachip() */
 123        /* construct bit 19 of screen start address */
 124        bool scrn_start_bit19 : 1;
 125
 126        /* initial SR07 value, then for each mode */
 127        unsigned char sr07;
 128        unsigned char sr07_1bpp;
 129        unsigned char sr07_1bpp_mux;
 130        unsigned char sr07_8bpp;
 131        unsigned char sr07_8bpp_mux;
 132
 133        unsigned char sr1f;     /* SR1F VGA initial register value */
 134} cirrusfb_board_info[] = {
 135        [BT_SD64] = {
 136                .name                   = "CL SD64",
 137                .maxclock               = {
 138                        /* guess */
 139                        /* the SD64/P4 have a higher max. videoclock */
 140                        135100, 135100, 85500, 85500, 0
 141                },
 142                .init_sr07              = true,
 143                .init_sr1f              = true,
 144                .scrn_start_bit19       = true,
 145                .sr07                   = 0xF0,
 146                .sr07_1bpp              = 0xF0,
 147                .sr07_1bpp_mux          = 0xF6,
 148                .sr07_8bpp              = 0xF1,
 149                .sr07_8bpp_mux          = 0xF7,
 150                .sr1f                   = 0x1E
 151        },
 152        [BT_PICCOLO] = {
 153                .name                   = "CL Piccolo",
 154                .maxclock               = {
 155                        /* guess */
 156                        90000, 90000, 90000, 90000, 90000
 157                },
 158                .init_sr07              = true,
 159                .init_sr1f              = true,
 160                .scrn_start_bit19       = false,
 161                .sr07                   = 0x80,
 162                .sr07_1bpp              = 0x80,
 163                .sr07_8bpp              = 0x81,
 164                .sr1f                   = 0x22
 165        },
 166        [BT_PICASSO] = {
 167                .name                   = "CL Picasso",
 168                .maxclock               = {
 169                        /* guess */
 170                        90000, 90000, 90000, 90000, 90000
 171                },
 172                .init_sr07              = true,
 173                .init_sr1f              = true,
 174                .scrn_start_bit19       = false,
 175                .sr07                   = 0x20,
 176                .sr07_1bpp              = 0x20,
 177                .sr07_8bpp              = 0x21,
 178                .sr1f                   = 0x22
 179        },
 180        [BT_SPECTRUM] = {
 181                .name                   = "CL Spectrum",
 182                .maxclock               = {
 183                        /* guess */
 184                        90000, 90000, 90000, 90000, 90000
 185                },
 186                .init_sr07              = true,
 187                .init_sr1f              = true,
 188                .scrn_start_bit19       = false,
 189                .sr07                   = 0x80,
 190                .sr07_1bpp              = 0x80,
 191                .sr07_8bpp              = 0x81,
 192                .sr1f                   = 0x22
 193        },
 194        [BT_PICASSO4] = {
 195                .name                   = "CL Picasso4",
 196                .maxclock               = {
 197                        135100, 135100, 85500, 85500, 0
 198                },
 199                .init_sr07              = true,
 200                .init_sr1f              = false,
 201                .scrn_start_bit19       = true,
 202                .sr07                   = 0xA0,
 203                .sr07_1bpp              = 0xA0,
 204                .sr07_1bpp_mux          = 0xA6,
 205                .sr07_8bpp              = 0xA1,
 206                .sr07_8bpp_mux          = 0xA7,
 207                .sr1f                   = 0
 208        },
 209        [BT_ALPINE] = {
 210                .name                   = "CL Alpine",
 211                .maxclock               = {
 212                        /* for the GD5430.  GD5446 can do more... */
 213                        85500, 85500, 50000, 28500, 0
 214                },
 215                .init_sr07              = true,
 216                .init_sr1f              = true,
 217                .scrn_start_bit19       = true,
 218                .sr07                   = 0xA0,
 219                .sr07_1bpp              = 0xA0,
 220                .sr07_1bpp_mux          = 0xA6,
 221                .sr07_8bpp              = 0xA1,
 222                .sr07_8bpp_mux          = 0xA7,
 223                .sr1f                   = 0x1C
 224        },
 225        [BT_GD5480] = {
 226                .name                   = "CL GD5480",
 227                .maxclock               = {
 228                        135100, 200000, 200000, 135100, 135100
 229                },
 230                .init_sr07              = true,
 231                .init_sr1f              = true,
 232                .scrn_start_bit19       = true,
 233                .sr07                   = 0x10,
 234                .sr07_1bpp              = 0x11,
 235                .sr07_8bpp              = 0x11,
 236                .sr1f                   = 0x1C
 237        },
 238        [BT_LAGUNA] = {
 239                .name                   = "CL Laguna",
 240                .maxclock               = {
 241                        /* taken from X11 code */
 242                        170000, 170000, 170000, 170000, 135100,
 243                },
 244                .init_sr07              = false,
 245                .init_sr1f              = false,
 246                .scrn_start_bit19       = true,
 247        },
 248        [BT_LAGUNAB] = {
 249                .name                   = "CL Laguna AGP",
 250                .maxclock               = {
 251                        /* taken from X11 code */
 252                        170000, 250000, 170000, 170000, 135100,
 253                },
 254                .init_sr07              = false,
 255                .init_sr1f              = false,
 256                .scrn_start_bit19       = true,
 257        }
 258};
 259
 260#ifdef CONFIG_PCI
 261#define CHIP(id, btype) \
 262        { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
 263
 264static struct pci_device_id cirrusfb_pci_table[] = {
 265        CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
 266        CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
 267        CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
 268        CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
 269        CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
 270        CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
 271        CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
 272        CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
 273        CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
 274        CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
 275        CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
 276        { 0, }
 277};
 278MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
 279#undef CHIP
 280#endif /* CONFIG_PCI */
 281
 282#ifdef CONFIG_ZORRO
 283static const struct zorro_device_id cirrusfb_zorro_table[] = {
 284        {
 285                .id             = ZORRO_PROD_HELFRICH_SD64_RAM,
 286                .driver_data    = BT_SD64,
 287        }, {
 288                .id             = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
 289                .driver_data    = BT_PICCOLO,
 290        }, {
 291                .id     = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
 292                .driver_data    = BT_PICASSO,
 293        }, {
 294                .id             = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
 295                .driver_data    = BT_SPECTRUM,
 296        }, {
 297                .id             = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
 298                .driver_data    = BT_PICASSO4,
 299        },
 300        { 0 }
 301};
 302
 303static const struct {
 304        zorro_id id2;
 305        unsigned long size;
 306} cirrusfb_zorro_table2[] = {
 307        [BT_SD64] = {
 308                .id2    = ZORRO_PROD_HELFRICH_SD64_REG,
 309                .size   = 0x400000
 310        },
 311        [BT_PICCOLO] = {
 312                .id2    = ZORRO_PROD_HELFRICH_PICCOLO_REG,
 313                .size   = 0x200000
 314        },
 315        [BT_PICASSO] = {
 316                .id2    = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
 317                .size   = 0x200000
 318        },
 319        [BT_SPECTRUM] = {
 320                .id2    = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
 321                .size   = 0x200000
 322        },
 323        [BT_PICASSO4] = {
 324                .id2    = 0,
 325                .size   = 0x400000
 326        }
 327};
 328#endif /* CONFIG_ZORRO */
 329
 330#ifdef CIRRUSFB_DEBUG
 331enum cirrusfb_dbg_reg_class {
 332        CRT,
 333        SEQ
 334};
 335#endif          /* CIRRUSFB_DEBUG */
 336
 337/* info about board */
 338struct cirrusfb_info {
 339        u8 __iomem *regbase;
 340        u8 __iomem *laguna_mmio;
 341        enum cirrus_board btype;
 342        unsigned char SFR;      /* Shadow of special function register */
 343
 344        int multiplexing;
 345        int doubleVCLK;
 346        int blank_mode;
 347        u32 pseudo_palette[16];
 348
 349        void (*unmap)(struct fb_info *info);
 350};
 351
 352static int noaccel __devinitdata;
 353static char *mode_option __devinitdata = "640x480@60";
 354
 355/****************************************************************************/
 356/**** BEGIN PROTOTYPES ******************************************************/
 357
 358/*--- Interface used by the world ------------------------------------------*/
 359static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
 360                                struct fb_info *info);
 361
 362/*--- Internal routines ----------------------------------------------------*/
 363static void init_vgachip(struct fb_info *info);
 364static void switch_monitor(struct cirrusfb_info *cinfo, int on);
 365static void WGen(const struct cirrusfb_info *cinfo,
 366                 int regnum, unsigned char val);
 367static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
 368static void AttrOn(const struct cirrusfb_info *cinfo);
 369static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
 370static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
 371static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
 372static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
 373                  unsigned char red, unsigned char green, unsigned char blue);
 374#if 0
 375static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
 376                  unsigned char *red, unsigned char *green,
 377                  unsigned char *blue);
 378#endif
 379static void cirrusfb_WaitBLT(u8 __iomem *regbase);
 380static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
 381                            u_short curx, u_short cury,
 382                            u_short destx, u_short desty,
 383                            u_short width, u_short height,
 384                            u_short line_length);
 385static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
 386                              u_short x, u_short y,
 387                              u_short width, u_short height,
 388                              u32 fg_color, u32 bg_color,
 389                              u_short line_length, u_char blitmode);
 390
 391static void bestclock(long freq, int *nom, int *den, int *div);
 392
 393#ifdef CIRRUSFB_DEBUG
 394static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
 395static void cirrusfb_dbg_print_regs(struct fb_info *info,
 396                                    caddr_t regbase,
 397                                    enum cirrusfb_dbg_reg_class reg_class, ...);
 398#endif /* CIRRUSFB_DEBUG */
 399
 400/*** END   PROTOTYPES ********************************************************/
 401/*****************************************************************************/
 402/*** BEGIN Interface Used by the World ***************************************/
 403
 404static inline int is_laguna(const struct cirrusfb_info *cinfo)
 405{
 406        return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
 407}
 408
 409static int opencount;
 410
 411/*--- Open /dev/fbx ---------------------------------------------------------*/
 412static int cirrusfb_open(struct fb_info *info, int user)
 413{
 414        if (opencount++ == 0)
 415                switch_monitor(info->par, 1);
 416        return 0;
 417}
 418
 419/*--- Close /dev/fbx --------------------------------------------------------*/
 420static int cirrusfb_release(struct fb_info *info, int user)
 421{
 422        if (--opencount == 0)
 423                switch_monitor(info->par, 0);
 424        return 0;
 425}
 426
 427/**** END   Interface used by the World *************************************/
 428/****************************************************************************/
 429/**** BEGIN Hardware specific Routines **************************************/
 430
 431/* Check if the MCLK is not a better clock source */
 432static int cirrusfb_check_mclk(struct fb_info *info, long freq)
 433{
 434        struct cirrusfb_info *cinfo = info->par;
 435        long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
 436
 437        /* Read MCLK value */
 438        mclk = (14318 * mclk) >> 3;
 439        dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
 440
 441        /* Determine if we should use MCLK instead of VCLK, and if so, what we
 442         * should divide it by to get VCLK
 443         */
 444
 445        if (abs(freq - mclk) < 250) {
 446                dev_dbg(info->device, "Using VCLK = MCLK\n");
 447                return 1;
 448        } else if (abs(freq - (mclk / 2)) < 250) {
 449                dev_dbg(info->device, "Using VCLK = MCLK/2\n");
 450                return 2;
 451        }
 452
 453        return 0;
 454}
 455
 456static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
 457                                   struct fb_info *info)
 458{
 459        long freq;
 460        long maxclock;
 461        struct cirrusfb_info *cinfo = info->par;
 462        unsigned maxclockidx = var->bits_per_pixel >> 3;
 463
 464        /* convert from ps to kHz */
 465        freq = PICOS2KHZ(var->pixclock);
 466
 467        dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
 468
 469        maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
 470        cinfo->multiplexing = 0;
 471
 472        /* If the frequency is greater than we can support, we might be able
 473         * to use multiplexing for the video mode */
 474        if (freq > maxclock) {
 475                dev_err(info->device,
 476                        "Frequency greater than maxclock (%ld kHz)\n",
 477                        maxclock);
 478                return -EINVAL;
 479        }
 480        /*
 481         * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
 482         * pixel clock
 483         */
 484        if (var->bits_per_pixel == 8) {
 485                switch (cinfo->btype) {
 486                case BT_ALPINE:
 487                case BT_SD64:
 488                case BT_PICASSO4:
 489                        if (freq > 85500)
 490                                cinfo->multiplexing = 1;
 491                        break;
 492                case BT_GD5480:
 493                        if (freq > 135100)
 494                                cinfo->multiplexing = 1;
 495                        break;
 496
 497                default:
 498                        break;
 499                }
 500        }
 501
 502        /* If we have a 1MB 5434, we need to put ourselves in a mode where
 503         * the VCLK is double the pixel clock. */
 504        cinfo->doubleVCLK = 0;
 505        if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
 506            var->bits_per_pixel == 16) {
 507                cinfo->doubleVCLK = 1;
 508        }
 509
 510        return 0;
 511}
 512
 513static int cirrusfb_check_var(struct fb_var_screeninfo *var,
 514                              struct fb_info *info)
 515{
 516        int yres;
 517        /* memory size in pixels */
 518        unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
 519        struct cirrusfb_info *cinfo = info->par;
 520
 521        switch (var->bits_per_pixel) {
 522        case 1:
 523                var->red.offset = 0;
 524                var->red.length = 1;
 525                var->green = var->red;
 526                var->blue = var->red;
 527                break;
 528
 529        case 8:
 530                var->red.offset = 0;
 531                var->red.length = 8;
 532                var->green = var->red;
 533                var->blue = var->red;
 534                break;
 535
 536        case 16:
 537                if (isPReP) {
 538                        var->red.offset = 2;
 539                        var->green.offset = -3;
 540                        var->blue.offset = 8;
 541                } else {
 542                        var->red.offset = 11;
 543                        var->green.offset = 5;
 544                        var->blue.offset = 0;
 545                }
 546                var->red.length = 5;
 547                var->green.length = 6;
 548                var->blue.length = 5;
 549                break;
 550
 551        case 24:
 552                if (isPReP) {
 553                        var->red.offset = 0;
 554                        var->green.offset = 8;
 555                        var->blue.offset = 16;
 556                } else {
 557                        var->red.offset = 16;
 558                        var->green.offset = 8;
 559                        var->blue.offset = 0;
 560                }
 561                var->red.length = 8;
 562                var->green.length = 8;
 563                var->blue.length = 8;
 564                break;
 565
 566        default:
 567                dev_dbg(info->device,
 568                        "Unsupported bpp size: %d\n", var->bits_per_pixel);
 569                return -EINVAL;
 570        }
 571
 572        if (var->xres_virtual < var->xres)
 573                var->xres_virtual = var->xres;
 574        /* use highest possible virtual resolution */
 575        if (var->yres_virtual == -1) {
 576                var->yres_virtual = pixels / var->xres_virtual;
 577
 578                dev_info(info->device,
 579                         "virtual resolution set to maximum of %dx%d\n",
 580                         var->xres_virtual, var->yres_virtual);
 581        }
 582        if (var->yres_virtual < var->yres)
 583                var->yres_virtual = var->yres;
 584
 585        if (var->xres_virtual * var->yres_virtual > pixels) {
 586                dev_err(info->device, "mode %dx%dx%d rejected... "
 587                      "virtual resolution too high to fit into video memory!\n",
 588                        var->xres_virtual, var->yres_virtual,
 589                        var->bits_per_pixel);
 590                return -EINVAL;
 591        }
 592
 593        if (var->xoffset < 0)
 594                var->xoffset = 0;
 595        if (var->yoffset < 0)
 596                var->yoffset = 0;
 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        case BT_GD5480:  /* fall through */
1481                /* from Klaus' NetBSD driver: */
1482                vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1483        case BT_ALPINE:  /* fall through */
1484                /* put blitter into 542x compat */
1485                vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1486                break;
1487
1488        case BT_LAGUNA:
1489        case BT_LAGUNAB:
1490                /* Nothing to do to reset the board. */
1491                break;
1492
1493        default:
1494                dev_err(info->device, "Warning: Unknown board type\n");
1495                break;
1496        }
1497
1498        /* make sure RAM size set by this point */
1499        assert(info->screen_size > 0);
1500
1501        /* the P4 is not fully initialized here; I rely on it having been */
1502        /* inited under AmigaOS already, which seems to work just fine    */
1503        /* (Klaus advised to do it this way)                          */
1504
1505        if (cinfo->btype != BT_PICASSO4) {
1506                WGen(cinfo, CL_VSSM, 0x10);     /* EGS: 0x16 */
1507                WGen(cinfo, CL_POS102, 0x01);
1508                WGen(cinfo, CL_VSSM, 0x08);     /* EGS: 0x0e */
1509
1510                if (cinfo->btype != BT_SD64)
1511                        WGen(cinfo, CL_VSSM2, 0x01);
1512
1513                /* reset sequencer logic */
1514                vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1515
1516                /* FullBandwidth (video off) and 8/9 dot clock */
1517                vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1518
1519                /* "magic cookie" - doesn't make any sense to me.. */
1520/*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */
1521                /* unlock all extension registers */
1522                vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1523
1524                switch (cinfo->btype) {
1525                case BT_GD5480:
1526                        vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1527                        break;
1528                case BT_ALPINE:
1529                case BT_LAGUNA:
1530                case BT_LAGUNAB:
1531                        break;
1532                case BT_SD64:
1533#ifdef CONFIG_ZORRO
1534                        vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1535#endif
1536                        break;
1537                default:
1538                        vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1539                        vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1540                        break;
1541                }
1542        }
1543        /* plane mask: nothing */
1544        vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1545        /* character map select: doesn't even matter in gx mode */
1546        vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1547        /* memory mode: chain4, ext. memory */
1548        vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1549
1550        /* controller-internal base address of video memory */
1551        if (bi->init_sr07)
1552                vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1553
1554        /*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1555        /* EEPROM control: shouldn't be necessary to write to this at all.. */
1556
1557        /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1558        vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1559        /* graphics cursor Y position (..."... ) */
1560        vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1561        /* graphics cursor attributes */
1562        vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1563        /* graphics cursor pattern address */
1564        vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1565
1566        /* writing these on a P4 might give problems..  */
1567        if (cinfo->btype != BT_PICASSO4) {
1568                /* configuration readback and ext. color */
1569                vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1570                /* signature generator */
1571                vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1572        }
1573
1574        /* Screen A preset row scan: none */
1575        vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1576        /* Text cursor start: disable text cursor */
1577        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1578        /* Text cursor end: - */
1579        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1580        /* text cursor location high: 0 */
1581        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1582        /* text cursor location low: 0 */
1583        vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1584
1585        /* Underline Row scanline: - */
1586        vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1587        /* ### add 0x40 for text modes with > 30 MHz pixclock */
1588        /* ext. display controls: ext.adr. wrap */
1589        vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1590
1591        /* Set/Reset registes: - */
1592        vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1593        /* Set/Reset enable: - */
1594        vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1595        /* Color Compare: - */
1596        vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1597        /* Data Rotate: - */
1598        vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1599        /* Read Map Select: - */
1600        vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1601        /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1602        vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1603        /* Miscellaneous: memory map base address, graphics mode */
1604        vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1605        /* Color Don't care: involve all planes */
1606        vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1607        /* Bit Mask: no mask at all */
1608        vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1609
1610        if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1611            is_laguna(cinfo))
1612                /* (5434 can't have bit 3 set for bitblt) */
1613                vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1614        else
1615        /* Graphics controller mode extensions: finer granularity,
1616         * 8byte data latches
1617         */
1618                vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1619
1620        vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1621        vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1622        vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1623        /* Background color byte 1: - */
1624        /*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1625        /*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1626
1627        /* Attribute Controller palette registers: "identity mapping" */
1628        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1629        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1630        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1631        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1632        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1633        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1634        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1635        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1636        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1637        vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1638        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1639        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1640        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1641        vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1642        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1643        vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1644
1645        /* Attribute Controller mode: graphics mode */
1646        vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1647        /* Overscan color reg.: reg. 0 */
1648        vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1649        /* Color Plane enable: Enable all 4 planes */
1650        vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1651        /* Color Select: - */
1652        vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1653
1654        WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1655
1656        /* BLT Start/status: Blitter reset */
1657        vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1658        /* - " -           : "end-of-reset" */
1659        vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1660
1661        /* misc... */
1662        WHDR(cinfo, 0); /* Hidden DAC register: - */
1663        return;
1664}
1665
1666static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1667{
1668#ifdef CONFIG_ZORRO /* only works on Zorro boards */
1669        static int IsOn = 0;    /* XXX not ok for multiple boards */
1670
1671        if (cinfo->btype == BT_PICASSO4)
1672                return;         /* nothing to switch */
1673        if (cinfo->btype == BT_ALPINE)
1674                return;         /* nothing to switch */
1675        if (cinfo->btype == BT_GD5480)
1676                return;         /* nothing to switch */
1677        if (cinfo->btype == BT_PICASSO) {
1678                if ((on && !IsOn) || (!on && IsOn))
1679                        WSFR(cinfo, 0xff);
1680                return;
1681        }
1682        if (on) {
1683                switch (cinfo->btype) {
1684                case BT_SD64:
1685                        WSFR(cinfo, cinfo->SFR | 0x21);
1686                        break;
1687                case BT_PICCOLO:
1688                        WSFR(cinfo, cinfo->SFR | 0x28);
1689                        break;
1690                case BT_SPECTRUM:
1691                        WSFR(cinfo, 0x6f);
1692                        break;
1693                default: /* do nothing */ break;
1694                }
1695        } else {
1696                switch (cinfo->btype) {
1697                case BT_SD64:
1698                        WSFR(cinfo, cinfo->SFR & 0xde);
1699                        break;
1700                case BT_PICCOLO:
1701                        WSFR(cinfo, cinfo->SFR & 0xd7);
1702                        break;
1703                case BT_SPECTRUM:
1704                        WSFR(cinfo, 0x4f);
1705                        break;
1706                default: /* do nothing */
1707                        break;
1708                }
1709        }
1710#endif /* CONFIG_ZORRO */
1711}
1712
1713/******************************************/
1714/* Linux 2.6-style  accelerated functions */
1715/******************************************/
1716
1717static int cirrusfb_sync(struct fb_info *info)
1718{
1719        struct cirrusfb_info *cinfo = info->par;
1720
1721        if (!is_laguna(cinfo)) {
1722                while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1723                        cpu_relax();
1724        }
1725        return 0;
1726}
1727
1728static void cirrusfb_fillrect(struct fb_info *info,
1729                              const struct fb_fillrect *region)
1730{
1731        struct fb_fillrect modded;
1732        int vxres, vyres;
1733        struct cirrusfb_info *cinfo = info->par;
1734        int m = info->var.bits_per_pixel;
1735        u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1736                cinfo->pseudo_palette[region->color] : region->color;
1737
1738        if (info->state != FBINFO_STATE_RUNNING)
1739                return;
1740        if (info->flags & FBINFO_HWACCEL_DISABLED) {
1741                cfb_fillrect(info, region);
1742                return;
1743        }
1744
1745        vxres = info->var.xres_virtual;
1746        vyres = info->var.yres_virtual;
1747
1748        memcpy(&modded, region, sizeof(struct fb_fillrect));
1749
1750        if (!modded.width || !modded.height ||
1751           modded.dx >= vxres || modded.dy >= vyres)
1752                return;
1753
1754        if (modded.dx + modded.width  > vxres)
1755                modded.width  = vxres - modded.dx;
1756        if (modded.dy + modded.height > vyres)
1757                modded.height = vyres - modded.dy;
1758
1759        cirrusfb_RectFill(cinfo->regbase,
1760                          info->var.bits_per_pixel,
1761                          (region->dx * m) / 8, region->dy,
1762                          (region->width * m) / 8, region->height,
1763                          color, color,
1764                          info->fix.line_length, 0x40);
1765}
1766
1767static void cirrusfb_copyarea(struct fb_info *info,
1768                              const struct fb_copyarea *area)
1769{
1770        struct fb_copyarea modded;
1771        u32 vxres, vyres;
1772        struct cirrusfb_info *cinfo = info->par;
1773        int m = info->var.bits_per_pixel;
1774
1775        if (info->state != FBINFO_STATE_RUNNING)
1776                return;
1777        if (info->flags & FBINFO_HWACCEL_DISABLED) {
1778                cfb_copyarea(info, area);
1779                return;
1780        }
1781
1782        vxres = info->var.xres_virtual;
1783        vyres = info->var.yres_virtual;
1784        memcpy(&modded, area, sizeof(struct fb_copyarea));
1785
1786        if (!modded.width || !modded.height ||
1787           modded.sx >= vxres || modded.sy >= vyres ||
1788           modded.dx >= vxres || modded.dy >= vyres)
1789                return;
1790
1791        if (modded.sx + modded.width > vxres)
1792                modded.width = vxres - modded.sx;
1793        if (modded.dx + modded.width > vxres)
1794                modded.width = vxres - modded.dx;
1795        if (modded.sy + modded.height > vyres)
1796                modded.height = vyres - modded.sy;
1797        if (modded.dy + modded.height > vyres)
1798                modded.height = vyres - modded.dy;
1799
1800        cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1801                        (area->sx * m) / 8, area->sy,
1802                        (area->dx * m) / 8, area->dy,
1803                        (area->width * m) / 8, area->height,
1804                        info->fix.line_length);
1805
1806}
1807
1808static void cirrusfb_imageblit(struct fb_info *info,
1809                               const struct fb_image *image)
1810{
1811        struct cirrusfb_info *cinfo = info->par;
1812        unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1813
1814        if (info->state != FBINFO_STATE_RUNNING)
1815                return;
1816        /* Alpine/SD64 does not work at 24bpp ??? */
1817        if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1818                cfb_imageblit(info, image);
1819        else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1820                  op == 0xc)
1821                cfb_imageblit(info, image);
1822        else {
1823                unsigned size = ((image->width + 7) >> 3) * image->height;
1824                int m = info->var.bits_per_pixel;
1825                u32 fg, bg;
1826
1827                if (info->var.bits_per_pixel == 8) {
1828                        fg = image->fg_color;
1829                        bg = image->bg_color;
1830                } else {
1831                        fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1832                        bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1833                }
1834                if (info->var.bits_per_pixel == 24) {
1835                        /* clear background first */
1836                        cirrusfb_RectFill(cinfo->regbase,
1837                                          info->var.bits_per_pixel,
1838                                          (image->dx * m) / 8, image->dy,
1839                                          (image->width * m) / 8,
1840                                          image->height,
1841                                          bg, bg,
1842                                          info->fix.line_length, 0x40);
1843                }
1844                cirrusfb_RectFill(cinfo->regbase,
1845                                  info->var.bits_per_pixel,
1846                                  (image->dx * m) / 8, image->dy,
1847                                  (image->width * m) / 8, image->height,
1848                                  fg, bg,
1849                                  info->fix.line_length, op);
1850                memcpy(info->screen_base, image->data, size);
1851        }
1852}
1853
1854#ifdef CONFIG_PPC_PREP
1855#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1856#define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
1857static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1858{
1859        *display = PREP_VIDEO_BASE;
1860        *registers = (unsigned long) PREP_IO_BASE;
1861}
1862
1863#endif                          /* CONFIG_PPC_PREP */
1864
1865#ifdef CONFIG_PCI
1866static int release_io_ports;
1867
1868/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1869 * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
1870 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1871 * seem to have. */
1872static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1873                                                   u8 __iomem *regbase)
1874{
1875        unsigned long mem;
1876        struct cirrusfb_info *cinfo = info->par;
1877
1878        if (is_laguna(cinfo)) {
1879                unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1880
1881                mem = ((SR14 & 7) + 1) << 20;
1882        } else {
1883                unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1884                switch ((SRF & 0x18)) {
1885                case 0x08:
1886                        mem = 512 * 1024;
1887                        break;
1888                case 0x10:
1889                        mem = 1024 * 1024;
1890                        break;
1891                /* 64-bit DRAM data bus width; assume 2MB.
1892                 * Also indicates 2MB memory on the 5430.
1893                 */
1894                case 0x18:
1895                        mem = 2048 * 1024;
1896                        break;
1897                default:
1898                        dev_warn(info->device, "Unknown memory size!\n");
1899                        mem = 1024 * 1024;
1900                }
1901                /* If DRAM bank switching is enabled, there must be
1902                 * twice as much memory installed. (4MB on the 5434)
1903                 */
1904                if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1905                        mem *= 2;
1906        }
1907
1908        /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1909        return mem;
1910}
1911
1912static void get_pci_addrs(const struct pci_dev *pdev,
1913                          unsigned long *display, unsigned long *registers)
1914{
1915        assert(pdev != NULL);
1916        assert(display != NULL);
1917        assert(registers != NULL);
1918
1919        *display = 0;
1920        *registers = 0;
1921
1922        /* This is a best-guess for now */
1923
1924        if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1925                *display = pci_resource_start(pdev, 1);
1926                *registers = pci_resource_start(pdev, 0);
1927        } else {
1928                *display = pci_resource_start(pdev, 0);
1929                *registers = pci_resource_start(pdev, 1);
1930        }
1931
1932        assert(*display != 0);
1933}
1934
1935static void cirrusfb_pci_unmap(struct fb_info *info)
1936{
1937        struct pci_dev *pdev = to_pci_dev(info->device);
1938        struct cirrusfb_info *cinfo = info->par;
1939
1940        if (cinfo->laguna_mmio == NULL)
1941                iounmap(cinfo->laguna_mmio);
1942        iounmap(info->screen_base);
1943#if 0 /* if system didn't claim this region, we would... */
1944        release_mem_region(0xA0000, 65535);
1945#endif
1946        if (release_io_ports)
1947                release_region(0x3C0, 32);
1948        pci_release_regions(pdev);
1949}
1950#endif /* CONFIG_PCI */
1951
1952#ifdef CONFIG_ZORRO
1953static void cirrusfb_zorro_unmap(struct fb_info *info)
1954{
1955        struct cirrusfb_info *cinfo = info->par;
1956        struct zorro_dev *zdev = to_zorro_dev(info->device);
1957
1958        zorro_release_device(zdev);
1959
1960        if (cinfo->btype == BT_PICASSO4) {
1961                cinfo->regbase -= 0x600000;
1962                iounmap((void *)cinfo->regbase);
1963                iounmap(info->screen_base);
1964        } else {
1965                if (zorro_resource_start(zdev) > 0x01000000)
1966                        iounmap(info->screen_base);
1967        }
1968}
1969#endif /* CONFIG_ZORRO */
1970
1971/* function table of the above functions */
1972static struct fb_ops cirrusfb_ops = {
1973        .owner          = THIS_MODULE,
1974        .fb_open        = cirrusfb_open,
1975        .fb_release     = cirrusfb_release,
1976        .fb_setcolreg   = cirrusfb_setcolreg,
1977        .fb_check_var   = cirrusfb_check_var,
1978        .fb_set_par     = cirrusfb_set_par,
1979        .fb_pan_display = cirrusfb_pan_display,
1980        .fb_blank       = cirrusfb_blank,
1981        .fb_fillrect    = cirrusfb_fillrect,
1982        .fb_copyarea    = cirrusfb_copyarea,
1983        .fb_sync        = cirrusfb_sync,
1984        .fb_imageblit   = cirrusfb_imageblit,
1985};
1986
1987static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
1988{
1989        struct cirrusfb_info *cinfo = info->par;
1990        struct fb_var_screeninfo *var = &info->var;
1991
1992        info->pseudo_palette = cinfo->pseudo_palette;
1993        info->flags = FBINFO_DEFAULT
1994                    | FBINFO_HWACCEL_XPAN
1995                    | FBINFO_HWACCEL_YPAN
1996                    | FBINFO_HWACCEL_FILLRECT
1997                    | FBINFO_HWACCEL_IMAGEBLIT
1998                    | FBINFO_HWACCEL_COPYAREA;
1999        if (noaccel || is_laguna(cinfo)) {
2000                info->flags |= FBINFO_HWACCEL_DISABLED;
2001                info->fix.accel = FB_ACCEL_NONE;
2002        } else
2003                info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
2004
2005        info->fbops = &cirrusfb_ops;
2006
2007        if (cinfo->btype == BT_GD5480) {
2008                if (var->bits_per_pixel == 16)
2009                        info->screen_base += 1 * MB_;
2010                if (var->bits_per_pixel == 32)
2011                        info->screen_base += 2 * MB_;
2012        }
2013
2014        /* Fill fix common fields */
2015        strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2016                sizeof(info->fix.id));
2017
2018        /* monochrome: only 1 memory plane */
2019        /* 8 bit and above: Use whole memory area */
2020        info->fix.smem_len   = info->screen_size;
2021        if (var->bits_per_pixel == 1)
2022                info->fix.smem_len /= 4;
2023        info->fix.type_aux   = 0;
2024        info->fix.xpanstep   = 1;
2025        info->fix.ypanstep   = 1;
2026        info->fix.ywrapstep  = 0;
2027
2028        /* FIXME: map region at 0xB8000 if available, fill in here */
2029        info->fix.mmio_len   = 0;
2030
2031        fb_alloc_cmap(&info->cmap, 256, 0);
2032
2033        return 0;
2034}
2035
2036static int __devinit cirrusfb_register(struct fb_info *info)
2037{
2038        struct cirrusfb_info *cinfo = info->par;
2039        int err;
2040
2041        /* sanity checks */
2042        assert(cinfo->btype != BT_NONE);
2043
2044        /* set all the vital stuff */
2045        cirrusfb_set_fbinfo(info);
2046
2047        dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2048
2049        err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2050        if (!err) {
2051                dev_dbg(info->device, "wrong initial video mode\n");
2052                err = -EINVAL;
2053                goto err_dealloc_cmap;
2054        }
2055
2056        info->var.activate = FB_ACTIVATE_NOW;
2057
2058        err = cirrusfb_check_var(&info->var, info);
2059        if (err < 0) {
2060                /* should never happen */
2061                dev_dbg(info->device,
2062                        "choking on default var... umm, no good.\n");
2063                goto err_dealloc_cmap;
2064        }
2065
2066        err = register_framebuffer(info);
2067        if (err < 0) {
2068                dev_err(info->device,
2069                        "could not register fb device; err = %d!\n", err);
2070                goto err_dealloc_cmap;
2071        }
2072
2073        return 0;
2074
2075err_dealloc_cmap:
2076        fb_dealloc_cmap(&info->cmap);
2077        return err;
2078}
2079
2080static void __devexit cirrusfb_cleanup(struct fb_info *info)
2081{
2082        struct cirrusfb_info *cinfo = info->par;
2083
2084        switch_monitor(cinfo, 0);
2085        unregister_framebuffer(info);
2086        fb_dealloc_cmap(&info->cmap);
2087        dev_dbg(info->device, "Framebuffer unregistered\n");
2088        cinfo->unmap(info);
2089        framebuffer_release(info);
2090}
2091
2092#ifdef CONFIG_PCI
2093static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2094                                           const struct pci_device_id *ent)
2095{
2096        struct cirrusfb_info *cinfo;
2097        struct fb_info *info;
2098        unsigned long board_addr, board_size;
2099        int ret;
2100
2101        ret = pci_enable_device(pdev);
2102        if (ret < 0) {
2103                printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2104                goto err_out;
2105        }
2106
2107        info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2108        if (!info) {
2109                printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2110                ret = -ENOMEM;
2111                goto err_out;
2112        }
2113
2114        cinfo = info->par;
2115        cinfo->btype = (enum cirrus_board) ent->driver_data;
2116
2117        dev_dbg(info->device,
2118                " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2119                (unsigned long long)pdev->resource[0].start,  cinfo->btype);
2120        dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2121                (unsigned long long)pdev->resource[1].start);
2122
2123        if (isPReP) {
2124                pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2125#ifdef CONFIG_PPC_PREP
2126                get_prep_addrs(&board_addr, &info->fix.mmio_start);
2127#endif
2128        /* PReP dies if we ioremap the IO registers, but it works w/out... */
2129                cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2130        } else {
2131                dev_dbg(info->device,
2132                        "Attempt to get PCI info for Cirrus Graphics Card\n");
2133                get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2134                /* FIXME: this forces VGA.  alternatives? */
2135                cinfo->regbase = NULL;
2136                cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2137        }
2138
2139        dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2140                board_addr, info->fix.mmio_start);
2141
2142        board_size = (cinfo->btype == BT_GD5480) ?
2143                32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2144
2145        ret = pci_request_regions(pdev, "cirrusfb");
2146        if (ret < 0) {
2147                dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2148                        board_addr);
2149                goto err_release_fb;
2150        }
2151#if 0 /* if the system didn't claim this region, we would... */
2152        if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2153                dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2154                        0xA0000L);
2155                ret = -EBUSY;
2156                goto err_release_regions;
2157        }
2158#endif
2159        if (request_region(0x3C0, 32, "cirrusfb"))
2160                release_io_ports = 1;
2161
2162        info->screen_base = ioremap(board_addr, board_size);
2163        if (!info->screen_base) {
2164                ret = -EIO;
2165                goto err_release_legacy;
2166        }
2167
2168        info->fix.smem_start = board_addr;
2169        info->screen_size = board_size;
2170        cinfo->unmap = cirrusfb_pci_unmap;
2171
2172        dev_info(info->device,
2173                 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2174                 info->screen_size >> 10, board_addr);
2175        pci_set_drvdata(pdev, info);
2176
2177        ret = cirrusfb_register(info);
2178        if (!ret)
2179                return 0;
2180
2181        pci_set_drvdata(pdev, NULL);
2182        iounmap(info->screen_base);
2183err_release_legacy:
2184        if (release_io_ports)
2185                release_region(0x3C0, 32);
2186#if 0
2187        release_mem_region(0xA0000, 65535);
2188err_release_regions:
2189#endif
2190        pci_release_regions(pdev);
2191err_release_fb:
2192        if (cinfo->laguna_mmio != NULL)
2193                iounmap(cinfo->laguna_mmio);
2194        framebuffer_release(info);
2195err_out:
2196        return ret;
2197}
2198
2199static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2200{
2201        struct fb_info *info = pci_get_drvdata(pdev);
2202
2203        cirrusfb_cleanup(info);
2204}
2205
2206static struct pci_driver cirrusfb_pci_driver = {
2207        .name           = "cirrusfb",
2208        .id_table       = cirrusfb_pci_table,
2209        .probe          = cirrusfb_pci_register,
2210        .remove         = __devexit_p(cirrusfb_pci_unregister),
2211#ifdef CONFIG_PM
2212#if 0
2213        .suspend        = cirrusfb_pci_suspend,
2214        .resume         = cirrusfb_pci_resume,
2215#endif
2216#endif
2217};
2218#endif /* CONFIG_PCI */
2219
2220#ifdef CONFIG_ZORRO
2221static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2222                                             const struct zorro_device_id *ent)
2223{
2224        struct cirrusfb_info *cinfo;
2225        struct fb_info *info;
2226        enum cirrus_board btype;
2227        struct zorro_dev *z2 = NULL;
2228        unsigned long board_addr, board_size, size;
2229        int ret;
2230
2231        btype = ent->driver_data;
2232        if (cirrusfb_zorro_table2[btype].id2)
2233                z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2234        size = cirrusfb_zorro_table2[btype].size;
2235
2236        info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2237        if (!info) {
2238                printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2239                ret = -ENOMEM;
2240                goto err_out;
2241        }
2242
2243        dev_info(info->device, "%s board detected\n",
2244                 cirrusfb_board_info[btype].name);
2245
2246        cinfo = info->par;
2247        cinfo->btype = btype;
2248
2249        assert(z);
2250        assert(btype != BT_NONE);
2251
2252        board_addr = zorro_resource_start(z);
2253        board_size = zorro_resource_len(z);
2254        info->screen_size = size;
2255
2256        if (!zorro_request_device(z, "cirrusfb")) {
2257                dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2258                        board_addr);
2259                ret = -EBUSY;
2260                goto err_release_fb;
2261        }
2262
2263        ret = -EIO;
2264
2265        if (btype == BT_PICASSO4) {
2266                dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
2267
2268                /* To be precise, for the P4 this is not the */
2269                /* begin of the board, but the begin of RAM. */
2270                /* for P4, map in its address space in 2 chunks (### TEST! ) */
2271                /* (note the ugly hardcoded 16M number) */
2272                cinfo->regbase = ioremap(board_addr, 16777216);
2273                if (!cinfo->regbase)
2274                        goto err_release_region;
2275
2276                dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2277                        cinfo->regbase);
2278                cinfo->regbase += 0x600000;
2279                info->fix.mmio_start = board_addr + 0x600000;
2280
2281                info->fix.smem_start = board_addr + 16777216;
2282                info->screen_base = ioremap(info->fix.smem_start, 16777216);
2283                if (!info->screen_base)
2284                        goto err_unmap_regbase;
2285        } else {
2286                dev_info(info->device, " REG at $%lx\n",
2287                         (unsigned long) z2->resource.start);
2288
2289                info->fix.smem_start = board_addr;
2290                if (board_addr > 0x01000000)
2291                        info->screen_base = ioremap(board_addr, board_size);
2292                else
2293                        info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2294                if (!info->screen_base)
2295                        goto err_release_region;
2296
2297                /* set address for REG area of board */
2298                cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2299                info->fix.mmio_start = z2->resource.start;
2300
2301                dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2302                        cinfo->regbase);
2303        }
2304        cinfo->unmap = cirrusfb_zorro_unmap;
2305
2306        dev_info(info->device,
2307                 "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
2308                 board_size / MB_, board_addr);
2309
2310        zorro_set_drvdata(z, info);
2311
2312        /* MCLK select etc. */
2313        if (cirrusfb_board_info[btype].init_sr1f)
2314                vga_wseq(cinfo->regbase, CL_SEQR1F,
2315                         cirrusfb_board_info[btype].sr1f);
2316
2317        ret = cirrusfb_register(info);
2318        if (!ret)
2319                return 0;
2320
2321        if (btype == BT_PICASSO4 || board_addr > 0x01000000)
2322                iounmap(info->screen_base);
2323
2324err_unmap_regbase:
2325        if (btype == BT_PICASSO4)
2326                iounmap(cinfo->regbase - 0x600000);
2327err_release_region:
2328        release_region(board_addr, board_size);
2329err_release_fb:
2330        framebuffer_release(info);
2331err_out:
2332        return ret;
2333}
2334
2335void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2336{
2337        struct fb_info *info = zorro_get_drvdata(z);
2338
2339        cirrusfb_cleanup(info);
2340}
2341
2342static struct zorro_driver cirrusfb_zorro_driver = {
2343        .name           = "cirrusfb",
2344        .id_table       = cirrusfb_zorro_table,
2345        .probe          = cirrusfb_zorro_register,
2346        .remove         = __devexit_p(cirrusfb_zorro_unregister),
2347};
2348#endif /* CONFIG_ZORRO */
2349
2350#ifndef MODULE
2351static int __init cirrusfb_setup(char *options)
2352{
2353        char *this_opt;
2354
2355        if (!options || !*options)
2356                return 0;
2357
2358        while ((this_opt = strsep(&options, ",")) != NULL) {
2359                if (!*this_opt)
2360                        continue;
2361
2362                if (!strcmp(this_opt, "noaccel"))
2363                        noaccel = 1;
2364                else if (!strncmp(this_opt, "mode:", 5))
2365                        mode_option = this_opt + 5;
2366                else
2367                        mode_option = this_opt;
2368        }
2369        return 0;
2370}
2371#endif
2372
2373    /*
2374     *  Modularization
2375     */
2376
2377MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2378MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2379MODULE_LICENSE("GPL");
2380
2381static int __init cirrusfb_init(void)
2382{
2383        int error = 0;
2384
2385#ifndef MODULE
2386        char *option = NULL;
2387
2388        if (fb_get_options("cirrusfb", &option))
2389                return -ENODEV;
2390        cirrusfb_setup(option);
2391#endif
2392
2393#ifdef CONFIG_ZORRO
2394        error |= zorro_register_driver(&cirrusfb_zorro_driver);
2395#endif
2396#ifdef CONFIG_PCI
2397        error |= pci_register_driver(&cirrusfb_pci_driver);
2398#endif
2399        return error;
2400}
2401
2402static void __exit cirrusfb_exit(void)
2403{
2404#ifdef CONFIG_PCI
2405        pci_unregister_driver(&cirrusfb_pci_driver);
2406#endif
2407#ifdef CONFIG_ZORRO
2408        zorro_unregister_driver(&cirrusfb_zorro_driver);
2409#endif
2410}
2411
2412module_init(cirrusfb_init);
2413
2414module_param(mode_option, charp, 0);
2415MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2416module_param(noaccel, bool, 0);
2417MODULE_PARM_DESC(noaccel, "Disable acceleration");
2418
2419#ifdef MODULE
2420module_exit(cirrusfb_exit);
2421#endif
2422
2423/**********************************************************************/
2424/* about the following functions - I have used the same names for the */
2425/* functions as Markus Wild did in his Retina driver for NetBSD as    */
2426/* they just made sense for this purpose. Apart from that, I wrote    */
2427/* these functions myself.                                          */
2428/**********************************************************************/
2429
2430/*** WGen() - write into one of the external/general registers ***/
2431static void WGen(const struct cirrusfb_info *cinfo,
2432                  int regnum, unsigned char val)
2433{
2434        unsigned long regofs = 0;
2435
2436        if (cinfo->btype == BT_PICASSO) {
2437                /* Picasso II specific hack */
2438/*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2439                  regnum == CL_VSSM2) */
2440                if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2441                        regofs = 0xfff;
2442        }
2443
2444        vga_w(cinfo->regbase, regofs + regnum, val);
2445}
2446
2447/*** RGen() - read out one of the external/general registers ***/
2448static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2449{
2450        unsigned long regofs = 0;
2451
2452        if (cinfo->btype == BT_PICASSO) {
2453                /* Picasso II specific hack */
2454/*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2455                  regnum == CL_VSSM2) */
2456                if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2457                        regofs = 0xfff;
2458        }
2459
2460        return vga_r(cinfo->regbase, regofs + regnum);
2461}
2462
2463/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2464static void AttrOn(const struct cirrusfb_info *cinfo)
2465{
2466        assert(cinfo != NULL);
2467
2468        if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2469                /* if we're just in "write value" mode, write back the */
2470                /* same value as before to not modify anything */
2471                vga_w(cinfo->regbase, VGA_ATT_IW,
2472                      vga_r(cinfo->regbase, VGA_ATT_R));
2473        }
2474        /* turn on video bit */
2475/*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2476        vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2477
2478        /* dummy write on Reg0 to be on "write index" mode next time */
2479        vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2480}
2481
2482/*** WHDR() - write into the Hidden DAC register ***/
2483/* as the HDR is the only extension register that requires special treatment
2484 * (the other extension registers are accessible just like the "ordinary"
2485 * registers of their functional group) here is a specialized routine for
2486 * accessing the HDR
2487 */
2488static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2489{
2490        unsigned char dummy;
2491
2492        if (is_laguna(cinfo))
2493                return;
2494        if (cinfo->btype == BT_PICASSO) {
2495                /* Klaus' hint for correct access to HDR on some boards */
2496                /* first write 0 to pixel mask (3c6) */
2497                WGen(cinfo, VGA_PEL_MSK, 0x00);
2498                udelay(200);
2499                /* next read dummy from pixel address (3c8) */
2500                dummy = RGen(cinfo, VGA_PEL_IW);
2501                udelay(200);
2502        }
2503        /* now do the usual stuff to access the HDR */
2504
2505        dummy = RGen(cinfo, VGA_PEL_MSK);
2506        udelay(200);
2507        dummy = RGen(cinfo, VGA_PEL_MSK);
2508        udelay(200);
2509        dummy = RGen(cinfo, VGA_PEL_MSK);
2510        udelay(200);
2511        dummy = RGen(cinfo, VGA_PEL_MSK);
2512        udelay(200);
2513
2514        WGen(cinfo, VGA_PEL_MSK, val);
2515        udelay(200);
2516
2517        if (cinfo->btype == BT_PICASSO) {
2518                /* now first reset HDR access counter */
2519                dummy = RGen(cinfo, VGA_PEL_IW);
2520                udelay(200);
2521
2522                /* and at the end, restore the mask value */
2523                /* ## is this mask always 0xff? */
2524                WGen(cinfo, VGA_PEL_MSK, 0xff);
2525                udelay(200);
2526        }
2527}
2528
2529/*** WSFR() - write to the "special function register" (SFR) ***/
2530static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2531{
2532#ifdef CONFIG_ZORRO
2533        assert(cinfo->regbase != NULL);
2534        cinfo->SFR = val;
2535        z_writeb(val, cinfo->regbase + 0x8000);
2536#endif
2537}
2538
2539/* The Picasso has a second register for switching the monitor bit */
2540static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2541{
2542#ifdef CONFIG_ZORRO
2543        /* writing an arbitrary value to this one causes the monitor switcher */
2544        /* to flip to Amiga display */
2545        assert(cinfo->regbase != NULL);
2546        cinfo->SFR = val;
2547        z_writeb(val, cinfo->regbase + 0x9000);
2548#endif
2549}
2550
2551/*** WClut - set CLUT entry (range: 0..63) ***/
2552static void WClut(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        /* address write mode register is not translated.. */
2558        vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2559
2560        if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2561            cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2562            cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2563                /* but DAC data register IS, at least for Picasso II */
2564                if (cinfo->btype == BT_PICASSO)
2565                        data += 0xfff;
2566                vga_w(cinfo->regbase, data, red);
2567                vga_w(cinfo->regbase, data, green);
2568                vga_w(cinfo->regbase, data, blue);
2569        } else {
2570                vga_w(cinfo->regbase, data, blue);
2571                vga_w(cinfo->regbase, data, green);
2572                vga_w(cinfo->regbase, data, red);
2573        }
2574}
2575
2576#if 0
2577/*** RClut - read CLUT entry (range 0..63) ***/
2578static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2579            unsigned char *green, unsigned char *blue)
2580{
2581        unsigned int data = VGA_PEL_D;
2582
2583        vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2584
2585        if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2586            cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2587                if (cinfo->btype == BT_PICASSO)
2588                        data += 0xfff;
2589                *red = vga_r(cinfo->regbase, data);
2590                *green = vga_r(cinfo->regbase, data);
2591                *blue = vga_r(cinfo->regbase, data);
2592        } else {
2593                *blue = vga_r(cinfo->regbase, data);
2594                *green = vga_r(cinfo->regbase, data);
2595                *red = vga_r(cinfo->regbase, data);
2596        }
2597}
2598#endif
2599
2600/*******************************************************************
2601        cirrusfb_WaitBLT()
2602
2603        Wait for the BitBLT engine to complete a possible earlier job
2604*********************************************************************/
2605
2606/* FIXME: use interrupts instead */
2607static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2608{
2609        while (vga_rgfx(regbase, CL_GR31) & 0x08)
2610                cpu_relax();
2611}
2612
2613/*******************************************************************
2614        cirrusfb_BitBLT()
2615
2616        perform accelerated "scrolling"
2617********************************************************************/
2618
2619static void cirrusfb_set_blitter(u8 __iomem *regbase,
2620                            u_short nwidth, u_short nheight,
2621                            u_long nsrc, u_long ndest,
2622                            u_short bltmode, u_short line_length)
2623
2624{
2625        /* pitch: set to line_length */
2626        /* dest pitch low */
2627        vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2628        /* dest pitch hi */
2629        vga_wgfx(regbase, CL_GR25, line_length >> 8);
2630        /* source pitch low */
2631        vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2632        /* source pitch hi */
2633        vga_wgfx(regbase, CL_GR27, line_length >> 8);
2634
2635        /* BLT width: actual number of pixels - 1 */
2636        /* BLT width low */
2637        vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2638        /* BLT width hi */
2639        vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2640
2641        /* BLT height: actual number of lines -1 */
2642        /* BLT height low */
2643        vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2644        /* BLT width hi */
2645        vga_wgfx(regbase, CL_GR23, nheight >> 8);
2646
2647        /* BLT destination */
2648        /* BLT dest low */
2649        vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2650        /* BLT dest mid */
2651        vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2652        /* BLT dest hi */
2653        vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2654
2655        /* BLT source */
2656        /* BLT src low */
2657        vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2658        /* BLT src mid */
2659        vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2660        /* BLT src hi */
2661        vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2662
2663        /* BLT mode */
2664        vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2665
2666        /* BLT ROP: SrcCopy */
2667        vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2668
2669        /* and finally: GO! */
2670        vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2671}
2672
2673/*******************************************************************
2674        cirrusfb_BitBLT()
2675
2676        perform accelerated "scrolling"
2677********************************************************************/
2678
2679static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2680                            u_short curx, u_short cury,
2681                            u_short destx, u_short desty,
2682                            u_short width, u_short height,
2683                            u_short line_length)
2684{
2685        u_short nwidth = width - 1;
2686        u_short nheight = height - 1;
2687        u_long nsrc, ndest;
2688        u_char bltmode;
2689
2690        bltmode = 0x00;
2691        /* if source adr < dest addr, do the Blt backwards */
2692        if (cury <= desty) {
2693                if (cury == desty) {
2694                        /* if src and dest are on the same line, check x */
2695                        if (curx < destx)
2696                                bltmode |= 0x01;
2697                } else
2698                        bltmode |= 0x01;
2699        }
2700        /* standard case: forward blitting */
2701        nsrc = (cury * line_length) + curx;
2702        ndest = (desty * line_length) + destx;
2703        if (bltmode) {
2704                /* this means start addresses are at the end,
2705                 * counting backwards
2706                 */
2707                nsrc += nheight * line_length + nwidth;
2708                ndest += nheight * line_length + nwidth;
2709        }
2710
2711        cirrusfb_WaitBLT(regbase);
2712
2713        cirrusfb_set_blitter(regbase, nwidth, nheight,
2714                            nsrc, ndest, bltmode, line_length);
2715}
2716
2717/*******************************************************************
2718        cirrusfb_RectFill()
2719
2720        perform accelerated rectangle fill
2721********************************************************************/
2722
2723static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2724                     u_short x, u_short y, u_short width, u_short height,
2725                     u32 fg_color, u32 bg_color, u_short line_length,
2726                     u_char blitmode)
2727{
2728        u_long ndest = (y * line_length) + x;
2729        u_char op;
2730
2731        cirrusfb_WaitBLT(regbase);
2732
2733        /* This is a ColorExpand Blt, using the */
2734        /* same color for foreground and background */
2735        vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2736        vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2737
2738        op = 0x80;
2739        if (bits_per_pixel >= 16) {
2740                vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2741                vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2742                op = 0x90;
2743        }
2744        if (bits_per_pixel >= 24) {
2745                vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2746                vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2747                op = 0xa0;
2748        }
2749        if (bits_per_pixel == 32) {
2750                vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2751                vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2752                op = 0xb0;
2753        }
2754        cirrusfb_set_blitter(regbase, width - 1, height - 1,
2755                            0, ndest, op | blitmode, line_length);
2756}
2757
2758/**************************************************************************
2759 * bestclock() - determine closest possible clock lower(?) than the
2760 * desired pixel clock
2761 **************************************************************************/
2762static void bestclock(long freq, int *nom, int *den, int *div)
2763{
2764        int n, d;
2765        long h, diff;
2766
2767        assert(nom != NULL);
2768        assert(den != NULL);
2769        assert(div != NULL);
2770
2771        *nom = 0;
2772        *den = 0;
2773        *div = 0;
2774
2775        if (freq < 8000)
2776                freq = 8000;
2777
2778        diff = freq;
2779
2780        for (n = 32; n < 128; n++) {
2781                int s = 0;
2782
2783                d = (14318 * n) / freq;
2784                if ((d >= 7) && (d <= 63)) {
2785                        int temp = d;
2786
2787                        if (temp > 31) {
2788                                s = 1;
2789                                temp >>= 1;
2790                        }
2791                        h = ((14318 * n) / temp) >> s;
2792                        h = h > freq ? h - freq : freq - h;
2793                        if (h < diff) {
2794                                diff = h;
2795                                *nom = n;
2796                                *den = temp;
2797                                *div = s;
2798                        }
2799                }
2800                d++;
2801                if ((d >= 7) && (d <= 63)) {
2802                        if (d > 31) {
2803                                s = 1;
2804                                d >>= 1;
2805                        }
2806                        h = ((14318 * n) / d) >> s;
2807                        h = h > freq ? h - freq : freq - h;
2808                        if (h < diff) {
2809                                diff = h;
2810                                *nom = n;
2811                                *den = d;
2812                                *div = s;
2813                        }
2814                }
2815        }
2816}
2817
2818/* -------------------------------------------------------------------------
2819 *
2820 * debugging functions
2821 *
2822 * -------------------------------------------------------------------------
2823 */
2824
2825#ifdef CIRRUSFB_DEBUG
2826
2827/**
2828 * cirrusfb_dbg_print_regs
2829 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2830 * @reg_class: type of registers to read: %CRT, or %SEQ
2831 *
2832 * DESCRIPTION:
2833 * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2834 * old-style I/O ports are queried for information, otherwise MMIO is
2835 * used at the given @base address to query the information.
2836 */
2837
2838static void cirrusfb_dbg_print_regs(struct fb_info *info,
2839                                    caddr_t regbase,
2840                                    enum cirrusfb_dbg_reg_class reg_class, ...)
2841{
2842        va_list list;
2843        unsigned char val = 0;
2844        unsigned reg;
2845        char *name;
2846
2847        va_start(list, reg_class);
2848
2849        name = va_arg(list, char *);
2850        while (name != NULL) {
2851                reg = va_arg(list, int);
2852
2853                switch (reg_class) {
2854                case CRT:
2855                        val = vga_rcrt(regbase, (unsigned char) reg);
2856                        break;
2857                case SEQ:
2858                        val = vga_rseq(regbase, (unsigned char) reg);
2859                        break;
2860                default:
2861                        /* should never occur */
2862                        assert(false);
2863                        break;
2864                }
2865
2866                dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2867
2868                name = va_arg(list, char *);
2869        }
2870
2871        va_end(list);
2872}
2873
2874/**
2875 * cirrusfb_dbg_reg_dump
2876 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2877 *
2878 * DESCRIPTION:
2879 * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2880 * old-style I/O ports are queried for information, otherwise MMIO is
2881 * used at the given @base address to query the information.
2882 */
2883
2884static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2885{
2886        dev_dbg(info->device, "VGA CRTC register dump:\n");
2887
2888        cirrusfb_dbg_print_regs(info, regbase, CRT,
2889                           "CR00", 0x00,
2890                           "CR01", 0x01,
2891                           "CR02", 0x02,
2892                           "CR03", 0x03,
2893                           "CR04", 0x04,
2894                           "CR05", 0x05,
2895                           "CR06", 0x06,
2896                           "CR07", 0x07,
2897                           "CR08", 0x08,
2898                           "CR09", 0x09,
2899                           "CR0A", 0x0A,
2900                           "CR0B", 0x0B,
2901                           "CR0C", 0x0C,
2902                           "CR0D", 0x0D,
2903                           "CR0E", 0x0E,
2904                           "CR0F", 0x0F,
2905                           "CR10", 0x10,
2906                           "CR11", 0x11,
2907                           "CR12", 0x12,
2908                           "CR13", 0x13,
2909                           "CR14", 0x14,
2910                           "CR15", 0x15,
2911                           "CR16", 0x16,
2912                           "CR17", 0x17,
2913                           "CR18", 0x18,
2914                           "CR22", 0x22,
2915                           "CR24", 0x24,
2916                           "CR26", 0x26,
2917                           "CR2D", 0x2D,
2918                           "CR2E", 0x2E,
2919                           "CR2F", 0x2F,
2920                           "CR30", 0x30,
2921                           "CR31", 0x31,
2922                           "CR32", 0x32,
2923                           "CR33", 0x33,
2924                           "CR34", 0x34,
2925                           "CR35", 0x35,
2926                           "CR36", 0x36,
2927                           "CR37", 0x37,
2928                           "CR38", 0x38,
2929                           "CR39", 0x39,
2930                           "CR3A", 0x3A,
2931                           "CR3B", 0x3B,
2932                           "CR3C", 0x3C,
2933                           "CR3D", 0x3D,
2934                           "CR3E", 0x3E,
2935                           "CR3F", 0x3F,
2936                           NULL);
2937
2938        dev_dbg(info->device, "\n");
2939
2940        dev_dbg(info->device, "VGA SEQ register dump:\n");
2941
2942        cirrusfb_dbg_print_regs(info, regbase, SEQ,
2943                           "SR00", 0x00,
2944                           "SR01", 0x01,
2945                           "SR02", 0x02,
2946                           "SR03", 0x03,
2947                           "SR04", 0x04,
2948                           "SR08", 0x08,
2949                           "SR09", 0x09,
2950                           "SR0A", 0x0A,
2951                           "SR0B", 0x0B,
2952                           "SR0D", 0x0D,
2953                           "SR10", 0x10,
2954                           "SR11", 0x11,
2955                           "SR12", 0x12,
2956                           "SR13", 0x13,
2957                           "SR14", 0x14,
2958                           "SR15", 0x15,
2959                           "SR16", 0x16,
2960                           "SR17", 0x17,
2961                           "SR18", 0x18,
2962                           "SR19", 0x19,
2963                           "SR1A", 0x1A,
2964                           "SR1B", 0x1B,
2965                           "SR1C", 0x1C,
2966                           "SR1D", 0x1D,
2967                           "SR1E", 0x1E,
2968                           "SR1F", 0x1F,
2969                           NULL);
2970
2971        dev_dbg(info->device, "\n");
2972}
2973
2974#endif                          /* CIRRUSFB_DEBUG */
2975
2976
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.