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