linux/drivers/video/fbdev/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        int domain = pci_domain_nr(par->pci_dev->bus);
 687
 688        if ((par->Chipset & 0x0FF0) == 0x01A0) {
 689                unsigned int uMClkPostDiv;
 690                dev = pci_get_domain_bus_and_slot(domain, 0, 3);
 691                pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
 692                uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
 693
 694                if (!uMClkPostDiv)
 695                        uMClkPostDiv = 4;
 696                MClk = 400000 / uMClkPostDiv;
 697        } else {
 698                dev = pci_get_domain_bus_and_slot(domain, 0, 5);
 699                pci_read_config_dword(dev, 0x4c, &MClk);
 700                MClk /= 1000;
 701        }
 702        pci_dev_put(dev);
 703        pll = NV_RD32(par->PRAMDAC0, 0x0500);
 704        M = (pll >> 0) & 0xFF;
 705        N = (pll >> 8) & 0xFF;
 706        P = (pll >> 16) & 0x0F;
 707        NVClk = (N * par->CrystalFreqKHz / M) >> P;
 708        sim_data.pix_bpp = (char)pixelDepth;
 709        sim_data.enable_video = 0;
 710        sim_data.enable_mp = 0;
 711        dev = pci_get_domain_bus_and_slot(domain, 0, 1);
 712        pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
 713        pci_dev_put(dev);
 714        sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
 715        sim_data.memory_width = 64;
 716
 717        dev = pci_get_domain_bus_and_slot(domain, 0, 3);
 718        pci_read_config_dword(dev, 0, &memctrl);
 719        pci_dev_put(dev);
 720        memctrl >>= 16;
 721
 722        if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
 723                u32 dimm[3];
 724
 725                dev = pci_get_domain_bus_and_slot(domain, 0, 2);
 726                pci_read_config_dword(dev, 0x40, &dimm[0]);
 727                dimm[0] = (dimm[0] >> 8) & 0x4f;
 728                pci_read_config_dword(dev, 0x44, &dimm[1]);
 729                dimm[1] = (dimm[1] >> 8) & 0x4f;
 730                pci_read_config_dword(dev, 0x48, &dimm[2]);
 731                dimm[2] = (dimm[2] >> 8) & 0x4f;
 732
 733                if ((dimm[0] + dimm[1]) != dimm[2]) {
 734                        printk("nvidiafb: your nForce DIMMs are not arranged "
 735                               "in optimal banks!\n");
 736                }
 737                pci_dev_put(dev);
 738        }
 739
 740        sim_data.mem_latency = 3;
 741        sim_data.mem_aligned = 1;
 742        sim_data.mem_page_miss = 10;
 743        sim_data.gr_during_vid = 0;
 744        sim_data.pclk_khz = VClk;
 745        sim_data.mclk_khz = MClk;
 746        sim_data.nvclk_khz = NVClk;
 747        nv10CalcArbitration(&fifo_data, &sim_data);
 748        if (fifo_data.valid) {
 749                int b = fifo_data.graphics_burst_size >> 4;
 750                *burst = 0;
 751                while (b >>= 1)
 752                        (*burst)++;
 753                *lwm = fifo_data.graphics_lwm >> 3;
 754        }
 755}
 756
 757/****************************************************************************\
 758*                                                                            *
 759*                          RIVA Mode State Routines                          *
 760*                                                                            *
 761\****************************************************************************/
 762
 763/*
 764 * Calculate the Video Clock parameters for the PLL.
 765 */
 766static void CalcVClock(int clockIn,
 767                       int *clockOut, u32 * pllOut, struct nvidia_par *par)
 768{
 769        unsigned lowM, highM;
 770        unsigned DeltaNew, DeltaOld;
 771        unsigned VClk, Freq;
 772        unsigned M, N, P;
 773
 774        DeltaOld = 0xFFFFFFFF;
 775
 776        VClk = (unsigned)clockIn;
 777
 778        if (par->CrystalFreqKHz == 13500) {
 779                lowM = 7;
 780                highM = 13;
 781        } else {
 782                lowM = 8;
 783                highM = 14;
 784        }
 785
 786        for (P = 0; P <= 4; P++) {
 787                Freq = VClk << P;
 788                if ((Freq >= 128000) && (Freq <= 350000)) {
 789                        for (M = lowM; M <= highM; M++) {
 790                                N = ((VClk << P) * M) / par->CrystalFreqKHz;
 791                                if (N <= 255) {
 792                                        Freq =
 793                                            ((par->CrystalFreqKHz * N) /
 794                                             M) >> P;
 795                                        if (Freq > VClk)
 796                                                DeltaNew = Freq - VClk;
 797                                        else
 798                                                DeltaNew = VClk - Freq;
 799                                        if (DeltaNew < DeltaOld) {
 800                                                *pllOut =
 801                                                    (P << 16) | (N << 8) | M;
 802                                                *clockOut = Freq;
 803                                                DeltaOld = DeltaNew;
 804                                        }
 805                                }
 806                        }
 807                }
 808        }
 809}
 810
 811static void CalcVClock2Stage(int clockIn,
 812                             int *clockOut,
 813                             u32 * pllOut,
 814                             u32 * pllBOut, struct nvidia_par *par)
 815{
 816        unsigned DeltaNew, DeltaOld;
 817        unsigned VClk, Freq;
 818        unsigned M, N, P;
 819
 820        DeltaOld = 0xFFFFFFFF;
 821
 822        *pllBOut = 0x80000401;  /* fixed at x4 for now */
 823
 824        VClk = (unsigned)clockIn;
 825
 826        for (P = 0; P <= 6; P++) {
 827                Freq = VClk << P;
 828                if ((Freq >= 400000) && (Freq <= 1000000)) {
 829                        for (M = 1; M <= 13; M++) {
 830                                N = ((VClk << P) * M) /
 831                                    (par->CrystalFreqKHz << 2);
 832                                if ((N >= 5) && (N <= 255)) {
 833                                        Freq =
 834                                            (((par->CrystalFreqKHz << 2) * N) /
 835                                             M) >> P;
 836                                        if (Freq > VClk)
 837                                                DeltaNew = Freq - VClk;
 838                                        else
 839                                                DeltaNew = VClk - Freq;
 840                                        if (DeltaNew < DeltaOld) {
 841                                                *pllOut =
 842                                                    (P << 16) | (N << 8) | M;
 843                                                *clockOut = Freq;
 844                                                DeltaOld = DeltaNew;
 845                                        }
 846                                }
 847                        }
 848                }
 849        }
 850}
 851
 852/*
 853 * Calculate extended mode parameters (SVGA) and save in a
 854 * mode state structure.
 855 */
 856void NVCalcStateExt(struct nvidia_par *par,
 857                    RIVA_HW_STATE * state,
 858                    int bpp,
 859                    int width,
 860                    int hDisplaySize, int height, int dotClock, int flags)
 861{
 862        int pixelDepth, VClk = 0;
 863        /*
 864         * Save mode parameters.
 865         */
 866        state->bpp = bpp;       /* this is not bitsPerPixel, it's 8,15,16,32 */
 867        state->width = width;
 868        state->height = height;
 869        /*
 870         * Extended RIVA registers.
 871         */
 872        pixelDepth = (bpp + 1) / 8;
 873        if (par->twoStagePLL)
 874                CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB,
 875                                 par);
 876        else
 877                CalcVClock(dotClock, &VClk, &state->pll, par);
 878
 879        switch (par->Architecture) {
 880        case NV_ARCH_04:
 881                nv4UpdateArbitrationSettings(VClk,
 882                                             pixelDepth * 8,
 883                                             &(state->arbitration0),
 884                                             &(state->arbitration1), par);
 885                state->cursor0 = 0x00;
 886                state->cursor1 = 0xbC;
 887                if (flags & FB_VMODE_DOUBLE)
 888                        state->cursor1 |= 2;
 889                state->cursor2 = 0x00000000;
 890                state->pllsel = 0x10000700;
 891                state->config = 0x00001114;
 892                state->general = bpp == 16 ? 0x00101100 : 0x00100100;
 893                state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
 894                break;
 895        case NV_ARCH_40:
 896                if (!par->FlatPanel)
 897                        state->control = NV_RD32(par->PRAMDAC0, 0x0580) &
 898                                0xeffffeff;
 899                fallthrough;
 900        case NV_ARCH_10:
 901        case NV_ARCH_20:
 902        case NV_ARCH_30:
 903        default:
 904                if ((par->Chipset & 0xfff0) == 0x0240 ||
 905                    (par->Chipset & 0xfff0) == 0x03d0) {
 906                        state->arbitration0 = 256;
 907                        state->arbitration1 = 0x0480;
 908                } else if (((par->Chipset & 0xffff) == 0x01A0) ||
 909                    ((par->Chipset & 0xffff) == 0x01f0)) {
 910                        nForceUpdateArbitrationSettings(VClk,
 911                                                        pixelDepth * 8,
 912                                                        &(state->arbitration0),
 913                                                        &(state->arbitration1),
 914                                                        par);
 915                } else if (par->Architecture < NV_ARCH_30) {
 916                        nv10UpdateArbitrationSettings(VClk,
 917                                                      pixelDepth * 8,
 918                                                      &(state->arbitration0),
 919                                                      &(state->arbitration1),
 920                                                      par);
 921                } else {
 922                        nv30UpdateArbitrationSettings(par,
 923                                                      &(state->arbitration0),
 924                                                      &(state->arbitration1));
 925                }
 926
 927                state->cursor0 = 0x80 | (par->CursorStart >> 17);
 928                state->cursor1 = (par->CursorStart >> 11) << 2;
 929                state->cursor2 = par->CursorStart >> 24;
 930                if (flags & FB_VMODE_DOUBLE)
 931                        state->cursor1 |= 2;
 932                state->pllsel = 0x10000700;
 933                state->config = NV_RD32(par->PFB, 0x00000200);
 934                state->general = bpp == 16 ? 0x00101100 : 0x00100100;
 935                state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
 936                break;
 937        }
 938
 939        if (bpp != 8)           /* DirectColor */
 940                state->general |= 0x00000030;
 941
 942        state->repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3;
 943        state->pixel = (pixelDepth > 2) ? 3 : pixelDepth;
 944}
 945
 946void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
 947{
 948        int i, j;
 949
 950        NV_WR32(par->PMC, 0x0140, 0x00000000);
 951        NV_WR32(par->PMC, 0x0200, 0xFFFF00FF);
 952        NV_WR32(par->PMC, 0x0200, 0xFFFFFFFF);
 953
 954        NV_WR32(par->PTIMER, 0x0200 * 4, 0x00000008);
 955        NV_WR32(par->PTIMER, 0x0210 * 4, 0x00000003);
 956        NV_WR32(par->PTIMER, 0x0140 * 4, 0x00000000);
 957        NV_WR32(par->PTIMER, 0x0100 * 4, 0xFFFFFFFF);
 958
 959        if (par->Architecture == NV_ARCH_04) {
 960                if (state)
 961                        NV_WR32(par->PFB, 0x0200, state->config);
 962        } else if ((par->Architecture < NV_ARCH_40) ||
 963                   (par->Chipset & 0xfff0) == 0x0040) {
 964                for (i = 0; i < 8; i++) {
 965                        NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
 966                        NV_WR32(par->PFB, 0x0244 + (i * 0x10),
 967                                par->FbMapSize - 1);
 968                }
 969        } else {
 970                int regions = 12;
 971
 972                if (((par->Chipset & 0xfff0) == 0x0090) ||
 973                    ((par->Chipset & 0xfff0) == 0x01D0) ||
 974                    ((par->Chipset & 0xfff0) == 0x0290) ||
 975                    ((par->Chipset & 0xfff0) == 0x0390) ||
 976                    ((par->Chipset & 0xfff0) == 0x03D0))
 977                        regions = 15;
 978                for(i = 0; i < regions; i++) {
 979                        NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
 980                        NV_WR32(par->PFB, 0x0604 + (i * 0x10),
 981                                par->FbMapSize - 1);
 982                }
 983        }
 984
 985        if (par->Architecture >= NV_ARCH_40) {
 986                NV_WR32(par->PRAMIN, 0x0000 * 4, 0x80000010);
 987                NV_WR32(par->PRAMIN, 0x0001 * 4, 0x00101202);
 988                NV_WR32(par->PRAMIN, 0x0002 * 4, 0x80000011);
 989                NV_WR32(par->PRAMIN, 0x0003 * 4, 0x00101204);
 990                NV_WR32(par->PRAMIN, 0x0004 * 4, 0x80000012);
 991                NV_WR32(par->PRAMIN, 0x0005 * 4, 0x00101206);
 992                NV_WR32(par->PRAMIN, 0x0006 * 4, 0x80000013);
 993                NV_WR32(par->PRAMIN, 0x0007 * 4, 0x00101208);
 994                NV_WR32(par->PRAMIN, 0x0008 * 4, 0x80000014);
 995                NV_WR32(par->PRAMIN, 0x0009 * 4, 0x0010120A);
 996                NV_WR32(par->PRAMIN, 0x000A * 4, 0x80000015);
 997                NV_WR32(par->PRAMIN, 0x000B * 4, 0x0010120C);
 998                NV_WR32(par->PRAMIN, 0x000C * 4, 0x80000016);
 999                NV_WR32(par->PRAMIN, 0x000D * 4, 0x0010120E);
1000                NV_WR32(par->PRAMIN, 0x000E * 4, 0x80000017);
1001                NV_WR32(par->PRAMIN, 0x000F * 4, 0x00101210);
1002                NV_WR32(par->PRAMIN, 0x0800 * 4, 0x00003000);
1003                NV_WR32(par->PRAMIN, 0x0801 * 4, par->FbMapSize - 1);
1004                NV_WR32(par->PRAMIN, 0x0802 * 4, 0x00000002);
1005                NV_WR32(par->PRAMIN, 0x0808 * 4, 0x02080062);
1006                NV_WR32(par->PRAMIN, 0x0809 * 4, 0x00000000);
1007                NV_WR32(par->PRAMIN, 0x080A * 4, 0x00001200);
1008                NV_WR32(par->PRAMIN, 0x080B * 4, 0x00001200);
1009                NV_WR32(par->PRAMIN, 0x080C * 4, 0x00000000);
1010                NV_WR32(par->PRAMIN, 0x080D * 4, 0x00000000);
1011                NV_WR32(par->PRAMIN, 0x0810 * 4, 0x02080043);
1012                NV_WR32(par->PRAMIN, 0x0811 * 4, 0x00000000);
1013                NV_WR32(par->PRAMIN, 0x0812 * 4, 0x00000000);
1014                NV_WR32(par->PRAMIN, 0x0813 * 4, 0x00000000);
1015                NV_WR32(par->PRAMIN, 0x0814 * 4, 0x00000000);
1016                NV_WR32(par->PRAMIN, 0x0815 * 4, 0x00000000);
1017                NV_WR32(par->PRAMIN, 0x0818 * 4, 0x02080044);
1018                NV_WR32(par->PRAMIN, 0x0819 * 4, 0x02000000);
1019                NV_WR32(par->PRAMIN, 0x081A * 4, 0x00000000);
1020                NV_WR32(par->PRAMIN, 0x081B * 4, 0x00000000);
1021                NV_WR32(par->PRAMIN, 0x081C * 4, 0x00000000);
1022                NV_WR32(par->PRAMIN, 0x081D * 4, 0x00000000);
1023                NV_WR32(par->PRAMIN, 0x0820 * 4, 0x02080019);
1024                NV_WR32(par->PRAMIN, 0x0821 * 4, 0x00000000);
1025                NV_WR32(par->PRAMIN, 0x0822 * 4, 0x00000000);
1026                NV_WR32(par->PRAMIN, 0x0823 * 4, 0x00000000);
1027                NV_WR32(par->PRAMIN, 0x0824 * 4, 0x00000000);
1028                NV_WR32(par->PRAMIN, 0x0825 * 4, 0x00000000);
1029                NV_WR32(par->PRAMIN, 0x0828 * 4, 0x020A005C);
1030                NV_WR32(par->PRAMIN, 0x0829 * 4, 0x00000000);
1031                NV_WR32(par->PRAMIN, 0x082A * 4, 0x00000000);
1032                NV_WR32(par->PRAMIN, 0x082B * 4, 0x00000000);
1033                NV_WR32(par->PRAMIN, 0x082C * 4, 0x00000000);
1034                NV_WR32(par->PRAMIN, 0x082D * 4, 0x00000000);
1035                NV_WR32(par->PRAMIN, 0x0830 * 4, 0x0208009F);
1036                NV_WR32(par->PRAMIN, 0x0831 * 4, 0x00000000);
1037                NV_WR32(par->PRAMIN, 0x0832 * 4, 0x00001200);
1038                NV_WR32(par->PRAMIN, 0x0833 * 4, 0x00001200);
1039                NV_WR32(par->PRAMIN, 0x0834 * 4, 0x00000000);
1040                NV_WR32(par->PRAMIN, 0x0835 * 4, 0x00000000);
1041                NV_WR32(par->PRAMIN, 0x0838 * 4, 0x0208004A);
1042                NV_WR32(par->PRAMIN, 0x0839 * 4, 0x02000000);
1043                NV_WR32(par->PRAMIN, 0x083A * 4, 0x00000000);
1044                NV_WR32(par->PRAMIN, 0x083B * 4, 0x00000000);
1045                NV_WR32(par->PRAMIN, 0x083C * 4, 0x00000000);
1046                NV_WR32(par->PRAMIN, 0x083D * 4, 0x00000000);
1047                NV_WR32(par->PRAMIN, 0x0840 * 4, 0x02080077);
1048                NV_WR32(par->PRAMIN, 0x0841 * 4, 0x00000000);
1049                NV_WR32(par->PRAMIN, 0x0842 * 4, 0x00001200);
1050                NV_WR32(par->PRAMIN, 0x0843 * 4, 0x00001200);
1051                NV_WR32(par->PRAMIN, 0x0844 * 4, 0x00000000);
1052                NV_WR32(par->PRAMIN, 0x0845 * 4, 0x00000000);
1053                NV_WR32(par->PRAMIN, 0x084C * 4, 0x00003002);
1054                NV_WR32(par->PRAMIN, 0x084D * 4, 0x00007FFF);
1055                NV_WR32(par->PRAMIN, 0x084E * 4,
1056                        par->FbUsableSize | 0x00000002);
1057
1058#ifdef __BIG_ENDIAN
1059                NV_WR32(par->PRAMIN, 0x080A * 4,
1060                        NV_RD32(par->PRAMIN, 0x080A * 4) | 0x01000000);
1061                NV_WR32(par->PRAMIN, 0x0812 * 4,
1062                        NV_RD32(par->PRAMIN, 0x0812 * 4) | 0x01000000);
1063                NV_WR32(par->PRAMIN, 0x081A * 4,
1064                        NV_RD32(par->PRAMIN, 0x081A * 4) | 0x01000000);
1065                NV_WR32(par->PRAMIN, 0x0822 * 4,
1066                        NV_RD32(par->PRAMIN, 0x0822 * 4) | 0x01000000);
1067                NV_WR32(par->PRAMIN, 0x082A * 4,
1068                        NV_RD32(par->PRAMIN, 0x082A * 4) | 0x01000000);
1069                NV_WR32(par->PRAMIN, 0x0832 * 4,
1070                        NV_RD32(par->PRAMIN, 0x0832 * 4) | 0x01000000);
1071                NV_WR32(par->PRAMIN, 0x083A * 4,
1072                        NV_RD32(par->PRAMIN, 0x083A * 4) | 0x01000000);
1073                NV_WR32(par->PRAMIN, 0x0842 * 4,
1074                        NV_RD32(par->PRAMIN, 0x0842 * 4) | 0x01000000);
1075                NV_WR32(par->PRAMIN, 0x0819 * 4, 0x01000000);
1076                NV_WR32(par->PRAMIN, 0x0839 * 4, 0x01000000);
1077#endif
1078        } else {
1079                NV_WR32(par->PRAMIN, 0x0000 * 4, 0x80000010);
1080                NV_WR32(par->PRAMIN, 0x0001 * 4, 0x80011201);
1081                NV_WR32(par->PRAMIN, 0x0002 * 4, 0x80000011);
1082                NV_WR32(par->PRAMIN, 0x0003 * 4, 0x80011202);
1083                NV_WR32(par->PRAMIN, 0x0004 * 4, 0x80000012);
1084                NV_WR32(par->PRAMIN, 0x0005 * 4, 0x80011203);
1085                NV_WR32(par->PRAMIN, 0x0006 * 4, 0x80000013);
1086                NV_WR32(par->PRAMIN, 0x0007 * 4, 0x80011204);
1087                NV_WR32(par->PRAMIN, 0x0008 * 4, 0x80000014);
1088                NV_WR32(par->PRAMIN, 0x0009 * 4, 0x80011205);
1089                NV_WR32(par->PRAMIN, 0x000A * 4, 0x80000015);
1090                NV_WR32(par->PRAMIN, 0x000B * 4, 0x80011206);
1091                NV_WR32(par->PRAMIN, 0x000C * 4, 0x80000016);
1092                NV_WR32(par->PRAMIN, 0x000D * 4, 0x80011207);
1093                NV_WR32(par->PRAMIN, 0x000E * 4, 0x80000017);
1094                NV_WR32(par->PRAMIN, 0x000F * 4, 0x80011208);
1095                NV_WR32(par->PRAMIN, 0x0800 * 4, 0x00003000);
1096                NV_WR32(par->PRAMIN, 0x0801 * 4, par->FbMapSize - 1);
1097                NV_WR32(par->PRAMIN, 0x0802 * 4, 0x00000002);
1098                NV_WR32(par->PRAMIN, 0x0803 * 4, 0x00000002);
1099                if (par->Architecture >= NV_ARCH_10)
1100                        NV_WR32(par->PRAMIN, 0x0804 * 4, 0x01008062);
1101                else
1102                        NV_WR32(par->PRAMIN, 0x0804 * 4, 0x01008042);
1103                NV_WR32(par->PRAMIN, 0x0805 * 4, 0x00000000);
1104                NV_WR32(par->PRAMIN, 0x0806 * 4, 0x12001200);
1105                NV_WR32(par->PRAMIN, 0x0807 * 4, 0x00000000);
1106                NV_WR32(par->PRAMIN, 0x0808 * 4, 0x01008043);
1107                NV_WR32(par->PRAMIN, 0x0809 * 4, 0x00000000);
1108                NV_WR32(par->PRAMIN, 0x080A * 4, 0x00000000);
1109                NV_WR32(par->PRAMIN, 0x080B * 4, 0x00000000);
1110                NV_WR32(par->PRAMIN, 0x080C * 4, 0x01008044);
1111                NV_WR32(par->PRAMIN, 0x080D * 4, 0x00000002);
1112                NV_WR32(par->PRAMIN, 0x080E * 4, 0x00000000);
1113                NV_WR32(par->PRAMIN, 0x080F * 4, 0x00000000);
1114                NV_WR32(par->PRAMIN, 0x0810 * 4, 0x01008019);
1115                NV_WR32(par->PRAMIN, 0x0811 * 4, 0x00000000);
1116                NV_WR32(par->PRAMIN, 0x0812 * 4, 0x00000000);
1117                NV_WR32(par->PRAMIN, 0x0813 * 4, 0x00000000);
1118                NV_WR32(par->PRAMIN, 0x0814 * 4, 0x0100A05C);
1119                NV_WR32(par->PRAMIN, 0x0815 * 4, 0x00000000);
1120                NV_WR32(par->PRAMIN, 0x0816 * 4, 0x00000000);
1121                NV_WR32(par->PRAMIN, 0x0817 * 4, 0x00000000);
1122                if (par->WaitVSyncPossible)
1123                        NV_WR32(par->PRAMIN, 0x0818 * 4, 0x0100809F);
1124                else
1125                        NV_WR32(par->PRAMIN, 0x0818 * 4, 0x0100805F);
1126                NV_WR32(par->PRAMIN, 0x0819 * 4, 0x00000000);
1127                NV_WR32(par->PRAMIN, 0x081A * 4, 0x12001200);
1128                NV_WR32(par->PRAMIN, 0x081B * 4, 0x00000000);
1129                NV_WR32(par->PRAMIN, 0x081C * 4, 0x0100804A);
1130                NV_WR32(par->PRAMIN, 0x081D * 4, 0x00000002);
1131                NV_WR32(par->PRAMIN, 0x081E * 4, 0x00000000);
1132                NV_WR32(par->PRAMIN, 0x081F * 4, 0x00000000);
1133                NV_WR32(par->PRAMIN, 0x0820 * 4, 0x01018077);
1134                NV_WR32(par->PRAMIN, 0x0821 * 4, 0x00000000);
1135                NV_WR32(par->PRAMIN, 0x0822 * 4, 0x12001200);
1136                NV_WR32(par->PRAMIN, 0x0823 * 4, 0x00000000);
1137                NV_WR32(par->PRAMIN, 0x0824 * 4, 0x00003002);
1138                NV_WR32(par->PRAMIN, 0x0825 * 4, 0x00007FFF);
1139                NV_WR32(par->PRAMIN, 0x0826 * 4,
1140                        par->FbUsableSize | 0x00000002);
1141                NV_WR32(par->PRAMIN, 0x0827 * 4, 0x00000002);
1142#ifdef __BIG_ENDIAN
1143                NV_WR32(par->PRAMIN, 0x0804 * 4,
1144                        NV_RD32(par->PRAMIN, 0x0804 * 4) | 0x00080000);
1145                NV_WR32(par->PRAMIN, 0x0808 * 4,
1146                        NV_RD32(par->PRAMIN, 0x0808 * 4) | 0x00080000);
1147                NV_WR32(par->PRAMIN, 0x080C * 4,
1148                        NV_RD32(par->PRAMIN, 0x080C * 4) | 0x00080000);
1149                NV_WR32(par->PRAMIN, 0x0810 * 4,
1150                        NV_RD32(par->PRAMIN, 0x0810 * 4) | 0x00080000);
1151                NV_WR32(par->PRAMIN, 0x0814 * 4,
1152                        NV_RD32(par->PRAMIN, 0x0814 * 4) | 0x00080000);
1153                NV_WR32(par->PRAMIN, 0x0818 * 4,
1154                        NV_RD32(par->PRAMIN, 0x0818 * 4) | 0x00080000);
1155                NV_WR32(par->PRAMIN, 0x081C * 4,
1156                        NV_RD32(par->PRAMIN, 0x081C * 4) | 0x00080000);
1157                NV_WR32(par->PRAMIN, 0x0820 * 4,
1158                        NV_RD32(par->PRAMIN, 0x0820 * 4) | 0x00080000);
1159                NV_WR32(par->PRAMIN, 0x080D * 4, 0x00000001);
1160                NV_WR32(par->PRAMIN, 0x081D * 4, 0x00000001);
1161#endif
1162        }
1163        if (par->Architecture < NV_ARCH_10) {
1164                if ((par->Chipset & 0x0fff) == 0x0020) {
1165                        NV_WR32(par->PRAMIN, 0x0824 * 4,
1166                                NV_RD32(par->PRAMIN, 0x0824 * 4) | 0x00020000);
1167                        NV_WR32(par->PRAMIN, 0x0826 * 4,
1168                                NV_RD32(par->PRAMIN,
1169                                        0x0826 * 4) + par->FbAddress);
1170                }
1171                NV_WR32(par->PGRAPH, 0x0080, 0x000001FF);
1172                NV_WR32(par->PGRAPH, 0x0080, 0x1230C000);
1173                NV_WR32(par->PGRAPH, 0x0084, 0x72111101);
1174                NV_WR32(par->PGRAPH, 0x0088, 0x11D5F071);
1175                NV_WR32(par->PGRAPH, 0x008C, 0x0004FF31);
1176                NV_WR32(par->PGRAPH, 0x008C, 0x4004FF31);
1177                NV_WR32(par->PGRAPH, 0x0140, 0x00000000);
1178                NV_WR32(par->PGRAPH, 0x0100, 0xFFFFFFFF);
1179                NV_WR32(par->PGRAPH, 0x0170, 0x10010100);
1180                NV_WR32(par->PGRAPH, 0x0710, 0xFFFFFFFF);
1181                NV_WR32(par->PGRAPH, 0x0720, 0x00000001);
1182                NV_WR32(par->PGRAPH, 0x0810, 0x00000000);
1183                NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF);
1184        } else {
1185                NV_WR32(par->PGRAPH, 0x0080, 0xFFFFFFFF);
1186                NV_WR32(par->PGRAPH, 0x0080, 0x00000000);
1187
1188                NV_WR32(par->PGRAPH, 0x0140, 0x00000000);
1189                NV_WR32(par->PGRAPH, 0x0100, 0xFFFFFFFF);
1190                NV_WR32(par->PGRAPH, 0x0144, 0x10010100);
1191                NV_WR32(par->PGRAPH, 0x0714, 0xFFFFFFFF);
1192                NV_WR32(par->PGRAPH, 0x0720, 0x00000001);
1193                NV_WR32(par->PGRAPH, 0x0710,
1194                        NV_RD32(par->PGRAPH, 0x0710) & 0x0007ff00);
1195                NV_WR32(par->PGRAPH, 0x0710,
1196                        NV_RD32(par->PGRAPH, 0x0710) | 0x00020100);
1197
1198                if (par->Architecture == NV_ARCH_10) {
1199                        NV_WR32(par->PGRAPH, 0x0084, 0x00118700);
1200                        NV_WR32(par->PGRAPH, 0x0088, 0x24E00810);
1201                        NV_WR32(par->PGRAPH, 0x008C, 0x55DE0030);
1202
1203                        for (i = 0; i < 32; i++)
1204                                NV_WR32(&par->PGRAPH[(0x0B00 / 4) + i], 0,
1205                                        NV_RD32(&par->PFB[(0x0240 / 4) + i],
1206                                                0));
1207
1208                        NV_WR32(par->PGRAPH, 0x640, 0);
1209                        NV_WR32(par->PGRAPH, 0x644, 0);
1210                        NV_WR32(par->PGRAPH, 0x684, par->FbMapSize - 1);
1211                        NV_WR32(par->PGRAPH, 0x688, par->FbMapSize - 1);
1212
1213                        NV_WR32(par->PGRAPH, 0x0810, 0x00000000);
1214                        NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF);
1215                } else {
1216                        if (par->Architecture >= NV_ARCH_40) {
1217                                NV_WR32(par->PGRAPH, 0x0084, 0x401287c0);
1218                                NV_WR32(par->PGRAPH, 0x008C, 0x60de8051);
1219                                NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
1220                                NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);
1221                                NV_WR32(par->PGRAPH, 0x0bc4,
1222                                        NV_RD32(par->PGRAPH, 0x0bc4) |
1223                                        0x00008000);
1224
1225                                j = NV_RD32(par->REGS, 0x1540) & 0xff;
1226
1227                                if (j) {
1228                                        for (i = 0; !(j & 1); j >>= 1, i++);
1229                                        NV_WR32(par->PGRAPH, 0x5000, i);
1230                                }
1231
1232                                if ((par->Chipset & 0xfff0) == 0x0040) {
1233                                        NV_WR32(par->PGRAPH, 0x09b0,
1234                                                0x83280fff);
1235                                        NV_WR32(par->PGRAPH, 0x09b4,
1236                                                0x000000a0);
1237                                } else {
1238                                        NV_WR32(par->PGRAPH, 0x0820,
1239                                                0x83280eff);
1240                                        NV_WR32(par->PGRAPH, 0x0824,
1241                                                0x000000a0);
1242                                }
1243
1244                                switch (par->Chipset & 0xfff0) {
1245                                case 0x0040:
1246                                case 0x0210:
1247                                        NV_WR32(par->PGRAPH, 0x09b8,
1248                                                0x0078e366);
1249                                        NV_WR32(par->PGRAPH, 0x09bc,
1250                                                0x0000014c);
1251                                        NV_WR32(par->PFB, 0x033C,
1252                                                NV_RD32(par->PFB, 0x33C) &
1253                                                0xffff7fff);
1254                                        break;
1255                                case 0x00C0:
1256                                case 0x0120:
1257                                        NV_WR32(par->PGRAPH, 0x0828,
1258                                                0x007596ff);
1259                                        NV_WR32(par->PGRAPH, 0x082C,
1260                                                0x00000108);
1261                                        break;
1262                                case 0x0160:
1263                                case 0x01D0:
1264                                case 0x0240:
1265                                case 0x03D0:
1266                                        NV_WR32(par->PMC, 0x1700,
1267                                                NV_RD32(par->PFB, 0x020C));
1268                                        NV_WR32(par->PMC, 0x1704, 0);
1269                                        NV_WR32(par->PMC, 0x1708, 0);
1270                                        NV_WR32(par->PMC, 0x170C,
1271                                                NV_RD32(par->PFB, 0x020C));
1272                                        NV_WR32(par->PGRAPH, 0x0860, 0);
1273                                        NV_WR32(par->PGRAPH, 0x0864, 0);
1274                                        NV_WR32(par->PRAMDAC, 0x0608,
1275                                                NV_RD32(par->PRAMDAC,
1276                                                        0x0608) | 0x00100000);
1277                                        break;
1278                                case 0x0140:
1279                                        NV_WR32(par->PGRAPH, 0x0828,
1280                                                0x0072cb77);
1281                                        NV_WR32(par->PGRAPH, 0x082C,
1282                                                0x00000108);
1283                                        break;
1284                                case 0x0220:
1285                                        NV_WR32(par->PGRAPH, 0x0860, 0);
1286                                        NV_WR32(par->PGRAPH, 0x0864, 0);
1287                                        NV_WR32(par->PRAMDAC, 0x0608,
1288                                                NV_RD32(par->PRAMDAC, 0x0608) |
1289                                                0x00100000);
1290                                        break;
1291                                case 0x0090:
1292                                case 0x0290:
1293                                case 0x0390:
1294                                        NV_WR32(par->PRAMDAC, 0x0608,
1295                                                NV_RD32(par->PRAMDAC, 0x0608) |
1296                                                0x00100000);
1297                                        NV_WR32(par->PGRAPH, 0x0828,
1298                                                0x07830610);
1299                                        NV_WR32(par->PGRAPH, 0x082C,
1300                                                0x0000016A);
1301                                        break;
1302                                default:
1303                                        break;
1304                                }
1305
1306                                NV_WR32(par->PGRAPH, 0x0b38, 0x2ffff800);
1307                                NV_WR32(par->PGRAPH, 0x0b3c, 0x00006000);
1308                                NV_WR32(par->PGRAPH, 0x032C, 0x01000000);
1309                                NV_WR32(par->PGRAPH, 0x0220, 0x00001200);
1310                        } else if (par->Architecture == NV_ARCH_30) {
1311                                NV_WR32(par->PGRAPH, 0x0084, 0x40108700);
1312                                NV_WR32(par->PGRAPH, 0x0890, 0x00140000);
1313                                NV_WR32(par->PGRAPH, 0x008C, 0xf00e0431);
1314                                NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
1315                                NV_WR32(par->PGRAPH, 0x0610, 0xf04b1f36);
1316                                NV_WR32(par->PGRAPH, 0x0B80, 0x1002d888);
1317                                NV_WR32(par->PGRAPH, 0x0B88, 0x62ff007f);
1318                        } else {
1319                                NV_WR32(par->PGRAPH, 0x0084, 0x00118700);
1320                                NV_WR32(par->PGRAPH, 0x008C, 0xF20E0431);
1321                                NV_WR32(par->PGRAPH, 0x0090, 0x00000000);
1322                                NV_WR32(par->PGRAPH, 0x009C, 0x00000040);
1323
1324                                if ((par->Chipset & 0x0ff0) >= 0x0250) {
1325                                        NV_WR32(par->PGRAPH, 0x0890,
1326                                                0x00080000);
1327                                        NV_WR32(par->PGRAPH, 0x0610,
1328                                                0x304B1FB6);
1329                                        NV_WR32(par->PGRAPH, 0x0B80,
1330                                                0x18B82880);
1331                                        NV_WR32(par->PGRAPH, 0x0B84,
1332                                                0x44000000);
1333                                        NV_WR32(par->PGRAPH, 0x0098,
1334                                                0x40000080);
1335                                        NV_WR32(par->PGRAPH, 0x0B88,
1336                                                0x000000ff);
1337                                } else {
1338                                        NV_WR32(par->PGRAPH, 0x0880,
1339                                                0x00080000);
1340                                        NV_WR32(par->PGRAPH, 0x0094,
1341                                                0x00000005);
1342                                        NV_WR32(par->PGRAPH, 0x0B80,
1343                                                0x45CAA208);
1344                                        NV_WR32(par->PGRAPH, 0x0B84,
1345                                                0x24000000);
1346                                        NV_WR32(par->PGRAPH, 0x0098,
1347                                                0x00000040);
1348                                        NV_WR32(par->PGRAPH, 0x0750,
1349                                                0x00E00038);
1350                                        NV_WR32(par->PGRAPH, 0x0754,
1351                                                0x00000030);
1352                                        NV_WR32(par->PGRAPH, 0x0750,
1353                                                0x00E10038);
1354                                        NV_WR32(par->PGRAPH, 0x0754,
1355                                                0x00000030);
1356                                }
1357                        }
1358
1359                        if ((par->Architecture < NV_ARCH_40) ||
1360                            ((par->Chipset & 0xfff0) == 0x0040)) {
1361                                for (i = 0; i < 32; i++) {
1362                                        NV_WR32(par->PGRAPH, 0x0900 + i*4,
1363                                                NV_RD32(par->PFB, 0x0240 +i*4));
1364                                        NV_WR32(par->PGRAPH, 0x6900 + i*4,
1365                                                NV_RD32(par->PFB, 0x0240 +i*4));
1366                                }
1367                        } else {
1368                                if (((par->Chipset & 0xfff0) == 0x0090) ||
1369                                    ((par->Chipset & 0xfff0) == 0x01D0) ||
1370                                    ((par->Chipset & 0xfff0) == 0x0290) ||
1371                                    ((par->Chipset & 0xfff0) == 0x0390) ||
1372                                    ((par->Chipset & 0xfff0) == 0x03D0)) {
1373                                        for (i = 0; i < 60; i++) {
1374                                                NV_WR32(par->PGRAPH,
1375                                                        0x0D00 + i*4,
1376                                                        NV_RD32(par->PFB,
1377                                                                0x0600 + i*4));
1378                                                NV_WR32(par->PGRAPH,
1379                                                        0x6900 + i*4,
1380                                                        NV_RD32(par->PFB,
1381                                                                0x0600 + i*4));
1382                                        }
1383                                } else {
1384                                        for (i = 0; i < 48; i++) {
1385                                                NV_WR32(par->PGRAPH,
1386                                                        0x0900 + i*4,
1387                                                        NV_RD32(par->PFB,
1388                                                                0x0600 + i*4));
1389                                                if(((par->Chipset & 0xfff0)
1390                                                    != 0x0160) &&
1391                                                   ((par->Chipset & 0xfff0)
1392                                                    != 0x0220) &&
1393                                                   ((par->Chipset & 0xfff0)
1394                                                    != 0x240))
1395                                                        NV_WR32(par->PGRAPH,
1396                                                                0x6900 + i*4,
1397                                                                NV_RD32(par->PFB,
1398                                                                        0x0600 + i*4));
1399                                        }
1400                                }
1401                        }
1402
1403                        if (par->Architecture >= NV_ARCH_40) {
1404                                if ((par->Chipset & 0xfff0) == 0x0040) {
1405                                        NV_WR32(par->PGRAPH, 0x09A4,
1406                                                NV_RD32(par->PFB, 0x0200));
1407                                        NV_WR32(par->PGRAPH, 0x09A8,
1408                                                NV_RD32(par->PFB, 0x0204));
1409                                        NV_WR32(par->PGRAPH, 0x69A4,
1410                                                NV_RD32(par->PFB, 0x0200));
1411                                        NV_WR32(par->PGRAPH, 0x69A8,
1412                                                NV_RD32(par->PFB, 0x0204));
1413
1414                                        NV_WR32(par->PGRAPH, 0x0820, 0);
1415                                        NV_WR32(par->PGRAPH, 0x0824, 0);
1416                                        NV_WR32(par->PGRAPH, 0x0864,
1417                                                par->FbMapSize - 1);
1418                                        NV_WR32(par->PGRAPH, 0x0868,
1419                                                par->FbMapSize - 1);
1420                                } else {
1421                                        if ((par->Chipset & 0xfff0) == 0x0090 ||
1422                                            (par->Chipset & 0xfff0) == 0x01D0 ||
1423                                            (par->Chipset & 0xfff0) == 0x0290 ||
1424                                            (par->Chipset & 0xfff0) == 0x0390) {
1425                                                NV_WR32(par->PGRAPH, 0x0DF0,
1426                                                        NV_RD32(par->PFB, 0x0200));
1427                                                NV_WR32(par->PGRAPH, 0x0DF4,
1428                                                        NV_RD32(par->PFB, 0x0204));
1429                                        } else {
1430                                                NV_WR32(par->PGRAPH, 0x09F0,
1431                                                        NV_RD32(par->PFB, 0x0200));
1432                                                NV_WR32(par->PGRAPH, 0x09F4,
1433                                                        NV_RD32(par->PFB, 0x0204));
1434                                        }
1435                                        NV_WR32(par->PGRAPH, 0x69F0,
1436                                                NV_RD32(par->PFB, 0x0200));
1437                                        NV_WR32(par->PGRAPH, 0x69F4,
1438                                                NV_RD32(par->PFB, 0x0204));
1439
1440                                        NV_WR32(par->PGRAPH, 0x0840, 0);
1441                                        NV_WR32(par->PGRAPH, 0x0844, 0);
1442                                        NV_WR32(par->PGRAPH, 0x08a0,
1443                                                par->FbMapSize - 1);
1444                                        NV_WR32(par->PGRAPH, 0x08a4,
1445                                                par->FbMapSize - 1);
1446                                }
1447                        } else {
1448                                NV_WR32(par->PGRAPH, 0x09A4,
1449                                        NV_RD32(par->PFB, 0x0200));
1450                                NV_WR32(par->PGRAPH, 0x09A8,
1451                                        NV_RD32(par->PFB, 0x0204));
1452                                NV_WR32(par->PGRAPH, 0x0750, 0x00EA0000);
1453                                NV_WR32(par->PGRAPH, 0x0754,
1454                                        NV_RD32(par->PFB, 0x0200));
1455                                NV_WR32(par->PGRAPH, 0x0750, 0x00EA0004);
1456                                NV_WR32(par->PGRAPH, 0x0754,
1457                                        NV_RD32(par->PFB, 0x0204));
1458
1459                                NV_WR32(par->PGRAPH, 0x0820, 0);
1460                                NV_WR32(par->PGRAPH, 0x0824, 0);
1461                                NV_WR32(par->PGRAPH, 0x0864,
1462                                        par->FbMapSize - 1);
1463                                NV_WR32(par->PGRAPH, 0x0868,
1464                                        par->FbMapSize - 1);
1465                        }
1466                        NV_WR32(par->PGRAPH, 0x0B20, 0x00000000);
1467                        NV_WR32(par->PGRAPH, 0x0B04, 0xFFFFFFFF);
1468                }
1469        }
1470        NV_WR32(par->PGRAPH, 0x053C, 0);
1471        NV_WR32(par->PGRAPH, 0x0540, 0);
1472        NV_WR32(par->PGRAPH, 0x0544, 0x00007FFF);
1473        NV_WR32(par->PGRAPH, 0x0548, 0x00007FFF);
1474
1475        NV_WR32(par->PFIFO, 0x0140 * 4, 0x00000000);
1476        NV_WR32(par->PFIFO, 0x0141 * 4, 0x00000001);
1477        NV_WR32(par->PFIFO, 0x0480 * 4, 0x00000000);
1478        NV_WR32(par->PFIFO, 0x0494 * 4, 0x00000000);
1479        if (par->Architecture >= NV_ARCH_40)
1480                NV_WR32(par->PFIFO, 0x0481 * 4, 0x00010000);
1481        else
1482                NV_WR32(par->PFIFO, 0x0481 * 4, 0x00000100);
1483        NV_WR32(par->PFIFO, 0x0490 * 4, 0x00000000);
1484        NV_WR32(par->PFIFO, 0x0491 * 4, 0x00000000);
1485        if (par->Architecture >= NV_ARCH_40)
1486                NV_WR32(par->PFIFO, 0x048B * 4, 0x00001213);
1487        else
1488                NV_WR32(par->PFIFO, 0x048B * 4, 0x00001209);
1489        NV_WR32(par->PFIFO, 0x0400 * 4, 0x00000000);
1490        NV_WR32(par->PFIFO, 0x0414 * 4, 0x00000000);
1491        NV_WR32(par->PFIFO, 0x0084 * 4, 0x03000100);
1492        NV_WR32(par->PFIFO, 0x0085 * 4, 0x00000110);
1493        NV_WR32(par->PFIFO, 0x0086 * 4, 0x00000112);
1494        NV_WR32(par->PFIFO, 0x0143 * 4, 0x0000FFFF);
1495        NV_WR32(par->PFIFO, 0x0496 * 4, 0x0000FFFF);
1496        NV_WR32(par->PFIFO, 0x0050 * 4, 0x00000000);
1497        NV_WR32(par->PFIFO, 0x0040 * 4, 0xFFFFFFFF);
1498        NV_WR32(par->PFIFO, 0x0415 * 4, 0x00000001);
1499        NV_WR32(par->PFIFO, 0x048C * 4, 0x00000000);
1500        NV_WR32(par->PFIFO, 0x04A0 * 4, 0x00000000);
1501#ifdef __BIG_ENDIAN
1502        NV_WR32(par->PFIFO, 0x0489 * 4, 0x800F0078);
1503#else
1504        NV_WR32(par->PFIFO, 0x0489 * 4, 0x000F0078);
1505#endif
1506        NV_WR32(par->PFIFO, 0x0488 * 4, 0x00000001);
1507        NV_WR32(par->PFIFO, 0x0480 * 4, 0x00000001);
1508        NV_WR32(par->PFIFO, 0x0494 * 4, 0x00000001);
1509        NV_WR32(par->PFIFO, 0x0495 * 4, 0x00000001);
1510        NV_WR32(par->PFIFO, 0x0140 * 4, 0x00000001);
1511
1512    if (!state) {
1513            par->CurrentState = NULL;
1514            return;
1515    }
1516
1517        if (par->Architecture >= NV_ARCH_10) {
1518                if (par->twoHeads) {
1519                        NV_WR32(par->PCRTC0, 0x0860, state->head);
1520                        NV_WR32(par->PCRTC0, 0x2860, state->head2);
1521                }
1522                NV_WR32(par->PRAMDAC, 0x0404, NV_RD32(par->PRAMDAC, 0x0404) |
1523                        (1 << 25));
1524
1525                NV_WR32(par->PMC, 0x8704, 1);
1526                NV_WR32(par->PMC, 0x8140, 0);
1527                NV_WR32(par->PMC, 0x8920, 0);
1528                NV_WR32(par->PMC, 0x8924, 0);
1529                NV_WR32(par->PMC, 0x8908, par->FbMapSize - 1);
1530                NV_WR32(par->PMC, 0x890C, par->FbMapSize - 1);
1531                NV_WR32(par->PMC, 0x1588, 0);
1532
1533                NV_WR32(par->PCRTC, 0x0810, state->cursorConfig);
1534                NV_WR32(par->PCRTC, 0x0830, state->displayV - 3);
1535                NV_WR32(par->PCRTC, 0x0834, state->displayV - 1);
1536
1537                if (par->FlatPanel) {
1538                        if ((par->Chipset & 0x0ff0) == 0x0110) {
1539                                NV_WR32(par->PRAMDAC, 0x0528, state->dither);
1540                        } else if (par->twoHeads) {
1541                                NV_WR32(par->PRAMDAC, 0x083C, state->dither);
1542                        }
1543
1544                        VGA_WR08(par->PCIO, 0x03D4, 0x53);
1545                        VGA_WR08(par->PCIO, 0x03D5, state->timingH);
1546                        VGA_WR08(par->PCIO, 0x03D4, 0x54);
1547                        VGA_WR08(par->PCIO, 0x03D5, state->timingV);
1548                        VGA_WR08(par->PCIO, 0x03D4, 0x21);
1549                        VGA_WR08(par->PCIO, 0x03D5, 0xfa);
1550                }
1551
1552                VGA_WR08(par->PCIO, 0x03D4, 0x41);
1553                VGA_WR08(par->PCIO, 0x03D5, state->extra);
1554        }
1555
1556        VGA_WR08(par->PCIO, 0x03D4, 0x19);
1557        VGA_WR08(par->PCIO, 0x03D5, state->repaint0);
1558        VGA_WR08(par->PCIO, 0x03D4, 0x1A);
1559        VGA_WR08(par->PCIO, 0x03D5, state->repaint1);
1560        VGA_WR08(par->PCIO, 0x03D4, 0x25);
1561        VGA_WR08(par->PCIO, 0x03D5, state->screen);
1562        VGA_WR08(par->PCIO, 0x03D4, 0x28);
1563        VGA_WR08(par->PCIO, 0x03D5, state->pixel);
1564        VGA_WR08(par->PCIO, 0x03D4, 0x2D);
1565        VGA_WR08(par->PCIO, 0x03D5, state->horiz);
1566        VGA_WR08(par->PCIO, 0x03D4, 0x1C);
1567        VGA_WR08(par->PCIO, 0x03D5, state->fifo);
1568        VGA_WR08(par->PCIO, 0x03D4, 0x1B);
1569        VGA_WR08(par->PCIO, 0x03D5, state->arbitration0);
1570        VGA_WR08(par->PCIO, 0x03D4, 0x20);
1571        VGA_WR08(par->PCIO, 0x03D5, state->arbitration1);
1572
1573        if(par->Architecture >= NV_ARCH_30) {
1574                VGA_WR08(par->PCIO, 0x03D4, 0x47);
1575                VGA_WR08(par->PCIO, 0x03D5, state->arbitration1 >> 8);
1576        }
1577
1578        VGA_WR08(par->PCIO, 0x03D4, 0x30);
1579        VGA_WR08(par->PCIO, 0x03D5, state->cursor0);
1580        VGA_WR08(par->PCIO, 0x03D4, 0x31);
1581        VGA_WR08(par->PCIO, 0x03D5, state->cursor1);
1582        VGA_WR08(par->PCIO, 0x03D4, 0x2F);
1583        VGA_WR08(par->PCIO, 0x03D5, state->cursor2);
1584        VGA_WR08(par->PCIO, 0x03D4, 0x39);
1585        VGA_WR08(par->PCIO, 0x03D5, state->interlace);
1586
1587        if (!par->FlatPanel) {
1588                if (par->Architecture >= NV_ARCH_40)
1589                        NV_WR32(par->PRAMDAC0, 0x0580, state->control);
1590
1591                NV_WR32(par->PRAMDAC0, 0x050C, state->pllsel);
1592                NV_WR32(par->PRAMDAC0, 0x0508, state->vpll);
1593                if (par->twoHeads)
1594                        NV_WR32(par->PRAMDAC0, 0x0520, state->vpll2);
1595                if (par->twoStagePLL) {
1596                        NV_WR32(par->PRAMDAC0, 0x0578, state->vpllB);
1597                        NV_WR32(par->PRAMDAC0, 0x057C, state->vpll2B);
1598                }
1599        } else {
1600                NV_WR32(par->PRAMDAC, 0x0848, state->scale);
1601                NV_WR32(par->PRAMDAC, 0x0828, state->crtcSync +
1602                        par->PanelTweak);
1603        }
1604
1605        NV_WR32(par->PRAMDAC, 0x0600, state->general);
1606
1607        NV_WR32(par->PCRTC, 0x0140, 0);
1608        NV_WR32(par->PCRTC, 0x0100, 1);
1609
1610        par->CurrentState = state;
1611}
1612
1613void NVUnloadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) {
1614        VGA_WR08(par->PCIO, 0x03D4, 0x19);
1615        state->repaint0 = VGA_RD08(par->PCIO, 0x03D5);
1616        VGA_WR08(par->PCIO, 0x03D4, 0x1A);
1617        state->repaint1 = VGA_RD08(par->PCIO, 0x03D5);
1618        VGA_WR08(par->PCIO, 0x03D4, 0x25);
1619        state->screen = VGA_RD08(par->PCIO, 0x03D5);
1620        VGA_WR08(par->PCIO, 0x03D4, 0x28);
1621        state->pixel = VGA_RD08(par->PCIO, 0x03D5);
1622        VGA_WR08(par->PCIO, 0x03D4, 0x2D);
1623        state->horiz = VGA_RD08(par->PCIO, 0x03D5);
1624        VGA_WR08(par->PCIO, 0x03D4, 0x1C);
1625        state->fifo         = VGA_RD08(par->PCIO, 0x03D5);
1626        VGA_WR08(par->PCIO, 0x03D4, 0x1B);
1627        state->arbitration0 = VGA_RD08(par->PCIO, 0x03D5);
1628        VGA_WR08(par->PCIO, 0x03D4, 0x20);
1629        state->arbitration1 = VGA_RD08(par->PCIO, 0x03D5);
1630
1631        if(par->Architecture >= NV_ARCH_30) {
1632                VGA_WR08(par->PCIO, 0x03D4, 0x47);
1633                state->arbitration1 |= (VGA_RD08(par->PCIO, 0x03D5) & 1) << 8;
1634        }
1635
1636        VGA_WR08(par->PCIO, 0x03D4, 0x30);
1637        state->cursor0 = VGA_RD08(par->PCIO, 0x03D5);
1638        VGA_WR08(par->PCIO, 0x03D4, 0x31);
1639        state->cursor1 = VGA_RD08(par->PCIO, 0x03D5);
1640        VGA_WR08(par->PCIO, 0x03D4, 0x2F);
1641        state->cursor2 = VGA_RD08(par->PCIO, 0x03D5);
1642        VGA_WR08(par->PCIO, 0x03D4, 0x39);
1643        state->interlace = VGA_RD08(par->PCIO, 0x03D5);
1644        state->vpll = NV_RD32(par->PRAMDAC0, 0x0508);
1645        if (par->twoHeads)
1646                state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520);
1647        if (par->twoStagePLL) {
1648                state->vpllB = NV_RD32(par->PRAMDAC0, 0x0578);
1649                state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C);
1650        }
1651        state->pllsel = NV_RD32(par->PRAMDAC0, 0x050C);
1652        state->general = NV_RD32(par->PRAMDAC, 0x0600);
1653        state->scale = NV_RD32(par->PRAMDAC, 0x0848);
1654        state->config = NV_RD32(par->PFB, 0x0200);
1655
1656        if (par->Architecture >= NV_ARCH_40 && !par->FlatPanel)
1657                state->control  = NV_RD32(par->PRAMDAC0, 0x0580);
1658
1659        if (par->Architecture >= NV_ARCH_10) {
1660                if (par->twoHeads) {
1661                        state->head = NV_RD32(par->PCRTC0, 0x0860);
1662                        state->head2 = NV_RD32(par->PCRTC0, 0x2860);
1663                        VGA_WR08(par->PCIO, 0x03D4, 0x44);
1664                        state->crtcOwner = VGA_RD08(par->PCIO, 0x03D5);
1665                }
1666                VGA_WR08(par->PCIO, 0x03D4, 0x41);
1667                state->extra = VGA_RD08(par->PCIO, 0x03D5);
1668                state->cursorConfig = NV_RD32(par->PCRTC, 0x0810);
1669
1670                if ((par->Chipset & 0x0ff0) == 0x0110) {
1671                        state->dither = NV_RD32(par->PRAMDAC, 0x0528);
1672                } else if (par->twoHeads) {
1673                        state->dither = NV_RD32(par->PRAMDAC, 0x083C);
1674                }
1675
1676                if (par->FlatPanel) {
1677                        VGA_WR08(par->PCIO, 0x03D4, 0x53);
1678                        state->timingH = VGA_RD08(par->PCIO, 0x03D5);
1679                        VGA_WR08(par->PCIO, 0x03D4, 0x54);
1680                        state->timingV = VGA_RD08(par->PCIO, 0x03D5);
1681                }
1682        }
1683}
1684
1685void NVSetStartAddress(struct nvidia_par *par, u32 start)
1686{
1687        NV_WR32(par->PCRTC, 0x800, start);
1688}
1689