1 /***************************************************************************\
3 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
14 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
38 \***************************************************************************/
40 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.48 2005/09/14 02:28:03 mvojkovi Exp $ */
42 #include "nv_include.h"
46 * Override VGA I/O routines.
48 static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
50 NVPtr pNv = (NVPtr)pVga->MMIOBase;
51 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
52 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
53 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
55 static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
57 NVPtr pNv = (NVPtr)pVga->MMIOBase;
58 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
59 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
60 return (VGA_RD08(ptr, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
62 static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
64 NVPtr pNv = (NVPtr)pVga->MMIOBase;
65 VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
66 VGA_WR08(pNv->PVIO0, VGA_GRAPH_DATA, value);
68 static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
70 NVPtr pNv = (NVPtr)pVga->MMIOBase;
71 VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
72 return (VGA_RD08(pNv->PVIO0, VGA_GRAPH_DATA));
74 static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
76 NVPtr pNv = (NVPtr)pVga->MMIOBase;
77 VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
78 VGA_WR08(pNv->PVIO0, VGA_SEQ_DATA, value);
80 static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
82 NVPtr pNv = (NVPtr)pVga->MMIOBase;
83 VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
84 return (VGA_RD08(pNv->PVIO0, VGA_SEQ_DATA));
86 static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
88 NVPtr pNv = (NVPtr)pVga->MMIOBase;
89 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
92 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
93 if (pVga->paletteEnabled)
97 VGA_WR08(ptr, VGA_ATTR_INDEX, index);
98 VGA_WR08(ptr, VGA_ATTR_DATA_W, value);
100 static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
102 NVPtr pNv = (NVPtr)pVga->MMIOBase;
103 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
106 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
107 if (pVga->paletteEnabled)
111 VGA_WR08(ptr, VGA_ATTR_INDEX, index);
112 return (VGA_RD08(ptr, VGA_ATTR_DATA_R));
114 static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
116 NVPtr pNv = (NVPtr)pVga->MMIOBase;
117 VGA_WR08(pNv->PVIO0, VGA_MISC_OUT_W, value);
119 static CARD8 NVReadMiscOut(vgaHWPtr pVga)
121 NVPtr pNv = (NVPtr)pVga->MMIOBase;
122 return (VGA_RD08(pNv->PVIO0, VGA_MISC_OUT_R));
124 static void NVEnablePalette(vgaHWPtr pVga)
126 NVPtr pNv = (NVPtr)pVga->MMIOBase;
127 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
130 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
131 VGA_WR08(ptr, VGA_ATTR_INDEX, 0x00);
132 pVga->paletteEnabled = TRUE;
134 static void NVDisablePalette(vgaHWPtr pVga)
136 NVPtr pNv = (NVPtr)pVga->MMIOBase;
137 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
140 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
141 VGA_WR08(ptr, VGA_ATTR_INDEX, 0x20);
142 pVga->paletteEnabled = FALSE;
144 static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
146 NVPtr pNv = (NVPtr)pVga->MMIOBase;
147 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
148 VGA_WR08(ptr, VGA_DAC_MASK, value);
150 static CARD8 NVReadDacMask(vgaHWPtr pVga)
152 NVPtr pNv = (NVPtr)pVga->MMIOBase;
153 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
154 return (VGA_RD08(ptr, VGA_DAC_MASK));
156 static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
158 NVPtr pNv = (NVPtr)pVga->MMIOBase;
159 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
160 VGA_WR08(ptr, VGA_DAC_READ_ADDR, value);
162 static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
164 NVPtr pNv = (NVPtr)pVga->MMIOBase;
165 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
166 VGA_WR08(ptr, VGA_DAC_WRITE_ADDR, value);
168 static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
170 NVPtr pNv = (NVPtr)pVga->MMIOBase;
171 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
172 VGA_WR08(ptr, VGA_DAC_DATA, value);
174 static CARD8 NVReadDacData(vgaHWPtr pVga)
176 NVPtr pNv = (NVPtr)pVga->MMIOBase;
177 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
178 return (VGA_RD08(ptr, VGA_DAC_DATA));
182 NVIsConnected (ScrnInfoPtr pScrn, int output)
184 NVPtr pNv = NVPTR(pScrn);
185 CARD32 reg52C, reg608, temp;
188 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
189 "Probing for analog device on output %s...\n",
192 reg52C = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
193 reg608 = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
195 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, (reg608 & ~0x00010000));
197 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, (reg52C & 0x0000FEEE));
200 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
201 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, temp | 1);
203 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_DATA, 0x94050140);
204 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
205 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
209 present = (NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
212 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...found one\n");
214 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...can't find one\n");
216 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
217 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
219 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, reg52C);
220 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, reg608);
226 NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head)
228 NVPtr pNv = NVPTR(pScrn);
230 pNv->cur_head = head;
234 NVProbeDDC (ScrnInfoPtr pScrn, int bus)
236 NVPtr pNv = NVPTR(pScrn);
237 xf86MonPtr MonInfo = NULL;
239 if(!pNv->I2C) return NULL;
241 pNv->DDCBase = bus ? 0x36 : 0x3e;
243 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
244 "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A");
246 if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pNv->I2C))) {
247 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
248 "DDC detected a %s:\n", MonInfo->features.input_type ?
250 xf86PrintEDID( MonInfo );
252 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
253 " ... none found\n");
259 static void nv4GetConfig (NVPtr pNv)
261 uint32_t reg_FB0 = nvReadFB(pNv, NV_PFB_BOOT_0);
263 if (reg_FB0 & 0x00000100)
264 pNv->RamAmountKBytes = ((reg_FB0 >> 12) & 0x0F) * 1024 * 2 + 1024 * 2;
266 switch (reg_FB0 & 0x00000003) {
268 pNv->RamAmountKBytes = 1024 * 32;
271 pNv->RamAmountKBytes = 1024 * 4;
274 pNv->RamAmountKBytes = 1024 * 8;
278 pNv->RamAmountKBytes = 1024 * 16;
282 pNv->CrystalFreqKHz = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x00000040) ? 14318 : 13500;
283 pNv->CURSOR = &(pNv->PRAMIN[0x5E00]);
284 pNv->MinVClockFreqKHz = 12000;
285 pNv->MaxVClockFreqKHz = 350000;
288 static void nv10GetConfig (NVPtr pNv)
290 uint32_t implementation = pNv->Chipset & 0x0ff0;
292 #if X_BYTE_ORDER == X_BIG_ENDIAN
293 if (!(nvReadMC(pNv, 0x0004) & 0x01000001))
294 xf86DrvMsg(0, X_ERROR, "Card is in big endian mode, something is very wrong !\n");
297 if (implementation == CHIPSET_NFORCE) {
299 #ifdef XSERVER_LIBPCIACCESS
300 const struct pci_slot_match match[] = { {0, 0, 0, 1, 0} };
301 struct pci_device_iterator *iterator = pci_slot_match_iterator_create(match);
302 /* assume one device to exist */
303 struct pci_device *device = pci_device_next(iterator);
304 PCI_DEV_READ_LONG(device, 0x7c, &amt);
306 amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
307 #endif /* XSERVER_LIBPCIACCESS */
308 pNv->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
309 } else if (implementation == CHIPSET_NFORCE2) {
311 #ifdef XSERVER_LIBPCIACCESS
312 const struct pci_slot_match match[] = { {0, 0, 0, 1, 0} };
313 struct pci_device_iterator *iterator = pci_slot_match_iterator_create(match);
314 /* assume one device to exist */
315 struct pci_device *device = pci_device_next(iterator);
316 PCI_DEV_READ_LONG(device, 0x84, &amt);
318 amt = pciReadLong(pciTag(0, 0, 1), 0x84);
319 #endif /* XSERVER_LIBPCIACCESS */
320 pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
322 pNv->RamAmountKBytes = (nvReadFB(pNv, NV_PFB_020C) & 0xFFF00000) >> 10;
324 if (pNv->RamAmountKBytes > 256*1024)
325 pNv->RamAmountKBytes = 256*1024;
327 pNv->CrystalFreqKHz = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & (1 << 6)) ? 14318 : 13500;
328 if (pNv->twoHeads && implementation != CHIPSET_NV11)
329 if (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & (1 << 22))
330 pNv->CrystalFreqKHz = 27000;
332 pNv->CURSOR = NULL; /* can't set this here */
333 pNv->MinVClockFreqKHz = 12000;
334 pNv->MaxVClockFreqKHz = pNv->twoStagePLL ? 400000 : 350000;
338 NVCommonSetup(ScrnInfoPtr pScrn)
340 NVPtr pNv = NVPTR(pScrn);
341 vgaHWPtr pVga = VGAHWPTR(pScrn);
342 uint16_t implementation = pNv->Chipset & 0x0ff0;
343 xf86MonPtr monitorA, monitorB;
346 int FlatPanel = -1; /* really means the CRTC is slaved */
347 bool Television = false;
350 * Override VGA I/O routines.
352 pVga->writeCrtc = NVWriteCrtc;
353 pVga->readCrtc = NVReadCrtc;
354 pVga->writeGr = NVWriteGr;
355 pVga->readGr = NVReadGr;
356 pVga->writeAttr = NVWriteAttr;
357 pVga->readAttr = NVReadAttr;
358 pVga->writeSeq = NVWriteSeq;
359 pVga->readSeq = NVReadSeq;
360 pVga->writeMiscOut = NVWriteMiscOut;
361 pVga->readMiscOut = NVReadMiscOut;
362 pVga->enablePalette = NVEnablePalette;
363 pVga->disablePalette = NVDisablePalette;
364 pVga->writeDacMask = NVWriteDacMask;
365 pVga->readDacMask = NVReadDacMask;
366 pVga->writeDacWriteAddr = NVWriteDacWriteAddr;
367 pVga->writeDacReadAddr = NVWriteDacReadAddr;
368 pVga->writeDacData = NVWriteDacData;
369 pVga->readDacData = NVReadDacData;
371 * Note: There are different pointers to the CRTC/AR and GR/SEQ registers.
372 * Bastardize the intended uses of these to make it work.
374 pVga->MMIOBase = (CARD8 *)pNv;
375 pVga->MMIOOffset = 0;
377 #ifndef XSERVER_LIBPCIACCESS
378 pNv->REGS = xf86MapPciMem(pScrn->scrnIndex,
379 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
380 pNv->PciTag, pNv->IOAddress, 0x01000000);
382 /* 0x01000000 is the size */
383 pci_device_map_range(pNv->PciInfo, pNv->IOAddress, 0x01000000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->REGS);
384 #endif /* XSERVER_LIBPCIACCESS */
386 pNv->PRAMIN = pNv->REGS + (NV_PRAMIN_OFFSET/4);
387 pNv->NV50_PCRTC = pNv->REGS + (NV50_PCRTC_OFFSET/4);
388 pNv->PGRAPH = pNv->REGS + (NV_PGRAPH_OFFSET/4);
390 /* 8 bit registers */
391 pNv->PCIO0 = (uint8_t *)pNv->REGS + NV_PCIO0_OFFSET;
392 pNv->PDIO0 = (uint8_t *)pNv->REGS + NV_PDIO0_OFFSET;
393 pNv->PVIO0 = (uint8_t *)pNv->REGS + NV_PVIO0_OFFSET;
394 pNv->PCIO1 = pNv->PCIO0 + NV_PCIO_SIZE;
395 pNv->PDIO1 = pNv->PDIO0 + NV_PDIO_SIZE;
396 pNv->PVIO1 = pNv->PVIO0 + NV_PVIO_SIZE;
398 pNv->alphaCursor = (pNv->NVArch >= 0x11);
400 pNv->twoHeads = (pNv->Architecture >= NV_ARCH_10) &&
401 (implementation != CHIPSET_NV10) &&
402 (implementation != CHIPSET_NV15) &&
403 (implementation != CHIPSET_NFORCE) &&
404 (implementation != CHIPSET_NV20);
406 pNv->fpScaler = (pNv->FpScale && pNv->twoHeads && implementation != CHIPSET_NV11);
408 pNv->twoStagePLL = (implementation == CHIPSET_NV31) ||
409 (implementation == CHIPSET_NV36) ||
410 (pNv->Architecture >= NV_ARCH_40);
412 /* Don't mess with pre-randr12 situations. */
413 if (pNv->NVArch == 0x30 && pNv->randr12_enable)
414 pNv->twoStagePLL = TRUE;
416 pNv->WaitVSyncPossible = (pNv->Architecture >= NV_ARCH_10) &&
417 (implementation != CHIPSET_NV10);
419 pNv->BlendingPossible = ((pNv->Chipset & 0xffff) > CHIPSET_NV04);
421 /* look for known laptop chips */
422 /* FIXME still probably missing some ids (for randr12, pre-nv40 mobile should be auto-detected) */
423 switch(pNv->Chipset & 0xffff) {
491 pNv->Television = FALSE;
494 pNv->vtOWNER = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER);
495 if (pNv->NVArch == 0x11) { /* reading OWNER is broken on nv11 */
496 if (nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */
499 NVSetOwner(pScrn, 1);
500 NVLockVgaCrtc(pNv, 1, false);
502 uint8_t slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_PIXEL) & 0x80;
504 tvB = !(NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_LCD) & 0x01);
506 NVSetOwner(pScrn, 0);
507 NVLockVgaCrtc(pNv, 0, false);
509 uint8_t slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_PIXEL) & 0x80;
511 tvA = !(NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_LCD) & 0x01);
513 if (slaved_on_A && !tvA)
515 else if (slaved_on_B && !tvB)
517 else if (slaved_on_A)
519 else if (slaved_on_B)
526 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER);
529 /* Parse the bios to initialize the card */
532 if (pNv->Architecture == NV_ARCH_04)
537 if (!pNv->randr12_enable) {
539 NVSelectHeadRegisters(pScrn, 0);
541 NVLockUnlock(pScrn, 0);
547 pNv->crtc_active[0] = TRUE;
548 pNv->crtc_active[1] = FALSE;
549 if((monitorA = NVProbeDDC(pScrn, 0))) {
550 FlatPanel = monitorA->features.input_type ? 1 : 0;
552 /* NV4 doesn't support FlatPanels */
553 if((pNv->Chipset & 0x0fff) <= CHIPSET_NV04)
556 if(nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
557 if(!(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01))
563 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
564 "HW is currently programmed for %s\n",
565 FlatPanel ? (Television ? "TV" : "DFP") : "CRT");
568 if(pNv->FlatPanel == -1) {
569 pNv->FlatPanel = FlatPanel;
570 pNv->Television = Television;
572 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
573 "Forcing display type to %s as specified\n",
574 pNv->FlatPanel ? "DFP" : "CRT");
577 CARD8 outputAfromCRTC, outputBfromCRTC;
578 pNv->crtc_active[0] = FALSE;
579 pNv->crtc_active[1] = FALSE;
580 CARD8 slaved_on_A, slaved_on_B;
581 Bool analog_on_A, analog_on_B;
585 if(implementation != CHIPSET_NV11) {
586 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT) & 0x100)
590 if(NVReadRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT) & 0x100)
594 analog_on_A = NVIsConnected(pScrn, 0);
595 analog_on_B = NVIsConnected(pScrn, 1);
605 nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 3);
606 NVSelectHeadRegisters(pScrn, 1);
607 NVLockUnlock(pScrn, 0);
609 slaved_on_B = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80;
611 tvB = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01);
614 nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 0);
615 NVSelectHeadRegisters(pScrn, 0);
616 NVLockUnlock(pScrn, 0);
618 slaved_on_A = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80;
620 tvA = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01);
623 oldhead = NVReadCRTC(pNv, 0, NV_CRTC_FSEL);
624 NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead | 0x00000010);
626 monitorA = NVProbeDDC(pScrn, 0);
627 monitorB = NVProbeDDC(pScrn, 1);
629 if(slaved_on_A && !tvA) {
630 pNv->crtc_active[0] = TRUE;
632 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
633 "CRTC 0 is currently programmed for DFP\n");
635 if(slaved_on_B && !tvB) {
636 pNv->crtc_active[1] = TRUE;
638 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
639 "CRTC 1 is currently programmed for DFP\n");
642 pNv->crtc_active[outputAfromCRTC] = TRUE;
644 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
645 "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
648 pNv->crtc_active[outputBfromCRTC] = TRUE;
650 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
651 "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
654 pNv->crtc_active[0] = TRUE;
657 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
658 "CRTC 0 is currently programmed for TV\n");
661 pNv->crtc_active[1] = TRUE;
664 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
665 "CRTC 1 is currently programmed for TV\n");
668 FlatPanel = monitorA->features.input_type ? 1 : 0;
671 FlatPanel = monitorB->features.input_type ? 1 : 0;
674 if(pNv->FlatPanel == -1) {
675 if(FlatPanel != -1) {
676 pNv->FlatPanel = FlatPanel;
677 pNv->Television = Television;
679 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
680 "Unable to detect display type...\n");
682 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
683 "...On a laptop, assuming DFP\n");
686 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
687 "...Using default of CRT\n");
692 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
693 "Forcing display type to %s as specified\n",
694 pNv->FlatPanel ? "DFP" : "CRT");
697 if(!(pNv->crtc_active[0]) && !(pNv->crtc_active[1])) {
698 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
699 "Unable to detect which CRTC is used...\n");
701 pNv->crtc_active[1] = TRUE;
703 pNv->crtc_active[0] = TRUE;
705 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
706 "...Defaulting to CRTCNumber %i\n", pNv->crtc_active[1]);
710 if((monitorA->features.input_type && pNv->FlatPanel) ||
711 (!monitorA->features.input_type && !pNv->FlatPanel))
724 if((monitorB->features.input_type && !pNv->FlatPanel) ||
725 (!monitorB->features.input_type && pNv->FlatPanel))
734 if(implementation == CHIPSET_NV11)
735 cr44 = pNv->crtc_active[1] * 0x3;
737 NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead);
739 nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, cr44);
740 NVSelectHeadRegisters(pScrn, pNv->crtc_active[1]);
743 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
744 "Using %s on CRTC %i\n",
745 pNv->FlatPanel ? (pNv->Television ? "TV" : "DFP") : "CRT",
746 pNv->crtc_active[1]);
748 if(pNv->FlatPanel && !pNv->Television) {
749 pNv->fpWidth = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HDISP_END) + 1;
750 pNv->fpHeight = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_VDISP_END) + 1;
751 pNv->fpSyncs = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0x30000033;
752 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
753 pNv->fpWidth, pNv->fpHeight);
757 xf86SetDDCproperties(pScrn, monitorA);
759 if(!pNv->FlatPanel || (pScrn->depth != 24) || !pNv->twoHeads)
760 pNv->FPDither = FALSE;
763 if(pNv->FlatPanel && pNv->twoHeads) {
764 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_FP_TMDS_CONTROL, 0x00010004);
765 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_FP_TMDS_DATA) & 1)
767 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel is %s\n",
768 pNv->LVDS ? "LVDS" : "TMDS");