diff options
author | Alan Coopersmith <Alan.Coopersmith@sun.com> | 2004-11-10 02:53:44 +0000 |
---|---|---|
committer | Alan Coopersmith <Alan.Coopersmith@sun.com> | 2004-11-10 02:53:44 +0000 |
commit | 7c34d051168eba499beb20c40fd95703375f4c7b (patch) | |
tree | 4a2367c446ef7a9852ff80ad750bf5bd3ed264eb /src/nv_hw.c | |
parent | fcd6d7b57edb4e396189a0a2683bcf08974f3b59 (diff) |
(Bugzilla #1777) Import Mark Vojkovich's changes to NV driver since lastxprint_packagertest_20041125_basexprint_packagertest_20041125
sync with XFree86, including: Support for new NVIDIA chips. Egbert has
a laptop that needs some DPMS ordering reversed. New chip support and
workaround for Toshiba M30 laptop issue. PCI-Xpress chip support. DPMS
support for DVI. Cursor changes for NV11 so that alpha blended cursors
will work in conjunction with dithering (laptop panels). It previously
did not. HW support for alpha blended stretch blits on NV5 and higher,
though nothing is using them at this point. Add support for VBlank
syncing the Xv Blit adaptor on hardware that supports it (NV11 and
higher). Make console restoration a little more robust. We were making
an assumption that failed on a newer laptop. Workaround for some NV31
DVI artifacts.
Also add nVidia license statement to nv man page to comply with requirement
that it appear in "user documentation"
Diffstat (limited to 'src/nv_hw.c')
-rw-r--r-- | src/nv_hw.c | 407 |
1 files changed, 315 insertions, 92 deletions
diff --git a/src/nv_hw.c b/src/nv_hw.c index 67e3b5b..25b10d2 100644 --- a/src/nv_hw.c +++ b/src/nv_hw.c @@ -36,7 +36,7 @@ |* those rights set forth herein. *| |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c,v 1.4 2003/11/03 05:11:25 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c,v 1.11 2004/10/15 20:32:21 mvojkovi Exp $ */ #include "nv_local.h" #include "compiler.h" @@ -71,6 +71,12 @@ int NVShowHideCursor ( (ShowHide & 0x01); VGA_WR08(pNv->PCIO, 0x3D4, 0x31); VGA_WR08(pNv->PCIO, 0x3D5, pNv->CurrentState->cursor1); + + if(pNv->Architecture == NV_ARCH_40) { /* HW bug */ + volatile CARD32 curpos = pNv->PRAMDAC[0x0300/4]; + pNv->PRAMDAC[0x0300/4] = curpos; + } + return (current & 0x01); } @@ -132,6 +138,26 @@ static void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk) { unsigned int pll, N, M, MB, NB, P; + if(pNv->Architecture >= NV_ARCH_40) { + pll = pNv->PMC[0x4020/4]; + P = (pll >> 16) & 0x03; + pll = pNv->PMC[0x4024/4]; + M = pll & 0xFF; + N = (pll >> 8) & 0xFF; + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; + *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P; + + pll = pNv->PMC[0x4000/4]; + P = (pll >> 16) & 0x03; + pll = pNv->PMC[0x4004/4]; + M = pll & 0xFF; + N = (pll >> 8) & 0xFF; + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; + + *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P; + } else if(pNv->twoStagePLL) { pll = pNv->PRAMDAC0[0x0504/4]; M = pll & 0xFF; @@ -202,6 +228,10 @@ static void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk) P = (pll >> 16) & 0x0F; *NVClk = (N * pNv->CrystalFreqKHz / M) >> P; } + +#if 0 + ErrorF("NVClock = %i MHz, MEMClock = %i MHz\n", *NVClk/1000, *MClk/1000); +#endif } @@ -632,12 +662,17 @@ static void nForceUpdateArbitrationSettings ( { nv10_fifo_info fifo_data; nv10_sim_state sim_data; - unsigned int M, N, P, pll, MClk, NVClk; - unsigned int uMClkPostDiv, memctrl; + unsigned int M, N, P, pll, MClk, NVClk, memctrl; - uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf; - if(!uMClkPostDiv) uMClkPostDiv = 4; - MClk = 400000 / uMClkPostDiv; + if((pNv->Chipset & 0x0FF0) == 0x01A0) { + unsigned int uMClkPostDiv; + + uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf; + if(!uMClkPostDiv) uMClkPostDiv = 4; + MClk = 400000 / uMClkPostDiv; + } else { + MClk = pciReadLong(pciTag(0, 0, 5), 0x4C) / 1000; + } pll = pNv->PRAMDAC0[0x0500/4]; M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; @@ -901,79 +936,167 @@ void NVLoadStateExt ( pNv->PFB[0x02B4/4] = pNv->FbMapSize - 1; } - pNv->PRAMIN[0x0000] = 0x80000010; - pNv->PRAMIN[0x0001] = 0x80011201; - pNv->PRAMIN[0x0002] = 0x80000011; - pNv->PRAMIN[0x0003] = 0x80011202; - pNv->PRAMIN[0x0004] = 0x80000012; - pNv->PRAMIN[0x0005] = 0x80011203; - pNv->PRAMIN[0x0006] = 0x80000013; - pNv->PRAMIN[0x0007] = 0x80011204; - pNv->PRAMIN[0x0008] = 0x80000014; - pNv->PRAMIN[0x0009] = 0x80011205; - pNv->PRAMIN[0x000A] = 0x80000015; - pNv->PRAMIN[0x000B] = 0x80011206; - pNv->PRAMIN[0x000C] = 0x80000016; - pNv->PRAMIN[0x000D] = 0x80011207; - pNv->PRAMIN[0x000E] = 0x80000017; - pNv->PRAMIN[0x000F] = 0x80011208; - pNv->PRAMIN[0x0800] = 0x00003000; - pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1; - pNv->PRAMIN[0x0802] = 0x00000002; - pNv->PRAMIN[0x0803] = 0x00000002; - if(pNv->Architecture >= NV_ARCH_10) - pNv->PRAMIN[0x0804] = 0x01008062; - else - pNv->PRAMIN[0x0804] = 0x01008042; - pNv->PRAMIN[0x0805] = 0x00000000; - pNv->PRAMIN[0x0806] = 0x12001200; - pNv->PRAMIN[0x0807] = 0x00000000; - pNv->PRAMIN[0x0808] = 0x01008043; - pNv->PRAMIN[0x0809] = 0x00000000; - pNv->PRAMIN[0x080A] = 0x00000000; - pNv->PRAMIN[0x080B] = 0x00000000; - pNv->PRAMIN[0x080C] = 0x01008044; - pNv->PRAMIN[0x080D] = 0x00000002; - pNv->PRAMIN[0x080E] = 0x00000000; - pNv->PRAMIN[0x080F] = 0x00000000; - pNv->PRAMIN[0x0810] = 0x01008019; - pNv->PRAMIN[0x0811] = 0x00000000; - pNv->PRAMIN[0x0812] = 0x00000000; - pNv->PRAMIN[0x0813] = 0x00000000; - pNv->PRAMIN[0x0814] = 0x0100A05C; - pNv->PRAMIN[0x0815] = 0x00000000; - pNv->PRAMIN[0x0816] = 0x00000000; - pNv->PRAMIN[0x0817] = 0x00000000; - pNv->PRAMIN[0x0818] = 0x0100805F; - pNv->PRAMIN[0x0819] = 0x00000000; - pNv->PRAMIN[0x081A] = 0x12001200; - pNv->PRAMIN[0x081B] = 0x00000000; - pNv->PRAMIN[0x081C] = 0x0100804A; - pNv->PRAMIN[0x081D] = 0x00000002; - pNv->PRAMIN[0x081E] = 0x00000000; - pNv->PRAMIN[0x081F] = 0x00000000; - pNv->PRAMIN[0x0820] = 0x01018077; - pNv->PRAMIN[0x0821] = 0x00000000; - pNv->PRAMIN[0x0822] = 0x01201200; - pNv->PRAMIN[0x0823] = 0x00000000; - pNv->PRAMIN[0x0824] = 0x00003002; - pNv->PRAMIN[0x0825] = 0x00007FFF; - pNv->PRAMIN[0x0826] = pNv->FbUsableSize | 0x00000002; - pNv->PRAMIN[0x0827] = 0x00000002; + if(pNv->Architecture >= NV_ARCH_40) { + pNv->PRAMIN[0x0000] = 0x80000010; + pNv->PRAMIN[0x0001] = 0x00101202; + pNv->PRAMIN[0x0002] = 0x80000011; + pNv->PRAMIN[0x0003] = 0x00101204; + pNv->PRAMIN[0x0004] = 0x80000012; + pNv->PRAMIN[0x0005] = 0x00101206; + pNv->PRAMIN[0x0006] = 0x80000013; + pNv->PRAMIN[0x0007] = 0x00101208; + pNv->PRAMIN[0x0008] = 0x80000014; + pNv->PRAMIN[0x0009] = 0x0010120A; + pNv->PRAMIN[0x000A] = 0x80000015; + pNv->PRAMIN[0x000B] = 0x0010120C; + pNv->PRAMIN[0x000C] = 0x80000016; + pNv->PRAMIN[0x000D] = 0x0010120E; + pNv->PRAMIN[0x000E] = 0x80000017; + pNv->PRAMIN[0x000F] = 0x00101210; + pNv->PRAMIN[0x0800] = 0x00003000; + pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1; + pNv->PRAMIN[0x0802] = 0x00000002; + pNv->PRAMIN[0x0808] = 0x02080062; + pNv->PRAMIN[0x0809] = 0x00000000; + pNv->PRAMIN[0x080A] = 0x00001200; + pNv->PRAMIN[0x080B] = 0x00001200; + pNv->PRAMIN[0x080C] = 0x00000000; + pNv->PRAMIN[0x080D] = 0x00000000; + pNv->PRAMIN[0x0810] = 0x02080043; + pNv->PRAMIN[0x0811] = 0x00000000; + pNv->PRAMIN[0x0812] = 0x00000000; + pNv->PRAMIN[0x0813] = 0x00000000; + pNv->PRAMIN[0x0814] = 0x00000000; + pNv->PRAMIN[0x0815] = 0x00000000; + pNv->PRAMIN[0x0818] = 0x02080044; + pNv->PRAMIN[0x0819] = 0x02000000; + pNv->PRAMIN[0x081A] = 0x00000000; + pNv->PRAMIN[0x081B] = 0x00000000; + pNv->PRAMIN[0x081C] = 0x00000000; + pNv->PRAMIN[0x081D] = 0x00000000; + pNv->PRAMIN[0x0820] = 0x02080019; + pNv->PRAMIN[0x0821] = 0x00000000; + pNv->PRAMIN[0x0822] = 0x00000000; + pNv->PRAMIN[0x0823] = 0x00000000; + pNv->PRAMIN[0x0824] = 0x00000000; + pNv->PRAMIN[0x0825] = 0x00000000; + pNv->PRAMIN[0x0828] = 0x020A005C; + pNv->PRAMIN[0x0829] = 0x00000000; + pNv->PRAMIN[0x082A] = 0x00000000; + pNv->PRAMIN[0x082B] = 0x00000000; + pNv->PRAMIN[0x082C] = 0x00000000; + pNv->PRAMIN[0x082D] = 0x00000000; + pNv->PRAMIN[0x0830] = 0x0208009F; + pNv->PRAMIN[0x0831] = 0x00000000; + pNv->PRAMIN[0x0832] = 0x00001200; + pNv->PRAMIN[0x0833] = 0x00001200; + pNv->PRAMIN[0x0834] = 0x00000000; + pNv->PRAMIN[0x0835] = 0x00000000; + pNv->PRAMIN[0x0838] = 0x0208004A; + pNv->PRAMIN[0x0839] = 0x02000000; + pNv->PRAMIN[0x083A] = 0x00000000; + pNv->PRAMIN[0x083B] = 0x00000000; + pNv->PRAMIN[0x083C] = 0x00000000; + pNv->PRAMIN[0x083D] = 0x00000000; + pNv->PRAMIN[0x0840] = 0x02080077; + pNv->PRAMIN[0x0841] = 0x00000000; + pNv->PRAMIN[0x0842] = 0x00001200; + pNv->PRAMIN[0x0843] = 0x00001200; + pNv->PRAMIN[0x0844] = 0x00000000; + pNv->PRAMIN[0x0845] = 0x00000000; + pNv->PRAMIN[0x084C] = 0x00003002; + pNv->PRAMIN[0x084D] = 0x00007FFF; + pNv->PRAMIN[0x084E] = pNv->FbUsableSize | 0x00000002; #if X_BYTE_ORDER == X_BIG_ENDIAN - pNv->PRAMIN[0x0804] |= 0x00080000; - pNv->PRAMIN[0x0808] |= 0x00080000; - pNv->PRAMIN[0x080C] |= 0x00080000; - pNv->PRAMIN[0x0810] |= 0x00080000; - pNv->PRAMIN[0x0814] |= 0x00080000; - pNv->PRAMIN[0x0818] |= 0x00080000; - pNv->PRAMIN[0x081C] |= 0x00080000; - pNv->PRAMIN[0x0820] |= 0x00080000; - - pNv->PRAMIN[0x080D] = 0x00000001; - pNv->PRAMIN[0x081D] = 0x00000001; + pNv->PRAMIN[0x080A] |= 0x01000000; + pNv->PRAMIN[0x0812] |= 0x01000000; + pNv->PRAMIN[0x081A] |= 0x01000000; + pNv->PRAMIN[0x0822] |= 0x01000000; + pNv->PRAMIN[0x082A] |= 0x01000000; + pNv->PRAMIN[0x0832] |= 0x01000000; + pNv->PRAMIN[0x083A] |= 0x01000000; + pNv->PRAMIN[0x0842] |= 0x01000000; + pNv->PRAMIN[0x0819] = 0x01000000; + pNv->PRAMIN[0x0839] = 0x01000000; #endif + } else { + pNv->PRAMIN[0x0000] = 0x80000010; + pNv->PRAMIN[0x0001] = 0x80011201; + pNv->PRAMIN[0x0002] = 0x80000011; + pNv->PRAMIN[0x0003] = 0x80011202; + pNv->PRAMIN[0x0004] = 0x80000012; + pNv->PRAMIN[0x0005] = 0x80011203; + pNv->PRAMIN[0x0006] = 0x80000013; + pNv->PRAMIN[0x0007] = 0x80011204; + pNv->PRAMIN[0x0008] = 0x80000014; + pNv->PRAMIN[0x0009] = 0x80011205; + pNv->PRAMIN[0x000A] = 0x80000015; + pNv->PRAMIN[0x000B] = 0x80011206; + pNv->PRAMIN[0x000C] = 0x80000016; + pNv->PRAMIN[0x000D] = 0x80011207; + pNv->PRAMIN[0x000E] = 0x80000017; + pNv->PRAMIN[0x000F] = 0x80011208; + pNv->PRAMIN[0x0800] = 0x00003000; + pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1; + pNv->PRAMIN[0x0802] = 0x00000002; + pNv->PRAMIN[0x0803] = 0x00000002; + if(pNv->Architecture >= NV_ARCH_10) + pNv->PRAMIN[0x0804] = 0x01008062; + else + pNv->PRAMIN[0x0804] = 0x01008042; + pNv->PRAMIN[0x0805] = 0x00000000; + pNv->PRAMIN[0x0806] = 0x12001200; + pNv->PRAMIN[0x0807] = 0x00000000; + pNv->PRAMIN[0x0808] = 0x01008043; + pNv->PRAMIN[0x0809] = 0x00000000; + pNv->PRAMIN[0x080A] = 0x00000000; + pNv->PRAMIN[0x080B] = 0x00000000; + pNv->PRAMIN[0x080C] = 0x01008044; + pNv->PRAMIN[0x080D] = 0x00000002; + pNv->PRAMIN[0x080E] = 0x00000000; + pNv->PRAMIN[0x080F] = 0x00000000; + pNv->PRAMIN[0x0810] = 0x01008019; + pNv->PRAMIN[0x0811] = 0x00000000; + pNv->PRAMIN[0x0812] = 0x00000000; + pNv->PRAMIN[0x0813] = 0x00000000; + pNv->PRAMIN[0x0814] = 0x0100A05C; + pNv->PRAMIN[0x0815] = 0x00000000; + pNv->PRAMIN[0x0816] = 0x00000000; + pNv->PRAMIN[0x0817] = 0x00000000; + if(pNv->WaitVSyncPossible) + pNv->PRAMIN[0x0818] = 0x0100809F; + else + pNv->PRAMIN[0x0818] = 0x0100805F; + pNv->PRAMIN[0x0819] = 0x00000000; + pNv->PRAMIN[0x081A] = 0x12001200; + pNv->PRAMIN[0x081B] = 0x00000000; + pNv->PRAMIN[0x081C] = 0x0100804A; + pNv->PRAMIN[0x081D] = 0x00000002; + pNv->PRAMIN[0x081E] = 0x00000000; + pNv->PRAMIN[0x081F] = 0x00000000; + pNv->PRAMIN[0x0820] = 0x01018077; + pNv->PRAMIN[0x0821] = 0x00000000; + pNv->PRAMIN[0x0822] = 0x12001200; + pNv->PRAMIN[0x0823] = 0x00000000; + pNv->PRAMIN[0x0824] = 0x00003002; + pNv->PRAMIN[0x0825] = 0x00007FFF; + pNv->PRAMIN[0x0826] = pNv->FbUsableSize | 0x00000002; + pNv->PRAMIN[0x0827] = 0x00000002; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + pNv->PRAMIN[0x0804] |= 0x00080000; + pNv->PRAMIN[0x0808] |= 0x00080000; + pNv->PRAMIN[0x080C] |= 0x00080000; + pNv->PRAMIN[0x0810] |= 0x00080000; + pNv->PRAMIN[0x0814] |= 0x00080000; + pNv->PRAMIN[0x0818] |= 0x00080000; + pNv->PRAMIN[0x081C] |= 0x00080000; + pNv->PRAMIN[0x0820] |= 0x00080000; + pNv->PRAMIN[0x080D] = 0x00000001; + pNv->PRAMIN[0x081D] = 0x00000001; +#endif + } if(pNv->Architecture < NV_ARCH_10) { if((pNv->Chipset & 0x0fff) == 0x0020) { @@ -985,6 +1108,7 @@ void NVLoadStateExt ( pNv->PGRAPH[0x0084/4] = 0x72111101; pNv->PGRAPH[0x0088/4] = 0x11D5F071; pNv->PGRAPH[0x008C/4] = 0x0004FF31; + pNv->PGRAPH[0x008C/4] = 0x4004FF31; pNv->PGRAPH[0x0140/4] = 0x00000000; pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF; @@ -993,6 +1117,7 @@ void NVLoadStateExt ( pNv->PGRAPH[0x0720/4] = 0x00000001; pNv->PGRAPH[0x0810/4] = 0x00000000; + pNv->PGRAPH[0x0608/4] = 0xFFFFFFFF; } else { pNv->PGRAPH[0x0080/4] = 0xFFFFFFFF; pNv->PGRAPH[0x0080/4] = 0x00000000; @@ -1002,6 +1127,8 @@ void NVLoadStateExt ( pNv->PGRAPH[0x0144/4] = 0x10010100; pNv->PGRAPH[0x0714/4] = 0xFFFFFFFF; pNv->PGRAPH[0x0720/4] = 0x00000001; + pNv->PGRAPH[0x0710/4] &= 0x0007ff00; + pNv->PGRAPH[0x0710/4] |= 0x00020100; if(pNv->Architecture == NV_ARCH_10) { pNv->PGRAPH[0x0084/4] = 0x00118700; @@ -1017,8 +1144,54 @@ void NVLoadStateExt ( pNv->PGRAPH[0x688/4] = pNv->FbMapSize - 1; pNv->PGRAPH[0x0810/4] = 0x00000000; + pNv->PGRAPH[0x0608/4] = 0xFFFFFFFF; } else { - if(pNv->Architecture >= NV_ARCH_30) { + if(pNv->Architecture >= NV_ARCH_40) { + pNv->PGRAPH[0x0084/4] = 0x401287c0; + pNv->PGRAPH[0x008C/4] = 0x60de8051; + pNv->PGRAPH[0x0090/4] = 0x00008000; + pNv->PGRAPH[0x0610/4] = 0x00be3c5f; + + if((pNv->Chipset & 0xfff0) == 0x0040) { + pNv->PGRAPH[0x09b0/4] = 0x83280fff; + pNv->PGRAPH[0x09b4/4] = 0x000000a0; + } else { + pNv->PGRAPH[0x0820/4] = 0x83280eff; + pNv->PGRAPH[0x0824/4] = 0x000000a0; + } + + switch(pNv->Chipset & 0xfff0) { + case 0x0040: + pNv->PGRAPH[0x09b8/4] = 0x0078e366; + pNv->PGRAPH[0x09bc/4] = 0x0000014c; + break; + case 0x00C0: + pNv->PGRAPH[0x0828/4] = 0x007596ff; + pNv->PGRAPH[0x082C/4] = 0x00000108; + break; + case 0x0160: + pNv->PMC[0x1700/4] = pNv->PFB[0x020C/4]; + pNv->PMC[0x1704/4] = 0; + pNv->PMC[0x1708/4] = 0; + pNv->PMC[0x170C/4] = pNv->PFB[0x020C/4]; + pNv->PGRAPH[0x0860/4] = 0; + pNv->PGRAPH[0x0864/4] = 0; + pNv->PRAMDAC[0x0608/4] |= 0x00100000; + break; + case 0x0140: + pNv->PGRAPH[0x0828/4] = 0x0072cb77; + pNv->PGRAPH[0x082C/4] = 0x00000108; + break; + default: + break; + }; + + pNv->PGRAPH[0x0b38/4] = 0x2ffff800; + pNv->PGRAPH[0x0b3c/4] = 0x00006000; + pNv->PGRAPH[0x032C/4] = 0x01000000; + pNv->PGRAPH[0x0220/4] = 0x00001200; + } else + if(pNv->Architecture == NV_ARCH_30) { pNv->PGRAPH[0x0084/4] = 0x40108700; pNv->PGRAPH[0x0890/4] = 0x00140000; pNv->PGRAPH[0x008C/4] = 0xf00e0431; @@ -1055,19 +1228,44 @@ void NVLoadStateExt ( for(i = 0; i < 32; i++) pNv->PGRAPH[(0x0900/4) + i] = pNv->PFB[(0x0240/4) + i]; - pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4]; - pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4]; - pNv->PGRAPH[0x0750/4] = 0x00EA0000; - pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0200/4]; - pNv->PGRAPH[0x0750/4] = 0x00EA0004; - pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0204/4]; - - pNv->PGRAPH[0x0820/4] = 0; - pNv->PGRAPH[0x0824/4] = 0; - pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1; - pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1; + if(pNv->Architecture >= NV_ARCH_40) { + if((pNv->Chipset & 0xfff0) == 0x0040) { + pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4]; + pNv->PGRAPH[0x69A4/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x69A8/4] = pNv->PFB[0x0204/4]; + + pNv->PGRAPH[0x0820/4] = 0; + pNv->PGRAPH[0x0824/4] = 0; + pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1; + pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1; + } else { + pNv->PGRAPH[0x09F0/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x09F4/4] = pNv->PFB[0x0204/4]; + pNv->PGRAPH[0x69F0/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x69F4/4] = pNv->PFB[0x0204/4]; + + pNv->PGRAPH[0x0840/4] = 0; + pNv->PGRAPH[0x0844/4] = 0; + pNv->PGRAPH[0x08a0/4] = pNv->FbMapSize - 1; + pNv->PGRAPH[0x08a4/4] = pNv->FbMapSize - 1; + } + } else { + pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4]; + pNv->PGRAPH[0x0750/4] = 0x00EA0000; + pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0200/4]; + pNv->PGRAPH[0x0750/4] = 0x00EA0004; + pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0204/4]; + + pNv->PGRAPH[0x0820/4] = 0; + pNv->PGRAPH[0x0824/4] = 0; + pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1; + pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1; + } pNv->PGRAPH[0x0B20/4] = 0x00000000; + pNv->PGRAPH[0x0B04/4] = 0xFFFFFFFF; } } pNv->PGRAPH[0x053C/4] = 0; @@ -1079,10 +1277,16 @@ void NVLoadStateExt ( pNv->PFIFO[0x0141] = 0x00000001; pNv->PFIFO[0x0480] = 0x00000000; pNv->PFIFO[0x0494] = 0x00000000; - pNv->PFIFO[0x0481] = 0x00000100; + if(pNv->Architecture >= NV_ARCH_40) + pNv->PFIFO[0x0481] = 0x00010000; + else + pNv->PFIFO[0x0481] = 0x00000100; pNv->PFIFO[0x0490] = 0x00000000; pNv->PFIFO[0x0491] = 0x00000000; - pNv->PFIFO[0x048B] = 0x00001209; + if(pNv->Architecture >= NV_ARCH_40) + pNv->PFIFO[0x048B] = 0x00001213; + else + pNv->PFIFO[0x048B] = 0x00001209; pNv->PFIFO[0x0400] = 0x00000000; pNv->PFIFO[0x0414] = 0x00000000; pNv->PFIFO[0x0084] = 0x03000100; @@ -1122,12 +1326,14 @@ void NVLoadStateExt ( pNv->PMC[0x1588/4] = 0; pNv->PCRTC[0x0810/4] = state->cursorConfig; + pNv->PCRTC[0x0830/4] = state->displayV - 3; + pNv->PCRTC[0x0834/4] = state->displayV - 1; if(pNv->FlatPanel) { if((pNv->Chipset & 0x0ff0) == 0x0110) { pNv->PRAMDAC[0x0528/4] = state->dither; } else - if((pNv->Chipset & 0x0ff0) >= 0x0170) { + if(pNv->twoHeads) { pNv->PRAMDAC[0x083C/4] = state->dither; } @@ -1177,6 +1383,23 @@ void NVLoadStateExt ( } } else { pNv->PRAMDAC[0x0848/4] = state->scale; + + /* begin flat panel hacks */ + /* This is unfortunate, but some chips need this register + tweaked or else you get artifacts where adjacent pixels are + swapped. There are no hard rules for what to set here so all + we can do is experiment and apply hacks. */ + + if(((pNv->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) { + /* At least one NV34 laptop needs this workaround. */ + pNv->PRAMDAC[0x0828/4] &= ~1; + } + + if((pNv->Chipset & 0xfff0) == 0x0310) { + pNv->PRAMDAC[0x0828/4] |= 1; + } + + /* end flat panel hacks */ } pNv->PRAMDAC[0x0600/4] = state->general; @@ -1240,7 +1463,7 @@ void NVUnloadStateExt if((pNv->Chipset & 0x0ff0) == 0x0110) { state->dither = pNv->PRAMDAC[0x0528/4]; } else - if((pNv->Chipset & 0x0ff0) >= 0x0170) { + if(pNv->twoHeads) { state->dither = pNv->PRAMDAC[0x083C/4]; } |