diff options
Diffstat (limited to 'src/nv_setup.c')
-rw-r--r-- | src/nv_setup.c | 815 |
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; } |