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