From 67c89797f62ea53b37927c64e0403e7e7c42de56 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Fri, 10 Dec 2004 03:56:42 +0000 Subject: Bugzilla #1985 sync to 12/08/04 version of Nvidia driver from Mark Vojkovich, including these fixes since last sync: Fix some DAC/Graphics memory contention issues on newer NVIDIA chips (specifically, NV40). More PCI IDs. Also, I've had trouble getting some panels to work automagically so I expose an FPTweak option to let the user adjust a troublesome register. --- src/nv_dac.c | 35 ++++++++++++++++++++++++- src/nv_driver.c | 33 ++++++++++++++++-------- src/nv_hw.c | 80 +++++++++++++++++++++++++++++++++------------------------ src/nv_setup.c | 10 +++----- src/nv_type.h | 6 ++++- 5 files changed, 112 insertions(+), 52 deletions(-) diff --git a/src/nv_dac.c b/src/nv_dac.c index 769179b..f62db58 100644 --- a/src/nv_dac.c +++ b/src/nv_dac.c @@ -37,10 +37,38 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.41 2004/10/05 21:23:03 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.44 2004/12/09 00:21:04 mvojkovi Exp $ */ #include "nv_include.h" +static int +NVDACPanelTweaks(NVPtr pNv, NVRegPtr state) +{ + int tweak = 0; + + if(pNv->usePanelTweak) { + tweak = pNv->PanelTweak; + } else { + /* 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. */ + tweak = -1; + } + + if((pNv->Chipset & 0xfff0) == 0x0310) { + tweak = 1; + } + /* end flat panel hacks */ + } + + return tweak; +} + Bool NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { @@ -185,6 +213,8 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { nvReg->scale |= (1 << 8) ; } + nvReg->crtcSync = pNv->PRAMDAC[0x0828/4]; + nvReg->crtcSync += NVDACPanelTweaks(pNv, nvReg); } nvReg->vpll = nvReg->pll; @@ -192,6 +222,9 @@ NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) nvReg->vpllB = nvReg->pllB; nvReg->vpll2B = nvReg->pllB; + VGA_WR08(pNv->PCIO, 0x03D4, 0x1C); + nvReg->fifo = VGA_RD08(pNv->PCIO, 0x03D5) & ~(1<<5); + if(pNv->CRTCnumber) { nvReg->head = pNv->PCRTC0[0x00000860/4] & ~0x00001000; nvReg->head2 = pNv->PCRTC0[0x00002860/4] | 0x00001000; diff --git a/src/nv_driver.c b/src/nv_driver.c index 601d7ef..ba665bc 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -1,4 +1,3 @@ -/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.5 2004/08/16 09:13:14 ajax Exp $ */ /* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */ /* * Copyright 1996-1997 David J. McKay @@ -25,7 +24,7 @@ /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.128 2004/10/09 22:53:25 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.130 2004/12/09 00:21:04 mvojkovi Exp $ */ #include "nv_include.h" @@ -113,18 +112,19 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE0175, "GeForce4 420 Go" }, { 0x10DE0176, "GeForce4 420 Go 32M" }, { 0x10DE0177, "GeForce4 460 Go" }, + { 0x10DE0178, "Quadro4 550 XGL" }, #if defined(__powerpc__) { 0x10DE0179, "GeForce4 MX (Mac)" }, #else { 0x10DE0179, "GeForce4 440 Go 64M" }, #endif - { 0x10DE017D, "GeForce4 410 Go 16M" }, - { 0x10DE017C, "Quadro4 500 GoGL" }, - { 0x10DE0178, "Quadro4 550 XGL" }, { 0x10DE017A, "Quadro4 NVS" }, + { 0x10DE017C, "Quadro4 500 GoGL" }, + { 0x10DE017D, "GeForce4 410 Go 16M" }, { 0x10DE0181, "GeForce4 MX 440 with AGP8X" }, { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" }, { 0x10DE0183, "GeForce4 MX 420 with AGP8X" }, + { 0x10DE0185, "GeForce4 MX 4000" }, { 0x10DE0186, "GeForce4 448 Go" }, { 0x10DE0187, "GeForce4 488 Go" }, { 0x10DE0188, "Quadro4 580 XGL" }, @@ -133,6 +133,8 @@ static SymTabRec NVKnownChipsets[] = #endif { 0x10DE018A, "Quadro4 280 NVS" }, { 0x10DE018B, "Quadro4 380 XGL" }, + { 0x10DE018C, "Quadro NVS 50 PCI" }, + { 0x10DE018D, "GeForce4 448 Go" }, { 0x10DE01F0, "GeForce4 MX Integrated GPU" }, { 0x10DE0200, "GeForce3" }, { 0x10DE0201, "GeForce3 Ti 200" }, @@ -213,9 +215,10 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE0045, "GeForce 6800 GT" }, { 0x10DE0049, "0x0049" }, { 0x10DE004E, "Quadro FX 4000" }, + { 0x10DE004D, "Quadro FX 4400" }, { 0x10DE00C0, "0x00C0" }, { 0x10DE00C1, "0x00C1" }, - { 0x10DE00C2, "0x00C2" }, + { 0x10DE00C2, "GeForce 6800 LE" }, { 0x10DE00C8, "0x00C8" }, { 0x10DE00C9, "0x00C9" }, { 0x10DE00CC, "0x00CC" }, @@ -224,11 +227,11 @@ static SymTabRec NVKnownChipsets[] = { 0x10DE0141, "GeForce 6600" }, { 0x10DE0142, "0x0142" }, { 0x10DE0143, "0x0143" }, - { 0x10DE0144, "0x0144" }, + { 0x10DE0144, "GeForce Go 6600" }, { 0x10DE0145, "GeForce 6610 XL" }, - { 0x10DE0146, "0x0146" }, + { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" }, { 0x10DE0147, "0x0147" }, - { 0x10DE0148, "0x0148" }, + { 0x10DE0148, "GeForce Go 6600" }, { 0x10DE0149, "0x0149" }, { 0x10DE014B, "0x014B" }, { 0x10DE014C, "0x014C" }, @@ -389,7 +392,8 @@ typedef enum { OPTION_FLAT_PANEL, OPTION_FP_DITHER, OPTION_CRTC_NUMBER, - OPTION_FP_SCALE + OPTION_FP_SCALE, + OPTION_FP_TWEAK } NVOpts; @@ -405,6 +409,7 @@ static const OptionInfoRec NVOptions[] = { { OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_CRTC_NUMBER, "CrtcNumber", OPTV_INTEGER, {0}, FALSE }, { OPTION_FP_SCALE, "FPScale", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FP_TWEAK, "FPTweak", OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -1220,6 +1225,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) pNv->CRTCnumber = -1; /* autodetect later */ } + + if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, + &pNv->PanelTweak)) + { + pNv->usePanelTweak = TRUE; + } else { + pNv->usePanelTweak = FALSE; + } if (pNv->pEnt->device->MemBase != 0) { /* Require that the config file value matches one of the PCI values. */ diff --git a/src/nv_hw.c b/src/nv_hw.c index 25b10d2..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.11 2004/10/15 20:32:21 mvojkovi 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" @@ -539,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; @@ -652,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, @@ -872,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; @@ -1164,6 +1175,7 @@ void NVLoadStateExt ( 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; @@ -1359,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); @@ -1383,23 +1401,7 @@ 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[0x0828/4] = state->crtcSync; } pNv->PRAMDAC[0x0600/4] = state->general; @@ -1425,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); @@ -1474,6 +1482,10 @@ void NVUnloadStateExt state->timingV = VGA_RD08(pNv->PCIO, 0x03D5); } } + + if(pNv->FlatPanel) { + state->crtcSync = pNv->PRAMDAC[0x0828/4]; + } } void NVSetStartAddress ( diff --git a/src/nv_setup.c b/src/nv_setup.c index cc157f6..95bb42f 100644 --- a/src/nv_setup.c +++ b/src/nv_setup.c @@ -37,7 +37,7 @@ |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.43 2004/08/26 22:38:47 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.44 2004/12/09 00:21:05 mvojkovi Exp $ */ #include "nv_include.h" @@ -407,7 +407,7 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x017D: case 0x0186: case 0x0187: - case 0x0189: + case 0x018D: case 0x0286: case 0x028C: case 0x0316: @@ -432,12 +432,10 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x0160: case 0x0166: case 0x00C8: - case 0x00C9: case 0x00CC: - case 0x0147: + case 0x0144: + case 0x0146: case 0x0148: - case 0x0149: - case 0x014C: mobile = TRUE; break; default: diff --git a/src/nv_type.h b/src/nv_type.h index 96ca4e4..690366e 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.48 2004/08/26 22:38:47 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.50 2004/12/09 00:21:05 mvojkovi Exp $ */ #ifndef __NV_STRUCT_H__ #define __NV_STRUCT_H__ @@ -44,6 +44,7 @@ typedef struct _riva_hw_state U032 scale; U032 dither; U032 extra; + U032 fifo; U032 pixel; U032 horiz; U032 arbitration0; @@ -67,6 +68,7 @@ typedef struct _riva_hw_state U032 timingH; U032 timingV; U032 displayV; + U032 crtcSync; } RIVA_HW_STATE, *NVRegPtr; @@ -157,6 +159,8 @@ typedef struct { int fpWidth; int fpHeight; CARD32 fpSyncs; + Bool usePanelTweak; + int PanelTweak; CARD32 dmaPut; CARD32 dmaCurrent; -- cgit v1.2.3