linux/drivers/video/nvidia/nv_hw.c
<<
>>
Prefs
   1 /***************************************************************************\
   2|*                                                                           *|
   3|*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
   4|*                                                                           *|
   5|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
   6|*     international laws.  Users and possessors of this source code are     *|
   7|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
   8|*     use this code in individual and commercial software.                  *|
   9|*                                                                           *|
  10|*     Any use of this source code must include,  in the user documenta-     *|
  11|*     tion and  internal comments to the code,  notices to the end user     *|
  12|*     as follows:                                                           *|
  13|*                                                                           *|
  14|*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
  15|*                                                                           *|
  16|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
  17|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
  18|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
  19|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
  20|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
  21|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
  22|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
  23|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
  24|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
  25|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
  26|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
  27|*                                                                           *|
  28|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
  29|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
  30|*     consisting  of "commercial  computer  software"  and  "commercial     *|
  31|*     computer  software  documentation,"  as such  terms  are  used in     *|
  32|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
  33|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
  34|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
  35|*     all U.S. Government End Users  acquire the source code  with only     *|
  36|*     those rights set forth herein.                                        *|
  37|*                                                                           *|
  38 \***************************************************************************/
  39
  40/*
  41 * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
  42 * XFree86 'nv' driver, this source code is provided under MIT-style licensing
  43 * where the source code is provided "as is" without warranty of any kind.
  44 * The only usage restriction is for the copyright notices to be retained
  45 * whenever code is used.
  46 *
  47 * Antonino Daplas <adaplas@pol.net> 2005-03-11
  48 */
  49
  50/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c,v 1.4 2003/11/03 05:11:25 tsi Exp $ */
  51
  52#include <linux/pci.h>
  53#include "nv_type.h"
  54#include "nv_local.h"
  55#include "nv_proto.h"
  56
  57void NVLockUnlock(struct nvidia_par *par, int Lock)
  58{
  59        u8 cr11;
  60
  61        VGA_WR08(par->PCIO, 0x3D4, 0x1F);
  62        VGA_WR08(par->PCIO, 0x3D5, Lock ? 0x99 : 0x57);
  63
  64        VGA_WR08(par->PCIO, 0x3D4, 0x11);
  65        cr11 = VGA_RD08(par->PCIO, 0x3D5);
  66        if (Lock)
  67                cr11 |= 0x80;
  68        else
  69                cr11 &= ~0x80;
  70        VGA_WR08(par->PCIO, 0x3D5, cr11);
  71}
  72
  73int NVShowHideCursor(struct nvidia_par *par, int ShowHide)
  74{
  75        int cur = par->CurrentState->cursor1;
  76
  77        par->CurrentState->cursor1 = (par->CurrentState->cursor1 & 0xFE) |
  78            (ShowHide & 0x01);
  79        VGA_WR08(par->PCIO, 0x3D4, 0x31);
  80        VGA_WR08(par->PCIO, 0x3D5, par->CurrentState->cursor1);
  81
  82        if (par->Architecture == NV_ARCH_40)
  83                NV_WR32(par->PRAMDAC, 0x0300, NV_RD32(par->PRAMDAC, 0x0300));
  84
  85        return (cur & 0x01);
  86}
  87
  88/****************************************************************************\
  89*                                                                            *
  90* The video arbitration routines calculate some "magic" numbers.  Fixes      *
  91* the snow seen when accessing the framebuffer without it.                   *
  92* It just works (I hope).                                                    *
  93*                                                                            *
  94\****************************************************************************/
  95
  96typedef struct {
  97        int graphics_lwm;
  98        int video_lwm;
  99        int graphics_burst_size;
 100        int video_burst_size;
 101        int valid;
 102} nv4_fifo_info;
 103
 104typedef struct {
 105        int pclk_khz;
 106        int mclk_khz;
 107        int nvclk_khz;
 108        char mem_page_miss;
 109        char mem_latency;
 110        int memory_width;
 111        char enable_video;
 112        char gr_during_vid;
 113        char pix_bpp;
 114        char mem_aligned;
 115        char enable_mp;
 116} nv4_sim_state;
 117
 118typedef struct {
 119        int graphics_lwm;
 120        int video_lwm;
 121        int graphics_burst_size;
 122        int video_burst_size;
 123        int valid;
 124} nv10_fifo_info;
 125
 126typedef struct {
 127        int pclk_khz;
 128        int mclk_khz;
 129        int nvclk_khz;
 130        char mem_page_miss;
 131        char mem_latency;
 132        u32 memory_type;
 133        int memory_width;
 134        char enable_video;
 135        char gr_during_vid;
 136        char pix_bpp;
 137        char mem_aligned;
 138        char enable_mp;
 139} nv10_sim_state;
 140
 141static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk,
 142                        unsigned int *NVClk)
 143{
 144        unsigned int pll, N, M, MB, NB, P;
 145
 146        if (par->Architecture >= NV_ARCH_40) {
 147                pll = NV_RD32(par->PMC, 0x4020);
 148                P = (pll >> 16) & 0x07;
 149                pll = NV_RD32(par->PMC, 0x4024);
 150                M = pll & 0xFF;
 151                N = (pll >> 8) & 0xFF;
 152                if (((par->Chipset & 0xfff0) == 0x0290) ||
 153                    ((par->Chipset & 0xfff0) == 0x0390)) {
 154                        MB = 1;
 155                        NB = 1;
 156                } else {
 157                        MB = (pll >> 16) & 0xFF;
 158                        NB = (pll >> 24) & 0xFF;
 159                }
 160                *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 161
 162                pll = NV_RD32(par->PMC, 0x4000);
 163                P = (pll >> 16) & 0x07;
 164                pll = NV_RD32(par->PMC, 0x4004);
 165                M = pll & 0xFF;
 166                N = (pll >> 8) & 0xFF;
 167                MB = (pll >> 16) & 0xFF;
 168                NB = (pll >> 24) & 0xFF;
 169
 170                *NVClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 171        } else if (par->twoStagePLL) {
 172                pll = NV_RD32(par->PRAMDAC0, 0x0504);
 173                M = pll & 0xFF;
 174                N = (pll >> 8) & 0xFF;
 175                P = (pll >> 16) & 0x0F;
 176                pll = NV_RD32(par->PRAMDAC0, 0x0574);
 177                if (pll & 0x80000000) {
 178                        MB = pll & 0xFF;
 179                        NB = (pll >> 8) & 0xFF;
 180                } else {
 181                        MB = 1;
 182                        NB = 1;
 183                }
 184                *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 185
 186                pll = NV_RD32(par->PRAMDAC0, 0x0500);
 187                M = pll & 0xFF;
 188                N = (pll >> 8) & 0xFF;
 189                P = (pll >> 16) & 0x0F;
 190                pll = NV_RD32(par->PRAMDAC0, 0x0570);
 191                if (pll & 0x80000000) {
 192                        MB = pll & 0xFF;
 193                        NB = (pll >> 8) & 0xFF;
 194                } else {
 195                        MB = 1;
 196                        NB = 1;
 197                }
 198                *NVClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 199        } else
 200            if (((par->Chipset & 0x0ff0) == 0x0300) ||
 201                ((par->Chipset & 0x0ff0) == 0x0330)) {
 202                pll = NV_RD32(par->PRAMDAC0, 0x0504);
 203                M = pll & 0x0F;
 204                N = (pll >> 8) & 0xFF;
 205                P = (pll >> 16) & 0x07;
 206                if (pll & 0x00000080) {
 207                        MB = (pll >> 4) & 0x07;
 208                        NB = (pll >> 19) & 0x1f;
 209                } else {
 210                        MB = 1;
 211                        NB = 1;
 212                }
 213                *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 214
 215                pll = NV_RD32(par->PRAMDAC0, 0x0500);
 216                M = pll & 0x0F;
 217                N = (pll >> 8) & 0xFF;
 218                P = (pll >> 16) & 0x07;
 219                if (pll & 0x00000080) {
 220                        MB = (pll >> 4) & 0x07;
 221                        NB = (pll >> 19) & 0x1f;
 222                } else {
 223                        MB = 1;
 224                        NB = 1;
 225                }
 226                *NVClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 227        } else {
 228                pll = NV_RD32(par->PRAMDAC0, 0x0504);
 229                M = pll & 0xFF;
 230                N = (pll >> 8) & 0xFF;
 231                P = (pll >> 16) & 0x0F;
 232                *MClk = (N * par->CrystalFreqKHz / M) >> P;
 233
 234                pll = NV_RD32(par->PRAMDAC0, 0x0500);
 235                M = pll & 0xFF;
 236                N = (pll >> 8) & 0xFF;
 237                P = (pll >> 16) & 0x0F;
 238                *NVClk = (N * par->CrystalFreqKHz / M) >> P;
 239        }
 240}
 241
 242static void nv4CalcArbitration(nv4_fifo_info * fifo, nv4_sim_state * arb)
 243{
 244        int data, pagemiss, cas, width, video_enable, bpp;
 245        int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
 246        int found, mclk_extra, mclk_loop, cbs, m1, p1;
 247        int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
 248        int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
 249        int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt, clwm;
 250
 251        fifo->valid = 1;
 252        pclk_freq = arb->pclk_khz;
 253        mclk_freq = arb->mclk_khz;
 254        nvclk_freq = arb->nvclk_khz;
 255        pagemiss = arb->mem_page_miss;
 256        cas = arb->mem_latency;
 257        width = arb->memory_width >> 6;
 258        video_enable = arb->enable_video;
 259        bpp = arb->pix_bpp;
 260        mp_enable = arb->enable_mp;
 261        clwm = 0;
 262        vlwm = 0;
 263        cbs = 128;
 264        pclks = 2;
 265        nvclks = 2;
 266        nvclks += 2;
 267        nvclks += 1;
 268        mclks = 5;
 269        mclks += 3;
 270        mclks += 1;
 271        mclks += cas;
 272        mclks += 1;
 273        mclks += 1;
 274        mclks += 1;
 275        mclks += 1;
 276        mclk_extra = 3;
 277        nvclks += 2;
 278        nvclks += 1;
 279        nvclks += 1;
 280        nvclks += 1;
 281        if (mp_enable)
 282                mclks += 4;
 283        nvclks += 0;
 284        pclks += 0;
 285        found = 0;
 286        vbs = 0;
 287        while (found != 1) {
 288                fifo->valid = 1;
 289                found = 1;
 290                mclk_loop = mclks + mclk_extra;
 291                us_m = mclk_loop * 1000 * 1000 / mclk_freq;
 292                us_n = nvclks * 1000 * 1000 / nvclk_freq;
 293                us_p = nvclks * 1000 * 1000 / pclk_freq;
 294                if (video_enable) {
 295                        video_drain_rate = pclk_freq * 2;
 296                        crtc_drain_rate = pclk_freq * bpp / 8;
 297                        vpagemiss = 2;
 298                        vpagemiss += 1;
 299                        crtpagemiss = 2;
 300                        vpm_us =
 301                            (vpagemiss * pagemiss) * 1000 * 1000 / mclk_freq;
 302                        if (nvclk_freq * 2 > mclk_freq * width)
 303                                video_fill_us =
 304                                    cbs * 1000 * 1000 / 16 / nvclk_freq;
 305                        else
 306                                video_fill_us =
 307                                    cbs * 1000 * 1000 / (8 * width) /
 308                                    mclk_freq;
 309                        us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
 310                        vlwm = us_video * video_drain_rate / (1000 * 1000);
 311                        vlwm++;
 312                        vbs = 128;
 313                        if (vlwm > 128)
 314                                vbs = 64;
 315                        if (vlwm > (256 - 64))
 316                                vbs = 32;
 317                        if (nvclk_freq * 2 > mclk_freq * width)
 318                                video_fill_us =
 319                                    vbs * 1000 * 1000 / 16 / nvclk_freq;
 320                        else
 321                                video_fill_us =
 322                                    vbs * 1000 * 1000 / (8 * width) /
 323                                    mclk_freq;
 324                        cpm_us =
 325                            crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
 326                        us_crt =
 327                            us_video + video_fill_us + cpm_us + us_m + us_n +
 328                            us_p;
 329                        clwm = us_crt * crtc_drain_rate / (1000 * 1000);
 330                        clwm++;
 331                } else {
 332                        crtc_drain_rate = pclk_freq * bpp / 8;
 333                        crtpagemiss = 2;
 334                        crtpagemiss += 1;
 335                        cpm_us =
 336                            crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
 337                        us_crt = cpm_us + us_m + us_n + us_p;
 338                        clwm = us_crt * crtc_drain_rate / (1000 * 1000);
 339                        clwm++;
 340                }
 341                m1 = clwm + cbs - 512;
 342                p1 = m1 * pclk_freq / mclk_freq;
 343                p1 = p1 * bpp / 8;
 344                if ((p1 < m1) && (m1 > 0)) {
 345                        fifo->valid = 0;
 346                        found = 0;
 347                        if (mclk_extra == 0)
 348                                found = 1;
 349                        mclk_extra--;
 350                } else if (video_enable) {
 351                        if ((clwm > 511) || (vlwm > 255)) {
 352                                fifo->valid = 0;
 353                                found = 0;
 354                                if (mclk_extra == 0)
 355                                        found = 1;
 356                                mclk_extra--;
 357                        }
 358                } else {
 359                        if (clwm > 519) {
 360                                fifo->valid = 0;
 361                                found = 0;
 362                                if (mclk_extra == 0)
 363                                        found = 1;
 364                                mclk_extra--;
 365                        }
 366                }
 367                if (clwm < 384)
 368                        clwm = 384;
 369                if (vlwm < 128)
 370                        vlwm = 128;
 371                data = (int)(clwm);
 372                fifo->graphics_lwm = data;
 373                fifo->graphics_burst_size = 128;
 374                data = (int)((vlwm + 15));
 375                fifo->video_lwm = data;
 376                fifo->video_burst_size = vbs;
 377        }
 378}
 379
 380static void nv4UpdateArbitrationSettings(unsigned VClk,
 381                                         unsigned pixelDepth,
 382                                         unsigned *burst,
 383                                         unsigned *lwm, struct nvidia_par *par)
 384{
 385        nv4_fifo_info fifo_data;
 386        nv4_sim_state sim_data;
 387        unsigned int MClk, NVClk, cfg1;
 388
 389        nvGetClocks(par, &MClk, &NVClk);
 390
 391        cfg1 = NV_RD32(par->PFB, 0x00000204);
 392        sim_data.pix_bpp = (char)pixelDepth;
 393        sim_data.enable_video = 0;
 394        sim_data.enable_mp = 0;
 395        sim_data.memory_width = (NV_RD32(par->PEXTDEV, 0x0000) & 0x10) ?
 396            128 : 64;
 397        sim_data.mem_latency = (char)cfg1 & 0x0F;
 398        sim_data.mem_aligned = 1;
 399        sim_data.mem_page_miss =
 400            (char)(((cfg1 >> 4) & 0x0F) + ((cfg1 >> 31) & 0x01));
 401        sim_data.gr_during_vid = 0;
 402        sim_data.pclk_khz = VClk;
 403        sim_data.mclk_khz = MClk;
 404        sim_data.nvclk_khz = NVClk;
 405        nv4CalcArbitration(&fifo_data, &sim_data);
 406        if (fifo_data.valid) {
 407                int b = fifo_data.graphics_burst_size >> 4;
 408                *burst = 0;
 409                while (b >>= 1)
 410                        (*burst)++;
 411                *lwm = fifo_data.graphics_lwm >> 3;
 412        }
 413}
 414
 415static void nv10CalcArbitration(nv10_fifo_info * fifo, nv10_sim_state * arb)
 416{
 417        int data, pagemiss, width, video_enable, bpp;
 418        int nvclks, mclks, pclks, vpagemiss, crtpagemiss;
 419        int nvclk_fill;
 420        int found, mclk_extra, mclk_loop, cbs, m1;
 421        int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
 422        int us_m, us_m_min, us_n, us_p, crtc_drain_rate;
 423        int vus_m;
 424        int vpm_us, us_video, cpm_us, us_crt, clwm;
 425        int clwm_rnd_down;
 426        int m2us, us_pipe_min, p1clk, p2;
 427        int min_mclk_extra;
 428        int us_min_mclk_extra;
 429
 430        fifo->valid = 1;
 431        pclk_freq = arb->pclk_khz;      /* freq in KHz */
 432        mclk_freq = arb->mclk_khz;
 433        nvclk_freq = arb->nvclk_khz;
 434        pagemiss = arb->mem_page_miss;
 435        width = arb->memory_width / 64;
 436        video_enable = arb->enable_video;
 437        bpp = arb->pix_bpp;
 438        mp_enable = arb->enable_mp;
 439        clwm = 0;
 440
 441        cbs = 512;
 442
 443        pclks = 4;      /* lwm detect. */
 444
 445        nvclks = 3;     /* lwm -> sync. */
 446        nvclks += 2;    /* fbi bus cycles (1 req + 1 busy) */
 447        /* 2 edge sync.  may be very close to edge so just put one. */
 448        mclks = 1;
 449        mclks += 1;     /* arb_hp_req */
 450        mclks += 5;     /* ap_hp_req   tiling pipeline */
 451
 452        mclks += 2;     /* tc_req     latency fifo */
 453        mclks += 2;     /* fb_cas_n_  memory request to fbio block */
 454        mclks += 7;     /* sm_d_rdv   data returned from fbio block */
 455
 456        /* fb.rd.d.Put_gc   need to accumulate 256 bits for read */
 457        if (arb->memory_type == 0)
 458                if (arb->memory_width == 64)    /* 64 bit bus */
 459                        mclks += 4;
 460                else
 461                        mclks += 2;
 462        else if (arb->memory_width == 64)       /* 64 bit bus */
 463                mclks += 2;
 464        else
 465                mclks += 1;
 466
 467        if ((!video_enable) && (arb->memory_width == 128)) {
 468                mclk_extra = (bpp == 32) ? 31 : 42;     /* Margin of error */
 469                min_mclk_extra = 17;
 470        } else {
 471                mclk_extra = (bpp == 32) ? 8 : 4;       /* Margin of error */
 472                /* mclk_extra = 4; *//* Margin of error */
 473                min_mclk_extra = 18;
 474        }
 475
 476        /* 2 edge sync.  may be very close to edge so just put one. */
 477        nvclks += 1;
 478        nvclks += 1;            /* fbi_d_rdv_n */
 479        nvclks += 1;            /* Fbi_d_rdata */
 480        nvclks += 1;            /* crtfifo load */
 481
 482        if (mp_enable)
 483                mclks += 4;     /* Mp can get in with a burst of 8. */
 484        /* Extra clocks determined by heuristics */
 485
 486        nvclks += 0;
 487        pclks += 0;
 488        found = 0;
 489        while (found != 1) {
 490                fifo->valid = 1;
 491                found = 1;
 492                mclk_loop = mclks + mclk_extra;
 493                /* Mclk latency in us */
 494                us_m = mclk_loop * 1000 * 1000 / mclk_freq;
 495                /* Minimum Mclk latency in us */
 496                us_m_min = mclks * 1000 * 1000 / mclk_freq;
 497                us_min_mclk_extra = min_mclk_extra * 1000 * 1000 / mclk_freq;
 498                /* nvclk latency in us */
 499                us_n = nvclks * 1000 * 1000 / nvclk_freq;
 500                /* nvclk latency in us */
 501                us_p = pclks * 1000 * 1000 / pclk_freq;
 502                us_pipe_min = us_m_min + us_n + us_p;
 503
 504                /* Mclk latency in us */
 505                vus_m = mclk_loop * 1000 * 1000 / mclk_freq;
 506
 507                if (video_enable) {
 508                        crtc_drain_rate = pclk_freq * bpp / 8;  /* MB/s */
 509
 510                        vpagemiss = 1;  /* self generating page miss */
 511                        vpagemiss += 1; /* One higher priority before */
 512
 513                        crtpagemiss = 2;        /* self generating page miss */
 514                        if (mp_enable)
 515                                crtpagemiss += 1;       /* if MA0 conflict */
 516
 517                        vpm_us =
 518                            (vpagemiss * pagemiss) * 1000 * 1000 / mclk_freq;
 519
 520                        /* Video has separate read return path */
 521                        us_video = vpm_us + vus_m;
 522
 523                        cpm_us =
 524                            crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
 525                        /* Wait for video */
 526                        us_crt = us_video
 527                            + cpm_us    /* CRT Page miss */
 528                            + us_m + us_n + us_p        /* other latency */
 529                            ;
 530
 531                        clwm = us_crt * crtc_drain_rate / (1000 * 1000);
 532                        /* fixed point <= float_point - 1.  Fixes that */
 533                        clwm++;
 534                } else {
 535                    /* bpp * pclk/8 */
 536                        crtc_drain_rate = pclk_freq * bpp / 8;
 537
 538                        crtpagemiss = 1;        /* self generating page miss */
 539                        crtpagemiss += 1;       /* MA0 page miss */
 540                        if (mp_enable)
 541                                crtpagemiss += 1;       /* if MA0 conflict */
 542                        cpm_us =
 543                            crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
 544                        us_crt = cpm_us + us_m + us_n + us_p;
 545                        clwm = us_crt * crtc_drain_rate / (1000 * 1000);
 546                        /* fixed point <= float_point - 1.  Fixes that */
 547                        clwm++;
 548
 549                        /* Finally, a heuristic check when width == 64 bits */
 550                        if (width == 1) {
 551                                nvclk_fill = nvclk_freq * 8;
 552                                if (crtc_drain_rate * 100 >= nvclk_fill * 102)
 553                                        /*Large number to fail */
 554                                        clwm = 0xfff;
 555
 556                                else if (crtc_drain_rate * 100 >=
 557                                         nvclk_fill * 98) {
 558                                        clwm = 1024;
 559                                        cbs = 512;
 560                                }
 561                        }
 562                }
 563
 564                /*
 565                   Overfill check:
 566                 */
 567
 568                clwm_rnd_down = ((int)clwm / 8) * 8;
 569                if (clwm_rnd_down < clwm)
 570                        clwm += 8;
 571
 572                m1 = clwm + cbs - 1024; /* Amount of overfill */
 573                m2us = us_pipe_min + us_min_mclk_extra;
 574
 575                /* pclk cycles to drain */
 576                p1clk = m2us * pclk_freq / (1000 * 1000);
 577                p2 = p1clk * bpp / 8;   /* bytes drained. */
 578
 579                if ((p2 < m1) && (m1 > 0)) {
 580                        fifo->valid = 0;
 581                        found = 0;
 582                        if (min_mclk_extra == 0) {
 583                                if (cbs <= 32) {
 584                                        /* Can't adjust anymore! */
 585                                        found = 1;
 586                                } else {
 587                                        /* reduce the burst size */
 588                                        cbs = cbs / 2;
 589                                }
 590                        } else {
 591                                min_mclk_extra--;
 592                        }
 593                } else {
 594                        if (clwm > 1023) {      /* Have some margin */
 595                                fifo->valid = 0;
 596                                found = 0;
 597                                if (min_mclk_extra == 0)
 598                                        /* Can't adjust anymore! */
 599                                        found = 1;
 600                                else
 601                                        min_mclk_extra--;
 602                        }
 603                }
 604
 605                if (clwm < (1024 - cbs + 8))
 606                        clwm = 1024 - cbs + 8;
 607                data = (int)(clwm);
 608                /*  printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n",
 609                    clwm, data ); */
 610                fifo->graphics_lwm = data;
 611                fifo->graphics_burst_size = cbs;
 612
 613                fifo->video_lwm = 1024;
 614                fifo->video_burst_size = 512;
 615        }
 616}
 617
 618static void nv10UpdateArbitrationSettings(unsigned VClk,
 619                                          unsigned pixelDepth,
 620                                          unsigned *burst,
 621                                          unsigned *lwm,
 622                                          struct nvidia_par *par)
 623{
 624        nv10_fifo_info fifo_data;
 625        nv10_sim_state sim_data;
 626        unsigned int MClk, NVClk, cfg1;
 627
 628        nvGetClocks(par, &MClk, &NVClk);
 629
 630        cfg1 = NV_RD32(par->PFB, 0x0204);
 631        sim_data.pix_bpp = (char)pixelDepth;
 632        sim_data.enable_video = 1;
 633        sim_data.enable_mp = 0;
 634        sim_data.memory_type = (NV_RD32(par->PFB, 0x0200) & 0x01) ? 1 : 0;
 635        sim_data.memory_width = (NV_RD32(par->PEXTDEV, 0x0000) & 0x10) ?
 636            128 : 64;
 637        sim_data.mem_latency = (char)cfg1 & 0x0F;
 638        sim_data.mem_aligned = 1;
 639        sim_data.mem_page_miss =
 640            (char)(((cfg1 >> 4) & 0x0F) + ((cfg1 >> 31) & 0x01));
 641        sim_data.gr_during_vid = 0;
 642        sim_data.pclk_khz = VClk;
 643        sim_data.mclk_khz = MClk;
 644        sim_data.nvclk_khz = NVClk;
 645        nv10CalcArbitration(&fifo_data, &sim_data);
 646        if (fifo_data.valid) {
 647                int b = fifo_data.graphics_burst_size >> 4;
 648                *burst = 0;
 649                while (b >>= 1)
 650                        (*burst)++;
 651                *lwm = fifo_data.graphics_lwm >> 3;
 652        }
 653}
 654
 655static void nv30UpdateArbitrationSettings (
 656    struct nvidia_par *par,
 657    unsigned int      *burst,
 658    unsigned int      *lwm
 659)
 660{
 661    unsigned int MClk, NVClk;
 662    unsigned int fifo_size, burst_size, graphics_lwm;
 663
 664    fifo_size = 2048;
 665    burst_size = 512;
 666    graphics_lwm = fifo_size - burst_size;
 667
 668    nvGetClocks(par, &MClk, &NVClk);
 669
 670    *burst = 0;
 671    burst_size >>= 5;
 672    while(burst_size >>= 1) (*burst)++;
 673    *lwm = graphics_lwm >> 3;
 674}
 675
 676static void nForceUpdateArbitrationSettings(unsigned VClk,
 677                                            unsigned pixelDepth,
 678                                            unsigned *burst,
 679                                            unsigned *lwm,
 680                                            struct nvidia_par *par)
 681{
 682        nv10_fifo_info fifo_data;
 683        nv10_sim_state sim_data;
 684        unsigned int M, N, P, pll, MClk, NVClk, memctrl;
 685        struct pci_dev *dev;
 686
 687        if ((par->Chipset & 0x0FF0) == 0x01A0) {
 688                unsigned int uMClkPostDiv;
 689                dev = pci_get_bus_and_slot(0, 3);
 690                pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
 691                uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
 692
 693                if (!uMClkPostDiv)
 694                        uMClkPostDiv = 4;
 695                MClk = 400000 / uMClkPostDiv;
 696        } else {
 697                dev = pci_get_bus_and_slot(0, 5);
 698                pci_read_config_dword(dev, 0x4c, &MClk);
 699                MClk /= 1000;
 700        }
 701        pci_dev_put(dev);
 702        pll = NV_RD32(par->PRAMDAC0, 0x0500);
 703        M = (pll >> 0) & 0xFF;
 704        N = (pll >> 8) & 0xFF;
 705        P = (pll >> 16) & 0x0F;
 706        NVClk = (N * par->CrystalFreqKHz / M) >> P;
 707        sim_data.pix_bpp = (char)pixelDepth;
 708        sim_data.enable_video = 0;
 709        sim_data.enable_mp = 0;
 710        dev = pci_get_bus_and_slot(0, 1);
 711        pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
 712        pci_dev_put(dev);
 713        sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
 714        sim_data.memory_width = 64;
 715
 716        dev = pci_get_bus_and_slot(0, 3);
 717        pci_read_config_dword(dev, 0, &memctrl);
 718        pci_dev_put(dev);
 719        memctrl >>= 16;
 720
 721        if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
 722                u32 dimm[3];
 723
 724                dev = pci_get_bus_and_slot(0, 2);
 725                pci_read_config_dword(dev, 0x40, &dimm[0]);
 726                dimm[0] = (dimm[0] >> 8) & 0x4f;
 727                pci_read_config_dword(dev, 0x44, &dimm[1]);
 728                dimm[1] = (dimm[1] >> 8) & 0x4f;
 729                pci_read_config_dword(dev, 0x48, &dimm[2]);
 730                dimm[2] = (dimm[2] >> 8) & 0x4f;
 731
 732                if ((dimm[0] + dimm[1]) != dimm[2]) {
 733                        printk("nvidiafb: your nForce DIMMs are not arranged "
 734                               "in optimal banks!\n");
 735                }
 736                pci_dev_put(dev);
 737        }
 738
 739        sim_data.mem_latency = 3;
 740        sim_data.mem_aligned = 1;
 741        sim_data.mem_page_miss = 10;
 742        sim_data.gr_during_vid = 0;
 743        sim_data.pclk_khz = VClk;
 744        sim_data.mclk_khz = MClk;
 745        sim_data.nvclk_khz = NVClk;
 746        nv10CalcArbitration(&fifo_data, &sim_data);
 747        if (fifo_data.valid) {
 748                int b = fifo_data.graphics_burst_size >> 4;
 749                *burst = 0;
 750                while (b >>= 1)
 751                        (*burst)++;
 752                *lwm = fifo_data.graphics_lwm >> 3;
 753        }
 754}
 755
 756/****************************************************************************\
 757*                                                                            *
 758*                          RIVA Mode State Routines                          *
 759*                                                                            *
 760\****************************************************************************/
 761
 762/*
 763 * Calculate the Video Clock parameters for the PLL.
 764 */
 765static void CalcVClock(int clockIn,
 766                       int *clockOut, u32 * pllOut, struct nvidia_par *par)
 767{
 768        unsigned lowM, highM;
 769        unsigned DeltaNew, DeltaOld;
 770        unsigned VClk, Freq;
 771        unsigned M, N, P;
 772
 773        DeltaOld = 0xFFFFFFFF;
 774
 775        VClk = (unsigned)clockIn;
 776
 777        if (par->CrystalFreqKHz == 13500) {
 778                lowM = 7;
 779                highM = 13;
 780        } else {
 781                lowM = 8;
 782                highM = 14;
 783        }
 784
 785        for (P = 0; P <= 4; P++) {
 786                Freq = VClk << P;
 787                if ((Freq >= 128000) && (Freq <= 350000)) {
 788                        for (M = lowM; M <= highM; M++) {
 789                                N = ((VClk << P) * M) / par->CrystalFreqKHz;
 790                                if (N <= 255) {
 791                                        Freq =
 792                                            ((par->CrystalFreqKHz * N) /
 793                                             M) >> P;
 794                                        if (Freq > VClk)
 795                                                DeltaNew = Freq - VClk;
 796                                        else
 797                                                DeltaNew = VClk - Freq;
 798                                        if (DeltaNew < DeltaOld) {
 799                                                *pllOut =
 800                                                    (P << 16) | (N << 8) | M;
 801                                                *clockOut = Freq;
 802                                                DeltaOld = DeltaNew;
 803                                        }
 804                                }
 805                        }
 806                }
 807        }
 808}
 809
 810static void CalcVClock2Stage(int clockIn,
 811                             int *clockOut,
 812                             u32 * pllOut,
 813                             u32 * pllBOut, struct nvidia_par *par)
 814{
 815        unsigned DeltaNew, DeltaOld;
 816        unsigned VClk, Freq;
 817        unsigned M, N, P;
 818
 819        DeltaOld = 0xFFFFFFFF;
 820
 821        *pllBOut = 0x80000401;  /* fixed at x4 for now */
 822
 823        VClk = (unsigned)clockIn;
 824
 825        for (P = 0; P <= 6; P++) {
 826                Freq = VClk << P;
 827                if ((Freq >= 400000) && (Freq <= 1000000)) {
 828                        for (M = 1; M <= 13; M++) {
 829                                N = ((VClk << P) * M) /
 830                                    (par->CrystalFreqKHz << 2);
 831                                if ((N >= 5) && (N <= 255)) {
 832                                        Freq =
 833                                            (((par->CrystalFreqKHz << 2) * N) /
 834                                             M) >> P;
 835                                        if (Freq > VClk)
 836                                                DeltaNew = Freq - VClk;
 837                                        else
 838                                                DeltaNew = VClk - Freq;
 839                                        if (DeltaNew < DeltaOld) {
 840                                                *pllOut =
 841                                                    (P << 16) | (N << 8) | M;
 842                                                *clockOut = Freq;
 843                                                DeltaOld = DeltaNew;
 844                                        }
 845                                }
 846                        }
 847                }
 848        }
 849}
 850
 851/*
 852 * Calculate extended mode parameters (SVGA) and save in a
 853 * mode state structure.
 854 */
 855void NVCalcStateExt(struct nvidia_par *par,
 856                    RIVA_HW_STATE * state,
 857                    int bpp,
 858                    int width,
 859                    int hDisplaySize, int height, int dotClock, int flags)
 860{
 861        int pixelDepth, VClk = 0;
 862        /*
 863         * Save mode parameters.
 864         */
 865        state->bpp = bpp;       /* this is not bitsPerPixel, it's 8,15,16,32 */
 866        state->width = width;
 867        state->height = height;
 868        /*
 869         * Extended RIVA registers.
 870         */
 871        pixelDepth = (bpp + 1) / 8;
 872        if (par->twoStagePLL)
 873                CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB,
 874                                 par);
 875        else
 876                CalcVClock(dotClock, &VClk, &state->pll, par);
 877
 878        switch (par->Architecture) {
 879        case NV_ARCH_04:
 880                nv4UpdateArbitrationSettings(VClk,
 881                                             pixelDepth * 8,
 882                                             &(state->arbitration0),
 883                                             &(state->arbitration1), par);
 884                state->cursor0 = 0x00;
 885                state->cursor1 = 0xbC;
 886                if (flags & FB_VMODE_DOUBLE)
 887                        state->cursor1 |= 2;
 888                state->cursor2 = 0x00000000;
 889                state->pllsel = 0x10000700;
 890                state->config = 0x00001114;
 891                state->general = bpp == 16 ? 0x00101100 : 0x00100100;
 892                state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
 893                break;
 894        case NV_ARCH_40:
 895                if (!par->FlatPanel)
 896                        state->control = NV_RD32(par->PRAMDAC0, 0x0580) &
 897                                0xeffffeff;
 898                /* fallthrough */
 899        case NV_ARCH_10:
 900        case NV_ARCH_20:
 901        case NV_ARCH_30:
 902        default:
 903                if ((par->Chipset & 0xfff0) == 0x0240 ||
 904                    (par->Chipset & 0xfff0) == 0x03d0) {
 905                        state->arbitration0 = 256;
 906                        state->arbitration1 = 0x0480;
 907                } else if (((par->Chipset & 0xffff) == 0x01A0) ||
 908                    ((par->Chipset & 0xffff) == 0x01f0)) {
 909                        nForceUpdateArbitrationSettings(VClk,
 910                                                        pixelDepth * 8,
 911                                                        &(state->arbitration0),
 912                                                        &(state->arbitration1),
 913                                                        par);
 914                } else if (par->Architecture < NV_ARCH_30) {
 915                        nv10UpdateArbitrationSettings(VClk,
 916                                                      pixelDepth * 8,
 917                                                      &(state->arbitration0),
 918                                                      &(state->arbitration1),
 919                                                      par);
 920                } else {
 921                        nv30UpdateArbitrationSettings(par,
 922                                                      &(state->arbitration0),
 923                                                      &(state->arbitration1));
 924                }
 925
 926                state->cursor0 = 0x80 | (par->CursorStart >> 17);
 927                state->cursor1 = (par->CursorStart >> 11) << 2;
 928                state->cursor2 = par->CursorStart >> 24;
 929                if (flags & FB_VMODE_DOUBLE)
 930                        state->cursor1 |= 2;
 931                state->pllsel = 0x10000700;
 932                state->config = NV_RD32(par->PFB, 0x00000200);
 933                state->general = bpp == 16 ? 0x00101100 : 0x00100100;
 934                state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
 935                break;
 936        }
 937
 938        if (bpp != 8)           /* DirectColor */
 939                state->general |= 0x00000030;
 940
 941        state->repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3;
 942        state->pixel = (pixelDepth > 2) ? 3 : pixelDepth;
 943}
 944
 945void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
 946{
 947        int i, j;
 948
 949        NV_WR32(par->PMC, 0x0140, 0x00000000);
 950        NV_WR32(par->PMC, 0x0200, 0xFFFF00FF);
 951        NV_WR32(par->PMC, 0x0200, 0xFFFFFFFF);
 952
 953        NV_WR32(par->PTIMER, 0x0200 * 4, 0x00000008);
 954        NV_WR32(par->PTIMER, 0x0210 * 4, 0x00000003);
 955        NV_WR32(par->PTIMER, 0x0140 * 4, 0x00000000);
 956        NV_WR32(par->PTIMER, 0x0100 * 4, 0xFFFFFFFF);
 957
 958        if (par->Architecture == NV_ARCH_04) {
 959                if (state)
 960                        NV_WR32(par->PFB, 0x0200, state->config);
 961        } else if ((par->Architecture < NV_ARCH_40) ||
 962                   (par->Chipset & 0xfff0) == 0x0040) {
 963                for (i = 0; i < 8; i++) {
 964                        NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
 965                        NV_WR32(par->PFB, 0x0244 + (i * 0x10),
 966                                par->FbMapSize - 1);
 967                }
 968        } else {
 969                int regions = 12;
 970
 971                if (((par->Chipset & 0xfff0) == 0x0090) ||
 972                    ((par->Chipset & 0xfff0) == 0x01D0) ||
 973                    ((par->Chipset & 0xfff0) == 0x0290) ||
 974                    ((par->Chipset & 0xfff0) == 0x0390) ||
 975                    ((par->Chipset & 0xfff0) == 0x03D0))
 976                        regions = 15;
 977                for(i = 0; i < regions; i++) {
 978                        NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
 979                        NV_WR32(par->PFB, 0x0604 + (i * 0x10),
 980                                par->FbMapSize - 1);
 981                }
 982        }
 983
 984        if (par->Architecture >= NV_ARCH_40) {
 985                NV_WR32(par->PRAMIN, 0x0000 * 4, 0x80000010);
 986                NV_WR32(par->PRAMIN, 0x0001 * 4, 0x00101202);
 987                NV_WR32(par->PRAMIN, 0x0002 * 4, 0x80000011);
 988                NV_WR32(par->PRAMIN, 0x0003 * 4, 0x00101204);
 989                NV_WR32(par->PRAMIN, 0x0004 * 4, 0x80000012);
 990                NV_WR32(par->PRAMIN, 0x0005 * 4, 0x00101206);
 991                NV_WR32(par->PRAMIN, 0x0006 * 4, 0x80000013);
 992                NV_WR32(par->PRAMIN, 0x0007 * 4, 0x00101208);
 993                NV_WR32(par->PRAMIN, 0x0008 * 4, 0x80000014);
 994                NV_WR32(par->PRAMIN, 0x0009 * 4, 0x0010120A);
 995                NV_WR32(par->PRAMIN, 0x000A * 4, 0x80000015);
 996                NV_WR32(par->PRAMIN, 0x000B * 4, 0x0010120C);
 997                NV_WR32(par->PRAMIN, 0x000C * 4, 0x80000016);
 998                NV_WR32(par->PRAMIN, 0x000D * 4, 0x0010120E);
 999                NV_WR32(par->PRAMIN, 0x000E * 4, 0x80000017);
1000                NV_WR32(par->PRAMIN, 0x000F * 4, 0x00101210);
1001                NV_WR32(par->PRAMIN, 0x0800 * 4, 0x00003000);
1002                NV_WR32(par->PRAMIN, 0x0801 * 4, par->FbMapSize - 1);
1003                NV_WR32(par->PRAMIN, 0x0802 * 4, 0x00000002);
1004                NV_WR32(par->PRAMIN, 0x0808 * 4, 0x02080062);
1005                NV_WR32(par->PRAMIN, 0x0809 * 4, 0x00000000);
1006                NV_WR32(par->PRAMIN, 0x080A * 4, 0x00001200);
1007                NV_WR32(par->PRAMIN, 0x080B * 4, 0x00001200);
1008                NV_WR32(par->PRAMIN, 0x080C * 4, 0x00000000);
1009                NV_WR32(par->PRAMIN, 0x080D * 4, 0x00000000);
1010                NV_WR32(par->PRAMIN, 0x0810 * 4, 0x02080043);
1011                NV_WR32(par->PRAMIN, 0x0811 * 4, 0x00000000);
1012                NV_WR32(par->PRAMIN, 0x0812 * 4, 0x00000000);
1013                NV_WR32(par->PRAMIN, 0x0813 * 4, 0x00000000);
1014                NV_WR32(par->PRAMIN, 0x0814 * 4, 0x00000000);
1015                NV_WR32(par->PRAMIN, 0x0815 * 4, 0x00000000);
1016                NV_WR32(par->PRAMIN, 0x0818 * 4, 0x02080044);
1017                NV_WR32(par->PRAMIN, 0x0819 * 4, 0x02000000);
1018                NV_WR32(par->PRAMIN, 0x081A * 4, 0x00000000);
1019                NV_WR32(par->PRAMIN, 0x081B * 4, 0x00000000);
1020                NV_WR32(par->PRAMIN, 0x081C * 4, 0x00000000);
1021                NV_WR32(par->PRAMIN, 0x081D * 4, 0x00000000);
1022                NV_WR32(par->PRAMIN, 0x0820 * 4, 0x02080019);
1023                NV_WR32(par->PRAMIN, 0x0821 * 4, 0x00000000);
1024                NV_WR32(par->PRAMIN, 0x0822 * 4, 0x00000000);
1025                NV_WR32(par->PRAMIN, 0x0823 * 4, 0x00000000);
1026                NV_WR32(par->PRAMIN, 0x0824 * 4, 0x00000000);
1027                NV_WR32(par->PRAMIN, 0x0825 * 4, 0x00000000);
1028                NV_WR32(par->PRAMIN, 0x0828 * 4, 0x020A005C);
1029                NV_WR32(par->PRAMIN, 0x0829 * 4, 0x00000000);
1030                NV_WR32(par->PRAMIN, 0x082A * 4, 0x00000000);
1031                NV_WR32(par->PRAMIN, 0x082B * 4, 0x00000000);
1032                NV_WR32(par->PRAMIN, 0x082C * 4, 0x00000000);
1033                NV_WR32(par->PRAMIN, 0x082D * 4, 0x00000000);
1034                NV_WR32(par->PRAMIN, 0x0830 * 4, 0x0208009F);
1035                NV_WR32(par->PRAMIN, 0x0831 * 4, 0x00000000);
1036                NV_WR32(par->PRAMIN, 0x0832 * 4, 0x00001200);
1037                NV_WR32(par->PRAMIN, 0x0833 * 4, 0x00001200);
1038                NV_WR32(par->PRAMIN, 0x0834 * 4, 0x00000000);
1039                NV_WR32(par->PRAMIN, 0x0835 * 4, 0x00000000);
1040                NV_WR32(par->PRAMIN, 0x0838 * 4, 0x0208004A);
1041                NV_WR32(par->PRAMIN, 0x0839 * 4, 0x02000000);
1042                NV_WR32(par->PRAMIN, 0x083A * 4, 0x00000000);
1043                NV_WR32(par->PRAMIN, 0x083B * 4, 0x00000000);
1044                NV_WR32(par->PRAMIN, 0x083C * 4, 0x00000000);
1045                NV_WR32(par->PRAMIN, 0x083D * 4, 0x00000000);
1046                NV_WR32(par->PRAMIN, 0x0840 * 4, 0x02080077);
1047                NV_WR32(par->PRAMIN, 0x0841 * 4, 0x00000000);
1048                NV_WR32(par->PRAMIN, 0x0842 * 4, 0x00001200);
1049                NV_WR32(par->PRAMIN, 0x0843 * 4, 0x00001200);
1050                NV_WR32(par->PRAMIN, 0x0844 * 4, 0x00000000);
1051                NV_WR32(par->PRAMIN, 0x0845 * 4, 0x00000000);
1052                NV_WR32(par->PRAMIN, 0x084C * 4, 0x00003002);
1053                NV_WR32(par->PRAMIN, 0x084D * 4, 0x00007FFF);
1054                NV_WR32(par->PRAMIN, 0x084E * 4,
1055                        par->FbUsableSize | 0x00000002);
1056
1057#ifdef __BIG_ENDIAN
1058                NV_WR32(par->PRAMIN, 0x080A * 4,
1059                        NV_RD32(par->PRAMIN, 0x080A * 4) | 0x01000000);
1060                NV_WR32(par->PRAMIN, 0x0812 * 4,
1061                        NV_RD32(par->PRAMIN, 0x0812 * 4) | 0x01000000);
1062                NV_WR32(par->PRAMIN, 0x081A * 4,
1063                        NV_RD32(par->PRAMIN, 0x081A * 4) | 0x01000000);
1064                NV_WR32(par->PRAMIN, 0x0822 * 4,
1065                        NV_RD32(par->PRAMIN, 0x0822 * 4) | 0x01000000);
1066                NV_WR32(par->PRAMIN, 0x082A * 4,
1067                        NV_RD32(par->PRAMIN, 0x082A * 4) | 0x01000000);
1068                NV_WR32(par->PRAMIN, 0x0832 * 4,
1069                        NV_RD32(par->PRAMIN, 0x0832 * 4) | 0x01000000);
1070                NV_WR32(par->PRAMIN, 0x083A * 4,
1071                        NV_RD32(par->PRAMIN, 0x083A * 4) | 0x01000000);
1072                NV_WR32(par->PRAMIN, 0x0842 * 4,
1073                        NV_RD32(par->PRAMIN, 0x0842 * 4) | 0x01000000);
1074                NV_WR32(par->PRAMIN, 0x0819 * 4, 0x01000000);
1075                NV_WR32(par->PRAMIN, 0x0839 * 4, 0x01000000);
1076#endif
1077        } else {
1078                NV_WR32(par->PRAMIN, 0x0000 * 4, 0x80000010);
1079                NV_WR32(par->PRAMIN, 0x0001 * 4, 0x80011201);
1080                NV_WR32(par->PRAMIN, 0x0002 * 4, 0x80000011);
1081                NV_WR32(par->PRAMIN, 0x0003 * 4, 0x80011202);
1082                NV_WR32(par->PRAMIN, 0x0004 * 4, 0x80000012);
1083                NV_WR32(par->PRAMIN, 0x0005 * 4, 0x80011203);
1084                NV_WR32(par->PRAMIN, 0x0006 * 4, 0x80000013);
1085                NV_WR32(par->PRAMIN, 0x0007 * 4, 0x80011204);
1086                NV_WR32(par->PRAMIN, 0x0008 * 4, 0x80000014);
1087                NV_WR32(par->PRAMIN, 0x0009 * 4, 0x80011205);
1088                NV_WR32(par->PRAMIN, 0x000A * 4, 0x80000015);
1089                NV_WR32(par->PRAMIN, 0x000B * 4, 0x80011206);
1090                NV_WR32(par->PRAMIN, 0x000C * 4, 0x80000016);
1091                NV_WR32(par->PRAMIN, 0x000D * 4, 0x80011207);
1092                NV_WR32(par->PRAMIN, 0x000E * 4, 0x80000017);
1093                NV_WR32(par->PRAMIN, 0x000F * 4, 0x80011208);
1094                NV_WR32(par->PRAMIN, 0x0800 * 4, 0x00003000);
1095                NV_WR32(par->PRAMIN, 0x0801 * 4, par->FbMapSize - 1);
1096                NV_WR32(par->PRAMIN, 0x0802 * 4, 0x00000002);
1097                NV_WR32(par->PRAMIN, 0x0803 * 4, 0x00000002);
1098                if (par->Architecture >= NV_ARCH_10)
1099                        NV_WR32(par->PRAMIN, 0x0804 * 4, 0x01008062);
1100                else
1101                        NV_WR32(par->PRAMIN, 0x0804 * 4, 0x01008042);
1102                NV_WR32(par->PRAMIN, 0x0805 * 4, 0x00000000);
1103                NV_WR32(par->PRAMIN, 0x0806 * 4, 0x12001200);
1104                NV_WR32(par->PRAMIN, 0x0807 * 4, 0x00000000);
1105                NV_WR32(par->PRAMIN, 0x0808 * 4, 0x01008043);
1106                NV_WR32(par->PRAMIN, 0x0809 * 4, 0x00000000);
1107                NV_WR32(par->PRAMIN, 0x080A * 4, 0x00000000);
1108                NV_WR32(par->PRAMIN, 0x080B * 4, 0x00000000);
1109                NV_WR32(par->PRAMIN, 0x080C * 4, 0x01008044);
1110                NV_WR32(par->PRAMIN, 0x080D * 4, 0x00000002);
1111                NV_WR32(par->PRAMIN, 0x080E * 4, 0x00000000);
1112                NV_WR32(par->PRAMIN, 0x080F * 4, 0x00000000);
1113                NV_WR32(par->PRAMIN, 0x0810 * 4, 0x01008019);
1114                NV_WR32(par->PRAMIN, 0x0811 * 4, 0x00000000);
1115                NV_WR32(par->PRAMIN, 0x0812 * 4, 0x00000000);
1116                NV_WR32(par->PRAMIN, 0x0813 * 4, 0x00000000);
1117                NV_WR32(par->PRAMIN, 0x0814 * 4, 0x0100A05C);
1118                NV_WR32(par->PRAMIN, 0x0815 * 4, 0x00000000);
1119                NV_WR32(par->PRAMIN, 0x0816 * 4, 0x00000000);
1120                NV_WR32(par->PRAMIN, 0x0817 * 4, 0x00000000);
1121                if (par->WaitVSyncPossible)
1122                        NV_WR32(par->PRAMIN, 0x0818 * 4, 0x0100809F);
1123                else
1124                        NV_WR32(par->PRAMIN, 0x0818 * 4, 0x0100805F);
1125                NV_WR32(par->PRAMIN, 0x0819 * 4, 0x00000000);
1126                NV_WR32(par->PRAMIN, 0x081A * 4, 0x12001200);
1127                NV_WR32(par->PRAMIN, 0x081B * 4, 0x00000000);
1128                NV_WR32(par->PRAMIN, 0x081C * 4, 0x0100804A);
1129                NV_WR32(par->PRAMIN, 0x081D * 4, 0x00000002);
1130                NV_WR32(par->PRAMIN, 0x081E * 4, 0x00000000);
1131                NV_WR32(par->PRAMIN, 0x081F * 4, 0x00000000);
1132                NV_WR32(par->PRAMIN, 0x0820 * 4, 0x01018077);
1133                NV_WR32(par->PRAMIN, 0x0821 * 4, 0x00000000);
1134                NV_WR32(par->PRAMIN, 0x0822 * 4, 0x12001200);
1135                NV_WR32(par->PRAMIN, 0x0823 * 4, 0x00000000);
1136                NV_WR32(par->PRAMIN, 0x0824 * 4, 0x00003002);
1137                NV_WR32(par->PRAMIN, 0x0825 * 4, 0x00007FFF);
1138                NV_WR32(par->PRAMIN, 0x0826 * 4,
1139                        par->FbUsableSize | 0x00000002);
1140                NV_WR32(par->PRAMIN, 0x0827 * 4, 0x00000002);
1141#ifdef __BIG_ENDIAN
1142                NV_WR32(par->PRAMIN, 0x0804 * 4,
1143                        NV_RD32(par->PRAMIN, 0x0804 * 4) | 0x00080000);
1144                NV_WR32(par->PRAMIN, 0x0808 * 4,
1145                        NV_RD32(par->PRAMIN, 0x0808 * 4) | 0x00080000);
1146                NV_WR32(par->PRAMIN, 0x080C * 4,
1147                        NV_RD32(par->PRAMIN, 0x080C * 4) | 0x00080000);
1148                NV_WR32(par->PRAMIN, 0x0810 * 4,
1149                        NV_RD32(par->PRAMIN, 0x0810 * 4) | 0x00080000);
1150                NV_WR32(par->PRAMIN, 0x0814 * 4,
1151                        NV_RD32(par->PRAMIN, 0x0814 * 4) | 0x00080000);
1152                NV_WR32(par->PRAMIN, 0x0818 * 4,
1153                        NV_RD32(par->PRAMIN, 0x0818 * 4) | 0x00080000);
1154                NV_WR32(par->PRAMIN, 0x081C * 4,
1155                        NV_RD32(par->PRAMIN, 0x081C * 4) | 0x00080000);
1156                NV_WR32(par->PRAMIN, 0x0820 * 4,
1157                        NV_RD32(par->PRAMIN, 0x0820 * 4) | 0x00080000);
1158                NV_WR32(par->PRAMIN, 0x080D * 4, 0x00000001);
1159                NV_WR32(par->PRAMIN, 0x081D * 4, 0x00000001);
1160#endif
1161        }
1162        if (par->Architecture < NV_ARCH_10) {
1163                if ((par->Chipset & 0x0fff) == 0x0020) {
1164                        NV_WR32(par->PRAMIN, 0x0824 * 4,
1165                                NV_RD32(par->PRAMIN, 0x0824 * 4) | 0x00020000);
1166                        NV_WR32(par->PRAMIN, 0x0826 * 4,
1167                                NV_RD32(par->PRAMIN,
1168                                        0x0826 * 4) + par->FbAddress);
1169                }
1170                NV_WR32(par->PGRAPH, 0x0080, 0x000001FF);
1171                NV_WR32(par->PGRAPH, 0x0080, 0x1230C000);
1172                NV_WR32(par->PGRAPH, 0x0084, 0x72111101);
1173                NV_WR32(par->PGRAPH, 0x0088, 0x11D5F071);
1174                NV_WR32(par->PGRAPH, 0x008C, 0x0004FF31);
1175                NV_WR32(par->PGRAPH, 0x008C, 0x4004FF31);
1176                NV_WR32(par->PGRAPH, 0x0140, 0x00000000);
1177                NV_WR32(par->PGRAPH, 0x0100, 0xFFFFFFFF);
1178                NV_WR32(par->PGRAPH, 0x0170, 0x10010100);
1179                NV_WR32(par->PGRAPH, 0x0710, 0xFFFFFFFF);
1180                NV_WR32(par->PGRAPH, 0x0720, 0x00000001);
1181                NV_WR32(par->PGRAPH, 0x0810, 0x00000000);
1182                NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF);
1183        } else {
1184                NV_WR32(par->PGRAPH, 0x0080, 0xFFFFFFFF);
1185                NV_WR32(par->PGRAPH, 0x0080, 0x00000000);
1186
1187                NV_WR32(par->PGRAPH, 0x0140, 0x00000000);
1188                NV_WR32(par->PGRAPH, 0x0100, 0xFFFFFFFF);
1189                NV_WR32(par->PGRAPH, 0x0144, 0x10010100);
1190                NV_WR32(par->PGRAPH, 0x0714, 0xFFFFFFFF);
1191                NV_WR32(par->PGRAPH, 0x0720, 0x00000001);
1192                NV_WR32(par->PGRAPH, 0x0710,
1193                        NV_RD32(par->PGRAPH, 0x0710) & 0x0007ff00);
1194                NV_WR32(par->PGRAPH, 0x0710,
1195                        NV_RD32(par->PGRAPH, 0x0710) | 0x00020100);
1196
1197                if (par->Architecture == NV_ARCH_10) {
1198                        NV_WR32(par->PGRAPH, 0x0084, 0x00118700);
1199                        NV_WR32(par->PGRAPH, 0x0088, 0x24E00810);
1200                        NV_WR32(par->PGRAPH, 0x008C, 0x55DE0030);
1201
1202                        for (i = 0; i < 32; i++)
1203                                NV_WR32(&par->PGRAPH[(0x0B00 / 4) + i], 0,
1204                                        NV_RD32(&par->PFB[(0x0240 / 4) + i],
1205                                                0));
1206
1207                        NV_WR32(par->PGRAPH, 0x640, 0);
1208                        NV_WR32(par->PGRAPH, 0x644, 0);
1209                        NV_WR32(par->PGRAPH, 0x684, par->FbMapSize - 1);
1210                        NV_WR32(par->PGRAPH, 0x688, par->FbMapSize - 1);
1211
1212                        NV_WR32(par->PGRAPH, 0x0810, 0x00000000);
1213                        NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF);
1214                } else {
1215                        if (par->Architecture >= NV_ARCH_40) {
1216                                NV_WR32(par->PGRAPH, 0x0084, 0x401287c0);
1217                                NV_WR32(par->PGRAPH, 0x008C, 0x60de8051);
1218                                NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
1219                                NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);
1220                                NV_WR32(par->PGRAPH, 0x0bc4,
1221                                        NV_RD32(par->PGRAPH, 0x0bc4) |
1222                                        0x00008000);
1223
1224                                j = NV_RD32(par->REGS, 0x1540) & 0xff;
1225
1226                                if (j) {
1227                                        for (i = 0; !(j & 1); j >>= 1, i++);
1228                                        NV_WR32(par->PGRAPH, 0x5000, i);
1229                                }
1230
1231                                if ((par->Chipset & 0xfff0) == 0x0040) {
1232                                        NV_WR32(par->PGRAPH, 0x09b0,
1233                                                0x83280fff);
1234                                        NV_WR32(par->PGRAPH, 0x09b4,
1235                                                0x000000a0);
1236                                } else {
1237                                        NV_WR32(par->PGRAPH, 0x0820,
1238                                                0x83280eff);
1239                                        NV_WR32(par->PGRAPH, 0x0824,
1240                                                0x000000a0);
1241                                }
1242
1243                                switch (par->Chipset & 0xfff0) {
1244                                case 0x0040:
1245                                case 0x0210:
1246                                        NV_WR32(par->PGRAPH, 0x09b8,
1247                                                0x0078e366);
1248                                        NV_WR32(par->PGRAPH, 0x09bc,
1249                                                0x0000014c);
1250                                        NV_WR32(par->PFB, 0x033C,
1251                                                NV_RD32(par->PFB, 0x33C) &
1252                                                0xffff7fff);
1253                                        break;
1254                                case 0x00C0:
1255                                case 0x0120:
1256                                        NV_WR32(par->PGRAPH, 0x0828,
1257                                                0x007596ff);
1258                                        NV_WR32(par->PGRAPH, 0x082C,
1259                                                0x00000108);
1260                                        break;
1261                                case 0x0160:
1262                                case 0x01D0:
1263                                case 0x0240:
1264                                case 0x03D0:
1265                                        NV_WR32(par->PMC, 0x1700,
1266                                                NV_RD32(par->PFB, 0x020C));
1267                                        NV_WR32(par->PMC, 0x1704, 0);
1268                                        NV_WR32(par->PMC, 0x1708, 0);
1269                                        NV_WR32(par->PMC, 0x170C,
1270                                                NV_RD32(par->PFB, 0x020C));
1271                                        NV_WR32(par->PGRAPH, 0x0860, 0);
1272                                        NV_WR32(par->PGRAPH, 0x0864, 0);
1273                                        NV_WR32(par->PRAMDAC, 0x0608,
1274                                                NV_RD32(par->PRAMDAC,
1275                                                        0x0608) | 0x00100000);
1276                                        break;
1277                                case 0x0140:
1278                                        NV_WR32(par->PGRAPH, 0x0828,
1279                                                0x0072cb77);
1280                                        NV_WR32(par->PGRAPH, 0x082C,
1281                                                0x00000108);
1282                                        break;
1283                                case 0x0220:
1284                                        NV_WR32(par->PGRAPH, 0x0860, 0);
1285                                        NV_WR32(par->PGRAPH, 0x0864, 0);
1286                                        NV_WR32(par->PRAMDAC, 0x0608,
1287                                                NV_RD32(par->PRAMDAC, 0x0608) |
1288                                                0x00100000);
1289                                        break;
1290                                case 0x0090:
1291                                case 0x0290:
1292                                case 0x0390:
1293                                        NV_WR32(par->PRAMDAC, 0x0608,
1294                                                NV_RD32(par->PRAMDAC, 0x0608) |
1295                                                0x00100000);
1296                                        NV_WR32(par->PGRAPH, 0x0828,
1297                                                0x07830610);
1298                                        NV_WR32(par->PGRAPH, 0x082C,
1299                                                0x0000016A);
1300                                        break;
1301                                default:
1302                                        break;
1303                                };
1304
1305                                NV_WR32(par->PGRAPH, 0x0b38, 0x2ffff800);
1306                                NV_WR32(par->PGRAPH, 0x0b3c, 0x00006000);
1307                                NV_WR32(par->PGRAPH, 0x032C, 0x01000000);
1308                                NV_WR32(par->PGRAPH, 0x0220, 0x00001200);
1309                        } else if (par->Architecture == NV_ARCH_30) {
1310                                NV_WR32(par->PGRAPH, 0x0084, 0x40108700);
1311                                NV_WR32(par->PGRAPH, 0x0890, 0x00140000);
1312                                NV_WR32(par->PGRAPH, 0x008C, 0xf00e0431);
1313                                NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
1314                                NV_WR32(par->PGRAPH, 0x0610, 0xf04b1f36);
1315                                NV_WR32(par->PGRAPH, 0x0B80, 0x1002d888);
1316                                NV_WR32(par->PGRAPH, 0x0B88, 0x62ff007f);
1317                        } else {
1318                                NV_WR32(par->PGRAPH, 0x0084, 0x00118700);
1319                                NV_WR32(par->PGRAPH, 0x008C, 0xF20E0431);
1320                                NV_WR32(par->PGRAPH, 0x0090, 0x00000000);
1321                                NV_WR32(par->PGRAPH, 0x009C, 0x00000040);
1322
1323                                if ((par->Chipset & 0x0ff0) >= 0x0250) {
1324                                        NV_WR32(par->PGRAPH, 0x0890,
1325                                                0x00080000);
1326                                        NV_WR32(par->PGRAPH, 0x0610,
1327                                                0x304B1FB6);
1328                                        NV_WR32(par->PGRAPH, 0x0B80,
1329                                                0x18B82880);
1330                                        NV_WR32(par->PGRAPH, 0x0B84,
1331                                                0x44000000);
1332                                        NV_WR32(par->PGRAPH, 0x0098,
1333                                                0x40000080);
1334                                        NV_WR32(par->PGRAPH, 0x0B88,
1335                                                0x000000ff);
1336                                } else {
1337                                        NV_WR32(par->PGRAPH, 0x0880,
1338                                                0x00080000);
1339                                        NV_WR32(par->PGRAPH, 0x0094,
1340                                                0x00000005);
1341                                        NV_WR32(par->PGRAPH, 0x0B80,
1342                                                0x45CAA208);
1343                                        NV_WR32(par->PGRAPH, 0x0B84,
1344                                                0x24000000);
1345                                        NV_WR32(par->PGRAPH, 0x0098,
1346                                                0x00000040);
1347                                        NV_WR32(par->PGRAPH, 0x0750,
1348                                                0x00E00038);
1349                                        NV_WR32(par->PGRAPH, 0x0754,
1350                                                0x00000030);
1351                                        NV_WR32(par->PGRAPH, 0x0750,
1352                                                0x00E10038);
1353                                        NV_WR32(par->PGRAPH, 0x0754,
1354                                                0x00000030);
1355                                }
1356                        }
1357
1358                        if ((par->Architecture < NV_ARCH_40) ||
1359                            ((par->Chipset & 0xfff0) == 0x0040)) {
1360                                for (i = 0; i < 32; i++) {
1361                                        NV_WR32(par->PGRAPH, 0x0900 + i*4,
1362                                                NV_RD32(par->PFB, 0x0240 +i*4));
1363                                        NV_WR32(par->PGRAPH, 0x6900 + i*4,
1364                                                NV_RD32(par->PFB, 0x0240 +i*4));
1365                                }
1366                        } else {
1367                                if (((par->Chipset & 0xfff0) == 0x0090) ||
1368                                    ((par->Chipset & 0xfff0) == 0x01D0) ||
1369                                    ((par->Chipset & 0xfff0) == 0x0290) ||
1370                                    ((par->Chipset & 0xfff0) == 0x0390) ||
1371                                    ((par->Chipset & 0xfff0) == 0x03D0)) {
1372                                        for (i = 0; i < 60; i++) {
1373                                                NV_WR32(par->PGRAPH,
1374                                                        0x0D00 + i*4,
1375                                                        NV_RD32(par->PFB,
1376                                                                0x0600 + i*4));
1377                                                NV_WR32(par->PGRAPH,
1378                                                        0x6900 + i*4,
1379                                                        NV_RD32(par->PFB,
1380                                                                0x0600 + i*4));
1381                                        }
1382                                } else {
1383                                        for (i = 0; i < 48; i++) {
1384                                                NV_WR32(par->PGRAPH,
1385                                                        0x0900 + i*4,
1386                                                        NV_RD32(par->PFB,
1387                                                                0x0600 + i*4));
1388                                                if(((par->Chipset & 0xfff0)
1389                                                    != 0x0160) &&
1390                                                   ((par->Chipset & 0xfff0)
1391                                                    != 0x0220) &&
1392                                                   ((par->Chipset & 0xfff0)
1393                                                    != 0x240))
1394                                                        NV_WR32(par->PGRAPH,
1395                                                                0x6900 + i*4,
1396                                                                NV_RD32(par->PFB,
1397                                                                        0x0600 + i*4));
1398                                        }
1399                                }
1400                        }
1401
1402                        if (par->Architecture >= NV_ARCH_40) {
1403                                if ((par->Chipset & 0xfff0) == 0x0040) {
1404                                        NV_WR32(par->PGRAPH, 0x09A4,
1405                                                NV_RD32(par->PFB, 0x0200));
1406                                        NV_WR32(par->PGRAPH, 0x09A8,
1407                                                NV_RD32(par->PFB, 0x0204));
1408                                        NV_WR32(par->PGRAPH, 0x69A4,
1409                                                NV_RD32(par->PFB, 0x0200));
1410                                        NV_WR32(par->PGRAPH, 0x69A8,
1411                                                NV_RD32(par->PFB, 0x0204));
1412
1413                                        NV_WR32(par->PGRAPH, 0x0820, 0);
1414                                        NV_WR32(par->PGRAPH, 0x0824, 0);
1415                                        NV_WR32(par->PGRAPH, 0x0864,
1416                                                par->FbMapSize - 1);
1417                                        NV_WR32(par->PGRAPH, 0x0868,
1418                                                par->FbMapSize - 1);
1419                                } else {
1420                                        if ((par->Chipset & 0xfff0) == 0x0090 ||
1421                                            (par->Chipset & 0xfff0) == 0x01D0 ||
1422                                            (par->Chipset & 0xfff0) == 0x0290 ||
1423                                            (par->Chipset & 0xfff0) == 0x0390) {
1424                                                NV_WR32(par->PGRAPH, 0x0DF0,
1425                                                        NV_RD32(par->PFB, 0x0200));
1426                                                NV_WR32(par->PGRAPH, 0x0DF4,
1427                                                        NV_RD32(par->PFB, 0x0204));
1428                                        } else {
1429                                                NV_WR32(par->PGRAPH, 0x09F0,
1430                                                        NV_RD32(par->PFB, 0x0200));
1431                                                NV_WR32(par->PGRAPH, 0x09F4,
1432                                                        NV_RD32(par->PFB, 0x0204));
1433                                        }
1434                                        NV_WR32(par->PGRAPH, 0x69F0,
1435                                                NV_RD32(par->PFB, 0x0200));
1436                                        NV_WR32(par->PGRAPH, 0x69F4,
1437                                                NV_RD32(par->PFB, 0x0204));
1438
1439                                        NV_WR32(par->PGRAPH, 0x0840, 0);
1440                                        NV_WR32(par->PGRAPH, 0x0844, 0);
1441                                        NV_WR32(par->PGRAPH, 0x08a0,
1442                                                par->FbMapSize - 1);
1443                                        NV_WR32(par->PGRAPH, 0x08a4,
1444                                                par->FbMapSize - 1);
1445                                }
1446                        } else {
1447                                NV_WR32(par->PGRAPH, 0x09A4,
1448                                        NV_RD32(par->PFB, 0x0200));
1449                                NV_WR32(par->PGRAPH, 0x09A8,
1450                                        NV_RD32(par->PFB, 0x0204));
1451                                NV_WR32(par->PGRAPH, 0x0750, 0x00EA0000);
1452                                NV_WR32(par->PGRAPH, 0x0754,
1453                                        NV_RD32(par->PFB, 0x0200));
1454                                NV_WR32(par->PGRAPH, 0x0750, 0x00EA0004);
1455                                NV_WR32(par->PGRAPH, 0x0754,
1456                                        NV_RD32(par->PFB, 0x0204));
1457
1458                                NV_WR32(par->PGRAPH, 0x0820, 0);
1459                                NV_WR32(par->PGRAPH, 0x0824, 0);
1460                                NV_WR32(par->PGRAPH, 0x0864,
1461                                        par->FbMapSize - 1);
1462                                NV_WR32(par->PGRAPH, 0x0868,
1463                                        par->FbMapSize - 1);
1464                        }
1465                        NV_WR32(par->PGRAPH, 0x0B20, 0x00000000);
1466                        NV_WR32(par->PGRAPH, 0x0B04, 0xFFFFFFFF);
1467                }
1468        }
1469        NV_WR32(par->PGRAPH, 0x053C, 0);
1470        NV_WR32(par->PGRAPH, 0x0540, 0);
1471        NV_WR32(par->PGRAPH, 0x0544, 0x00007FFF);
1472        NV_WR32(par->PGRAPH, 0x0548, 0x00007FFF);
1473
1474        NV_WR32(par->PFIFO, 0x0140 * 4, 0x00000000);
1475        NV_WR32(par->PFIFO, 0x0141 * 4, 0x00000001);
1476        NV_WR32(par->PFIFO, 0x0480 * 4, 0x00000000);
1477        NV_WR32(par->PFIFO, 0x0494 * 4, 0x00000000);
1478        if (par->Architecture >= NV_ARCH_40)
1479                NV_WR32(par->PFIFO, 0x0481 * 4, 0x00010000);
1480        else
1481                NV_WR32(par->PFIFO, 0x0481 * 4, 0x00000100);
1482        NV_WR32(par->PFIFO, 0x0490 * 4, 0x00000000);
1483        NV_WR32(par->PFIFO, 0x0491 * 4, 0x00000000);
1484        if (par->Architecture >= NV_ARCH_40)
1485                NV_WR32(par->PFIFO, 0x048B * 4, 0x00001213);
1486        else
1487                NV_WR32(par->PFIFO, 0x048B * 4, 0x00001209);
1488        NV_WR32(par->PFIFO, 0x0400 * 4, 0x00000000);
1489        NV_WR32(par->PFIFO, 0x0414 * 4, 0x00000000);
1490        NV_WR32(par->PFIFO, 0x0084 * 4, 0x03000100);
1491        NV_WR32(par->PFIFO, 0x0085 * 4, 0x00000110);
1492        NV_WR32(par->PFIFO, 0x0086 * 4, 0x00000112);
1493        NV_WR32(par->PFIFO, 0x0143 * 4, 0x0000FFFF);
1494        NV_WR32(par->PFIFO, 0x0496 * 4, 0x0000FFFF);
1495        NV_WR32(par->PFIFO, 0x0050 * 4, 0x00000000);
1496        NV_WR32(par->PFIFO, 0x0040 * 4, 0xFFFFFFFF);
1497        NV_WR32(par->PFIFO, 0x0415 * 4, 0x00000001);
1498        NV_WR32(par->PFIFO, 0x048C * 4, 0x00000000);
1499        NV_WR32(par->PFIFO, 0x04A0 * 4, 0x00000000);
1500#ifdef __BIG_ENDIAN
1501        NV_WR32(par->PFIFO, 0x0489 * 4, 0x800F0078);
1502#else
1503        NV_WR32(par->PFIFO, 0x0489 * 4, 0x000F0078);
1504#endif
1505        NV_WR32(par->PFIFO, 0x0488 * 4, 0x00000001);
1506        NV_WR32(par->PFIFO, 0x0480 * 4, 0x00000001);
1507        NV_WR32(par->PFIFO, 0x0494 * 4, 0x00000001);
1508        NV_WR32(par->PFIFO, 0x0495 * 4, 0x00000001);
1509        NV_WR32(par->PFIFO, 0x0140 * 4, 0x00000001);
1510
1511    if (!state) {
1512            par->CurrentState = NULL;
1513            return;
1514    }
1515
1516        if (par->Architecture >= NV_ARCH_10) {
1517                if (par->twoHeads) {
1518                        NV_WR32(par->PCRTC0, 0x0860, state->head);
1519                        NV_WR32(par->PCRTC0, 0x2860, state->head2);
1520                }
1521                NV_WR32(par->PRAMDAC, 0x0404, NV_RD32(par->PRAMDAC, 0x0404) |
1522                        (1 << 25));
1523
1524                NV_WR32(par->PMC, 0x8704, 1);
1525                NV_WR32(par->PMC, 0x8140, 0);
1526                NV_WR32(par->PMC, 0x8920, 0);
1527                NV_WR32(par->PMC, 0x8924, 0);
1528                NV_WR32(par->PMC, 0x8908, par->FbMapSize - 1);
1529                NV_WR32(par->PMC, 0x890C, par->FbMapSize - 1);
1530                NV_WR32(par->PMC, 0x1588, 0);
1531
1532                NV_WR32(par->PCRTC, 0x0810, state->cursorConfig);
1533                NV_WR32(par->PCRTC, 0x0830, state->displayV - 3);
1534                NV_WR32(par->PCRTC, 0x0834, state->displayV - 1);
1535
1536                if (par->FlatPanel) {
1537                        if ((par->Chipset & 0x0ff0) == 0x0110) {
1538                                NV_WR32(par->PRAMDAC, 0x0528, state->dither);
1539                        } else if (par->twoHeads) {
1540                                NV_WR32(par->PRAMDAC, 0x083C, state->dither);
1541                        }
1542
1543                        VGA_WR08(par->PCIO, 0x03D4, 0x53);
1544                        VGA_WR08(par->PCIO, 0x03D5, state->timingH);
1545                        VGA_WR08(par->PCIO, 0x03D4, 0x54);
1546                        VGA_WR08(par->PCIO, 0x03D5, state->timingV);
1547                        VGA_WR08(par->PCIO, 0x03D4, 0x21);
1548                        VGA_WR08(par->PCIO, 0x03D5, 0xfa);
1549                }
1550
1551                VGA_WR08(par->PCIO, 0x03D4, 0x41);
1552                VGA_WR08(par->PCIO, 0x03D5, state->extra);
1553        }
1554
1555        VGA_WR08(par->PCIO, 0x03D4, 0x19);
1556        VGA_WR08(par->PCIO, 0x03D5, state->repaint0);
1557        VGA_WR08(par->PCIO, 0x03D4, 0x1A);
1558        VGA_WR08(par->PCIO, 0x03D5, state->repaint1);
1559        VGA_WR08(par->PCIO, 0x03D4, 0x25);
1560        VGA_WR08(par->PCIO, 0x03D5, state->screen);
1561        VGA_WR08(par->PCIO, 0x03D4, 0x28);
1562        VGA_WR08(par->PCIO, 0x03D5, state->pixel);
1563        VGA_WR08(par->PCIO, 0x03D4, 0x2D);
1564        VGA_WR08(par->PCIO, 0x03D5, state->horiz);
1565        VGA_WR08(par->PCIO, 0x03D4, 0x1C);
1566        VGA_WR08(par->PCIO, 0x03D5, state->fifo);
1567        VGA_WR08(par->PCIO, 0x03D4, 0x1B);
1568        VGA_WR08(par->PCIO, 0x03D5, state->arbitration0);
1569        VGA_WR08(par->PCIO, 0x03D4, 0x20);
1570        VGA_WR08(par->PCIO, 0x03D5, state->arbitration1);
1571
1572        if(par->Architecture >= NV_ARCH_30) {
1573                VGA_WR08(par->PCIO, 0x03D4, 0x47);
1574                VGA_WR08(par->PCIO, 0x03D5, state->arbitration1 >> 8);
1575        }
1576
1577        VGA_WR08(par->PCIO, 0x03D4, 0x30);
1578        VGA_WR08(par->PCIO, 0x03D5, state->cursor0);
1579        VGA_WR08(par->PCIO, 0x03D4, 0x31);
1580        VGA_WR08(par->PCIO, 0x03D5, state->cursor1);
1581        VGA_WR08(par->PCIO, 0x03D4, 0x2F);
1582        VGA_WR08(par->PCIO, 0x03D5, state->cursor2);
1583        VGA_WR08(par->PCIO, 0x03D4, 0x39);
1584        VGA_WR08(par->PCIO, 0x03D5, state->interlace);
1585
1586        if (!par->FlatPanel) {
1587                if (par->Architecture >= NV_ARCH_40)
1588                        NV_WR32(par->PRAMDAC0, 0x0580, state->control);
1589
1590                NV_WR32(par->PRAMDAC0, 0x050C, state->pllsel);
1591                NV_WR32(par->PRAMDAC0, 0x0508, state->vpll);
1592                if (par->twoHeads)
1593                        NV_WR32(par->PRAMDAC0, 0x0520, state->vpll2);
1594                if (par->twoStagePLL) {
1595                        NV_WR32(par->PRAMDAC0, 0x0578, state->vpllB);
1596                        NV_WR32(par->PRAMDAC0, 0x057C, state->vpll2B);
1597                }
1598        } else {
1599                NV_WR32(par->PRAMDAC, 0x0848, state->scale);
1600                NV_WR32(par->PRAMDAC, 0x0828, state->crtcSync +
1601                        par->PanelTweak);
1602        }
1603
1604        NV_WR32(par->PRAMDAC, 0x0600, state->general);
1605
1606        NV_WR32(par->PCRTC, 0x0140, 0);
1607        NV_WR32(par->PCRTC, 0x0100, 1);
1608
1609        par->CurrentState = state;
1610}
1611
1612void NVUnloadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) {
1613        VGA_WR08(par->PCIO, 0x03D4, 0x19);
1614        state->repaint0 = VGA_RD08(par->PCIO, 0x03D5);
1615        VGA_WR08(par->PCIO, 0x03D4, 0x1A);
1616        state->repaint1 = VGA_RD08(par->PCIO, 0x03D5);
1617        VGA_WR08(par->PCIO, 0x03D4, 0x25);
1618        state->screen = VGA_RD08(par->PCIO, 0x03D5);
1619        VGA_WR08(par->PCIO, 0x03D4, 0x28);
1620        state->pixel = VGA_RD08(par->PCIO, 0x03D5);
1621        VGA_WR08(par->PCIO, 0x03D4, 0x2D);
1622        state->horiz = VGA_RD08(par->PCIO, 0x03D5);
1623        VGA_WR08(par->PCIO, 0x03D4, 0x1C);
1624        state->fifo         = VGA_RD08(par->PCIO, 0x03D5);
1625        VGA_WR08(par->PCIO, 0x03D4, 0x1B);
1626        state->arbitration0 = VGA_RD08(par->PCIO, 0x03D5);
1627        VGA_WR08(par->PCIO, 0x03D4, 0x20);
1628        state->arbitration1 = VGA_RD08(par->PCIO, 0x03D5);
1629
1630        if(par->Architecture >= NV_ARCH_30) {
1631                VGA_WR08(par->PCIO, 0x03D4, 0x47);
1632                state->arbitration1 |= (VGA_RD08(par->PCIO, 0x03D5) & 1) << 8;
1633        }
1634
1635        VGA_WR08(par->PCIO, 0x03D4, 0x30);
1636        state->cursor0 = VGA_RD08(par->PCIO, 0x03D5);
1637        VGA_WR08(par->PCIO, 0x03D4, 0x31);
1638        state->cursor1 = VGA_RD08(par->PCIO, 0x03D5);
1639        VGA_WR08(par->PCIO, 0x03D4, 0x2F);
1640        state->cursor2 = VGA_RD08(par->PCIO, 0x03D5);
1641        VGA_WR08(par->PCIO, 0x03D4, 0x39);
1642        state->interlace = VGA_RD08(par->PCIO, 0x03D5);
1643        state->vpll = NV_RD32(par->PRAMDAC0, 0x0508);
1644        if (par->twoHeads)
1645                state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
1646        if (par->twoStagePLL) {
1647                state->vpllB = NV_RD32(par->PRAMDAC0, 0x0578);
1648                state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
1649        }
1650        state->pllsel = NV_RD32(par->PRAMDAC0, 0x050C);
1651        state->general = NV_RD32(par->PRAMDAC, 0x0600);
1652        state->scale = NV_RD32(par->PRAMDAC, 0x0848);
1653        state->config = NV_RD32(par->PFB, 0x0200);
1654
1655        if (par->Architecture >= NV_ARCH_40 && !par->FlatPanel)
1656                state->control  = NV_RD32(par->PRAMDAC0, 0x0580);
1657
1658        if (par->Architecture >= NV_ARCH_10) {
1659                if (par->twoHeads) {
1660                        state->head = NV_RD32(par->PCRTC0, 0x0860);
1661                        state->head2 = NV_RD32(par->PCRTC0, 0x2860);
1662                        VGA_WR08(par->PCIO, 0x03D4, 0x44);
1663                        state->crtcOwner = VGA_RD08(par->PCIO, 0x03D5);
1664                }
1665                VGA_WR08(par->PCIO, 0x03D4, 0x41);
1666                state->extra = VGA_RD08(par->PCIO, 0x03D5);
1667                state->cursorConfig = NV_RD32(par->PCRTC, 0x0810);
1668
1669                if ((par->Chipset & 0x0ff0) == 0x0110) {
1670                        state->dither = NV_RD32(par->PRAMDAC, 0x0528);
1671                } else if (par->twoHeads) {
1672                        state->dither = NV_RD32(par->PRAMDAC, 0x083C);
1673                }
1674
1675                if (par->FlatPanel) {
1676                        VGA_WR08(par->PCIO, 0x03D4, 0x53);
1677                        state->timingH = VGA_RD08(par->PCIO, 0x03D5);
1678                        VGA_WR08(par->PCIO, 0x03D4, 0x54);
1679                        state->timingV = VGA_RD08(par->PCIO, 0x03D5);
1680                }
1681        }
1682}
1683
1684void NVSetStartAddress(struct nvidia_par *par, u32 start)
1685{
1686        NV_WR32(par->PCRTC, 0x800, start);
1687}
1688