randr12: refactor dcb usage
[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_ramdac, 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_ramdac, 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_ramdac, 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_ramdac, tmds_reg);
155 }
156
157 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
158 {
159     NVOutputPrivatePtr nv_output = output->driver_private;
160     ScrnInfoPtr pScrn = output->scrn;
161     NVPtr pNv = NVPTR(pScrn);
162
163     nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
164 }
165
166 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
167 {
168     NVOutputPrivatePtr nv_output = output->driver_private;
169     ScrnInfoPtr pScrn = output->scrn;
170     NVPtr pNv = NVPTR(pScrn);
171
172     return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
173 }
174
175 static void nv_output_backlight_enable(xf86OutputPtr output,  Bool on)
176 {
177         ScrnInfoPtr pScrn = output->scrn;
178         NVPtr pNv = NVPTR(pScrn);
179
180         ErrorF("nv_output_backlight_enable is called for output %s to turn %s\n", output->name, on ? "on" : "off");
181
182         /* This is done differently on each laptop.  Here we
183          * define the ones we know for sure. */
184
185 #if defined(__powerpc__)
186         if ((pNv->Chipset == 0x10DE0179) ||
187             (pNv->Chipset == 0x10DE0189) ||
188             (pNv->Chipset == 0x10DE0329)) {
189                 /* NV17,18,34 Apple iMac, iBook, PowerBook */
190                 CARD32 tmp_pmc, tmp_pcrt;
191                 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
192                 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
193                 if (on) {
194                         tmp_pmc |= (1 << 31);
195                         tmp_pcrt |= 0x1;
196                 }
197                 nvWriteMC(pNv, 0x10F0, tmp_pmc);
198                 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
199         }
200 #endif
201
202         if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
203                 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
204 }
205
206 static void dpms_update_output_ramdac(NVPtr pNv, int ramdac, int mode)
207 {
208         if (ramdac == -1)
209                 return;
210
211         /* We may be going for modesetting, so we must reset the ramdacs */
212         if (mode == DPMSModeOff) {
213                 pNv->ramdac_active[ramdac] = FALSE;
214                 ErrorF("Deactivating ramdac %d\n", ramdac);
215                 return;
216         }
217
218         /* The previous call was not a modeset, but a normal dpms call */
219         pNv->ramdac_active[ramdac] = TRUE;
220         ErrorF("Activating ramdac %d\n", ramdac);
221 }
222
223 static void
224 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
225 {
226         NVOutputPrivatePtr nv_output = output->driver_private;
227         NVPtr pNv = NVPTR(output->scrn);
228
229         dpms_update_output_ramdac(pNv, nv_output->ramdac, mode);
230
231         switch (mode) {
232         case DPMSModeStandby:
233         case DPMSModeSuspend:
234         case DPMSModeOff:
235                 nv_output_backlight_enable(output, 0);
236                 break;
237         case DPMSModeOn:
238                 nv_output_backlight_enable(output, 1);
239         default:
240                 break;
241         }
242 }
243
244 static void
245 nv_analog_output_dpms(xf86OutputPtr output, int mode)
246 {
247         xf86CrtcPtr crtc = output->crtc;
248         NVOutputPrivatePtr nv_output = output->driver_private;
249         NVPtr pNv = NVPTR(output->scrn);
250
251         ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
252
253         dpms_update_output_ramdac(pNv, nv_output->ramdac, mode);
254
255         if (crtc) {
256                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
257
258                 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
259         }
260 }
261
262 static void
263 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
264 {
265         xf86CrtcPtr crtc = output->crtc;
266         NVOutputPrivatePtr nv_output = output->driver_private;
267         NVPtr pNv = NVPTR(output->scrn);
268
269         ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
270
271         dpms_update_output_ramdac(pNv, nv_output->ramdac, mode);
272
273         /* Are we assigned a ramdac already?, else we will be activated during mode set */
274         if (crtc && nv_output->ramdac != -1) {
275                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
276
277                 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
278
279                 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
280                 switch(mode) {
281                         case DPMSModeStandby:
282                         case DPMSModeSuspend:
283                         case DPMSModeOff:
284                                 /* cut the TMDS output */           
285                                 fpcontrol |= 0x20000022;
286                                 break;
287                         case DPMSModeOn:
288                                 /* disable cutting the TMDS output */
289                                 fpcontrol &= ~0x20000022;
290                                 break;
291                 }
292                 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
293         }
294 }
295
296 /* This sequence is an optimized/shortened version of what the blob does */
297 /* 0x40 and 0x43 are dual link dvi/lvds related, so don't touch them for now */
298 uint32_t tmds_regs_nv40[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, /* 0x40, 0x43,*/ 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a, 0x2b };
299 uint32_t tmds_regs_nv30[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x29, 0x2a, 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a, 0x2b };
300
301 #define TMDS_REGS(index) ( tmds_regs(pNv, index) )
302
303 uint32_t tmds_regs(NVPtr pNv, int i)
304 {
305         if (pNv->Architecture == NV_ARCH_40) {
306                 return tmds_regs_nv40[i];
307         } else {
308                 return tmds_regs_nv30[i];
309         }
310 }
311
312 #define TMDS_SIZE ( tmds_size(pNv) )
313
314 uint32_t tmds_size(NVPtr pNv)
315 {
316         if (pNv->Architecture == NV_ARCH_40) {
317                 return(sizeof(tmds_regs_nv40)/sizeof(tmds_regs_nv40[0]));
318         } else {
319                 return(sizeof(tmds_regs_nv30)/sizeof(tmds_regs_nv30[0]));
320         }
321 }
322
323 /* Does anyone know the precise purpose of this second register set? */
324 uint32_t tmds2_regs_nv40[] = { 0x2b };
325 uint32_t tmds2_regs_nv30[] = { 0x2b };
326
327 #define TMDS2_REGS(index) ( tmds2_regs(pNv, index) )
328
329 uint32_t tmds2_regs(NVPtr pNv, int i)
330 {
331         if (pNv->Architecture == NV_ARCH_40) {
332                 return tmds2_regs_nv40[i];
333         } else {
334                 return tmds2_regs_nv30[i];
335         }
336 }
337
338 #define TMDS2_SIZE ( tmds2_size(pNv) )
339
340 uint32_t tmds2_size(NVPtr pNv)
341 {
342         if (pNv->Architecture == NV_ARCH_40) {
343                 return(sizeof(tmds2_regs_nv40)/sizeof(tmds2_regs_nv40[0]));
344         } else {
345                 return(sizeof(tmds2_regs_nv30)/sizeof(tmds2_regs_nv30[0]));
346         }
347 }
348
349 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
350 {
351         NVOutputPrivatePtr nv_output = output->driver_private;
352         ScrnInfoPtr pScrn = output->scrn;
353         NVPtr pNv = NVPTR(pScrn);
354         NVOutputRegPtr regp;
355         int i;
356
357         regp = &state->dac_reg[nv_output->ramdac];
358         state->config       = nvReadFB(pNv, NV_PFB_CFG0);
359
360         /* This exists purely for proper text mode restore */
361         if (override) regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
362
363         for (i = 0; i < TMDS_SIZE; i++) {
364                 regp->TMDS[TMDS_REGS(i)] = NVOutputReadTMDS(output, TMDS_REGS(i));
365         }
366
367         /* If the data ever changes between TMDS and TMDS2, then regp data needs a new set */
368         /* TMDS2 is related to dual link dvi/lvds, leave it untouched for the moment */
369         //for (i = 0; i < TMDS2_SIZE; i++) {
370         //      regp->TMDS[TMDS2_REGS(i)] = NVOutputReadTMDS2(output, TMDS2_REGS(i));
371         //}
372 }
373
374 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
375 {
376         NVOutputPrivatePtr nv_output = output->driver_private;
377         NVOutputRegPtr regp;
378         ScrnInfoPtr pScrn = output->scrn;
379         NVPtr pNv = NVPTR(pScrn);
380         int i;
381
382         regp = &state->dac_reg[nv_output->ramdac];
383
384         /* This exists purely for proper text mode restore */
385         if (override) NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
386
387         for (i = 0; i < TMDS_SIZE; i++) {
388                 NVOutputWriteTMDS(output, TMDS_REGS(i), regp->TMDS[TMDS_REGS(i)]);
389         }
390
391         /* If the data ever changes between TMDS and TMDS2, then regp data needs a new set */
392         /* TMDS2 is related to dual link dvi/lvds, leave it untouched for the moment */
393         //for (i = 0; i < TMDS2_SIZE; i++) {
394         //      NVOutputWriteTMDS(output, TMDS2_REGS(i), regp->TMDS[TMDS2_REGS(i)]);
395         //}
396 }
397
398 /* NOTE: Don't rely on this data for anything other than restoring VT's */
399
400 static void
401 nv_output_save (xf86OutputPtr output)
402 {
403         ScrnInfoPtr     pScrn = output->scrn;
404         NVPtr pNv = NVPTR(pScrn);
405         RIVA_HW_STATE *state;
406         NVOutputPrivatePtr nv_output = output->driver_private;
407         int ramdac_backup = nv_output->ramdac;
408
409         ErrorF("nv_output_save is called\n");
410
411         /* This is early init and we have not yet been assigned a ramdac */
412         /* Always choose the prefered ramdac, for consistentcy */
413         /* Assumption: there is always once output that can only run of the primary ramdac */
414         if (nv_output->valid_ramdac & RAMDAC_1) {
415                 nv_output->ramdac = 1;
416         } else {
417                 nv_output->ramdac = 0;
418         }
419
420         state = &pNv->SavedReg;
421
422         /* Due to strange mapping of outputs we could have swapped analog and digital */
423         /* So we force save all the registers */
424         nv_output_save_state_ext(output, state, TRUE);
425
426         /* restore previous state */
427         nv_output->ramdac = ramdac_backup;
428 }
429
430 static void
431 nv_output_restore (xf86OutputPtr output)
432 {
433         ScrnInfoPtr pScrn = output->scrn;
434         NVPtr pNv = NVPTR(pScrn);
435         RIVA_HW_STATE *state;
436         NVOutputPrivatePtr nv_output = output->driver_private;
437         int ramdac_backup = nv_output->ramdac;
438
439         ErrorF("nv_output_restore is called\n");
440
441         /* We want consistent mode restoring and the ramdac entry is variable */
442         /* Always choose the prefered ramdac, for consistentcy */
443         /* Assumption: there is always once output that can only run of the primary ramdac */
444         if (nv_output->valid_ramdac & RAMDAC_1) {
445                 nv_output->ramdac = 1;
446         } else {
447                 nv_output->ramdac = 0;
448         }
449
450         state = &pNv->SavedReg;
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         /* restore previous state */
457         nv_output->ramdac = ramdac_backup;
458 }
459
460 static int
461 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
462 {
463         if (pMode->Flags & V_DBLSCAN)
464                 return MODE_NO_DBLESCAN;
465
466         if (pMode->Clock > 400000 || pMode->Clock < 25000)
467                 return MODE_CLOCK_RANGE;
468
469         return MODE_OK;
470 }
471
472
473 static Bool
474 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
475                      DisplayModePtr adjusted_mode)
476 {
477         ErrorF("nv_output_mode_fixup is called\n");
478
479         return TRUE;
480 }
481
482 static void
483 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
484 {
485         NVOutputPrivatePtr nv_output = output->driver_private;
486         ScrnInfoPtr pScrn = output->scrn;
487         NVPtr pNv = NVPTR(pScrn);
488         RIVA_HW_STATE *state, *sv_state;
489         Bool is_fp = FALSE;
490         Bool is_lvds = FALSE;
491         NVOutputRegPtr regp, regp2, savep;
492         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
493         int i;
494
495         xf86CrtcPtr crtc = output->crtc;
496         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
497
498         state = &pNv->ModeReg;
499         regp = &state->dac_reg[nv_output->ramdac];
500         /* The other ramdac */
501         regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
502
503         sv_state = &pNv->SavedReg;
504         savep = &sv_state->dac_reg[nv_output->ramdac];
505
506         if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
507                 is_fp = TRUE;
508                 if (nv_output->type == OUTPUT_LVDS) {
509                         is_lvds = TRUE;
510                 }
511         }
512
513         /* This is just a guess, there are probably more registers which need setting */
514         /* But we must start somewhere ;-) */
515         if (is_fp) {
516                 regp->TMDS[0x4] = 0x80;
517                 /* Enable crosswired mode */
518                 /* This will upset the monitor, trust me, i know it :-( */
519                 /* Now allowed for non-bios inited systems */
520                 //if (nv_output->ramdac != nv_output->preferred_ramdac) {
521                 if (nv_crtc->head != nv_output->preferred_ramdac) {
522                         regp->TMDS[0x4] |= (1 << 3);
523                 }
524
525                 if (is_lvds) {
526                         regp->TMDS[0x4] |= (1 << 0);
527                 }
528         }
529
530         /* The TMDS game begins */
531         /* A few registers are also programmed on non-tmds monitors */
532         /* At the moment i can't give rationale for these values */
533         if (!is_fp) {
534                 regp->TMDS[0x2b] = 0x7d;
535         } else {
536                 uint32_t pll_setup_control = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SETUP_CONTROL);
537                 regp->TMDS[0x2b] = 0x7d;
538                 regp->TMDS[0x2c] = 0x0;
539                 /* Various combinations exist for lvds, 0x08, 0x48, 0xc8, 0x88 */
540                 /* 0x88 seems most popular and (maybe) the end setting */
541                 if (is_lvds) {
542                         if (pNv->Architecture == NV_ARCH_40) {
543                                 regp->TMDS[0x2e] = 0x88;
544                         } else {
545                                 /* observed on nv31m */
546                                 regp->TMDS[0x2e] = 0x0;
547                         }
548                 } else {
549                         /* 0x81 is also observed, but it's much rarer */
550                         regp->TMDS[0x2e] = 0x85;
551                 }
552                 /* 0x08 is also seen for lvds */
553                 regp->TMDS[0x2f] = 0x21;
554                 regp->TMDS[0x30] = 0x0;
555                 regp->TMDS[0x31] = 0x0;
556                 regp->TMDS[0x32] = 0x0;
557                 regp->TMDS[0x33] = 0xf0;
558                 regp->TMDS[0x3a] = 0x0;
559
560                 /* Sometimes 0x68 is also used */
561                 regp->TMDS[0x5] = 0x6e;
562
563                 if (is_lvds) {
564                         if (pNv->Architecture == NV_ARCH_40) {
565                                 regp->TMDS[0x0] = 0x60;
566                         } else {
567                                 /* observed on a nv31m */
568                                 regp->TMDS[0x0] = 0x70;
569                         }
570                 } else {
571                         /* This seems to be related to PLL_SETUP_CONTROL */
572                         /* When PLL_SETUP_CONTROL ends with 0x1c, then this value is 0xcX */
573                         /* Otherwise 0xfX */
574                         if ((pll_setup_control & 0xff) == 0x1c) {
575                                 regp->TMDS[0x0] = 0xc0;
576                         } else {
577                                 regp->TMDS[0x0] = 0xf0;
578                         }
579                 }
580
581                 /* Not a 100% sure if this is not crtc determined */
582                 if (nv_output->preferred_ramdac != nv_output->ramdac) {
583                         regp->TMDS[0x0] |= 0xa;
584                 } else {
585                         regp->TMDS[0x0] |= 0x1;
586                 }
587
588                 if (pll_setup_control == 0) {
589                         regp->TMDS[0x1] = 0x0;
590                 } else {
591                         /* Also seen: 0x47, what does this register do? */
592                         if (nv_output->ramdac != nv_output->preferred_ramdac) {
593                                 regp->TMDS[0x1] = 0x42;
594                         } else {
595                                 regp->TMDS[0x1] = 0x41;
596                         }
597                 }
598
599                 if (is_lvds) {
600                         regp->TMDS[0x2] = 0x0;
601                 } else if (pll_setup_control == 0) {
602                         regp->TMDS[0x2] = 0x90;
603                 } else {
604                         if (nv_output->preferred_ramdac == 1) { /* This is the "output" */
605                                 regp->TMDS[0x2] = 0xa9;
606                         } else {
607                                 regp->TMDS[0x2] = 0x89;
608                         }
609                 }
610
611                 /* I assume they are zero for !is_lvds */
612                 if (is_lvds && pNv->Architecture == NV_ARCH_40) {
613                         /* Observed values are 0x11 and 0x14, TODO: this needs refinement */
614                         regp->TMDS[0x40] = 0x14;
615                         regp->TMDS[0x43] = 0xb0;
616                 }
617         }
618
619         if (output->crtc) {
620                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
621                 int two_crt = FALSE;
622                 int two_mon = FALSE;
623
624                 for (i = 0; i < config->num_output; i++) {
625                         NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
626
627                         /* is it this output ?? */
628                         if (config->output[i] == output)
629                                 continue;
630
631                         /* it the output connected */
632                         if (config->output[i]->crtc == NULL)
633                                 continue;
634
635                         two_mon = TRUE;
636                         if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
637                                 two_crt = TRUE;
638                         }
639                 }
640
641                 ErrorF("%d: crtc %d ramdac %d twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->ramdac, two_crt, two_mon);
642         }
643 }
644
645 static void
646 nv_output_mode_set_routing(xf86OutputPtr output)
647 {
648         NVOutputPrivatePtr nv_output = output->driver_private;
649         xf86CrtcPtr crtc = output->crtc;
650         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
651         ScrnInfoPtr     pScrn = output->scrn;
652         NVPtr pNv = NVPTR(pScrn);
653         Bool is_fp = FALSE;
654
655         uint32_t output_reg[2];
656
657         if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
658                 is_fp = TRUE;
659         }
660
661         if (pNv->Architecture == NV_ARCH_40) {
662                 /* NV4x cards have strange ways of dealing with dualhead */
663                 /* Also see reg594 in nv_crtc.c */
664                 output_reg[0] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
665                 /* So far only dual dvi cards(or lvds + dvi i think) seem to use (and need?) this */
666                 if (pNv->dual_dvi)
667                         output_reg[1] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
668         } else {
669                 if (!is_fp) {
670                         output_reg[nv_output->preferred_ramdac] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
671                 } else { 
672                         output_reg[nv_output->preferred_ramdac] = 0x0;
673                 }
674         }
675
676         /* Only one can be on crtc1 */
677         if (nv_crtc->head == 1) {
678                 output_reg[nv_output->preferred_ramdac] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
679         } else {
680                 output_reg[(~nv_output->preferred_ramdac) & 1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
681         }
682
683         if (pNv->Architecture == NV_ARCH_40) {
684                 /* The registers can't be considered seperately on nv40 */
685                 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT, output_reg[0]);
686                 nvWriteRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT, output_reg[1]);
687         } else {
688                 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT, output_reg[nv_output->preferred_ramdac]);
689         }
690
691         /* This could use refinement for flatpanels, but it should work this way */
692         if (pNv->NVArch < 0x44) {
693                 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, 0xf0000000);
694                 if (pNv->Architecture == NV_ARCH_40)
695                         nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0xf0000000);
696         } else {
697                 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, 0x00100000);
698                 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0x00100000);
699         }
700 }
701
702 static void
703 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
704                    DisplayModePtr adjusted_mode)
705 {
706     ScrnInfoPtr pScrn = output->scrn;
707     NVPtr pNv = NVPTR(pScrn);
708     RIVA_HW_STATE *state;
709
710         ErrorF("nv_output_mode_set is called\n");
711
712     state = &pNv->ModeReg;
713
714     nv_output_mode_set_regs(output, mode, adjusted_mode);
715     nv_output_load_state_ext(output, state, FALSE);
716         nv_output_mode_set_routing(output);
717 }
718
719 static xf86MonPtr
720 nv_get_edid(xf86OutputPtr output)
721 {
722         /* no use for shared DDC output */
723         NVOutputPrivatePtr nv_output = output->driver_private;
724         xf86MonPtr ddc_mon;
725
726         if (nv_output->pDDCBus == NULL)
727                 return NULL;
728
729         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
730         if (!ddc_mon)
731                 return NULL;
732
733         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
734                 goto invalid;
735
736         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
737                                 nv_output->type == OUTPUT_LVDS))
738                 goto invalid;
739
740         return ddc_mon;
741
742 invalid:
743         xfree(ddc_mon);
744         return NULL;
745 }
746
747 static Bool
748 nv_ddc_detect(xf86OutputPtr output)
749 {
750         xf86MonPtr m = nv_get_edid(output);
751
752         if (m == NULL)
753                 return FALSE;
754
755         xfree(m);
756         return TRUE;
757 }
758
759 static Bool
760 nv_crt_load_detect(xf86OutputPtr output)
761 {
762         ScrnInfoPtr pScrn = output->scrn;
763         NVOutputPrivatePtr nv_output = output->driver_private;
764         NVPtr pNv = NVPTR(pScrn);
765         CARD32 reg_output, reg_test_ctrl, temp;
766         Bool present = FALSE;
767         int ramdac;
768
769         /* Usually these outputs are native to ramdac 1 */
770         if (nv_output->valid_ramdac & RAMDAC_0 && nv_output->valid_ramdac & RAMDAC_1) {
771                 ramdac = 1;
772         } else if (nv_output->valid_ramdac & RAMDAC_1) {
773                 ramdac = 1;
774         } else if (nv_output->valid_ramdac & RAMDAC_0) {
775                 ramdac = 0;
776         } else {
777                 return FALSE;
778         }
779
780         /* For some reason we get false positives on ramdac 1, maybe due tv-out? */
781         if (ramdac == 1) {
782                 return FALSE;
783         }
784
785         if (nv_output->pDDCBus != NULL) {
786                 xf86MonPtr ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
787                 /* Is there a digital flatpanel on this channel? */
788                 if (ddc_mon && ddc_mon->features.input_type) {
789                         return FALSE;
790                 }
791         }
792
793         reg_output = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
794         reg_test_ctrl = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
795
796         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
797
798         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
799         usleep(1000);
800
801         temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
802         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, temp | 1);
803
804         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
805         temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
806         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
807
808         usleep(1000);
809
810         present = (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
811
812         temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
813         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
814
815         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, reg_output);
816         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
817
818         if (present) {
819                 ErrorF("A crt was detected on ramdac %d with no ddc support\n", ramdac);
820                 return TRUE;
821         }
822
823         return FALSE;
824 }
825
826 static xf86OutputStatus
827 nv_tmds_output_detect(xf86OutputPtr output)
828 {
829         ErrorF("nv_tmds_output_detect is called\n");
830
831         if (nv_ddc_detect(output))
832                 return XF86OutputStatusConnected;
833
834         return XF86OutputStatusDisconnected;
835 }
836
837
838 static xf86OutputStatus
839 nv_analog_output_detect(xf86OutputPtr output)
840 {
841         ErrorF("nv_analog_output_detect is called\n");
842
843         if (nv_ddc_detect(output))
844                 return XF86OutputStatusConnected;
845
846         if (nv_crt_load_detect(output))
847                 return XF86OutputStatusConnected;
848
849         return XF86OutputStatusDisconnected;
850 }
851
852 static DisplayModePtr
853 nv_output_get_modes(xf86OutputPtr output)
854 {
855         NVOutputPrivatePtr nv_output = output->driver_private;
856         xf86MonPtr ddc_mon;
857         DisplayModePtr ddc_modes;
858
859         ErrorF("nv_output_get_modes is called\n");
860
861         ddc_mon = nv_get_edid(output);
862
863         xf86OutputSetEDID(output, ddc_mon);
864
865         if (ddc_mon == NULL)
866                 return NULL;
867
868         ddc_modes = xf86OutputGetEDIDModes (output);
869
870         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
871                 int i;
872                 DisplayModePtr mode;
873
874                 for (i = 0; i < 4; i++) {
875                         /* We only look at detailed timings atm */
876                         if (ddc_mon->det_mon[i].type != DT)
877                                 continue;
878                         /* Selecting only based on width ok? */
879                         if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
880                                 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
881                                 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
882                         }
883                 }
884
885                 /* Add a native resolution mode that is preferred */
886                 /* Reduced blanking should be fine on DVI monitor */
887                 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
888                 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
889                 /* We want the new mode to be preferred */
890                 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
891                         if (mode->type & M_T_PREFERRED) {
892                                 mode->type &= ~M_T_PREFERRED;
893                         }
894                 }
895                 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
896         }
897
898         return ddc_modes;
899 }
900
901 static void
902 nv_output_destroy (xf86OutputPtr output)
903 {
904         ErrorF("nv_output_destroy is called\n");
905         if (output->driver_private)
906                 xfree (output->driver_private);
907 }
908
909 static xf86OutputPtr
910 nv_find_output_and_clear_ramdac_from_outputs(xf86OutputPtr output, int ramdac)
911 {
912         int i;
913         ScrnInfoPtr pScrn = output->scrn;
914         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
915         xf86OutputPtr output2 = NULL;
916         NVOutputPrivatePtr nv_output2;
917         for (i = 0; i < xf86_config->num_output; i++) {
918                 output2 = xf86_config->output[i];
919                 nv_output2 = output2->driver_private;
920                 if (nv_output2->ramdac == ramdac && output != output2) {
921                         nv_output2->ramdac = -1;
922                         break;
923                 }
924         }
925
926         return output2;
927 }
928
929 static void
930 nv_output_prepare(xf86OutputPtr output)
931 {
932         ErrorF("nv_output_prepare is called\n");
933         NVOutputPrivatePtr nv_output = output->driver_private;
934         ScrnInfoPtr pScrn = output->scrn;
935         NVPtr pNv = NVPTR(pScrn);
936         Bool stole_ramdac = FALSE;
937         xf86OutputPtr output2 = NULL;
938         int ramdac;
939
940         output->funcs->dpms(output, DPMSModeOff);
941
942         /* We need ramdac 0, so let's steal it */
943         if (!(nv_output->valid_ramdac & RAMDAC_1) && pNv->ramdac_active[0]) {
944                 ErrorF("Stealing ramdac0 ;-)\n");
945                 output2 = nv_find_output_and_clear_ramdac_from_outputs(output, 0);
946                 pNv->ramdac_active[0] = FALSE;
947                 stole_ramdac = TRUE;
948         }
949
950         /* We need ramdac 1, so let's steal it */
951         if (!(nv_output->valid_ramdac & RAMDAC_0) && pNv->ramdac_active[1]) {
952                 ErrorF("Stealing ramdac1 ;-)\n");
953                 output2 = nv_find_output_and_clear_ramdac_from_outputs(output, 1);
954                 pNv->ramdac_active[1] = FALSE;
955                 stole_ramdac = TRUE;
956         }
957
958         /* TODO: figure out what ramdac 2 is and how it is identified */
959
960         /* At this point we already stole ramdac 0 or 1 if we need it */
961         if (!pNv->ramdac_active[0] && (nv_output->valid_ramdac & RAMDAC_0))
962                 ramdac = 0;
963         else
964                 ramdac = 1;
965
966         ErrorF("Activating ramdac %d\n", ramdac);
967         pNv->ramdac_active[ramdac] = TRUE;
968         nv_output->ramdac = ramdac;
969         if (!stole_ramdac)
970                 nv_find_output_and_clear_ramdac_from_outputs(output, ramdac);
971
972         if (stole_ramdac) {
973                 ErrorF("Resetting the stolen ramdac\n");
974                 DisplayModePtr adjusted_mode = xf86DuplicateMode(&(output2->crtc->desiredMode));
975                 xf86CrtcPtr crtc2 = output2->crtc;
976                 /* Assign a ramdac */
977                 output2->funcs->prepare(output2);
978                 /* We must set the vpll's to ensure they are properly set */
979                 crtc2->funcs->mode_fixup(crtc2, &(crtc2->desiredMode), adjusted_mode);
980                 crtc2->funcs->mode_set(crtc2, &(crtc2->desiredMode), adjusted_mode, crtc2->x, crtc2->y);
981                 output2->funcs->mode_set(output2, &(crtc2->desiredMode), adjusted_mode);
982                 /* Anyone know were this mode is stored, so we don't accidentally wake up a screen that is DPMSModeOff? */
983                 crtc2->funcs->dpms(crtc2, DPMSModeOn);
984                 output2->funcs->commit(output2);
985                 xfree(adjusted_mode);
986         }
987 }
988
989 static void
990 nv_output_commit(xf86OutputPtr output)
991 {
992         ErrorF("nv_output_commit is called\n");
993
994         output->funcs->dpms(output, DPMSModeOn);
995 }
996
997 static const xf86OutputFuncsRec nv_analog_output_funcs = {
998     .dpms = nv_analog_output_dpms,
999     .save = nv_output_save,
1000     .restore = nv_output_restore,
1001     .mode_valid = nv_output_mode_valid,
1002     .mode_fixup = nv_output_mode_fixup,
1003     .mode_set = nv_output_mode_set,
1004     .detect = nv_analog_output_detect,
1005     .get_modes = nv_output_get_modes,
1006     .destroy = nv_output_destroy,
1007     .prepare = nv_output_prepare,
1008     .commit = nv_output_commit,
1009 };
1010
1011 #ifdef RANDR_12_INTERFACE
1012 /*
1013  * Two scaling modes exist, let the user choose.
1014  */
1015 #define SCALING_MODE_NAME "SCALING_MODE"
1016 #define NUM_SCALING_METHODS 2
1017 static char *scaling_mode_names[] = {
1018         "gpu",
1019         "panel",
1020 };
1021 static Atom scaling_mode_atom;
1022
1023 static int
1024 nv_scaling_mode_lookup(char *name, int size)
1025 {
1026         int i;
1027         const int len = strlen(name);
1028
1029         for (i = 0; i < NUM_SCALING_METHODS; i++)
1030                 if (size == len && !strncmp(name, scaling_mode_names[i], len))
1031                         return i;
1032
1033         return -1;
1034 }
1035
1036 static void
1037 nv_tmds_create_resources(xf86OutputPtr output)
1038 {
1039         NVOutputPrivatePtr nv_output = output->driver_private;
1040         ScrnInfoPtr pScrn = output->scrn;
1041         int error;
1042
1043         /*
1044          * Setup scaling mode property.
1045          */
1046         scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
1047
1048         error = RRConfigureOutputProperty(output->randr_output,
1049                                         scaling_mode_atom, TRUE, FALSE, FALSE,
1050                                         0, NULL);
1051
1052         if (error != 0) {
1053                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1054                         "RRConfigureOutputProperty error, %d\n", error);
1055         }
1056
1057         error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
1058                                         XA_STRING, 8, PropModeReplace, 
1059                                         strlen(scaling_mode_names[nv_output->scaling_mode]),
1060                                         scaling_mode_names[nv_output->scaling_mode],
1061                                         FALSE, TRUE);
1062
1063         if (error != 0) {
1064                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1065                         "Failed to set scaling mode, %d\n", error);
1066         }
1067 }
1068
1069 static Bool
1070 nv_tmds_set_property(xf86OutputPtr output, Atom property,
1071                                 RRPropertyValuePtr value)
1072 {
1073         NVOutputPrivatePtr nv_output = output->driver_private;
1074
1075         if (property == scaling_mode_atom) {
1076                 int32_t ret;
1077                 char *name;
1078
1079                 if (value->type != XA_STRING || value->format != 8)
1080                         return FALSE;
1081
1082                 name = (char*) value->data;
1083
1084                 /* Match a string to a scaling mode */
1085                 ret = nv_scaling_mode_lookup(name, value->size);
1086                 if (ret < 0)
1087                         return FALSE;
1088
1089                 nv_output->scaling_mode = ret;
1090                 return TRUE;
1091         }
1092
1093         return TRUE;
1094 }
1095
1096 #endif /* RANDR_12_INTERFACE */
1097
1098 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
1099         .dpms = nv_tmds_output_dpms,
1100         .save = nv_output_save,
1101         .restore = nv_output_restore,
1102         .mode_valid = nv_output_mode_valid,
1103         .mode_fixup = nv_output_mode_fixup,
1104         .mode_set = nv_output_mode_set,
1105         .detect = nv_tmds_output_detect,
1106         .get_modes = nv_output_get_modes,
1107         .destroy = nv_output_destroy,
1108         .prepare = nv_output_prepare,
1109         .commit = nv_output_commit,
1110 #ifdef RANDR_12_INTERFACE
1111         .create_resources = nv_tmds_create_resources,
1112         .set_property = nv_tmds_set_property,
1113 #endif /* RANDR_12_INTERFACE */
1114 };
1115
1116 static int nv_lvds_output_mode_valid
1117 (xf86OutputPtr output, DisplayModePtr pMode)
1118 {
1119         NVOutputPrivatePtr nv_output = output->driver_private;
1120
1121         /* No modes > panel's native res */
1122         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
1123                 return MODE_PANEL;
1124
1125         return nv_output_mode_valid(output, pMode);
1126 }
1127
1128 static xf86OutputStatus
1129 nv_lvds_output_detect(xf86OutputPtr output)
1130 {
1131         ScrnInfoPtr pScrn = output->scrn;
1132         NVPtr pNv = NVPTR(pScrn);
1133
1134         if (pNv->fp_native_mode || nv_ddc_detect(output))
1135                 return XF86OutputStatusConnected;
1136
1137         return XF86OutputStatusDisconnected;
1138 }
1139
1140 static DisplayModePtr
1141 nv_lvds_output_get_modes(xf86OutputPtr output)
1142 {
1143         ScrnInfoPtr pScrn = output->scrn;
1144         NVPtr pNv = NVPTR(pScrn);
1145         NVOutputPrivatePtr nv_output = output->driver_private;
1146         DisplayModePtr modes;
1147
1148         if ((modes = nv_output_get_modes(output)))
1149                 return modes;
1150
1151         /* it is possible to set up a mode from what we can read from the
1152          * RAMDAC registers, but if we can't read the BIOS table correctly
1153          * we might as well give up */
1154         if (pNv->fp_native_mode == NULL)
1155                 return NULL;
1156
1157         nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1158         nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1159         nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1160
1161         if (pNv->fp_native_mode->HDisplay != nv_output->fpWidth ||
1162                 pNv->fp_native_mode->VDisplay != nv_output->fpHeight) {
1163                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1164                         "Panel size mismatch; ignoring RAMDAC\n");
1165                 nv_output->fpWidth = pNv->fp_native_mode->HDisplay;
1166                 nv_output->fpHeight = pNv->fp_native_mode->VDisplay;
1167         }
1168
1169         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1170                 nv_output->fpWidth, nv_output->fpHeight);
1171
1172         nv_output->native_mode = xf86DuplicateMode(pNv->fp_native_mode);
1173
1174         return xf86DuplicateMode(pNv->fp_native_mode);
1175 }
1176
1177 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1178         .dpms = nv_lvds_output_dpms,
1179         .save = nv_output_save,
1180         .restore = nv_output_restore,
1181         .mode_valid = nv_lvds_output_mode_valid,
1182         .mode_fixup = nv_output_mode_fixup,
1183         .mode_set = nv_output_mode_set,
1184         .detect = nv_lvds_output_detect,
1185         .get_modes = nv_lvds_output_get_modes,
1186         .destroy = nv_output_destroy,
1187         .prepare = nv_output_prepare,
1188         .commit = nv_output_commit,
1189 };
1190
1191 static void nv_add_analog_output(ScrnInfoPtr pScrn, int dcb_entry, Bool dvi_pair)
1192 {
1193         NVPtr pNv = NVPTR(pScrn);
1194         xf86OutputPtr       output;
1195         NVOutputPrivatePtr    nv_output;
1196         char outputname[20];
1197         Bool create_output = TRUE;
1198         int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1199
1200         /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1201         if (dvi_pair) {
1202                 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1203                 pNv->dvi_a_count++;
1204         } else {
1205                 sprintf(outputname, "VGA-%d", pNv->vga_count);
1206                 pNv->vga_count++;
1207         }
1208
1209         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1210         if (!nv_output) {
1211                 return;
1212         }
1213
1214         nv_output->dcb_entry = dcb_entry;
1215
1216         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1217                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1218
1219         nv_output->type = OUTPUT_ANALOG;
1220
1221         /* order:
1222          * bit0: RAMDAC_0 valid
1223          * bit1: RAMDAC_1 valid
1224          * So lowest order has highest priority.
1225          * Below is guesswork:
1226          * bit2: All ramdac's valid?
1227          * FIXME: this probably wrong
1228          */
1229         nv_output->valid_ramdac = ffs(pNv->dcb_table.entry[dcb_entry].or);
1230
1231         if (!create_output) {
1232                 xfree(nv_output);
1233                 return;
1234         }
1235
1236         /* Delay creation of output until we actually know we want it */
1237         output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1238         if (!output)
1239                 return;
1240
1241         output->driver_private = nv_output;
1242
1243         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1244
1245         nv_output->ramdac = -1;
1246
1247         /* This is only to facilitate proper output routing for dvi */
1248         /* See sel_clk assignment in nv_crtc.c */
1249         if (nv_output->valid_ramdac & RAMDAC_1) {
1250                 nv_output->preferred_ramdac = 1;
1251         } else {
1252                 nv_output->preferred_ramdac = 0;
1253         }
1254
1255         output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1256
1257         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1258 }
1259
1260 static void nv_add_digital_output(ScrnInfoPtr pScrn, int dcb_entry, int lvds)
1261 {
1262         NVPtr pNv = NVPTR(pScrn);
1263         xf86OutputPtr       output;
1264         NVOutputPrivatePtr    nv_output;
1265         char outputname[20];
1266         Bool create_output = TRUE;
1267         int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1268
1269         if (lvds) {
1270                 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1271                 pNv->lvds_count++;
1272         } else {
1273                 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1274                 pNv->dvi_d_count++;
1275         }
1276
1277         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1278
1279         if (!nv_output) {
1280                 return;
1281         }
1282
1283         nv_output->dcb_entry = dcb_entry;
1284
1285         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1286                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1287
1288         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1289
1290         /* order:
1291          * bit0: RAMDAC_0 valid
1292          * bit1: RAMDAC_1 valid
1293          * So lowest order has highest priority.
1294          * Below is guesswork:
1295          * bit2: All ramdac's valid?
1296          * FIXME: this probably wrong
1297          */
1298         nv_output->valid_ramdac = ffs(pNv->dcb_table.entry[dcb_entry].or);
1299
1300         if (lvds) {
1301                 nv_output->type = OUTPUT_LVDS;
1302                 /* comment below two lines to test LVDS under RandR12.
1303                  * If your screen "blooms" or "bleeds" (i.e. has a developing
1304                  * white / psychedelic pattern) then KILL X IMMEDIATELY
1305                  * (ctrl+alt+backspace) & if the effect continues reset power */
1306                 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1307                 create_output = FALSE;
1308         } else {
1309                 nv_output->type = OUTPUT_TMDS;
1310         }
1311
1312         if (!create_output) {
1313                 xfree(nv_output);
1314                 return;
1315         }
1316
1317         /* Delay creation of output until we are certain is desirable */
1318         if (lvds)
1319                 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1320         else
1321                 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1322         if (!output)
1323                 return;
1324
1325         output->driver_private = nv_output;
1326
1327         nv_output->ramdac = -1;
1328
1329         /* This is only to facilitate proper output routing for dvi */
1330         /* See sel_clk assignment in nv_crtc.c */
1331         if (nv_output->valid_ramdac & RAMDAC_1) {
1332                 nv_output->preferred_ramdac = 1;
1333         } else {
1334                 nv_output->preferred_ramdac = 0;
1335         }
1336
1337         if (pNv->fpScaler) {
1338                 /* Aspect ratio */
1339                 nv_output->scaling_mode = 0;
1340         } else {
1341                 /* "Panel mode" fully filled */
1342                 nv_output->scaling_mode = 1;
1343         }
1344
1345         output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1346
1347         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1348 }
1349
1350 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1351 {
1352         NVPtr pNv = NVPTR(pScrn);
1353         int i, type, bus_count[0xf], digital_counter = 0;
1354
1355         memset(bus_count, 0, sizeof(bus_count));
1356         for (i = 0 ; i < pNv->dcb_table.entries; i++)
1357                 bus_count[pNv->dcb_table.entry[i].bus]++;
1358
1359         /* we setup the outputs up from the BIOS table */
1360         for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1361                 type = pNv->dcb_table.entry[i].type;
1362                 if (type > 3) {
1363                         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1364                         continue;
1365                 }
1366
1367                 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);
1368
1369                 switch(type) {
1370                 case OUTPUT_ANALOG:
1371                         nv_add_analog_output(pScrn, i, (bus_count[pNv->dcb_table.entry[i].bus] > 1));
1372                         break;
1373                 case OUTPUT_TMDS:
1374                         nv_add_digital_output(pScrn, i, 0);
1375                         digital_counter++;
1376                         break;
1377                 case OUTPUT_LVDS:
1378                         nv_add_digital_output(pScrn, i, 1);
1379                         /* I'm assuming that lvds+dvi has the same effect as dual dvi */
1380                         digital_counter++;
1381                         break;
1382                 default:
1383                         break;
1384                 }
1385         }
1386
1387         if (digital_counter > 1) {
1388                 pNv->dual_dvi = TRUE;
1389         } else {
1390                 pNv->dual_dvi = FALSE;
1391         }
1392 }
1393
1394 void NvSetupOutputs(ScrnInfoPtr pScrn)
1395 {
1396         NVPtr pNv = NVPTR(pScrn);
1397
1398         pNv->Television = FALSE;
1399
1400         memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1401         NvDCBSetupOutputs(pScrn);
1402 }
1403
1404 /*************************************************************************** \
1405 |*                                                                           *|
1406 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1407 |*                                                                           *|
1408 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1409 |*     international laws.  Users and possessors of this source code are     *|
1410 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1411 |*     use this code in individual and commercial software.                  *|
1412 |*                                                                           *|
1413 |*     Any use of this source code must include,  in the user documenta-     *|
1414 |*     tion and  internal comments to the code,  notices to the end user     *|
1415 |*     as follows:                                                           *|
1416 |*                                                                           *|
1417 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1418 |*                                                                           *|
1419 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1420 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1421 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1422 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1423 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1424 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1425 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1426 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1427 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1428 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1429 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1430 |*                                                                           *|
1431 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1432 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1433 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1434 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1435 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1436 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1437 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1438 |*     all U.S. Government End Users  acquire the source code  with only     *|
1439 |*     those rights set forth herein.                                        *|
1440 |*                                                                           *|
1441  \***************************************************************************/