summaryrefslogtreecommitdiff
path: root/src/nv_setup.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:48:59 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:48:59 +0000
commitb56dd6bacff59e17249b5a1427f99edf93657f30 (patch)
tree35b54cb736b90c40f13185173092c178038b7e8c /src/nv_setup.c
parent6962e55a393c6b1cddf6b23f9c39842234b4ef7d (diff)
merge latest (4.3.99.16) from XFree86 (vendor) branch
Diffstat (limited to 'src/nv_setup.c')
-rw-r--r--src/nv_setup.c815
1 files changed, 468 insertions, 347 deletions
diff --git a/src/nv_setup.c b/src/nv_setup.c
index cdb0ade..8f84f8e 100644
--- a/src/nv_setup.c
+++ b/src/nv_setup.c
@@ -1,30 +1,43 @@
-/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
-/*
- * Copyright 1996-1997 David J. McKay
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* 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_setup.c,v 1.27.2.1 2003/05/09 02:17:49 dawes Exp $ */
+ /***************************************************************************\
+|* *|
+|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
+|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
+|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+ \***************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.39 2003/11/07 23:56:28 mvojkovi Exp $ */
#include "nv_include.h"
@@ -34,82 +47,82 @@
static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
- VGA_WR08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
+ VGA_WR08(pNv->PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ VGA_WR08(pNv->PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
}
static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
- return (VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
+ VGA_WR08(pNv->PCIO, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ return (VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
}
static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PVIO, VGA_GRAPH_INDEX, index);
- VGA_WR08(pNv->riva.PVIO, VGA_GRAPH_DATA, value);
+ VGA_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
+ VGA_WR08(pNv->PVIO, VGA_GRAPH_DATA, value);
}
static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PVIO, VGA_GRAPH_INDEX, index);
- return (VGA_RD08(pNv->riva.PVIO, VGA_GRAPH_DATA));
+ VGA_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
+ return (VGA_RD08(pNv->PVIO, VGA_GRAPH_DATA));
}
static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PVIO, VGA_SEQ_INDEX, index);
- VGA_WR08(pNv->riva.PVIO, VGA_SEQ_DATA, value);
+ VGA_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
+ VGA_WR08(pNv->PVIO, VGA_SEQ_DATA, value);
}
static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PVIO, VGA_SEQ_INDEX, index);
- return (VGA_RD08(pNv->riva.PVIO, VGA_SEQ_DATA));
+ VGA_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
+ return (VGA_RD08(pNv->PVIO, VGA_SEQ_DATA));
}
static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
volatile CARD8 tmp;
- tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
if (pVga->paletteEnabled)
index &= ~0x20;
else
index |= 0x20;
- VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, index);
- VGA_WR08(pNv->riva.PCIO, VGA_ATTR_DATA_W, value);
+ VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, index);
+ VGA_WR08(pNv->PCIO, VGA_ATTR_DATA_W, value);
}
static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
volatile CARD8 tmp;
- tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
if (pVga->paletteEnabled)
index &= ~0x20;
else
index |= 0x20;
- VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, index);
- return (VGA_RD08(pNv->riva.PCIO, VGA_ATTR_DATA_R));
+ VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, index);
+ return (VGA_RD08(pNv->PCIO, VGA_ATTR_DATA_R));
}
static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PVIO, VGA_MISC_OUT_W, value);
+ VGA_WR08(pNv->PVIO, VGA_MISC_OUT_W, value);
}
static CARD8 NVReadMiscOut(vgaHWPtr pVga)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- return (VGA_RD08(pNv->riva.PVIO, VGA_MISC_OUT_R));
+ return (VGA_RD08(pNv->PVIO, VGA_MISC_OUT_R));
}
static void NVEnablePalette(vgaHWPtr pVga)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
volatile CARD8 tmp;
- tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
- VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, 0x00);
+ tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, 0x00);
pVga->paletteEnabled = TRUE;
}
static void NVDisablePalette(vgaHWPtr pVga)
@@ -117,50 +130,54 @@ static void NVDisablePalette(vgaHWPtr pVga)
NVPtr pNv = (NVPtr)pVga->MMIOBase;
volatile CARD8 tmp;
- tmp = VGA_RD08(pNv->riva.PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
- VGA_WR08(pNv->riva.PCIO, VGA_ATTR_INDEX, 0x20);
+ tmp = VGA_RD08(pNv->PCIO, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
+ VGA_WR08(pNv->PCIO, VGA_ATTR_INDEX, 0x20);
pVga->paletteEnabled = FALSE;
}
static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PDIO, VGA_DAC_MASK, value);
+ VGA_WR08(pNv->PDIO, VGA_DAC_MASK, value);
}
static CARD8 NVReadDacMask(vgaHWPtr pVga)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- return (VGA_RD08(pNv->riva.PDIO, VGA_DAC_MASK));
+ return (VGA_RD08(pNv->PDIO, VGA_DAC_MASK));
}
static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PDIO, VGA_DAC_READ_ADDR, value);
+ VGA_WR08(pNv->PDIO, VGA_DAC_READ_ADDR, value);
}
static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PDIO, VGA_DAC_WRITE_ADDR, value);
+ VGA_WR08(pNv->PDIO, VGA_DAC_WRITE_ADDR, value);
}
static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- VGA_WR08(pNv->riva.PDIO, VGA_DAC_DATA, value);
+ VGA_WR08(pNv->PDIO, VGA_DAC_DATA, value);
}
static CARD8 NVReadDacData(vgaHWPtr pVga)
{
NVPtr pNv = (NVPtr)pVga->MMIOBase;
- return (VGA_RD08(pNv->riva.PDIO, VGA_DAC_DATA));
+ return (VGA_RD08(pNv->PDIO, VGA_DAC_DATA));
}
static Bool
-NVIsConnected (ScrnInfoPtr pScrn, Bool second)
+NVIsConnected (ScrnInfoPtr pScrn, int output)
{
NVPtr pNv = NVPTR(pScrn);
- volatile U032 *PRAMDAC = pNv->riva.PRAMDAC0;
+ volatile U032 *PRAMDAC = pNv->PRAMDAC0;
CARD32 reg52C, reg608;
Bool present;
- if(second) PRAMDAC += 0x800;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Probing for analog device on output %s...\n",
+ output ? "B" : "A");
+
+ if(output) PRAMDAC += 0x800;
reg52C = PRAMDAC[0x052C/4];
reg608 = PRAMDAC[0x0608/4];
@@ -171,14 +188,19 @@ NVIsConnected (ScrnInfoPtr pScrn, Bool second)
usleep(1000);
PRAMDAC[0x052C/4] |= 1;
- pNv->riva.PRAMDAC0[0x0610/4] = 0x94050140;
- pNv->riva.PRAMDAC0[0x0608/4] |= 0x00001000;
+ pNv->PRAMDAC0[0x0610/4] = 0x94050140;
+ pNv->PRAMDAC0[0x0608/4] |= 0x00001000;
usleep(1000);
present = (PRAMDAC[0x0608/4] & (1 << 28)) ? TRUE : FALSE;
- pNv->riva.PRAMDAC0[0x0608/4] &= 0x0000EFFF;
+ if(present)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...found one\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...can't find one\n");
+
+ pNv->PRAMDAC0[0x0608/4] &= 0x0000EFFF;
PRAMDAC[0x052C/4] = reg52C;
PRAMDAC[0x0608/4] = reg608;
@@ -187,94 +209,130 @@ NVIsConnected (ScrnInfoPtr pScrn, Bool second)
}
static void
-NVOverrideCRTC(ScrnInfoPtr pScrn)
+NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head)
{
NVPtr pNv = NVPTR(pScrn);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected CRTC controller %i being used\n",
- pNv->SecondCRTC ? 1 : 0);
-
- if(pNv->forceCRTC != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Forcing usage of CRTC %i\n", pNv->forceCRTC);
- pNv->SecondCRTC = pNv->forceCRTC;
+ if(head) {
+ pNv->PCIO = pNv->PCIO0 + 0x2000;
+ pNv->PCRTC = pNv->PCRTC0 + 0x800;
+ pNv->PRAMDAC = pNv->PRAMDAC0 + 0x800;
+ pNv->PDIO = pNv->PDIO0 + 0x2000;
+ } else {
+ pNv->PCIO = pNv->PCIO0;
+ pNv->PCRTC = pNv->PCRTC0;
+ pNv->PRAMDAC = pNv->PRAMDAC0;
+ pNv->PDIO = pNv->PDIO0;
}
}
-static void
-NVIsSecond (ScrnInfoPtr pScrn)
+static xf86MonPtr
+NVProbeDDC (ScrnInfoPtr pScrn, int bus)
{
NVPtr pNv = NVPTR(pScrn);
+ xf86MonPtr MonInfo = NULL;
- if(pNv->FlatPanel == 1) {
- switch(pNv->Chipset & 0xffff) {
- case 0x0174:
- case 0x0175:
- case 0x0176:
- case 0x0177:
- case 0x0179:
- case 0x017C:
- case 0x017D:
- case 0x0186:
- case 0x0187:
- /* this might not be a good default for the chips below */
- case 0x0286:
- case 0x028C:
- case 0x0316:
- case 0x0317:
- case 0x031A:
- case 0x031B:
- case 0x031C:
- case 0x031D:
- case 0x031E:
- case 0x031F:
- case 0x0326:
- case 0x032E:
- pNv->SecondCRTC = TRUE;
- break;
- default:
- pNv->SecondCRTC = FALSE;
- break;
- }
+ if(!pNv->I2C) return NULL;
+
+ pNv->DDCBase = bus ? 0x36 : 0x3e;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A");
+
+ if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pNv->I2C))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "DDC detected a %s:\n", MonInfo->features.input_type ?
+ "DFP" : "CRT");
+ xf86PrintEDID( MonInfo );
} else {
- if(NVIsConnected(pScrn, 0)) {
- if(pNv->riva.PRAMDAC0[0x0000052C/4] & 0x100)
- pNv->SecondCRTC = TRUE;
- else
- pNv->SecondCRTC = FALSE;
- } else
- if (NVIsConnected(pScrn, 1)) {
- pNv->DDCBase = 0x36;
- if(pNv->riva.PRAMDAC0[0x0000252C/4] & 0x100)
- pNv->SecondCRTC = TRUE;
- else
- pNv->SecondCRTC = FALSE;
- } else /* default */
- pNv->SecondCRTC = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " ... none found\n");
}
- NVOverrideCRTC(pScrn);
+ return MonInfo;
}
-static void
-NVCommonSetup(ScrnInfoPtr pScrn)
+static void nv4GetConfig (NVPtr pNv)
{
- NVPtr pNv = NVPTR(pScrn);
- vgaHWPtr pVga = VGAHWPTR(pScrn);
- CARD32 regBase = pNv->IOAddress;
- int mmioFlags;
+ if (pNv->PFB[0x0000/4] & 0x00000100) {
+ pNv->RamAmountKBytes = ((pNv->PFB[0x0000/4] >> 12) & 0x0F) * 1024 * 2
+ + 1024 * 2;
+ } else {
+ switch (pNv->PFB[0x0000/4] & 0x00000003) {
+ case 0:
+ pNv->RamAmountKBytes = 1024 * 32;
+ break;
+ case 1:
+ pNv->RamAmountKBytes = 1024 * 4;
+ break;
+ case 2:
+ pNv->RamAmountKBytes = 1024 * 8;
+ break;
+ case 3:
+ default:
+ pNv->RamAmountKBytes = 1024 * 16;
+ break;
+ }
+ }
+ pNv->CrystalFreqKHz = (pNv->PEXTDEV[0x0000/4] & 0x00000040) ? 14318 : 13500;
+ pNv->CURSOR = &(pNv->PRAMIN[0x1E00]);
+ pNv->MinVClockFreqKHz = 12000;
+ pNv->MaxVClockFreqKHz = 350000;
+}
+
+static void nv10GetConfig (NVPtr pNv)
+{
+ CARD32 implementation = pNv->Chipset & 0x0ff0;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* turn on big endian register access */
+ if(!(pNv->PMC[0x0004/4] & 0x01000001)) {
+ pNv->PMC[0x0004/4] = 0x01000001;
+ mem_barrier();
+ }
+#endif
+
+ if((pNv->Chipset && 0xffff) == 0x01a0) {
+ int amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
+ pNv->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
+ } else if((pNv->Chipset & 0xffff) == 0x01f0) {
+ int amt = pciReadLong(pciTag(0, 0, 1), 0x84);
+ pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
+ } else {
+ pNv->RamAmountKBytes = (pNv->PFB[0x020C/4] & 0xFFF00000) >> 10;
+ }
+
+ pNv->CrystalFreqKHz = (pNv->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 : 13500;
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVCommonSetup\n"));
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Regbase %x\n", regBase));
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- riva %x\n", &pNv->riva));
+ if((implementation == 0x0170) ||
+ (implementation == 0x0180) ||
+ (implementation == 0x01F0) ||
+ (implementation >= 0x0250))
+ {
+ if(pNv->PEXTDEV[0x0000/4] & (1 << 22))
+ pNv->CrystalFreqKHz = 27000;
+ }
- pNv->Save = NVDACSave;
- pNv->Restore = NVDACRestore;
- pNv->ModeInit = NVDACInit;
+ pNv->CursorStart = (pNv->RamAmountKBytes - 96) * 1024;
+ pNv->CURSOR = NULL; /* can't set this here */
+ pNv->MinVClockFreqKHz = 12000;
+ pNv->MaxVClockFreqKHz = pNv->twoStagePLL ? 400000 : 350000;
+}
- pNv->Dac.LoadPalette = NVDACLoadPalette;
+void
+NVCommonSetup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ vgaHWPtr pVga = VGAHWPTR(pScrn);
+ CARD16 implementation = pNv->Chipset & 0x0ff0;
+ xf86MonPtr monitorA, monitorB;
+ Bool mobile = FALSE;
+ Bool tvA = FALSE;
+ Bool tvB = FALSE;
+ int FlatPanel = -1; /* really means the CRTC is slaved */
+ Bool Television = FALSE;
+
/*
* Override VGA I/O routines.
*/
@@ -303,249 +361,312 @@ NVCommonSetup(ScrnInfoPtr pScrn)
pVga->MMIOBase = (CARD8 *)pNv;
pVga->MMIOOffset = 0;
- /*
- * No IRQ in use.
- */
- pNv->riva.EnableIRQ = 0;
- /*
- * Map remaining registers. This MUST be done in the OS specific driver code.
- */
- pNv->riva.IO = VGA_IOBASE_COLOR;
-
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- IO %x\n", pNv->riva.IO));
-
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
-
- pNv->riva.PRAMDAC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00680000, 0x00003000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PRAMDAC %x\n", pNv->riva.PRAMDAC0));
- pNv->riva.PFB = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00100000, 0x00001000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PFB %x\n", pNv->riva.PFB));
- pNv->riva.PFIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00002000, 0x00002000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PFIFO %x\n", pNv->riva.PFIFO));
- pNv->riva.PGRAPH = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00400000, 0x00002000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PGRAPH %x\n", pNv->riva.PGRAPH));
- pNv->riva.PEXTDEV = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00101000, 0x00001000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PEXTDEV %x\n", pNv->riva.PEXTDEV));
- pNv->riva.PTIMER = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00009000, 0x00001000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PTIMER %x\n", pNv->riva.PTIMER));
- pNv->riva.PMC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00000000, 0x00009000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PMC %x\n", pNv->riva.PMC));
- pNv->riva.FIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00800000, 0x00010000);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- FIFO %x\n", pNv->riva.FIFO));
-
- /*
- * These registers are read/write as 8 bit values. Probably have to map
- * sparse on alpha.
- */
- pNv->riva.PCIO0 = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
- pNv->PciTag, regBase+0x00601000,
- 0x00003000);
- pNv->riva.PDIO0 = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
- pNv->PciTag, regBase+0x00681000,
- 0x00003000);
- pNv->riva.PVIO = (U008 *)xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
- pNv->PciTag, regBase+0x000C0000,
- 0x00001000);
-
- if(pNv->FlatPanel == -1) {
- switch(pNv->Chipset & 0xffff) {
- case 0x0112: /* known laptop chips */
- case 0x0174:
- case 0x0175:
- case 0x0176:
- case 0x0177:
- case 0x0179:
- case 0x017C:
- case 0x017D:
- case 0x0186:
- case 0x0187:
- case 0x0286:
- case 0x028C:
- case 0x0316:
- case 0x0317:
- case 0x031A:
- case 0x031B:
- case 0x031C:
- case 0x031D:
- case 0x031E:
- case 0x031F:
- case 0x0326:
- case 0x032E:
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "On a laptop. Assuming Digital Flat Panel\n");
- pNv->FlatPanel = 1;
- break;
- default:
- break;
- }
- }
-
- pNv->DDCBase = 0x3e;
-
- switch(pNv->Chipset & 0x0ff0) {
- case 0x0110:
- if((pNv->Chipset & 0xffff) == 0x0112)
- pNv->SecondCRTC = TRUE;
-#if defined(__powerpc__)
- else if(pNv->FlatPanel == 1)
- pNv->SecondCRTC = TRUE;
-#endif
- NVOverrideCRTC(pScrn);
- break;
- case 0x0170:
- case 0x0180:
- case 0x01F0:
- case 0x0250:
- case 0x0280:
- case 0x0300:
- case 0x0310:
- case 0x0320:
- case 0x0330:
- case 0x0340:
- NVIsSecond(pScrn);
+ pNv->REGS = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ pNv->PciTag, pNv->IOAddress, 0x01000000);
+
+ pNv->PRAMIN = pNv->REGS + (0x00710000/4);
+ pNv->PCRTC0 = pNv->REGS + (0x00600000/4);
+ pNv->PRAMDAC0 = pNv->REGS + (0x00680000/4);
+ pNv->PFB = pNv->REGS + (0x00100000/4);
+ pNv->PFIFO = pNv->REGS + (0x00002000/4);
+ pNv->PGRAPH = pNv->REGS + (0x00400000/4);
+ pNv->PEXTDEV = pNv->REGS + (0x00101000/4);
+ pNv->PTIMER = pNv->REGS + (0x00009000/4);
+ pNv->PMC = pNv->REGS + (0x00000000/4);
+ pNv->FIFO = pNv->REGS + (0x00800000/4);
+
+ /* 8 bit registers */
+ pNv->PCIO0 = (U008*)pNv->REGS + 0x00601000;
+ pNv->PDIO0 = (U008*)pNv->REGS + 0x00681000;
+ pNv->PVIO = (U008*)pNv->REGS + 0x000C0000;
+
+ pNv->twoHeads = (implementation >= 0x0110) &&
+ (implementation != 0x0150) &&
+ (implementation != 0x01A0) &&
+ (implementation != 0x0200);
+
+ pNv->fpScaler = (pNv->twoHeads && (implementation != 0x0110));
+
+ pNv->twoStagePLL = (implementation == 0x0310) ||
+ (implementation == 0x0340);
+
+ /* look for known laptop chips */
+ switch(pNv->Chipset & 0xffff) {
+ case 0x0112:
+ case 0x0174:
+ case 0x0175:
+ case 0x0176:
+ case 0x0177:
+ case 0x0179:
+ case 0x017C:
+ case 0x017D:
+ case 0x0186:
+ case 0x0187:
+ case 0x0189:
+ case 0x0286:
+ case 0x028C:
+ case 0x0316:
+ case 0x0317:
+ case 0x031A:
+ case 0x031B:
+ case 0x031C:
+ case 0x031D:
+ case 0x031E:
+ case 0x031F:
+ case 0x0324:
+ case 0x0325:
+ case 0x0328:
+ case 0x0329:
+ case 0x032C:
+ case 0x032D:
+ case 0x0347:
+ case 0x0348:
+ case 0x0349:
+ case 0x034B:
+ case 0x034C:
+ mobile = TRUE;
break;
default:
break;
}
- if(pNv->riva.Architecture == 3)
- pNv->riva.PCRTC0 = pNv->riva.PGRAPH;
+ if(pNv->Architecture == NV_ARCH_04)
+ nv4GetConfig(pNv);
+ else
+ nv10GetConfig(pNv);
- if(pNv->SecondCRTC) {
- pNv->riva.PCIO = pNv->riva.PCIO0 + 0x2000;
- pNv->riva.PCRTC = pNv->riva.PCRTC0 + 0x800;
- pNv->riva.PRAMDAC = pNv->riva.PRAMDAC0 + 0x800;
- pNv->riva.PDIO = pNv->riva.PDIO0 + 0x2000;
- } else {
- pNv->riva.PCIO = pNv->riva.PCIO0;
- pNv->riva.PCRTC = pNv->riva.PCRTC0;
- pNv->riva.PRAMDAC = pNv->riva.PRAMDAC0;
- pNv->riva.PDIO = pNv->riva.PDIO0;
- }
+ NVSelectHeadRegisters(pScrn, 0);
- RivaGetConfig(pNv);
+ NVLockUnlock(pNv, 0);
- pNv->Dac.maxPixelClock = pNv->riva.MaxVClockFreqKHz;
+ NVI2CInit(pScrn);
- pNv->riva.LockUnlock(&pNv->riva, 0);
+ pNv->Television = FALSE;
- NVRamdacInit(pScrn);
+ if(!pNv->twoHeads) {
+ pNv->CRTCnumber = 0;
+ if((monitorA = NVProbeDDC(pScrn, 0))) {
+ FlatPanel = monitorA->features.input_type ? 1 : 0;
-#if !defined(__powerpc__)
- /* Read and print the Monitor DDC info */
- pScrn->monitor->DDC = NVdoDDC(pScrn);
-#endif
- if(pNv->FlatPanel == -1) {
- pNv->FlatPanel = 0;
- if(pScrn->monitor->DDC) {
- xf86MonPtr ddc = (xf86MonPtr)pScrn->monitor->DDC;
-
- if(ddc->features.input_type) {
- pNv->FlatPanel = 1;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "autodetected Digital Flat Panel\n");
+ /* NV4 doesn't support FlatPanels */
+ if((pNv->Chipset & 0x0fff) <= 0x0020)
+ FlatPanel = 0;
+ } else {
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
+ if(VGA_RD08(pNv->PCIO, 0x03D5) & 0x80) {
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x33);
+ if(!(VGA_RD08(pNv->PCIO, 0x03D5) & 0x01))
+ Television = TRUE;
+ FlatPanel = 1;
+ } else {
+ FlatPanel = 0;
}
- }
- }
- pNv->riva.flatPanel = (pNv->FlatPanel > 0) ? FP_ENABLE : 0;
- if(pNv->riva.flatPanel && pNv->FPDither && (pScrn->depth == 24))
- pNv->riva.flatPanel |= FP_DITHER;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "HW is currently programmed for %s\n",
+ FlatPanel ? (Television ? "TV" : "DFP") : "CRT");
+ }
+
+ if(pNv->FlatPanel == -1) {
+ pNv->FlatPanel = FlatPanel;
+ pNv->Television = Television;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Forcing display type to %s as specified\n",
+ pNv->FlatPanel ? "DFP" : "CRT");
+ }
+ } else {
+ CARD8 outputAfromCRTC, outputBfromCRTC;
+ int CRTCnumber = -1;
+ CARD8 slaved_on_A, slaved_on_B;
+ Bool analog_on_A, analog_on_B;
+ CARD32 oldhead;
+ CARD8 cr44;
+
+ if(implementation != 0x0110) {
+ if(pNv->PRAMDAC0[0x0000052C/4] & 0x100)
+ outputAfromCRTC = 1;
+ else
+ outputAfromCRTC = 0;
+ if(pNv->PRAMDAC0[0x0000252C/4] & 0x100)
+ outputBfromCRTC = 1;
+ else
+ outputBfromCRTC = 0;
+ analog_on_A = NVIsConnected(pScrn, 0);
+ analog_on_B = NVIsConnected(pScrn, 1);
+ } else {
+ outputAfromCRTC = 0;
+ outputBfromCRTC = 1;
+ analog_on_A = FALSE;
+ analog_on_B = FALSE;
+ }
-}
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ cr44 = VGA_RD08(pNv->PCIO, 0x03D5);
-void
-NV1Setup(ScrnInfoPtr pScrn)
-{
-}
+ VGA_WR08(pNv->PCIO, 0x03D5, 3);
+ NVSelectHeadRegisters(pScrn, 1);
+ NVLockUnlock(pNv, 0);
-void
-NV3Setup(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- CARD32 frameBase = pNv->FbAddress;
- int mmioFlags;
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
+ slaved_on_B = VGA_RD08(pNv->PCIO, 0x03D5) & 0x80;
+ if(slaved_on_B) {
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x33);
+ tvB = !(VGA_RD08(pNv->PCIO, 0x03D5) & 0x01);
+ }
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV3Setup\n"));
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ VGA_WR08(pNv->PCIO, 0x03D5, 0);
+ NVSelectHeadRegisters(pScrn, 0);
+ NVLockUnlock(pNv, 0);
- /*
- * Record chip architecture based in PCI probe.
- */
- pNv->riva.Architecture = 3;
- /*
- * Map chip-specific memory-mapped registers. This MUST be done in the OS specific driver code.
- */
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
- pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- frameBase+0x00C00000, 0x00008000);
-
- NVCommonSetup(pScrn);
-}
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
+ slaved_on_A = VGA_RD08(pNv->PCIO, 0x03D5) & 0x80;
+ if(slaved_on_A) {
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x33);
+ tvA = !(VGA_RD08(pNv->PCIO, 0x03D5) & 0x01);
+ }
-void
-NV4Setup(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- CARD32 regBase = pNv->IOAddress;
- int mmioFlags;
+ oldhead = pNv->PCRTC0[0x00000860/4];
+ pNv->PCRTC0[0x00000860/4] = oldhead | 0x00000010;
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV4Setup\n"));
+ monitorA = NVProbeDDC(pScrn, 0);
+ monitorB = NVProbeDDC(pScrn, 1);
- pNv->riva.Architecture = 4;
- /*
- * Map chip-specific memory-mapped registers. This MUST be done in the OS specific driver code.
- */
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
- pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00710000, 0x00010000);
- pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00600000, 0x00001000);
+ if(slaved_on_A && !tvA) {
+ CRTCnumber = 0;
+ FlatPanel = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRTC 0 is currently programmed for DFP\n");
+ } else
+ if(slaved_on_B && !tvB) {
+ CRTCnumber = 1;
+ FlatPanel = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRTC 1 is currently programmed for DFP\n");
+ } else
+ if(analog_on_A) {
+ CRTCnumber = outputAfromCRTC;
+ FlatPanel = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRTC %i appears to have a CRT attached\n", CRTCnumber);
+ } else
+ if(analog_on_B) {
+ CRTCnumber = outputBfromCRTC;
+ FlatPanel = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRTC %i appears to have a CRT attached\n", CRTCnumber);
+ } else
+ if(slaved_on_A) {
+ CRTCnumber = 0;
+ FlatPanel = 1;
+ Television = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRTC 0 is currently programmed for TV\n");
+ } else
+ if(slaved_on_B) {
+ CRTCnumber = 1;
+ FlatPanel = 1;
+ Television = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRTC 1 is currently programmed for TV\n");
+ } else
+ if(monitorA) {
+ FlatPanel = monitorA->features.input_type ? 1 : 0;
+ } else
+ if(monitorB) {
+ FlatPanel = monitorB->features.input_type ? 1 : 0;
+ }
- NVCommonSetup(pScrn);
-}
+ if(pNv->FlatPanel == -1) {
+ if(FlatPanel != -1) {
+ pNv->FlatPanel = FlatPanel;
+ pNv->Television = Television;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Unable to detect display type...\n");
+ if(mobile) {
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "...On a laptop, assuming DFP\n");
+ pNv->FlatPanel = 1;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "...Using default of CRT\n");
+ pNv->FlatPanel = 0;
+ }
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Forcing display type to %s as specified\n",
+ pNv->FlatPanel ? "DFP" : "CRT");
+ }
-void
-NV10Setup(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- CARD32 regBase = pNv->IOAddress;
- int mmioFlags;
+ if(pNv->CRTCnumber == -1) {
+ if(CRTCnumber != -1) pNv->CRTCnumber = CRTCnumber;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Unable to detect which CRTCNumber...\n");
+ if(pNv->FlatPanel) pNv->CRTCnumber = 1;
+ else pNv->CRTCnumber = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "...Defaulting to CRTCNumber %i\n", pNv->CRTCnumber);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Forcing CRTCNumber %i as specified\n", pNv->CRTCnumber);
+ }
+
+ if(monitorA) {
+ if((monitorA->features.input_type && pNv->FlatPanel) ||
+ (!monitorA->features.input_type && !pNv->FlatPanel))
+ {
+ if(monitorB) {
+ xfree(monitorB);
+ monitorB = NULL;
+ }
+ } else {
+ xfree(monitorA);
+ monitorA = NULL;
+ }
+ }
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV10Setup\n"));
+ if(monitorB) {
+ if((monitorB->features.input_type && !pNv->FlatPanel) ||
+ (!monitorB->features.input_type && pNv->FlatPanel))
+ {
+ xfree(monitorB);
+ } else {
+ monitorA = monitorB;
+ }
+ monitorB = NULL;
+ }
- pNv->riva.Architecture = 0x10;
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
- pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00710000, 0x00010000);
- pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00600000, 0x00003000);
+ if(implementation == 0x0110)
+ cr44 = pNv->CRTCnumber * 0x3;
- NVCommonSetup(pScrn);
-}
+ pNv->PCRTC0[0x00000860/4] = oldhead;
-void
-NV20Setup(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- CARD32 regBase = pNv->IOAddress;
- int mmioFlags;
+ VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
+ VGA_WR08(pNv->PCIO, 0x03D5, cr44);
+ NVSelectHeadRegisters(pScrn, pNv->CRTCnumber);
+ }
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV20Setup\n"));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %s on CRTC %i\n",
+ pNv->FlatPanel ? (pNv->Television ? "TV" : "DFP") : "CRT",
+ pNv->CRTCnumber);
+
+ if(pNv->FlatPanel && !pNv->Television) {
+ pNv->fpWidth = pNv->PRAMDAC[0x0820/4] + 1;
+ pNv->fpHeight = pNv->PRAMDAC[0x0800/4] + 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
+ pNv->fpWidth, pNv->fpHeight);
+ }
- pNv->riva.Architecture = 0x20;
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
- pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00710000, 0x00010000);
- pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
- regBase+0x00600000, 0x00003000);
+ if(monitorA)
+ xf86SetDDCproperties(pScrn, monitorA);
- NVCommonSetup(pScrn);
+ if(!pNv->FlatPanel || (pScrn->depth != 24))
+ pNv->FPDither = FALSE;
}