randr12: Some reindenting.
[nouveau] / src / nv_output.c
1 /*
2  * Copyright 2006 Dave Airlie
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *  Dave Airlie
25  */
26 /*
27  * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
28  * decleration is at the bottom of this file as it is rather ugly 
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #ifdef ENABLE_RANDR12
36
37 #include "xf86.h"
38 #include "os.h"
39 #include "mibank.h"
40 #include "globals.h"
41 #include "xf86.h"
42 #include "xf86Priv.h"
43 #include "xf86DDC.h"
44 #include "mipointer.h"
45 #include "windowstr.h"
46 #include <randrstr.h>
47 #include <X11/extensions/render.h>
48
49 #include "xf86Crtc.h"
50 #include "nv_include.h"
51
52 const char *OutputType[] = {
53     "None",
54     "VGA",
55     "DVI",
56     "LVDS",
57     "S-video",
58     "Composite",
59 };
60
61 const char *MonTypeName[7] = {
62     "AUTO",
63     "NONE",
64     "CRT",
65     "LVDS",
66     "TMDS",
67     "CTV",
68     "STV"
69 };
70
71 /* 
72  * TMDS registers are indirect 8 bit registers.
73  * Reading is straightforward, writing a bit odd.
74  * Reading: Write adress (+write protect bit, do not forget this), then read value.
75  * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
76  */
77
78 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
79 {
80         NVOutputPrivatePtr nv_output = output->driver_private;
81         ScrnInfoPtr     pScrn = output->scrn;
82         NVPtr pNv = NVPTR(pScrn);
83
84         nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
85                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
86
87         nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
88
89         nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
90         nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
91                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
92 }
93
94 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
95 {
96         NVOutputPrivatePtr nv_output = output->driver_private;
97         ScrnInfoPtr     pScrn = output->scrn;
98         NVPtr pNv = NVPTR(pScrn);
99
100         nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL, 
101                 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
102
103         return (nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
104 }
105
106 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
107 {
108     NVOutputPrivatePtr nv_output = output->driver_private;
109     ScrnInfoPtr pScrn = output->scrn;
110     NVPtr pNv = NVPTR(pScrn);
111
112     nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
113 }
114
115 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
116 {
117     NVOutputPrivatePtr nv_output = output->driver_private;
118     ScrnInfoPtr pScrn = output->scrn;
119     NVPtr pNv = NVPTR(pScrn);
120
121     return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
122 }
123
124 static void nv_output_backlight_enable(xf86OutputPtr output,  Bool on)
125 {
126     ScrnInfoPtr pScrn = output->scrn;
127     NVPtr pNv = NVPTR(pScrn);   
128
129     /* This is done differently on each laptop.  Here we
130        define the ones we know for sure. */
131     
132 #if defined(__powerpc__)
133     if((pNv->Chipset == 0x10DE0179) || 
134        (pNv->Chipset == 0x10DE0189) || 
135        (pNv->Chipset == 0x10DE0329))
136     {
137         /* NV17,18,34 Apple iMac, iBook, PowerBook */
138         CARD32 tmp_pmc, tmp_pcrt;
139         tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
140         tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
141         if(on) {
142             tmp_pmc |= (1 << 31);
143             tmp_pcrt |= 0x1;
144         }
145         nvWriteMC(pNv, 0x10F0, tmp_pmc);
146         nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
147     }
148 #endif
149     
150     if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
151         nvWriteMC(pNv, 0x130C, on ? 3 : 7);
152 }
153
154 static void
155 nv_panel_output_dpms(xf86OutputPtr output, int mode)
156 {
157
158     switch(mode) {
159     case DPMSModeStandby:
160     case DPMSModeSuspend:
161     case DPMSModeOff:
162         nv_output_backlight_enable(output, 0);
163         break;
164     case DPMSModeOn:
165         nv_output_backlight_enable(output, 1);
166     default:
167         break;
168     }
169 }
170
171 static void
172 nv_analog_output_dpms(xf86OutputPtr output, int mode)
173 {
174
175 }
176
177 static void
178 nv_digital_output_dpms(xf86OutputPtr output, int mode)
179 {
180         xf86CrtcPtr crtc = output->crtc;
181
182         if (crtc) {
183                 NVPtr pNv = NVPTR(output->scrn);
184                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
185
186                 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL);      
187                 switch(mode) {
188                         case DPMSModeStandby:
189                         case DPMSModeSuspend:
190                         case DPMSModeOff:
191                                 /* cut the TMDS output */           
192                                 fpcontrol |= 0x20000022;
193                                 break;
194                         case DPMSModeOn:
195                                 /* disable cutting the TMDS output */
196                                 fpcontrol &= ~0x20000022;
197                                 break;
198                 }
199                 nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL, fpcontrol);
200         }
201 }
202
203 int tmds_regs[] = { 0x2, 0x4, 0x2b };
204
205 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
206 {
207         NVOutputPrivatePtr nv_output = output->driver_private;
208         ScrnInfoPtr pScrn = output->scrn;
209         NVPtr pNv = NVPTR(pScrn);
210         NVOutputRegPtr regp;
211         int i;
212
213         regp = &state->dac_reg[nv_output->ramdac];
214         regp->general       = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
215         regp->fp_control    = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
216         regp->debug_0   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
217         regp->debug_1   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
218         regp->debug_2   = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
219         state->config       = nvReadFB(pNv, NV_PFB_CFG0);
220
221         regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
222
223         if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
224                 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
225         } else if (pNv->twoHeads) {
226                 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
227         }
228         regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC);
229         regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
230
231         for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
232                 regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
233         }
234
235         if (nv_output->type == OUTPUT_DIGITAL) {
236
237                 for (i = 0; i < 7; i++) {
238                         uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
239                         regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
240                 }
241                 
242                 for (i = 0; i < 7; i++) {
243                         uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
244                         regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
245                 }
246
247                 regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
248                 regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
249                 regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
250                 regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
251         }
252 }
253
254 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
255 {
256         NVOutputPrivatePtr nv_output = output->driver_private;
257         ScrnInfoPtr     pScrn = output->scrn;
258         NVPtr pNv = NVPTR(pScrn);
259         NVOutputRegPtr regp;
260         int i;
261
262         regp = &state->dac_reg[nv_output->ramdac];
263
264         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
265         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
266         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
267         NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
268         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
269         NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync);
270
271         if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
272                 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
273         } else if (pNv->twoHeads) {
274                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
275         }
276
277         NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
278         NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
279
280         for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
281                 NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
282         }
283
284         if (nv_output->type == OUTPUT_DIGITAL) {
285
286                 for (i = 0; i < 7; i++) {
287                         uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
288                         NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
289                 }
290                 
291                 for (i = 0; i < 7; i++) {
292                         uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
293                         NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
294                 }
295
296                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
297                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
298                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
299                 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
300         }
301
302         
303 }
304
305
306 static void
307 nv_output_save (xf86OutputPtr output)
308 {
309     ScrnInfoPtr pScrn = output->scrn;
310     NVPtr pNv = NVPTR(pScrn);
311     RIVA_HW_STATE *state;
312   
313     state = &pNv->SavedReg;
314   
315     nv_output_save_state_ext(output, state);    
316   
317 }
318
319 static void
320 nv_output_restore (xf86OutputPtr output)
321 {
322     ScrnInfoPtr pScrn = output->scrn;
323     NVPtr pNv = NVPTR(pScrn);
324     RIVA_HW_STATE *state;
325   
326     state = &pNv->SavedReg;
327   
328     nv_output_load_state_ext(output, state);
329 }
330
331 static int
332 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
333 {
334     if (pMode->Flags & V_DBLSCAN)
335         return MODE_NO_DBLESCAN;
336   
337     if (pMode->Clock > 400000 || pMode->Clock < 25000)
338         return MODE_CLOCK_RANGE;
339   
340     return MODE_OK;
341 }
342
343
344 static Bool
345 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
346                      DisplayModePtr adjusted_mode)
347 {
348     return TRUE;
349 }
350
351 static int
352 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
353 {
354     NVOutputPrivatePtr nv_output = output->driver_private;
355     ScrnInfoPtr pScrn = output->scrn;
356     NVPtr pNv = NVPTR(pScrn);
357     NVOutputRegPtr regp;
358     int tweak = 0;
359   
360     regp = &state->dac_reg[nv_output->ramdac];
361     if (pNv->usePanelTweak) {
362         tweak = pNv->PanelTweak;
363     } else {
364         /* begin flat panel hacks */
365         /* This is unfortunate, but some chips need this register
366            tweaked or else you get artifacts where adjacent pixels are
367            swapped.  There are no hard rules for what to set here so all
368            we can do is experiment and apply hacks. */
369     
370         if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
371             /* At least one NV34 laptop needs this workaround. */
372             tweak = -1;
373         }
374                 
375         if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
376             tweak = 1;
377         }
378         /* end flat panel hacks */
379     }
380     return tweak;
381 }
382
383 static void
384 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
385 {
386         NVOutputPrivatePtr nv_output = output->driver_private;
387         ScrnInfoPtr pScrn = output->scrn;
388         int bpp;
389         NVPtr pNv = NVPTR(pScrn);
390         NVFBLayout *pLayout = &pNv->CurrentLayout;
391         RIVA_HW_STATE *state, *sv_state;
392         Bool is_fp = FALSE;
393         NVOutputRegPtr regp, savep;
394         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
395         float aspect_ratio, panel_ratio;
396         uint32_t h_scale, v_scale;
397         int i;
398
399         state = &pNv->ModeReg;
400         regp = &state->dac_reg[nv_output->ramdac];
401
402         sv_state = &pNv->SavedReg;
403         savep = &sv_state->dac_reg[nv_output->ramdac];
404
405         if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
406                 is_fp = TRUE;
407
408                 regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
409                 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
410                 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
411                 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
412                 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
413                 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
414                 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
415
416                 regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
417                 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
418                 regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
419                 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
420                 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
421                 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
422                 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
423         }
424
425         /* This seems to be a common mode
426          * bit0: positive vsync
427          * bit1: positive hsync
428          * bit8: enable panel scaling 
429          */
430         regp->fp_control = 0x11100011;
431
432         if (is_fp) {
433                 ErrorF("Pre-panel scaling\n");
434                 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
435                 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
436                 ErrorF("panel_ratio=%f\n", panel_ratio);
437                 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
438                 ErrorF("aspect_ratio=%f\n", aspect_ratio);
439                 /* Scale factors is the so called 20.12 format, taken from Haiku */
440                 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
441                 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
442                 ErrorF("h_scale=%d\n", h_scale);
443                 ErrorF("v_scale=%d\n", v_scale);
444
445                 /* Enable full width  and height on the flat panel */
446                 regp->fp_hvalid_start = 0;
447                 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
448
449                 regp->fp_vvalid_start = 0;
450                 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
451
452                 /* When doing vertical scaling, limit the last fetched line */
453                 if (v_scale != (1 << 12)) {
454                         regp->debug_2 = (1 << 28) | ((mode->VDisplay - 1) << 16);
455                 } else {
456                         regp->debug_2 = 0;
457                 }
458
459                 /* GPU scaling happens automaticly at a ratio of 1:33 */
460                 /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
461                 if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
462                         uint32_t diff;
463
464                         ErrorF("Scaling resolution on a widescreen panel\n");
465
466                         /* Scaling in both directions needs to the same */
467                         h_scale = v_scale;
468                         diff = nv_output->fpWidth - ((1 << 12) * mode->HDisplay)/h_scale;
469                         regp->fp_hvalid_start = diff/2;
470                         regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
471                 }
472
473                 /* Same scaling, just for panels with aspect ratio's smaller than 1 */
474                 if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
475                         uint32_t diff;
476
477                         ErrorF("Scaling resolution on a portrait panel\n");
478
479                         /* Scaling in both directions needs to the same */
480                         v_scale = h_scale;
481                         diff = nv_output->fpHeight - ((1 << 12) * mode->VDisplay)/v_scale;
482                         regp->fp_vvalid_start = diff/2;
483                         regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
484                 }
485
486                 ErrorF("Post-panel scaling\n");
487         } else {
488                 /* copy a bunch of things from the current state for non-dfp's */
489                 regp->debug_2 = savep->debug_2;
490         }
491
492         if (pNv->Architecture >= NV_ARCH_10) {
493                 /* Bios and blob don't seem to do anything (else) */
494                 regp->nv10_cursync = (1<<25);
495         }
496
497         /* These are the common blob values, minus a few fp specific bit's */
498         regp->debug_0 = 0x1101111;
499         regp->debug_1 = savep->debug_1;
500         if(is_fp) {
501                 /* My bios does 0x500, blob seems to do 0x4c4 or 0x4e4, all work */
502                 regp->crtcSync = 0x4c4;
503                 //regp->crtcSync += nv_output_tweak_panel(output, state);
504
505                 /* I am not completely certain, but seems to be set only for dfp's */
506                 regp->debug_0 |= (1<<8);
507                 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
508         } else {
509                 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
510         }
511
512         ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
513
514         /* This is just a guess, there are probably more registers which need setting */
515         /* But we must start somewhere ;-) */
516         if (is_fp) {
517                 regp->TMDS[0x2] = 0x29;
518                 regp->TMDS[0x4] = 0x80;
519                 regp->TMDS[0x2b] = 0x7f;
520         }
521
522         /* Flatpanel support needs at least a NV10 */
523         if(pNv->twoHeads) {
524                 /* Instead of 1, several other values are also used: 2, 7, 9 */
525                 /* The purpose is unknown */
526                 if(pNv->FPDither) {
527                         regp->dither = 0x00010000;
528                 }
529         }
530
531         if(pLayout->depth < 24) {
532                 bpp = pLayout->depth;
533         } else {
534                 bpp = 32;
535         }
536
537         regp->general = bpp == 16 ? 0x00101100 : 0x00100100;
538
539         if (pNv->alphaCursor) {
540                 regp->general |= (1<<29);
541         }
542
543         if(bpp != 8) {/* DirectColor */
544                 regp->general |= 0x00000030;
545         }
546
547         regp->bpp = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
548
549         if (output->crtc) {
550                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
551                 int two_crt = FALSE;
552                 int two_mon = FALSE;
553
554                 for (i = 0; i < config->num_output; i++) {
555                         NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
556
557                         /* is it this output ?? */
558                         if (config->output[i] == output)
559                                 continue;
560
561                         /* it the output connected */
562                         if (config->output[i]->crtc == NULL)
563                                 continue;
564
565                         two_mon = TRUE;
566                         if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
567                                 two_crt = TRUE;
568                         }
569                 }
570
571                 if (is_fp == TRUE) {
572                         regp->output = 0x0;
573                 } else { 
574                         regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
575                 }
576
577                 if (nv_crtc->crtc == 1) {
578                         regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2;
579                 } else {
580                         regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_CRTC2;
581                 }
582
583                 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);
584         }
585 }
586
587 static void
588 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
589                    DisplayModePtr adjusted_mode)
590 {
591     ScrnInfoPtr pScrn = output->scrn;
592     NVPtr pNv = NVPTR(pScrn);
593     RIVA_HW_STATE *state;
594
595     state = &pNv->ModeReg;
596
597     nv_output_mode_set_regs(output, mode);
598     nv_output_load_state_ext(output, state);
599 }
600
601 static Bool
602 nv_ddc_detect(xf86OutputPtr output)
603 {
604         /* no use for shared DDC output */
605         NVOutputPrivatePtr nv_output = output->driver_private;
606         xf86MonPtr ddc_mon;
607
608         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
609         if (!ddc_mon)
610                 return FALSE;
611
612         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
613                 return FALSE;
614
615         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
616                 return FALSE;
617         }
618
619         xf86PrintEDID(ddc_mon);
620
621         if (nv_output->type == OUTPUT_DIGITAL) {
622                 int i;
623                 for (i = 0; i < 8; i++) {
624                         if ((ddc_mon->timings2[i].hsize > nv_output->fpWidth) ||
625                                 (ddc_mon->timings2[i].vsize > nv_output->fpHeight)) {
626
627                                 nv_output->fpWidth = ddc_mon->timings2[i].hsize;
628                                 nv_output->fpHeight = ddc_mon->timings2[i].vsize;
629                         }
630                 }
631         }
632
633         return TRUE;
634 }
635
636 static Bool
637 nv_crt_load_detect(xf86OutputPtr output)
638 {
639     ScrnInfoPtr pScrn = output->scrn;
640     CARD32 reg_output, reg_test_ctrl, temp;
641     int present = FALSE;
642           
643     reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
644     reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
645
646     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
647     
648     NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
649     usleep(1000);
650           
651     temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
652     NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
653
654     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
655     temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
656     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
657
658     usleep(1000);
659           
660     present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
661           
662     temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
663     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
664           
665     NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
666     NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
667     
668     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
669                present);
670
671     return present;
672
673 }
674
675 static xf86OutputStatus
676 nv_digital_output_detect(xf86OutputPtr output)
677 {
678     NVOutputPrivatePtr nv_output = output->driver_private;
679
680     if (nv_ddc_detect(output))
681         return XF86OutputStatusConnected;
682
683     return XF86OutputStatusDisconnected;
684 }
685
686
687 static xf86OutputStatus
688 nv_analog_output_detect(xf86OutputPtr output)
689 {
690     NVOutputPrivatePtr nv_output = output->driver_private;
691
692     if (nv_ddc_detect(output))
693         return XF86OutputStatusConnected;
694
695     /* seems a bit flaky on ramdac 1 */
696     if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
697         return XF86OutputStatusConnected;
698     
699     return XF86OutputStatusDisconnected;
700 }
701
702 static DisplayModePtr
703 nv_output_get_modes(xf86OutputPtr output)
704 {
705     ScrnInfoPtr pScrn = output->scrn;
706     NVOutputPrivatePtr nv_output = output->driver_private;
707     xf86MonPtr ddc_mon;
708     DisplayModePtr ddc_modes, mode;
709     int i;
710
711
712     ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
713
714     if (ddc_mon == NULL) {
715         xf86OutputSetEDID(output, ddc_mon);
716         return NULL;
717     }
718
719     if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
720         xf86OutputSetEDID(output, NULL);
721         return NULL;
722     }
723
724     if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
725         xf86OutputSetEDID(output, NULL);
726         return NULL;
727     }
728
729     xf86OutputSetEDID(output, ddc_mon);
730
731     ddc_modes = xf86OutputGetEDIDModes (output);          
732     return ddc_modes;
733
734 }
735
736 static void
737 nv_output_destroy (xf86OutputPtr output)
738 {
739     if (output->driver_private)
740         xfree (output->driver_private);
741
742 }
743
744 static void
745 nv_output_prepare(xf86OutputPtr output)
746 {
747
748 }
749
750 static void
751 nv_output_commit(xf86OutputPtr output)
752 {
753
754
755 }
756
757 static const xf86OutputFuncsRec nv_analog_output_funcs = {
758     .dpms = nv_analog_output_dpms,
759     .save = nv_output_save,
760     .restore = nv_output_restore,
761     .mode_valid = nv_output_mode_valid,
762     .mode_fixup = nv_output_mode_fixup,
763     .mode_set = nv_output_mode_set,
764     .detect = nv_analog_output_detect,
765     .get_modes = nv_output_get_modes,
766     .destroy = nv_output_destroy,
767     .prepare = nv_output_prepare,
768     .commit = nv_output_commit,
769 };
770
771 static const xf86OutputFuncsRec nv_digital_output_funcs = {
772     .dpms = nv_digital_output_dpms,
773     .save = nv_output_save,
774     .restore = nv_output_restore,
775     .mode_valid = nv_output_mode_valid,
776     .mode_fixup = nv_output_mode_fixup,
777     .mode_set = nv_output_mode_set,
778     .detect = nv_digital_output_detect,
779     .get_modes = nv_output_get_modes,
780     .destroy = nv_output_destroy,
781     .prepare = nv_output_prepare,
782     .commit = nv_output_commit,
783 };
784
785 static xf86OutputStatus
786 nv_output_lvds_detect(xf86OutputPtr output)
787 {
788     return XF86OutputStatusUnknown;    
789 }
790
791 static DisplayModePtr
792 nv_output_lvds_get_modes(xf86OutputPtr output)
793 {
794     ScrnInfoPtr pScrn = output->scrn;
795     NVOutputPrivatePtr nv_output = output->driver_private;
796
797     //    nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
798     //    nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
799     nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
800     //    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
801     //         nv_output->fpWidth, nv_output->fpHeight);
802
803     return NULL;
804
805 }
806
807 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
808     .dpms = nv_panel_output_dpms,
809     .save = nv_output_save,
810     .restore = nv_output_restore,
811     .mode_valid = nv_output_mode_valid,
812     .mode_fixup = nv_output_mode_fixup,
813     .mode_set = nv_output_mode_set,
814     .detect = nv_output_lvds_detect,
815     .get_modes = nv_output_lvds_get_modes,
816     .destroy = nv_output_destroy,
817     .prepare = nv_output_prepare,
818     .commit = nv_output_commit,
819 };
820
821
822 static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
823 {
824         NVPtr pNv = NVPTR(pScrn);
825         xf86OutputPtr       output;
826         NVOutputPrivatePtr    nv_output;
827         char outputname[20];
828         int   crtc_mask = (1<<0) | (1<<1);
829
830         sprintf(outputname, "Analog-%d", pNv->analog_count);
831         output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
832         if (!output)
833                 return;
834         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
835         if (!nv_output) {
836                 xf86OutputDestroy (output);
837                 return;
838         }
839
840         output->driver_private = nv_output;
841         nv_output->type = OUTPUT_ANALOG;
842
843         /* dvi outputs share their i2c port with their analog output on the same port */
844         /* But they can never work at the same time, so it's convient to share ramdac index */
845         nv_output->ramdac = i2c_index;
846
847         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
848
849         output->possible_crtcs = crtc_mask;
850         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
851
852         pNv->analog_count++;
853 }
854
855
856 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index, int lvds)
857 {
858         NVPtr pNv = NVPTR(pScrn);
859         xf86OutputPtr       output;
860         NVOutputPrivatePtr    nv_output;
861         char outputname[20];
862         int   crtc_mask = (1<<0) | (1<<1);
863
864         sprintf(outputname, "Digital-%d", pNv->digital_count);
865         if (lvds)
866                 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
867         else
868                 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
869         if (!output)
870                 return;
871         nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
872         if (!nv_output) {
873                 xf86OutputDestroy (output);
874                 return;
875         }
876
877         output->driver_private = nv_output;
878         nv_output->type = OUTPUT_DIGITAL;
879
880         nv_output->ramdac = i2c_index;
881
882         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
883
884         output->possible_crtcs = crtc_mask;
885         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
886
887         pNv->digital_count++;
888 }
889 /**
890  * Set up the outputs according to what type of chip we are.
891  *
892  * Some outputs may not initialize, due to allocation failure or because a
893  * controller chip isn't found.
894  */
895
896 void Nv20SetupOutputs(ScrnInfoPtr pScrn)
897 {
898     NVPtr pNv = NVPTR(pScrn);
899     xf86OutputPtr           output;
900     NVOutputPrivatePtr    nv_output;
901     int i;
902     int num_analog_outputs = pNv->twoHeads ? 2 : 1;
903     int num_digital_outputs = 1;
904
905     for (i = 0 ; i < num_analog_outputs; i++) {
906       nv_add_analog_output(pScrn, i);
907     }
908
909     for (i = 0 ; i < num_digital_outputs; i++) {
910       nv_add_digital_output(pScrn, i, 0);
911     }
912 }
913
914 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
915 {
916         unsigned char type, port, or, i2c_index;
917         NVPtr pNv = NVPTR(pScrn);
918         int i;
919
920         /* we setup the outputs up from the BIOS table */
921         if (pNv->dcb_entries) {
922                 for (i = 0 ; i < pNv->dcb_entries; i++) {
923                         type = pNv->dcb_table[i] & 0xf;
924                         port = (pNv->dcb_table[i] >> 4) & 0xf;
925                         or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1;
926                         if (pNv->Architecture == NV_ARCH_40) {
927                                 /* Ports seem to be inverse on nv4x */
928                                 i2c_index = (~port) & 1;
929                         } else {
930                                 i2c_index = port;
931                         }
932
933                         if (type < 4)
934                                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or);
935                         if (type < 4 && port != 0xf) {
936                                 switch(type) {
937                                 case 0: /* analog */
938                                         nv_add_analog_output(pScrn, i2c_index);
939                                         break;
940                                 case 2:
941                                         nv_add_digital_output(pScrn, i2c_index, 0);
942                                         break;
943                                 case 3:
944                                         nv_add_digital_output(pScrn, i2c_index, 1);
945                                         break;
946                                 default:
947                                         break;
948                                 }
949                         }
950                 }
951         } else
952                 Nv20SetupOutputs(pScrn);
953 }
954
955 struct nv_i2c_struct {
956         int reg;
957         char *name;
958 } nv_i2c_buses[] = { 
959         { 0x3e, "DDC1" },
960         { 0x36, "DDC2" },
961         { 0x50, "TV" },
962 };
963
964 void NvSetupOutputs(ScrnInfoPtr pScrn)
965 {
966     int i;
967     NVPtr pNv = NVPTR(pScrn);
968     xf86OutputPtr           output;
969     NVOutputPrivatePtr    nv_output;
970
971     int num_outputs = pNv->twoHeads ? 2 : 1;
972     char outputname[20];
973     pNv->Television = FALSE;
974
975         /* add the 3 I2C buses */
976         for (i = 0; i < NV_I2C_BUSES; i++) {
977                 NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name);
978         }
979
980     NvDCBSetupOutputs(pScrn);
981
982 #if 0
983     if (pNv->Mobile) {
984         output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
985         if (!output)
986             return;
987
988         nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
989         if (!nv_output) {
990             xf86OutputDestroy(output);
991             return;
992         }
993
994         output->driver_private = nv_output;
995         nv_output->type = output_type;
996
997         output->possible_crtcs = i ? 1 : crtc_mask;
998     }
999 #endif
1000 }
1001
1002 #endif /* ENABLE_RANDR12 */
1003
1004 /*************************************************************************** \
1005 |*                                                                           *|
1006 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1007 |*                                                                           *|
1008 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1009 |*     international laws.  Users and possessors of this source code are     *|
1010 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1011 |*     use this code in individual and commercial software.                  *|
1012 |*                                                                           *|
1013 |*     Any use of this source code must include,  in the user documenta-     *|
1014 |*     tion and  internal comments to the code,  notices to the end user     *|
1015 |*     as follows:                                                           *|
1016 |*                                                                           *|
1017 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1018 |*                                                                           *|
1019 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1020 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1021 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1022 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1023 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1024 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1025 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1026 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1027 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1028 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1029 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1030 |*                                                                           *|
1031 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1032 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1033 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1034 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1035 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1036 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1037 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1038 |*     all U.S. Government End Users  acquire the source code  with only     *|
1039 |*     those rights set forth herein.                                        *|
1040 |*                                                                           *|
1041  \***************************************************************************/