summaryrefslogtreecommitdiff
path: root/src/nv_driver.c
diff options
context:
space:
mode:
authorAlan Coopersmith <Alan.Coopersmith@sun.com>2004-11-10 02:53:44 +0000
committerAlan Coopersmith <Alan.Coopersmith@sun.com>2004-11-10 02:53:44 +0000
commit7c34d051168eba499beb20c40fd95703375f4c7b (patch)
tree4a2367c446ef7a9852ff80ad750bf5bd3ed264eb /src/nv_driver.c
parentfcd6d7b57edb4e396189a0a2683bcf08974f3b59 (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_driver.c')
-rw-r--r--src/nv_driver.c219
1 files changed, 183 insertions, 36 deletions
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 3ca1786..601d7ef 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.6 2004/09/17 03:04:52 ajax Exp $ */
+/* $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 +25,7 @@
/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
<jpaana@s2.org> */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.122 2004/01/10 22:31:53 mvojkovi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.128 2004/10/09 22:53:25 mvojkovi Exp $ */
#include "nv_include.h"
@@ -174,6 +174,8 @@ static SymTabRec NVKnownChipsets[] =
{ 0x10DE0323, "GeForce FX 5200SE" },
{ 0x10DE0324, "GeForce FX Go5200" },
{ 0x10DE0325, "GeForce FX Go5250" },
+ { 0x10DE0326, "GeForce FX 5500" },
+ { 0x10DE0327, "GeForce FX 5100" },
{ 0x10DE0328, "GeForce FX Go5200 32M/64M" },
#if defined(__powerpc__)
{ 0x10DE0329, "GeForce FX 5200 (Mac)" },
@@ -181,15 +183,16 @@ static SymTabRec NVKnownChipsets[] =
{ 0x10DE0329, "0x0329" },
#endif
{ 0x10DE032A, "Quadro NVS 280 PCI" },
- { 0x10DE032B, "Quadro FX 500" },
- { 0x10DE032C, "GeForce FX Go5300" },
+ { 0x10DE032B, "Quadro FX 500/600 PCI" },
+ { 0x10DE032C, "GeForce FX Go53xx Series" },
{ 0x10DE032D, "GeForce FX Go5100" },
{ 0x10DE032F, "0x032F" },
{ 0x10DE0330, "GeForce FX 5900 Ultra" },
{ 0x10DE0331, "GeForce FX 5900" },
{ 0x10DE0332, "GeForce FX 5900XT" },
{ 0x10DE0333, "GeForce FX 5950 Ultra" },
- { 0x10DE0334, "0x0334" },
+ { 0x10DE033F, "Quadro FX 700" },
+ { 0x10DE0334, "GeForce FX 5900ZT" },
{ 0x10DE0338, "Quadro FX 3000" },
{ 0x10DE0341, "GeForce FX 5700 Ultra" },
{ 0x10DE0342, "GeForce FX 5700" },
@@ -203,6 +206,41 @@ static SymTabRec NVKnownChipsets[] =
{ 0x10DE034C, "Quadro FX Go1000" },
{ 0x10DE034E, "Quadro FX 1100" },
{ 0x10DE034F, "0x034F" },
+ { 0x10DE0040, "GeForce 6800 Ultra" },
+ { 0x10DE0041, "GeForce 6800" },
+ { 0x10DE0042, "GeForce 6800 LE" },
+ { 0x10DE0043, "0x0043" },
+ { 0x10DE0045, "GeForce 6800 GT" },
+ { 0x10DE0049, "0x0049" },
+ { 0x10DE004E, "Quadro FX 4000" },
+ { 0x10DE00C0, "0x00C0" },
+ { 0x10DE00C1, "0x00C1" },
+ { 0x10DE00C2, "0x00C2" },
+ { 0x10DE00C8, "0x00C8" },
+ { 0x10DE00C9, "0x00C9" },
+ { 0x10DE00CC, "0x00CC" },
+ { 0x10DE00CE, "0x00CE" },
+ { 0x10DE0140, "GeForce 6600 GT" },
+ { 0x10DE0141, "GeForce 6600" },
+ { 0x10DE0142, "0x0142" },
+ { 0x10DE0143, "0x0143" },
+ { 0x10DE0144, "0x0144" },
+ { 0x10DE0145, "GeForce 6610 XL" },
+ { 0x10DE0146, "0x0146" },
+ { 0x10DE0147, "0x0147" },
+ { 0x10DE0148, "0x0148" },
+ { 0x10DE0149, "0x0149" },
+ { 0x10DE014B, "0x014B" },
+ { 0x10DE014C, "0x014C" },
+ { 0x10DE014D, "0x014D" },
+ { 0x10DE014E, "Quadro FX 540" },
+ { 0x10DE014F, "GeForce 6200" },
+ { 0x10DE0160, "0x0160" },
+ { 0x10DE0166, "0x0166" },
+ { 0x10DE0210, "0x0210" },
+ { 0x10DE0211, "0x0211" },
+ { 0x10DE021D, "0x021D" },
+ { 0x10DE021E, "0x021E" },
{-1, NULL}
};
@@ -350,7 +388,8 @@ typedef enum {
OPTION_VIDEO_KEY,
OPTION_FLAT_PANEL,
OPTION_FP_DITHER,
- OPTION_CRTC_NUMBER
+ OPTION_CRTC_NUMBER,
+ OPTION_FP_SCALE
} NVOpts;
@@ -365,6 +404,7 @@ static const OptionInfoRec NVOptions[] = {
{ OPTION_FLAT_PANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_CRTC_NUMBER, "CrtcNumber", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FP_SCALE, "FPScale", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -494,6 +534,36 @@ NVGetScrnInfoRec(PciChipsets *chips, int chip)
#define MAX_CHIPS MAXSCREENS
+
+static CARD32
+NVGetPCIXpressChip (pciVideoPtr pVideo)
+{
+ volatile CARD32 *regs;
+ CARD32 pciid, pcicmd;
+ PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag;
+
+ pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG);
+ pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE);
+
+ regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000);
+
+ pciid = regs[0x1800/4];
+
+ xf86UnMapVidMem(-1, (pointer)regs, 0x2000);
+
+ pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd);
+
+ if((pciid & 0x0000ffff) == 0x000010DE)
+ pciid = 0x10DE0000 | (pciid >> 16);
+ else
+ if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */
+ pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) |
+ ((pciid >> 8) & 0x000000ff);
+
+ return pciid;
+}
+
+
/* Mandatory */
static Bool
NVProbe(DriverPtr drv, int flags)
@@ -523,7 +593,11 @@ NVProbe(DriverPtr drv, int flags)
((*ppPci)->vendor == PCI_VENDOR_NVIDIA))
{
SymTabRec *nvchips = NVKnownChipsets;
- int token = ((*ppPci)->vendor << 16) | (*ppPci)->chipType;
+ int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType;
+ int token = pciid;
+
+ if((token & 0xfff0) == 0x00F0)
+ token = NVGetPCIXpressChip(*ppPci);
while(nvchips->name) {
if(token == nvchips->token)
@@ -532,10 +606,10 @@ NVProbe(DriverPtr drv, int flags)
}
if(nvchips->name) { /* found one */
- NVChipsets[numUsed].token = nvchips->token;
+ NVChipsets[numUsed].token = pciid;
NVChipsets[numUsed].name = nvchips->name;
- NVPciChipsets[numUsed].numChipset = nvchips->token;
- NVPciChipsets[numUsed].PCIid = nvchips->token;
+ NVPciChipsets[numUsed].numChipset = pciid;
+ NVPciChipsets[numUsed].PCIid = pciid;
NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
numUsed++;
} else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) {
@@ -551,10 +625,19 @@ NVProbe(DriverPtr drv, int flags)
case 0x0320:
case 0x0330:
case 0x0340:
- NVChipsets[numUsed].token = token;
+ case 0x0040:
+ case 0x00C0:
+ case 0x0120:
+ case 0x0140:
+ case 0x0160:
+ case 0x0130:
+ case 0x01D0:
+ case 0x0090:
+ case 0x0210:
+ NVChipsets[numUsed].token = pciid;
NVChipsets[numUsed].name = "Unknown NVIDIA chip";
- NVPciChipsets[numUsed].numChipset = token;
- NVPciChipsets[numUsed].PCIid = token;
+ NVPciChipsets[numUsed].numChipset = pciid;
+ NVPciChipsets[numUsed].PCIid = pciid;
NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
numUsed++;
break;
@@ -768,6 +851,17 @@ NVFreeScreen(int scrnIndex, int flags)
static ModeStatus
NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
+ NVPtr pNv = NVPTR(xf86Screens[scrnIndex]);
+
+ if(pNv->fpWidth && pNv->fpHeight) {
+ if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay)) {
+ xf86DrvMsg(scrnIndex, X_INFO, "Mode \"%s\" is larger than "
+ "BIOS programmed panel size of %d x %d. Removing.\n",
+ mode->name, pNv->fpWidth, pNv->fpHeight);
+ return (MODE_BAD);
+ }
+ }
+
return (MODE_OK);
}
@@ -887,11 +981,16 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
} else {
from = X_PROBED;
pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType;
+
+ if((pNv->Chipset & 0xfff0) == 0x00F0)
+ pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo);
+
pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets,
pNv->Chipset);
if(!pScrn->chipset)
pScrn->chipset = "Unknown NVIDIA chipset";
}
+
if (pNv->pEnt->device->chipRev >= 0) {
pNv->ChipRev = pNv->pEnt->device->chipRev;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
@@ -1026,6 +1125,12 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
}
xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
pNv->HWCursor ? "HW" : "SW");
+
+ pNv->FpScale = TRUE;
+ if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
+ pNv->FpScale ? "on" : "off");
+ }
if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
pNv->NoAccel = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
@@ -1178,12 +1283,46 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- pNv->alphaCursor = ((pNv->Chipset & 0x0ff0) >= 0x0110);
-
- pNv->Architecture = (pNv->Chipset & 0x0f00) >> 4;
+ switch (pNv->Chipset & 0x0ff0) {
+ case 0x0100: /* GeForce 256 */
+ case 0x0110: /* GeForce2 MX */
+ case 0x0150: /* GeForce2 */
+ case 0x0170: /* GeForce4 MX */
+ case 0x0180: /* GeForce4 MX (8x AGP) */
+ case 0x01A0: /* nForce */
+ case 0x01F0: /* nForce2 */
+ pNv->Architecture = NV_ARCH_10;
+ break;
+ case 0x0200: /* GeForce3 */
+ case 0x0250: /* GeForce4 Ti */
+ case 0x0280: /* GeForce4 Ti (8x AGP) */
+ pNv->Architecture = NV_ARCH_20;
+ break;
+ case 0x0300: /* GeForceFX 5800 */
+ case 0x0310: /* GeForceFX 5600 */
+ case 0x0320: /* GeForceFX 5200 */
+ case 0x0330: /* GeForceFX 5900 */
+ case 0x0340: /* GeForceFX 5700 */
+ pNv->Architecture = NV_ARCH_30;
+ break;
+ case 0x0040:
+ case 0x00C0:
+ case 0x0120:
+ case 0x0130:
+ case 0x0140:
+ case 0x0160:
+ case 0x01D0:
+ case 0x0090:
+ case 0x0210:
+ pNv->Architecture = NV_ARCH_40;
+ break;
+ default:
+ pNv->Architecture = NV_ARCH_04;
+ break;
+ }
- if(pNv->Architecture < NV_ARCH_10)
- pNv->Architecture = NV_ARCH_04;
+ pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) &&
+ ((pNv->Chipset & 0x0ff0) != 0x0100);
NVCommonSetup(pScrn);
@@ -1225,17 +1364,17 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
clockRanges->minClock = pNv->MinVClockFreqKHz;
clockRanges->maxClock = pNv->MaxVClockFreqKHz;
clockRanges->clockIndex = -1; /* programmable */
- if(((pNv->Chipset & 0x0ff0) <= 0x0100) ||
- ((pNv->Chipset & 0x0ff0) == 0x0150) ||
- ((pNv->Chipset & 0x0ff0) >= 0x0300))
+ clockRanges->doubleScanAllowed = TRUE;
+ if((pNv->Architecture == NV_ARCH_20) ||
+ ((pNv->Architecture == NV_ARCH_10) &&
+ ((pNv->Chipset & 0x0ff0) != 0x0100) &&
+ ((pNv->Chipset & 0x0ff0) != 0x0150)))
{
- clockRanges->interlaceAllowed = TRUE;
- } else {
- /* No NV2x chips support interlaced modes and the only
- NV1x chips that do are NV10 and NV15 */
+ /* HW is broken */
clockRanges->interlaceAllowed = FALSE;
+ } else {
+ clockRanges->interlaceAllowed = TRUE;
}
- clockRanges->doubleScanAllowed = TRUE;
if(pNv->FlatPanel == 1) {
clockRanges->interlaceAllowed = FALSE;
@@ -1489,25 +1628,27 @@ NVRestore(ScrnInfoPtr pScrn)
NVRegPtr nvReg = &pNv->SavedReg;
NVLockUnlock(pNv, 0);
+
if(pNv->twoHeads) {
- VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
- VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3);
- NVLockUnlock(pNv, 0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3);
+ NVLockUnlock(pNv, 0);
}
/* Only restore text mode fonts/text for the primary card */
vgaHWProtect(pScrn, TRUE);
NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
if(pNv->twoHeads) {
- VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
- VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner);
- }
-
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner);
+ }
vgaHWProtect(pScrn, FALSE);
}
static void NVBacklightEnable(NVPtr pNv, Bool on)
{
+ CARD32 fpcontrol = pNv->PRAMDAC[0x0848/4] & 0xCfffffCC;
+
/* This is done differently on each laptop. Here we
define the ones we know for sure. */
@@ -1528,6 +1669,12 @@ static void NVBacklightEnable(NVPtr pNv, Bool on)
pNv->PCRTC0[0x081C/4] = tmp_pcrt;
}
#endif
+
+ /* cut the TMDS output */
+ if(on) fpcontrol |= pNv->fpSyncs;
+ else fpcontrol |= 0x20000022;
+
+ pNv->PRAMDAC[0x0848/4] = fpcontrol;
}
static void
@@ -1837,9 +1984,9 @@ NVSave(ScrnInfoPtr pScrn)
NVLockUnlock(pNv, 0);
if(pNv->twoHeads) {
- VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
- VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3);
- NVLockUnlock(pNv, 0);
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3);
+ NVLockUnlock(pNv, 0);
}
NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);