randr12: We cannot reset ramdacs during detect, there may not be a modesetting after it.
[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 #ifdef ENABLE_RANDR12
34
35 #include "xf86.h"
36 #include "os.h"
37 #include "mibank.h"
38 #include "globals.h"
39 #include "xf86.h"
40 #include "xf86Priv.h"
41 #include "xf86DDC.h"
42 #include "mipointer.h"
43 #include "windowstr.h"
44 #include <randrstr.h>
45 #include <X11/extensions/render.h>
46
47 #include "xf86Crtc.h"
48 #include "nv_include.h"
49
50 const char *OutputType[] = {
51     "None",
52     "VGA",
53     "DVI",
54     "LVDS",
55     "S-video",
56     "Composite",
57 };
58
59 const char *MonTypeName[7] = {
60     "AUTO",
61     "NONE",
62     "CRT",
63     "LVDS",
64     "TMDS",
65     "CTV",
66     "STV"
67 };
68
69 /* 
70  * TMDS registers are indirect 8 bit registers.
71  * Reading is straightforward, writing a bit odd.
72  * Reading: Write adress (+write protect bit, do not forget this), then read value.
73  * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
74  */
75
76 void NVWriteTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
77 {
78         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
79                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
80
81         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
82
83         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
84         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
85                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
86 }
87
88 CARD8 NVReadTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg)
89 {
90         nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
91                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
92
93         return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
94 }
95
96 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
97 {
98         NVOutputPrivatePtr nv_output = output->driver_private;
99         ScrnInfoPtr     pScrn = output->scrn;
100         NVPtr pNv = NVPTR(pScrn);
101         int ramdac;
102
103         /* Is TMDS programmed on a different output? */
104         /* Always choose the prefered ramdac, since that one contains the tmds stuff */
105         /* Assumption: there is always once output that can only run of the primary ramdac */
106         if (nv_output->valid_ramdac & RAMDAC_1) {
107                 ramdac = 1;
108         } else {
109                 ramdac = 0;
110         }
111
112         NVWriteTMDS(pNv, ramdac, tmds_reg, val);
113 }
114
115 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
116 {
117         NVOutputPrivatePtr nv_output = output->driver_private;
118         ScrnInfoPtr     pScrn = output->scrn;
119         NVPtr pNv = NVPTR(pScrn);
120         int ramdac;
121
122         /* Is TMDS programmed on a different output? */
123         /* Always choose the prefered ramdac, since that one contains the tmds stuff */
124         /* Assumption: there is always once output that can only run of the primary ramdac */
125         if (nv_output->valid_ramdac & RAMDAC_1) {
126                 ramdac = 1;
127         } else {
128                 ramdac = 0;
129         }
130
131         return NVReadTMDS(pNv, ramdac, tmds_reg);
132 }
133
134 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
135 {
136     NVOutputPrivatePtr nv_output = output->driver_private;
137     ScrnInfoPtr pScrn = output->scrn;
138     NVPtr pNv = NVPTR(pScrn);
139
140     nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
141 }
142
143 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
144 {
145     NVOutputPrivatePtr nv_output = output->driver_private;
146     ScrnInfoPtr pScrn = output->scrn;
147     NVPtr pNv = NVPTR(pScrn);
148
149     return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
150 }
151
152 static void nv_output_backlight_enable(xf86OutputPtr output,  Bool on)
153 {
154     ScrnInfoPtr pScrn = output->scrn;
155     NVPtr pNv = NVPTR(pScrn);   
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     {
165         /* NV17,18,34 Apple iMac, iBook, PowerBook */
166         CARD32 tmp_pmc, tmp_pcrt;
167         tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
168         tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
169         if(on) {
170             tmp_pmc |= (1 << 31);
171             tmp_pcrt |= 0x1;
172         }
173         nvWriteMC(pNv, 0x10F0, tmp_pmc);
174         nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
175     }
176 #endif
177     
178     if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
179         nvWriteMC(pNv, 0x130C, on ? 3 : 7);
180 }
181
182 static void
183 nv_panel_output_dpms(xf86OutputPtr output, int mode)
184 {
185
186     switch(mode) {
187     case DPMSModeStandby:
188     case DPMSModeSuspend:
189     case DPMSModeOff:
190         nv_output_backlight_enable(output, 0);
191         break;
192     case DPMSModeOn:
193         nv_output_backlight_enable(output, 1);
194     default:
195         break;
196     }
197 }
198
199 static void
200 nv_analog_output_dpms(xf86OutputPtr output, int mode)
201 {
202         xf86CrtcPtr crtc = output->crtc;
203
204         if (crtc) {
205                 NVPtr pNv = NVPTR(output->scrn);
206                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
207
208                 /* We are going for modesetting, so we must reset the ramdacs */
209                 if (mode == DPMSModeOff) {
210                                 ScrnInfoPtr pScrn = output->scrn;
211                                 NVPtr pNv = NVPTR(pScrn);
212                                 NVOutputPrivatePtr nv_output = output->driver_private;
213                                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
214
215                                 /* We no longer have ramdac, which will be reassigned soon enough */
216                                 pNv->ramdac_active[nv_output->ramdac] = FALSE;
217                                 nv_output->ramdac_assigned = FALSE;
218                                 nv_output->ramdac = -1;
219                 }
220
221                 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
222         }
223 }
224
225 static void
226 nv_digital_output_dpms(xf86OutputPtr output, int mode)
227 {
228         xf86CrtcPtr crtc = output->crtc;
229         NVOutputPrivatePtr nv_output = output->driver_private;
230
231         /* Are we assigned a ramdac already?, else we will be activeted during mode set */
232         if (crtc && nv_output->ramdac_assigned) {
233                 NVPtr pNv = NVPTR(output->scrn);
234                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
235
236                 ErrorF("nv_digital_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
237
238                 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
239                 switch(mode) {
240                         case DPMSModeStandby:
241                         case DPMSModeSuspend:
242                         case DPMSModeOff:
243                                 /* cut the TMDS output */           
244                                 fpcontrol |= 0x20000022;
245                                 break;
246                         case DPMSModeOn:
247                                 /* disable cutting the TMDS output */
248                                 fpcontrol &= ~0x20000022;
249                                 break;
250                 }
251                 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
252
253                 /* We are going for modesetting, so we must reset the ramdacs */
254                 if (mode == DPMSModeOff) {
255                                 ScrnInfoPtr pScrn = output->scrn;
256                                 NVPtr pNv = NVPTR(pScrn);
257                                 NVOutputPrivatePtr nv_output = output->driver_private;
258                                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
259
260                                 /* We no longer have ramdac, which will be reassigned soon enough */
261                                 pNv->ramdac_active[nv_output->ramdac] = FALSE;
262                                 nv_output->ramdac_assigned = FALSE;
263                                 nv_output->ramdac = -1;
264                 }
265         }
266 }
267
268 int tmds_regs[] = { 0x4, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x3a };
269
270 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
271 {
272         NVOutputPrivatePtr nv_output = output->driver_private;
273         ScrnInfoPtr pScrn = output->scrn;
274         NVPtr pNv = NVPTR(pScrn);
275         NVOutputRegPtr regp;
276         int i;
277
278         regp = &state->dac_reg[nv_output->ramdac];
279         regp->general       = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
280         regp->fp_control    = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
281         regp->debug_0   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
282         regp->debug_1   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
283         regp->debug_2   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
284         regp->sel_clk           = NVOutputReadRAMDAC(output, NV_RAMDAC_SEL_CLK);
285         state->config       = nvReadFB(pNv, NV_PFB_CFG0);
286
287         regp->unk_a20 = NVOutputReadRAMDAC(output, NV_RAMDAC_A20);
288         regp->unk_a24 = NVOutputReadRAMDAC(output, NV_RAMDAC_A24);
289         regp->unk_a34 = NVOutputReadRAMDAC(output, NV_RAMDAC_A34);
290
291         regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
292
293         if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
294                 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
295         } else if (pNv->twoHeads) {
296                 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
297         }
298         regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
299
300         for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
301                 regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
302         }
303
304         /* The regs below are 0 for non-flatpanels, so you can load and save them */
305
306         for (i = 0; i < 7; i++) {
307                 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
308                 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
309         }
310
311         for (i = 0; i < 7; i++) {
312                 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
313                 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
314         }
315
316         regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
317         regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
318         regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
319         regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
320 }
321
322 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
323 {
324         NVOutputPrivatePtr nv_output = output->driver_private;
325         ScrnInfoPtr     pScrn = output->scrn;
326         NVPtr pNv = NVPTR(pScrn);
327         NVOutputRegPtr regp;
328         int i;
329
330         regp = &state->dac_reg[nv_output->ramdac];
331
332         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
333         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
334         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
335         NVOutputWriteRAMDAC(output, NV_RAMDAC_SEL_CLK, regp->sel_clk);
336         NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
337         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
338
339         NVOutputWriteRAMDAC(output, NV_RAMDAC_A20, regp->unk_a20);
340         NVOutputWriteRAMDAC(output, NV_RAMDAC_A24, regp->unk_a24);
341         NVOutputWriteRAMDAC(output, NV_RAMDAC_A34, regp->unk_a34);
342
343         if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
344                 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
345         } else if (pNv->twoHeads) {
346                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
347         }
348
349         NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
350         NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
351
352         for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
353                 NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
354         }
355
356         /* The regs below are 0 for non-flatpanels, so you can load and save them */
357
358         for (i = 0; i < 7; i++) {
359                 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
360                 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
361         }
362
363         for (i = 0; i < 7; i++) {
364                 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
365                 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
366         }
367
368         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
369         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
370         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
371         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
372 }
373
374 /* NOTE: Don't rely on this data for anything other than restoring VT's */
375
376 static void
377 nv_output_save (xf86OutputPtr output)
378 {
379         ScrnInfoPtr     pScrn = output->scrn;
380         NVPtr pNv = NVPTR(pScrn);
381         RIVA_HW_STATE *state;
382         NVOutputPrivatePtr nv_output = output->driver_private;
383         int ramdac_backup = nv_output->ramdac;
384
385         ErrorF("nv_output_save is called\n");
386
387         /* This is early init and we have not yet been assigned a ramdac */
388         /* Always choose the prefered ramdac, for consistentcy */
389         /* Assumption: there is always once output that can only run of the primary ramdac */
390         if (nv_output->valid_ramdac & RAMDAC_1) {
391                 nv_output->ramdac = 1;
392         } else {
393                 nv_output->ramdac = 0;
394         }
395
396         state = &pNv->SavedReg;
397
398         /* Due to strange mapping of outputs we could have swapped analog and digital */
399         /* So we force save all the registers */
400         nv_output_save_state_ext(output, state, TRUE);
401
402         /* restore previous state */
403         nv_output->ramdac = ramdac_backup;
404 }
405
406 static void
407 nv_output_restore (xf86OutputPtr output)
408 {
409         ScrnInfoPtr     pScrn = output->scrn;
410         NVPtr pNv = NVPTR(pScrn);
411         RIVA_HW_STATE *state;
412         NVOutputPrivatePtr nv_output = output->driver_private;
413         int ramdac_backup = nv_output->ramdac;
414
415         ErrorF("nv_output_restore is called\n");
416
417         /* We want consistent mode restoring and the ramdac entry is variable */
418         /* Always choose the prefered ramdac, for consistentcy */
419         /* Assumption: there is always once output that can only run of the primary ramdac */
420         if (nv_output->valid_ramdac & RAMDAC_1) {
421                 nv_output->ramdac = 1;
422         } else {
423                 nv_output->ramdac = 0;
424         }
425
426         state = &pNv->SavedReg;
427
428         /* Due to strange mapping of outputs we could have swapped analog and digital */
429         /* So we force load all the registers */
430         nv_output_load_state_ext(output, state, TRUE);
431
432         /* restore previous state */
433         nv_output->ramdac = ramdac_backup;
434 }
435
436 static int
437 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
438 {
439     if (pMode->Flags & V_DBLSCAN)
440         return MODE_NO_DBLESCAN;
441   
442     if (pMode->Clock > 400000 || pMode->Clock < 25000)
443         return MODE_CLOCK_RANGE;
444   
445     return MODE_OK;
446 }
447
448
449 static Bool
450 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
451                      DisplayModePtr adjusted_mode)
452 {
453         ErrorF("nv_output_mode_fixup is called\n");
454
455         return TRUE;
456 }
457
458 static int
459 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
460 {
461     NVOutputPrivatePtr nv_output = output->driver_private;
462     ScrnInfoPtr pScrn = output->scrn;
463     NVPtr pNv = NVPTR(pScrn);
464     NVOutputRegPtr regp;
465     int tweak = 0;
466   
467     regp = &state->dac_reg[nv_output->ramdac];
468     if (pNv->usePanelTweak) {
469         tweak = pNv->PanelTweak;
470     } else {
471         /* begin flat panel hacks */
472         /* This is unfortunate, but some chips need this register
473            tweaked or else you get artifacts where adjacent pixels are
474            swapped.  There are no hard rules for what to set here so all
475            we can do is experiment and apply hacks. */
476     
477         if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
478             /* At least one NV34 laptop needs this workaround. */
479             tweak = -1;
480         }
481                 
482         if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
483             tweak = 1;
484         }
485         /* end flat panel hacks */
486     }
487     return tweak;
488 }
489
490 static void
491 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
492 {
493         NVOutputPrivatePtr nv_output = output->driver_private;
494         ScrnInfoPtr pScrn = output->scrn;
495         int bpp;
496         NVPtr pNv = NVPTR(pScrn);
497         NVFBLayout *pLayout = &pNv->CurrentLayout;
498         RIVA_HW_STATE *state, *sv_state;
499         Bool is_fp = FALSE;
500         NVOutputRegPtr regp, regp2, savep;
501         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
502         float aspect_ratio, panel_ratio;
503         uint32_t h_scale, v_scale;
504         int i;
505
506         state = &pNv->ModeReg;
507         regp = &state->dac_reg[nv_output->ramdac];
508         /* The other ramdac */
509         regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
510
511         sv_state = &pNv->SavedReg;
512         savep = &sv_state->dac_reg[nv_output->ramdac];
513
514         if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
515                 is_fp = TRUE;
516
517                 /* Do we need to set the native mode or not? */
518                 if (pNv->fpScaler) {
519                         /* We can set the mode as usual if we let the panel scale */
520                         regp->fp_horiz_regs[REG_DISP_END] = mode->HDisplay - 1;
521                         regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->HTotal - 1;
522                         regp->fp_horiz_regs[REG_DISP_CRTC] = mode->HDisplay;
523                         regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->HSyncStart - 1;
524                         regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->HSyncEnd - 1;
525                         regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->HSkew;
526                         regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->HDisplay - 1;
527
528                         regp->fp_vert_regs[REG_DISP_END] = mode->VDisplay - 1;
529                         regp->fp_vert_regs[REG_DISP_TOTAL] = mode->VTotal - 1;
530                         regp->fp_vert_regs[REG_DISP_CRTC] = mode->VDisplay;
531                         regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->VSyncStart - 1;
532                         regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->VSyncEnd - 1;
533                         regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
534                         regp->fp_vert_regs[REG_DISP_VALID_END] = mode->VDisplay - 1;
535                 } else {
536                         /* For gpu scaling we need the native mode */
537                         /* Let's find our native mode amongst all the ddc modes */
538                         DisplayModePtr native = nv_output->monitor_modes;
539                         do {
540                                 /* assumption: each mode has it's unique clock */
541                                 if (nv_output->clock == native->Clock) {
542                                         break;
543                                 }
544                         } while (native = native->next);
545                         regp->fp_horiz_regs[REG_DISP_END] = native->HDisplay - 1;
546                         regp->fp_horiz_regs[REG_DISP_TOTAL] = native->HTotal - 1;
547                         regp->fp_horiz_regs[REG_DISP_CRTC] = native->HDisplay;
548                         regp->fp_horiz_regs[REG_DISP_SYNC_START] = native->HSyncStart - 1;
549                         regp->fp_horiz_regs[REG_DISP_SYNC_END] = native->HSyncEnd - 1;
550                         regp->fp_horiz_regs[REG_DISP_VALID_START] = native->HSkew;
551                         regp->fp_horiz_regs[REG_DISP_VALID_END] = native->HDisplay - 1;
552
553                         regp->fp_vert_regs[REG_DISP_END] = native->VDisplay - 1;
554                         regp->fp_vert_regs[REG_DISP_TOTAL] = native->VTotal - 1;
555                         regp->fp_vert_regs[REG_DISP_CRTC] = native->VDisplay;
556                         regp->fp_vert_regs[REG_DISP_SYNC_START] = native->VSyncStart - 1;
557                         regp->fp_vert_regs[REG_DISP_SYNC_END] = native->VSyncEnd - 1;
558                         regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
559                         regp->fp_vert_regs[REG_DISP_VALID_END] = native->VDisplay - 1;
560                 }
561
562                 ErrorF("Horizontal:\n");
563                 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_END]);
564                 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_horiz_regs[REG_DISP_TOTAL]);
565                 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_horiz_regs[REG_DISP_CRTC]);
566                 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_START]);
567                 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_END]);
568                 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_START]);
569                 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_END]);
570
571                 ErrorF("Vertical:\n");
572                 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_END]);
573                 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_vert_regs[REG_DISP_TOTAL]);
574                 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_vert_regs[REG_DISP_CRTC]);
575                 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_START]);
576                 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_END]);
577                 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_START]);
578                 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_END]);
579         }
580
581         /* This register is only used on the primary ramdac */
582         /* The value 0x40000 is not acceptable in text mode, but seems to do no harm in X mode */
583         /* The blob does this often, the exact purpose is not exactly known */
584         if (nv_output->ramdac == 0) {
585                 regp->sel_clk = nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) | (1 << 18);
586         }
587
588         /* This seems to be a common mode
589         * bit0: positive vsync
590         * bit4: positive hsync
591         * bit8: enable panel scaling 
592         * This must also be set for non-flatpanels
593         */
594         regp->fp_control = 0x11100000;
595
596         /* Deal with vsync/hsync polarity */
597         if (mode->Flags & V_PVSYNC) {
598                 regp->fp_control |= (1 << 0);
599         }
600
601         if (mode->Flags & V_PHSYNC) {
602                 regp->fp_control |= (1 << 4);
603         }
604
605         if (is_fp) {
606                 ErrorF("Pre-panel scaling\n");
607                 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
608                 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
609                 ErrorF("panel_ratio=%f\n", panel_ratio);
610                 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
611                 ErrorF("aspect_ratio=%f\n", aspect_ratio);
612                 /* Scale factors is the so called 20.12 format, taken from Haiku */
613                 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
614                 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
615                 ErrorF("h_scale=%d\n", h_scale);
616                 ErrorF("v_scale=%d\n", v_scale);
617
618                 /* Don't limit last fetched line */
619                 regp->debug_2 = 0;
620
621                 /* We want automatic scaling */
622                 regp->debug_1 = 0;
623
624                 regp->fp_hvalid_start = 0;
625                 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
626
627                 regp->fp_vvalid_start = 0;
628                 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
629
630                 if (pNv->fpScaler) {
631                         ErrorF("Flat panel is doing the scaling.\n");
632                         regp->fp_control |= (1 << 8);
633                 } else {
634                         ErrorF("GPU is doing the scaling.\n");
635                         /* GPU scaling happens automaticly at a ratio of 1:33 */
636                         /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
637                         if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
638                                 uint32_t diff;
639
640                                 ErrorF("Scaling resolution on a widescreen panel\n");
641
642                                 /* Scaling in both directions needs to the same */
643                                 h_scale = v_scale;
644
645                                 /* Set a new horizontal scale factor and enable testmode (bit12) */
646                                 regp->debug_1 = ((h_scale >> 1) & 0xfff) | (1 << 12);
647
648                                 diff = nv_output->fpWidth - (((1 << 12) * mode->HDisplay)/h_scale);
649                                 regp->fp_hvalid_start = diff/2;
650                                 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
651                         }
652
653                         /* Same scaling, just for panels with aspect ratio's smaller than 1 */
654                         /* This may be broken */
655                         if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
656                                 uint32_t diff;
657
658                                 ErrorF("Scaling resolution on a portrait panel\n");
659
660                                 /* Scaling in both directions needs to the same */
661                                 v_scale = h_scale;
662
663                                 /* Is this ok, since haiku only does widescreen panels? */
664                                 regp->debug_1 = ((v_scale >> 1) & 0xfff) | (1 << 12);
665
666                                 diff = nv_output->fpHeight - (((1 << 12) * mode->VDisplay)/v_scale);
667                                 regp->fp_vvalid_start = diff/2;
668                                 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
669                         }
670                 }
671
672                 ErrorF("Post-panel scaling\n");
673         }
674
675         if (pNv->Architecture >= NV_ARCH_10) {
676                 /* Bios and blob don't seem to do anything (else) */
677                 regp->nv10_cursync = (1<<25);
678         }
679
680         /* These are the common blob values, minus a few fp specific bit's */
681         /* The OR mask is in case the powerdown switch was enabled from the other output */
682         regp->debug_0 |= 0x1101111;
683
684         if(is_fp) {
685                 /* I am not completely certain, but seems to be set only for dfp's */
686                 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED;
687         }
688
689         /* We must ensure that we never disable the wrong tmds control */
690         /* Assumption: one output can only run of ramdac 0 */
691         if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)) {
692                 if (is_fp) {
693                         regp2->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
694                 } else {
695                         regp2->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
696                 }
697         } else {
698                 if (is_fp) {
699                         regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
700                 } else {
701                         regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
702                 }
703         }
704
705         ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
706
707         /* This is just a guess, there are probably more registers which need setting */
708         /* But we must start somewhere ;-) */
709         if (is_fp) {
710                 regp->TMDS[0x4] = 0x80;
711                 /* Enable crosswired mode */
712                 /* As far as i know, this may never be set on ramdac 0 tmds registers (ramdac 1 -> crosswired -> ramdac 0 tmds regs) */
713                 /* This will upset the monitor, trust me, i know it :-( */
714                 /* Restricting to cards that had this setup at bootup time, until i am certain it's ok to use */
715                 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)
716                         && pNv->output_info & OUTPUT_1_CROSSWIRED_TMDS) {
717                         regp->TMDS[0x4] |= (1 << 3);
718                 }
719         }
720
721         /* Completely unknown TMDS registers:
722          * 0x0
723          * 0x1
724          * 0x2
725          * 0x5
726          */
727
728         /* The TMDS game begins */
729         /* A few registers are also programmed on non-tmds monitors */
730         /* At the moment i can't give rationale for these values */
731         if (!is_fp) {
732                 regp->TMDS[0x2e] = 0x80;
733                 regp->TMDS[0x2f] = 0xff;
734                 regp->TMDS[0x33] = 0xfe;
735         } else {
736                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
737                 regp->TMDS[0x2b] = 0x7d;
738                 regp->TMDS[0x2c] = 0x0;
739                 if (nv_crtc->head == 1) {
740                         regp->TMDS[0x2e] = 0x81;
741                 } else {
742                         regp->TMDS[0x2e] = 0x85;
743                 }
744                 regp->TMDS[0x2f] = 0x21;
745                 regp->TMDS[0x30] = 0x0;
746                 regp->TMDS[0x31] = 0x0;
747                 regp->TMDS[0x32] = 0x0;
748                 regp->TMDS[0x33] = 0xf0;
749                 regp->TMDS[0x3a] = 0x80;
750         }
751
752         /* Flatpanel support needs at least a NV10 */
753         if(pNv->twoHeads) {
754                 /* Instead of 1, several other values are also used: 2, 7, 9 */
755                 /* The purpose is unknown */
756                 if(pNv->FPDither) {
757                         regp->dither = 0x00010000;
758                 }
759         }
760
761         if(pLayout->depth < 24) {
762                 bpp = pLayout->depth;
763         } else {
764                 bpp = 32;
765         }
766
767         /* Kindly borrowed from haiku driver */
768         /* bit4 and bit5 activate indirect mode trough color palette */
769         switch (pLayout->depth) {
770                 case 32:
771                 case 16:
772                         regp->general = 0x00101130;
773                         break;
774                 case 24:
775                 case 15:
776                         regp->general = 0x00100130;
777                         break;
778                 case 8:
779                 default:
780                         regp->general = 0x00101100;
781                         break;
782         }
783
784         if (pNv->alphaCursor) {
785                 regp->general |= (1<<29);
786         }
787
788         regp->bpp = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
789
790         /* Some values the blob sets */
791         /* This may apply to the real ramdac that is being used (for crosswired situations) */
792         /* Nevertheless, it's unlikely to cause many problems, since the values are equal for both */
793         regp->unk_a20 = 0x0;
794         regp->unk_a24 = 0xfffff;
795         regp->unk_a34 = 0x1;
796
797         if (output->crtc) {
798                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
799                 int two_crt = FALSE;
800                 int two_mon = FALSE;
801
802                 for (i = 0; i < config->num_output; i++) {
803                         NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
804
805                         /* is it this output ?? */
806                         if (config->output[i] == output)
807                                 continue;
808
809                         /* it the output connected */
810                         if (config->output[i]->crtc == NULL)
811                                 continue;
812
813                         two_mon = TRUE;
814                         if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
815                                 two_crt = TRUE;
816                         }
817                 }
818
819                 if (is_fp == TRUE) {
820                         regp->output = 0x0;
821                 } else { 
822                         regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
823                 }
824
825                 if (nv_crtc->head == 1) {
826                         regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
827                 } else {
828                         regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_CRTC1;
829                 }
830
831                 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);
832         }
833 }
834
835 static void
836 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
837                    DisplayModePtr adjusted_mode)
838 {
839     ScrnInfoPtr pScrn = output->scrn;
840     NVPtr pNv = NVPTR(pScrn);
841     RIVA_HW_STATE *state;
842
843         ErrorF("nv_output_mode_set is called\n");
844
845     state = &pNv->ModeReg;
846
847     nv_output_mode_set_regs(output, mode);
848     nv_output_load_state_ext(output, state, FALSE);
849 }
850
851 static Bool
852 nv_ddc_detect(xf86OutputPtr output)
853 {
854         /* no use for shared DDC output */
855         NVOutputPrivatePtr nv_output = output->driver_private;
856         xf86MonPtr ddc_mon;
857         ScrnInfoPtr     pScrn = output->scrn;
858
859         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
860         if (!ddc_mon)
861                 return FALSE;
862
863         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
864                 return FALSE;
865
866         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
867                 return FALSE;
868         }
869
870         if (nv_output->type == OUTPUT_DIGITAL) {
871                 int i, j;
872                 for (i = 0; i < 4; i++) {
873                         /* Filter out the stupid entries */
874                         if (ddc_mon->det_mon[i].section.d_timings.h_active > 4096)
875                                 continue;
876                         if (ddc_mon->det_mon[i].section.d_timings.v_active > 4096)
877                                 continue;
878                         /* Selecting only based on width ok? */
879                         if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
880                                 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
881                                 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
882                                 /* ddc clocks are in Hz, while mode clocks are in kHz */
883                                 nv_output->clock = ddc_mon->det_mon[i].section.d_timings.clock/1000;
884                                 /* Find the matchig native refresh rate */
885                                 for (j = 0; i < 5; i++) {
886                                         if (ddc_mon->det_mon[i].section.std_t[j].hsize == nv_output->fpWidth &&
887                                                 ddc_mon->det_mon[i].section.std_t[j].vsize == nv_output->fpHeight) {
888
889                                                 nv_output->refresh = ddc_mon->det_mon[i].section.std_t[j].refresh;
890                                                 break;
891                                         }
892                                 }
893                                 nv_output->monitor_modes = xf86DDCGetModes(pScrn->scrnIndex, ddc_mon);
894                         }
895                 }
896         }
897
898         return TRUE;
899 }
900
901 static Bool
902 nv_crt_load_detect(xf86OutputPtr output)
903 {
904     ScrnInfoPtr pScrn = output->scrn;
905     CARD32 reg_output, reg_test_ctrl, temp;
906     int present = FALSE;
907           
908     reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
909     reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
910
911     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
912     
913     NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
914     usleep(1000);
915           
916     temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
917     NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
918
919     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
920     temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
921     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
922
923     usleep(1000);
924           
925     present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
926           
927     temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
928     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
929           
930     NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
931     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
932     
933     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
934                present);
935
936     return present;
937
938 }
939
940 static xf86OutputStatus
941 nv_digital_output_detect(xf86OutputPtr output)
942 {
943     NVOutputPrivatePtr nv_output = output->driver_private;
944
945         ErrorF("nv_digital_output_detect is called\n");
946
947     if (nv_ddc_detect(output))
948         return XF86OutputStatusConnected;
949
950     return XF86OutputStatusDisconnected;
951 }
952
953
954 static xf86OutputStatus
955 nv_analog_output_detect(xf86OutputPtr output)
956 {
957     NVOutputPrivatePtr nv_output = output->driver_private;
958
959         ErrorF("nv_analog_output_detect is called\n");
960
961     if (nv_ddc_detect(output))
962         return XF86OutputStatusConnected;
963
964         /* Disabled for now, since we don't actually have a ramdac yet and i need time to figure out a nice way to do this ;-) */
965         /* seems a bit flaky on ramdac 1 */
966         //if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
967                 //return XF86OutputStatusConnected;
968
969     return XF86OutputStatusDisconnected;
970 }
971
972 static DisplayModePtr
973 nv_output_get_modes(xf86OutputPtr output)
974 {
975     ScrnInfoPtr pScrn = output->scrn;
976     NVOutputPrivatePtr nv_output = output->driver_private;
977     xf86MonPtr ddc_mon;
978     DisplayModePtr ddc_modes, mode;
979
980         ErrorF("nv_output_get_modes is called\n");
981
982     ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
983
984     if (ddc_mon == NULL) {
985         xf86OutputSetEDID(output, ddc_mon);
986         return NULL;
987     }
988
989     if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
990         xf86OutputSetEDID(output, NULL);
991         return NULL;
992     }
993
994     if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
995         xf86OutputSetEDID(output, NULL);
996         return NULL;
997     }
998
999     xf86OutputSetEDID(output, ddc_mon);
1000
1001     ddc_modes = xf86OutputGetEDIDModes (output);          
1002     return ddc_modes;
1003
1004 }
1005
1006 static void
1007 nv_output_destroy (xf86OutputPtr output)
1008 {
1009         ErrorF("nv_output_destroy is called\n");
1010         if (output->driver_private)
1011                 xfree (output->driver_private);
1012
1013 }
1014
1015 static void
1016 nv_output_prepare(xf86OutputPtr output)
1017 {
1018         ErrorF("nv_output_prepare is called\n");
1019         NVOutputPrivatePtr nv_output = output->driver_private;
1020         ScrnInfoPtr     pScrn = output->scrn;
1021         NVPtr pNv = NVPTR(pScrn);
1022
1023         if (nv_output->ramdac_assigned) {
1024                 ErrorF("We already have a ramdac, what went wrong?\n");
1025                 return;
1026         }
1027
1028         if ((nv_output->valid_ramdac & RAMDAC_0) && !(pNv->ramdac_active[0])) {
1029                 pNv->ramdac_active[0] = TRUE;
1030                 nv_output->ramdac = 0;
1031         } else if ((nv_output->valid_ramdac & RAMDAC_1) && !(pNv->ramdac_active[1])) {
1032                 pNv->ramdac_active[1] = TRUE;
1033                 nv_output->ramdac = 1;
1034         }
1035
1036         if (nv_output->ramdac != -1)
1037                 nv_output->ramdac_assigned = TRUE;
1038 }
1039
1040 static void
1041 nv_output_commit(xf86OutputPtr output)
1042 {
1043         ErrorF("nv_output_commit is called\n");
1044 }
1045
1046 static const xf86OutputFuncsRec nv_analog_output_funcs = {
1047     .dpms = nv_analog_output_dpms,
1048     .save = nv_output_save,
1049     .restore = nv_output_restore,
1050     .mode_valid = nv_output_mode_valid,
1051     .mode_fixup = nv_output_mode_fixup,
1052     .mode_set = nv_output_mode_set,
1053     .detect = nv_analog_output_detect,
1054     .get_modes = nv_output_get_modes,
1055     .destroy = nv_output_destroy,
1056     .prepare = nv_output_prepare,
1057     .commit = nv_output_commit,
1058 };
1059
1060 static const xf86OutputFuncsRec nv_digital_output_funcs = {
1061     .dpms = nv_digital_output_dpms,
1062     .save = nv_output_save,
1063     .restore = nv_output_restore,
1064     .mode_valid = nv_output_mode_valid,
1065     .mode_fixup = nv_output_mode_fixup,
1066     .mode_set = nv_output_mode_set,
1067     .detect = nv_digital_output_detect,
1068     .get_modes = nv_output_get_modes,
1069     .destroy = nv_output_destroy,
1070     .prepare = nv_output_prepare,
1071     .commit = nv_output_commit,
1072 };
1073
1074 static xf86OutputStatus
1075 nv_output_lvds_detect(xf86OutputPtr output)
1076 {
1077     return XF86OutputStatusUnknown;    
1078 }
1079
1080 static DisplayModePtr
1081 nv_output_lvds_get_modes(xf86OutputPtr output)
1082 {
1083     ScrnInfoPtr pScrn = output->scrn;
1084     NVOutputPrivatePtr nv_output = output->driver_private;
1085
1086     //    nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1087     //    nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1088     nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1089     //    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
1090     //         nv_output->fpWidth, nv_output->fpHeight);
1091
1092     return NULL;
1093
1094 }
1095
1096 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1097     .dpms = nv_panel_output_dpms,
1098     .save = nv_output_save,
1099     .restore = nv_output_restore,
1100     .mode_valid = nv_output_mode_valid,
1101     .mode_fixup = nv_output_mode_fixup,
1102     .mode_set = nv_output_mode_set,
1103     .detect = nv_output_lvds_detect,
1104     .get_modes = nv_output_lvds_get_modes,
1105     .destroy = nv_output_destroy,
1106     .prepare = nv_output_prepare,
1107     .commit = nv_output_commit,
1108 };
1109
1110
1111 static void nv_add_analog_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dvi_pair)
1112 {
1113         NVPtr pNv = NVPTR(pScrn);
1114         xf86OutputPtr       output;
1115         NVOutputPrivatePtr    nv_output;
1116         char outputname[20];
1117         int crtc_mask = (1<<0) | (1<<1);
1118         int real_index;
1119         Bool create_output = TRUE;
1120
1121         sprintf(outputname, "Analog-%d", pNv->analog_count);
1122         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1123         if (!nv_output) {
1124                 return;
1125         }
1126
1127         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1128                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1129
1130         nv_output->type = OUTPUT_ANALOG;
1131
1132         /* order + 1:
1133          * bit0: RAMDAC_0 valid
1134          * bit1: RAMDAC_1 valid
1135          * So lowest order has highest priority.
1136          */
1137         nv_output->valid_ramdac = order + 1;
1138
1139         if (!create_output) {
1140                 xfree(nv_output);
1141                 return;
1142         }
1143
1144         /* Delay creation of output until we actually know we want it */
1145         output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1146         if (!output)
1147                 return;
1148
1149         output->driver_private = nv_output;
1150
1151         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1152
1153         output->possible_crtcs = crtc_mask;
1154         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1155
1156         pNv->analog_count++;
1157 }
1158
1159
1160 static void nv_add_digital_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dual_dvi, int lvds)
1161 {
1162         NVPtr pNv = NVPTR(pScrn);
1163         xf86OutputPtr       output;
1164         NVOutputPrivatePtr    nv_output;
1165         char outputname[20];
1166         int crtc_mask = (1<<0) | (1<<1);
1167         Bool create_output = TRUE;
1168         int index = i2c_index;
1169
1170         sprintf(outputname, "Digital-%d", pNv->digital_count);
1171         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1172
1173         if (!nv_output) {
1174                 return;
1175         }
1176
1177         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1178                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1179
1180         nv_output->type = OUTPUT_DIGITAL;
1181
1182         /* order + 1:
1183          * bit0: RAMDAC_0 valid
1184          * bit1: RAMDAC_1 valid
1185          * So lowest order has highest priority.
1186          */
1187         nv_output->valid_ramdac = order + 1;
1188
1189         /* Sorry, i don't know what to do with lvds */
1190         if (!lvds) {
1191                 int real_index;
1192                 /* Is anyone crosswired?, pick the other index */
1193                 if (pNv->output_info & OUTPUT_0_CROSSWIRED_TMDS || 
1194                         pNv->output_info & OUTPUT_1_CROSSWIRED_TMDS) {
1195
1196                         real_index = (~index) & 1; 
1197                 } else {
1198                         real_index = index;
1199                 }
1200
1201                 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1202
1203                 /* This detection may be flawed, it will corrected as soon as i have a good idea */
1204
1205                 /* At the moment something must be already active, before we do anything */
1206                 if (nvReadRAMDAC(pNv,  real_index, NV_RAMDAC_FP_DEBUG_0) & NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED) {
1207                         /* We're not supposed to be LVDS */
1208                         /* Using index, because this is part of the TMDS programming */
1209                         if (pNv->output_info & (OUTPUT_0_LVDS << index)) {
1210                                 ErrorF("Output refused because this is supposed to be TMDS, not LVDS.\n");
1211                                 create_output = FALSE;
1212                         }
1213                         /* we should be slaved to a ramdac, otherwise we don't exist */
1214                         if (!(pNv->output_info & (OUTPUT_0_SLAVED << real_index))) {
1215                                 ErrorF("Output refused because the output is not slaved, which is needed for a DFP.\n");
1216                                 create_output = FALSE;
1217                         }
1218                 } else {
1219                         ErrorF("Output refused because the DFP doesn't seem to be active.\n");
1220                         ErrorF("Debug info:\n");
1221                         ErrorF("Ramdac index: %d\n", real_index);
1222                         ErrorF("Ramdac0: NV_RAMDAC_FP_DEBUG_0: 0x%X\n", nvReadRAMDAC(pNv,  0, NV_RAMDAC_FP_DEBUG_0));
1223                         ErrorF("Ramdac1: NV_RAMDAC_FP_DEBUG_0: 0x%X\n", nvReadRAMDAC(pNv,  1, NV_RAMDAC_FP_DEBUG_0));
1224                         create_output = FALSE;
1225                 }
1226         } else {
1227                 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1228                 create_output = FALSE;
1229         }
1230
1231         if (!create_output) {
1232                 xfree(nv_output);
1233                 return;
1234         }
1235
1236         /* Delay creation of output until we are certain is desirable */
1237         if (lvds)
1238                 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1239         else
1240                 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
1241         if (!output)
1242                 return;
1243
1244         output->driver_private = nv_output;
1245
1246         output->possible_crtcs = crtc_mask;
1247         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1248
1249         pNv->digital_count++;
1250 }
1251
1252 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1253 {
1254         unsigned char type, i2c_index, or;
1255         NVPtr pNv = NVPTR(pScrn);
1256         int i;
1257         int num_digital = 0;
1258         Bool dual_dvi = FALSE;
1259         Bool dvi_pair = FALSE;
1260
1261         /* check how many TMDS ports there are */
1262         if (pNv->dcb_table.entries) {
1263                 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1264                         type = pNv->dcb_table.connection[i] & 0xf;
1265                         i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1266                         /* TMDS */
1267                         if (type == 2 && i2c_index != 0xf) {
1268                                 num_digital++;
1269                         }
1270                 }
1271         }
1272
1273         if (num_digital > 1) {
1274                 dual_dvi = TRUE;
1275         }
1276
1277         /* It's time to gather some information */
1278
1279         /* Being slaved indicates we're a flatpanel (or tv-out) */
1280         if (NVReadVGA0(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1281                 pNv->output_info |= OUTPUT_0_SLAVED;
1282         }
1283         if (NVReadVGA1(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1284                 pNv->output_info |= OUTPUT_1_SLAVED;
1285         }
1286         /* This is an educated guess */
1287         if (NVReadTMDS(pNv, 0, 0x4) & (1 << 3)) {
1288                 pNv->output_info |= OUTPUT_0_CROSSWIRED_TMDS;
1289         }
1290         if (NVReadTMDS(pNv, 1, 0x4) & (1 << 3)) {
1291                 pNv->output_info |= OUTPUT_1_CROSSWIRED_TMDS;
1292         }
1293         /* Are we LVDS? */
1294         if (NVReadTMDS(pNv, 0, 0x4) & (1 << 0)) {
1295                 pNv->output_info |= OUTPUT_0_LVDS;
1296         }
1297         if (NVReadTMDS(pNv, 1, 0x4) & (1 << 0)) {
1298                 pNv->output_info |= OUTPUT_1_LVDS;
1299         }
1300
1301         /* we setup the outputs up from the BIOS table */
1302         if (pNv->dcb_table.entries) {
1303                 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1304                         type = pNv->dcb_table.connection[i] & 0xf;
1305                         i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1306                         or = ffs((pNv->dcb_table.connection[i] >> 24) & 0xf) - 1;
1307
1308                         if (type < 4) {
1309                                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, i2c_index: %d, or: %d\n", i, pNv->dcb_table.connection[i], type, i2c_index, or);
1310
1311                                 switch(type) {
1312                                 case OUTPUT_ANALOG: /* Analogue VGA */
1313                                         nv_add_analog_output(pScrn, or, i2c_index, dvi_pair);
1314                                         dvi_pair = FALSE;
1315                                         break;
1316                                 case OUTPUT_DIGITAL: /* TMDS */
1317                                         dvi_pair = TRUE;
1318                                         nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 0);
1319                                         break;
1320                                 case OUTPUT_PANEL: /* LVDS */
1321                                         nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 1);
1322                                         break;
1323                                 default:
1324                                         break;
1325                                 }
1326                         }
1327                 }
1328         }
1329 }
1330
1331 void NvSetupOutputs(ScrnInfoPtr pScrn)
1332 {
1333         int i;
1334         NVPtr pNv = NVPTR(pScrn);
1335
1336         pNv->Television = FALSE;
1337
1338         memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1339         NvDCBSetupOutputs(pScrn);
1340
1341 #if 0
1342         xf86OutputPtr output;
1343         NVOutputPrivatePtr nv_output;
1344
1345     if (pNv->Mobile) {
1346         output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
1347         if (!output)
1348             return;
1349
1350         nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
1351         if (!nv_output) {
1352             xf86OutputDestroy(output);
1353             return;
1354         }
1355
1356         output->driver_private = nv_output;
1357         nv_output->type = output_type;
1358
1359         output->possible_crtcs = i ? 1 : crtc_mask;
1360     }
1361 #endif
1362 }
1363
1364 #endif /* ENABLE_RANDR12 */
1365
1366 /*************************************************************************** \
1367 |*                                                                           *|
1368 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1369 |*                                                                           *|
1370 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1371 |*     international laws.  Users and possessors of this source code are     *|
1372 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1373 |*     use this code in individual and commercial software.                  *|
1374 |*                                                                           *|
1375 |*     Any use of this source code must include,  in the user documenta-     *|
1376 |*     tion and  internal comments to the code,  notices to the end user     *|
1377 |*     as follows:                                                           *|
1378 |*                                                                           *|
1379 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1380 |*                                                                           *|
1381 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1382 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1383 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1384 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1385 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1386 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1387 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1388 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1389 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1390 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1391 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1392 |*                                                                           *|
1393 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1394 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1395 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1396 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1397 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1398 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1399 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1400 |*     all U.S. Government End Users  acquire the source code  with only     *|
1401 |*     those rights set forth herein.                                        *|
1402 |*                                                                           *|
1403  \***************************************************************************/