2 * Copyright 2003 NVIDIA, Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include "nv_include.h"
27 * Override VGA I/O routines.
29 static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
31 NVPtr pNv = (NVPtr)pVga->MMIOBase;
32 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
33 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
34 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
36 static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
38 NVPtr pNv = (NVPtr)pVga->MMIOBase;
39 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
40 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
41 return (VGA_RD08(ptr, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
43 static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
45 NVPtr pNv = (NVPtr)pVga->MMIOBase;
46 VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
47 VGA_WR08(pNv->PVIO0, VGA_GRAPH_DATA, value);
49 static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
51 NVPtr pNv = (NVPtr)pVga->MMIOBase;
52 VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
53 return (VGA_RD08(pNv->PVIO0, VGA_GRAPH_DATA));
55 static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
57 NVPtr pNv = (NVPtr)pVga->MMIOBase;
58 VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
59 VGA_WR08(pNv->PVIO0, VGA_SEQ_DATA, value);
61 static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
63 NVPtr pNv = (NVPtr)pVga->MMIOBase;
64 VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
65 return (VGA_RD08(pNv->PVIO0, VGA_SEQ_DATA));
67 static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
69 NVPtr pNv = (NVPtr)pVga->MMIOBase;
70 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
73 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
74 if (pVga->paletteEnabled)
78 VGA_WR08(ptr, VGA_ATTR_INDEX, index);
79 VGA_WR08(ptr, VGA_ATTR_DATA_W, value);
81 static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
83 NVPtr pNv = (NVPtr)pVga->MMIOBase;
84 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
87 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
88 if (pVga->paletteEnabled)
92 VGA_WR08(ptr, VGA_ATTR_INDEX, index);
93 return (VGA_RD08(ptr, VGA_ATTR_DATA_R));
95 static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
97 NVPtr pNv = (NVPtr)pVga->MMIOBase;
98 VGA_WR08(pNv->PVIO0, VGA_MISC_OUT_W, value);
100 static CARD8 NVReadMiscOut(vgaHWPtr pVga)
102 NVPtr pNv = (NVPtr)pVga->MMIOBase;
103 return (VGA_RD08(pNv->PVIO0, VGA_MISC_OUT_R));
105 static void NVEnablePalette(vgaHWPtr pVga)
107 NVPtr pNv = (NVPtr)pVga->MMIOBase;
108 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
111 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
112 VGA_WR08(ptr, VGA_ATTR_INDEX, 0x00);
113 pVga->paletteEnabled = TRUE;
115 static void NVDisablePalette(vgaHWPtr pVga)
117 NVPtr pNv = (NVPtr)pVga->MMIOBase;
118 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
121 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
122 VGA_WR08(ptr, VGA_ATTR_INDEX, 0x20);
123 pVga->paletteEnabled = FALSE;
125 static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
127 NVPtr pNv = (NVPtr)pVga->MMIOBase;
128 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
129 VGA_WR08(ptr, VGA_DAC_MASK, value);
131 static CARD8 NVReadDacMask(vgaHWPtr pVga)
133 NVPtr pNv = (NVPtr)pVga->MMIOBase;
134 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
135 return (VGA_RD08(ptr, VGA_DAC_MASK));
137 static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
139 NVPtr pNv = (NVPtr)pVga->MMIOBase;
140 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
141 VGA_WR08(ptr, VGA_DAC_READ_ADDR, value);
143 static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
145 NVPtr pNv = (NVPtr)pVga->MMIOBase;
146 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
147 VGA_WR08(ptr, VGA_DAC_WRITE_ADDR, value);
149 static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
151 NVPtr pNv = (NVPtr)pVga->MMIOBase;
152 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
153 VGA_WR08(ptr, VGA_DAC_DATA, value);
155 static CARD8 NVReadDacData(vgaHWPtr pVga)
157 NVPtr pNv = (NVPtr)pVga->MMIOBase;
158 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
159 return (VGA_RD08(ptr, VGA_DAC_DATA));
163 NVIsConnected (ScrnInfoPtr pScrn, int output)
165 NVPtr pNv = NVPTR(pScrn);
166 CARD32 reg52C, reg608, temp;
169 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
170 "Probing for analog device on output %s...\n",
173 reg52C = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
174 reg608 = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
176 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, (reg608 & ~0x00010000));
178 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, (reg52C & 0x0000FEEE));
181 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
182 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, temp | 1);
184 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_DATA, 0x94050140);
185 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
186 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
190 present = (NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
193 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...found one\n");
195 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...can't find one\n");
197 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
198 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
200 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, reg52C);
201 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, reg608);
207 NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head)
209 NVPtr pNv = NVPTR(pScrn);
211 pNv->cur_head = head;
215 NVProbeDDC (ScrnInfoPtr pScrn, int bus)
217 NVPtr pNv = NVPTR(pScrn);
218 xf86MonPtr MonInfo = NULL;
220 if(!pNv->I2C) return NULL;
222 pNv->DDCBase = bus ? 0x36 : 0x3e;
224 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
225 "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A");
227 if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pNv->I2C))) {
228 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
229 "DDC detected a %s:\n", MonInfo->features.input_type ?
231 xf86PrintEDID( MonInfo );
233 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
234 " ... none found\n");
240 static void nv4GetConfig (NVPtr pNv)
242 uint32_t reg_FB0 = nvReadFB(pNv, NV_PFB_BOOT_0);
244 if (reg_FB0 & 0x00000100)
245 pNv->RamAmountKBytes = ((reg_FB0 >> 12) & 0x0F) * 1024 * 2 + 1024 * 2;
247 switch (reg_FB0 & 0x00000003) {
249 pNv->RamAmountKBytes = 1024 * 32;
252 pNv->RamAmountKBytes = 1024 * 4;
255 pNv->RamAmountKBytes = 1024 * 8;
259 pNv->RamAmountKBytes = 1024 * 16;
263 pNv->CrystalFreqKHz = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x00000040) ? 14318 : 13500;
264 pNv->CURSOR = &(pNv->PRAMIN[0x5E00]);
265 pNv->MinVClockFreqKHz = 12000;
266 pNv->MaxVClockFreqKHz = 350000;
269 static void nv10GetConfig (NVPtr pNv)
271 uint32_t implementation = pNv->Chipset & 0x0ff0;
273 #if X_BYTE_ORDER == X_BIG_ENDIAN
274 if (!(nvReadMC(pNv, 0x0004) & 0x01000001))
275 xf86DrvMsg(0, X_ERROR, "Card is in big endian mode, something is very wrong !\n");
278 if (implementation == CHIPSET_NFORCE) {
280 #ifdef XSERVER_LIBPCIACCESS
281 const struct pci_slot_match match[] = { {0, 0, 0, 1, 0} };
282 struct pci_device_iterator *iterator = pci_slot_match_iterator_create(match);
283 /* assume one device to exist */
284 struct pci_device *device = pci_device_next(iterator);
285 PCI_DEV_READ_LONG(device, 0x7c, &amt);
287 amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
288 #endif /* XSERVER_LIBPCIACCESS */
289 pNv->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
290 } else if (implementation == CHIPSET_NFORCE2) {
292 #ifdef XSERVER_LIBPCIACCESS
293 const struct pci_slot_match match[] = { {0, 0, 0, 1, 0} };
294 struct pci_device_iterator *iterator = pci_slot_match_iterator_create(match);
295 /* assume one device to exist */
296 struct pci_device *device = pci_device_next(iterator);
297 PCI_DEV_READ_LONG(device, 0x84, &amt);
299 amt = pciReadLong(pciTag(0, 0, 1), 0x84);
300 #endif /* XSERVER_LIBPCIACCESS */
301 pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
303 pNv->RamAmountKBytes = (nvReadFB(pNv, NV_PFB_020C) & 0xFFF00000) >> 10;
305 if (pNv->RamAmountKBytes > 256*1024)
306 pNv->RamAmountKBytes = 256*1024;
308 pNv->CrystalFreqKHz = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & (1 << 6)) ? 14318 : 13500;
309 if (pNv->twoHeads && implementation != CHIPSET_NV11)
310 if (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & (1 << 22))
311 pNv->CrystalFreqKHz = 27000;
313 pNv->CURSOR = NULL; /* can't set this here */
314 pNv->MinVClockFreqKHz = 12000;
315 pNv->MaxVClockFreqKHz = pNv->twoStagePLL ? 400000 : 350000;
319 NVCommonSetup(ScrnInfoPtr pScrn)
321 NVPtr pNv = NVPTR(pScrn);
322 vgaHWPtr pVga = VGAHWPTR(pScrn);
323 uint16_t implementation = pNv->Chipset & 0x0ff0;
326 xf86MonPtr monitorA, monitorB;
327 int FlatPanel = -1; /* really means the CRTC is slaved */
328 bool Television = false;
331 * Override VGA I/O routines.
333 pVga->writeCrtc = NVWriteCrtc;
334 pVga->readCrtc = NVReadCrtc;
335 pVga->writeGr = NVWriteGr;
336 pVga->readGr = NVReadGr;
337 pVga->writeAttr = NVWriteAttr;
338 pVga->readAttr = NVReadAttr;
339 pVga->writeSeq = NVWriteSeq;
340 pVga->readSeq = NVReadSeq;
341 pVga->writeMiscOut = NVWriteMiscOut;
342 pVga->readMiscOut = NVReadMiscOut;
343 pVga->enablePalette = NVEnablePalette;
344 pVga->disablePalette = NVDisablePalette;
345 pVga->writeDacMask = NVWriteDacMask;
346 pVga->readDacMask = NVReadDacMask;
347 pVga->writeDacWriteAddr = NVWriteDacWriteAddr;
348 pVga->writeDacReadAddr = NVWriteDacReadAddr;
349 pVga->writeDacData = NVWriteDacData;
350 pVga->readDacData = NVReadDacData;
352 * Note: There are different pointers to the CRTC/AR and GR/SEQ registers.
353 * Bastardize the intended uses of these to make it work.
355 pVga->MMIOBase = (CARD8 *)pNv;
356 pVga->MMIOOffset = 0;
358 #ifndef XSERVER_LIBPCIACCESS
359 pNv->REGS = xf86MapPciMem(pScrn->scrnIndex,
360 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
361 pNv->PciTag, pNv->IOAddress, 0x01000000);
362 pNv->FB_BAR = xf86MapPciMem(pScrn->scrnIndex,
363 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
364 pNv->PciTag, pNv->VRAMPhysical, 0x10000);
366 /* 0x01000000 is the size */
367 pci_device_map_range(pNv->PciInfo, pNv->IOAddress, 0x01000000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->REGS);
368 pci_device_map_range(pNv->PciInfo, pNv->VRAMPhysical, 0x10000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->FB_BAR);
369 #endif /* XSERVER_LIBPCIACCESS */
371 pNv->PRAMIN = pNv->REGS + (NV_PRAMIN_OFFSET/4);
372 pNv->PGRAPH = pNv->REGS + (NV_PGRAPH_OFFSET/4);
374 /* 8 bit registers */
375 pNv->PCIO0 = (uint8_t *)pNv->REGS + NV_PCIO0_OFFSET;
376 pNv->PDIO0 = (uint8_t *)pNv->REGS + NV_PDIO0_OFFSET;
377 pNv->PVIO0 = (uint8_t *)pNv->REGS + NV_PVIO0_OFFSET;
378 pNv->PCIO1 = pNv->PCIO0 + NV_PCIO_SIZE;
379 pNv->PDIO1 = pNv->PDIO0 + NV_PDIO_SIZE;
380 pNv->PVIO1 = pNv->PVIO0 + NV_PVIO_SIZE;
382 pNv->alphaCursor = (pNv->NVArch >= 0x11);
384 pNv->twoHeads = (pNv->Architecture >= NV_ARCH_10) &&
385 (implementation != CHIPSET_NV10) &&
386 (implementation != CHIPSET_NV15) &&
387 (implementation != CHIPSET_NFORCE) &&
388 (implementation != CHIPSET_NV20);
390 pNv->fpScaler = (pNv->FpScale && pNv->twoHeads && implementation != CHIPSET_NV11);
392 /* nv30 and nv35 have two stage PLLs, but use only one register; they are dealt with separately */
393 pNv->twoStagePLL = (implementation == CHIPSET_NV31) ||
394 (implementation == CHIPSET_NV36) ||
395 (pNv->Architecture >= NV_ARCH_40);
397 pNv->WaitVSyncPossible = (pNv->Architecture >= NV_ARCH_10) &&
398 (implementation != CHIPSET_NV10);
400 pNv->BlendingPossible = ((pNv->Chipset & 0xffff) > CHIPSET_NV04);
402 /* look for known laptop chips */
403 /* FIXME still probably missing some ids (for randr12, pre-nv40 mobile should be auto-detected) */
404 switch(pNv->Chipset & 0xffff) {
472 pNv->Television = FALSE;
475 pNv->vtOWNER = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER);
476 if (pNv->NVArch == 0x11) { /* reading OWNER is broken on nv11 */
477 if (nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */
480 uint8_t slaved_on_A, slaved_on_B;
482 NVSetOwner(pScrn, 1);
483 NVLockVgaCrtc(pNv, 1, false);
485 slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_PIXEL) & 0x80;
487 tvB = !(NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_LCD) & 0x01);
489 NVSetOwner(pScrn, 0);
490 NVLockVgaCrtc(pNv, 0, false);
492 slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_PIXEL) & 0x80;
494 tvA = !(NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_LCD) & 0x01);
496 if (slaved_on_A && !tvA)
498 else if (slaved_on_B && !tvB)
500 else if (slaved_on_A)
502 else if (slaved_on_B)
509 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER);
512 /* Parse the bios to initialize the card */
515 if (pNv->Architecture == NV_ARCH_04)
520 if (!pNv->randr12_enable) {
522 NVSelectHeadRegisters(pScrn, 0);
524 NVLockUnlock(pScrn, 0);
530 pNv->crtc_active[0] = TRUE;
531 pNv->crtc_active[1] = FALSE;
532 if((monitorA = NVProbeDDC(pScrn, 0))) {
533 FlatPanel = monitorA->features.input_type ? 1 : 0;
535 /* NV4 doesn't support FlatPanels */
536 if((pNv->Chipset & 0x0fff) <= CHIPSET_NV04)
539 if(nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
540 if(!(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01))
546 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
547 "HW is currently programmed for %s\n",
548 FlatPanel ? (Television ? "TV" : "DFP") : "CRT");
551 if(pNv->FlatPanel == -1) {
552 pNv->FlatPanel = FlatPanel;
553 pNv->Television = Television;
555 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
556 "Forcing display type to %s as specified\n",
557 pNv->FlatPanel ? "DFP" : "CRT");
560 CARD8 outputAfromCRTC, outputBfromCRTC;
561 pNv->crtc_active[0] = FALSE;
562 pNv->crtc_active[1] = FALSE;
563 CARD8 slaved_on_A, slaved_on_B;
564 Bool analog_on_A, analog_on_B;
568 if(implementation != CHIPSET_NV11) {
569 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT) & 0x100)
573 if(NVReadRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT) & 0x100)
577 analog_on_A = NVIsConnected(pScrn, 0);
578 analog_on_B = NVIsConnected(pScrn, 1);
588 nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 3);
589 NVSelectHeadRegisters(pScrn, 1);
590 NVLockUnlock(pScrn, 0);
592 slaved_on_B = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80;
594 tvB = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01);
597 nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 0);
598 NVSelectHeadRegisters(pScrn, 0);
599 NVLockUnlock(pScrn, 0);
601 slaved_on_A = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80;
603 tvA = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01);
606 oldhead = NVReadCRTC(pNv, 0, NV_CRTC_FSEL);
607 NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead | 0x00000010);
609 monitorA = NVProbeDDC(pScrn, 0);
610 monitorB = NVProbeDDC(pScrn, 1);
612 if(slaved_on_A && !tvA) {
613 pNv->crtc_active[0] = TRUE;
615 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
616 "CRTC 0 is currently programmed for DFP\n");
618 if(slaved_on_B && !tvB) {
619 pNv->crtc_active[1] = TRUE;
621 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
622 "CRTC 1 is currently programmed for DFP\n");
625 pNv->crtc_active[outputAfromCRTC] = TRUE;
627 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
628 "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
631 pNv->crtc_active[outputBfromCRTC] = TRUE;
633 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
634 "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
637 pNv->crtc_active[0] = TRUE;
640 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
641 "CRTC 0 is currently programmed for TV\n");
644 pNv->crtc_active[1] = TRUE;
647 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
648 "CRTC 1 is currently programmed for TV\n");
651 FlatPanel = monitorA->features.input_type ? 1 : 0;
654 FlatPanel = monitorB->features.input_type ? 1 : 0;
657 if(pNv->FlatPanel == -1) {
658 if(FlatPanel != -1) {
659 pNv->FlatPanel = FlatPanel;
660 pNv->Television = Television;
662 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
663 "Unable to detect display type...\n");
665 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
666 "...On a laptop, assuming DFP\n");
669 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
670 "...Using default of CRT\n");
675 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
676 "Forcing display type to %s as specified\n",
677 pNv->FlatPanel ? "DFP" : "CRT");
680 if(!(pNv->crtc_active[0]) && !(pNv->crtc_active[1])) {
681 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
682 "Unable to detect which CRTC is used...\n");
684 pNv->crtc_active[1] = TRUE;
686 pNv->crtc_active[0] = TRUE;
688 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
689 "...Defaulting to CRTCNumber %i\n", pNv->crtc_active[1]);
693 if((monitorA->features.input_type && pNv->FlatPanel) ||
694 (!monitorA->features.input_type && !pNv->FlatPanel))
707 if((monitorB->features.input_type && !pNv->FlatPanel) ||
708 (!monitorB->features.input_type && pNv->FlatPanel))
717 if(implementation == CHIPSET_NV11)
718 cr44 = pNv->crtc_active[1] * 0x3;
720 NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead);
722 nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, cr44);
723 NVSelectHeadRegisters(pScrn, pNv->crtc_active[1]);
726 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
727 "Using %s on CRTC %i\n",
728 pNv->FlatPanel ? (pNv->Television ? "TV" : "DFP") : "CRT",
729 pNv->crtc_active[1]);
731 if(pNv->FlatPanel && !pNv->Television) {
732 pNv->fpWidth = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HDISP_END) + 1;
733 pNv->fpHeight = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_VDISP_END) + 1;
734 pNv->fpSyncs = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0x30000033;
735 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
736 pNv->fpWidth, pNv->fpHeight);
740 xf86SetDDCproperties(pScrn, monitorA);
742 if(!pNv->FlatPanel || (pScrn->depth != 24) || !pNv->twoHeads)
743 pNv->FPDither = FALSE;
746 if(pNv->FlatPanel && pNv->twoHeads) {
747 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_FP_TMDS_CONTROL, 0x00010004);
748 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_FP_TMDS_DATA) & 1)
750 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel is %s\n",
751 pNv->LVDS ? "LVDS" : "TMDS");