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"
26 * Override VGA I/O routines.
28 static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
30 NVPtr pNv = (NVPtr)pVga->MMIOBase;
31 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
32 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
33 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_DATA_OFFSET, value);
35 static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
37 NVPtr pNv = (NVPtr)pVga->MMIOBase;
38 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
39 VGA_WR08(ptr, pVga->IOBase + VGA_CRTC_INDEX_OFFSET, index);
40 return (VGA_RD08(ptr, pVga->IOBase + VGA_CRTC_DATA_OFFSET));
42 static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
44 NVPtr pNv = (NVPtr)pVga->MMIOBase;
45 VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
46 VGA_WR08(pNv->PVIO0, VGA_GRAPH_DATA, value);
48 static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
50 NVPtr pNv = (NVPtr)pVga->MMIOBase;
51 VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
52 return (VGA_RD08(pNv->PVIO0, VGA_GRAPH_DATA));
54 static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
56 NVPtr pNv = (NVPtr)pVga->MMIOBase;
57 VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
58 VGA_WR08(pNv->PVIO0, VGA_SEQ_DATA, value);
60 static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
62 NVPtr pNv = (NVPtr)pVga->MMIOBase;
63 VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
64 return (VGA_RD08(pNv->PVIO0, VGA_SEQ_DATA));
66 static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
68 NVPtr pNv = (NVPtr)pVga->MMIOBase;
69 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
72 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
73 if (pVga->paletteEnabled)
77 VGA_WR08(ptr, VGA_ATTR_INDEX, index);
78 VGA_WR08(ptr, VGA_ATTR_DATA_W, value);
80 static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
82 NVPtr pNv = (NVPtr)pVga->MMIOBase;
83 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
86 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
87 if (pVga->paletteEnabled)
91 VGA_WR08(ptr, VGA_ATTR_INDEX, index);
92 return (VGA_RD08(ptr, VGA_ATTR_DATA_R));
94 static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
96 NVPtr pNv = (NVPtr)pVga->MMIOBase;
97 VGA_WR08(pNv->PVIO0, VGA_MISC_OUT_W, value);
99 static CARD8 NVReadMiscOut(vgaHWPtr pVga)
101 NVPtr pNv = (NVPtr)pVga->MMIOBase;
102 return (VGA_RD08(pNv->PVIO0, VGA_MISC_OUT_R));
104 static void NVEnablePalette(vgaHWPtr pVga)
106 NVPtr pNv = (NVPtr)pVga->MMIOBase;
107 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
110 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
111 VGA_WR08(ptr, VGA_ATTR_INDEX, 0x00);
112 pVga->paletteEnabled = TRUE;
114 static void NVDisablePalette(vgaHWPtr pVga)
116 NVPtr pNv = (NVPtr)pVga->MMIOBase;
117 volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
120 tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
121 VGA_WR08(ptr, VGA_ATTR_INDEX, 0x20);
122 pVga->paletteEnabled = FALSE;
124 static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
126 NVPtr pNv = (NVPtr)pVga->MMIOBase;
127 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
128 VGA_WR08(ptr, VGA_DAC_MASK, value);
130 static CARD8 NVReadDacMask(vgaHWPtr pVga)
132 NVPtr pNv = (NVPtr)pVga->MMIOBase;
133 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
134 return (VGA_RD08(ptr, VGA_DAC_MASK));
136 static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
138 NVPtr pNv = (NVPtr)pVga->MMIOBase;
139 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
140 VGA_WR08(ptr, VGA_DAC_READ_ADDR, value);
142 static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
144 NVPtr pNv = (NVPtr)pVga->MMIOBase;
145 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
146 VGA_WR08(ptr, VGA_DAC_WRITE_ADDR, value);
148 static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
150 NVPtr pNv = (NVPtr)pVga->MMIOBase;
151 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
152 VGA_WR08(ptr, VGA_DAC_DATA, value);
154 static CARD8 NVReadDacData(vgaHWPtr pVga)
156 NVPtr pNv = (NVPtr)pVga->MMIOBase;
157 volatile CARD8 *ptr = pNv->cur_head ? pNv->PDIO1 : pNv->PDIO0;
158 return (VGA_RD08(ptr, VGA_DAC_DATA));
162 NVIsConnected (ScrnInfoPtr pScrn, int output)
164 NVPtr pNv = NVPTR(pScrn);
165 CARD32 reg52C, reg608, temp;
168 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
169 "Probing for analog device on output %s...\n",
172 reg52C = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
173 reg608 = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
175 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, (reg608 & ~0x00010000));
177 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, (reg52C & 0x0000FEEE));
180 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
181 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, temp | 1);
183 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_DATA, 0x94050140);
184 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
185 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
189 present = (NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
192 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...found one\n");
194 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...can't find one\n");
196 temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
197 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
199 NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, reg52C);
200 NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, reg608);
206 NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head)
208 NVPtr pNv = NVPTR(pScrn);
210 pNv->cur_head = head;
214 NVProbeDDC (ScrnInfoPtr pScrn, int bus)
216 NVPtr pNv = NVPTR(pScrn);
217 xf86MonPtr MonInfo = NULL;
219 if(!pNv->I2C) return NULL;
221 pNv->DDCBase = bus ? 0x36 : 0x3e;
223 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
224 "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A");
226 if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pNv->I2C))) {
227 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
228 "DDC detected a %s:\n", MonInfo->features.input_type ?
230 xf86PrintEDID( MonInfo );
232 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
233 " ... none found\n");
239 static void store_initial_head_owner(ScrnInfoPtr pScrn)
241 NVPtr pNv = NVPTR(pScrn);
243 if (pNv->NVArch != 0x11) {
244 pNv->vtOWNER = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_44);
248 /* reading CR44 is broken on nv11, so we attempt to infer it */
249 if (nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */
252 uint8_t slaved_on_A, slaved_on_B;
253 bool tvA, tvB = false;
255 NVLockVgaCrtcs(pNv, false);
257 slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
259 tvB = !(NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_LCD__INDEX) & NV_CIO_CRE_LCD_LCD_SELECT);
261 slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
263 tvA = !(NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_LCD__INDEX) & NV_CIO_CRE_LCD_LCD_SELECT);
265 NVLockVgaCrtcs(pNv, true);
267 if (slaved_on_A && !tvA)
269 else if (slaved_on_B && !tvB)
271 else if (slaved_on_A)
273 else if (slaved_on_B)
280 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER);
282 /* we need to ensure the heads are not tied henceforth, or reading any
283 * 8 bit reg on head B will fail
284 * setting a single arbitrary head solves that */
288 static void nv4GetConfig (NVPtr pNv)
290 uint32_t reg_FB0 = nvReadFB(pNv, NV_PFB_BOOT_0);
292 if (reg_FB0 & 0x00000100)
293 pNv->RamAmountKBytes = ((reg_FB0 >> 12) & 0x0F) * 1024 * 2 + 1024 * 2;
295 switch (reg_FB0 & 0x00000003) {
297 pNv->RamAmountKBytes = 1024 * 32;
300 pNv->RamAmountKBytes = 1024 * 4;
303 pNv->RamAmountKBytes = 1024 * 8;
307 pNv->RamAmountKBytes = 1024 * 16;
311 pNv->CrystalFreqKHz = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x00000040) ? 14318 : 13500;
312 pNv->CURSOR = &(pNv->PRAMIN[0x5E00]);
313 pNv->MinVClockFreqKHz = 12000;
314 pNv->MaxVClockFreqKHz = 350000;
317 static void nForce_check_dimms(ScrnInfoPtr pScrn)
319 uint16_t mem_ctrlr_pciid = PCI_SLOT_READ_LONG(3, 0x00) >> 16;
321 if ((mem_ctrlr_pciid == 0x1a9) || (mem_ctrlr_pciid == 0x1ab) || (mem_ctrlr_pciid == 0x1ed)) {
324 dimm[0] = (PCI_SLOT_READ_LONG(2, 0x40) >> 8) & 0x4f;
325 dimm[1] = (PCI_SLOT_READ_LONG(2, 0x44) >> 8) & 0x4f;
326 dimm[2] = (PCI_SLOT_READ_LONG(2, 0x48) >> 8) & 0x4f;
328 if (dimm[0] + dimm[1] != dimm[2])
329 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
330 "Your nForce DIMMs are not arranged in optimal banks!\n");
334 static void nv10GetConfig(ScrnInfoPtr pScrn)
336 NVPtr pNv = NVPTR(pScrn);
337 uint32_t implementation = pNv->Chipset & 0x0ff0;
339 #if X_BYTE_ORDER == X_BIG_ENDIAN
340 if (!(nvReadMC(pNv, 0x0004) & 0x01000001))
341 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
342 "Card is in big endian mode, something is very wrong !\n");
345 if (implementation == CHIPSET_NFORCE) {
346 pNv->RamAmountKBytes = (((PCI_SLOT_READ_LONG(1, 0x7c) >> 6) & 31) + 1) * 1024;
347 nForce_check_dimms(pScrn);
348 } else if (implementation == CHIPSET_NFORCE2) {
349 pNv->RamAmountKBytes = (((PCI_SLOT_READ_LONG(1, 0x84) >> 4) & 127) + 1) * 1024;
350 nForce_check_dimms(pScrn);
352 pNv->RamAmountKBytes = (nvReadFB(pNv, NV_PFB_CSTATUS) & 0xFFF00000) >> 10;
354 if (pNv->RamAmountKBytes > 256*1024)
355 pNv->RamAmountKBytes = 256*1024;
357 pNv->CrystalFreqKHz = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & (1 << 6)) ? 14318 : 13500;
358 if (pNv->twoHeads && implementation != CHIPSET_NV11)
359 if (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & (1 << 22))
360 pNv->CrystalFreqKHz = 27000;
362 pNv->CURSOR = NULL; /* can't set this here */
363 pNv->MinVClockFreqKHz = 12000;
364 pNv->MaxVClockFreqKHz = pNv->twoStagePLL ? 400000 : 350000;
368 NVCommonSetup(ScrnInfoPtr pScrn)
370 NVPtr pNv = NVPTR(pScrn);
371 vgaHWPtr pVga = VGAHWPTR(pScrn);
372 uint16_t implementation = pNv->Chipset & 0x0ff0;
375 xf86MonPtr monitorA, monitorB;
376 int FlatPanel = -1; /* really means the CRTC is slaved */
377 bool Television = false;
380 * Override VGA I/O routines.
382 pVga->writeCrtc = NVWriteCrtc;
383 pVga->readCrtc = NVReadCrtc;
384 pVga->writeGr = NVWriteGr;
385 pVga->readGr = NVReadGr;
386 pVga->writeAttr = NVWriteAttr;
387 pVga->readAttr = NVReadAttr;
388 pVga->writeSeq = NVWriteSeq;
389 pVga->readSeq = NVReadSeq;
390 pVga->writeMiscOut = NVWriteMiscOut;
391 pVga->readMiscOut = NVReadMiscOut;
392 pVga->enablePalette = NVEnablePalette;
393 pVga->disablePalette = NVDisablePalette;
394 pVga->writeDacMask = NVWriteDacMask;
395 pVga->readDacMask = NVReadDacMask;
396 pVga->writeDacWriteAddr = NVWriteDacWriteAddr;
397 pVga->writeDacReadAddr = NVWriteDacReadAddr;
398 pVga->writeDacData = NVWriteDacData;
399 pVga->readDacData = NVReadDacData;
401 * Note: There are different pointers to the CRTC/AR and GR/SEQ registers.
402 * Bastardize the intended uses of these to make it work.
404 pVga->MMIOBase = (CARD8 *)pNv;
405 pVga->MMIOOffset = 0;
407 #ifndef XSERVER_LIBPCIACCESS
408 pNv->REGS = xf86MapPciMem(pScrn->scrnIndex,
409 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
410 pNv->PciTag, pNv->IOAddress, 0x01000000);
411 pNv->FB_BAR = xf86MapPciMem(pScrn->scrnIndex,
412 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
413 pNv->PciTag, pNv->VRAMPhysical, 0x10000);
415 /* 0x01000000 is the size */
416 pci_device_map_range(pNv->PciInfo, pNv->IOAddress, 0x01000000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->REGS);
417 pci_device_map_range(pNv->PciInfo, pNv->VRAMPhysical, 0x10000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->FB_BAR);
418 #endif /* XSERVER_LIBPCIACCESS */
420 pNv->PRAMIN = pNv->REGS + (NV_PRAMIN_OFFSET/4);
421 pNv->PGRAPH = pNv->REGS + (NV_PGRAPH_OFFSET/4);
423 /* 8 bit registers */
424 pNv->PCIO0 = (uint8_t *)pNv->REGS + NV_PRMCIO0_OFFSET;
425 pNv->PDIO0 = (uint8_t *)pNv->REGS + NV_PRMDIO0_OFFSET;
426 pNv->PVIO0 = (uint8_t *)pNv->REGS + NV_PRMVIO0_OFFSET;
427 pNv->PCIO1 = pNv->PCIO0 + NV_PRMCIO_SIZE;
428 pNv->PDIO1 = pNv->PDIO0 + NV_PRMDIO_SIZE;
429 pNv->PVIO1 = pNv->PVIO0 + NV_PRMVIO_SIZE;
431 pNv->alphaCursor = (pNv->NVArch >= 0x11);
433 pNv->twoHeads = (pNv->Architecture >= NV_ARCH_10) &&
434 (implementation != CHIPSET_NV10) &&
435 (implementation != CHIPSET_NV15) &&
436 (implementation != CHIPSET_NFORCE) &&
437 (implementation != CHIPSET_NV20);
439 pNv->fpScaler = (pNv->FpScale && pNv->twoHeads && implementation != CHIPSET_NV11);
441 /* nv30 and nv35 have two stage PLLs, but use only one register; they are dealt with separately */
442 pNv->twoStagePLL = (implementation == CHIPSET_NV31) ||
443 (implementation == CHIPSET_NV36) ||
444 (pNv->Architecture >= NV_ARCH_40);
446 pNv->WaitVSyncPossible = (pNv->Architecture >= NV_ARCH_10) &&
447 (implementation != CHIPSET_NV10);
449 pNv->BlendingPossible = ((pNv->Chipset & 0xffff) > CHIPSET_NV04);
451 /* look for known laptop chips */
452 /* FIXME still probably missing some ids (for randr12, pre-nv40 mobile should be auto-detected) */
453 switch(pNv->Chipset & 0xffff) {
521 pNv->Television = FALSE;
524 store_initial_head_owner(pScrn);
526 /* Parse the bios to initialize the card */
529 if (pNv->Architecture == NV_ARCH_04)
532 nv10GetConfig(pScrn);
534 if (!pNv->randr12_enable) {
536 NVSelectHeadRegisters(pScrn, 0);
538 NVLockUnlock(pScrn, 0);
544 pNv->crtc_active[0] = TRUE;
545 pNv->crtc_active[1] = FALSE;
546 if((monitorA = NVProbeDDC(pScrn, 0))) {
547 FlatPanel = monitorA->features.input_type ? 1 : 0;
549 /* NV4 doesn't support FlatPanels */
550 if((pNv->Chipset & 0x0fff) <= CHIPSET_NV04)
553 if(nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX) & 0x80) {
554 if(!(nvReadCurVGA(pNv, NV_CIO_CRE_LCD__INDEX) & 0x01))
560 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
561 "HW is currently programmed for %s\n",
562 FlatPanel ? (Television ? "TV" : "DFP") : "CRT");
565 if(pNv->FlatPanel == -1) {
566 pNv->FlatPanel = FlatPanel;
567 pNv->Television = Television;
569 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
570 "Forcing display type to %s as specified\n",
571 pNv->FlatPanel ? "DFP" : "CRT");
574 CARD8 outputAfromCRTC, outputBfromCRTC;
575 pNv->crtc_active[0] = FALSE;
576 pNv->crtc_active[1] = FALSE;
577 CARD8 slaved_on_A, slaved_on_B;
578 Bool analog_on_A, analog_on_B;
582 if(implementation != CHIPSET_NV11) {
583 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT) & 0x100)
587 if(NVReadRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT) & 0x100)
591 analog_on_A = NVIsConnected(pScrn, 0);
592 analog_on_B = NVIsConnected(pScrn, 1);
602 nvWriteCurVGA(pNv, NV_CIO_CRE_44, 3);
603 NVSelectHeadRegisters(pScrn, 1);
604 NVLockUnlock(pScrn, 0);
606 slaved_on_B = nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
608 tvB = !(nvReadCurVGA(pNv, NV_CIO_CRE_LCD__INDEX) & 0x01);
611 nvWriteCurVGA(pNv, NV_CIO_CRE_44, 0);
612 NVSelectHeadRegisters(pScrn, 0);
613 NVLockUnlock(pScrn, 0);
615 slaved_on_A = nvReadCurVGA(pNv, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
617 tvA = !(nvReadCurVGA(pNv, NV_CIO_CRE_LCD__INDEX) & 0x01);
620 oldhead = NVReadCRTC(pNv, 0, NV_CRTC_FSEL);
621 NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead | 0x00000010);
623 monitorA = NVProbeDDC(pScrn, 0);
624 monitorB = NVProbeDDC(pScrn, 1);
626 if(slaved_on_A && !tvA) {
627 pNv->crtc_active[0] = TRUE;
629 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
630 "CRTC 0 is currently programmed for DFP\n");
632 if(slaved_on_B && !tvB) {
633 pNv->crtc_active[1] = TRUE;
635 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
636 "CRTC 1 is currently programmed for DFP\n");
639 pNv->crtc_active[outputAfromCRTC] = TRUE;
641 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
642 "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
645 pNv->crtc_active[outputBfromCRTC] = TRUE;
647 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
648 "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
651 pNv->crtc_active[0] = TRUE;
654 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
655 "CRTC 0 is currently programmed for TV\n");
658 pNv->crtc_active[1] = TRUE;
661 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
662 "CRTC 1 is currently programmed for TV\n");
665 FlatPanel = monitorA->features.input_type ? 1 : 0;
668 FlatPanel = monitorB->features.input_type ? 1 : 0;
671 if(pNv->FlatPanel == -1) {
672 if(FlatPanel != -1) {
673 pNv->FlatPanel = FlatPanel;
674 pNv->Television = Television;
676 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
677 "Unable to detect display type...\n");
679 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
680 "...On a laptop, assuming DFP\n");
683 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
684 "...Using default of CRT\n");
689 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
690 "Forcing display type to %s as specified\n",
691 pNv->FlatPanel ? "DFP" : "CRT");
694 if(!(pNv->crtc_active[0]) && !(pNv->crtc_active[1])) {
695 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
696 "Unable to detect which CRTC is used...\n");
698 pNv->crtc_active[1] = TRUE;
700 pNv->crtc_active[0] = TRUE;
702 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
703 "...Defaulting to CRTCNumber %i\n", pNv->crtc_active[1]);
707 if((monitorA->features.input_type && pNv->FlatPanel) ||
708 (!monitorA->features.input_type && !pNv->FlatPanel))
721 if((monitorB->features.input_type && !pNv->FlatPanel) ||
722 (!monitorB->features.input_type && pNv->FlatPanel))
731 if(implementation == CHIPSET_NV11)
732 cr44 = pNv->crtc_active[1] * 0x3;
734 NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead);
736 nvWriteCurVGA(pNv, NV_CIO_CRE_44, cr44);
737 NVSelectHeadRegisters(pScrn, pNv->crtc_active[1]);
740 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
741 "Using %s on CRTC %i\n",
742 pNv->FlatPanel ? (pNv->Television ? "TV" : "DFP") : "CRT",
743 pNv->crtc_active[1]);
745 if(pNv->FlatPanel && !pNv->Television) {
746 pNv->fpWidth = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HDISP_END) + 1;
747 pNv->fpHeight = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_VDISP_END) + 1;
748 pNv->fpSyncs = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0x30000033;
749 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
750 pNv->fpWidth, pNv->fpHeight);
754 xf86SetDDCproperties(pScrn, monitorA);
756 if(!pNv->FlatPanel || (pScrn->depth != 24) || !pNv->twoHeads)
757 pNv->FPDither = FALSE;
760 if(pNv->FlatPanel && pNv->twoHeads) {
761 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_FP_TMDS_CONTROL, 0x00010004);
762 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_FP_TMDS_DATA) & 1)
764 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel is %s\n",
765 pNv->LVDS ? "LVDS" : "TMDS");