linux/drivers/video/cyber2000fb.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/video/cyber2000fb.c
   3 *
   4 *  Copyright (C) 1998-2002 Russell King
   5 *
   6 *  MIPS and 50xx clock support
   7 *  Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com>
   8 *
   9 *  32 bit support, text color and panning fixes for modes != 8 bit
  10 *  Copyright (C) 2002 Denis Oliver Kropp <dok@directfb.org>
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License version 2 as
  14 * published by the Free Software Foundation.
  15 *
  16 * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
  17 *
  18 * Based on cyberfb.c.
  19 *
  20 * Note that we now use the new fbcon fix, var and cmap scheme.  We do
  21 * still have to check which console is the currently displayed one
  22 * however, especially for the colourmap stuff.
  23 *
  24 * We also use the new hotplug PCI subsystem.  I'm not sure if there
  25 * are any such cards, but I'm erring on the side of caution.  We don't
  26 * want to go pop just because someone does have one.
  27 *
  28 * Note that this doesn't work fully in the case of multiple CyberPro
  29 * cards with grabbers.  We currently can only attach to the first
  30 * CyberPro card found.
  31 *
  32 * When we're in truecolour mode, we power down the LUT RAM as a power
  33 * saving feature.  Also, when we enter any of the powersaving modes
  34 * (except soft blanking) we power down the RAMDACs.  This saves about
  35 * 1W, which is roughly 8% of the power consumption of a NetWinder
  36 * (which, incidentally, is about the same saving as a 2.5in hard disk
  37 * entering standby mode.)
  38 */
  39#include <linux/module.h>
  40#include <linux/kernel.h>
  41#include <linux/errno.h>
  42#include <linux/string.h>
  43#include <linux/mm.h>
  44#include <linux/slab.h>
  45#include <linux/delay.h>
  46#include <linux/fb.h>
  47#include <linux/pci.h>
  48#include <linux/init.h>
  49#include <linux/io.h>
  50#include <linux/i2c.h>
  51#include <linux/i2c-algo-bit.h>
  52
  53#include <asm/pgtable.h>
  54
  55#ifdef __arm__
  56#include <asm/mach-types.h>
  57#endif
  58
  59#include "cyber2000fb.h"
  60
  61struct cfb_info {
  62        struct fb_info          fb;
  63        struct display_switch   *dispsw;
  64        struct display          *display;
  65        unsigned char           __iomem *region;
  66        unsigned char           __iomem *regs;
  67        u_int                   id;
  68        u_int                   irq;
  69        int                     func_use_count;
  70        u_long                  ref_ps;
  71
  72        /*
  73         * Clock divisors
  74         */
  75        u_int                   divisors[4];
  76
  77        struct {
  78                u8 red, green, blue;
  79        } palette[NR_PALETTE];
  80
  81        u_char                  mem_ctl1;
  82        u_char                  mem_ctl2;
  83        u_char                  mclk_mult;
  84        u_char                  mclk_div;
  85        /*
  86         * RAMDAC control register is both of these or'ed together
  87         */
  88        u_char                  ramdac_ctrl;
  89        u_char                  ramdac_powerdown;
  90
  91        u32                     pseudo_palette[16];
  92
  93        spinlock_t              reg_b0_lock;
  94
  95#ifdef CONFIG_FB_CYBER2000_DDC
  96        bool                    ddc_registered;
  97        struct i2c_adapter      ddc_adapter;
  98        struct i2c_algo_bit_data        ddc_algo;
  99#endif
 100
 101#ifdef CONFIG_FB_CYBER2000_I2C
 102        struct i2c_adapter      i2c_adapter;
 103        struct i2c_algo_bit_data i2c_algo;
 104#endif
 105};
 106
 107static char *default_font = "Acorn8x8";
 108module_param(default_font, charp, 0);
 109MODULE_PARM_DESC(default_font, "Default font name");
 110
 111/*
 112 * Our access methods.
 113 */
 114#define cyber2000fb_writel(val, reg, cfb)       writel(val, (cfb)->regs + (reg))
 115#define cyber2000fb_writew(val, reg, cfb)       writew(val, (cfb)->regs + (reg))
 116#define cyber2000fb_writeb(val, reg, cfb)       writeb(val, (cfb)->regs + (reg))
 117
 118#define cyber2000fb_readb(reg, cfb)             readb((cfb)->regs + (reg))
 119
 120static inline void
 121cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 122{
 123        cyber2000fb_writew((reg & 255) | val << 8, 0x3d4, cfb);
 124}
 125
 126static inline void
 127cyber2000_grphw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 128{
 129        cyber2000fb_writew((reg & 255) | val << 8, 0x3ce, cfb);
 130}
 131
 132static inline unsigned int
 133cyber2000_grphr(unsigned int reg, struct cfb_info *cfb)
 134{
 135        cyber2000fb_writeb(reg, 0x3ce, cfb);
 136        return cyber2000fb_readb(0x3cf, cfb);
 137}
 138
 139static inline void
 140cyber2000_attrw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 141{
 142        cyber2000fb_readb(0x3da, cfb);
 143        cyber2000fb_writeb(reg, 0x3c0, cfb);
 144        cyber2000fb_readb(0x3c1, cfb);
 145        cyber2000fb_writeb(val, 0x3c0, cfb);
 146}
 147
 148static inline void
 149cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
 150{
 151        cyber2000fb_writew((reg & 255) | val << 8, 0x3c4, cfb);
 152}
 153
 154/* -------------------- Hardware specific routines ------------------------- */
 155
 156/*
 157 * Hardware Cyber2000 Acceleration
 158 */
 159static void
 160cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 161{
 162        struct cfb_info *cfb = (struct cfb_info *)info;
 163        unsigned long dst, col;
 164
 165        if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
 166                cfb_fillrect(info, rect);
 167                return;
 168        }
 169
 170        cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 171        cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb);
 172        cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb);
 173
 174        col = rect->color;
 175        if (cfb->fb.var.bits_per_pixel > 8)
 176                col = ((u32 *)cfb->fb.pseudo_palette)[col];
 177        cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb);
 178
 179        dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual;
 180        if (cfb->fb.var.bits_per_pixel == 24) {
 181                cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 182                dst *= 3;
 183        }
 184
 185        cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
 186        cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
 187        cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
 188        cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
 189}
 190
 191static void
 192cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 193{
 194        struct cfb_info *cfb = (struct cfb_info *)info;
 195        unsigned int cmd = CO_CMD_L_PATTERN_FGCOL;
 196        unsigned long src, dst;
 197
 198        if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
 199                cfb_copyarea(info, region);
 200                return;
 201        }
 202
 203        cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 204        cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb);
 205        cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb);
 206
 207        src = region->sx + region->sy * cfb->fb.var.xres_virtual;
 208        dst = region->dx + region->dy * cfb->fb.var.xres_virtual;
 209
 210        if (region->sx < region->dx) {
 211                src += region->width - 1;
 212                dst += region->width - 1;
 213                cmd |= CO_CMD_L_INC_LEFT;
 214        }
 215
 216        if (region->sy < region->dy) {
 217                src += (region->height - 1) * cfb->fb.var.xres_virtual;
 218                dst += (region->height - 1) * cfb->fb.var.xres_virtual;
 219                cmd |= CO_CMD_L_INC_UP;
 220        }
 221
 222        if (cfb->fb.var.bits_per_pixel == 24) {
 223                cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 224                src *= 3;
 225                dst *= 3;
 226        }
 227        cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
 228        cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
 229        cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
 230        cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
 231        cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER,
 232                           CO_REG_CMD_H, cfb);
 233}
 234
 235static void
 236cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image)
 237{
 238        cfb_imageblit(info, image);
 239        return;
 240}
 241
 242static int cyber2000fb_sync(struct fb_info *info)
 243{
 244        struct cfb_info *cfb = (struct cfb_info *)info;
 245        int count = 100000;
 246
 247        if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT))
 248                return 0;
 249
 250        while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
 251                if (!count--) {
 252                        debug_printf("accel_wait timed out\n");
 253                        cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
 254                        break;
 255                }
 256                udelay(1);
 257        }
 258        return 0;
 259}
 260
 261/*
 262 * ===========================================================================
 263 */
 264
 265static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf)
 266{
 267        u_int mask = (1 << bf->length) - 1;
 268
 269        return (val >> (16 - bf->length) & mask) << bf->offset;
 270}
 271
 272/*
 273 *    Set a single color register. Return != 0 for invalid regno.
 274 */
 275static int
 276cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 277                      u_int transp, struct fb_info *info)
 278{
 279        struct cfb_info *cfb = (struct cfb_info *)info;
 280        struct fb_var_screeninfo *var = &cfb->fb.var;
 281        u32 pseudo_val;
 282        int ret = 1;
 283
 284        switch (cfb->fb.fix.visual) {
 285        default:
 286                return 1;
 287
 288        /*
 289         * Pseudocolour:
 290         *         8     8
 291         * pixel --/--+--/-->  red lut  --> red dac
 292         *            |  8
 293         *            +--/--> green lut --> green dac
 294         *            |  8
 295         *            +--/-->  blue lut --> blue dac
 296         */
 297        case FB_VISUAL_PSEUDOCOLOR:
 298                if (regno >= NR_PALETTE)
 299                        return 1;
 300
 301                red >>= 8;
 302                green >>= 8;
 303                blue >>= 8;
 304
 305                cfb->palette[regno].red = red;
 306                cfb->palette[regno].green = green;
 307                cfb->palette[regno].blue = blue;
 308
 309                cyber2000fb_writeb(regno, 0x3c8, cfb);
 310                cyber2000fb_writeb(red, 0x3c9, cfb);
 311                cyber2000fb_writeb(green, 0x3c9, cfb);
 312                cyber2000fb_writeb(blue, 0x3c9, cfb);
 313                return 0;
 314
 315        /*
 316         * Direct colour:
 317         *         n     rl
 318         * pixel --/--+--/-->  red lut  --> red dac
 319         *            |  gl
 320         *            +--/--> green lut --> green dac
 321         *            |  bl
 322         *            +--/-->  blue lut --> blue dac
 323         * n = bpp, rl = red length, gl = green length, bl = blue length
 324         */
 325        case FB_VISUAL_DIRECTCOLOR:
 326                red >>= 8;
 327                green >>= 8;
 328                blue >>= 8;
 329
 330                if (var->green.length == 6 && regno < 64) {
 331                        cfb->palette[regno << 2].green = green;
 332
 333                        /*
 334                         * The 6 bits of the green component are applied
 335                         * to the high 6 bits of the LUT.
 336                         */
 337                        cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
 338                        cyber2000fb_writeb(cfb->palette[regno >> 1].red,
 339                                           0x3c9, cfb);
 340                        cyber2000fb_writeb(green, 0x3c9, cfb);
 341                        cyber2000fb_writeb(cfb->palette[regno >> 1].blue,
 342                                           0x3c9, cfb);
 343
 344                        green = cfb->palette[regno << 3].green;
 345
 346                        ret = 0;
 347                }
 348
 349                if (var->green.length >= 5 && regno < 32) {
 350                        cfb->palette[regno << 3].red = red;
 351                        cfb->palette[regno << 3].green = green;
 352                        cfb->palette[regno << 3].blue = blue;
 353
 354                        /*
 355                         * The 5 bits of each colour component are
 356                         * applied to the high 5 bits of the LUT.
 357                         */
 358                        cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
 359                        cyber2000fb_writeb(red, 0x3c9, cfb);
 360                        cyber2000fb_writeb(green, 0x3c9, cfb);
 361                        cyber2000fb_writeb(blue, 0x3c9, cfb);
 362                        ret = 0;
 363                }
 364
 365                if (var->green.length == 4 && regno < 16) {
 366                        cfb->palette[regno << 4].red = red;
 367                        cfb->palette[regno << 4].green = green;
 368                        cfb->palette[regno << 4].blue = blue;
 369
 370                        /*
 371                         * The 5 bits of each colour component are
 372                         * applied to the high 5 bits of the LUT.
 373                         */
 374                        cyber2000fb_writeb(regno << 4, 0x3c8, cfb);
 375                        cyber2000fb_writeb(red, 0x3c9, cfb);
 376                        cyber2000fb_writeb(green, 0x3c9, cfb);
 377                        cyber2000fb_writeb(blue, 0x3c9, cfb);
 378                        ret = 0;
 379                }
 380
 381                /*
 382                 * Since this is only used for the first 16 colours, we
 383                 * don't have to care about overflowing for regno >= 32
 384                 */
 385                pseudo_val = regno << var->red.offset |
 386                             regno << var->green.offset |
 387                             regno << var->blue.offset;
 388                break;
 389
 390        /*
 391         * True colour:
 392         *         n     rl
 393         * pixel --/--+--/--> red dac
 394         *            |  gl
 395         *            +--/--> green dac
 396         *            |  bl
 397         *            +--/--> blue dac
 398         * n = bpp, rl = red length, gl = green length, bl = blue length
 399         */
 400        case FB_VISUAL_TRUECOLOR:
 401                pseudo_val = convert_bitfield(transp ^ 0xffff, &var->transp);
 402                pseudo_val |= convert_bitfield(red, &var->red);
 403                pseudo_val |= convert_bitfield(green, &var->green);
 404                pseudo_val |= convert_bitfield(blue, &var->blue);
 405                ret = 0;
 406                break;
 407        }
 408
 409        /*
 410         * Now set our pseudo palette for the CFB16/24/32 drivers.
 411         */
 412        if (regno < 16)
 413                ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
 414
 415        return ret;
 416}
 417
 418struct par_info {
 419        /*
 420         * Hardware
 421         */
 422        u_char  clock_mult;
 423        u_char  clock_div;
 424        u_char  extseqmisc;
 425        u_char  co_pixfmt;
 426        u_char  crtc_ofl;
 427        u_char  crtc[19];
 428        u_int   width;
 429        u_int   pitch;
 430        u_int   fetch;
 431
 432        /*
 433         * Other
 434         */
 435        u_char  ramdac;
 436};
 437
 438static const u_char crtc_idx[] = {
 439        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 440        0x08, 0x09,
 441        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
 442};
 443
 444static void cyber2000fb_write_ramdac_ctrl(struct cfb_info *cfb)
 445{
 446        unsigned int i;
 447        unsigned int val = cfb->ramdac_ctrl | cfb->ramdac_powerdown;
 448
 449        cyber2000fb_writeb(0x56, 0x3ce, cfb);
 450        i = cyber2000fb_readb(0x3cf, cfb);
 451        cyber2000fb_writeb(i | 4, 0x3cf, cfb);
 452        cyber2000fb_writeb(val, 0x3c6, cfb);
 453        cyber2000fb_writeb(i, 0x3cf, cfb);
 454        /* prevent card lock-up observed on x86 with CyberPro 2000 */
 455        cyber2000fb_readb(0x3cf, cfb);
 456}
 457
 458static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
 459{
 460        u_int i;
 461
 462        /*
 463         * Blank palette
 464         */
 465        for (i = 0; i < NR_PALETTE; i++) {
 466                cyber2000fb_writeb(i, 0x3c8, cfb);
 467                cyber2000fb_writeb(0, 0x3c9, cfb);
 468                cyber2000fb_writeb(0, 0x3c9, cfb);
 469                cyber2000fb_writeb(0, 0x3c9, cfb);
 470        }
 471
 472        cyber2000fb_writeb(0xef, 0x3c2, cfb);
 473        cyber2000_crtcw(0x11, 0x0b, cfb);
 474        cyber2000_attrw(0x11, 0x00, cfb);
 475
 476        cyber2000_seqw(0x00, 0x01, cfb);
 477        cyber2000_seqw(0x01, 0x01, cfb);
 478        cyber2000_seqw(0x02, 0x0f, cfb);
 479        cyber2000_seqw(0x03, 0x00, cfb);
 480        cyber2000_seqw(0x04, 0x0e, cfb);
 481        cyber2000_seqw(0x00, 0x03, cfb);
 482
 483        for (i = 0; i < sizeof(crtc_idx); i++)
 484                cyber2000_crtcw(crtc_idx[i], hw->crtc[i], cfb);
 485
 486        for (i = 0x0a; i < 0x10; i++)
 487                cyber2000_crtcw(i, 0, cfb);
 488
 489        cyber2000_grphw(EXT_CRT_VRTOFL, hw->crtc_ofl, cfb);
 490        cyber2000_grphw(0x00, 0x00, cfb);
 491        cyber2000_grphw(0x01, 0x00, cfb);
 492        cyber2000_grphw(0x02, 0x00, cfb);
 493        cyber2000_grphw(0x03, 0x00, cfb);
 494        cyber2000_grphw(0x04, 0x00, cfb);
 495        cyber2000_grphw(0x05, 0x60, cfb);
 496        cyber2000_grphw(0x06, 0x05, cfb);
 497        cyber2000_grphw(0x07, 0x0f, cfb);
 498        cyber2000_grphw(0x08, 0xff, cfb);
 499
 500        /* Attribute controller registers */
 501        for (i = 0; i < 16; i++)
 502                cyber2000_attrw(i, i, cfb);
 503
 504        cyber2000_attrw(0x10, 0x01, cfb);
 505        cyber2000_attrw(0x11, 0x00, cfb);
 506        cyber2000_attrw(0x12, 0x0f, cfb);
 507        cyber2000_attrw(0x13, 0x00, cfb);
 508        cyber2000_attrw(0x14, 0x00, cfb);
 509
 510        /* PLL registers */
 511        spin_lock(&cfb->reg_b0_lock);
 512        cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
 513        cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
 514        cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
 515        cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
 516        cyber2000_grphw(0x90, 0x01, cfb);
 517        cyber2000_grphw(0xb9, 0x80, cfb);
 518        cyber2000_grphw(0xb9, 0x00, cfb);
 519        spin_unlock(&cfb->reg_b0_lock);
 520
 521        cfb->ramdac_ctrl = hw->ramdac;
 522        cyber2000fb_write_ramdac_ctrl(cfb);
 523
 524        cyber2000fb_writeb(0x20, 0x3c0, cfb);
 525        cyber2000fb_writeb(0xff, 0x3c6, cfb);
 526
 527        cyber2000_grphw(0x14, hw->fetch, cfb);
 528        cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
 529                              ((hw->pitch >> 4) & 0x30), cfb);
 530        cyber2000_grphw(EXT_SEQ_MISC, hw->extseqmisc, cfb);
 531
 532        /*
 533         * Set up accelerator registers
 534         */
 535        cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
 536        cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
 537        cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
 538}
 539
 540static inline int
 541cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var)
 542{
 543        u_int base = var->yoffset * var->xres_virtual + var->xoffset;
 544
 545        base *= var->bits_per_pixel;
 546
 547        /*
 548         * Convert to bytes and shift two extra bits because DAC
 549         * can only start on 4 byte aligned data.
 550         */
 551        base >>= 5;
 552
 553        if (base >= 1 << 20)
 554                return -EINVAL;
 555
 556        cyber2000_grphw(0x10, base >> 16 | 0x10, cfb);
 557        cyber2000_crtcw(0x0c, base >> 8, cfb);
 558        cyber2000_crtcw(0x0d, base, cfb);
 559
 560        return 0;
 561}
 562
 563static int
 564cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
 565                        struct fb_var_screeninfo *var)
 566{
 567        u_int Htotal, Hblankend, Hsyncend;
 568        u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
 569#define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2))
 570
 571        hw->crtc[13] = hw->pitch;
 572        hw->crtc[17] = 0xe3;
 573        hw->crtc[14] = 0;
 574        hw->crtc[8]  = 0;
 575
 576        Htotal     = var->xres + var->right_margin +
 577                     var->hsync_len + var->left_margin;
 578
 579        if (Htotal > 2080)
 580                return -EINVAL;
 581
 582        hw->crtc[0] = (Htotal >> 3) - 5;
 583        hw->crtc[1] = (var->xres >> 3) - 1;
 584        hw->crtc[2] = var->xres >> 3;
 585        hw->crtc[4] = (var->xres + var->right_margin) >> 3;
 586
 587        Hblankend   = (Htotal - 4 * 8) >> 3;
 588
 589        hw->crtc[3] = ENCODE_BIT(Hblankend,  0, 0x1f,  0) |
 590                      ENCODE_BIT(1,          0, 0x01,  7);
 591
 592        Hsyncend    = (var->xres + var->right_margin + var->hsync_len) >> 3;
 593
 594        hw->crtc[5] = ENCODE_BIT(Hsyncend,   0, 0x1f,  0) |
 595                      ENCODE_BIT(Hblankend,  5, 0x01,  7);
 596
 597        Vdispend    = var->yres - 1;
 598        Vsyncstart  = var->yres + var->lower_margin;
 599        Vsyncend    = var->yres + var->lower_margin + var->vsync_len;
 600        Vtotal      = var->yres + var->lower_margin + var->vsync_len +
 601                      var->upper_margin - 2;
 602
 603        if (Vtotal > 2047)
 604                return -EINVAL;
 605
 606        Vblankstart = var->yres + 6;
 607        Vblankend   = Vtotal - 10;
 608
 609        hw->crtc[6]  = Vtotal;
 610        hw->crtc[7]  = ENCODE_BIT(Vtotal,     8, 0x01,  0) |
 611                        ENCODE_BIT(Vdispend,   8, 0x01,  1) |
 612                        ENCODE_BIT(Vsyncstart, 8, 0x01,  2) |
 613                        ENCODE_BIT(Vblankstart, 8, 0x01,  3) |
 614                        ENCODE_BIT(1,          0, 0x01,  4) |
 615                        ENCODE_BIT(Vtotal,     9, 0x01,  5) |
 616                        ENCODE_BIT(Vdispend,   9, 0x01,  6) |
 617                        ENCODE_BIT(Vsyncstart, 9, 0x01,  7);
 618        hw->crtc[9]  = ENCODE_BIT(0,          0, 0x1f,  0) |
 619                        ENCODE_BIT(Vblankstart, 9, 0x01,  5) |
 620                        ENCODE_BIT(1,          0, 0x01,  6);
 621        hw->crtc[10] = Vsyncstart;
 622        hw->crtc[11] = ENCODE_BIT(Vsyncend,   0, 0x0f,  0) |
 623                       ENCODE_BIT(1,          0, 0x01,  7);
 624        hw->crtc[12] = Vdispend;
 625        hw->crtc[15] = Vblankstart;
 626        hw->crtc[16] = Vblankend;
 627        hw->crtc[18] = 0xff;
 628
 629        /*
 630         * overflow - graphics reg 0x11
 631         * 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10
 632         * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
 633         */
 634        hw->crtc_ofl =
 635                ENCODE_BIT(Vtotal, 10, 0x01, 0) |
 636                ENCODE_BIT(Vdispend, 10, 0x01, 1) |
 637                ENCODE_BIT(Vsyncstart, 10, 0x01, 2) |
 638                ENCODE_BIT(Vblankstart, 10, 0x01, 3) |
 639                EXT_CRT_VRTOFL_LINECOMP10;
 640
 641        /* woody: set the interlaced bit... */
 642        /* FIXME: what about doublescan? */
 643        if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
 644                hw->crtc_ofl |= EXT_CRT_VRTOFL_INTERLACE;
 645
 646        return 0;
 647}
 648
 649/*
 650 * The following was discovered by a good monitor, bit twiddling, theorising
 651 * and but mostly luck.  Strangely, it looks like everyone elses' PLL!
 652 *
 653 * Clock registers:
 654 *   fclock = fpll / div2
 655 *   fpll   = fref * mult / div1
 656 * where:
 657 *   fref = 14.318MHz (69842ps)
 658 *   mult = reg0xb0.7:0
 659 *   div1 = (reg0xb1.5:0 + 1)
 660 *   div2 =  2^(reg0xb1.7:6)
 661 *   fpll should be between 115 and 260 MHz
 662 *  (8696ps and 3846ps)
 663 */
 664static int
 665cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
 666                         struct fb_var_screeninfo *var)
 667{
 668        u_long pll_ps = var->pixclock;
 669        const u_long ref_ps = cfb->ref_ps;
 670        u_int div2, t_div1, best_div1, best_mult;
 671        int best_diff;
 672        int vco;
 673
 674        /*
 675         * Step 1:
 676         *   find div2 such that 115MHz < fpll < 260MHz
 677         *   and 0 <= div2 < 4
 678         */
 679        for (div2 = 0; div2 < 4; div2++) {
 680                u_long new_pll;
 681
 682                new_pll = pll_ps / cfb->divisors[div2];
 683                if (8696 > new_pll && new_pll > 3846) {
 684                        pll_ps = new_pll;
 685                        break;
 686                }
 687        }
 688
 689        if (div2 == 4)
 690                return -EINVAL;
 691
 692        /*
 693         * Step 2:
 694         *  Given pll_ps and ref_ps, find:
 695         *    pll_ps * 0.995 < pll_ps_calc < pll_ps * 1.005
 696         *  where { 1 < best_div1 < 32, 1 < best_mult < 256 }
 697         *    pll_ps_calc = best_div1 / (ref_ps * best_mult)
 698         */
 699        best_diff = 0x7fffffff;
 700        best_mult = 2;
 701        best_div1 = 32;
 702        for (t_div1 = 2; t_div1 < 32; t_div1 += 1) {
 703                u_int rr, t_mult, t_pll_ps;
 704                int diff;
 705
 706                /*
 707                 * Find the multiplier for this divisor
 708                 */
 709                rr = ref_ps * t_div1;
 710                t_mult = (rr + pll_ps / 2) / pll_ps;
 711
 712                /*
 713                 * Is the multiplier within the correct range?
 714                 */
 715                if (t_mult > 256 || t_mult < 2)
 716                        continue;
 717
 718                /*
 719                 * Calculate the actual clock period from this multiplier
 720                 * and divisor, and estimate the error.
 721                 */
 722                t_pll_ps = (rr + t_mult / 2) / t_mult;
 723                diff = pll_ps - t_pll_ps;
 724                if (diff < 0)
 725                        diff = -diff;
 726
 727                if (diff < best_diff) {
 728                        best_diff = diff;
 729                        best_mult = t_mult;
 730                        best_div1 = t_div1;
 731                }
 732
 733                /*
 734                 * If we hit an exact value, there is no point in continuing.
 735                 */
 736                if (diff == 0)
 737                        break;
 738        }
 739
 740        /*
 741         * Step 3:
 742         *  combine values
 743         */
 744        hw->clock_mult = best_mult - 1;
 745        hw->clock_div  = div2 << 6 | (best_div1 - 1);
 746
 747        vco = ref_ps * best_div1 / best_mult;
 748        if ((ref_ps == 40690) && (vco < 5556))
 749                /* Set VFSEL when VCO > 180MHz (5.556 ps). */
 750                hw->clock_div |= EXT_DCLK_DIV_VFSEL;
 751
 752        return 0;
 753}
 754
 755/*
 756 *    Set the User Defined Part of the Display
 757 */
 758static int
 759cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 760{
 761        struct cfb_info *cfb = (struct cfb_info *)info;
 762        struct par_info hw;
 763        unsigned int mem;
 764        int err;
 765
 766        var->transp.msb_right   = 0;
 767        var->red.msb_right      = 0;
 768        var->green.msb_right    = 0;
 769        var->blue.msb_right     = 0;
 770        var->transp.offset      = 0;
 771        var->transp.length      = 0;
 772
 773        switch (var->bits_per_pixel) {
 774        case 8: /* PSEUDOCOLOUR, 256 */
 775                var->red.offset         = 0;
 776                var->red.length         = 8;
 777                var->green.offset       = 0;
 778                var->green.length       = 8;
 779                var->blue.offset        = 0;
 780                var->blue.length        = 8;
 781                break;
 782
 783        case 16:/* DIRECTCOLOUR, 64k or 32k */
 784                switch (var->green.length) {
 785                case 6: /* RGB565, 64k */
 786                        var->red.offset         = 11;
 787                        var->red.length         = 5;
 788                        var->green.offset       = 5;
 789                        var->green.length       = 6;
 790                        var->blue.offset        = 0;
 791                        var->blue.length        = 5;
 792                        break;
 793
 794                default:
 795                case 5: /* RGB555, 32k */
 796                        var->red.offset         = 10;
 797                        var->red.length         = 5;
 798                        var->green.offset       = 5;
 799                        var->green.length       = 5;
 800                        var->blue.offset        = 0;
 801                        var->blue.length        = 5;
 802                        break;
 803
 804                case 4: /* RGB444, 4k + transparency? */
 805                        var->transp.offset      = 12;
 806                        var->transp.length      = 4;
 807                        var->red.offset         = 8;
 808                        var->red.length         = 4;
 809                        var->green.offset       = 4;
 810                        var->green.length       = 4;
 811                        var->blue.offset        = 0;
 812                        var->blue.length        = 4;
 813                        break;
 814                }
 815                break;
 816
 817        case 24:/* TRUECOLOUR, 16m */
 818                var->red.offset         = 16;
 819                var->red.length         = 8;
 820                var->green.offset       = 8;
 821                var->green.length       = 8;
 822                var->blue.offset        = 0;
 823                var->blue.length        = 8;
 824                break;
 825
 826        case 32:/* TRUECOLOUR, 16m */
 827                var->transp.offset      = 24;
 828                var->transp.length      = 8;
 829                var->red.offset         = 16;
 830                var->red.length         = 8;
 831                var->green.offset       = 8;
 832                var->green.length       = 8;
 833                var->blue.offset        = 0;
 834                var->blue.length        = 8;
 835                break;
 836
 837        default:
 838                return -EINVAL;
 839        }
 840
 841        mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
 842        if (mem > cfb->fb.fix.smem_len)
 843                var->yres_virtual = cfb->fb.fix.smem_len * 8 /
 844                                    (var->bits_per_pixel * var->xres_virtual);
 845
 846        if (var->yres > var->yres_virtual)
 847                var->yres = var->yres_virtual;
 848        if (var->xres > var->xres_virtual)
 849                var->xres = var->xres_virtual;
 850
 851        err = cyber2000fb_decode_clock(&hw, cfb, var);
 852        if (err)
 853                return err;
 854
 855        err = cyber2000fb_decode_crtc(&hw, cfb, var);
 856        if (err)
 857                return err;
 858
 859        return 0;
 860}
 861
 862static int cyber2000fb_set_par(struct fb_info *info)
 863{
 864        struct cfb_info *cfb = (struct cfb_info *)info;
 865        struct fb_var_screeninfo *var = &cfb->fb.var;
 866        struct par_info hw;
 867        unsigned int mem;
 868
 869        hw.width = var->xres_virtual;
 870        hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
 871
 872        switch (var->bits_per_pixel) {
 873        case 8:
 874                hw.co_pixfmt            = CO_PIXFMT_8BPP;
 875                hw.pitch                = hw.width >> 3;
 876                hw.extseqmisc           = EXT_SEQ_MISC_8;
 877                break;
 878
 879        case 16:
 880                hw.co_pixfmt            = CO_PIXFMT_16BPP;
 881                hw.pitch                = hw.width >> 2;
 882
 883                switch (var->green.length) {
 884                case 6: /* RGB565, 64k */
 885                        hw.extseqmisc   = EXT_SEQ_MISC_16_RGB565;
 886                        break;
 887                case 5: /* RGB555, 32k */
 888                        hw.extseqmisc   = EXT_SEQ_MISC_16_RGB555;
 889                        break;
 890                case 4: /* RGB444, 4k + transparency? */
 891                        hw.extseqmisc   = EXT_SEQ_MISC_16_RGB444;
 892                        break;
 893                default:
 894                        BUG();
 895                }
 896                break;
 897
 898        case 24:/* TRUECOLOUR, 16m */
 899                hw.co_pixfmt            = CO_PIXFMT_24BPP;
 900                hw.width                *= 3;
 901                hw.pitch                = hw.width >> 3;
 902                hw.ramdac               |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
 903                hw.extseqmisc           = EXT_SEQ_MISC_24_RGB888;
 904                break;
 905
 906        case 32:/* TRUECOLOUR, 16m */
 907                hw.co_pixfmt            = CO_PIXFMT_32BPP;
 908                hw.pitch                = hw.width >> 1;
 909                hw.ramdac               |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
 910                hw.extseqmisc           = EXT_SEQ_MISC_32;
 911                break;
 912
 913        default:
 914                BUG();
 915        }
 916
 917        /*
 918         * Sigh, this is absolutely disgusting, but caused by
 919         * the way the fbcon developers want to separate out
 920         * the "checking" and the "setting" of the video mode.
 921         *
 922         * If the mode is not suitable for the hardware here,
 923         * we can't prevent it being set by returning an error.
 924         *
 925         * In theory, since NetWinders contain just one VGA card,
 926         * we should never end up hitting this problem.
 927         */
 928        BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0);
 929        BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0);
 930
 931        hw.width -= 1;
 932        hw.fetch = hw.pitch;
 933        if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
 934                hw.fetch <<= 1;
 935        hw.fetch += 1;
 936
 937        cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
 938
 939        /*
 940         * Same here - if the size of the video mode exceeds the
 941         * available RAM, we can't prevent this mode being set.
 942         *
 943         * In theory, since NetWinders contain just one VGA card,
 944         * we should never end up hitting this problem.
 945         */
 946        mem = cfb->fb.fix.line_length * var->yres_virtual;
 947        BUG_ON(mem > cfb->fb.fix.smem_len);
 948
 949        /*
 950         * 8bpp displays are always pseudo colour.  16bpp and above
 951         * are direct colour or true colour, depending on whether
 952         * the RAMDAC palettes are bypassed.  (Direct colour has
 953         * palettes, true colour does not.)
 954         */
 955        if (var->bits_per_pixel == 8)
 956                cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
 957        else if (hw.ramdac & RAMDAC_BYPASS)
 958                cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
 959        else
 960                cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
 961
 962        cyber2000fb_set_timing(cfb, &hw);
 963        cyber2000fb_update_start(cfb, var);
 964
 965        return 0;
 966}
 967
 968/*
 969 *    Pan or Wrap the Display
 970 */
 971static int
 972cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 973{
 974        struct cfb_info *cfb = (struct cfb_info *)info;
 975
 976        if (cyber2000fb_update_start(cfb, var))
 977                return -EINVAL;
 978
 979        cfb->fb.var.xoffset = var->xoffset;
 980        cfb->fb.var.yoffset = var->yoffset;
 981
 982        if (var->vmode & FB_VMODE_YWRAP) {
 983                cfb->fb.var.vmode |= FB_VMODE_YWRAP;
 984        } else {
 985                cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
 986        }
 987
 988        return 0;
 989}
 990
 991/*
 992 *    (Un)Blank the display.
 993 *
 994 *  Blank the screen if blank_mode != 0, else unblank. If
 995 *  blank == NULL then the caller blanks by setting the CLUT
 996 *  (Color Look Up Table) to all black. Return 0 if blanking
 997 *  succeeded, != 0 if un-/blanking failed due to e.g. a
 998 *  video mode which doesn't support it. Implements VESA
 999 *  suspend and powerdown modes on hardware that supports
1000 *  disabling hsync/vsync:
1001 *    blank_mode == 2: suspend vsync
1002 *    blank_mode == 3: suspend hsync
1003 *    blank_mode == 4: powerdown
1004 *
1005 *  wms...Enable VESA DMPS compatible powerdown mode
1006 *  run "setterm -powersave powerdown" to take advantage
1007 */
1008static int cyber2000fb_blank(int blank, struct fb_info *info)
1009{
1010        struct cfb_info *cfb = (struct cfb_info *)info;
1011        unsigned int sync = 0;
1012        int i;
1013
1014        switch (blank) {
1015        case FB_BLANK_POWERDOWN:        /* powerdown - both sync lines down */
1016                sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
1017                break;
1018        case FB_BLANK_HSYNC_SUSPEND:    /* hsync off */
1019                sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
1020                break;
1021        case FB_BLANK_VSYNC_SUSPEND:    /* vsync off */
1022                sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
1023                break;
1024        case FB_BLANK_NORMAL:           /* soft blank */
1025        default:                        /* unblank */
1026                break;
1027        }
1028
1029        cyber2000_grphw(EXT_SYNC_CTL, sync, cfb);
1030
1031        if (blank <= 1) {
1032                /* turn on ramdacs */
1033                cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS |
1034                                           RAMDAC_RAMPWRDN);
1035                cyber2000fb_write_ramdac_ctrl(cfb);
1036        }
1037
1038        /*
1039         * Soft blank/unblank the display.
1040         */
1041        if (blank) {    /* soft blank */
1042                for (i = 0; i < NR_PALETTE; i++) {
1043                        cyber2000fb_writeb(i, 0x3c8, cfb);
1044                        cyber2000fb_writeb(0, 0x3c9, cfb);
1045                        cyber2000fb_writeb(0, 0x3c9, cfb);
1046                        cyber2000fb_writeb(0, 0x3c9, cfb);
1047                }
1048        } else {        /* unblank */
1049                for (i = 0; i < NR_PALETTE; i++) {
1050                        cyber2000fb_writeb(i, 0x3c8, cfb);
1051                        cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
1052                        cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
1053                        cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
1054                }
1055        }
1056
1057        if (blank >= 2) {
1058                /* turn off ramdacs */
1059                cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS |
1060                                         RAMDAC_RAMPWRDN;
1061                cyber2000fb_write_ramdac_ctrl(cfb);
1062        }
1063
1064        return 0;
1065}
1066
1067static struct fb_ops cyber2000fb_ops = {
1068        .owner          = THIS_MODULE,
1069        .fb_check_var   = cyber2000fb_check_var,
1070        .fb_set_par     = cyber2000fb_set_par,
1071        .fb_setcolreg   = cyber2000fb_setcolreg,
1072        .fb_blank       = cyber2000fb_blank,
1073        .fb_pan_display = cyber2000fb_pan_display,
1074        .fb_fillrect    = cyber2000fb_fillrect,
1075        .fb_copyarea    = cyber2000fb_copyarea,
1076        .fb_imageblit   = cyber2000fb_imageblit,
1077        .fb_sync        = cyber2000fb_sync,
1078};
1079
1080/*
1081 * This is the only "static" reference to the internal data structures
1082 * of this driver.  It is here solely at the moment to support the other
1083 * CyberPro modules external to this driver.
1084 */
1085static struct cfb_info *int_cfb_info;
1086
1087/*
1088 * Enable access to the extended registers
1089 */
1090void cyber2000fb_enable_extregs(struct cfb_info *cfb)
1091{
1092        cfb->func_use_count += 1;
1093
1094        if (cfb->func_use_count == 1) {
1095                int old;
1096
1097                old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
1098                old |= EXT_FUNC_CTL_EXTREGENBL;
1099                cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
1100        }
1101}
1102EXPORT_SYMBOL(cyber2000fb_enable_extregs);
1103
1104/*
1105 * Disable access to the extended registers
1106 */
1107void cyber2000fb_disable_extregs(struct cfb_info *cfb)
1108{
1109        if (cfb->func_use_count == 1) {
1110                int old;
1111
1112                old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
1113                old &= ~EXT_FUNC_CTL_EXTREGENBL;
1114                cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
1115        }
1116
1117        if (cfb->func_use_count == 0)
1118                printk(KERN_ERR "disable_extregs: count = 0\n");
1119        else
1120                cfb->func_use_count -= 1;
1121}
1122EXPORT_SYMBOL(cyber2000fb_disable_extregs);
1123
1124/*
1125 * Attach a capture/tv driver to the core CyberX0X0 driver.
1126 */
1127int cyber2000fb_attach(struct cyberpro_info *info, int idx)
1128{
1129        if (int_cfb_info != NULL) {
1130                info->dev             = int_cfb_info->fb.device;
1131#ifdef CONFIG_FB_CYBER2000_I2C
1132                info->i2c             = &int_cfb_info->i2c_adapter;
1133#else
1134                info->i2c             = NULL;
1135#endif
1136                info->regs            = int_cfb_info->regs;
1137                info->irq             = int_cfb_info->irq;
1138                info->fb              = int_cfb_info->fb.screen_base;
1139                info->fb_size         = int_cfb_info->fb.fix.smem_len;
1140                info->info            = int_cfb_info;
1141
1142                strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
1143                        sizeof(info->dev_name));
1144        }
1145
1146        return int_cfb_info != NULL;
1147}
1148EXPORT_SYMBOL(cyber2000fb_attach);
1149
1150/*
1151 * Detach a capture/tv driver from the core CyberX0X0 driver.
1152 */
1153void cyber2000fb_detach(int idx)
1154{
1155}
1156EXPORT_SYMBOL(cyber2000fb_detach);
1157
1158#ifdef CONFIG_FB_CYBER2000_DDC
1159
1160#define DDC_REG         0xb0
1161#define DDC_SCL_OUT     (1 << 0)
1162#define DDC_SDA_OUT     (1 << 4)
1163#define DDC_SCL_IN      (1 << 2)
1164#define DDC_SDA_IN      (1 << 6)
1165
1166static void cyber2000fb_enable_ddc(struct cfb_info *cfb)
1167{
1168        spin_lock(&cfb->reg_b0_lock);
1169        cyber2000fb_writew(0x1bf, 0x3ce, cfb);
1170}
1171
1172static void cyber2000fb_disable_ddc(struct cfb_info *cfb)
1173{
1174        cyber2000fb_writew(0x0bf, 0x3ce, cfb);
1175        spin_unlock(&cfb->reg_b0_lock);
1176}
1177
1178
1179static void cyber2000fb_ddc_setscl(void *data, int val)
1180{
1181        struct cfb_info *cfb = data;
1182        unsigned char reg;
1183
1184        cyber2000fb_enable_ddc(cfb);
1185        reg = cyber2000_grphr(DDC_REG, cfb);
1186        if (!val)       /* bit is inverted */
1187                reg |= DDC_SCL_OUT;
1188        else
1189                reg &= ~DDC_SCL_OUT;
1190        cyber2000_grphw(DDC_REG, reg, cfb);
1191        cyber2000fb_disable_ddc(cfb);
1192}
1193
1194static void cyber2000fb_ddc_setsda(void *data, int val)
1195{
1196        struct cfb_info *cfb = data;
1197        unsigned char reg;
1198
1199        cyber2000fb_enable_ddc(cfb);
1200        reg = cyber2000_grphr(DDC_REG, cfb);
1201        if (!val)       /* bit is inverted */
1202                reg |= DDC_SDA_OUT;
1203        else
1204                reg &= ~DDC_SDA_OUT;
1205        cyber2000_grphw(DDC_REG, reg, cfb);
1206        cyber2000fb_disable_ddc(cfb);
1207}
1208
1209static int cyber2000fb_ddc_getscl(void *data)
1210{
1211        struct cfb_info *cfb = data;
1212        int retval;
1213
1214        cyber2000fb_enable_ddc(cfb);
1215        retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SCL_IN);
1216        cyber2000fb_disable_ddc(cfb);
1217
1218        return retval;
1219}
1220
1221static int cyber2000fb_ddc_getsda(void *data)
1222{
1223        struct cfb_info *cfb = data;
1224        int retval;
1225
1226        cyber2000fb_enable_ddc(cfb);
1227        retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SDA_IN);
1228        cyber2000fb_disable_ddc(cfb);
1229
1230        return retval;
1231}
1232
1233static int cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
1234{
1235        strlcpy(cfb->ddc_adapter.name, cfb->fb.fix.id,
1236                sizeof(cfb->ddc_adapter.name));
1237        cfb->ddc_adapter.owner          = THIS_MODULE;
1238        cfb->ddc_adapter.class          = I2C_CLASS_DDC;
1239        cfb->ddc_adapter.algo_data      = &cfb->ddc_algo;
1240        cfb->ddc_adapter.dev.parent     = cfb->fb.device;
1241        cfb->ddc_algo.setsda            = cyber2000fb_ddc_setsda;
1242        cfb->ddc_algo.setscl            = cyber2000fb_ddc_setscl;
1243        cfb->ddc_algo.getsda            = cyber2000fb_ddc_getsda;
1244        cfb->ddc_algo.getscl            = cyber2000fb_ddc_getscl;
1245        cfb->ddc_algo.udelay            = 10;
1246        cfb->ddc_algo.timeout           = 20;
1247        cfb->ddc_algo.data              = cfb;
1248
1249        i2c_set_adapdata(&cfb->ddc_adapter, cfb);
1250
1251        return i2c_bit_add_bus(&cfb->ddc_adapter);
1252}
1253#endif /* CONFIG_FB_CYBER2000_DDC */
1254
1255#ifdef CONFIG_FB_CYBER2000_I2C
1256static void cyber2000fb_i2c_setsda(void *data, int state)
1257{
1258        struct cfb_info *cfb = data;
1259        unsigned int latch2;
1260
1261        spin_lock(&cfb->reg_b0_lock);
1262        latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1263        latch2 &= EXT_LATCH2_I2C_CLKEN;
1264        if (state)
1265                latch2 |= EXT_LATCH2_I2C_DATEN;
1266        cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1267        spin_unlock(&cfb->reg_b0_lock);
1268}
1269
1270static void cyber2000fb_i2c_setscl(void *data, int state)
1271{
1272        struct cfb_info *cfb = data;
1273        unsigned int latch2;
1274
1275        spin_lock(&cfb->reg_b0_lock);
1276        latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1277        latch2 &= EXT_LATCH2_I2C_DATEN;
1278        if (state)
1279                latch2 |= EXT_LATCH2_I2C_CLKEN;
1280        cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1281        spin_unlock(&cfb->reg_b0_lock);
1282}
1283
1284static int cyber2000fb_i2c_getsda(void *data)
1285{
1286        struct cfb_info *cfb = data;
1287        int ret;
1288
1289        spin_lock(&cfb->reg_b0_lock);
1290        ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_DAT);
1291        spin_unlock(&cfb->reg_b0_lock);
1292
1293        return ret;
1294}
1295
1296static int cyber2000fb_i2c_getscl(void *data)
1297{
1298        struct cfb_info *cfb = data;
1299        int ret;
1300
1301        spin_lock(&cfb->reg_b0_lock);
1302        ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_CLK);
1303        spin_unlock(&cfb->reg_b0_lock);
1304
1305        return ret;
1306}
1307
1308static int cyber2000fb_i2c_register(struct cfb_info *cfb)
1309{
1310        strlcpy(cfb->i2c_adapter.name, cfb->fb.fix.id,
1311                sizeof(cfb->i2c_adapter.name));
1312        cfb->i2c_adapter.owner = THIS_MODULE;
1313        cfb->i2c_adapter.algo_data = &cfb->i2c_algo;
1314        cfb->i2c_adapter.dev.parent = cfb->fb.device;
1315        cfb->i2c_algo.setsda = cyber2000fb_i2c_setsda;
1316        cfb->i2c_algo.setscl = cyber2000fb_i2c_setscl;
1317        cfb->i2c_algo.getsda = cyber2000fb_i2c_getsda;
1318        cfb->i2c_algo.getscl = cyber2000fb_i2c_getscl;
1319        cfb->i2c_algo.udelay = 5;
1320        cfb->i2c_algo.timeout = msecs_to_jiffies(100);
1321        cfb->i2c_algo.data = cfb;
1322
1323        return i2c_bit_add_bus(&cfb->i2c_adapter);
1324}
1325
1326static void cyber2000fb_i2c_unregister(struct cfb_info *cfb)
1327{
1328        i2c_del_adapter(&cfb->i2c_adapter);
1329}
1330#else
1331#define cyber2000fb_i2c_register(cfb)   (0)
1332#define cyber2000fb_i2c_unregister(cfb) do { } while (0)
1333#endif
1334
1335/*
1336 * These parameters give
1337 * 640x480, hsync 31.5kHz, vsync 60Hz
1338 */
1339static struct fb_videomode cyber2000fb_default_mode = {
1340        .refresh        = 60,
1341        .xres           = 640,
1342        .yres           = 480,
1343        .pixclock       = 39722,
1344        .left_margin    = 56,
1345        .right_margin   = 16,
1346        .upper_margin   = 34,
1347        .lower_margin   = 9,
1348        .hsync_len      = 88,
1349        .vsync_len      = 2,
1350        .sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
1351        .vmode          = FB_VMODE_NONINTERLACED
1352};
1353
1354static char igs_regs[] = {
1355        EXT_CRT_IRQ,            0,
1356        EXT_CRT_TEST,           0,
1357        EXT_SYNC_CTL,           0,
1358        EXT_SEG_WRITE_PTR,      0,
1359        EXT_SEG_READ_PTR,       0,
1360        EXT_BIU_MISC,           EXT_BIU_MISC_LIN_ENABLE |
1361                                EXT_BIU_MISC_COP_ENABLE |
1362                                EXT_BIU_MISC_COP_BFC,
1363        EXT_FUNC_CTL,           0,
1364        CURS_H_START,           0,
1365        CURS_H_START + 1,       0,
1366        CURS_H_PRESET,          0,
1367        CURS_V_START,           0,
1368        CURS_V_START + 1,       0,
1369        CURS_V_PRESET,          0,
1370        CURS_CTL,               0,
1371        EXT_ATTRIB_CTL,         EXT_ATTRIB_CTL_EXT,
1372        EXT_OVERSCAN_RED,       0,
1373        EXT_OVERSCAN_GREEN,     0,
1374        EXT_OVERSCAN_BLUE,      0,
1375
1376        /* some of these are questionable when we have a BIOS */
1377        EXT_MEM_CTL0,           EXT_MEM_CTL0_7CLK |
1378                                EXT_MEM_CTL0_RAS_1 |
1379                                EXT_MEM_CTL0_MULTCAS,
1380        EXT_HIDDEN_CTL1,        0x30,
1381        EXT_FIFO_CTL,           0x0b,
1382        EXT_FIFO_CTL + 1,       0x17,
1383        0x76,                   0x00,
1384        EXT_HIDDEN_CTL4,        0xc8
1385};
1386
1387/*
1388 * Initialise the CyberPro hardware.  On the CyberPro5XXXX,
1389 * ensure that we're using the correct PLL (5XXX's may be
1390 * programmed to use an additional set of PLLs.)
1391 */
1392static void cyberpro_init_hw(struct cfb_info *cfb)
1393{
1394        int i;
1395
1396        for (i = 0; i < sizeof(igs_regs); i += 2)
1397                cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);
1398
1399        if (cfb->id == ID_CYBERPRO_5000) {
1400                unsigned char val;
1401                cyber2000fb_writeb(0xba, 0x3ce, cfb);
1402                val = cyber2000fb_readb(0x3cf, cfb) & 0x80;
1403                cyber2000fb_writeb(val, 0x3cf, cfb);
1404        }
1405}
1406
1407static struct cfb_info *cyberpro_alloc_fb_info(unsigned int id, char *name)
1408{
1409        struct cfb_info *cfb;
1410
1411        cfb = kzalloc(sizeof(struct cfb_info), GFP_KERNEL);
1412        if (!cfb)
1413                return NULL;
1414
1415
1416        cfb->id                 = id;
1417
1418        if (id == ID_CYBERPRO_5000)
1419                cfb->ref_ps     = 40690; /* 24.576 MHz */
1420        else
1421                cfb->ref_ps     = 69842; /* 14.31818 MHz (69841?) */
1422
1423        cfb->divisors[0]        = 1;
1424        cfb->divisors[1]        = 2;
1425        cfb->divisors[2]        = 4;
1426
1427        if (id == ID_CYBERPRO_2000)
1428                cfb->divisors[3] = 8;
1429        else
1430                cfb->divisors[3] = 6;
1431
1432        strcpy(cfb->fb.fix.id, name);
1433
1434        cfb->fb.fix.type        = FB_TYPE_PACKED_PIXELS;
1435        cfb->fb.fix.type_aux    = 0;
1436        cfb->fb.fix.xpanstep    = 0;
1437        cfb->fb.fix.ypanstep    = 1;
1438        cfb->fb.fix.ywrapstep   = 0;
1439
1440        switch (id) {
1441        case ID_IGA_1682:
1442                cfb->fb.fix.accel = 0;
1443                break;
1444
1445        case ID_CYBERPRO_2000:
1446                cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000;
1447                break;
1448
1449        case ID_CYBERPRO_2010:
1450                cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010;
1451                break;
1452
1453        case ID_CYBERPRO_5000:
1454                cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000;
1455                break;
1456        }
1457
1458        cfb->fb.var.nonstd      = 0;
1459        cfb->fb.var.activate    = FB_ACTIVATE_NOW;
1460        cfb->fb.var.height      = -1;
1461        cfb->fb.var.width       = -1;
1462        cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
1463
1464        cfb->fb.fbops           = &cyber2000fb_ops;
1465        cfb->fb.flags           = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1466        cfb->fb.pseudo_palette  = cfb->pseudo_palette;
1467
1468        spin_lock_init(&cfb->reg_b0_lock);
1469
1470        fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
1471
1472        return cfb;
1473}
1474
1475static void cyberpro_free_fb_info(struct cfb_info *cfb)
1476{
1477        if (cfb) {
1478                /*
1479                 * Free the colourmap
1480                 */
1481                fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
1482
1483                kfree(cfb);
1484        }
1485}
1486
1487/*
1488 * Parse Cyber2000fb options.  Usage:
1489 *  video=cyber2000:font:fontname
1490 */
1491#ifndef MODULE
1492static int cyber2000fb_setup(char *options)
1493{
1494        char *opt;
1495
1496        if (!options || !*options)
1497                return 0;
1498
1499        while ((opt = strsep(&options, ",")) != NULL) {
1500                if (!*opt)
1501                        continue;
1502
1503                if (strncmp(opt, "font:", 5) == 0) {
1504                        static char default_font_storage[40];
1505
1506                        strlcpy(default_font_storage, opt + 5,
1507                                sizeof(default_font_storage));
1508                        default_font = default_font_storage;
1509                        continue;
1510                }
1511
1512                printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n", opt);
1513        }
1514        return 0;
1515}
1516#endif  /*  MODULE  */
1517
1518/*
1519 * The CyberPro chips can be placed on many different bus types.
1520 * This probe function is common to all bus types.  The bus-specific
1521 * probe function is expected to have:
1522 *  - enabled access to the linear memory region
1523 *  - memory mapped access to the registers
1524 *  - initialised mem_ctl1 and mem_ctl2 appropriately.
1525 */
1526static int cyberpro_common_probe(struct cfb_info *cfb)
1527{
1528        u_long smem_size;
1529        u_int h_sync, v_sync;
1530        int err;
1531
1532        cyberpro_init_hw(cfb);
1533
1534        /*
1535         * Get the video RAM size and width from the VGA register.
1536         * This should have been already initialised by the BIOS,
1537         * but if it's garbage, claim default 1MB VRAM (woody)
1538         */
1539        cfb->mem_ctl1 = cyber2000_grphr(EXT_MEM_CTL1, cfb);
1540        cfb->mem_ctl2 = cyber2000_grphr(EXT_MEM_CTL2, cfb);
1541
1542        /*
1543         * Determine the size of the memory.
1544         */
1545        switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
1546        case MEM_CTL2_SIZE_4MB:
1547                smem_size = 0x00400000;
1548                break;
1549        case MEM_CTL2_SIZE_2MB:
1550                smem_size = 0x00200000;
1551                break;
1552        case MEM_CTL2_SIZE_1MB:
1553                smem_size = 0x00100000;
1554                break;
1555        default:
1556                smem_size = 0x00100000;
1557                break;
1558        }
1559
1560        cfb->fb.fix.smem_len   = smem_size;
1561        cfb->fb.fix.mmio_len   = MMIO_SIZE;
1562        cfb->fb.screen_base    = cfb->region;
1563
1564#ifdef CONFIG_FB_CYBER2000_DDC
1565        if (cyber2000fb_setup_ddc_bus(cfb) == 0)
1566                cfb->ddc_registered = true;
1567#endif
1568
1569        err = -EINVAL;
1570        if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
1571                          &cyber2000fb_default_mode, 8)) {
1572                printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);
1573                goto failed;
1574        }
1575
1576        cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 /
1577                        (cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual);
1578
1579        if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
1580                cfb->fb.var.yres_virtual = cfb->fb.var.yres;
1581
1582/*      fb_set_var(&cfb->fb.var, -1, &cfb->fb); */
1583
1584        /*
1585         * Calculate the hsync and vsync frequencies.  Note that
1586         * we split the 1e12 constant up so that we can preserve
1587         * the precision and fit the results into 32-bit registers.
1588         *  (1953125000 * 512 = 1e12)
1589         */
1590        h_sync = 1953125000 / cfb->fb.var.pixclock;
1591        h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin +
1592                 cfb->fb.var.right_margin + cfb->fb.var.hsync_len);
1593        v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +
1594                 cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);
1595
1596        printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
1597                cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,
1598                cfb->fb.var.xres, cfb->fb.var.yres,
1599                h_sync / 1000, h_sync % 1000, v_sync);
1600
1601        err = cyber2000fb_i2c_register(cfb);
1602        if (err)
1603                goto failed;
1604
1605        err = register_framebuffer(&cfb->fb);
1606        if (err)
1607                cyber2000fb_i2c_unregister(cfb);
1608
1609failed:
1610#ifdef CONFIG_FB_CYBER2000_DDC
1611        if (err && cfb->ddc_registered)
1612                i2c_del_adapter(&cfb->ddc_adapter);
1613#endif
1614        return err;
1615}
1616
1617static void cyberpro_common_remove(struct cfb_info *cfb)
1618{
1619        unregister_framebuffer(&cfb->fb);
1620#ifdef CONFIG_FB_CYBER2000_DDC
1621        if (cfb->ddc_registered)
1622                i2c_del_adapter(&cfb->ddc_adapter);
1623#endif
1624        cyber2000fb_i2c_unregister(cfb);
1625}
1626
1627static void cyberpro_common_resume(struct cfb_info *cfb)
1628{
1629        cyberpro_init_hw(cfb);
1630
1631        /*
1632         * Reprogram the MEM_CTL1 and MEM_CTL2 registers
1633         */
1634        cyber2000_grphw(EXT_MEM_CTL1, cfb->mem_ctl1, cfb);
1635        cyber2000_grphw(EXT_MEM_CTL2, cfb->mem_ctl2, cfb);
1636
1637        /*
1638         * Restore the old video mode and the palette.
1639         * We also need to tell fbcon to redraw the console.
1640         */
1641        cyber2000fb_set_par(&cfb->fb);
1642}
1643
1644#ifdef CONFIG_ARCH_SHARK
1645
1646#include <mach/framebuffer.h>
1647
1648static int cyberpro_vl_probe(void)
1649{
1650        struct cfb_info *cfb;
1651        int err = -ENOMEM;
1652
1653        if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))
1654                return err;
1655
1656        cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
1657        if (!cfb)
1658                goto failed_release;
1659
1660        cfb->irq = -1;
1661        cfb->region = ioremap(FB_START, FB_SIZE);
1662        if (!cfb->region)
1663                goto failed_ioremap;
1664
1665        cfb->regs = cfb->region + MMIO_OFFSET;
1666        cfb->fb.device = NULL;
1667        cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;
1668        cfb->fb.fix.smem_start = FB_START;
1669
1670        /*
1671         * Bring up the hardware.  This is expected to enable access
1672         * to the linear memory region, and allow access to the memory
1673         * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be
1674         * initialised.
1675         */
1676        cyber2000fb_writeb(0x18, 0x46e8, cfb);
1677        cyber2000fb_writeb(0x01, 0x102, cfb);
1678        cyber2000fb_writeb(0x08, 0x46e8, cfb);
1679        cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb);
1680        cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb);
1681
1682        cfb->mclk_mult = 0xdb;
1683        cfb->mclk_div  = 0x54;
1684
1685        err = cyberpro_common_probe(cfb);
1686        if (err)
1687                goto failed;
1688
1689        if (int_cfb_info == NULL)
1690                int_cfb_info = cfb;
1691
1692        return 0;
1693
1694failed:
1695        iounmap(cfb->region);
1696failed_ioremap:
1697        cyberpro_free_fb_info(cfb);
1698failed_release:
1699        release_mem_region(FB_START, FB_SIZE);
1700
1701        return err;
1702}
1703#endif /* CONFIG_ARCH_SHARK */
1704
1705/*
1706 * PCI specific support.
1707 */
1708#ifdef CONFIG_PCI
1709/*
1710 * We need to wake up the CyberPro, and make sure its in linear memory
1711 * mode.  Unfortunately, this is specific to the platform and card that
1712 * we are running on.
1713 *
1714 * On x86 and ARM, should we be initialising the CyberPro first via the
1715 * IO registers, and then the MMIO registers to catch all cases?  Can we
1716 * end up in the situation where the chip is in MMIO mode, but not awake
1717 * on an x86 system?
1718 */
1719static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
1720{
1721        unsigned char val;
1722
1723#if defined(__sparc_v9__)
1724#error "You lose, consult DaveM."
1725#elif defined(__sparc__)
1726        /*
1727         * SPARC does not have an "outb" instruction, so we generate
1728         * I/O cycles storing into a reserved memory space at
1729         * physical address 0x3000000
1730         */
1731        unsigned char __iomem *iop;
1732
1733        iop = ioremap(0x3000000, 0x5000);
1734        if (iop == NULL) {
1735                printk(KERN_ERR "iga5000: cannot map I/O\n");
1736                return -ENOMEM;
1737        }
1738
1739        writeb(0x18, iop + 0x46e8);
1740        writeb(0x01, iop + 0x102);
1741        writeb(0x08, iop + 0x46e8);
1742        writeb(EXT_BIU_MISC, iop + 0x3ce);
1743        writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);
1744
1745        iounmap(iop);
1746#else
1747        /*
1748         * Most other machine types are "normal", so
1749         * we use the standard IO-based wakeup.
1750         */
1751        outb(0x18, 0x46e8);
1752        outb(0x01, 0x102);
1753        outb(0x08, 0x46e8);
1754        outb(EXT_BIU_MISC, 0x3ce);
1755        outb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf);
1756#endif
1757
1758        /*
1759         * Allow the CyberPro to accept PCI burst accesses
1760         */
1761        if (cfb->id == ID_CYBERPRO_2010) {
1762                printk(KERN_INFO "%s: NOT enabling PCI bursts\n",
1763                       cfb->fb.fix.id);
1764        } else {
1765                val = cyber2000_grphr(EXT_BUS_CTL, cfb);
1766                if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
1767                        printk(KERN_INFO "%s: enabling PCI bursts\n",
1768                                cfb->fb.fix.id);
1769
1770                        val |= EXT_BUS_CTL_PCIBURST_WRITE;
1771
1772                        if (cfb->id == ID_CYBERPRO_5000)
1773                                val |= EXT_BUS_CTL_PCIBURST_READ;
1774
1775                        cyber2000_grphw(EXT_BUS_CTL, val, cfb);
1776                }
1777        }
1778
1779        return 0;
1780}
1781
1782static int cyberpro_pci_probe(struct pci_dev *dev,
1783                              const struct pci_device_id *id)
1784{
1785        struct cfb_info *cfb;
1786        char name[16];
1787        int err;
1788
1789        sprintf(name, "CyberPro%4X", id->device);
1790
1791        err = pci_enable_device(dev);
1792        if (err)
1793                return err;
1794
1795        err = -ENOMEM;
1796        cfb = cyberpro_alloc_fb_info(id->driver_data, name);
1797        if (!cfb)
1798                goto failed_release;
1799
1800        err = pci_request_regions(dev, cfb->fb.fix.id);
1801        if (err)
1802                goto failed_regions;
1803
1804        cfb->irq = dev->irq;
1805        cfb->region = pci_ioremap_bar(dev, 0);
1806        if (!cfb->region) {
1807                err = -ENOMEM;
1808                goto failed_ioremap;
1809        }
1810
1811        cfb->regs = cfb->region + MMIO_OFFSET;
1812        cfb->fb.device = &dev->dev;
1813        cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
1814        cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
1815
1816        /*
1817         * Bring up the hardware.  This is expected to enable access
1818         * to the linear memory region, and allow access to the memory
1819         * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be
1820         * initialised.
1821         */
1822        err = cyberpro_pci_enable_mmio(cfb);
1823        if (err)
1824                goto failed;
1825
1826        /*
1827         * Use MCLK from BIOS. FIXME: what about hotplug?
1828         */
1829        cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb);
1830        cfb->mclk_div  = cyber2000_grphr(EXT_MCLK_DIV, cfb);
1831
1832#ifdef __arm__
1833        /*
1834         * MCLK on the NetWinder and the Shark is fixed at 75MHz
1835         */
1836        if (machine_is_netwinder()) {
1837                cfb->mclk_mult = 0xdb;
1838                cfb->mclk_div  = 0x54;
1839        }
1840#endif
1841
1842        err = cyberpro_common_probe(cfb);
1843        if (err)
1844                goto failed;
1845
1846        /*
1847         * Our driver data
1848         */
1849        pci_set_drvdata(dev, cfb);
1850        if (int_cfb_info == NULL)
1851                int_cfb_info = cfb;
1852
1853        return 0;
1854
1855failed:
1856        iounmap(cfb->region);
1857failed_ioremap:
1858        pci_release_regions(dev);
1859failed_regions:
1860        cyberpro_free_fb_info(cfb);
1861failed_release:
1862        return err;
1863}
1864
1865static void cyberpro_pci_remove(struct pci_dev *dev)
1866{
1867        struct cfb_info *cfb = pci_get_drvdata(dev);
1868
1869        if (cfb) {
1870                cyberpro_common_remove(cfb);
1871                iounmap(cfb->region);
1872                cyberpro_free_fb_info(cfb);
1873
1874                /*
1875                 * Ensure that the driver data is no longer
1876                 * valid.
1877                 */
1878                pci_set_drvdata(dev, NULL);
1879                if (cfb == int_cfb_info)
1880                        int_cfb_info = NULL;
1881
1882                pci_release_regions(dev);
1883        }
1884}
1885
1886static int cyberpro_pci_suspend(struct pci_dev *dev, pm_message_t state)
1887{
1888        return 0;
1889}
1890
1891/*
1892 * Re-initialise the CyberPro hardware
1893 */
1894static int cyberpro_pci_resume(struct pci_dev *dev)
1895{
1896        struct cfb_info *cfb = pci_get_drvdata(dev);
1897
1898        if (cfb) {
1899                cyberpro_pci_enable_mmio(cfb);
1900                cyberpro_common_resume(cfb);
1901        }
1902
1903        return 0;
1904}
1905
1906static struct pci_device_id cyberpro_pci_table[] = {
1907/*      Not yet
1908 *      { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
1909 *              PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
1910 */
1911        { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
1912                PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
1913        { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
1914                PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 },
1915        { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,
1916                PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 },
1917        { 0, }
1918};
1919
1920MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
1921
1922static struct pci_driver cyberpro_driver = {
1923        .name           = "CyberPro",
1924        .probe          = cyberpro_pci_probe,
1925        .remove         = cyberpro_pci_remove,
1926        .suspend        = cyberpro_pci_suspend,
1927        .resume         = cyberpro_pci_resume,
1928        .id_table       = cyberpro_pci_table
1929};
1930#endif
1931
1932/*
1933 * I don't think we can use the "module_init" stuff here because
1934 * the fbcon stuff may not be initialised yet.  Hence the #ifdef
1935 * around module_init.
1936 *
1937 * Tony: "module_init" is now required
1938 */
1939static int __init cyber2000fb_init(void)
1940{
1941        int ret = -1, err;
1942
1943#ifndef MODULE
1944        char *option = NULL;
1945
1946        if (fb_get_options("cyber2000fb", &option))
1947                return -ENODEV;
1948        cyber2000fb_setup(option);
1949#endif
1950
1951#ifdef CONFIG_ARCH_SHARK
1952        err = cyberpro_vl_probe();
1953        if (!err)
1954                ret = 0;
1955#endif
1956#ifdef CONFIG_PCI
1957        err = pci_register_driver(&cyberpro_driver);
1958        if (!err)
1959                ret = 0;
1960#endif
1961
1962        return ret ? err : 0;
1963}
1964module_init(cyber2000fb_init);
1965
1966#ifndef CONFIG_ARCH_SHARK
1967static void __exit cyberpro_exit(void)
1968{
1969        pci_unregister_driver(&cyberpro_driver);
1970}
1971module_exit(cyberpro_exit);
1972#endif
1973
1974MODULE_AUTHOR("Russell King");
1975MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
1976MODULE_LICENSE("GPL");
1977
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.