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