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