summaryrefslogtreecommitdiff
path: root/src/nv_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv_hw.c')
-rw-r--r--src/nv_hw.c451
1 files changed, 343 insertions, 108 deletions
diff --git a/src/nv_hw.c b/src/nv_hw.c
index 67e3b5b..7499d97 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.13 2004/12/09 00:21:04 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
}
@@ -509,21 +539,6 @@ static void nv10CalcArbitration (
clwm = us_crt * crtc_drain_rate/(1000*1000);
clwm++; /* fixed point <= float_point - 1. Fixes that */
- /*
- //
- // Another concern, only for high pclks so don't do this
- // with video:
- // What happens if the latency to fetch the cbs is so large that
- // fifo empties. In that case we need to have an alternate clwm value
- // based off the total burst fetch
- //
- us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
- us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq;
- clwm_mt = us_crt * crtc_drain_rate/(1000*1000);
- clwm_mt ++;
- if(clwm_mt > clwm)
- clwm = clwm_mt;
- */
/* Finally, a heuristic check when width == 64 bits */
if(width == 1){
nvclk_fill = nvclk_freq * 8;
@@ -622,6 +637,28 @@ static void nv10UpdateArbitrationSettings (
}
}
+
+static void nv30UpdateArbitrationSettings (
+ NVPtr pNv,
+ unsigned *burst,
+ unsigned *lwm
+)
+{
+ unsigned int MClk, NVClk;
+ unsigned int fifo_size, burst_size, graphics_lwm;
+
+ fifo_size = 2048;
+ burst_size = 512;
+ graphics_lwm = fifo_size - burst_size;
+
+ nvGetClocks(pNv, &MClk, &NVClk);
+
+ *burst = 0;
+ burst_size >>= 5;
+ while(burst_size >>= 1) (*burst)++;
+ *lwm = graphics_lwm >> 3;
+}
+
static void nForceUpdateArbitrationSettings (
unsigned VClk,
unsigned pixelDepth,
@@ -632,12 +669,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;
+
+ if((pNv->Chipset & 0x0FF0) == 0x01A0) {
+ unsigned int uMClkPostDiv;
- uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf;
- if(!uMClkPostDiv) uMClkPostDiv = 4;
- MClk = 400000 / 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;
@@ -837,12 +879,16 @@ void NVCalcStateExt (
&(state->arbitration0),
&(state->arbitration1),
pNv);
- } else {
+ } else if(pNv->Architecture < NV_ARCH_30) {
nv10UpdateArbitrationSettings(VClk,
pixelDepth * 8,
&(state->arbitration0),
&(state->arbitration1),
pNv);
+ } else {
+ nv30UpdateArbitrationSettings(pNv,
+ &(state->arbitration0),
+ &(state->arbitration1));
}
state->cursor0 = 0x80 | (pNv->CursorStart >> 17);
state->cursor1 = (pNv->CursorStart >> 11) << 2;
@@ -901,79 +947,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[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;
+ 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 +1119,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 +1128,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 +1138,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 +1155,55 @@ 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;
+ pNv->PFB[0x033C/4] &= 0xffff7fff;
+ 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 +1240,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 +1289,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 +1338,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;
}
@@ -1153,10 +1371,16 @@ void NVLoadStateExt (
VGA_WR08(pNv->PCIO, 0x03D5, state->pixel);
VGA_WR08(pNv->PCIO, 0x03D4, 0x2D);
VGA_WR08(pNv->PCIO, 0x03D5, state->horiz);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x1C);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->fifo);
VGA_WR08(pNv->PCIO, 0x03D4, 0x1B);
VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration0);
VGA_WR08(pNv->PCIO, 0x03D4, 0x20);
VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1);
+ if(pNv->Architecture >= NV_ARCH_30) {
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x47);
+ VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1 >> 8);
+ }
VGA_WR08(pNv->PCIO, 0x03D4, 0x30);
VGA_WR08(pNv->PCIO, 0x03D5, state->cursor0);
VGA_WR08(pNv->PCIO, 0x03D4, 0x31);
@@ -1177,6 +1401,7 @@ void NVLoadStateExt (
}
} else {
pNv->PRAMDAC[0x0848/4] = state->scale;
+ pNv->PRAMDAC[0x0828/4] = state->crtcSync;
}
pNv->PRAMDAC[0x0600/4] = state->general;
@@ -1202,10 +1427,16 @@ void NVUnloadStateExt
state->pixel = VGA_RD08(pNv->PCIO, 0x03D5);
VGA_WR08(pNv->PCIO, 0x03D4, 0x2D);
state->horiz = VGA_RD08(pNv->PCIO, 0x03D5);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x1C);
+ state->fifo = VGA_RD08(pNv->PCIO, 0x03D5);
VGA_WR08(pNv->PCIO, 0x03D4, 0x1B);
state->arbitration0 = VGA_RD08(pNv->PCIO, 0x03D5);
VGA_WR08(pNv->PCIO, 0x03D4, 0x20);
state->arbitration1 = VGA_RD08(pNv->PCIO, 0x03D5);
+ if(pNv->Architecture >= NV_ARCH_30) {
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x47);
+ state->arbitration1 |= (VGA_RD08(pNv->PCIO, 0x03D5) & 1) << 8;
+ }
VGA_WR08(pNv->PCIO, 0x03D4, 0x30);
state->cursor0 = VGA_RD08(pNv->PCIO, 0x03D5);
VGA_WR08(pNv->PCIO, 0x03D4, 0x31);
@@ -1240,7 +1471,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];
}
@@ -1251,6 +1482,10 @@ void NVUnloadStateExt
state->timingV = VGA_RD08(pNv->PCIO, 0x03D5);
}
}
+
+ if(pNv->FlatPanel) {
+ state->crtcSync = pNv->PRAMDAC[0x0828/4];
+ }
}
void NVSetStartAddress (