diff options
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]; } |