randr12: Improved values for FP_CONTROL register.
[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 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
95 {
96         NVOutputPrivatePtr nv_output = output->driver_private;
97         ScrnInfoPtr     pScrn = output->scrn;
98         NVPtr pNv = NVPTR(pScrn);
99         int ramdac;
100
101         /* Is TMDS programmed on a different output? */
102         /* Always choose the prefered ramdac, since that one contains the tmds stuff */
103         /* Assumption: there is always once output that can only run of the primary ramdac */
104         if (nv_output->valid_ramdac & RAMDAC_1) {
105                 ramdac = 1;
106         } else {
107                 ramdac = 0;
108         }
109
110         NVWriteTMDS(pNv, ramdac, tmds_reg, val);
111 }
112
113 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
114 {
115         NVOutputPrivatePtr nv_output = output->driver_private;
116         ScrnInfoPtr     pScrn = output->scrn;
117         NVPtr pNv = NVPTR(pScrn);
118         int ramdac;
119
120         /* Is TMDS programmed on a different output? */
121         /* Always choose the prefered ramdac, since that one contains the tmds stuff */
122         /* Assumption: there is always once output that can only run of the primary ramdac */
123         if (nv_output->valid_ramdac & RAMDAC_1) {
124                 ramdac = 1;
125         } else {
126                 ramdac = 0;
127         }
128
129         return NVReadTMDS(pNv, ramdac, tmds_reg);
130 }
131
132 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
133 {
134     NVOutputPrivatePtr nv_output = output->driver_private;
135     ScrnInfoPtr pScrn = output->scrn;
136     NVPtr pNv = NVPTR(pScrn);
137
138     nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
139 }
140
141 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
142 {
143     NVOutputPrivatePtr nv_output = output->driver_private;
144     ScrnInfoPtr pScrn = output->scrn;
145     NVPtr pNv = NVPTR(pScrn);
146
147     return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
148 }
149
150 static void nv_output_backlight_enable(xf86OutputPtr output,  Bool on)
151 {
152         ScrnInfoPtr pScrn = output->scrn;
153         NVPtr pNv = NVPTR(pScrn);
154
155         ErrorF("nv_output_backlight_enable is called for output %s to turn %s\n", output->name, on ? "on" : "off");
156
157         /* This is done differently on each laptop.  Here we
158          * define the ones we know for sure. */
159
160 #if defined(__powerpc__)
161         if ((pNv->Chipset == 0x10DE0179) ||
162             (pNv->Chipset == 0x10DE0189) ||
163             (pNv->Chipset == 0x10DE0329)) {
164                 /* NV17,18,34 Apple iMac, iBook, PowerBook */
165                 CARD32 tmp_pmc, tmp_pcrt;
166                 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
167                 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
168                 if (on) {
169                         tmp_pmc |= (1 << 31);
170                         tmp_pcrt |= 0x1;
171                 }
172                 nvWriteMC(pNv, 0x10F0, tmp_pmc);
173                 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
174         }
175 #endif
176
177         if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
178                 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
179 }
180
181 static void
182 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
183 {
184         NVOutputPrivatePtr nv_output = output->driver_private;
185         NVPtr pNv = NVPTR(output->scrn);
186
187         if (nv_output->ramdac != -1 && mode != DPMSModeOff) {
188                 /* This was not a modeset, but a normal dpms call */
189                 pNv->ramdac_active[nv_output->ramdac] = TRUE;
190                 ErrorF("Activating ramdac %d\n", nv_output->ramdac);
191                 nv_output->ramdac_assigned = TRUE;
192         }
193
194         switch (mode) {
195         case DPMSModeStandby:
196         case DPMSModeSuspend:
197         case DPMSModeOff:
198                 nv_output_backlight_enable(output, 0);
199                 break;
200         case DPMSModeOn:
201                 nv_output_backlight_enable(output, 1);
202         default:
203                 break;
204         }
205
206         /* We may be going for modesetting, so we must reset the ramdacs */
207         if (nv_output->ramdac != -1 && mode == DPMSModeOff) {
208                 pNv->ramdac_active[nv_output->ramdac] = FALSE;
209                 ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
210                 nv_output->ramdac_assigned = FALSE;
211         }
212 }
213
214 static void
215 nv_analog_output_dpms(xf86OutputPtr output, int mode)
216 {
217         xf86CrtcPtr crtc = output->crtc;
218         NVOutputPrivatePtr nv_output = output->driver_private;
219         NVPtr pNv = NVPTR(output->scrn);
220
221         ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
222
223         if (nv_output->ramdac != -1) {
224                 /* We may be going for modesetting, so we must reset the ramdacs */
225                 if (mode == DPMSModeOff) {
226                         pNv->ramdac_active[nv_output->ramdac] = FALSE;
227                         ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
228                         nv_output->ramdac_assigned = FALSE;
229                         /* This was not a modeset, but a normal dpms call */
230                 } else {
231                         pNv->ramdac_active[nv_output->ramdac] = TRUE;
232                         ErrorF("Activating ramdac %d\n", nv_output->ramdac);
233                         nv_output->ramdac_assigned = TRUE;
234                 }
235         }
236
237         if (crtc) {
238                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
239
240                 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
241         }
242 }
243
244 static void
245 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
246 {
247         xf86CrtcPtr crtc = output->crtc;
248         NVOutputPrivatePtr nv_output = output->driver_private;
249         NVPtr pNv = NVPTR(output->scrn);
250
251         ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
252
253         /* We just woke up again from an actual monitor dpms and not a modeset prepare */
254         /* Put here since we actually need our ramdac to wake up again ;-) */
255         if (nv_output->ramdac != -1 && mode != DPMSModeOff) {
256                 pNv->ramdac_active[nv_output->ramdac] = TRUE;
257                 nv_output->ramdac_assigned = TRUE;
258                 ErrorF("Activating ramdac %d\n", nv_output->ramdac);
259         }
260
261         /* Are we assigned a ramdac already?, else we will be activated during mode set */
262         if (crtc && nv_output->ramdac != -1) {
263                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
264
265                 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
266
267                 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
268                 switch(mode) {
269                         case DPMSModeStandby:
270                         case DPMSModeSuspend:
271                         case DPMSModeOff:
272                                 /* cut the TMDS output */           
273                                 fpcontrol |= 0x20000022;
274                                 break;
275                         case DPMSModeOn:
276                                 /* disable cutting the TMDS output */
277                                 fpcontrol &= ~0x20000022;
278                                 break;
279                 }
280                 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
281         }
282
283         /* We may be going for modesetting, so we must reset the ramdacs */
284         if (nv_output->ramdac != -1 && mode == DPMSModeOff) {
285                 pNv->ramdac_active[nv_output->ramdac] = FALSE;
286                 nv_output->ramdac_assigned = FALSE;
287                 ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
288         }
289 }
290
291 /* Some registers are not set, because they are zero. */
292 /* This sequence matters, this is how the blob does it */
293 int tmds_regs[] = { 0x2f, 0x2e, 0x33, 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x04, 0x3a, 0x33, 0x04 };
294
295 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
296 {
297         NVOutputPrivatePtr nv_output = output->driver_private;
298         ScrnInfoPtr pScrn = output->scrn;
299         NVPtr pNv = NVPTR(pScrn);
300         NVOutputRegPtr regp;
301         int i;
302
303         regp = &state->dac_reg[nv_output->ramdac];
304         regp->general       = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
305         regp->test_control      = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
306         regp->unk_670   = NVOutputReadRAMDAC(output, NV_RAMDAC_670);
307         regp->fp_control        = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
308         regp->debug_0   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
309         regp->debug_1   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
310         regp->debug_2   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
311         state->config       = nvReadFB(pNv, NV_PFB_CFG0);
312
313         //regp->unk_900         = NVOutputReadRAMDAC(output, NV_RAMDAC_900);
314
315         regp->unk_a20 = NVOutputReadRAMDAC(output, NV_RAMDAC_A20);
316         regp->unk_a24 = NVOutputReadRAMDAC(output, NV_RAMDAC_A24);
317         regp->unk_a34 = NVOutputReadRAMDAC(output, NV_RAMDAC_A34);
318
319         regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
320
321         if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
322                 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
323         } else if (pNv->twoHeads) {
324                 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
325         }
326         regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
327
328         /* I want to be able reset TMDS registers for DVI-D/DVI-A pairs for example */
329         /* Also write on VT restore */
330         if (nv_output->type != OUTPUT_LVDS || override )
331                 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
332                         regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
333                 }
334
335         /* The regs below are 0 for non-flatpanels, so you can load and save them */
336
337         for (i = 0; i < 7; i++) {
338                 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
339                 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
340         }
341
342         for (i = 0; i < 7; i++) {
343                 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
344                 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
345         }
346
347         regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
348         regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
349         regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
350         regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
351 }
352
353 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
354 {
355         NVOutputPrivatePtr nv_output = output->driver_private;
356         ScrnInfoPtr     pScrn = output->scrn;
357         NVPtr pNv = NVPTR(pScrn);
358         NVOutputRegPtr regp;
359         int i;
360
361         regp = &state->dac_reg[nv_output->ramdac];
362
363         if (nv_output->type == OUTPUT_LVDS) {
364                 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_0\n", regp->debug_0);
365                 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_1\n", regp->debug_1);
366                 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_2\n", regp->debug_2);
367                 ErrorF("Writing %08X to RAMDAC_OUTPUT\n", regp->output);
368                 ErrorF("Writing %08X to RAMDAC_FP_CONTROL\n", regp->fp_control);
369         }
370         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
371         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
372         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
373         NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
374         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
375
376         NVOutputWriteRAMDAC(output, NV_RAMDAC_A20, regp->unk_a20);
377         NVOutputWriteRAMDAC(output, NV_RAMDAC_A24, regp->unk_a24);
378         NVOutputWriteRAMDAC(output, NV_RAMDAC_A34, regp->unk_a34);
379
380         //NVOutputWriteRAMDAC(output, NV_RAMDAC_900, regp->unk_900);
381
382         if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
383                 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
384         } else if (pNv->twoHeads) {
385                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
386         }
387
388         NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
389         NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, regp->test_control);
390         NVOutputWriteRAMDAC(output, NV_RAMDAC_670, regp->unk_670);
391         NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
392
393         /* I want to be able reset TMDS registers for DVI-D/DVI-A pairs for example */
394         /* Also write on VT restore */
395         if (nv_output->type != OUTPUT_LVDS || override )
396                 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
397                         NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
398                 }
399
400         /* The regs below are 0 for non-flatpanels, so you can load and save them */
401
402         for (i = 0; i < 7; i++) {
403                 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
404                 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
405         }
406
407         for (i = 0; i < 7; i++) {
408                 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
409                 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
410         }
411
412         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
413         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
414         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
415         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
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         ScrnInfoPtr pScrn = output->scrn;
498         NVPtr pNv = NVPTR(pScrn);
499         NVOutputPrivatePtr nv_output = output->driver_private;
500
501         ErrorF("nv_output_mode_fixup is called\n");
502
503         /* For internal panels and gpu scaling on DVI we need the native mode */
504         if ((nv_output->type == OUTPUT_LVDS) || (pNv->fpScaler && (nv_output->type == OUTPUT_TMDS))) {
505                 adjusted_mode->HDisplay = nv_output->native_mode->HDisplay;
506                 adjusted_mode->HSkew = nv_output->native_mode->HSkew;
507                 adjusted_mode->HSyncStart = nv_output->native_mode->HSyncStart;
508                 adjusted_mode->HSyncEnd = nv_output->native_mode->HSyncEnd;
509                 adjusted_mode->HTotal = nv_output->native_mode->HTotal;
510                 adjusted_mode->VDisplay = nv_output->native_mode->VDisplay;
511                 adjusted_mode->VScan = nv_output->native_mode->VScan;
512                 adjusted_mode->VSyncStart = nv_output->native_mode->VSyncStart;
513                 adjusted_mode->VSyncEnd = nv_output->native_mode->VSyncEnd;
514                 adjusted_mode->VTotal = nv_output->native_mode->VTotal;
515                 adjusted_mode->Clock = nv_output->native_mode->Clock;
516
517                 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
518         }
519
520         return TRUE;
521 }
522
523 static int
524 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
525 {
526     NVOutputPrivatePtr nv_output = output->driver_private;
527     ScrnInfoPtr pScrn = output->scrn;
528     NVPtr pNv = NVPTR(pScrn);
529     NVOutputRegPtr regp;
530     int tweak = 0;
531   
532     regp = &state->dac_reg[nv_output->ramdac];
533     if (pNv->usePanelTweak) {
534         tweak = pNv->PanelTweak;
535     } else {
536         /* begin flat panel hacks */
537         /* This is unfortunate, but some chips need this register
538            tweaked or else you get artifacts where adjacent pixels are
539            swapped.  There are no hard rules for what to set here so all
540            we can do is experiment and apply hacks. */
541     
542         if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
543             /* At least one NV34 laptop needs this workaround. */
544             tweak = -1;
545         }
546                 
547         if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
548             tweak = 1;
549         }
550         /* end flat panel hacks */
551     }
552     return tweak;
553 }
554
555 static void
556 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
557 {
558         NVOutputPrivatePtr nv_output = output->driver_private;
559         ScrnInfoPtr pScrn = output->scrn;
560         int bpp;
561         NVPtr pNv = NVPTR(pScrn);
562         NVFBLayout *pLayout = &pNv->CurrentLayout;
563         RIVA_HW_STATE *state, *sv_state;
564         Bool is_fp = FALSE;
565         NVOutputRegPtr regp, regp2, savep;
566         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
567         float aspect_ratio, panel_ratio;
568         uint32_t h_scale, v_scale;
569         int i;
570
571         state = &pNv->ModeReg;
572         regp = &state->dac_reg[nv_output->ramdac];
573         /* The other ramdac */
574         regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
575
576         sv_state = &pNv->SavedReg;
577         savep = &sv_state->dac_reg[nv_output->ramdac];
578
579         if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
580                 is_fp = TRUE;
581
582                 regp->fp_horiz_regs[REG_DISP_END] = adjusted_mode->HDisplay - 1;
583                 regp->fp_horiz_regs[REG_DISP_TOTAL] = adjusted_mode->HTotal - 1;
584                 regp->fp_horiz_regs[REG_DISP_CRTC] = adjusted_mode->HDisplay;
585                 regp->fp_horiz_regs[REG_DISP_SYNC_START] = adjusted_mode->HSyncStart - 1;
586                 regp->fp_horiz_regs[REG_DISP_SYNC_END] = adjusted_mode->HSyncEnd - 1;
587                 regp->fp_horiz_regs[REG_DISP_VALID_START] = adjusted_mode->HSkew;
588                 regp->fp_horiz_regs[REG_DISP_VALID_END] = adjusted_mode->HDisplay - 1;
589
590                 regp->fp_vert_regs[REG_DISP_END] = adjusted_mode->VDisplay - 1;
591                 regp->fp_vert_regs[REG_DISP_TOTAL] = adjusted_mode->VTotal - 1;
592                 regp->fp_vert_regs[REG_DISP_CRTC] = adjusted_mode->VDisplay;
593                 regp->fp_vert_regs[REG_DISP_SYNC_START] = adjusted_mode->VSyncStart - 1;
594                 regp->fp_vert_regs[REG_DISP_SYNC_END] = adjusted_mode->VSyncEnd - 1;
595                 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
596                 regp->fp_vert_regs[REG_DISP_VALID_END] = adjusted_mode->VDisplay - 1;
597
598                 ErrorF("Horizontal:\n");
599                 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_END]);
600                 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_horiz_regs[REG_DISP_TOTAL]);
601                 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_horiz_regs[REG_DISP_CRTC]);
602                 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_START]);
603                 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_END]);
604                 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_START]);
605                 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_END]);
606
607                 ErrorF("Vertical:\n");
608                 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_END]);
609                 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_vert_regs[REG_DISP_TOTAL]);
610                 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_vert_regs[REG_DISP_CRTC]);
611                 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_START]);
612                 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_END]);
613                 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_START]);
614                 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_END]);
615         }
616
617         /*
618         * bit0: positive vsync
619         * bit4: positive hsync
620         * bit8: enable panel scaling 
621         * bit26: a bit sometimes seen on some g70 cards
622         * bit31: sometimes seen on LVDS panels
623         * This must also be set for non-flatpanels
624         * Some bits seem shifted for vga monitors
625         */
626
627         if (is_fp) {
628                 regp->fp_control = 0x11100000;
629         } else {
630                 regp->fp_control = 0x21100000;
631         }
632         if (nv_output->type == OUTPUT_LVDS) {
633                 /* Let's assume LVDS to be on ramdac0, remember that in the ramdac routing is somewhat random (compared to bios setup), so don't trust it */
634                 regp->fp_control = nvReadRAMDAC0(pNv, NV_RAMDAC_FP_CONTROL) & 0xfff00000;
635         } else {
636                 /* If the special bit exists, it exists on both ramdac's */
637                 regp->fp_control |= nvReadRAMDAC0(pNv, NV_RAMDAC_FP_CONTROL) & (1 << 26);
638         }
639
640         /* Deal with vsync/hsync polarity */
641         /* These analog monitor offsets are guesswork */
642         if (adjusted_mode->Flags & V_PVSYNC) {
643                 regp->fp_control |= (1 << (0 + !is_fp));
644         }
645
646         if (adjusted_mode->Flags & V_PHSYNC) {
647                 regp->fp_control |= (1 << (4 + !is_fp));
648         }
649
650         if (is_fp) {
651                 ErrorF("Pre-panel scaling\n");
652                 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
653                 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
654                 ErrorF("panel_ratio=%f\n", panel_ratio);
655                 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
656                 ErrorF("aspect_ratio=%f\n", aspect_ratio);
657                 /* Scale factors is the so called 20.12 format, taken from Haiku */
658                 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
659                 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
660                 ErrorF("h_scale=%d\n", h_scale);
661                 ErrorF("v_scale=%d\n", v_scale);
662
663                 /* Don't limit last fetched line */
664                 regp->debug_2 = 0;
665
666                 /* We want automatic scaling */
667                 regp->debug_1 = 0;
668
669                 regp->fp_hvalid_start = 0;
670                 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
671
672                 regp->fp_vvalid_start = 0;
673                 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
674
675                 if (!pNv->fpScaler) {
676                         ErrorF("Flat panel is doing the scaling.\n");
677                         regp->fp_control |= (1 << 8);
678                 } else {
679                         ErrorF("GPU is doing the scaling.\n");
680                         /* GPU scaling happens automaticly at a ratio of 1.33 */
681                         /* A 1280x1024 panel has a ratio of 1.25, we don't want to scale that at 4:3 resolutions */
682                         if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
683                                 uint32_t diff;
684
685                                 ErrorF("Scaling resolution on a widescreen panel\n");
686
687                                 /* Scaling in both directions needs to the same */
688                                 h_scale = v_scale;
689
690                                 /* Set a new horizontal scale factor and enable testmode (bit12) */
691                                 regp->debug_1 = ((h_scale >> 1) & 0xfff) | (1 << 12);
692
693                                 diff = nv_output->fpWidth - (((1 << 12) * mode->HDisplay)/h_scale);
694                                 regp->fp_hvalid_start = diff/2;
695                                 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
696                         }
697
698                         /* Same scaling, just for panels with aspect ratio's smaller than 1 */
699                         if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
700                                 uint32_t diff;
701
702                                 ErrorF("Scaling resolution on a portrait panel\n");
703
704                                 /* Scaling in both directions needs to the same */
705                                 v_scale = h_scale;
706
707                                 /* Set a new vertical scale factor and enable testmode (bit28) */
708                                 regp->debug_1 = (((v_scale >> 1) & 0xfff) << 16) | (1 << (12 + 16));
709
710                                 diff = nv_output->fpHeight - (((1 << 12) * mode->VDisplay)/v_scale);
711                                 regp->fp_vvalid_start = diff/2;
712                                 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
713                         }
714                 }
715
716                 ErrorF("Post-panel scaling\n");
717         }
718
719         if (pNv->Architecture >= NV_ARCH_10) {
720                 /* Bios and blob don't seem to do anything (else) */
721                 regp->nv10_cursync = (1<<25);
722         }
723
724         /* These are the common blob values, minus a few fp specific bit's */
725         /* Let's keep the TMDS pll and fpclock running in all situations */
726         regp->debug_0 = 0x1101111;
727
728         if(is_fp) {
729                 /* I am not completely certain, but seems to be set only for dfp's */
730                 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED;
731         }
732
733         ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
734
735         /* This is just a guess, there are probably more registers which need setting */
736         /* But we must start somewhere ;-) */
737         if (is_fp) {
738                 regp->TMDS[0x4] = 0x80;
739                 /* Enable crosswired mode */
740                 /* As far as i know, this may never be set on ramdac 0 tmds registers (ramdac 1 -> crosswired -> ramdac 0 tmds regs) */
741                 /* This will upset the monitor, trust me, i know it :-( */
742                 /* Now allowed for non-bios inited systems */
743                 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)) {
744                         regp->TMDS[0x4] |= (1 << 3);
745                 }
746         }
747
748         /* The TMDS game begins */
749         /* A few registers are also programmed on non-tmds monitors */
750         /* At the moment i can't give rationale for these values */
751         if (!is_fp) {
752                 regp->TMDS[0x2e] = 0x80;
753                 regp->TMDS[0x2f] = 0xff;
754                 regp->TMDS[0x33] = 0xfe;
755         } else {
756                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
757                 uint32_t pll_setup_control = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SETUP_CONTROL);
758                 regp->TMDS[0x2b] = 0x7d;
759                 regp->TMDS[0x2c] = 0x0;
760                 if (nv_crtc->head == 1) {
761                         regp->TMDS[0x2e] = 0x81;
762                 } else {
763                         regp->TMDS[0x2e] = 0x85;
764                 }
765                 regp->TMDS[0x2f] = 0x21;
766                 regp->TMDS[0x30] = 0x0;
767                 regp->TMDS[0x31] = 0x0;
768                 regp->TMDS[0x32] = 0x0;
769                 regp->TMDS[0x33] = 0xf0;
770                 regp->TMDS[0x3a] = 0x80;
771
772                 /* Here starts the registers that may cause problems for some */
773                 /* This an educated guess */
774                 if (pNv->misc_info.reg_c040 & (1 << 10)) {
775                         regp->TMDS[0x5] = 0x68;
776                 } else {
777                         regp->TMDS[0x5] = 0x6e;
778                 }
779
780                 /* This seems to be related to PLL_SETUP_CONTROL */
781                 /* When PLL_SETUP_CONTROL ends with 0x1c, then this value is 0xc1 */
782                 /* Otherwise 0xf1 */
783                 if ((pll_setup_control & 0xff) == 0x1c) {
784                         regp->TMDS[0x0] = 0xc1;
785                 } else {
786                         regp->TMDS[0x0] = 0xf1;
787                 }
788
789                 /* This is also related to PLL_SETUP_CONTROL, exactly how is unknown */
790                 if (pll_setup_control == 0) {
791                         regp->TMDS[0x1] = 0x0;
792                 } else {
793                         if (nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) & (1<<12)) {
794                                 regp->TMDS[0x1] = 0x41;
795                         } else {
796                                 regp->TMDS[0x1] = 0x42;
797                         }
798                 }
799
800                 if (pll_setup_control == 0x0) {
801                         regp->TMDS[0x2] = 0x90;
802                 } else {
803                         regp->TMDS[0x2] = 0x89;
804                 }
805                 /* This test is not needed for me although the blob sets this value */
806                 /* It may be wrong, but i'm leaving it for historical reference */
807                 /*if (pNv->misc_info.reg_c040 == 0x3c0bc003 || pNv->misc_info.reg_c040 == 0x3c0bc333) {
808                         regp->TMDS[0x2] = 0xa9;
809                 }*/
810         }
811
812         /* Flatpanel support needs at least a NV10 */
813         if(pNv->twoHeads) {
814                 /* Instead of 1, several other values are also used: 2, 7, 9 */
815                 /* The purpose is unknown */
816                 if(pNv->FPDither) {
817                         regp->dither = 0x00010000;
818                 }
819         }
820
821         if(pLayout->depth < 24) {
822                 bpp = pLayout->depth;
823         } else {
824                 bpp = 32;
825         }
826
827         /* Kindly borrowed from haiku driver */
828         /* bit4 and bit5 activate indirect mode trough color palette */
829         switch (pLayout->depth) {
830                 case 32:
831                 case 16:
832                         regp->general = 0x00101130;
833                         break;
834                 case 24:
835                 case 15:
836                         regp->general = 0x00100130;
837                         break;
838                 case 8:
839                 default:
840                         regp->general = 0x00101100;
841                         break;
842         }
843
844         if (pNv->alphaCursor) {
845                 regp->general |= (1<<29);
846         }
847
848         regp->bpp = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
849
850         /* Some values the blob sets */
851         /* This may apply to the real ramdac that is being used (for crosswired situations) */
852         /* Nevertheless, it's unlikely to cause many problems, since the values are equal for both */
853         regp->unk_a20 = 0x0;
854         regp->unk_a24 = 0xfffff;
855         regp->unk_a34 = 0x1;
856
857         /* Put test control into what seems to be the neutral position */
858         if (pNv->NVArch < 0x44) {
859                 regp->test_control = 0xf0000000;
860         } else {
861                 regp->test_control = 0xf0100000;
862         }
863
864         /* This is a similar register to test control */
865         /* Common values are 0xf0000000, 0xf0100000 and 0xf0010000, also without the f */
866         /* This is an educated guess */
867         /* The blob doesn't set this on ramdac 1, so maybe the primary one counts for both? */
868         if (pNv->NVArch < 0x44) {
869                 regp->unk_670 = 0xf0010000;
870         } else {
871                 regp->unk_670 = 0xf0100000;
872         }
873
874         /* This may be causing problems */
875         //regp->unk_900 = 0x10000;
876
877         if (output->crtc) {
878                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
879                 int two_crt = FALSE;
880                 int two_mon = FALSE;
881
882                 for (i = 0; i < config->num_output; i++) {
883                         NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
884
885                         /* is it this output ?? */
886                         if (config->output[i] == output)
887                                 continue;
888
889                         /* it the output connected */
890                         if (config->output[i]->crtc == NULL)
891                                 continue;
892
893                         two_mon = TRUE;
894                         if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
895                                 two_crt = TRUE;
896                         }
897                 }
898
899                 if (is_fp == TRUE) {
900                         regp->output = 0x0;
901                 } else { 
902                         regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
903                 }
904
905                 if (nv_crtc->head == 1) {
906                         regp->output |= NV_RAMDAC_OUTPUT_SELECT_VPLL2;
907                 } else {
908                         regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_VPLL2;
909                 }
910
911                 ErrorF("%d: crtc %d output%d: %04X: twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->ramdac, regp->output, two_crt, two_mon);
912         }
913 }
914
915 static void
916 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
917                    DisplayModePtr adjusted_mode)
918 {
919     ScrnInfoPtr pScrn = output->scrn;
920     NVPtr pNv = NVPTR(pScrn);
921     RIVA_HW_STATE *state;
922
923         ErrorF("nv_output_mode_set is called\n");
924
925     state = &pNv->ModeReg;
926
927     nv_output_mode_set_regs(output, mode, adjusted_mode);
928     nv_output_load_state_ext(output, state, FALSE);
929 }
930
931 static xf86MonPtr
932 nv_get_edid(xf86OutputPtr output)
933 {
934         /* no use for shared DDC output */
935         NVOutputPrivatePtr nv_output = output->driver_private;
936         xf86MonPtr ddc_mon;
937
938         if (nv_output->pDDCBus == NULL)
939                 return NULL;
940
941         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
942         if (!ddc_mon)
943                 return NULL;
944
945         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
946                 goto invalid;
947
948         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
949                                 nv_output->type == OUTPUT_LVDS))
950                 goto invalid;
951
952         return ddc_mon;
953
954 invalid:
955         xfree(ddc_mon);
956         return NULL;
957 }
958
959 static Bool
960 nv_ddc_detect(xf86OutputPtr output)
961 {
962         xf86MonPtr m = nv_get_edid(output);
963
964         if (m == NULL)
965                 return FALSE;
966
967         xfree(m);
968         return TRUE;
969 }
970
971 static Bool
972 nv_crt_load_detect(xf86OutputPtr output)
973 {
974         ScrnInfoPtr pScrn = output->scrn;
975         NVOutputPrivatePtr nv_output = output->driver_private;
976         NVPtr pNv = NVPTR(pScrn);
977         CARD32 reg_output, reg_test_ctrl, temp;
978         Bool present[2];
979         present[0] = FALSE;
980         present[1] = FALSE;
981         int ramdac;
982
983         /* Restrict to primary ramdac for now, because i get false positives on the secondary */
984         for (ramdac = 0; ramdac < 1; ramdac++) {
985                 reg_output = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
986                 reg_test_ctrl = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
987
988                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
989
990                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
991                 usleep(1000);
992
993                 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
994                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, temp | 1);
995
996                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
997                 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
998                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
999
1000                 usleep(1000);
1001
1002                 present[ramdac] = (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
1003
1004                 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
1005                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
1006
1007                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, reg_output);
1008                 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
1009         }
1010
1011         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d for ramdac0\n", present[0]);
1012         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d for ramdac1\n", present[1]);
1013
1014         /* Can we only be ramdac0 ?*/
1015         if (!(nv_output->valid_ramdac & RAMDAC_1)) {
1016                 if (present[0]) 
1017                         return TRUE;
1018         } else {
1019                 if (present[1])
1020                         return TRUE;
1021                 /* What do with a secondary output running of the primary ramdac? */
1022         }
1023
1024         return FALSE;
1025 }
1026
1027 static xf86OutputStatus
1028 nv_tmds_output_detect(xf86OutputPtr output)
1029 {
1030         ErrorF("nv_tmds_output_detect is called\n");
1031
1032         if (nv_ddc_detect(output))
1033                 return XF86OutputStatusConnected;
1034
1035         return XF86OutputStatusDisconnected;
1036 }
1037
1038
1039 static xf86OutputStatus
1040 nv_analog_output_detect(xf86OutputPtr output)
1041 {
1042         ErrorF("nv_analog_output_detect is called\n");
1043
1044         if (nv_ddc_detect(output))
1045                 return XF86OutputStatusConnected;
1046
1047         /* This may not work in all cases, but it's the best that can be done */
1048         /* Example: Secondary output running of primary ramdac, what to do? */
1049         //if (nv_crt_load_detect(output))
1050         //      return XF86OutputStatusConnected;
1051
1052         return XF86OutputStatusDisconnected;
1053 }
1054
1055 static DisplayModePtr
1056 nv_output_get_modes(xf86OutputPtr output)
1057 {
1058         NVOutputPrivatePtr nv_output = output->driver_private;
1059         xf86MonPtr ddc_mon;
1060         DisplayModePtr ddc_modes;
1061
1062         ErrorF("nv_output_get_modes is called\n");
1063
1064         ddc_mon = nv_get_edid(output);
1065
1066         xf86OutputSetEDID(output, ddc_mon);
1067
1068         if (ddc_mon == NULL)
1069                 return NULL;
1070
1071         ddc_modes = xf86OutputGetEDIDModes (output);
1072
1073         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
1074                 int i;
1075                 DisplayModePtr mode;
1076
1077                 for (i = 0; i < 4; i++) {
1078                         /* We only look at detailed timings atm */
1079                         if (ddc_mon->det_mon[i].type != DT)
1080                                 continue;
1081                         /* Selecting only based on width ok? */
1082                         if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
1083                                 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
1084                                 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
1085                         }
1086                 }
1087
1088                 /* Add a native resolution mode that is preferred */
1089                 /* Reduced blanking should be fine on DVI monitor */
1090                 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
1091                 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
1092                 /* We want the new mode to be preferred */
1093                 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
1094                         if (mode->type & M_T_PREFERRED) {
1095                                 mode->type &= ~M_T_PREFERRED;
1096                         }
1097                 }
1098                 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
1099         }
1100
1101         return ddc_modes;
1102 }
1103
1104 static void
1105 nv_output_destroy (xf86OutputPtr output)
1106 {
1107         ErrorF("nv_output_destroy is called\n");
1108         if (output->driver_private)
1109                 xfree (output->driver_private);
1110 }
1111
1112 static void
1113 nv_clear_ramdac_from_outputs(xf86OutputPtr output, int ramdac)
1114 {
1115         int i;
1116         ScrnInfoPtr pScrn = output->scrn;
1117         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1118         xf86OutputPtr output2;
1119         NVOutputPrivatePtr nv_output2;
1120         for (i = 0; i < xf86_config->num_output; i++) {
1121                 output2 = xf86_config->output[i];
1122                 nv_output2 = output2->driver_private;
1123                 if (nv_output2->ramdac == ramdac && output != output2) {
1124                         nv_output2->ramdac = -1;
1125                         nv_output2->ramdac_assigned = FALSE;
1126                         break;
1127                 }
1128         }
1129 }
1130
1131 static void
1132 nv_output_prepare(xf86OutputPtr output)
1133 {
1134         ErrorF("nv_output_prepare is called\n");
1135         NVOutputPrivatePtr nv_output = output->driver_private;
1136         ScrnInfoPtr     pScrn = output->scrn;
1137         NVPtr pNv = NVPTR(pScrn);
1138         xf86CrtcPtr crtc = output->crtc;
1139         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1140
1141         output->funcs->dpms(output, DPMSModeOff);
1142
1143         if (nv_output->ramdac_assigned) {
1144                 ErrorF("We already have a ramdac.\n");
1145                 return;
1146         }
1147
1148         /* We need this ramdac, so let's steal it */
1149         if (!(nv_output->valid_ramdac & RAMDAC_1) && pNv->ramdac_active[0]) {
1150                 ErrorF("Stealing ramdac0 ;-)\n");
1151                 int i;
1152                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1153                 xf86OutputPtr output2;
1154                 NVOutputPrivatePtr nv_output2;
1155                 for (i = 0; i < xf86_config->num_output; i++) {
1156                         output2 = xf86_config->output[i];
1157                         nv_output2 = output2->driver_private;
1158                         if (nv_output2->ramdac == 0 && output != output2) {
1159                                 nv_output2->ramdac = -1;
1160                                 nv_output2->ramdac_assigned = FALSE;
1161                                 break;
1162                         }
1163                 }
1164                 pNv->ramdac_active[0] = FALSE;
1165         }
1166
1167         /* I sometimes get the strange feeling that ramdac's like to be paired with their matching crtc */
1168         if ((nv_output->valid_ramdac & RAMDAC_0) && !(pNv->ramdac_active[0]) && nv_crtc->head == 0) {
1169                 ErrorF("Activating ramdac %d\n", 0);
1170                 pNv->ramdac_active[0] = TRUE;
1171                 nv_output->ramdac = 0;
1172         } else if ((nv_output->valid_ramdac & RAMDAC_1) && !(pNv->ramdac_active[1]) && nv_crtc->head == 1) {
1173                 ErrorF("Activating ramdac %d\n", 1);
1174                 pNv->ramdac_active[1] = TRUE;
1175                 nv_output->ramdac = 1;
1176         }
1177
1178         if (nv_output->ramdac != -1) {
1179                 nv_output->ramdac_assigned = TRUE;
1180                 nv_clear_ramdac_from_outputs(output, nv_output->ramdac);
1181         }
1182 }
1183
1184 static void
1185 nv_output_commit(xf86OutputPtr output)
1186 {
1187         ErrorF("nv_output_commit is called\n");
1188
1189         output->funcs->dpms(output, DPMSModeOn);
1190 }
1191
1192 static const xf86OutputFuncsRec nv_analog_output_funcs = {
1193     .dpms = nv_analog_output_dpms,
1194     .save = nv_output_save,
1195     .restore = nv_output_restore,
1196     .mode_valid = nv_output_mode_valid,
1197     .mode_fixup = nv_output_mode_fixup,
1198     .mode_set = nv_output_mode_set,
1199     .detect = nv_analog_output_detect,
1200     .get_modes = nv_output_get_modes,
1201     .destroy = nv_output_destroy,
1202     .prepare = nv_output_prepare,
1203     .commit = nv_output_commit,
1204 };
1205
1206 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
1207     .dpms = nv_tmds_output_dpms,
1208     .save = nv_output_save,
1209     .restore = nv_output_restore,
1210     .mode_valid = nv_output_mode_valid,
1211     .mode_fixup = nv_output_mode_fixup,
1212     .mode_set = nv_output_mode_set,
1213     .detect = nv_tmds_output_detect,
1214     .get_modes = nv_output_get_modes,
1215     .destroy = nv_output_destroy,
1216     .prepare = nv_output_prepare,
1217     .commit = nv_output_commit,
1218 };
1219
1220 static int nv_lvds_output_mode_valid
1221 (xf86OutputPtr output, DisplayModePtr pMode)
1222 {
1223         NVOutputPrivatePtr nv_output = output->driver_private;
1224
1225         /* No modes > panel's native res */
1226         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
1227                 return MODE_PANEL;
1228
1229         return nv_output_mode_valid(output, pMode);
1230 }
1231
1232 static xf86OutputStatus
1233 nv_lvds_output_detect(xf86OutputPtr output)
1234 {
1235         ScrnInfoPtr pScrn = output->scrn;
1236         NVPtr pNv = NVPTR(pScrn);
1237
1238         if (pNv->fp_native_mode || nv_ddc_detect(output))
1239                 return XF86OutputStatusConnected;
1240
1241         return XF86OutputStatusDisconnected;
1242 }
1243
1244 static DisplayModePtr
1245 nv_lvds_output_get_modes(xf86OutputPtr output)
1246 {
1247         ScrnInfoPtr pScrn = output->scrn;
1248         NVPtr pNv = NVPTR(pScrn);
1249         NVOutputPrivatePtr nv_output = output->driver_private;
1250         DisplayModePtr modes;
1251
1252         if ((modes = nv_output_get_modes(output)))
1253                 return modes;
1254
1255         /* it is possible to set up a mode from what we can read from the
1256          * RAMDAC registers, but if we can't read the BIOS table correctly
1257          * we might as well give up */
1258         if (pNv->fp_native_mode == NULL)
1259                 return NULL;
1260
1261         nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1262         nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1263         nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1264
1265         if (pNv->fp_native_mode->HDisplay != nv_output->fpWidth ||
1266                 pNv->fp_native_mode->VDisplay != nv_output->fpHeight) {
1267                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1268                         "Panel size mismatch; ignoring RAMDAC\n");
1269                 nv_output->fpWidth = pNv->fp_native_mode->HDisplay;
1270                 nv_output->fpHeight = pNv->fp_native_mode->VDisplay;
1271         }
1272
1273         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1274                 nv_output->fpWidth, nv_output->fpHeight);
1275
1276         nv_output->native_mode = xf86DuplicateMode(pNv->fp_native_mode);
1277
1278         return xf86DuplicateMode(pNv->fp_native_mode);
1279 }
1280
1281 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1282         .dpms = nv_lvds_output_dpms,
1283         .save = nv_output_save,
1284         .restore = nv_output_restore,
1285         .mode_valid = nv_lvds_output_mode_valid,
1286         .mode_fixup = nv_output_mode_fixup,
1287         .mode_set = nv_output_mode_set,
1288         .detect = nv_lvds_output_detect,
1289         .get_modes = nv_lvds_output_get_modes,
1290         .destroy = nv_output_destroy,
1291         .prepare = nv_output_prepare,
1292         .commit = nv_output_commit,
1293 };
1294
1295 static void nv_add_analog_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dvi_pair)
1296 {
1297         NVPtr pNv = NVPTR(pScrn);
1298         xf86OutputPtr       output;
1299         NVOutputPrivatePtr    nv_output;
1300         char outputname[20];
1301         int crtc_mask = 0;
1302         Bool create_output = TRUE;
1303
1304         /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1305         if (dvi_pair) {
1306                 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1307                 pNv->dvi_a_count++;
1308         } else {
1309                 sprintf(outputname, "VGA-%d", pNv->vga_count);
1310                 pNv->vga_count++;
1311         }
1312
1313         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1314         if (!nv_output) {
1315                 return;
1316         }
1317
1318         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1319                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1320
1321         nv_output->type = OUTPUT_ANALOG;
1322
1323         /* order:
1324          * bit0: RAMDAC_0 valid
1325          * bit1: RAMDAC_1 valid
1326          * So lowest order has highest priority.
1327          */
1328         nv_output->valid_ramdac = order;
1329
1330         /* Some early nvidia cards have outputs only valid on secondary */
1331         if (nv_output->valid_ramdac & RAMDAC_0) 
1332                 crtc_mask |= (1<<0);
1333
1334         /* Restricting this will cause a full mode set when trying to squeeze in the primary mode */
1335         if (nv_output->valid_ramdac & RAMDAC_1) 
1336                 crtc_mask |= (1<<1);
1337
1338         if (!create_output) {
1339                 xfree(nv_output);
1340                 return;
1341         }
1342
1343         /* Delay creation of output until we actually know we want it */
1344         output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1345         if (!output)
1346                 return;
1347
1348         output->driver_private = nv_output;
1349
1350         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1351
1352         nv_output->ramdac = -1;
1353
1354         output->possible_crtcs = crtc_mask;
1355         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1356 }
1357
1358 static void nv_add_digital_output(ScrnInfoPtr pScrn, int order, int i2c_index, int lvds)
1359 {
1360         NVPtr pNv = NVPTR(pScrn);
1361         xf86OutputPtr       output;
1362         NVOutputPrivatePtr    nv_output;
1363         char outputname[20];
1364         int crtc_mask = 0;
1365         Bool create_output = TRUE;
1366
1367         if (lvds) {
1368                 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1369                 pNv->lvds_count++;
1370         } else {
1371                 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1372                 pNv->dvi_d_count++;
1373         }
1374
1375         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1376
1377         if (!nv_output) {
1378                 return;
1379         }
1380
1381         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1382                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1383
1384         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1385
1386         /* order:
1387          * bit0: RAMDAC_0 valid
1388          * bit1: RAMDAC_1 valid
1389          * So lowest order has highest priority.
1390          */
1391         nv_output->valid_ramdac = order;
1392
1393         /* Some early nvidia cards have outputs only valid on secondary */
1394         if (nv_output->valid_ramdac & RAMDAC_0) 
1395                 crtc_mask |= (1<<0);
1396
1397         /* Restricting this will cause a full mode set when trying to squeeze in the primary mode */
1398         if (nv_output->valid_ramdac & RAMDAC_1) 
1399                 crtc_mask |= (1<<1);
1400
1401         if (lvds) {
1402                 nv_output->type = OUTPUT_LVDS;
1403                 /* comment below two lines to test LVDS under RandR12.
1404                  * If your screen "blooms" or "bleeds" (i.e. has a developing
1405                  * white / psychedelic pattern) then KILL X IMMEDIATELY
1406                  * (ctrl+alt+backspace) & if the effect continues reset power */
1407                 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1408                 create_output = FALSE;
1409         } else {
1410                 nv_output->type = OUTPUT_TMDS;
1411         }
1412
1413         if (!create_output) {
1414                 xfree(nv_output);
1415                 return;
1416         }
1417
1418         /* Delay creation of output until we are certain is desirable */
1419         if (lvds)
1420                 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1421         else
1422                 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1423         if (!output)
1424                 return;
1425
1426         output->driver_private = nv_output;
1427
1428         nv_output->ramdac = -1;
1429
1430         output->possible_crtcs = crtc_mask;
1431         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1432 }
1433
1434 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1435 {
1436         unsigned char type, i2c_index = 0xf, old_i2c_index, or;
1437         NVPtr pNv = NVPTR(pScrn);
1438         int i;
1439         Bool dvi_pair[MAX_NUM_DCB_ENTRIES];
1440
1441         /* check how many TMDS ports there are */
1442         if (pNv->dcb_table.entries) {
1443                 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1444                         type = pNv->dcb_table.entry[i].type;
1445                         old_i2c_index = i2c_index;
1446                         i2c_index = pNv->dcb_table.entry[i].i2c_index;
1447
1448                         dvi_pair[i] = FALSE;
1449
1450                         /* Are we on the same i2c index? */
1451                         if (i2c_index != 0xf && i2c_index == old_i2c_index) {
1452                                 /* Have we passed the analog connector or not? */
1453                                 if (type == OUTPUT_TMDS) {
1454                                         dvi_pair[i - 1] = TRUE;
1455                                 } else if (type == OUTPUT_ANALOG) {
1456                                         dvi_pair[i ] = TRUE;
1457                                 }
1458                         }
1459                 }
1460         }
1461
1462         /* It's time to gather some information */
1463
1464         /* Being slaved indicates we're a flatpanel (or tv-out) */
1465         if (NVReadVGA0(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1466                 pNv->output_info |= OUTPUT_0_SLAVED;
1467         }
1468         if (NVReadVGA1(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1469                 pNv->output_info |= OUTPUT_1_SLAVED;
1470         }
1471         /* This is an educated guess */
1472         if (NVReadTMDS(pNv, 0, 0x4) & (1 << 3)) {
1473                 pNv->output_info |= OUTPUT_0_CROSSWIRED_TMDS;
1474         }
1475         if (NVReadTMDS(pNv, 1, 0x4) & (1 << 3)) {
1476                 pNv->output_info |= OUTPUT_1_CROSSWIRED_TMDS;
1477         }
1478         /* Are we LVDS? */
1479         if (NVReadTMDS(pNv, 0, 0x4) & (1 << 0)) {
1480                 pNv->output_info |= OUTPUT_0_LVDS;
1481         }
1482         if (NVReadTMDS(pNv, 1, 0x4) & (1 << 0)) {
1483                 pNv->output_info |= OUTPUT_1_LVDS;
1484         }
1485
1486         /* we setup the outputs up from the BIOS table */
1487         for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1488                 type = pNv->dcb_table.entry[i].type;
1489                 i2c_index = pNv->dcb_table.entry[i].i2c_index;
1490                 or = ffs(pNv->dcb_table.entry[i].or);
1491
1492                 if (type < 4) {
1493                         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry %d: type: %d, i2c_index: %d, or: %d\n", i, type, i2c_index, or);
1494
1495                         switch(type) {
1496                         case OUTPUT_ANALOG:
1497                                 nv_add_analog_output(pScrn, or, i2c_index, dvi_pair[i]);
1498                                 break;
1499                         case OUTPUT_TMDS:
1500                                 nv_add_digital_output(pScrn, or, i2c_index, 0);
1501                                 break;
1502                         case OUTPUT_LVDS:
1503                                 nv_add_digital_output(pScrn, or, i2c_index, 1);
1504                                 break;
1505                         default:
1506                                 break;
1507                         }
1508                 }
1509         }
1510 }
1511
1512 void NvSetupOutputs(ScrnInfoPtr pScrn)
1513 {
1514         NVPtr pNv = NVPTR(pScrn);
1515
1516         pNv->Television = FALSE;
1517
1518         memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1519         NvDCBSetupOutputs(pScrn);
1520 }
1521
1522 /*************************************************************************** \
1523 |*                                                                           *|
1524 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1525 |*                                                                           *|
1526 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1527 |*     international laws.  Users and possessors of this source code are     *|
1528 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1529 |*     use this code in individual and commercial software.                  *|
1530 |*                                                                           *|
1531 |*     Any use of this source code must include,  in the user documenta-     *|
1532 |*     tion and  internal comments to the code,  notices to the end user     *|
1533 |*     as follows:                                                           *|
1534 |*                                                                           *|
1535 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1536 |*                                                                           *|
1537 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1538 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1539 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1540 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1541 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1542 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1543 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1544 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1545 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1546 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1547 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1548 |*                                                                           *|
1549 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1550 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1551 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1552 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1553 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1554 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1555 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1556 |*     all U.S. Government End Users  acquire the source code  with only     *|
1557 |*     those rights set forth herein.                                        *|
1558 |*                                                                           *|
1559  \***************************************************************************/