randr12: Optimize tmds_regs a little bit.
[nouveau] / src / nv_output.c
1 /*
2  * Copyright 2006 Dave Airlie
3  * Copyright 2007 Maarten Maathuis
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 /*
25  * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
26  * decleration is at the bottom of this file as it is rather ugly 
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "xf86.h"
34 #include "os.h"
35 #include "mibank.h"
36 #include "globals.h"
37 #include "xf86.h"
38 #include "xf86Priv.h"
39 #include "xf86DDC.h"
40 #include "mipointer.h"
41 #include "windowstr.h"
42 #include <randrstr.h>
43 #include <X11/extensions/render.h>
44
45 #include "xf86Crtc.h"
46 #include "nv_include.h"
47
48 const char *OutputType[] = {
49     "None",
50     "VGA",
51     "DVI",
52     "LVDS",
53     "S-video",
54     "Composite",
55 };
56
57 const char *MonTypeName[7] = {
58     "AUTO",
59     "NONE",
60     "CRT",
61     "LVDS",
62     "TMDS",
63     "CTV",
64     "STV"
65 };
66
67 /* 
68  * TMDS registers are indirect 8 bit registers.
69  * Reading is straightforward, writing a bit odd.
70  * Reading: Write adress (+write protect bit, do not forget this), then read value.
71  * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
72  */
73
74 void NVWriteTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
75 {
76         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
77                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
78
79         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
80
81         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
82         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
83                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
84 }
85
86 CARD8 NVReadTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg)
87 {
88         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
89                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
90
91         return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
92 }
93
94 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
95 {
96         NVOutputPrivatePtr nv_output = output->driver_private;
97         ScrnInfoPtr     pScrn = output->scrn;
98         NVPtr pNv = NVPTR(pScrn);
99         int ramdac;
100
101         /* Is TMDS programmed on a different output? */
102         /* Always choose the prefered ramdac, since that one contains the tmds stuff */
103         /* Assumption: there is always once output that can only run of the primary ramdac */
104         if (nv_output->valid_ramdac & RAMDAC_1) {
105                 ramdac = 1;
106         } else {
107                 ramdac = 0;
108         }
109
110         NVWriteTMDS(pNv, ramdac, tmds_reg, val);
111 }
112
113 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
114 {
115         NVOutputPrivatePtr nv_output = output->driver_private;
116         ScrnInfoPtr     pScrn = output->scrn;
117         NVPtr pNv = NVPTR(pScrn);
118         int ramdac;
119
120         /* Is TMDS programmed on a different output? */
121         /* Always choose the prefered ramdac, since that one contains the tmds stuff */
122         /* Assumption: there is always once output that can only run of the primary ramdac */
123         if (nv_output->valid_ramdac & RAMDAC_1) {
124                 ramdac = 1;
125         } else {
126                 ramdac = 0;
127         }
128
129         return NVReadTMDS(pNv, ramdac, tmds_reg);
130 }
131
132 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
133 {
134     NVOutputPrivatePtr nv_output = output->driver_private;
135     ScrnInfoPtr pScrn = output->scrn;
136     NVPtr pNv = NVPTR(pScrn);
137
138     nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
139 }
140
141 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
142 {
143     NVOutputPrivatePtr nv_output = output->driver_private;
144     ScrnInfoPtr pScrn = output->scrn;
145     NVPtr pNv = NVPTR(pScrn);
146
147     return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
148 }
149
150 static void nv_output_backlight_enable(xf86OutputPtr output,  Bool on)
151 {
152         ScrnInfoPtr pScrn = output->scrn;
153         NVPtr pNv = NVPTR(pScrn);
154
155         ErrorF("nv_output_backlight_enable is called for output %s to turn %s\n", output->name, on ? "on" : "off");
156
157         /* This is done differently on each laptop.  Here we
158          * define the ones we know for sure. */
159
160 #if defined(__powerpc__)
161         if ((pNv->Chipset == 0x10DE0179) ||
162             (pNv->Chipset == 0x10DE0189) ||
163             (pNv->Chipset == 0x10DE0329)) {
164                 /* NV17,18,34 Apple iMac, iBook, PowerBook */
165                 CARD32 tmp_pmc, tmp_pcrt;
166                 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
167                 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
168                 if (on) {
169                         tmp_pmc |= (1 << 31);
170                         tmp_pcrt |= 0x1;
171                 }
172                 nvWriteMC(pNv, 0x10F0, tmp_pmc);
173                 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
174         }
175 #endif
176
177         if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
178                 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
179 }
180
181 static void
182 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
183 {
184         NVOutputPrivatePtr nv_output = output->driver_private;
185         NVPtr pNv = NVPTR(output->scrn);
186
187         if (nv_output->ramdac != -1 && mode != DPMSModeOff) {
188                 /* This was not a modeset, but a normal dpms call */
189                 pNv->ramdac_active[nv_output->ramdac] = TRUE;
190                 ErrorF("Activating ramdac %d\n", nv_output->ramdac);
191                 nv_output->ramdac_assigned = TRUE;
192         }
193
194         switch (mode) {
195         case DPMSModeStandby:
196         case DPMSModeSuspend:
197         case DPMSModeOff:
198                 nv_output_backlight_enable(output, 0);
199                 break;
200         case DPMSModeOn:
201                 nv_output_backlight_enable(output, 1);
202         default:
203                 break;
204         }
205
206         /* We may be going for modesetting, so we must reset the ramdacs */
207         if (nv_output->ramdac != -1 && mode == DPMSModeOff) {
208                 pNv->ramdac_active[nv_output->ramdac] = FALSE;
209                 ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
210                 nv_output->ramdac_assigned = FALSE;
211         }
212 }
213
214 static void
215 nv_analog_output_dpms(xf86OutputPtr output, int mode)
216 {
217         xf86CrtcPtr crtc = output->crtc;
218         NVOutputPrivatePtr nv_output = output->driver_private;
219         NVPtr pNv = NVPTR(output->scrn);
220
221         ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
222
223         if (nv_output->ramdac != -1) {
224                 /* We may be going for modesetting, so we must reset the ramdacs */
225                 if (mode == DPMSModeOff) {
226                         pNv->ramdac_active[nv_output->ramdac] = FALSE;
227                         ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
228                         nv_output->ramdac_assigned = FALSE;
229                         /* This was not a modeset, but a normal dpms call */
230                 } else {
231                         pNv->ramdac_active[nv_output->ramdac] = TRUE;
232                         ErrorF("Activating ramdac %d\n", nv_output->ramdac);
233                         nv_output->ramdac_assigned = TRUE;
234                 }
235         }
236
237         if (crtc) {
238                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
239
240                 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
241         }
242 }
243
244 static void
245 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
246 {
247         xf86CrtcPtr crtc = output->crtc;
248         NVOutputPrivatePtr nv_output = output->driver_private;
249         NVPtr pNv = NVPTR(output->scrn);
250
251         ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
252
253         /* We just woke up again from an actual monitor dpms and not a modeset prepare */
254         /* Put here since we actually need our ramdac to wake up again ;-) */
255         if (nv_output->ramdac != -1 && mode != DPMSModeOff) {
256                 pNv->ramdac_active[nv_output->ramdac] = TRUE;
257                 nv_output->ramdac_assigned = TRUE;
258                 ErrorF("Activating ramdac %d\n", nv_output->ramdac);
259         }
260
261         /* Are we assigned a ramdac already?, else we will be activated during mode set */
262         if (crtc && nv_output->ramdac != -1) {
263                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
264
265                 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
266
267                 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
268                 switch(mode) {
269                         case DPMSModeStandby:
270                         case DPMSModeSuspend:
271                         case DPMSModeOff:
272                                 /* cut the TMDS output */           
273                                 fpcontrol |= 0x20000022;
274                                 break;
275                         case DPMSModeOn:
276                                 /* disable cutting the TMDS output */
277                                 fpcontrol &= ~0x20000022;
278                                 break;
279                 }
280                 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
281         }
282
283         /* We may be going for modesetting, so we must reset the ramdacs */
284         if (nv_output->ramdac != -1 && mode == DPMSModeOff) {
285                 pNv->ramdac_active[nv_output->ramdac] = FALSE;
286                 nv_output->ramdac_assigned = FALSE;
287                 ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
288         }
289 }
290
291 /* This sequence is an optimized/shortened version of what the blob does */
292 int tmds_regs[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a };
293
294 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
295 {
296         NVOutputPrivatePtr nv_output = output->driver_private;
297         ScrnInfoPtr pScrn = output->scrn;
298         NVPtr pNv = NVPTR(pScrn);
299         NVOutputRegPtr regp;
300         int i;
301
302         regp = &state->dac_reg[nv_output->ramdac];
303         regp->test_control      = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
304         regp->unk_670   = NVOutputReadRAMDAC(output, NV_RAMDAC_670);
305         state->config       = nvReadFB(pNv, NV_PFB_CFG0);
306
307         //regp->unk_900         = NVOutputReadRAMDAC(output, NV_RAMDAC_900);
308
309         /* This exists purely for proper text mode restore */
310         if (override) regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
311
312         /* I want to be able reset TMDS registers for DVI-D/DVI-A pairs for example */
313         /* Also write on VT restore */
314         if (nv_output->type != OUTPUT_LVDS || override )
315                 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
316                         regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
317                 }
318 }
319
320 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
321 {
322         NVOutputPrivatePtr nv_output = output->driver_private;
323         NVOutputRegPtr regp;
324         int i;
325
326         regp = &state->dac_reg[nv_output->ramdac];
327
328         /* This exists purely for proper text mode restore */
329         if (override) NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
330
331         //NVOutputWriteRAMDAC(output, NV_RAMDAC_900, regp->unk_900);
332
333         NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, regp->test_control);
334         NVOutputWriteRAMDAC(output, NV_RAMDAC_670, regp->unk_670);
335
336         /* I want to be able reset TMDS registers for DVI-D/DVI-A pairs for example */
337         /* Also write on VT restore */
338         if (nv_output->type != OUTPUT_LVDS || override )
339                 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
340                         NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
341                 }
342 }
343
344 /* NOTE: Don't rely on this data for anything other than restoring VT's */
345
346 static void
347 nv_output_save (xf86OutputPtr output)
348 {
349         ScrnInfoPtr     pScrn = output->scrn;
350         NVPtr pNv = NVPTR(pScrn);
351         RIVA_HW_STATE *state;
352         NVOutputPrivatePtr nv_output = output->driver_private;
353         int ramdac_backup = nv_output->ramdac;
354
355         ErrorF("nv_output_save is called\n");
356
357         /* This is early init and we have not yet been assigned a ramdac */
358         /* Always choose the prefered ramdac, for consistentcy */
359         /* Assumption: there is always once output that can only run of the primary ramdac */
360         if (nv_output->valid_ramdac & RAMDAC_1) {
361                 nv_output->ramdac = 1;
362         } else {
363                 nv_output->ramdac = 0;
364         }
365
366         state = &pNv->SavedReg;
367
368         /* Due to strange mapping of outputs we could have swapped analog and digital */
369         /* So we force save all the registers */
370         nv_output_save_state_ext(output, state, TRUE);
371
372         /* restore previous state */
373         nv_output->ramdac = ramdac_backup;
374 }
375
376 static void
377 nv_output_restore (xf86OutputPtr output)
378 {
379         ScrnInfoPtr pScrn = output->scrn;
380         NVPtr pNv = NVPTR(pScrn);
381         RIVA_HW_STATE *state;
382         NVOutputPrivatePtr nv_output = output->driver_private;
383         int ramdac_backup = nv_output->ramdac;
384
385         ErrorF("nv_output_restore is called\n");
386
387         /* We want consistent mode restoring and the ramdac entry is variable */
388         /* Always choose the prefered ramdac, for consistentcy */
389         /* Assumption: there is always once output that can only run of the primary ramdac */
390         if (nv_output->valid_ramdac & RAMDAC_1) {
391                 nv_output->ramdac = 1;
392         } else {
393                 nv_output->ramdac = 0;
394         }
395
396         state = &pNv->SavedReg;
397
398         /* Due to strange mapping of outputs we could have swapped analog and digital */
399         /* So we force load all the registers */
400         nv_output_load_state_ext(output, state, TRUE);
401
402         /* restore previous state */
403         nv_output->ramdac = ramdac_backup;
404 }
405
406 static int
407 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
408 {
409         if (pMode->Flags & V_DBLSCAN)
410                 return MODE_NO_DBLESCAN;
411
412         if (pMode->Clock > 400000 || pMode->Clock < 25000)
413                 return MODE_CLOCK_RANGE;
414
415         return MODE_OK;
416 }
417
418
419 static Bool
420 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
421                      DisplayModePtr adjusted_mode)
422 {
423         ErrorF("nv_output_mode_fixup is called\n");
424
425         return TRUE;
426 }
427
428 static void
429 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
430 {
431         NVOutputPrivatePtr nv_output = output->driver_private;
432         ScrnInfoPtr pScrn = output->scrn;
433         NVPtr pNv = NVPTR(pScrn);
434         RIVA_HW_STATE *state, *sv_state;
435         Bool is_fp = FALSE;
436         Bool is_lvds = FALSE;
437         NVOutputRegPtr regp, regp2, savep;
438         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
439         int i;
440
441         xf86CrtcPtr crtc = output->crtc;
442         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
443
444         state = &pNv->ModeReg;
445         regp = &state->dac_reg[nv_output->ramdac];
446         /* The other ramdac */
447         regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
448
449         sv_state = &pNv->SavedReg;
450         savep = &sv_state->dac_reg[nv_output->ramdac];
451
452         if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
453                 is_fp = TRUE;
454                 if (nv_output->type == OUTPUT_LVDS) {
455                         is_lvds = TRUE;
456                 }
457         }
458
459         /* This is just a guess, there are probably more registers which need setting */
460         /* But we must start somewhere ;-) */
461         if (is_fp) {
462                 regp->TMDS[0x4] = 0x80;
463                 /* Enable crosswired mode */
464                 /* This will upset the monitor, trust me, i know it :-( */
465                 /* Now allowed for non-bios inited systems */
466                 if (nv_crtc->head != nv_output->preferred_crtc) {
467                         regp->TMDS[0x4] |= (1 << 3);
468                 }
469
470                 if (is_lvds) {
471                         regp->TMDS[0x4] |= (1 << 0);
472                 }
473         }
474
475         /* The TMDS game begins */
476         /* A few registers are also programmed on non-tmds monitors */
477         /* At the moment i can't give rationale for these values */
478         if (!is_fp) {
479                 regp->TMDS[0x2e] = 0x80;
480                 regp->TMDS[0x2f] = 0xff;
481                 regp->TMDS[0x33] = 0xfe;
482         } else {
483                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
484                 uint32_t pll_setup_control = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SETUP_CONTROL);
485                 regp->TMDS[0x2b] = 0x7d;
486                 regp->TMDS[0x2c] = 0x0;
487                 /* Various combinations exist for lvds, 0x08, 0x48, 0xc8, 0x88 */
488                 /* 0x88 seems most popular and (maybe) the end setting */
489                 if (is_lvds) {
490                         regp->TMDS[0x2e] = 0x88;
491                 } else {
492                         if (nv_crtc->head == 1) {
493                                 regp->TMDS[0x2e] = 0x81;
494                         } else {
495                                 regp->TMDS[0x2e] = 0x85;
496                         }
497                 }
498                 /* 0x08 is also seen for lvds */
499                 regp->TMDS[0x2f] = 0x21;
500                 regp->TMDS[0x30] = 0x0;
501                 regp->TMDS[0x31] = 0x0;
502                 regp->TMDS[0x32] = 0x0;
503                 regp->TMDS[0x33] = 0xf0;
504                 /* 0x00 is also seen for lvds */
505                 regp->TMDS[0x3a] = 0x80;
506
507                 /* Here starts the registers that may cause problems for some */
508                 /* This an educated guess */
509                 if (pNv->misc_info.reg_c040 & (1 << 10)) {
510                         regp->TMDS[0x5] = 0x68;
511                 } else {
512                         regp->TMDS[0x5] = 0x6e;
513                 }
514
515                 if (is_lvds) {
516                         regp->TMDS[0x0] = 0x61;
517                 } else {
518                         /* This seems to be related to PLL_SETUP_CONTROL */
519                         /* When PLL_SETUP_CONTROL ends with 0x1c, then this value is 0xc1 */
520                         /* Otherwise 0xf1 */
521                         if ((pll_setup_control & 0xff) == 0x1c) {
522                                 regp->TMDS[0x0] = 0xc1;
523                         } else {
524                                 regp->TMDS[0x0] = 0xf1;
525                         }
526                 }
527
528                 /* This is also related to PLL_SETUP_CONTROL, exactly how is unknown */
529                 if (pll_setup_control == 0) {
530                         regp->TMDS[0x1] = 0x0;
531                 } else {
532                         if (nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) & (1<<12)) {
533                                 regp->TMDS[0x1] = 0x41;
534                         } else {
535                                 regp->TMDS[0x1] = 0x42;
536                         }
537                 }
538
539                 if (is_lvds) {
540                         regp->TMDS[0x2] = 0x0;
541                 } else {
542                         if (pll_setup_control == 0x0) {
543                                 regp->TMDS[0x2] = 0x90;
544                         } else {
545                                 regp->TMDS[0x2] = 0x89;
546                         }
547                 }
548                 /* This test is not needed for me although the blob sets this value */
549                 /* It may be wrong, but i'm leaving it for historical reference */
550                 /*if (pNv->misc_info.reg_c040 == 0x3c0bc003 || pNv->misc_info.reg_c040 == 0x3c0bc333) {
551                         regp->TMDS[0x2] = 0xa9;
552                 }*/
553
554                 /* I assume they are zero for !is_lvds */
555                 if (is_lvds) {
556                         /* Observed values are 0x11 and 0x14, TODO: this needs refinement */
557                         regp->TMDS[0x40] = 0x14;
558                         regp->TMDS[0x43] = 0xb0;
559                 }
560         }
561
562         /* Put test control into what seems to be the neutral position */
563         if (pNv->NVArch < 0x44) {
564                 regp->test_control = 0x00000000;
565         } else {
566                 regp->test_control = 0x00100000;
567         }
568
569         /* This is a similar register to test control */
570         regp->unk_670 = regp->test_control;
571
572         /* This may be causing problems */
573         //regp->unk_900 = 0x10000;
574
575         if (output->crtc) {
576                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
577                 int two_crt = FALSE;
578                 int two_mon = FALSE;
579
580                 for (i = 0; i < config->num_output; i++) {
581                         NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
582
583                         /* is it this output ?? */
584                         if (config->output[i] == output)
585                                 continue;
586
587                         /* it the output connected */
588                         if (config->output[i]->crtc == NULL)
589                                 continue;
590
591                         two_mon = TRUE;
592                         if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
593                                 two_crt = TRUE;
594                         }
595                 }
596
597                 ErrorF("%d: crtc %d ramdac %d twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->ramdac, two_crt, two_mon);
598         }
599 }
600
601 static void
602 nv_output_mode_set_routing(xf86OutputPtr output)
603 {
604         NVOutputPrivatePtr nv_output = output->driver_private;
605         xf86CrtcPtr crtc = output->crtc;
606         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
607         ScrnInfoPtr     pScrn = output->scrn;
608         NVPtr pNv = NVPTR(pScrn);
609         Bool is_fp = FALSE;
610         int other_ramdac = 0;
611
612         uint32_t output_reg = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_OUTPUT);
613
614         if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
615                 is_fp = TRUE;
616         }
617
618         if (is_fp) {
619                 output_reg = 0x0;
620         } else { 
621                 output_reg = NV_RAMDAC_OUTPUT_DAC_ENABLE;
622         }
623
624         if (nv_crtc->head == 1) {
625                 output_reg |= NV_RAMDAC_OUTPUT_SELECT_VPLL2;
626         } else {
627                 output_reg &= ~NV_RAMDAC_OUTPUT_SELECT_VPLL2;
628         }
629
630         if (nv_output->ramdac == 1) {
631                 other_ramdac = 0;
632         } else {
633                 other_ramdac = 1;
634         }
635
636         uint32_t output2_reg = nvReadRAMDAC(pNv, other_ramdac, NV_RAMDAC_OUTPUT);
637         
638         if (nv_crtc->head == 1) {
639                 output2_reg &= ~NV_RAMDAC_OUTPUT_SELECT_VPLL2;
640         } else {
641                 output2_reg |= NV_RAMDAC_OUTPUT_SELECT_VPLL2;
642         }
643
644         nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_OUTPUT, output_reg);
645         nvWriteRAMDAC(pNv, other_ramdac, NV_RAMDAC_OUTPUT, output2_reg);
646 }
647
648 static void
649 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
650                    DisplayModePtr adjusted_mode)
651 {
652     ScrnInfoPtr pScrn = output->scrn;
653     NVPtr pNv = NVPTR(pScrn);
654     RIVA_HW_STATE *state;
655
656         ErrorF("nv_output_mode_set is called\n");
657
658     state = &pNv->ModeReg;
659
660     nv_output_mode_set_regs(output, mode, adjusted_mode);
661     nv_output_load_state_ext(output, state, FALSE);
662         nv_output_mode_set_routing(output);
663 }
664
665 static xf86MonPtr
666 nv_get_edid(xf86OutputPtr output)
667 {
668         /* no use for shared DDC output */
669         NVOutputPrivatePtr nv_output = output->driver_private;
670         xf86MonPtr ddc_mon;
671
672         if (nv_output->pDDCBus == NULL)
673                 return NULL;
674
675         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
676         if (!ddc_mon)
677                 return NULL;
678
679         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
680                 goto invalid;
681
682         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
683                                 nv_output->type == OUTPUT_LVDS))
684                 goto invalid;
685
686         return ddc_mon;
687
688 invalid:
689         xfree(ddc_mon);
690         return NULL;
691 }
692
693 static Bool
694 nv_ddc_detect(xf86OutputPtr output)
695 {
696         xf86MonPtr m = nv_get_edid(output);
697
698         if (m == NULL)
699                 return FALSE;
700
701         xfree(m);
702         return TRUE;
703 }
704
705 static Bool
706 nv_crt_load_detect(xf86OutputPtr output)
707 {
708         ScrnInfoPtr pScrn = output->scrn;
709         NVOutputPrivatePtr nv_output = output->driver_private;
710         NVPtr pNv = NVPTR(pScrn);
711         CARD32 reg_output, reg_test_ctrl, temp;
712         Bool present = FALSE;
713         int ramdac;
714
715         /* Usually these outputs are native to ramdac 1 */
716         if (nv_output->valid_ramdac & RAMDAC_0 && nv_output->valid_ramdac & RAMDAC_1) {
717                 ramdac = 1;
718         } else if (nv_output->valid_ramdac & RAMDAC_1) {
719                 ramdac = 1;
720         } else if (nv_output->valid_ramdac & RAMDAC_0) {
721                 ramdac = 0;
722         } else {
723                 return FALSE;
724         }
725
726         /* For some reason we get false positives on ramdac 1, maybe due tv-out? */
727         if (ramdac == 1) {
728                 return FALSE;
729         }
730
731         if (nv_output->pDDCBus != NULL) {
732                 xf86MonPtr ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
733                 /* Is there a digital flatpanel on this channel? */
734                 if (ddc_mon && ddc_mon->features.input_type) {
735                         return FALSE;
736                 }
737         }
738
739         reg_output = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
740         reg_test_ctrl = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
741
742         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
743
744         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
745         usleep(1000);
746
747         temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
748         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, temp | 1);
749
750         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
751         temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
752         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
753
754         usleep(1000);
755
756         present = (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
757
758         temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
759         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
760
761         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, reg_output);
762         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
763
764         if (present) {
765                 ErrorF("A crt was detected on ramdac %d with no ddc support\n", ramdac);
766                 return TRUE;
767         }
768
769         return FALSE;
770 }
771
772 static xf86OutputStatus
773 nv_tmds_output_detect(xf86OutputPtr output)
774 {
775         ErrorF("nv_tmds_output_detect is called\n");
776
777         if (nv_ddc_detect(output))
778                 return XF86OutputStatusConnected;
779
780         return XF86OutputStatusDisconnected;
781 }
782
783
784 static xf86OutputStatus
785 nv_analog_output_detect(xf86OutputPtr output)
786 {
787         ErrorF("nv_analog_output_detect is called\n");
788
789         if (nv_ddc_detect(output))
790                 return XF86OutputStatusConnected;
791
792         if (nv_crt_load_detect(output))
793                 return XF86OutputStatusConnected;
794
795         return XF86OutputStatusDisconnected;
796 }
797
798 static DisplayModePtr
799 nv_output_get_modes(xf86OutputPtr output)
800 {
801         NVOutputPrivatePtr nv_output = output->driver_private;
802         xf86MonPtr ddc_mon;
803         DisplayModePtr ddc_modes;
804
805         ErrorF("nv_output_get_modes is called\n");
806
807         ddc_mon = nv_get_edid(output);
808
809         xf86OutputSetEDID(output, ddc_mon);
810
811         if (ddc_mon == NULL)
812                 return NULL;
813
814         ddc_modes = xf86OutputGetEDIDModes (output);
815
816         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
817                 int i;
818                 DisplayModePtr mode;
819
820                 for (i = 0; i < 4; i++) {
821                         /* We only look at detailed timings atm */
822                         if (ddc_mon->det_mon[i].type != DT)
823                                 continue;
824                         /* Selecting only based on width ok? */
825                         if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
826                                 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
827                                 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
828                         }
829                 }
830
831                 /* Add a native resolution mode that is preferred */
832                 /* Reduced blanking should be fine on DVI monitor */
833                 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
834                 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
835                 /* We want the new mode to be preferred */
836                 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
837                         if (mode->type & M_T_PREFERRED) {
838                                 mode->type &= ~M_T_PREFERRED;
839                         }
840                 }
841                 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
842         }
843
844         return ddc_modes;
845 }
846
847 static void
848 nv_output_destroy (xf86OutputPtr output)
849 {
850         ErrorF("nv_output_destroy is called\n");
851         if (output->driver_private)
852                 xfree (output->driver_private);
853 }
854
855 static void
856 nv_clear_ramdac_from_outputs(xf86OutputPtr output, int ramdac)
857 {
858         int i;
859         ScrnInfoPtr pScrn = output->scrn;
860         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
861         xf86OutputPtr output2;
862         NVOutputPrivatePtr nv_output2;
863         for (i = 0; i < xf86_config->num_output; i++) {
864                 output2 = xf86_config->output[i];
865                 nv_output2 = output2->driver_private;
866                 if (nv_output2->ramdac == ramdac && output != output2) {
867                         nv_output2->ramdac = -1;
868                         nv_output2->ramdac_assigned = FALSE;
869                         break;
870                 }
871         }
872 }
873
874 static void
875 nv_output_prepare(xf86OutputPtr output)
876 {
877         ErrorF("nv_output_prepare is called\n");
878         NVOutputPrivatePtr nv_output = output->driver_private;
879         ScrnInfoPtr     pScrn = output->scrn;
880         NVPtr pNv = NVPTR(pScrn);
881         Bool stole_ramdac = FALSE;
882         xf86OutputPtr output2 = NULL;
883
884         output->funcs->dpms(output, DPMSModeOff);
885
886         if (nv_output->ramdac_assigned) {
887                 ErrorF("We already have a ramdac.\n");
888                 return;
889         }
890
891         /* We need ramdac 0, so let's steal it */
892         if (!(nv_output->valid_ramdac & RAMDAC_1) && pNv->ramdac_active[0]) {
893                 ErrorF("Stealing ramdac0 ;-)\n");
894                 int i;
895                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
896                 NVOutputPrivatePtr nv_output2;
897                 for (i = 0; i < xf86_config->num_output; i++) {
898                         output2 = xf86_config->output[i];
899                         nv_output2 = output2->driver_private;
900                         if (nv_output2->ramdac == 0 && output != output2) {
901                                 nv_output2->ramdac = -1;
902                                 nv_output2->ramdac_assigned = FALSE;
903                                 break;
904                         }
905                 }
906                 pNv->ramdac_active[0] = FALSE;
907                 stole_ramdac = TRUE;
908         }
909
910         /* We need ramdac 1, so let's steal it */
911         if (!(nv_output->valid_ramdac & RAMDAC_0) && pNv->ramdac_active[1]) {
912                 ErrorF("Stealing ramdac1 ;-)\n");
913                 int i;
914                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
915                 NVOutputPrivatePtr nv_output2;
916                 for (i = 0; i < xf86_config->num_output; i++) {
917                         output2 = xf86_config->output[i];
918                         nv_output2 = output2->driver_private;
919                         if (nv_output2->ramdac == 1 && output != output2) {
920                                 nv_output2->ramdac = -1;
921                                 nv_output2->ramdac_assigned = FALSE;
922                                 break;
923                         }
924                 }
925                 pNv->ramdac_active[1] = FALSE;
926                 stole_ramdac = TRUE;
927         }
928
929         /* TODO: figure out what ramdac 2 is and how it is identified */
930
931         /* At this point we already stole ramdac 0 or 1 if we need it */
932         if (!pNv->ramdac_active[0] && (nv_output->valid_ramdac & RAMDAC_0)) {
933                 ErrorF("Activating ramdac %d\n", 0);
934                 pNv->ramdac_active[0] = TRUE;
935                 nv_output->ramdac = 0;
936         } else {
937                 ErrorF("Activating ramdac %d\n", 1);
938                 pNv->ramdac_active[1] = TRUE;
939                 nv_output->ramdac = 1;
940         }
941
942         if (nv_output->ramdac != -1) {
943                 nv_output->ramdac_assigned = TRUE;
944                 nv_clear_ramdac_from_outputs(output, nv_output->ramdac);
945         }
946
947         if (stole_ramdac) {
948                 ErrorF("Resetting the stolen ramdac\n");
949                 output2->funcs->prepare(output2);
950                 output2->funcs->mode_set(output2, &(output2->crtc->desiredMode), &(output2->crtc->desiredMode));
951         }
952 }
953
954 static void
955 nv_output_commit(xf86OutputPtr output)
956 {
957         ErrorF("nv_output_commit is called\n");
958
959         output->funcs->dpms(output, DPMSModeOn);
960 }
961
962 static const xf86OutputFuncsRec nv_analog_output_funcs = {
963     .dpms = nv_analog_output_dpms,
964     .save = nv_output_save,
965     .restore = nv_output_restore,
966     .mode_valid = nv_output_mode_valid,
967     .mode_fixup = nv_output_mode_fixup,
968     .mode_set = nv_output_mode_set,
969     .detect = nv_analog_output_detect,
970     .get_modes = nv_output_get_modes,
971     .destroy = nv_output_destroy,
972     .prepare = nv_output_prepare,
973     .commit = nv_output_commit,
974 };
975
976 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
977     .dpms = nv_tmds_output_dpms,
978     .save = nv_output_save,
979     .restore = nv_output_restore,
980     .mode_valid = nv_output_mode_valid,
981     .mode_fixup = nv_output_mode_fixup,
982     .mode_set = nv_output_mode_set,
983     .detect = nv_tmds_output_detect,
984     .get_modes = nv_output_get_modes,
985     .destroy = nv_output_destroy,
986     .prepare = nv_output_prepare,
987     .commit = nv_output_commit,
988 };
989
990 static int nv_lvds_output_mode_valid
991 (xf86OutputPtr output, DisplayModePtr pMode)
992 {
993         NVOutputPrivatePtr nv_output = output->driver_private;
994
995         /* No modes > panel's native res */
996         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
997                 return MODE_PANEL;
998
999         return nv_output_mode_valid(output, pMode);
1000 }
1001
1002 static xf86OutputStatus
1003 nv_lvds_output_detect(xf86OutputPtr output)
1004 {
1005         ScrnInfoPtr pScrn = output->scrn;
1006         NVPtr pNv = NVPTR(pScrn);
1007
1008         if (pNv->fp_native_mode || nv_ddc_detect(output))
1009                 return XF86OutputStatusConnected;
1010
1011         return XF86OutputStatusDisconnected;
1012 }
1013
1014 static DisplayModePtr
1015 nv_lvds_output_get_modes(xf86OutputPtr output)
1016 {
1017         ScrnInfoPtr pScrn = output->scrn;
1018         NVPtr pNv = NVPTR(pScrn);
1019         NVOutputPrivatePtr nv_output = output->driver_private;
1020         DisplayModePtr modes;
1021
1022         if ((modes = nv_output_get_modes(output)))
1023                 return modes;
1024
1025         /* it is possible to set up a mode from what we can read from the
1026          * RAMDAC registers, but if we can't read the BIOS table correctly
1027          * we might as well give up */
1028         if (pNv->fp_native_mode == NULL)
1029                 return NULL;
1030
1031         nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1032         nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1033         nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1034
1035         if (pNv->fp_native_mode->HDisplay != nv_output->fpWidth ||
1036                 pNv->fp_native_mode->VDisplay != nv_output->fpHeight) {
1037                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1038                         "Panel size mismatch; ignoring RAMDAC\n");
1039                 nv_output->fpWidth = pNv->fp_native_mode->HDisplay;
1040                 nv_output->fpHeight = pNv->fp_native_mode->VDisplay;
1041         }
1042
1043         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1044                 nv_output->fpWidth, nv_output->fpHeight);
1045
1046         nv_output->native_mode = xf86DuplicateMode(pNv->fp_native_mode);
1047
1048         return xf86DuplicateMode(pNv->fp_native_mode);
1049 }
1050
1051 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1052         .dpms = nv_lvds_output_dpms,
1053         .save = nv_output_save,
1054         .restore = nv_output_restore,
1055         .mode_valid = nv_lvds_output_mode_valid,
1056         .mode_fixup = nv_output_mode_fixup,
1057         .mode_set = nv_output_mode_set,
1058         .detect = nv_lvds_output_detect,
1059         .get_modes = nv_lvds_output_get_modes,
1060         .destroy = nv_output_destroy,
1061         .prepare = nv_output_prepare,
1062         .commit = nv_output_commit,
1063 };
1064
1065 static void nv_add_analog_output(ScrnInfoPtr pScrn, int heads, int order, int i2c_index, Bool dvi_pair)
1066 {
1067         NVPtr pNv = NVPTR(pScrn);
1068         xf86OutputPtr       output;
1069         NVOutputPrivatePtr    nv_output;
1070         char outputname[20];
1071         Bool create_output = TRUE;
1072
1073         /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1074         if (dvi_pair) {
1075                 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1076                 pNv->dvi_a_count++;
1077         } else {
1078                 sprintf(outputname, "VGA-%d", pNv->vga_count);
1079                 pNv->vga_count++;
1080         }
1081
1082         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1083         if (!nv_output) {
1084                 return;
1085         }
1086
1087         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1088                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1089
1090         nv_output->type = OUTPUT_ANALOG;
1091
1092         /* order:
1093          * bit0: RAMDAC_0 valid
1094          * bit1: RAMDAC_1 valid
1095          * So lowest order has highest priority.
1096          * Below is guesswork:
1097          * bit2: All ramdac's valid?
1098          * FIXME: this probably wrong
1099          */
1100         nv_output->valid_ramdac = order;
1101
1102         if (!create_output) {
1103                 xfree(nv_output);
1104                 return;
1105         }
1106
1107         /* Delay creation of output until we actually know we want it */
1108         output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1109         if (!output)
1110                 return;
1111
1112         output->driver_private = nv_output;
1113
1114         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1115
1116         nv_output->ramdac = -1;
1117
1118         /* This is only to facilitate proper output routing for dvi */
1119         /* See sel_clk assignment in nv_crtc.c */
1120         if (order & RAMDAC_1) {
1121                 nv_output->preferred_crtc = 1;
1122         } else {
1123                 nv_output->preferred_crtc = 0;
1124         }
1125
1126         output->possible_crtcs = heads;
1127         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1128 }
1129
1130 static void nv_add_digital_output(ScrnInfoPtr pScrn, int heads, int order, int i2c_index, int lvds)
1131 {
1132         NVPtr pNv = NVPTR(pScrn);
1133         xf86OutputPtr       output;
1134         NVOutputPrivatePtr    nv_output;
1135         char outputname[20];
1136         Bool create_output = TRUE;
1137
1138         if (lvds) {
1139                 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1140                 pNv->lvds_count++;
1141         } else {
1142                 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1143                 pNv->dvi_d_count++;
1144         }
1145
1146         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1147
1148         if (!nv_output) {
1149                 return;
1150         }
1151
1152         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1153                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1154
1155         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1156
1157         /* order:
1158          * bit0: RAMDAC_0 valid
1159          * bit1: RAMDAC_1 valid
1160          * So lowest order has highest priority.
1161          * Below is guesswork:
1162          * bit2: All ramdac's valid?
1163          * FIXME: this probably wrong
1164          */
1165         nv_output->valid_ramdac = order;
1166
1167         if (lvds) {
1168                 nv_output->type = OUTPUT_LVDS;
1169                 /* comment below two lines to test LVDS under RandR12.
1170                  * If your screen "blooms" or "bleeds" (i.e. has a developing
1171                  * white / psychedelic pattern) then KILL X IMMEDIATELY
1172                  * (ctrl+alt+backspace) & if the effect continues reset power */
1173                 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1174                 create_output = FALSE;
1175         } else {
1176                 nv_output->type = OUTPUT_TMDS;
1177         }
1178
1179         if (!create_output) {
1180                 xfree(nv_output);
1181                 return;
1182         }
1183
1184         /* Delay creation of output until we are certain is desirable */
1185         if (lvds)
1186                 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1187         else
1188                 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1189         if (!output)
1190                 return;
1191
1192         output->driver_private = nv_output;
1193
1194         nv_output->ramdac = -1;
1195
1196         /* This is a theory: */
1197         /* DVI outputs are in no way bound to ramdac's, but exist purely on a crtc level */
1198         /* Don't ask why this relation seems valid, ask those weirdos at nvidia */
1199         if (order & RAMDAC_1) {
1200                 nv_output->preferred_crtc = 1;
1201         } else {
1202                 nv_output->preferred_crtc = 0;
1203         }
1204
1205         output->possible_crtcs = heads;
1206         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1207 }
1208
1209 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1210 {
1211         unsigned char type, i2c_index, or, heads, bus;
1212         NVPtr pNv = NVPTR(pScrn);
1213         int i, bus_count[0xf];
1214
1215         memset(bus_count, 0, sizeof(bus_count));
1216         for (i = 0 ; i < pNv->dcb_table.entries; i++)
1217                 bus_count[pNv->dcb_table.entry[i].bus]++;
1218
1219         /* we setup the outputs up from the BIOS table */
1220         for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1221                 type = pNv->dcb_table.entry[i].type;
1222                 i2c_index = pNv->dcb_table.entry[i].i2c_index;
1223                 or = ffs(pNv->dcb_table.entry[i].or);
1224                 heads = pNv->dcb_table.entry[i].head;
1225                 bus = pNv->dcb_table.entry[i].bus;
1226
1227                 if (type > 3) {
1228                         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1229                         continue;
1230                 }
1231
1232                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry %d: type: %d, i2c_index: %d, head: %d, bus: %d, or: %d\n", i, type, i2c_index, heads, bus, or);
1233
1234                 switch(type) {
1235                 case OUTPUT_ANALOG:
1236                         nv_add_analog_output(pScrn, heads, or, i2c_index, (bus_count[bus] > 1));
1237                         break;
1238                 case OUTPUT_TMDS:
1239                         nv_add_digital_output(pScrn, heads, or, i2c_index, 0);
1240                         break;
1241                 case OUTPUT_LVDS:
1242                         nv_add_digital_output(pScrn, heads, or, i2c_index, 1);
1243                         break;
1244                 default:
1245                         break;
1246                 }
1247         }
1248 }
1249
1250 void NvSetupOutputs(ScrnInfoPtr pScrn)
1251 {
1252         NVPtr pNv = NVPTR(pScrn);
1253
1254         pNv->Television = FALSE;
1255
1256         memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1257         NvDCBSetupOutputs(pScrn);
1258 }
1259
1260 /*************************************************************************** \
1261 |*                                                                           *|
1262 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1263 |*                                                                           *|
1264 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1265 |*     international laws.  Users and possessors of this source code are     *|
1266 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1267 |*     use this code in individual and commercial software.                  *|
1268 |*                                                                           *|
1269 |*     Any use of this source code must include,  in the user documenta-     *|
1270 |*     tion and  internal comments to the code,  notices to the end user     *|
1271 |*     as follows:                                                           *|
1272 |*                                                                           *|
1273 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1274 |*                                                                           *|
1275 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1276 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1277 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1278 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1279 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1280 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1281 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1282 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1283 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1284 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1285 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1286 |*                                                                           *|
1287 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1288 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1289 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1290 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1291 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1292 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1293 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1294 |*     all U.S. Government End Users  acquire the source code  with only     *|
1295 |*     those rights set forth herein.                                        *|
1296 |*                                                                           *|
1297  \***************************************************************************/