randr12: Disable crt load detect again, until i know how to use it properly.
[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 #include "X11/Xatom.h"
45
46 #include "xf86Crtc.h"
47 #include "nv_include.h"
48
49 const char *OutputType[] = {
50     "None",
51     "VGA",
52     "DVI",
53     "LVDS",
54     "S-video",
55     "Composite",
56 };
57
58 const char *MonTypeName[7] = {
59     "AUTO",
60     "NONE",
61     "CRT",
62     "LVDS",
63     "TMDS",
64     "CTV",
65     "STV"
66 };
67
68 /* 
69  * TMDS registers are indirect 8 bit registers.
70  * Reading is straightforward, writing a bit odd.
71  * Reading: Write adress (+write protect bit, do not forget this), then read value.
72  * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
73  */
74
75 void NVWriteTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
76 {
77         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
78                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
79
80         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
81
82         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
83         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
84                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
85 }
86
87 CARD8 NVReadTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg)
88 {
89         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
90                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
91
92         return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
93 }
94
95 /* Two register sets exist, this one is only used for dual link dvi/lvds */
96
97 void NVWriteTMDS2(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
98 {
99         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, 
100                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
101
102         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2, val & 0xff);
103
104         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, tmds_reg & 0xff);
105         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, 
106                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
107 }
108
109 CARD8 NVReadTMDS2(NVPtr pNv, int ramdac, CARD32 tmds_reg)
110 {
111         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, 
112                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
113
114         return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2) & 0xff);
115 }
116
117 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
118 {
119         NVOutputPrivatePtr nv_output = output->driver_private;
120         ScrnInfoPtr     pScrn = output->scrn;
121         NVPtr pNv = NVPTR(pScrn);
122
123         /* We must write to the "bus" of the output */
124         NVWriteTMDS(pNv, nv_output->preferred_output, tmds_reg, val);
125 }
126
127 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
128 {
129         NVOutputPrivatePtr nv_output = output->driver_private;
130         ScrnInfoPtr     pScrn = output->scrn;
131         NVPtr pNv = NVPTR(pScrn);
132
133         /* We must read from the "bus" of the output */
134         return NVReadTMDS(pNv, nv_output->preferred_output, tmds_reg);
135 }
136
137 void NVOutputWriteTMDS2(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
138 {
139         NVOutputPrivatePtr nv_output = output->driver_private;
140         ScrnInfoPtr     pScrn = output->scrn;
141         NVPtr pNv = NVPTR(pScrn);
142
143         /* We must write to the "bus" of the output */
144         NVWriteTMDS2(pNv, nv_output->preferred_output, tmds_reg, val);
145 }
146
147 CARD8 NVOutputReadTMDS2(xf86OutputPtr output, CARD32 tmds_reg)
148 {
149         NVOutputPrivatePtr nv_output = output->driver_private;
150         ScrnInfoPtr     pScrn = output->scrn;
151         NVPtr pNv = NVPTR(pScrn);
152
153         /* We must read from the "bus" of the output */
154         return NVReadTMDS2(pNv, nv_output->preferred_output, tmds_reg);
155 }
156
157 /* These functions now write into the output, instead of a specific ramdac */
158
159 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
160 {
161     NVOutputPrivatePtr nv_output = output->driver_private;
162     ScrnInfoPtr pScrn = output->scrn;
163     NVPtr pNv = NVPTR(pScrn);
164
165     nvWriteRAMDAC(pNv, nv_output->preferred_output, ramdac_reg, val);
166 }
167
168 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
169 {
170     NVOutputPrivatePtr nv_output = output->driver_private;
171     ScrnInfoPtr pScrn = output->scrn;
172     NVPtr pNv = NVPTR(pScrn);
173
174     return nvReadRAMDAC(pNv, nv_output->preferred_output, ramdac_reg);
175 }
176
177 static void dpms_update_output_ramdac(xf86OutputPtr output, int mode)
178 {
179         NVOutputPrivatePtr nv_output = output->driver_private;
180         ScrnInfoPtr pScrn = output->scrn;
181         NVPtr pNv = NVPTR(pScrn);
182         xf86CrtcPtr crtc = output->crtc;
183         if (!crtc)      /* we need nv_crtc, so give up */
184                 return;
185         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
186
187         /* We may be going for modesetting, so we must reset our output binding */
188         if (mode == DPMSModeOff) {
189                 NVWriteVGACR5758(pNv, nv_crtc->head, 0, 0x7f);
190                 NVWriteVGACR5758(pNv, nv_crtc->head, 2, 0);
191                 return;
192         }
193
194         /* The previous call was not a modeset, but a normal dpms call */
195         NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
196         NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
197 }
198
199 static void
200 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
201 {
202         NVOutputPrivatePtr nv_output = output->driver_private;
203         NVPtr pNv = NVPTR(output->scrn);
204         xf86CrtcPtr crtc = output->crtc;
205         if (!crtc)      /* we need nv_crtc, so give up */
206                 return;
207         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
208
209         ErrorF("nv_lvds_output_dpms is called with mode %d\n", mode);
210
211         dpms_update_output_ramdac(output, mode);
212
213         if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_power_scripts)
214                 return;
215
216         switch (mode) {
217         case DPMSModeStandby:
218         case DPMSModeSuspend:
219                 call_lvds_script(output->scrn, nv_crtc->head, nv_output->dcb_entry, LVDS_BACKLIGHT_OFF, 0);
220                 break;
221         case DPMSModeOff:
222                 call_lvds_script(output->scrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_OFF, 0);
223                 break;
224         case DPMSModeOn:
225                 call_lvds_script(output->scrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_ON, 0);
226         default:
227                 break;
228         }
229 }
230
231 static void
232 nv_analog_output_dpms(xf86OutputPtr output, int mode)
233 {
234         xf86CrtcPtr crtc = output->crtc;
235
236         ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
237
238         dpms_update_output_ramdac(output, mode);
239
240         if (crtc) {
241                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
242
243                 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->head, mode);
244         }
245 }
246
247 static void
248 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
249 {
250         xf86CrtcPtr crtc = output->crtc;
251         NVPtr pNv = NVPTR(output->scrn);
252
253         ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
254
255         dpms_update_output_ramdac(output, mode);
256
257         /* Are we assigned a ramdac already?, else we will be activated during mode set */
258         if (crtc) {
259                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
260
261                 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->head, mode);
262
263                 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL);
264                 switch(mode) {
265                         case DPMSModeStandby:
266                         case DPMSModeSuspend:
267                         case DPMSModeOff:
268                                 /* cut the TMDS output */           
269                                 fpcontrol |= 0x20000022;
270                                 break;
271                         case DPMSModeOn:
272                                 /* disable cutting the TMDS output */
273                                 fpcontrol &= ~0x20000022;
274                                 break;
275                 }
276                 nvWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, fpcontrol);
277         }
278 }
279
280 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
281 {
282         NVOutputPrivatePtr nv_output = output->driver_private;
283         NVOutputRegPtr regp;
284         int i;
285
286         regp = &state->dac_reg[nv_output->preferred_output];
287
288         regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
289
290         /* NV11's don't seem to like this, so let's restrict it to digital outputs only. */
291         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
292                 /* Store the registers in case we need them again for something (like data for VT restore) */
293                 for (i = 0; i < 0xFF; i++) {
294                         regp->TMDS[i] = NVOutputReadTMDS(output, i);
295                 }
296
297                 for (i = 0; i < 0xFF; i++) {
298                         regp->TMDS2[i] = NVOutputReadTMDS2(output, i);
299                 }
300         }
301 }
302
303 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
304 {
305         NVOutputPrivatePtr nv_output = output->driver_private;
306         NVOutputRegPtr regp;
307
308         regp = &state->dac_reg[nv_output->preferred_output];
309
310         /* This exists purely for proper text mode restore */
311         if (override) NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
312 }
313
314 /* NOTE: Don't rely on this data for anything other than restoring VT's */
315
316 static void
317 nv_output_save (xf86OutputPtr output)
318 {
319         ScrnInfoPtr     pScrn = output->scrn;
320         NVPtr pNv = NVPTR(pScrn);
321         RIVA_HW_STATE *state;
322
323         ErrorF("nv_output_save is called\n");
324         state = &pNv->SavedReg;
325
326         /* Due to strange mapping of outputs we could have swapped analog and digital */
327         /* So we force save all the registers */
328         nv_output_save_state_ext(output, state);
329 }
330
331 uint32_t nv_calc_tmds_clock_from_pll(xf86OutputPtr output)
332 {
333         ScrnInfoPtr pScrn = output->scrn;
334         NVPtr pNv = NVPTR(pScrn);
335         RIVA_HW_STATE *state;
336         NVOutputRegPtr regp;
337         NVOutputPrivatePtr nv_output = output->driver_private;
338
339         state = &pNv->SavedReg;
340         /* Registers are stored by their preferred ramdac */
341         regp = &state->dac_reg[nv_output->preferred_output];
342
343         /* Only do it once for a dvi-d/dvi-a pair */
344         Bool swapped_clock = FALSE;
345         Bool vpllb_disabled = FALSE;
346         /* Bit3 swaps crtc (clocks are bound to crtc) and output */
347         if (regp->TMDS[0x4] & (1 << 3)) {
348                 swapped_clock = TRUE;
349         }
350
351         uint8_t vpll_num = swapped_clock ^ nv_output->preferred_output;
352
353         uint32_t vplla = 0;
354         uint32_t vpllb = 0;
355
356         /* For the moment the syntax is the same for NV40 and earlier */
357         if (pNv->Architecture == NV_ARCH_40) {
358                 vplla = vpll_num ? state->vpll2_a : state->vpll1_a;
359                 vpllb = vpll_num ? state->vpll2_b : state->vpll1_b;
360         } else {
361                 vplla = vpll_num ? state->vpll2 : state->vpll;
362                 if (pNv->twoStagePLL)
363                         vpllb = vpll_num ? state->vpll2B : state->vpllB;
364         }
365
366         if (!pNv->twoStagePLL)
367                 vpllb_disabled = TRUE;
368
369         /* This is the dummy value nvidia sets when vpll is disabled */
370         if ((vpllb & 0xFFFF) == 0x11F)
371                 vpllb_disabled = TRUE;
372
373         uint8_t m1, m2, n1, n2, p;
374
375         m1 = vplla & 0xFF;
376         n1 = (vplla >> 8) & 0xFF;
377         p = (vplla >> 16) & 0x7;
378
379         if (vpllb_disabled) {
380                 m2 = 1;
381                 n2 = 1;
382         } else {
383                 m2 = vpllb & 0xFF;
384                 n2 = (vpllb >> 8) & 0xFF;
385         }
386
387         uint32_t clock = ((pNv->CrystalFreqKHz * n1 * n2)/(m1 * m2)) >> p;
388         ErrorF("The original bios clock seems to have been %d kHz\n", clock);
389         return clock;
390 }
391
392 void nv_set_tmds_registers(xf86OutputPtr output, uint32_t clock, Bool override, Bool crosswired)
393 {
394         ScrnInfoPtr pScrn = output->scrn;
395         NVOutputPrivatePtr nv_output = output->driver_private;
396         xf86CrtcPtr crtc = output->crtc;
397         /* We have no crtc, so what are we supposed to do now? */
398         /* This can only happen during VT restore */
399         if (crtc && !override) {
400                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
401                 /*
402                  * Resetting all registers is a bad idea, it seems to work fine without it.
403                  */
404                 if (nv_output->type == OUTPUT_TMDS)
405                         run_tmds_table(pScrn, nv_output->dcb_entry, nv_crtc->head, clock/10);
406                 else
407                         call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_RESET, clock / 10);
408         } else {
409                 /*
410                  * We have no crtc, but we do know what output we are and if we were crosswired.
411                  * We can determine our crtc from this.
412                  */
413                 if (nv_output->type == OUTPUT_TMDS)
414                         run_tmds_table(pScrn, nv_output->dcb_entry, nv_output->preferred_output ^ crosswired, clock/10);
415                 else {
416                         call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_RESET, clock / 10);
417                         call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_PANEL_ON, 0);
418                 }
419         }
420 }
421
422 static void
423 nv_output_restore (xf86OutputPtr output)
424 {
425         ScrnInfoPtr pScrn = output->scrn;
426         NVPtr pNv = NVPTR(pScrn);
427         RIVA_HW_STATE *state;
428         NVOutputPrivatePtr nv_output = output->driver_private;
429         NVOutputRegPtr regp;
430         ErrorF("nv_output_restore is called\n");
431
432         state = &pNv->SavedReg;
433         regp = &state->dac_reg[nv_output->preferred_output];
434
435         /* Due to strange mapping of outputs we could have swapped analog and digital */
436         /* So we force load all the registers */
437         nv_output_load_state_ext(output, state, TRUE);
438 }
439
440 static int
441 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
442 {
443         if (pMode->Flags & V_DBLSCAN)
444                 return MODE_NO_DBLESCAN;
445
446         if (pMode->Clock > 400000 || pMode->Clock < 25000)
447                 return MODE_CLOCK_RANGE;
448
449         return MODE_OK;
450 }
451
452
453 static Bool
454 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
455                      DisplayModePtr adjusted_mode)
456 {
457         ErrorF("nv_output_mode_fixup is called\n");
458
459         return TRUE;
460 }
461
462 static void
463 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
464 {
465         NVOutputPrivatePtr nv_output = output->driver_private;
466         ScrnInfoPtr pScrn = output->scrn;
467         //RIVA_HW_STATE *state;
468         //NVOutputRegPtr regp, savep;
469         Bool is_fp = FALSE;
470         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
471         int i;
472
473         /* It's getting quiet here, not removing function just yet, we may still need it */
474
475         //state = &pNv->ModeReg;
476         //regp = &state->dac_reg[nv_output->preferred_output];
477
478         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
479                 is_fp = TRUE;
480
481         if (output->crtc) {
482                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
483                 int two_crt = FALSE;
484                 int two_mon = FALSE;
485
486                 for (i = 0; i < config->num_output; i++) {
487                         NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
488
489                         /* is it this output ?? */
490                         if (config->output[i] == output)
491                                 continue;
492
493                         /* it the output connected */
494                         if (config->output[i]->crtc == NULL)
495                                 continue;
496
497                         two_mon = TRUE;
498                         if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
499                                 two_crt = TRUE;
500                         }
501                 }
502
503                 ErrorF("%d: crtc %d output %d twocrt %d twomon %d\n", is_fp, nv_crtc->head, nv_output->preferred_output, two_crt, two_mon);
504         }
505 }
506
507 /* Only return if output is active (=have a crtc). */
508
509 static Bool 
510 nv_have_duallink(ScrnInfoPtr pScrn)
511 {
512         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
513         NVPtr pNv = NVPTR(pScrn);
514         int i;
515
516         for (i = 0; i < xf86_config->num_output; i++) {
517                 xf86OutputPtr output = xf86_config->output[i];
518                 NVOutputPrivatePtr nv_output = output->driver_private;
519                 if (pNv->dcb_table.entry[nv_output->dcb_entry].duallink_possible && 
520                         (pNv->dcb_table.entry[nv_output->dcb_entry].type == OUTPUT_LVDS || 
521                         pNv->dcb_table.entry[nv_output->dcb_entry].type == OUTPUT_TMDS) &&
522                         output->crtc) {
523
524                         return TRUE;
525                 }
526         }
527
528         return FALSE;
529 }
530
531 static void
532 nv_output_mode_set_routing(xf86OutputPtr output)
533 {
534         NVOutputPrivatePtr nv_output = output->driver_private;
535         xf86CrtcPtr crtc = output->crtc;
536         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
537         ScrnInfoPtr pScrn = output->scrn;
538         NVPtr pNv = NVPTR(pScrn);
539
540         uint32_t output_reg[2] = {0, 0};
541
542         /* This is for simplicity */
543         output_reg[0] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
544         output_reg[1] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
545
546         /* Some (most?) pre-NV30 cards have switchable crtc's. */
547         if (pNv->switchable_crtc) {
548                 if (!nv_have_duallink(pScrn)) { /* normal */
549                         if (nv_crtc->head == 1) {
550                                 output_reg[nv_output->preferred_output] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
551                         } else {
552                                 output_reg[(~nv_output->preferred_output) & 1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
553                         }
554                 } else { /* some dual-link stuff is strange */
555                         output_reg[0] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
556                         output_reg[1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
557
558                         /* There are some odd bits that we want to keep. */
559                         /* bit 17 and 18 for example. */
560                         output_reg[0] |= (pNv->misc_info.output[0] & (~0 << 9));
561                         output_reg[1] |= (pNv->misc_info.output[1] & (~0 << 9));
562                 }
563         }
564
565         /* The registers can't be considered seperately on most cards */
566         nvWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT, output_reg[0]);
567         nvWriteRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT, output_reg[1]);
568
569         /* This could use refinement for flatpanels, but it should work this way */
570         if (pNv->NVArch < 0x44) {
571                 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, 0xf0000000);
572                 if (pNv->Architecture == NV_ARCH_40)
573                         nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0xf0000000);
574         } else {
575                 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, 0x00100000);
576                 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0x00100000);
577         }
578 }
579
580 static void
581 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
582                    DisplayModePtr adjusted_mode)
583 {
584         ScrnInfoPtr pScrn = output->scrn;
585         NVPtr pNv = NVPTR(pScrn);
586         NVOutputPrivatePtr nv_output = output->driver_private;
587         RIVA_HW_STATE *state;
588
589         ErrorF("nv_output_mode_set is called\n");
590
591         state = &pNv->ModeReg;
592
593         nv_output_mode_set_regs(output, mode, adjusted_mode);
594         nv_output_load_state_ext(output, state, FALSE);
595         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
596                 nv_set_tmds_registers(output, adjusted_mode->Clock, FALSE, FALSE);
597
598         nv_output_mode_set_routing(output);
599 }
600
601 static xf86MonPtr
602 nv_get_edid(xf86OutputPtr output)
603 {
604         /* no use for shared DDC output */
605         NVOutputPrivatePtr nv_output = output->driver_private;
606         xf86MonPtr ddc_mon;
607
608         if (nv_output->pDDCBus == NULL)
609                 return NULL;
610
611         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
612         if (!ddc_mon)
613                 return NULL;
614
615         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
616                 goto invalid;
617
618         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
619                                 nv_output->type == OUTPUT_LVDS))
620                 goto invalid;
621
622         return ddc_mon;
623
624 invalid:
625         xfree(ddc_mon);
626         return NULL;
627 }
628
629 static Bool
630 nv_ddc_detect(xf86OutputPtr output)
631 {
632         xf86MonPtr m = nv_get_edid(output);
633
634         if (m == NULL)
635                 return FALSE;
636
637         xfree(m);
638         return TRUE;
639 }
640
641 static Bool
642 nv_crt_load_detect(xf86OutputPtr output)
643 {
644         ScrnInfoPtr pScrn = output->scrn;
645         NVOutputPrivatePtr nv_output = output->driver_private;
646         NVPtr pNv = NVPTR(pScrn);
647         CARD32 reg_output, reg_test_ctrl, temp;
648         Bool present = FALSE;
649
650         /* For some reason we get false positives on output 1, maybe due tv-out? */
651         if (nv_output->preferred_output == 1) {
652                 return FALSE;
653         }
654
655         if (nv_output->pDDCBus != NULL) {
656                 xf86MonPtr ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
657                 /* Is there a digital flatpanel on this channel? */
658                 if (ddc_mon && ddc_mon->features.input_type) {
659                         return FALSE;
660                 }
661         }
662
663         reg_output = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT);
664         reg_test_ctrl = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL);
665
666         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
667
668         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
669         usleep(1000);
670
671         temp = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT);
672         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT, temp | 1);
673
674         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_DATA, 0x94050140);
675         temp = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL);
676         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
677
678         usleep(1000);
679
680         present = (nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
681
682         temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
683         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
684
685         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT, reg_output);
686         nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
687
688         if (present) {
689                 ErrorF("A crt was detected on output %d with no ddc support\n", nv_output->preferred_output);
690                 return TRUE;
691         }
692
693         return FALSE;
694 }
695
696 static xf86OutputStatus
697 nv_tmds_output_detect(xf86OutputPtr output)
698 {
699         ErrorF("nv_tmds_output_detect is called\n");
700
701         if (nv_ddc_detect(output))
702                 return XF86OutputStatusConnected;
703
704         return XF86OutputStatusDisconnected;
705 }
706
707
708 static xf86OutputStatus
709 nv_analog_output_detect(xf86OutputPtr output)
710 {
711         ErrorF("nv_analog_output_detect is called\n");
712
713         if (nv_ddc_detect(output))
714                 return XF86OutputStatusConnected;
715
716         //if (nv_crt_load_detect(output))
717         //      return XF86OutputStatusConnected;
718
719         return XF86OutputStatusDisconnected;
720 }
721
722 static DisplayModePtr
723 nv_output_get_modes(xf86OutputPtr output)
724 {
725         NVOutputPrivatePtr nv_output = output->driver_private;
726         xf86MonPtr ddc_mon;
727         DisplayModePtr ddc_modes;
728
729         ErrorF("nv_output_get_modes is called\n");
730
731         ddc_mon = nv_get_edid(output);
732
733         xf86OutputSetEDID(output, ddc_mon);
734
735         if (ddc_mon == NULL)
736                 return NULL;
737
738         ddc_modes = xf86OutputGetEDIDModes (output);
739
740         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
741                 int i;
742                 DisplayModePtr mode;
743
744                 for (i = 0; i < 4; i++) {
745                         /* We only look at detailed timings atm */
746                         if (ddc_mon->det_mon[i].type != DT)
747                                 continue;
748                         /* Selecting only based on width ok? */
749                         if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
750                                 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
751                                 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
752                         }
753                 }
754
755                 nv_output->native_mode = NULL;
756                 if (nv_output->type == OUTPUT_TMDS) {
757                         DisplayModePtr cvtmode;
758                         /* Add a native resolution mode that is preferred */
759                         /* Reduced blanking should be fine on DVI monitor */
760                         cvtmode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
761                         cvtmode->type = M_T_DRIVER | M_T_PREFERRED;
762
763                         /* can xf86CVTMode generate invalid modes? */
764                         if (output->funcs->mode_valid(output, cvtmode) == MODE_OK) {
765                                 ddc_modes = xf86ModesAdd(ddc_modes, cvtmode);
766                                 nv_output->native_mode = cvtmode;
767                         } else
768                                 xf86DeleteMode(&cvtmode, cvtmode);
769                 }
770
771                 if (!nv_output->native_mode)
772                         for (mode = ddc_modes; mode != NULL; mode = mode->next)
773                                 if (mode->HDisplay == nv_output->fpWidth &&
774                                     mode->VDisplay == nv_output->fpHeight) {
775                                         nv_output->native_mode = mode;
776                                         break;
777                                 }
778                 if (!nv_output->native_mode) {
779                         ErrorF("Really bad stuff happening, CVT mode bad and no other native mode can be found.\n");
780                         ErrorF("Bailing out\n");
781                         return NULL;
782                 }
783
784                 /* We want the new mode to be the only preferred one */
785                 for (mode = ddc_modes; mode != NULL; mode = mode->next)
786                         if (mode->type & M_T_PREFERRED && mode != nv_output->native_mode)
787                                 mode->type &= ~M_T_PREFERRED;
788         }
789
790         return ddc_modes;
791 }
792
793 static void
794 nv_output_destroy (xf86OutputPtr output)
795 {
796         ErrorF("nv_output_destroy is called\n");
797         if (output->driver_private)
798                 xfree (output->driver_private);
799 }
800
801 static void
802 nv_output_prepare(xf86OutputPtr output)
803 {
804         ErrorF("nv_output_prepare is called\n");
805         NVOutputPrivatePtr nv_output = output->driver_private;
806         ScrnInfoPtr pScrn = output->scrn;
807         xf86CrtcPtr crtc = output->crtc;
808         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
809         NVPtr pNv = NVPTR(pScrn);
810
811         output->funcs->dpms(output, DPMSModeOff);
812
813         /* Set our output type and output routing possibilities to the right registers */
814         NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
815         NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
816 }
817
818 static void
819 nv_output_commit(xf86OutputPtr output)
820 {
821         ErrorF("nv_output_commit is called\n");
822
823         output->funcs->dpms(output, DPMSModeOn);
824 }
825
826 static const xf86OutputFuncsRec nv_analog_output_funcs = {
827     .dpms = nv_analog_output_dpms,
828     .save = nv_output_save,
829     .restore = nv_output_restore,
830     .mode_valid = nv_output_mode_valid,
831     .mode_fixup = nv_output_mode_fixup,
832     .mode_set = nv_output_mode_set,
833     .detect = nv_analog_output_detect,
834     .get_modes = nv_output_get_modes,
835     .destroy = nv_output_destroy,
836     .prepare = nv_output_prepare,
837     .commit = nv_output_commit,
838 };
839
840 #ifdef RANDR_12_INTERFACE
841 /*
842  * Several scaling modes exist, let the user choose.
843  */
844 #define SCALING_MODE_NAME "SCALING_MODE"
845 static const struct {
846         char *name;
847         enum scaling_modes mode;
848 } scaling_mode[] = {
849         { "panel", SCALE_PANEL },
850         { "fullscreen", SCALE_FULLSCREEN },
851         { "aspect", SCALE_ASPECT },
852         { "noscale", SCALE_NOSCALE },
853         { NULL, SCALE_INVALID}
854 };
855 static Atom scaling_mode_atom;
856
857 static int
858 nv_scaling_mode_lookup(char *name, int size)
859 {
860         int i;
861
862         /* for when name is zero terminated */
863         if (size < 0)
864                 size = strlen(name);
865
866         for (i = 0; scaling_mode[i].name; i++)
867                 /* We're getting non-terminated strings */
868                 if (strlen(scaling_mode[i].name) >= size &&
869                                 !strncasecmp(name, scaling_mode[i].name, size))
870                         break;
871
872         return scaling_mode[i].mode;
873 }
874
875 static void
876 nv_digital_output_create_resources(xf86OutputPtr output)
877 {
878         NVOutputPrivatePtr nv_output = output->driver_private;
879         ScrnInfoPtr pScrn = output->scrn;
880         int error, i;
881
882         /*
883          * Setup scaling mode property.
884          */
885         scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
886
887         error = RRConfigureOutputProperty(output->randr_output,
888                                         scaling_mode_atom, TRUE, FALSE, FALSE,
889                                         0, NULL);
890
891         if (error != 0) {
892                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
893                         "RRConfigureOutputProperty error, %d\n", error);
894         }
895
896         char *existing_scale_name = NULL;
897         for (i = 0; scaling_mode[i].name; i++)
898                 if (scaling_mode[i].mode == nv_output->scaling_mode)
899                         existing_scale_name = scaling_mode[i].name;
900
901         error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
902                                         XA_STRING, 8, PropModeReplace, 
903                                         strlen(existing_scale_name),
904                                         existing_scale_name, FALSE, TRUE);
905
906         if (error != 0) {
907                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
908                         "Failed to set scaling mode, %d\n", error);
909         }
910 }
911
912 static Bool
913 nv_digital_output_set_property(xf86OutputPtr output, Atom property,
914                                 RRPropertyValuePtr value)
915 {
916         NVOutputPrivatePtr nv_output = output->driver_private;
917
918         if (property == scaling_mode_atom) {
919                 int32_t ret;
920                 char *name = NULL;
921
922                 if (value->type != XA_STRING || value->format != 8)
923                         return FALSE;
924
925                 name = (char *) value->data;
926
927                 /* Match a string to a scaling mode */
928                 ret = nv_scaling_mode_lookup(name, value->size);
929                 if (ret == SCALE_INVALID)
930                         return FALSE;
931
932                 /* LVDS must always use gpu scaling. */
933                 if (ret == SCALE_PANEL && nv_output->type == OUTPUT_LVDS)
934                         return FALSE;
935
936                 nv_output->scaling_mode = ret;
937                 return TRUE;
938         }
939
940         return TRUE;
941 }
942
943 #endif /* RANDR_12_INTERFACE */
944
945 static int 
946 nv_tmds_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
947 {
948         ScrnInfoPtr pScrn = output->scrn;
949         NVPtr pNv = NVPTR(pScrn);
950         NVOutputPrivatePtr nv_output = output->driver_private;
951
952         /* We can't exceed the native mode.*/
953         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
954                 return MODE_PANEL;
955
956         if (pNv->dcb_table.entry[nv_output->dcb_entry].duallink_possible) {
957                 if (pMode->Clock > 330000) /* 2x165 MHz */
958                         return MODE_CLOCK_RANGE;
959         } else {
960                 if (pMode->Clock > 165000) /* 165 MHz */
961                         return MODE_CLOCK_RANGE;
962         }
963
964         return nv_output_mode_valid(output, pMode);
965 }
966
967 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
968         .dpms = nv_tmds_output_dpms,
969         .save = nv_output_save,
970         .restore = nv_output_restore,
971         .mode_valid = nv_tmds_output_mode_valid,
972         .mode_fixup = nv_output_mode_fixup,
973         .mode_set = nv_output_mode_set,
974         .detect = nv_tmds_output_detect,
975         .get_modes = nv_output_get_modes,
976         .destroy = nv_output_destroy,
977         .prepare = nv_output_prepare,
978         .commit = nv_output_commit,
979 #ifdef RANDR_12_INTERFACE
980         .create_resources = nv_digital_output_create_resources,
981         .set_property = nv_digital_output_set_property,
982 #endif /* RANDR_12_INTERFACE */
983 };
984
985 static int nv_lvds_output_mode_valid
986 (xf86OutputPtr output, DisplayModePtr pMode)
987 {
988         NVOutputPrivatePtr nv_output = output->driver_private;
989
990         /* No modes > panel's native res */
991         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
992                 return MODE_PANEL;
993
994         return nv_output_mode_valid(output, pMode);
995 }
996
997 static xf86OutputStatus
998 nv_lvds_output_detect(xf86OutputPtr output)
999 {
1000         ScrnInfoPtr pScrn = output->scrn;
1001         NVPtr pNv = NVPTR(pScrn);
1002         NVOutputPrivatePtr nv_output = output->driver_private;
1003
1004         if (pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode &&
1005             pNv->VBIOS.fp.native_mode)
1006                 return XF86OutputStatusConnected;
1007         if (nv_ddc_detect(output))
1008                 return XF86OutputStatusConnected;
1009
1010         return XF86OutputStatusDisconnected;
1011 }
1012
1013 static DisplayModePtr
1014 nv_lvds_output_get_modes(xf86OutputPtr output)
1015 {
1016         ScrnInfoPtr pScrn = output->scrn;
1017         NVPtr pNv = NVPTR(pScrn);
1018         NVOutputPrivatePtr nv_output = output->driver_private;
1019         DisplayModePtr modes;
1020
1021         if ((modes = nv_output_get_modes(output)))
1022                 return modes;
1023
1024         /* it is possible to set up a mode from what we can read from the
1025          * RAMDAC registers, but if we can't read the BIOS table correctly
1026          * we might as well give up */
1027         if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode ||
1028             (pNv->VBIOS.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->VBIOS.fp.native_mode->HDisplay != nv_output->fpWidth ||
1036                 pNv->VBIOS.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->VBIOS.fp.native_mode->HDisplay;
1040                 nv_output->fpHeight = pNv->VBIOS.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->VBIOS.fp.native_mode);
1047
1048         return xf86DuplicateMode(pNv->VBIOS.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 #ifdef RANDR_12_INTERFACE
1064         .create_resources = nv_digital_output_create_resources,
1065         .set_property = nv_digital_output_set_property,
1066 #endif /* RANDR_12_INTERFACE */
1067 };
1068
1069 static void nv_add_analog_output(ScrnInfoPtr pScrn, int dcb_entry, Bool dvi_pair)
1070 {
1071         NVPtr pNv = NVPTR(pScrn);
1072         xf86OutputPtr       output;
1073         NVOutputPrivatePtr    nv_output;
1074         char outputname[20];
1075         Bool create_output = TRUE;
1076         int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1077
1078         /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1079         if (dvi_pair) {
1080                 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1081                 pNv->dvi_a_count++;
1082         } else {
1083                 sprintf(outputname, "VGA-%d", pNv->vga_count);
1084                 pNv->vga_count++;
1085         }
1086
1087         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1088         if (!nv_output) {
1089                 return;
1090         }
1091
1092         nv_output->dcb_entry = dcb_entry;
1093
1094         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1095                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1096
1097         nv_output->type = OUTPUT_ANALOG;
1098
1099         /* output route:
1100          * bit0: OUTPUT_0 valid
1101          * bit1: OUTPUT_1 valid
1102          * So lowest order has highest priority.
1103          * Below is guesswork:
1104          * bit2: All outputs valid
1105          */
1106         /* This also facilitates proper output routing for dvi */
1107         /* See sel_clk assignment in nv_crtc.c */
1108         if (ffs(pNv->dcb_table.entry[dcb_entry].or) & OUTPUT_1) {
1109                 nv_output->preferred_output = 1;
1110         } else {
1111                 nv_output->preferred_output = 0;
1112         }
1113
1114         nv_output->bus = pNv->dcb_table.entry[dcb_entry].bus;
1115
1116         if (!create_output) {
1117                 xfree(nv_output);
1118                 return;
1119         }
1120
1121         /* Delay creation of output until we actually know we want it */
1122         output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1123         if (!output)
1124                 return;
1125
1126         output->driver_private = nv_output;
1127
1128         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1129
1130         if (pNv->switchable_crtc) {
1131                 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1132         } else {
1133                 output->possible_crtcs = (1 << nv_output->preferred_output);
1134         }
1135
1136         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1137 }
1138
1139 static void nv_add_digital_output(ScrnInfoPtr pScrn, int dcb_entry, int lvds)
1140 {
1141         NVPtr pNv = NVPTR(pScrn);
1142         xf86OutputPtr       output;
1143         NVOutputPrivatePtr    nv_output;
1144         char outputname[20];
1145         Bool create_output = TRUE;
1146         int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1147
1148         if (lvds) {
1149                 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1150                 pNv->lvds_count++;
1151         } else {
1152                 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1153                 pNv->dvi_d_count++;
1154         }
1155
1156         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1157
1158         if (!nv_output) {
1159                 return;
1160         }
1161
1162         nv_output->dcb_entry = dcb_entry;
1163
1164         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1165                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1166
1167         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1168
1169         /* output route:
1170          * bit0: OUTPUT_0 valid
1171          * bit1: OUTPUT_1 valid
1172          * So lowest order has highest priority.
1173          * Below is guesswork:
1174          * bit2: All outputs valid
1175          */
1176         /* This also facilitates proper output routing for dvi */
1177         /* See sel_clk assignment in nv_crtc.c */
1178         if (ffs(pNv->dcb_table.entry[dcb_entry].or) & OUTPUT_1) {
1179                 nv_output->preferred_output = 1;
1180         } else {
1181                 nv_output->preferred_output = 0;
1182         }
1183
1184         nv_output->bus = pNv->dcb_table.entry[dcb_entry].bus;
1185
1186         if (lvds) {
1187                 nv_output->type = OUTPUT_LVDS;
1188                 /* comment below two lines to test LVDS under RandR12.
1189                  * If your screen "blooms" or "bleeds" (i.e. has a developing
1190                  * white / psychedelic pattern) then KILL X IMMEDIATELY
1191                  * (ctrl+alt+backspace) & if the effect continues reset power */
1192                 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1193                 create_output = FALSE;
1194         } else {
1195                 nv_output->type = OUTPUT_TMDS;
1196         }
1197
1198         if (!create_output) {
1199                 xfree(nv_output);
1200                 return;
1201         }
1202
1203         /* Delay creation of output until we are certain is desirable */
1204         if (lvds)
1205                 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1206         else
1207                 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1208         if (!output)
1209                 return;
1210
1211         output->driver_private = nv_output;
1212
1213         if (pNv->fpScaler) /* GPU Scaling */
1214                 nv_output->scaling_mode = SCALE_ASPECT;
1215         else /* Panel scaling */
1216                 nv_output->scaling_mode = SCALE_PANEL;
1217
1218 #ifdef RANDR_12_INTERFACE
1219         if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
1220                 nv_output->scaling_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
1221                 if (nv_output->scaling_mode == SCALE_INVALID)
1222                         nv_output->scaling_mode = SCALE_ASPECT; /* default */
1223         }
1224 #endif /* RANDR_12_INTERFACE */
1225
1226         /* Due to serious problems we have to restrict the crtc's for certain types of outputs. */
1227         /* This is a result of problems with G70 cards that have a dvi with ffs(or) == 1 */
1228         /* Anyone know what the solution for this is? */
1229         if (nv_output->preferred_output == 0) {
1230                 output->possible_crtcs = (1 << 0);
1231         } else {
1232                 if (pNv->switchable_crtc) {
1233                         output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1234                 } else {
1235                         output->possible_crtcs = (1 << nv_output->preferred_output);
1236                 }
1237         }
1238
1239         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1240 }
1241
1242 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1243 {
1244         NVPtr pNv = NVPTR(pScrn);
1245         int i, type, i2c_count[0xf];
1246
1247         pNv->switchable_crtc = FALSE;
1248         /* I was wrong, again. */
1249         if (pNv->NVArch > 0x11 && pNv->twoHeads)
1250                 pNv->switchable_crtc = TRUE;
1251
1252         memset(i2c_count, 0, sizeof(i2c_count));
1253         for (i = 0 ; i < pNv->dcb_table.entries; i++)
1254                 i2c_count[pNv->dcb_table.entry[i].i2c_index]++;
1255
1256         /* we setup the outputs up from the BIOS table */
1257         for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1258                 type = pNv->dcb_table.entry[i].type;
1259                 if (type > 3) {
1260                         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1261                         continue;
1262                 }
1263
1264                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry %d: type: %d, i2c_index: %d, heads: %d, bus: %d, or: %d\n", i, type, pNv->dcb_table.entry[i].i2c_index, pNv->dcb_table.entry[i].heads, pNv->dcb_table.entry[i].bus, pNv->dcb_table.entry[i].or);
1265
1266                 switch(type) {
1267                 case OUTPUT_ANALOG:
1268                         nv_add_analog_output(pScrn, i, (i2c_count[pNv->dcb_table.entry[i].i2c_index] > 1));
1269                         break;
1270                 case OUTPUT_TMDS:
1271                         nv_add_digital_output(pScrn, i, 0);
1272                         break;
1273                 case OUTPUT_LVDS:
1274                         nv_add_digital_output(pScrn, i, 1);
1275                         break;
1276                 default:
1277                         break;
1278                 }
1279         }
1280 }
1281
1282 void NvSetupOutputs(ScrnInfoPtr pScrn)
1283 {
1284         NVPtr pNv = NVPTR(pScrn);
1285
1286         pNv->Television = FALSE;
1287
1288         memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1289         NvDCBSetupOutputs(pScrn);
1290 }
1291
1292 /*************************************************************************** \
1293 |*                                                                           *|
1294 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1295 |*                                                                           *|
1296 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1297 |*     international laws.  Users and possessors of this source code are     *|
1298 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1299 |*     use this code in individual and commercial software.                  *|
1300 |*                                                                           *|
1301 |*     Any use of this source code must include,  in the user documenta-     *|
1302 |*     tion and  internal comments to the code,  notices to the end user     *|
1303 |*     as follows:                                                           *|
1304 |*                                                                           *|
1305 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1306 |*                                                                           *|
1307 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1308 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1309 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1310 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1311 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1312 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1313 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1314 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1315 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1316 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1317 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1318 |*                                                                           *|
1319 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1320 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1321 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1322 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1323 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1324 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1325 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1326 |*     all U.S. Government End Users  acquire the source code  with only     *|
1327 |*     those rights set forth herein.                                        *|
1328 |*                                                                           *|
1329  \***************************************************************************/