linux/drivers/video/nvidia/nvidia.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/video/nvidia/nvidia.c - nVidia fb driver
   3 *
   4 * Copyright 2004 Antonino Daplas <adaplas@pol.net>
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file COPYING in the main directory of this archive
   8 * for more details.
   9 *
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/kernel.h>
  14#include <linux/errno.h>
  15#include <linux/string.h>
  16#include <linux/mm.h>
  17#include <linux/slab.h>
  18#include <linux/delay.h>
  19#include <linux/fb.h>
  20#include <linux/init.h>
  21#include <linux/pci.h>
  22#include <linux/console.h>
  23#include <linux/backlight.h>
  24#ifdef CONFIG_MTRR
  25#include <asm/mtrr.h>
  26#endif
  27#ifdef CONFIG_PPC_OF
  28#include <asm/prom.h>
  29#include <asm/pci-bridge.h>
  30#endif
  31#ifdef CONFIG_BOOTX_TEXT
  32#include <asm/btext.h>
  33#endif
  34
  35#include "nv_local.h"
  36#include "nv_type.h"
  37#include "nv_proto.h"
  38#include "nv_dma.h"
  39
  40#ifdef CONFIG_FB_NVIDIA_DEBUG
  41#define NVTRACE          printk
  42#else
  43#define NVTRACE          if (0) printk
  44#endif
  45
  46#define NVTRACE_ENTER(...)  NVTRACE("%s START\n", __func__)
  47#define NVTRACE_LEAVE(...)  NVTRACE("%s END\n", __func__)
  48
  49#ifdef CONFIG_FB_NVIDIA_DEBUG
  50#define assert(expr) \
  51        if (!(expr)) { \
  52        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
  53        #expr,__FILE__,__func__,__LINE__); \
  54        BUG(); \
  55        }
  56#else
  57#define assert(expr)
  58#endif
  59
  60#define PFX "nvidiafb: "
  61
  62/* HW cursor parameters */
  63#define MAX_CURS                32
  64
  65static struct pci_device_id nvidiafb_pci_tbl[] = {
  66        {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
  67         PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
  68        { 0, }
  69};
  70MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
  71
  72/* command line data, set in nvidiafb_setup() */
  73static int flatpanel __devinitdata = -1;        /* Autodetect later */
  74static int fpdither __devinitdata = -1;
  75static int forceCRTC __devinitdata = -1;
  76static int hwcur __devinitdata = 0;
  77static int noaccel __devinitdata = 0;
  78static int noscale __devinitdata = 0;
  79static int paneltweak __devinitdata = 0;
  80static int vram __devinitdata = 0;
  81static int bpp __devinitdata = 8;
  82static int reverse_i2c __devinitdata;
  83#ifdef CONFIG_MTRR
  84static int nomtrr __devinitdata = 0;
  85#endif
  86#ifdef CONFIG_PMAC_BACKLIGHT
  87static int backlight __devinitdata = 1;
  88#else
  89static int backlight __devinitdata = 0;
  90#endif
  91
  92static char *mode_option __devinitdata = NULL;
  93
  94static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
  95        .type = FB_TYPE_PACKED_PIXELS,
  96        .xpanstep = 8,
  97        .ypanstep = 1,
  98};
  99
 100static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
 101        .xres = 640,
 102        .yres = 480,
 103        .xres_virtual = 640,
 104        .yres_virtual = 480,
 105        .bits_per_pixel = 8,
 106        .red = {0, 8, 0},
 107        .green = {0, 8, 0},
 108        .blue = {0, 8, 0},
 109        .transp = {0, 0, 0},
 110        .activate = FB_ACTIVATE_NOW,
 111        .height = -1,
 112        .width = -1,
 113        .pixclock = 39721,
 114        .left_margin = 40,
 115        .right_margin = 24,
 116        .upper_margin = 32,
 117        .lower_margin = 11,
 118        .hsync_len = 96,
 119        .vsync_len = 2,
 120        .vmode = FB_VMODE_NONINTERLACED
 121};
 122
 123static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
 124                                       u16 bg, u16 fg, u32 w, u32 h)
 125{
 126        u32 *data = (u32 *) data8;
 127        int i, j, k = 0;
 128        u32 b, tmp;
 129
 130        w = (w + 1) & ~1;
 131
 132        for (i = 0; i < h; i++) {
 133                b = *data++;
 134                reverse_order(&b);
 135
 136                for (j = 0; j < w / 2; j++) {
 137                        tmp = 0;
 138#if defined (__BIG_ENDIAN)
 139                        tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
 140                        b <<= 1;
 141                        tmp |= (b & (1 << 31)) ? fg : bg;
 142                        b <<= 1;
 143#else
 144                        tmp = (b & 1) ? fg : bg;
 145                        b >>= 1;
 146                        tmp |= (b & 1) ? fg << 16 : bg << 16;
 147                        b >>= 1;
 148#endif
 149                        NV_WR32(&par->CURSOR[k++], 0, tmp);
 150                }
 151                k += (MAX_CURS - w) / 2;
 152        }
 153}
 154
 155static void nvidia_write_clut(struct nvidia_par *par,
 156                              u8 regnum, u8 red, u8 green, u8 blue)
 157{
 158        NVWriteDacMask(par, 0xff);
 159        NVWriteDacWriteAddr(par, regnum);
 160        NVWriteDacData(par, red);
 161        NVWriteDacData(par, green);
 162        NVWriteDacData(par, blue);
 163}
 164
 165static void nvidia_read_clut(struct nvidia_par *par,
 166                             u8 regnum, u8 * red, u8 * green, u8 * blue)
 167{
 168        NVWriteDacMask(par, 0xff);
 169        NVWriteDacReadAddr(par, regnum);
 170        *red = NVReadDacData(par);
 171        *green = NVReadDacData(par);
 172        *blue = NVReadDacData(par);
 173}
 174
 175static int nvidia_panel_tweak(struct nvidia_par *par,
 176                              struct _riva_hw_state *state)
 177{
 178        int tweak = 0;
 179
 180   if (par->paneltweak) {
 181           tweak = par->paneltweak;
 182   } else {
 183           /* begin flat panel hacks */
 184           /* This is unfortunate, but some chips need this register
 185              tweaked or else you get artifacts where adjacent pixels are
 186              swapped.  There are no hard rules for what to set here so all
 187              we can do is experiment and apply hacks. */
 188
 189           if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
 190                   /* At least one NV34 laptop needs this workaround. */
 191                   tweak = -1;
 192           }
 193
 194           if((par->Chipset & 0xfff0) == 0x0310) {
 195                   tweak = 1;
 196           }
 197           /* end flat panel hacks */
 198   }
 199
 200   return tweak;
 201}
 202
 203static void nvidia_screen_off(struct nvidia_par *par, int on)
 204{
 205        unsigned char tmp;
 206
 207        if (on) {
 208                /*
 209                 * Turn off screen and disable sequencer.
 210                 */
 211                tmp = NVReadSeq(par, 0x01);
 212
 213                NVWriteSeq(par, 0x00, 0x01);            /* Synchronous Reset */
 214                NVWriteSeq(par, 0x01, tmp | 0x20);      /* disable the display */
 215        } else {
 216                /*
 217                 * Reenable sequencer, then turn on screen.
 218                 */
 219
 220                tmp = NVReadSeq(par, 0x01);
 221
 222                NVWriteSeq(par, 0x01, tmp & ~0x20);     /* reenable display */
 223                NVWriteSeq(par, 0x00, 0x03);            /* End Reset */
 224        }
 225}
 226
 227static void nvidia_save_vga(struct nvidia_par *par,
 228                            struct _riva_hw_state *state)
 229{
 230        int i;
 231
 232        NVTRACE_ENTER();
 233        NVLockUnlock(par, 0);
 234
 235        NVUnloadStateExt(par, state);
 236
 237        state->misc_output = NVReadMiscOut(par);
 238
 239        for (i = 0; i < NUM_CRT_REGS; i++)
 240                state->crtc[i] = NVReadCrtc(par, i);
 241
 242        for (i = 0; i < NUM_ATC_REGS; i++)
 243                state->attr[i] = NVReadAttr(par, i);
 244
 245        for (i = 0; i < NUM_GRC_REGS; i++)
 246                state->gra[i] = NVReadGr(par, i);
 247
 248        for (i = 0; i < NUM_SEQ_REGS; i++)
 249                state->seq[i] = NVReadSeq(par, i);
 250        NVTRACE_LEAVE();
 251}
 252
 253#undef DUMP_REG
 254
 255static void nvidia_write_regs(struct nvidia_par *par,
 256                              struct _riva_hw_state *state)
 257{
 258        int i;
 259
 260        NVTRACE_ENTER();
 261
 262        NVLoadStateExt(par, state);
 263
 264        NVWriteMiscOut(par, state->misc_output);
 265
 266        for (i = 1; i < NUM_SEQ_REGS; i++) {
 267#ifdef DUMP_REG
 268                printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
 269#endif
 270                NVWriteSeq(par, i, state->seq[i]);
 271        }
 272
 273        /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
 274        NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
 275
 276        for (i = 0; i < NUM_CRT_REGS; i++) {
 277                switch (i) {
 278                case 0x19:
 279                case 0x20 ... 0x40:
 280                        break;
 281                default:
 282#ifdef DUMP_REG
 283                        printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
 284#endif
 285                        NVWriteCrtc(par, i, state->crtc[i]);
 286                }
 287        }
 288
 289        for (i = 0; i < NUM_GRC_REGS; i++) {
 290#ifdef DUMP_REG
 291                printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
 292#endif
 293                NVWriteGr(par, i, state->gra[i]);
 294        }
 295
 296        for (i = 0; i < NUM_ATC_REGS; i++) {
 297#ifdef DUMP_REG
 298                printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
 299#endif
 300                NVWriteAttr(par, i, state->attr[i]);
 301        }
 302
 303        NVTRACE_LEAVE();
 304}
 305
 306static int nvidia_calc_regs(struct fb_info *info)
 307{
 308        struct nvidia_par *par = info->par;
 309        struct _riva_hw_state *state = &par->ModeReg;
 310        int i, depth = fb_get_color_depth(&info->var, &info->fix);
 311        int h_display = info->var.xres / 8 - 1;
 312        int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
 313        int h_end = (info->var.xres + info->var.right_margin +
 314                     info->var.hsync_len) / 8 - 1;
 315        int h_total = (info->var.xres + info->var.right_margin +
 316                       info->var.hsync_len + info->var.left_margin) / 8 - 5;
 317        int h_blank_s = h_display;
 318        int h_blank_e = h_total + 4;
 319        int v_display = info->var.yres - 1;
 320        int v_start = info->var.yres + info->var.lower_margin - 1;
 321        int v_end = (info->var.yres + info->var.lower_margin +
 322                     info->var.vsync_len) - 1;
 323        int v_total = (info->var.yres + info->var.lower_margin +
 324                       info->var.vsync_len + info->var.upper_margin) - 2;
 325        int v_blank_s = v_display;
 326        int v_blank_e = v_total + 1;
 327
 328        /*
 329         * Set all CRTC values.
 330         */
 331
 332        if (info->var.vmode & FB_VMODE_INTERLACED)
 333                v_total |= 1;
 334
 335        if (par->FlatPanel == 1) {
 336                v_start = v_total - 3;
 337                v_end = v_total - 2;
 338                v_blank_s = v_start;
 339                h_start = h_total - 5;
 340                h_end = h_total - 2;
 341                h_blank_e = h_total + 4;
 342        }
 343
 344        state->crtc[0x0] = Set8Bits(h_total);
 345        state->crtc[0x1] = Set8Bits(h_display);
 346        state->crtc[0x2] = Set8Bits(h_blank_s);
 347        state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0)
 348                | SetBit(7);
 349        state->crtc[0x4] = Set8Bits(h_start);
 350        state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7)
 351                | SetBitField(h_end, 4: 0, 4:0);
 352        state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0);
 353        state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0)
 354                | SetBitField(v_display, 8: 8, 1:1)
 355                | SetBitField(v_start, 8: 8, 2:2)
 356                | SetBitField(v_blank_s, 8: 8, 3:3)
 357                | SetBit(4)
 358                | SetBitField(v_total, 9: 9, 5:5)
 359                | SetBitField(v_display, 9: 9, 6:6)
 360                | SetBitField(v_start, 9: 9, 7:7);
 361        state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5)
 362                | SetBit(6)
 363                | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00);
 364        state->crtc[0x10] = Set8Bits(v_start);
 365        state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5);
 366        state->crtc[0x12] = Set8Bits(v_display);
 367        state->crtc[0x13] = ((info->var.xres_virtual / 8) *
 368                             (info->var.bits_per_pixel / 8));
 369        state->crtc[0x15] = Set8Bits(v_blank_s);
 370        state->crtc[0x16] = Set8Bits(v_blank_e);
 371
 372        state->attr[0x10] = 0x01;
 373
 374        if (par->Television)
 375                state->attr[0x11] = 0x00;
 376
 377        state->screen = SetBitField(h_blank_e, 6: 6, 4:4)
 378                | SetBitField(v_blank_s, 10: 10, 3:3)
 379                | SetBitField(v_start, 10: 10, 2:2)
 380                | SetBitField(v_display, 10: 10, 1:1)
 381                | SetBitField(v_total, 10: 10, 0:0);
 382
 383        state->horiz = SetBitField(h_total, 8: 8, 0:0)
 384                | SetBitField(h_display, 8: 8, 1:1)
 385                | SetBitField(h_blank_s, 8: 8, 2:2)
 386                | SetBitField(h_start, 8: 8, 3:3);
 387
 388        state->extra = SetBitField(v_total, 11: 11, 0:0)
 389                | SetBitField(v_display, 11: 11, 2:2)
 390                | SetBitField(v_start, 11: 11, 4:4)
 391                | SetBitField(v_blank_s, 11: 11, 6:6);
 392
 393        if (info->var.vmode & FB_VMODE_INTERLACED) {
 394                h_total = (h_total >> 1) & ~1;
 395                state->interlace = Set8Bits(h_total);
 396                state->horiz |= SetBitField(h_total, 8: 8, 4:4);
 397        } else {
 398                state->interlace = 0xff;        /* interlace off */
 399        }
 400
 401        /*
 402         * Calculate the extended registers.
 403         */
 404
 405        if (depth < 24)
 406                i = depth;
 407        else
 408                i = 32;
 409
 410        if (par->Architecture >= NV_ARCH_10)
 411                par->CURSOR = (volatile u32 __iomem *)(info->screen_base +
 412                                                       par->CursorStart);
 413
 414        if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
 415                state->misc_output &= ~0x40;
 416        else
 417                state->misc_output |= 0x40;
 418        if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
 419                state->misc_output &= ~0x80;
 420        else
 421                state->misc_output |= 0x80;
 422
 423        NVCalcStateExt(par, state, i, info->var.xres_virtual,
 424                       info->var.xres, info->var.yres_virtual,
 425                       1000000000 / info->var.pixclock, info->var.vmode);
 426
 427        state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff;
 428        if (par->FlatPanel == 1) {
 429                state->pixel |= (1 << 7);
 430
 431                if (!par->fpScaler || (par->fpWidth <= info->var.xres)
 432                    || (par->fpHeight <= info->var.yres)) {
 433                        state->scale |= (1 << 8);
 434                }
 435
 436                if (!par->crtcSync_read) {
 437                        state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828);
 438                        par->crtcSync_read = 1;
 439                }
 440
 441                par->PanelTweak = nvidia_panel_tweak(par, state);
 442        }
 443
 444        state->vpll = state->pll;
 445        state->vpll2 = state->pll;
 446        state->vpllB = state->pllB;
 447        state->vpll2B = state->pllB;
 448
 449        VGA_WR08(par->PCIO, 0x03D4, 0x1C);
 450        state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5);
 451
 452        if (par->CRTCnumber) {
 453                state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000;
 454                state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000;
 455                state->crtcOwner = 3;
 456                state->pllsel |= 0x20000800;
 457                state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508);
 458                if (par->twoStagePLL)
 459                        state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578);
 460        } else if (par->twoHeads) {
 461                state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000;
 462                state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000;
 463                state->crtcOwner = 0;
 464                state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
 465                if (par->twoStagePLL)
 466                        state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
 467        }
 468
 469        state->cursorConfig = 0x00000100;
 470
 471        if (info->var.vmode & FB_VMODE_DOUBLE)
 472                state->cursorConfig |= (1 << 4);
 473
 474        if (par->alphaCursor) {
 475                if ((par->Chipset & 0x0ff0) != 0x0110)
 476                        state->cursorConfig |= 0x04011000;
 477                else
 478                        state->cursorConfig |= 0x14011000;
 479                state->general |= (1 << 29);
 480        } else
 481                state->cursorConfig |= 0x02000000;
 482
 483        if (par->twoHeads) {
 484                if ((par->Chipset & 0x0ff0) == 0x0110) {
 485                        state->dither = NV_RD32(par->PRAMDAC, 0x0528) &
 486                            ~0x00010000;
 487                        if (par->FPDither)
 488                                state->dither |= 0x00010000;
 489                } else {
 490                        state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1;
 491                        if (par->FPDither)
 492                                state->dither |= 1;
 493                }
 494        }
 495
 496        state->timingH = 0;
 497        state->timingV = 0;
 498        state->displayV = info->var.xres;
 499
 500        return 0;
 501}
 502
 503static void nvidia_init_vga(struct fb_info *info)
 504{
 505        struct nvidia_par *par = info->par;
 506        struct _riva_hw_state *state = &par->ModeReg;
 507        int i;
 508
 509        for (i = 0; i < 0x10; i++)
 510                state->attr[i] = i;
 511        state->attr[0x10] = 0x41;
 512        state->attr[0x11] = 0xff;
 513        state->attr[0x12] = 0x0f;
 514        state->attr[0x13] = 0x00;
 515        state->attr[0x14] = 0x00;
 516
 517        memset(state->crtc, 0x00, NUM_CRT_REGS);
 518        state->crtc[0x0a] = 0x20;
 519        state->crtc[0x17] = 0xe3;
 520        state->crtc[0x18] = 0xff;
 521        state->crtc[0x28] = 0x40;
 522
 523        memset(state->gra, 0x00, NUM_GRC_REGS);
 524        state->gra[0x05] = 0x40;
 525        state->gra[0x06] = 0x05;
 526        state->gra[0x07] = 0x0f;
 527        state->gra[0x08] = 0xff;
 528
 529        state->seq[0x00] = 0x03;
 530        state->seq[0x01] = 0x01;
 531        state->seq[0x02] = 0x0f;
 532        state->seq[0x03] = 0x00;
 533        state->seq[0x04] = 0x0e;
 534
 535        state->misc_output = 0xeb;
 536}
 537
 538static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 539{
 540        struct nvidia_par *par = info->par;
 541        u8 data[MAX_CURS * MAX_CURS / 8];
 542        int i, set = cursor->set;
 543        u16 fg, bg;
 544
 545        if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
 546                return -ENXIO;
 547
 548        NVShowHideCursor(par, 0);
 549
 550        if (par->cursor_reset) {
 551                set = FB_CUR_SETALL;
 552                par->cursor_reset = 0;
 553        }
 554
 555        if (set & FB_CUR_SETSIZE)
 556                memset_io(par->CURSOR, 0, MAX_CURS * MAX_CURS * 2);
 557
 558        if (set & FB_CUR_SETPOS) {
 559                u32 xx, yy, temp;
 560
 561                yy = cursor->image.dy - info->var.yoffset;
 562                xx = cursor->image.dx - info->var.xoffset;
 563                temp = xx & 0xFFFF;
 564                temp |= yy << 16;
 565
 566                NV_WR32(par->PRAMDAC, 0x0000300, temp);
 567        }
 568
 569        if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
 570                u32 bg_idx = cursor->image.bg_color;
 571                u32 fg_idx = cursor->image.fg_color;
 572                u32 s_pitch = (cursor->image.width + 7) >> 3;
 573                u32 d_pitch = MAX_CURS / 8;
 574                u8 *dat = (u8 *) cursor->image.data;
 575                u8 *msk = (u8 *) cursor->mask;
 576                u8 *src;
 577
 578                src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
 579
 580                if (src) {
 581                        switch (cursor->rop) {
 582                        case ROP_XOR:
 583                                for (i = 0; i < s_pitch * cursor->image.height; i++)
 584                                        src[i] = dat[i] ^ msk[i];
 585                                break;
 586                        case ROP_COPY:
 587                        default:
 588                                for (i = 0; i < s_pitch * cursor->image.height; i++)
 589                                        src[i] = dat[i] & msk[i];
 590                                break;
 591                        }
 592
 593                        fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
 594                                                cursor->image.height);
 595
 596                        bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
 597                            ((info->cmap.green[bg_idx] & 0xf8) << 2) |
 598                            ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
 599
 600                        fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
 601                            ((info->cmap.green[fg_idx] & 0xf8) << 2) |
 602                            ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
 603
 604                        NVLockUnlock(par, 0);
 605
 606                        nvidiafb_load_cursor_image(par, data, bg, fg,
 607                                                   cursor->image.width,
 608                                                   cursor->image.height);
 609                        kfree(src);
 610                }
 611        }
 612
 613        if (cursor->enable)
 614                NVShowHideCursor(par, 1);
 615
 616        return 0;
 617}
 618
 619static int nvidiafb_set_par(struct fb_info *info)
 620{
 621        struct nvidia_par *par = info->par;
 622
 623        NVTRACE_ENTER();
 624
 625        NVLockUnlock(par, 1);
 626        if (!par->FlatPanel || !par->twoHeads)
 627                par->FPDither = 0;
 628
 629        if (par->FPDither < 0) {
 630                if ((par->Chipset & 0x0ff0) == 0x0110)
 631                        par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
 632                                           & 0x00010000);
 633                else
 634                        par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
 635                printk(KERN_INFO PFX "Flat panel dithering %s\n",
 636                       par->FPDither ? "enabled" : "disabled");
 637        }
 638
 639        info->fix.visual = (info->var.bits_per_pixel == 8) ?
 640            FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 641
 642        nvidia_init_vga(info);
 643        nvidia_calc_regs(info);
 644
 645        NVLockUnlock(par, 0);
 646        if (par->twoHeads) {
 647                VGA_WR08(par->PCIO, 0x03D4, 0x44);
 648                VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);
 649                NVLockUnlock(par, 0);
 650        }
 651
 652        nvidia_screen_off(par, 1);
 653
 654        nvidia_write_regs(par, &par->ModeReg);
 655        NVSetStartAddress(par, 0);
 656
 657#if defined (__BIG_ENDIAN)
 658        /* turn on LFB swapping */
 659        {
 660                unsigned char tmp;
 661
 662                VGA_WR08(par->PCIO, 0x3d4, 0x46);
 663                tmp = VGA_RD08(par->PCIO, 0x3d5);
 664                tmp |= (1 << 7);
 665                VGA_WR08(par->PCIO, 0x3d5, tmp);
 666    }
 667#endif
 668
 669        info->fix.line_length = (info->var.xres_virtual *
 670                                 info->var.bits_per_pixel) >> 3;
 671        if (info->var.accel_flags) {
 672                info->fbops->fb_imageblit = nvidiafb_imageblit;
 673                info->fbops->fb_fillrect = nvidiafb_fillrect;
 674                info->fbops->fb_copyarea = nvidiafb_copyarea;
 675                info->fbops->fb_sync = nvidiafb_sync;
 676                info->pixmap.scan_align = 4;
 677                info->flags &= ~FBINFO_HWACCEL_DISABLED;
 678                info->flags |= FBINFO_READS_FAST;
 679                NVResetGraphics(info);
 680        } else {
 681                info->fbops->fb_imageblit = cfb_imageblit;
 682                info->fbops->fb_fillrect = cfb_fillrect;
 683                info->fbops->fb_copyarea = cfb_copyarea;
 684                info->fbops->fb_sync = NULL;
 685                info->pixmap.scan_align = 1;
 686                info->flags |= FBINFO_HWACCEL_DISABLED;
 687                info->flags &= ~FBINFO_READS_FAST;
 688        }
 689
 690        par->cursor_reset = 1;
 691
 692        nvidia_screen_off(par, 0);
 693
 694#ifdef CONFIG_BOOTX_TEXT
 695        /* Update debug text engine */
 696        btext_update_display(info->fix.smem_start,
 697                             info->var.xres, info->var.yres,
 698                             info->var.bits_per_pixel, info->fix.line_length);
 699#endif
 700
 701        NVLockUnlock(par, 0);
 702        NVTRACE_LEAVE();
 703        return 0;
 704}
 705
 706static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,
 707                              unsigned blue, unsigned transp,
 708                              struct fb_info *info)
 709{
 710        struct nvidia_par *par = info->par;
 711        int i;
 712
 713        NVTRACE_ENTER();
 714        if (regno >= (1 << info->var.green.length))
 715                return -EINVAL;
 716
 717        if (info->var.grayscale) {
 718                /* gray = 0.30*R + 0.59*G + 0.11*B */
 719                red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
 720        }
 721
 722        if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 723                ((u32 *) info->pseudo_palette)[regno] =
 724                    (regno << info->var.red.offset) |
 725                    (regno << info->var.green.offset) |
 726                    (regno << info->var.blue.offset);
 727        }
 728
 729        switch (info->var.bits_per_pixel) {
 730        case 8:
 731                /* "transparent" stuff is completely ignored. */
 732                nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
 733                break;
 734        case 16:
 735                if (info->var.green.length == 5) {
 736                        for (i = 0; i < 8; i++) {
 737                                nvidia_write_clut(par, regno * 8 + i, red >> 8,
 738                                                  green >> 8, blue >> 8);
 739                        }
 740                } else {
 741                        u8 r, g, b;
 742
 743                        if (regno < 32) {
 744                                for (i = 0; i < 8; i++) {
 745                                        nvidia_write_clut(par, regno * 8 + i,
 746                                                          red >> 8, green >> 8,
 747                                                          blue >> 8);
 748                                }
 749                        }
 750
 751                        nvidia_read_clut(par, regno * 4, &r, &g, &b);
 752
 753                        for (i = 0; i < 4; i++)
 754                                nvidia_write_clut(par, regno * 4 + i, r,
 755                                                  green >> 8, b);
 756                }
 757                break;
 758        case 32:
 759                nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);
 760                break;
 761        default:
 762                /* do nothing */
 763                break;
 764        }
 765
 766        NVTRACE_LEAVE();
 767        return 0;
 768}
 769
 770static int nvidiafb_check_var(struct fb_var_screeninfo *var,
 771                              struct fb_info *info)
 772{
 773        struct nvidia_par *par = info->par;
 774        int memlen, vramlen, mode_valid = 0;
 775        int pitch, err = 0;
 776
 777        NVTRACE_ENTER();
 778
 779        var->transp.offset = 0;
 780        var->transp.length = 0;
 781
 782        var->xres &= ~7;
 783
 784        if (var->bits_per_pixel <= 8)
 785                var->bits_per_pixel = 8;
 786        else if (var->bits_per_pixel <= 16)
 787                var->bits_per_pixel = 16;
 788        else
 789                var->bits_per_pixel = 32;
 790
 791        switch (var->bits_per_pixel) {
 792        case 8:
 793                var->red.offset = 0;
 794                var->red.length = 8;
 795                var->green.offset = 0;
 796                var->green.length = 8;
 797                var->blue.offset = 0;
 798                var->blue.length = 8;
 799                var->transp.offset = 0;
 800                var->transp.length = 0;
 801                break;
 802        case 16:
 803                var->green.length = (var->green.length < 6) ? 5 : 6;
 804                var->red.length = 5;
 805                var->blue.length = 5;
 806                var->transp.length = 6 - var->green.length;
 807                var->blue.offset = 0;
 808                var->green.offset = 5;
 809                var->red.offset = 5 + var->green.length;
 810                var->transp.offset = (5 + var->red.offset) & 15;
 811                break;
 812        case 32:                /* RGBA 8888 */
 813                var->red.offset = 16;
 814                var->red.length = 8;
 815                var->green.offset = 8;
 816                var->green.length = 8;
 817                var->blue.offset = 0;
 818                var->blue.length = 8;
 819                var->transp.length = 8;
 820                var->transp.offset = 24;
 821                break;
 822        }
 823
 824        var->red.msb_right = 0;
 825        var->green.msb_right = 0;
 826        var->blue.msb_right = 0;
 827        var->transp.msb_right = 0;
 828
 829        if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
 830            !info->monspecs.dclkmax || !fb_validate_mode(var, info))
 831                mode_valid = 1;
 832
 833        /* calculate modeline if supported by monitor */
 834        if (!mode_valid && info->monspecs.gtf) {
 835                if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
 836                        mode_valid = 1;
 837        }
 838
 839        if (!mode_valid) {
 840                const struct fb_videomode *mode;
 841
 842                mode = fb_find_best_mode(var, &info->modelist);
 843                if (mode) {
 844                        fb_videomode_to_var(var, mode);
 845                        mode_valid = 1;
 846                }
 847        }
 848
 849        if (!mode_valid && info->monspecs.modedb_len)
 850                return -EINVAL;
 851
 852        /*
 853         * If we're on a flat panel, check if the mode is outside of the
 854         * panel dimensions. If so, cap it and try for the next best mode
 855         * before bailing out.
 856         */
 857        if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
 858                                              par->fpHeight < var->yres)) {
 859                const struct fb_videomode *mode;
 860
 861                var->xres = par->fpWidth;
 862                var->yres = par->fpHeight;
 863
 864                mode = fb_find_best_mode(var, &info->modelist);
 865                if (!mode) {
 866                        printk(KERN_ERR PFX "mode out of range of flat "
 867                               "panel dimensions\n");
 868                        return -EINVAL;
 869                }
 870
 871                fb_videomode_to_var(var, mode);
 872        }
 873
 874        if (var->yres_virtual < var->yres)
 875                var->yres_virtual = var->yres;
 876
 877        if (var->xres_virtual < var->xres)
 878                var->xres_virtual = var->xres;
 879
 880        var->xres_virtual = (var->xres_virtual + 63) & ~63;
 881
 882        vramlen = info->screen_size;
 883        pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;
 884        memlen = pitch * var->yres_virtual;
 885
 886        if (memlen > vramlen) {
 887                var->yres_virtual = vramlen / pitch;
 888
 889                if (var->yres_virtual < var->yres) {
 890                        var->yres_virtual = var->yres;
 891                        var->xres_virtual = vramlen / var->yres_virtual;
 892                        var->xres_virtual /= var->bits_per_pixel / 8;
 893                        var->xres_virtual &= ~63;
 894                        pitch = (var->xres_virtual *
 895                                 var->bits_per_pixel + 7) / 8;
 896                        memlen = pitch * var->yres;
 897
 898                        if (var->xres_virtual < var->xres) {
 899                                printk("nvidiafb: required video memory, "
 900                                       "%d bytes, for %dx%d-%d (virtual) "
 901                                       "is out of range\n",
 902                                       memlen, var->xres_virtual,
 903                                       var->yres_virtual, var->bits_per_pixel);
 904                                err = -ENOMEM;
 905                        }
 906                }
 907        }
 908
 909        if (var->accel_flags) {
 910                if (var->yres_virtual > 0x7fff)
 911                        var->yres_virtual = 0x7fff;
 912                if (var->xres_virtual > 0x7fff)
 913                        var->xres_virtual = 0x7fff;
 914        }
 915
 916        var->xres_virtual &= ~63;
 917
 918        NVTRACE_LEAVE();
 919
 920        return err;
 921}
 922
 923static int nvidiafb_pan_display(struct fb_var_screeninfo *var,
 924                                struct fb_info *info)
 925{
 926        struct nvidia_par *par = info->par;
 927        u32 total;
 928
 929        total = var->yoffset * info->fix.line_length + var->xoffset;
 930
 931        NVSetStartAddress(par, total);
 932
 933        return 0;
 934}
 935
 936static int nvidiafb_blank(int blank, struct fb_info *info)
 937{
 938        struct nvidia_par *par = info->par;
 939        unsigned char tmp, vesa;
 940
 941        tmp = NVReadSeq(par, 0x01) & ~0x20;     /* screen on/off */
 942        vesa = NVReadCrtc(par, 0x1a) & ~0xc0;   /* sync on/off */
 943
 944        NVTRACE_ENTER();
 945
 946        if (blank)
 947                tmp |= 0x20;
 948
 949        switch (blank) {
 950        case FB_BLANK_UNBLANK:
 951        case FB_BLANK_NORMAL:
 952                break;
 953        case FB_BLANK_VSYNC_SUSPEND:
 954                vesa |= 0x80;
 955                break;
 956        case FB_BLANK_HSYNC_SUSPEND:
 957                vesa |= 0x40;
 958                break;
 959        case FB_BLANK_POWERDOWN:
 960                vesa |= 0xc0;
 961                break;
 962        }
 963
 964        NVWriteSeq(par, 0x01, tmp);
 965        NVWriteCrtc(par, 0x1a, vesa);
 966
 967        NVTRACE_LEAVE();
 968
 969        return 0;
 970}
 971
 972/*
 973 * Because the VGA registers are not mapped linearly in its MMIO space,
 974 * restrict VGA register saving and restore to x86 only, where legacy VGA IO
 975 * access is legal. Consequently, we must also check if the device is the
 976 * primary display.
 977 */
 978#ifdef CONFIG_X86
 979static void save_vga_x86(struct nvidia_par *par)
 980{
 981        struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
 982
 983        if (res && res->flags & IORESOURCE_ROM_SHADOW) {
 984                memset(&par->vgastate, 0, sizeof(par->vgastate));
 985                par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
 986                        VGA_SAVE_CMAP;
 987                save_vga(&par->vgastate);
 988        }
 989}
 990
 991static void restore_vga_x86(struct nvidia_par *par)
 992{
 993        struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
 994
 995        if (res && res->flags & IORESOURCE_ROM_SHADOW)
 996                restore_vga(&par->vgastate);
 997}
 998#else
 999#define save_vga_x86(x) do {} while (0)
