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