require libnouveau_drm 0.0.109.1
[nouveau] / src / nv_setup.c
1 /*
2  * Copyright 2003 NVIDIA, Corporation
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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
20  * SOFTWARE.
21  */
22
23 #include "nv_include.h"
24 #include "nvreg.h"
25
26 /*
27  * Override VGA I/O routines.
28  */
29 static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value)
30 {
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);
35 }
36 static CARD8 NVReadCrtc(vgaHWPtr pVga, CARD8 index)
37 {
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));
42 }
43 static void NVWriteGr(vgaHWPtr pVga, CARD8 index, CARD8 value)
44 {
45     NVPtr pNv = (NVPtr)pVga->MMIOBase;
46     VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
47     VGA_WR08(pNv->PVIO0, VGA_GRAPH_DATA,  value);
48 }
49 static CARD8 NVReadGr(vgaHWPtr pVga, CARD8 index)
50 {
51     NVPtr pNv = (NVPtr)pVga->MMIOBase;
52     VGA_WR08(pNv->PVIO0, VGA_GRAPH_INDEX, index);
53     return (VGA_RD08(pNv->PVIO0, VGA_GRAPH_DATA));
54 }
55 static void NVWriteSeq(vgaHWPtr pVga, CARD8 index, CARD8 value)
56 {
57     NVPtr pNv = (NVPtr)pVga->MMIOBase;
58     VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
59     VGA_WR08(pNv->PVIO0, VGA_SEQ_DATA,  value);
60 }
61 static CARD8 NVReadSeq(vgaHWPtr pVga, CARD8 index)
62 {
63     NVPtr pNv = (NVPtr)pVga->MMIOBase;
64     VGA_WR08(pNv->PVIO0, VGA_SEQ_INDEX, index);
65     return (VGA_RD08(pNv->PVIO0, VGA_SEQ_DATA));
66 }
67 static void NVWriteAttr(vgaHWPtr pVga, CARD8 index, CARD8 value)
68 {
69     NVPtr pNv = (NVPtr)pVga->MMIOBase;
70     volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
71     volatile CARD8 tmp;
72
73     tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
74     if (pVga->paletteEnabled)
75         index &= ~0x20;
76     else
77         index |= 0x20;
78     VGA_WR08(ptr, VGA_ATTR_INDEX,  index);
79     VGA_WR08(ptr, VGA_ATTR_DATA_W, value);
80 }
81 static CARD8 NVReadAttr(vgaHWPtr pVga, CARD8 index)
82 {
83     NVPtr pNv = (NVPtr)pVga->MMIOBase;
84     volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
85     volatile CARD8 tmp;
86
87     tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
88     if (pVga->paletteEnabled)
89         index &= ~0x20;
90     else
91         index |= 0x20;
92     VGA_WR08(ptr, VGA_ATTR_INDEX, index);
93     return (VGA_RD08(ptr, VGA_ATTR_DATA_R));
94 }
95 static void NVWriteMiscOut(vgaHWPtr pVga, CARD8 value)
96 {
97     NVPtr pNv = (NVPtr)pVga->MMIOBase;
98     VGA_WR08(pNv->PVIO0, VGA_MISC_OUT_W, value);
99 }
100 static CARD8 NVReadMiscOut(vgaHWPtr pVga)
101 {
102     NVPtr pNv = (NVPtr)pVga->MMIOBase;
103     return (VGA_RD08(pNv->PVIO0, VGA_MISC_OUT_R));
104 }
105 static void NVEnablePalette(vgaHWPtr pVga)
106 {
107     NVPtr pNv = (NVPtr)pVga->MMIOBase;
108     volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
109     volatile CARD8 tmp;
110
111     tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
112     VGA_WR08(ptr, VGA_ATTR_INDEX, 0x00);
113     pVga->paletteEnabled = TRUE;
114 }
115 static void NVDisablePalette(vgaHWPtr pVga)
116 {
117     NVPtr pNv = (NVPtr)pVga->MMIOBase;
118     volatile CARD8 *ptr = pNv->cur_head ? pNv->PCIO1 : pNv->PCIO0;
119     volatile CARD8 tmp;
120
121     tmp = VGA_RD08(ptr, pVga->IOBase + VGA_IN_STAT_1_OFFSET);
122     VGA_WR08(ptr, VGA_ATTR_INDEX, 0x20);
123     pVga->paletteEnabled = FALSE;
124 }
125 static void NVWriteDacMask(vgaHWPtr pVga, CARD8 value)
126 {
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);
130 }
131 static CARD8 NVReadDacMask(vgaHWPtr pVga)
132 {
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));
136 }
137 static void NVWriteDacReadAddr(vgaHWPtr pVga, CARD8 value)
138 {
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);
142 }
143 static void NVWriteDacWriteAddr(vgaHWPtr pVga, CARD8 value)
144 {
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);
148 }
149 static void NVWriteDacData(vgaHWPtr pVga, CARD8 value)
150 {
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);
154 }
155 static CARD8 NVReadDacData(vgaHWPtr pVga)
156 {
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));
160 }
161
162 static Bool 
163 NVIsConnected (ScrnInfoPtr pScrn, int output)
164 {
165     NVPtr pNv = NVPTR(pScrn);
166     CARD32 reg52C, reg608, temp;
167     Bool present;
168
169     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
170                "Probing for analog device on output %s...\n", 
171                 output ? "B" : "A");
172
173     reg52C = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
174     reg608 = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
175
176     NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, (reg608 & ~0x00010000));
177
178     NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, (reg52C & 0x0000FEEE));
179     usleep(1000);
180     
181     temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_OUTPUT);
182     NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, temp | 1);
183
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);
187
188     usleep(1000);
189
190     present = (NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
191
192     if(present)
193        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ...found one\n");
194     else
195        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ...can't find one\n");
196
197     temp = NVReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL);
198     NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
199
200     NVWriteRAMDAC(pNv, output, NV_RAMDAC_OUTPUT, reg52C);
201     NVWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, reg608);
202
203     return present;
204 }
205
206 static void
207 NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head)
208 {
209     NVPtr pNv = NVPTR(pScrn);
210
211     pNv->cur_head = head;
212 }
213
214 static xf86MonPtr 
215 NVProbeDDC (ScrnInfoPtr pScrn, int bus)
216 {
217     NVPtr pNv = NVPTR(pScrn);
218     xf86MonPtr MonInfo = NULL;
219
220     if(!pNv->I2C) return NULL;
221
222     pNv->DDCBase = bus ? 0x36 : 0x3e;
223
224     xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
225                "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A");
226
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 ?
230                   "DFP" : "CRT");
231        xf86PrintEDID( MonInfo );
232     } else {
233        xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
234                   "  ... none found\n");
235     }
236
237     return MonInfo;
238 }
239
240 static void nv4GetConfig (NVPtr pNv)
241 {
242         uint32_t reg_FB0 = nvReadFB(pNv, NV_PFB_BOOT_0);
243
244         if (reg_FB0 & 0x00000100)
245                 pNv->RamAmountKBytes = ((reg_FB0 >> 12) & 0x0F) * 1024 * 2 + 1024 * 2;
246         else
247                 switch (reg_FB0 & 0x00000003) {
248                 case 0:
249                         pNv->RamAmountKBytes = 1024 * 32;
250                         break;
251                 case 1:
252                         pNv->RamAmountKBytes = 1024 * 4;
253                         break;
254                 case 2:
255                         pNv->RamAmountKBytes = 1024 * 8;
256                         break;
257                 case 3:
258                 default:
259                         pNv->RamAmountKBytes = 1024 * 16;
260                         break;
261                 }
262
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;
267 }
268
269 static void nv10GetConfig (NVPtr pNv)
270 {
271         uint32_t implementation = pNv->Chipset & 0x0ff0;
272
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");
276 #endif
277
278         if (implementation == CHIPSET_NFORCE) {
279                 uint32_t amt;
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);
286 #else
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) {
291                 uint32_t amt; 
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);
298 #else
299                 amt = pciReadLong(pciTag(0, 0, 1), 0x84);
300 #endif /* XSERVER_LIBPCIACCESS */
301                 pNv->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
302         } else
303                 pNv->RamAmountKBytes = (nvReadFB(pNv, NV_PFB_020C) & 0xFFF00000) >> 10;
304
305         if (pNv->RamAmountKBytes > 256*1024)
306                 pNv->RamAmountKBytes = 256*1024;
307
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;
312
313         pNv->CURSOR           = NULL;  /* can't set this here */
314         pNv->MinVClockFreqKHz = 12000;
315         pNv->MaxVClockFreqKHz = pNv->twoStagePLL ? 400000 : 350000;
316 }
317
318 void
319 NVCommonSetup(ScrnInfoPtr pScrn)
320 {
321         NVPtr pNv = NVPTR(pScrn);
322         vgaHWPtr pVga = VGAHWPTR(pScrn);
323         uint16_t implementation = pNv->Chipset & 0x0ff0;
324         bool tvA = false;
325         bool tvB = false;
326         xf86MonPtr monitorA, monitorB;
327         int FlatPanel = -1;   /* really means the CRTC is slaved */
328         bool Television = false;
329  
330     /*
331      * Override VGA I/O routines.
332      */
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;
351     /*
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.
354      */
355     pVga->MMIOBase   = (CARD8 *)pNv;
356     pVga->MMIOOffset = 0;
357
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);
365 #else
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 */
370
371         pNv->PRAMIN   = pNv->REGS + (NV_PRAMIN_OFFSET/4);
372         pNv->PGRAPH   = pNv->REGS + (NV_PGRAPH_OFFSET/4);
373
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;
381
382         pNv->alphaCursor = (pNv->NVArch >= 0x11);
383
384         pNv->twoHeads = (pNv->Architecture >= NV_ARCH_10) &&
385                         (implementation != CHIPSET_NV10) &&
386                         (implementation != CHIPSET_NV15) &&
387                         (implementation != CHIPSET_NFORCE) &&
388                         (implementation != CHIPSET_NV20);
389
390         pNv->fpScaler = (pNv->FpScale && pNv->twoHeads && implementation != CHIPSET_NV11);
391
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);
396
397         pNv->WaitVSyncPossible = (pNv->Architecture >= NV_ARCH_10) &&
398                                  (implementation != CHIPSET_NV10);
399
400         pNv->BlendingPossible = ((pNv->Chipset & 0xffff) > CHIPSET_NV04);
401
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) {
405     case 0x0098:
406     case 0x0099:
407     case 0x00C8:
408     case 0x00C9:
409     case 0x00CC:
410     case 0x0112:
411     case 0x0144:
412     case 0x0146:
413     case 0x0148:
414     case 0x0149:
415     case 0x0160:
416     case 0x0164:
417     case 0x0166:
418     case 0x0167:
419     case 0x0168:
420     case 0x0169:
421     case 0x016B:
422     case 0x016C:
423     case 0x016D:
424     case 0x0174:
425     case 0x0175:
426     case 0x0176:
427     case 0x0177:
428     case 0x0179:
429     case 0x017C:
430     case 0x017D:
431     case 0x0186:
432     case 0x0187:
433     case 0x018D:
434     case 0x01D6:
435     case 0x01D7:
436     case 0x01D8:
437     case 0x0228:
438     case 0x0244:
439     case 0x0286:
440     case 0x028C:
441     case 0x0297:
442     case 0x0298:
443     case 0x0299:
444     case 0x0316:
445     case 0x0317:
446     case 0x031A:
447     case 0x031B:
448     case 0x031C:
449     case 0x031D:
450     case 0x031E:
451     case 0x031F:
452     case 0x0324:
453     case 0x0325:
454     case 0x0328:
455     case 0x0329:
456     case 0x032C:
457     case 0x032D:
458     case 0x0347:
459     case 0x0348:
460     case 0x0349:
461     case 0x034B:
462     case 0x034C:
463     case 0x0397:
464     case 0x0398:
465     case 0x039B:
466         pNv->Mobile = TRUE;
467         break;
468     default:
469         break;
470     }
471
472         pNv->Television = FALSE;
473
474         if (pNv->twoHeads) {
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 */
478                                 pNv->vtOWNER = 0x04;
479                         else {
480                                 uint8_t slaved_on_A, slaved_on_B;
481
482                                 NVSetOwner(pScrn, 1);
483                                 NVLockVgaCrtc(pNv, 1, false);
484
485                                 slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_PIXEL) & 0x80;
486                                 if (slaved_on_B)
487                                         tvB = !(NVReadVgaCrtc(pNv, 1, NV_VGA_CRTCX_LCD) & 0x01);
488
489                                 NVSetOwner(pScrn, 0);
490                                 NVLockVgaCrtc(pNv, 0, false);
491
492                                 slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_PIXEL) & 0x80;
493                                 if (slaved_on_A)
494                                         tvA = !(NVReadVgaCrtc(pNv, 0, NV_VGA_CRTCX_LCD) & 0x01);
495
496                                 if (slaved_on_A && !tvA)
497                                         pNv->vtOWNER = 0x0;
498                                 else if (slaved_on_B && !tvB)
499                                         pNv->vtOWNER = 0x3;
500                                 else if (slaved_on_A)
501                                         pNv->vtOWNER = 0x0;
502                                 else if (slaved_on_B)
503                                         pNv->vtOWNER = 0x3;
504                                 else
505                                         pNv->vtOWNER = 0x0;
506                         }
507                 }
508
509                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER);
510         }
511
512         /* Parse the bios to initialize the card */
513         NVParseBios(pScrn);
514
515         if (pNv->Architecture == NV_ARCH_04)
516                 nv4GetConfig(pNv);
517         else
518                 nv10GetConfig(pNv);
519
520     if (!pNv->randr12_enable) {
521       
522         NVSelectHeadRegisters(pScrn, 0);
523         
524         NVLockUnlock(pScrn, 0);
525         
526         NVI2CInit(pScrn);
527         
528         
529         if(!pNv->twoHeads) {
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;
534                 
535                 /* NV4 doesn't support FlatPanels */
536                 if((pNv->Chipset & 0x0fff) <= CHIPSET_NV04)
537                     FlatPanel = 0;
538             } else {
539                 if(nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
540                     if(!(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01)) 
541                         Television = TRUE;
542                     FlatPanel = 1;
543                 } else {
544                     FlatPanel = 0;
545                 }
546                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
547                            "HW is currently programmed for %s\n",
548                            FlatPanel ? (Television ? "TV" : "DFP") : "CRT");
549             } 
550             
551             if(pNv->FlatPanel == -1) {
552                 pNv->FlatPanel = FlatPanel;
553                 pNv->Television = Television;
554             } else {
555                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
556                            "Forcing display type to %s as specified\n", 
557                            pNv->FlatPanel ? "DFP" : "CRT");
558             }
559         } else {
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;
565             CARD32 oldhead;
566             CARD8 cr44;
567             
568             if(implementation != CHIPSET_NV11) {
569                 if(NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT) & 0x100)
570                     outputAfromCRTC = 1;
571                 else            
572                     outputAfromCRTC = 0;
573                 if(NVReadRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT) & 0x100)
574                     outputBfromCRTC = 1;
575                 else
576                     outputBfromCRTC = 0;
577                 analog_on_A = NVIsConnected(pScrn, 0);
578                 analog_on_B = NVIsConnected(pScrn, 1);
579             } else {
580                 outputAfromCRTC = 0;
581                 outputBfromCRTC = 1;
582                 analog_on_A = FALSE;
583                 analog_on_B = FALSE;
584             }
585             
586             cr44 = pNv->vtOWNER;
587             
588             nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 3);
589             NVSelectHeadRegisters(pScrn, 1);
590             NVLockUnlock(pScrn, 0);
591             
592             slaved_on_B = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80;
593             if(slaved_on_B) {
594                 tvB = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01);
595             }
596             
597             nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, 0);
598             NVSelectHeadRegisters(pScrn, 0);
599             NVLockUnlock(pScrn, 0);
600             
601             slaved_on_A = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL) & 0x80; 
602             if(slaved_on_A) {
603                 tvA = !(nvReadCurVGA(pNv, NV_VGA_CRTCX_LCD) & 0x01);
604             }
605             
606             oldhead = NVReadCRTC(pNv, 0, NV_CRTC_FSEL);
607             NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, oldhead | 0x00000010);
608             
609             monitorA = NVProbeDDC(pScrn, 0);
610             monitorB = NVProbeDDC(pScrn, 1);
611             
612             if(slaved_on_A && !tvA) {
613                 pNv->crtc_active[0] = TRUE;
614                 FlatPanel = 1;
615                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
616                            "CRTC 0 is currently programmed for DFP\n");
617             } else 
618                 if(slaved_on_B && !tvB) {
619                     pNv->crtc_active[1] = TRUE;
620                     FlatPanel = 1;
621                     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
622                                "CRTC 1 is currently programmed for DFP\n");
623                 } else
624                     if(analog_on_A) {
625                         pNv->crtc_active[outputAfromCRTC] = TRUE;
626                         FlatPanel = 0;
627                         xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
628                                    "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
629                     } else
630                         if(analog_on_B) {
631                             pNv->crtc_active[outputBfromCRTC] = TRUE;
632                             FlatPanel = 0;
633                             xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
634                                        "CRTC %i appears to have a CRT attached\n", pNv->crtc_active[1]);
635                         } else
636                             if(slaved_on_A) {
637                                 pNv->crtc_active[0] = TRUE;
638                                 FlatPanel = 1;
639                                 Television = 1;
640                                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
641                                            "CRTC 0 is currently programmed for TV\n");
642                             } else
643                                 if(slaved_on_B) {
644                                     pNv->crtc_active[1] = TRUE;
645                                     FlatPanel = 1;
646                                     Television = 1;
647                                     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
648                                                "CRTC 1 is currently programmed for TV\n");
649                                 } else
650                                     if(monitorA) {
651                                         FlatPanel = monitorA->features.input_type ? 1 : 0;
652                                     } else 
653                                         if(monitorB) {
654                                             FlatPanel = monitorB->features.input_type ? 1 : 0;
655                                         }
656             
657             if(pNv->FlatPanel == -1) {
658                 if(FlatPanel != -1) {
659                     pNv->FlatPanel = FlatPanel;
660                     pNv->Television = Television;
661                 } else {
662                     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
663                                "Unable to detect display type...\n");
664                     if(pNv->Mobile) {
665                         xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
666                                    "...On a laptop, assuming DFP\n");
667                         pNv->FlatPanel = 1;
668                     } else {
669                         xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
670                                    "...Using default of CRT\n");
671                         pNv->FlatPanel = 0;
672                     }
673                 }
674             } else {
675                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
676                            "Forcing display type to %s as specified\n", 
677                            pNv->FlatPanel ? "DFP" : "CRT");
678             }
679             
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");
683                         if(pNv->FlatPanel) {
684                                 pNv->crtc_active[1] = TRUE;
685                         } else {
686                                 pNv->crtc_active[0] = TRUE;
687                         }
688                         xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
689                         "...Defaulting to CRTCNumber %i\n", pNv->crtc_active[1]);
690                 }
691
692             if(monitorA) {
693                 if((monitorA->features.input_type && pNv->FlatPanel) ||
694                    (!monitorA->features.input_type && !pNv->FlatPanel))
695                 {
696                     if(monitorB) { 
697                         xfree(monitorB);
698                         monitorB = NULL;
699                     }
700                 } else {
701                     xfree(monitorA);
702                     monitorA = NULL;
703                 }
704             }
705             
706             if(monitorB) {
707                 if((monitorB->features.input_type && !pNv->FlatPanel) ||
708                    (!monitorB->features.input_type && pNv->FlatPanel)) 
709                 {
710                     xfree(monitorB);
711                 } else {
712                     monitorA = monitorB;
713                 }
714                 monitorB = NULL;
715             }
716             
717             if(implementation == CHIPSET_NV11)
718                 cr44 = pNv->crtc_active[1] * 0x3;
719             
720             NVWriteCRTC(pNv, 0, NV_CRTC_FSEL,  oldhead);
721
722             nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, cr44);
723             NVSelectHeadRegisters(pScrn, pNv->crtc_active[1]);
724         }
725         
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]);
730         
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);
737         }
738         
739         if(monitorA)
740             xf86SetDDCproperties(pScrn, monitorA);
741
742         if(!pNv->FlatPanel || (pScrn->depth != 24) || !pNv->twoHeads)
743             pNv->FPDither = FALSE;
744         
745         pNv->LVDS = 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)
749                 pNv->LVDS = TRUE;
750             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel is %s\n", 
751                        pNv->LVDS ? "LVDS" : "TMDS");
752         }
753     }
754 }
755