1000#define restore_vga_x86(x) do {} while (0)
1001#endif /* X86 */
1002
1003static int nvidiafb_open(struct fb_info *info, int user)
1004{
1005        struct nvidia_par *par = info->par;
1006
1007        if (!par->open_count) {
1008                save_vga_x86(par);
1009                nvidia_save_vga(par, &par->initial_state);
1010        }
1011
1012        par->open_count++;
1013        return 0;
1014}
1015
1016static int nvidiafb_release(struct fb_info *info, int user)
1017{
1018        struct nvidia_par *par = info->par;
1019        int err = 0;
1020
1021        if (!par->open_count) {
1022                err = -EINVAL;
1023                goto done;
1024        }
1025
1026        if (par->open_count == 1) {
1027                nvidia_write_regs(par, &par->initial_state);
1028                restore_vga_x86(par);
1029        }
1030
1031        par->open_count--;
1032done:
1033        return err;
1034}
1035
1036static struct fb_ops nvidia_fb_ops = {
1037        .owner          = THIS_MODULE,
1038        .fb_open        = nvidiafb_open,
1039        .fb_release     = nvidiafb_release,
1040        .fb_check_var   = nvidiafb_check_var,
1041        .fb_set_par     = nvidiafb_set_par,
1042        .fb_setcolreg   = nvidiafb_setcolreg,
1043        .fb_pan_display = nvidiafb_pan_display,
1044        .fb_blank       = nvidiafb_blank,
1045        .fb_fillrect    = nvidiafb_fillrect,
1046        .fb_copyarea    = nvidiafb_copyarea,
1047        .fb_imageblit   = nvidiafb_imageblit,
1048        .fb_cursor      = nvidiafb_cursor,
1049        .fb_sync        = nvidiafb_sync,
1050};
1051
1052#ifdef CONFIG_PM
1053static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
1054{
1055        struct fb_info *info = pci_get_drvdata(dev);
1056        struct nvidia_par *par = info->par;
1057
1058        if (mesg.event == PM_EVENT_PRETHAW)
1059                mesg.event = PM_EVENT_FREEZE;
1060        acquire_console_sem();
1061        par->pm_state = mesg.event;
1062
1063        if (mesg.event & PM_EVENT_SLEEP) {
1064                fb_set_suspend(info, 1);
1065                nvidiafb_blank(FB_BLANK_POWERDOWN, info);
1066                nvidia_write_regs(par, &par->SavedReg);
1067                pci_save_state(dev);
1068                pci_disable_device(dev);
1069                pci_set_power_state(dev, pci_choose_state(dev, mesg));
1070        }
1071        dev->dev.power.power_state = mesg;
1072
1073        release_console_sem();
1074        return 0;
1075}
1076
1077static int nvidiafb_resume(struct pci_dev *dev)
1078{
1079        struct fb_info *info = pci_get_drvdata(dev);
1080        struct nvidia_par *par = info->par;
1081
1082        acquire_console_sem();
1083        pci_set_power_state(dev, PCI_D0);
1084
1085        if (par->pm_state != PM_EVENT_FREEZE) {
1086                pci_restore_state(dev);
1087
1088                if (pci_enable_device(dev))
1089                        goto fail;
1090
1091                pci_set_master(dev);
1092        }
1093
1094        par->pm_state = PM_EVENT_ON;
1095        nvidiafb_set_par(info);
1096        fb_set_suspend (info, 0);
1097        nvidiafb_blank(FB_BLANK_UNBLANK, info);
1098
1099fail:
1100        release_console_sem();
1101        return 0;
1102}
1103#else
1104#define nvidiafb_suspend NULL
1105#define nvidiafb_resume NULL
1106#endif
1107
1108static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1109{
1110        struct fb_monspecs *specs = &info->monspecs;
1111        struct fb_videomode modedb;
1112        struct nvidia_par *par = info->par;
1113        int lpitch;
1114
1115        NVTRACE_ENTER();
1116        info->flags = FBINFO_DEFAULT
1117            | FBINFO_HWACCEL_IMAGEBLIT
1118            | FBINFO_HWACCEL_FILLRECT
1119            | FBINFO_HWACCEL_COPYAREA
1120            | FBINFO_HWACCEL_YPAN;
1121
1122        fb_videomode_to_modelist(info->monspecs.modedb,
1123                                 info->monspecs.modedb_len, &info->modelist);
1124        fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1125
1126        switch (bpp) {
1127        case 0 ... 8:
1128                bpp = 8;
1129                break;
1130        case 9 ... 16:
1131                bpp = 16;
1132                break;
1133        default:
1134                bpp = 32;
1135                break;
1136        }
1137
1138        if (specs->modedb != NULL) {
1139                const struct fb_videomode *mode;
1140
1141                mode = fb_find_best_display(specs, &info->modelist);
1142                fb_videomode_to_var(&nvidiafb_default_var, mode);
1143                nvidiafb_default_var.bits_per_pixel = bpp;
1144        } else if (par->fpWidth && par->fpHeight) {
1145                char buf[16];
1146
1147                memset(buf, 0, 16);
1148                snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
1149                fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
1150                             specs->modedb_len, &modedb, bpp);
1151        }
1152
1153        if (mode_option)
1154                fb_find_mode(&nvidiafb_default_var, info, mode_option,
1155                             specs->modedb, specs->modedb_len, &modedb, bpp);
1156
1157        info->var = nvidiafb_default_var;
1158        info->fix.visual = (info->var.bits_per_pixel == 8) ?
1159                FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1160        info->pseudo_palette = par->pseudo_palette;
1161        fb_alloc_cmap(&info->cmap, 256, 0);
1162        fb_destroy_modedb(info->monspecs.modedb);
1163        info->monspecs.modedb = NULL;
1164
1165        /* maximize virtual vertical length */
1166        lpitch = info->var.xres_virtual *
1167                ((info->var.bits_per_pixel + 7) >> 3);
1168        info->var.yres_virtual = info->screen_size / lpitch;
1169
1170        info->pixmap.scan_align = 4;
1171        info->pixmap.buf_align = 4;
1172        info->pixmap.access_align = 32;
1173        info->pixmap.size = 8 * 1024;
1174        info->pixmap.flags = FB_PIXMAP_SYSTEM;
1175
1176        if (!hwcur)
1177            info->fbops->fb_cursor = NULL;
1178
1179        info->var.accel_flags = (!noaccel);
1180
1181        switch (par->Architecture) {
1182        case NV_ARCH_04:
1183                info->fix.accel = FB_ACCEL_NV4;
1184                break;
1185        case NV_ARCH_10:
1186                info->fix.accel = FB_ACCEL_NV_10;
1187                break;
1188        case NV_ARCH_20:
1189                info->fix.accel = FB_ACCEL_NV_20;
1190                break;
1191        case NV_ARCH_30:
1192                info->fix.accel = FB_ACCEL_NV_30;
1193                break;
1194        case NV_ARCH_40:
1195                info->fix.accel = FB_ACCEL_NV_40;
1196                break;
1197        }
1198
1199        NVTRACE_LEAVE();
1200
1201        return nvidiafb_check_var(&info->var, info);
1202}
1203
1204static u32 __devinit nvidia_get_chipset(struct fb_info *info)
1205{
1206        struct nvidia_par *par = info->par;
1207        u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
1208
1209        printk(KERN_INFO PFX "Device ID: %x \n", id);
1210
1211        if ((id & 0xfff0) == 0x00f0 ||
1212            (id & 0xfff0) == 0x02e0) {
1213                /* pci-e */
1214                id = NV_RD32(par->REGS, 0x1800);
1215
1216                if ((id & 0x0000ffff) == 0x000010DE)
1217                        id = 0x10DE0000 | (id >> 16);
1218                else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
1219                        id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
1220                            ((id >> 8) & 0x000000ff);
1221                printk(KERN_INFO PFX "Subsystem ID: %x \n", id);
1222        }
1223
1224        return id;
1225}
1226
1227static u32 __devinit nvidia_get_arch(struct fb_info *info)
1228{
1229        struct nvidia_par *par = info->par;
1230        u32 arch = 0;
1231
1232        switch (par->Chipset & 0x0ff0) {
1233        case 0x0100:            /* GeForce 256 */
1234        case 0x0110:            /* GeForce2 MX */
1235        case 0x0150:            /* GeForce2 */
1236        case 0x0170:            /* GeForce4 MX */
1237        case 0x0180:            /* GeForce4 MX (8x AGP) */
1238        case 0x01A0:            /* nForce */
1239        case 0x01F0:            /* nForce2 */
1240                arch = NV_ARCH_10;
1241                break;
1242        case 0x0200:            /* GeForce3 */
1243        case 0x0250:            /* GeForce4 Ti */
1244        case 0x0280:            /* GeForce4 Ti (8x AGP) */
1245                arch = NV_ARCH_20;
1246                break;
1247        case 0x0300:            /* GeForceFX 5800 */
1248        case 0x0310:            /* GeForceFX 5600 */
1249        case 0x0320:            /* GeForceFX 5200 */
1250        case 0x0330:            /* GeForceFX 5900 */
1251        case 0x0340:            /* GeForceFX 5700 */
1252                arch = NV_ARCH_30;
1253                break;
1254        case 0x0040:            /* GeForce 6800 */
1255        case 0x00C0:            /* GeForce 6800 */
1256        case 0x0120:            /* GeForce 6800 */
1257        case 0x0140:            /* GeForce 6600 */
1258        case 0x0160:            /* GeForce 6200 */
1259        case 0x01D0:            /* GeForce 7200, 7300, 7400 */
1260        case 0x0090:            /* GeForce 7800 */
1261        case 0x0210:            /* GeForce 6800 */
1262        case 0x0220:            /* GeForce 6200 */
1263        case 0x0240:            /* GeForce 6100 */
1264        case 0x0290:            /* GeForce 7900 */
1265        case 0x0390:            /* GeForce 7600 */
1266        case 0x03D0:
1267                arch = NV_ARCH_40;
1268                break;
1269        case 0x0020:            /* TNT, TNT2 */
1270                arch = NV_ARCH_04;
1271                break;
1272        default:                /* unknown architecture */
1273                break;
1274        }
1275
1276        return arch;
1277}
1278
1279static int __devinit nvidiafb_probe(struct pci_dev *pd,
1280                                    const struct pci_device_id *ent)
1281{
1282        struct nvidia_par *par;
1283        struct fb_info *info;
1284        unsigned short cmd;
1285
1286
1287        NVTRACE_ENTER();
1288        assert(pd != NULL);
1289
1290        info = framebuffer_alloc(sizeof(struct nvidia_par), &pd->dev);
1291
1292        if (!info)
1293                goto err_out;
1294
1295        par = info->par;
1296        par->pci_dev = pd;
1297        info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
1298
1299        if (info->pixmap.addr == NULL)
1300                goto err_out_kfree;
1301
1302        if (pci_enable_device(pd)) {
1303                printk(KERN_ERR PFX "cannot enable PCI device\n");
1304                goto err_out_enable;
1305        }
1306
1307        if (pci_request_regions(pd, "nvidiafb")) {
1308                printk(KERN_ERR PFX "cannot request PCI regions\n");
1309                goto err_out_enable;
1310        }
1311
1312        par->FlatPanel = flatpanel;
1313        if (flatpanel == 1)
1314                printk(KERN_INFO PFX "flatpanel support enabled\n");
1315        par->FPDither = fpdither;
1316
1317        par->CRTCnumber = forceCRTC;
1318        par->FpScale = (!noscale);
1319        par->paneltweak = paneltweak;
1320        par->reverse_i2c = reverse_i2c;
1321
1322        /* enable IO and mem if not already done */
1323        pci_read_config_word(pd, PCI_COMMAND, &cmd);
1324        cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1325        pci_write_config_word(pd, PCI_COMMAND, cmd);
1326
1327        nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
1328        nvidiafb_fix.smem_start = pci_resource_start(pd, 1);
1329        nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
1330
1331        par->REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
1332
1333        if (!par->REGS) {
1334                printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1335                goto err_out_free_base0;
1336        }
1337
1338        par->Chipset = nvidia_get_chipset(info);
1339        par->Architecture = nvidia_get_arch(info);
1340
1341        if (par->Architecture == 0) {
1342                printk(KERN_ERR PFX "unknown NV_ARCH\n");
1343                goto err_out_arch;
1344        }
1345
1346        sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1347
1348        if (NVCommonSetup(info))
1349                goto err_out_arch;
1350
1351        par->FbAddress = nvidiafb_fix.smem_start;
1352        par->FbMapSize = par->RamAmountKBytes * 1024;
1353        if (vram && vram * 1024 * 1024 < par->FbMapSize)
1354                par->FbMapSize = vram * 1024 * 1024;
1355
1356        /* Limit amount of vram to 64 MB */
1357        if (par->FbMapSize > 64 * 1024 * 1024)
1358                par->FbMapSize = 64 * 1024 * 1024;
1359
1360        if(par->Architecture >= NV_ARCH_40)
1361                par->FbUsableSize = par->FbMapSize - (560 * 1024);
1362        else
1363                par->FbUsableSize = par->FbMapSize - (128 * 1024);
1364        par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
1365            16 * 1024;
1366        par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
1367        par->CursorStart = par->FbUsableSize + (32 * 1024);
1368
1369        info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
1370        info->screen_size = par->FbUsableSize;
1371        nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
1372
1373        if (!info->screen_base) {
1374                printk(KERN_ERR PFX "cannot ioremap FB base\n");
1375                goto err_out_free_base1;
1376        }
1377
1378        par->FbStart = info->screen_base;
1379
1380#ifdef CONFIG_MTRR
1381        if (!nomtrr) {
1382                par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start,
1383                                          par->RamAmountKBytes * 1024,
1384                                          MTRR_TYPE_WRCOMB, 1);
1385                if (par->mtrr.vram < 0) {
1386                        printk(KERN_ERR PFX "unable to setup MTRR\n");
1387                } else {
1388                        par->mtrr.vram_valid = 1;
1389                        /* let there be speed */
1390                        printk(KERN_INFO PFX "MTRR set to ON\n");
1391                }
1392        }
1393#endif                          /* CONFIG_MTRR */
1394
1395        info->fbops = &nvidia_fb_ops;
1396        info->fix = nvidiafb_fix;
1397
1398        if (nvidia_set_fbinfo(info) < 0) {
1399                printk(KERN_ERR PFX "error setting initial video mode\n");
1400                goto err_out_iounmap_fb;
1401        }
1402
1403        nvidia_save_vga(par, &par->SavedReg);
1404
1405        pci_set_drvdata(pd, info);
1406
1407        if (backlight)
1408                nvidia_bl_init(par);
1409
1410        if (register_framebuffer(info) < 0) {
1411                printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
1412                goto err_out_iounmap_fb;
1413        }
1414
1415
1416        printk(KERN_INFO PFX
1417               "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n",
1418               info->fix.id,
1419               par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1420
1421        NVTRACE_LEAVE();
1422        return 0;
1423
1424err_out_iounmap_fb:
1425        iounmap(info->screen_base);
1426err_out_free_base1:
1427        fb_destroy_modedb(info->monspecs.modedb);
1428        nvidia_delete_i2c_busses(par);
1429err_out_arch:
1430        iounmap(par->REGS);
1431 err_out_free_base0:
1432        pci_release_regions(pd);
1433err_out_enable:
1434        kfree(info->pixmap.addr);
1435err_out_kfree:
1436        framebuffer_release(info);
1437err_out:
1438        return -ENODEV;
1439}
1440
1441static void __devexit nvidiafb_remove(struct pci_dev *pd)
1442{
1443        struct fb_info *info = pci_get_drvdata(pd);
1444        struct nvidia_par *par = info->par;
1445
1446        NVTRACE_ENTER();
1447
1448        unregister_framebuffer(info);
1449
1450        nvidia_bl_exit(par);
1451
1452#ifdef CONFIG_MTRR
1453        if (par->mtrr.vram_valid)
1454                mtrr_del(par->mtrr.vram, info->fix.smem_start,
1455                         info->fix.smem_len);
1456#endif                          /* CONFIG_MTRR */
1457
1458        iounmap(info->screen_base);
1459        fb_destroy_modedb(info->monspecs.modedb);
1460        nvidia_delete_i2c_busses(par);
1461        iounmap(par->REGS);
1462        pci_release_regions(pd);
1463        kfree(info->pixmap.addr);
1464        framebuffer_release(info);
1465        pci_set_drvdata(pd, NULL);
1466        NVTRACE_LEAVE();
1467}
1468
1469/* ------------------------------------------------------------------------- *
1470 *
1471 * initialization
1472 *
1473 * ------------------------------------------------------------------------- */
1474
1475#ifndef MODULE
1476static int __devinit nvidiafb_setup(char *options)
1477{
1478        char *this_opt;
1479
1480        NVTRACE_ENTER();
1481        if (!options || !*options)
1482                return 0;
1483
1484        while ((this_opt = strsep(&options, ",")) != NULL) {
1485                if (!strncmp(this_opt, "forceCRTC", 9)) {
1486                        char *p;
1487
1488                        p = this_opt + 9;
1489                        if (!*p || !*(++p))
1490                                continue;
1491                        forceCRTC = *p - '0';
1492                        if (forceCRTC < 0 || forceCRTC > 1)
1493                                forceCRTC = -1;
1494                } else if (!strncmp(this_opt, "flatpanel", 9)) {
1495                        flatpanel = 1;
1496                } else if (!strncmp(this_opt, "hwcur", 5)) {
1497                        hwcur = 1;
1498                } else if (!strncmp(this_opt, "noaccel", 6)) {
1499                        noaccel = 1;
1500                } else if (!strncmp(this_opt, "noscale", 7)) {
1501                        noscale = 1;
1502                } else if (!strncmp(this_opt, "reverse_i2c", 11)) {
1503                        reverse_i2c = 1;
1504                } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1505                        paneltweak = simple_strtoul(this_opt+11, NULL, 0);
1506                } else if (!strncmp(this_opt, "vram:", 5)) {
1507                        vram = simple_strtoul(this_opt+5, NULL, 0);
1508                } else if (!strncmp(this_opt, "backlight:", 10)) {
1509                        backlight = simple_strtoul(this_opt+10, NULL, 0);
1510#ifdef CONFIG_MTRR
1511                } else if (!strncmp(this_opt, "nomtrr", 6)) {
1512                        nomtrr = 1;
1513#endif
1514                } else if (!strncmp(this_opt, "fpdither:", 9)) {
1515                        fpdither = simple_strtol(this_opt+9, NULL, 0);
1516                } else if (!strncmp(this_opt, "bpp:", 4)) {
1517                        bpp = simple_strtoul(this_opt+4, NULL, 0);
1518                } else
1519                        mode_option = this_opt;
1520        }
1521        NVTRACE_LEAVE();
1522        return 0;
1523}
1524#endif                          /* !MODULE */
1525
1526static struct pci_driver nvidiafb_driver = {
1527        .name = "nvidiafb",
1528        .id_table = nvidiafb_pci_tbl,
1529        .probe    = nvidiafb_probe,
1530        .suspend  = nvidiafb_suspend,
1531        .resume   = nvidiafb_resume,
1532        .remove   = __devexit_p(nvidiafb_remove),
1533};
1534
1535/* ------------------------------------------------------------------------- *
1536 *
1537 * modularization
1538 *
1539 * ------------------------------------------------------------------------- */
1540
1541static int __devinit nvidiafb_init(void)
1542{
1543#ifndef MODULE
1544        char *option = NULL;
1545
1546        if (fb_get_options("nvidiafb", &option))
1547                return -ENODEV;
1548        nvidiafb_setup(option);
1549#endif
1550        return pci_register_driver(&nvidiafb_driver);
1551}
1552
1553module_init(nvidiafb_init);
1554
1555static void __exit nvidiafb_exit(void)
1556{
1557        pci_unregister_driver(&nvidiafb_driver);
1558}
1559
1560module_exit(nvidiafb_exit);
1561
1562module_param(flatpanel, int, 0);
1563MODULE_PARM_DESC(flatpanel,
1564                 "Enables experimental flat panel support for some chipsets. "
1565                 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1566module_param(fpdither, int, 0);
1567MODULE_PARM_DESC(fpdither,
1568                 "Enables dithering of flat panel for 6 bits panels. "
1569                 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1570module_param(hwcur, int, 0);
1571MODULE_PARM_DESC(hwcur,
1572                 "Enables hardware cursor implementation. (0 or 1=enabled) "
1573                 "(default=0)");
1574module_param(noaccel, int, 0);
1575MODULE_PARM_DESC(noaccel,
1576                 "Disables hardware acceleration. (0 or 1=disable) "
1577                 "(default=0)");
1578module_param(noscale, int, 0);
1579MODULE_PARM_DESC(noscale,
1580                 "Disables screen scaleing. (0 or 1=disable) "
1581                 "(default=0, do scaling)");
1582module_param(paneltweak, int, 0);
1583MODULE_PARM_DESC(paneltweak,
1584                 "Tweak display settings for flatpanels. "
1585                 "(default=0, no tweaks)");
1586module_param(forceCRTC, int, 0);
1587MODULE_PARM_DESC(forceCRTC,
1588                 "Forces usage of a particular CRTC in case autodetection "
1589                 "fails. (0 or 1) (default=autodetect)");
1590module_param(vram, int, 0);
1591MODULE_PARM_DESC(vram,
1592                 "amount of framebuffer memory to remap in MiB"
1593                 "(default=0 - remap entire memory)");
1594module_param(mode_option, charp, 0);
1595MODULE_PARM_DESC(mode_option, "Specify initial video mode");
1596module_param(bpp, int, 0);
1597MODULE_PARM_DESC(bpp, "pixel width in bits"
1598                 "(default=8)");
1599module_param(reverse_i2c, int, 0);
1600MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
1601#ifdef CONFIG_MTRR
1602module_param(nomtrr, bool, 0);
1603MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
1604                 "(default=0)");
1605#endif
1606
1607MODULE_AUTHOR("Antonino Daplas");
1608MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");
1609MODULE_LICENSE("GPL");
1610