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