2 * Copyright 2006 Dave Airlie
3 * Copyright 2007 Maarten Maathuis
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:
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
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.
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
40 #include "mipointer.h"
41 #include "windowstr.h"
43 #include <X11/extensions/render.h>
44 #include "X11/Xatom.h"
47 #include "nv_include.h"
49 const char *OutputType[] = {
58 const char *MonTypeName[7] = {
69 * TMDS registers are indirect 8 bit registers.
70 * Reading is straightforward, writing a bit odd.
71 * Reading: Write adress (+write protect bit, do not forget this), then read value.
72 * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
75 void NVWriteTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
77 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
78 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
80 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
82 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
83 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
84 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
87 CARD8 NVReadTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg)
89 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
90 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
92 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
95 /* Two register sets exist, this one is only used for dual link dvi/lvds */
97 void NVWriteTMDS2(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
99 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
100 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
102 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2, val & 0xff);
104 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, tmds_reg & 0xff);
105 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
106 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
109 CARD8 NVReadTMDS2(NVPtr pNv, int ramdac, CARD32 tmds_reg)
111 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
112 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
114 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2) & 0xff);
117 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
119 NVOutputPrivatePtr nv_output = output->driver_private;
120 ScrnInfoPtr pScrn = output->scrn;
121 NVPtr pNv = NVPTR(pScrn);
123 /* We must write to the "bus" of the output */
124 NVWriteTMDS(pNv, nv_output->preferred_ramdac, tmds_reg, val);
127 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
129 NVOutputPrivatePtr nv_output = output->driver_private;
130 ScrnInfoPtr pScrn = output->scrn;
131 NVPtr pNv = NVPTR(pScrn);
133 /* We must read from the "bus" of the output */
134 return NVReadTMDS(pNv, nv_output->preferred_ramdac, tmds_reg);
137 void NVOutputWriteTMDS2(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
139 NVOutputPrivatePtr nv_output = output->driver_private;
140 ScrnInfoPtr pScrn = output->scrn;
141 NVPtr pNv = NVPTR(pScrn);
143 /* We must write to the "bus" of the output */
144 NVWriteTMDS2(pNv, nv_output->preferred_ramdac, tmds_reg, val);
147 CARD8 NVOutputReadTMDS2(xf86OutputPtr output, CARD32 tmds_reg)
149 NVOutputPrivatePtr nv_output = output->driver_private;
150 ScrnInfoPtr pScrn = output->scrn;
151 NVPtr pNv = NVPTR(pScrn);
153 /* We must read from the "bus" of the output */
154 return NVReadTMDS2(pNv, nv_output->preferred_ramdac, tmds_reg);
157 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
159 NVOutputPrivatePtr nv_output = output->driver_private;
160 ScrnInfoPtr pScrn = output->scrn;
161 NVPtr pNv = NVPTR(pScrn);
163 nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
166 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
168 NVOutputPrivatePtr nv_output = output->driver_private;
169 ScrnInfoPtr pScrn = output->scrn;
170 NVPtr pNv = NVPTR(pScrn);
172 return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
175 static void nv_output_backlight_enable(xf86OutputPtr output, Bool on)
177 ScrnInfoPtr pScrn = output->scrn;
178 NVPtr pNv = NVPTR(pScrn);
180 ErrorF("nv_output_backlight_enable is called for output %s to turn %s\n", output->name, on ? "on" : "off");
182 /* This is done differently on each laptop. Here we
183 * define the ones we know for sure. */
185 #if defined(__powerpc__)
186 if ((pNv->Chipset == 0x10DE0179) ||
187 (pNv->Chipset == 0x10DE0189) ||
188 (pNv->Chipset == 0x10DE0329)) {
189 /* NV17,18,34 Apple iMac, iBook, PowerBook */
190 CARD32 tmp_pmc, tmp_pcrt;
191 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
192 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
194 tmp_pmc |= (1 << 31);
197 nvWriteMC(pNv, 0x10F0, tmp_pmc);
198 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
202 if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
203 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
206 static void dpms_update_output_ramdac(NVPtr pNv, int ramdac, int mode)
211 /* We may be going for modesetting, so we must reset the ramdacs */
212 if (mode == DPMSModeOff) {
213 pNv->ramdac_active[ramdac] = FALSE;
214 ErrorF("Deactivating ramdac %d\n", ramdac);
218 /* The previous call was not a modeset, but a normal dpms call */
219 pNv->ramdac_active[ramdac] = TRUE;
220 ErrorF("Activating ramdac %d\n", ramdac);
224 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
226 NVOutputPrivatePtr nv_output = output->driver_private;
227 NVPtr pNv = NVPTR(output->scrn);
229 dpms_update_output_ramdac(pNv, nv_output->ramdac, mode);
232 case DPMSModeStandby:
233 case DPMSModeSuspend:
235 nv_output_backlight_enable(output, 0);
238 nv_output_backlight_enable(output, 1);
245 nv_analog_output_dpms(xf86OutputPtr output, int mode)
247 xf86CrtcPtr crtc = output->crtc;
248 NVOutputPrivatePtr nv_output = output->driver_private;
249 NVPtr pNv = NVPTR(output->scrn);
251 ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
253 dpms_update_output_ramdac(pNv, nv_output->ramdac, mode);
256 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
258 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
263 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
265 xf86CrtcPtr crtc = output->crtc;
266 NVOutputPrivatePtr nv_output = output->driver_private;
267 NVPtr pNv = NVPTR(output->scrn);
269 ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
271 dpms_update_output_ramdac(pNv, nv_output->ramdac, mode);
273 /* Are we assigned a ramdac already?, else we will be activated during mode set */
274 if (crtc && nv_output->ramdac != -1) {
275 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
277 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
279 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
281 case DPMSModeStandby:
282 case DPMSModeSuspend:
284 /* cut the TMDS output */
285 fpcontrol |= 0x20000022;
288 /* disable cutting the TMDS output */
289 fpcontrol &= ~0x20000022;
292 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
296 /* This sequence is an optimized/shortened version of what the blob does */
297 /* 0x40 and 0x43 are dual link dvi/lvds related, so don't touch them for now */
298 uint32_t tmds_regs_nv40[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, /* 0x40, 0x43,*/ 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a, 0x2b };
299 uint32_t tmds_regs_nv30[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x29, 0x2a, 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a, 0x2b };
301 #define TMDS_REGS(index) ( tmds_regs(pNv, index) )
303 uint32_t tmds_regs(NVPtr pNv, int i)
305 if (pNv->Architecture == NV_ARCH_40) {
306 return tmds_regs_nv40[i];
308 return tmds_regs_nv30[i];
312 #define TMDS_SIZE ( tmds_size(pNv) )
314 uint32_t tmds_size(NVPtr pNv)
316 if (pNv->Architecture == NV_ARCH_40) {
317 return(sizeof(tmds_regs_nv40)/sizeof(tmds_regs_nv40[0]));
319 return(sizeof(tmds_regs_nv30)/sizeof(tmds_regs_nv30[0]));
323 /* Does anyone know the precise purpose of this second register set? */
324 uint32_t tmds2_regs_nv40[] = { 0x2b };
325 uint32_t tmds2_regs_nv30[] = { 0x2b };
327 #define TMDS2_REGS(index) ( tmds2_regs(pNv, index) )
329 uint32_t tmds2_regs(NVPtr pNv, int i)
331 if (pNv->Architecture == NV_ARCH_40) {
332 return tmds2_regs_nv40[i];
334 return tmds2_regs_nv30[i];
338 #define TMDS2_SIZE ( tmds2_size(pNv) )
340 uint32_t tmds2_size(NVPtr pNv)
342 if (pNv->Architecture == NV_ARCH_40) {
343 return(sizeof(tmds2_regs_nv40)/sizeof(tmds2_regs_nv40[0]));
345 return(sizeof(tmds2_regs_nv30)/sizeof(tmds2_regs_nv30[0]));
349 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
351 NVOutputPrivatePtr nv_output = output->driver_private;
352 ScrnInfoPtr pScrn = output->scrn;
353 NVPtr pNv = NVPTR(pScrn);
357 regp = &state->dac_reg[nv_output->ramdac];
358 state->config = nvReadFB(pNv, NV_PFB_CFG0);
360 /* This exists purely for proper text mode restore */
361 if (override) regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
363 for (i = 0; i < TMDS_SIZE; i++) {
364 regp->TMDS[TMDS_REGS(i)] = NVOutputReadTMDS(output, TMDS_REGS(i));
367 /* If the data ever changes between TMDS and TMDS2, then regp data needs a new set */
368 /* TMDS2 is related to dual link dvi/lvds, leave it untouched for the moment */
369 //for (i = 0; i < TMDS2_SIZE; i++) {
370 // regp->TMDS[TMDS2_REGS(i)] = NVOutputReadTMDS2(output, TMDS2_REGS(i));
374 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
376 NVOutputPrivatePtr nv_output = output->driver_private;
378 ScrnInfoPtr pScrn = output->scrn;
379 NVPtr pNv = NVPTR(pScrn);
382 regp = &state->dac_reg[nv_output->ramdac];
384 /* This exists purely for proper text mode restore */
385 if (override) NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
387 for (i = 0; i < TMDS_SIZE; i++) {
388 NVOutputWriteTMDS(output, TMDS_REGS(i), regp->TMDS[TMDS_REGS(i)]);
391 /* If the data ever changes between TMDS and TMDS2, then regp data needs a new set */
392 /* TMDS2 is related to dual link dvi/lvds, leave it untouched for the moment */
393 //for (i = 0; i < TMDS2_SIZE; i++) {
394 // NVOutputWriteTMDS(output, TMDS2_REGS(i), regp->TMDS[TMDS2_REGS(i)]);
398 /* NOTE: Don't rely on this data for anything other than restoring VT's */
401 nv_output_save (xf86OutputPtr output)
403 ScrnInfoPtr pScrn = output->scrn;
404 NVPtr pNv = NVPTR(pScrn);
405 RIVA_HW_STATE *state;
406 NVOutputPrivatePtr nv_output = output->driver_private;
407 int ramdac_backup = nv_output->ramdac;
409 ErrorF("nv_output_save is called\n");
411 /* This is early init and we have not yet been assigned a ramdac */
412 /* Always choose the prefered ramdac, for consistentcy */
413 /* Assumption: there is always once output that can only run of the primary ramdac */
414 if (nv_output->valid_ramdac & RAMDAC_1) {
415 nv_output->ramdac = 1;
417 nv_output->ramdac = 0;
420 state = &pNv->SavedReg;
422 /* Due to strange mapping of outputs we could have swapped analog and digital */
423 /* So we force save all the registers */
424 nv_output_save_state_ext(output, state, TRUE);
426 /* restore previous state */
427 nv_output->ramdac = ramdac_backup;
431 nv_output_restore (xf86OutputPtr output)
433 ScrnInfoPtr pScrn = output->scrn;
434 NVPtr pNv = NVPTR(pScrn);
435 RIVA_HW_STATE *state;
436 NVOutputPrivatePtr nv_output = output->driver_private;
437 int ramdac_backup = nv_output->ramdac;
439 ErrorF("nv_output_restore is called\n");
441 /* We want consistent mode restoring and the ramdac entry is variable */
442 /* Always choose the prefered ramdac, for consistentcy */
443 /* Assumption: there is always once output that can only run of the primary ramdac */
444 if (nv_output->valid_ramdac & RAMDAC_1) {
445 nv_output->ramdac = 1;
447 nv_output->ramdac = 0;
450 state = &pNv->SavedReg;
452 /* Due to strange mapping of outputs we could have swapped analog and digital */
453 /* So we force load all the registers */
454 nv_output_load_state_ext(output, state, TRUE);
456 /* restore previous state */
457 nv_output->ramdac = ramdac_backup;
461 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
463 if (pMode->Flags & V_DBLSCAN)
464 return MODE_NO_DBLESCAN;
466 if (pMode->Clock > 400000 || pMode->Clock < 25000)
467 return MODE_CLOCK_RANGE;
474 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
475 DisplayModePtr adjusted_mode)
477 ErrorF("nv_output_mode_fixup is called\n");
483 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
485 NVOutputPrivatePtr nv_output = output->driver_private;
486 ScrnInfoPtr pScrn = output->scrn;
487 NVPtr pNv = NVPTR(pScrn);
488 RIVA_HW_STATE *state, *sv_state;
490 Bool is_lvds = FALSE;
491 NVOutputRegPtr regp, regp2, savep;
492 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
495 xf86CrtcPtr crtc = output->crtc;
496 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
498 state = &pNv->ModeReg;
499 regp = &state->dac_reg[nv_output->ramdac];
500 /* The other ramdac */
501 regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
503 sv_state = &pNv->SavedReg;
504 savep = &sv_state->dac_reg[nv_output->ramdac];
506 if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
508 if (nv_output->type == OUTPUT_LVDS) {
513 /* This is just a guess, there are probably more registers which need setting */
514 /* But we must start somewhere ;-) */
516 regp->TMDS[0x4] = 0x80;
517 /* Enable crosswired mode */
518 /* This will upset the monitor, trust me, i know it :-( */
519 /* Now allowed for non-bios inited systems */
520 //if (nv_output->ramdac != nv_output->preferred_ramdac) {
521 if (nv_crtc->head != nv_output->preferred_ramdac) {
522 regp->TMDS[0x4] |= (1 << 3);
526 regp->TMDS[0x4] |= (1 << 0);
530 /* The TMDS game begins */
531 /* A few registers are also programmed on non-tmds monitors */
532 /* At the moment i can't give rationale for these values */
534 regp->TMDS[0x2b] = 0x7d;
536 uint32_t pll_setup_control = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SETUP_CONTROL);
537 regp->TMDS[0x2b] = 0x7d;
538 regp->TMDS[0x2c] = 0x0;
539 /* Various combinations exist for lvds, 0x08, 0x48, 0xc8, 0x88 */
540 /* 0x88 seems most popular and (maybe) the end setting */
542 if (pNv->Architecture == NV_ARCH_40) {
543 regp->TMDS[0x2e] = 0x88;
545 /* observed on nv31m */
546 regp->TMDS[0x2e] = 0x0;
549 /* 0x81 is also observed, but it's much rarer */
550 regp->TMDS[0x2e] = 0x85;
552 /* 0x08 is also seen for lvds */
553 regp->TMDS[0x2f] = 0x21;
554 regp->TMDS[0x30] = 0x0;
555 regp->TMDS[0x31] = 0x0;
556 regp->TMDS[0x32] = 0x0;
557 regp->TMDS[0x33] = 0xf0;
558 regp->TMDS[0x3a] = 0x0;
560 /* Sometimes 0x68 is also used */
561 regp->TMDS[0x5] = 0x6e;
564 if (pNv->Architecture == NV_ARCH_40) {
565 regp->TMDS[0x0] = 0x60;
567 /* observed on a nv31m */
568 regp->TMDS[0x0] = 0x70;
571 /* This seems to be related to PLL_SETUP_CONTROL */
572 /* When PLL_SETUP_CONTROL ends with 0x1c, then this value is 0xcX */
574 if ((pll_setup_control & 0xff) == 0x1c) {
575 regp->TMDS[0x0] = 0xc0;
577 regp->TMDS[0x0] = 0xf0;
581 /* Not a 100% sure if this is not crtc determined */
582 if (nv_output->preferred_ramdac != nv_output->ramdac) {
583 regp->TMDS[0x0] |= 0xa;
585 regp->TMDS[0x0] |= 0x1;
588 if (pll_setup_control == 0) {
589 regp->TMDS[0x1] = 0x0;
591 /* Also seen: 0x47, what does this register do? */
592 if (nv_output->ramdac != nv_output->preferred_ramdac) {
593 regp->TMDS[0x1] = 0x42;
595 regp->TMDS[0x1] = 0x41;
600 regp->TMDS[0x2] = 0x0;
601 } else if (pll_setup_control == 0) {
602 regp->TMDS[0x2] = 0x90;
604 if (nv_output->preferred_ramdac == 1) { /* This is the "output" */
605 regp->TMDS[0x2] = 0xa9;
607 regp->TMDS[0x2] = 0x89;
611 /* I assume they are zero for !is_lvds */
612 if (is_lvds && pNv->Architecture == NV_ARCH_40) {
613 /* Observed values are 0x11 and 0x14, TODO: this needs refinement */
614 regp->TMDS[0x40] = 0x14;
615 regp->TMDS[0x43] = 0xb0;
620 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
624 for (i = 0; i < config->num_output; i++) {
625 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
627 /* is it this output ?? */
628 if (config->output[i] == output)
631 /* it the output connected */
632 if (config->output[i]->crtc == NULL)
636 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
641 ErrorF("%d: crtc %d ramdac %d twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->ramdac, two_crt, two_mon);
646 nv_output_mode_set_routing(xf86OutputPtr output)
648 NVOutputPrivatePtr nv_output = output->driver_private;
649 xf86CrtcPtr crtc = output->crtc;
650 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
651 ScrnInfoPtr pScrn = output->scrn;
652 NVPtr pNv = NVPTR(pScrn);
655 uint32_t output_reg[2];
657 if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
661 if (pNv->Architecture == NV_ARCH_40) {
662 /* NV4x cards have strange ways of dealing with dualhead */
663 /* Also see reg594 in nv_crtc.c */
664 output_reg[0] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
665 /* So far only dual dvi cards(or lvds + dvi i think) seem to use (and need?) this */
667 output_reg[1] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
670 output_reg[nv_output->preferred_ramdac] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
672 output_reg[nv_output->preferred_ramdac] = 0x0;
676 /* Only one can be on crtc1 */
677 if (nv_crtc->head == 1) {
678 output_reg[nv_output->preferred_ramdac] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
680 output_reg[(~nv_output->preferred_ramdac) & 1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
683 if (pNv->Architecture == NV_ARCH_40) {
684 /* The registers can't be considered seperately on nv40 */
685 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT, output_reg[0]);
686 nvWriteRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT, output_reg[1]);
688 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT, output_reg[nv_output->preferred_ramdac]);
691 /* This could use refinement for flatpanels, but it should work this way */
692 if (pNv->NVArch < 0x44) {
693 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, 0xf0000000);
694 if (pNv->Architecture == NV_ARCH_40)
695 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0xf0000000);
697 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, 0x00100000);
698 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0x00100000);
703 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
704 DisplayModePtr adjusted_mode)
706 ScrnInfoPtr pScrn = output->scrn;
707 NVPtr pNv = NVPTR(pScrn);
708 RIVA_HW_STATE *state;
710 ErrorF("nv_output_mode_set is called\n");
712 state = &pNv->ModeReg;
714 nv_output_mode_set_regs(output, mode, adjusted_mode);
715 nv_output_load_state_ext(output, state, FALSE);
716 nv_output_mode_set_routing(output);
720 nv_get_edid(xf86OutputPtr output)
722 /* no use for shared DDC output */
723 NVOutputPrivatePtr nv_output = output->driver_private;
726 if (nv_output->pDDCBus == NULL)
729 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
733 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
736 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
737 nv_output->type == OUTPUT_LVDS))
748 nv_ddc_detect(xf86OutputPtr output)
750 xf86MonPtr m = nv_get_edid(output);
760 nv_crt_load_detect(xf86OutputPtr output)
762 ScrnInfoPtr pScrn = output->scrn;
763 NVOutputPrivatePtr nv_output = output->driver_private;
764 NVPtr pNv = NVPTR(pScrn);
765 CARD32 reg_output, reg_test_ctrl, temp;
766 Bool present = FALSE;
769 /* Usually these outputs are native to ramdac 1 */
770 if (nv_output->valid_ramdac & RAMDAC_0 && nv_output->valid_ramdac & RAMDAC_1) {
772 } else if (nv_output->valid_ramdac & RAMDAC_1) {
774 } else if (nv_output->valid_ramdac & RAMDAC_0) {
780 /* For some reason we get false positives on ramdac 1, maybe due tv-out? */
785 if (nv_output->pDDCBus != NULL) {
786 xf86MonPtr ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
787 /* Is there a digital flatpanel on this channel? */
788 if (ddc_mon && ddc_mon->features.input_type) {
793 reg_output = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
794 reg_test_ctrl = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
796 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
798 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
801 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
802 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, temp | 1);
804 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
805 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
806 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
810 present = (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
812 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
813 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
815 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, reg_output);
816 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
819 ErrorF("A crt was detected on ramdac %d with no ddc support\n", ramdac);
826 static xf86OutputStatus
827 nv_tmds_output_detect(xf86OutputPtr output)
829 ErrorF("nv_tmds_output_detect is called\n");
831 if (nv_ddc_detect(output))
832 return XF86OutputStatusConnected;
834 return XF86OutputStatusDisconnected;
838 static xf86OutputStatus
839 nv_analog_output_detect(xf86OutputPtr output)
841 ErrorF("nv_analog_output_detect is called\n");
843 if (nv_ddc_detect(output))
844 return XF86OutputStatusConnected;
846 if (nv_crt_load_detect(output))
847 return XF86OutputStatusConnected;
849 return XF86OutputStatusDisconnected;
852 static DisplayModePtr
853 nv_output_get_modes(xf86OutputPtr output)
855 NVOutputPrivatePtr nv_output = output->driver_private;
857 DisplayModePtr ddc_modes;
859 ErrorF("nv_output_get_modes is called\n");
861 ddc_mon = nv_get_edid(output);
863 xf86OutputSetEDID(output, ddc_mon);
868 ddc_modes = xf86OutputGetEDIDModes (output);
870 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
874 for (i = 0; i < 4; i++) {
875 /* We only look at detailed timings atm */
876 if (ddc_mon->det_mon[i].type != DT)
878 /* Selecting only based on width ok? */
879 if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
880 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
881 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
885 /* Add a native resolution mode that is preferred */
886 /* Reduced blanking should be fine on DVI monitor */
887 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
888 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
889 /* We want the new mode to be preferred */
890 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
891 if (mode->type & M_T_PREFERRED) {
892 mode->type &= ~M_T_PREFERRED;
895 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
902 nv_output_destroy (xf86OutputPtr output)
904 ErrorF("nv_output_destroy is called\n");
905 if (output->driver_private)
906 xfree (output->driver_private);
910 nv_find_output_and_clear_ramdac_from_outputs(xf86OutputPtr output, int ramdac)
913 ScrnInfoPtr pScrn = output->scrn;
914 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
915 xf86OutputPtr output2 = NULL;
916 NVOutputPrivatePtr nv_output2;
917 for (i = 0; i < xf86_config->num_output; i++) {
918 output2 = xf86_config->output[i];
919 nv_output2 = output2->driver_private;
920 if (nv_output2->ramdac == ramdac && output != output2) {
921 nv_output2->ramdac = -1;
930 nv_output_prepare(xf86OutputPtr output)
932 ErrorF("nv_output_prepare is called\n");
933 NVOutputPrivatePtr nv_output = output->driver_private;
934 ScrnInfoPtr pScrn = output->scrn;
935 NVPtr pNv = NVPTR(pScrn);
936 Bool stole_ramdac = FALSE;
937 xf86OutputPtr output2 = NULL;
940 output->funcs->dpms(output, DPMSModeOff);
942 /* We need ramdac 0, so let's steal it */
943 if (!(nv_output->valid_ramdac & RAMDAC_1) && pNv->ramdac_active[0]) {
944 ErrorF("Stealing ramdac0 ;-)\n");
945 output2 = nv_find_output_and_clear_ramdac_from_outputs(output, 0);
946 pNv->ramdac_active[0] = FALSE;
950 /* We need ramdac 1, so let's steal it */
951 if (!(nv_output->valid_ramdac & RAMDAC_0) && pNv->ramdac_active[1]) {
952 ErrorF("Stealing ramdac1 ;-)\n");
953 output2 = nv_find_output_and_clear_ramdac_from_outputs(output, 1);
954 pNv->ramdac_active[1] = FALSE;
958 /* TODO: figure out what ramdac 2 is and how it is identified */
960 /* At this point we already stole ramdac 0 or 1 if we need it */
961 if (!pNv->ramdac_active[0] && (nv_output->valid_ramdac & RAMDAC_0))
966 ErrorF("Activating ramdac %d\n", ramdac);
967 pNv->ramdac_active[ramdac] = TRUE;
968 nv_output->ramdac = ramdac;
970 nv_find_output_and_clear_ramdac_from_outputs(output, ramdac);
973 ErrorF("Resetting the stolen ramdac\n");
974 DisplayModePtr adjusted_mode = xf86DuplicateMode(&(output2->crtc->desiredMode));
975 xf86CrtcPtr crtc2 = output2->crtc;
976 /* Assign a ramdac */
977 output2->funcs->prepare(output2);
978 /* We must set the vpll's to ensure they are properly set */
979 crtc2->funcs->mode_fixup(crtc2, &(crtc2->desiredMode), adjusted_mode);
980 crtc2->funcs->mode_set(crtc2, &(crtc2->desiredMode), adjusted_mode, crtc2->x, crtc2->y);
981 output2->funcs->mode_set(output2, &(crtc2->desiredMode), adjusted_mode);
982 /* Anyone know were this mode is stored, so we don't accidentally wake up a screen that is DPMSModeOff? */
983 crtc2->funcs->dpms(crtc2, DPMSModeOn);
984 output2->funcs->commit(output2);
985 xfree(adjusted_mode);
990 nv_output_commit(xf86OutputPtr output)
992 ErrorF("nv_output_commit is called\n");
994 output->funcs->dpms(output, DPMSModeOn);
997 static const xf86OutputFuncsRec nv_analog_output_funcs = {
998 .dpms = nv_analog_output_dpms,
999 .save = nv_output_save,
1000 .restore = nv_output_restore,
1001 .mode_valid = nv_output_mode_valid,
1002 .mode_fixup = nv_output_mode_fixup,
1003 .mode_set = nv_output_mode_set,
1004 .detect = nv_analog_output_detect,
1005 .get_modes = nv_output_get_modes,
1006 .destroy = nv_output_destroy,
1007 .prepare = nv_output_prepare,
1008 .commit = nv_output_commit,
1011 #ifdef RANDR_12_INTERFACE
1013 * Two scaling modes exist, let the user choose.
1015 #define SCALING_MODE_NAME "SCALING_MODE"
1016 #define NUM_SCALING_METHODS 2
1017 static char *scaling_mode_names[] = {
1021 static Atom scaling_mode_atom;
1024 nv_scaling_mode_lookup(char *name, int size)
1027 const int len = strlen(name);
1029 for (i = 0; i < NUM_SCALING_METHODS; i++)
1030 if (size == len && !strncmp(name, scaling_mode_names[i], len))
1037 nv_tmds_create_resources(xf86OutputPtr output)
1039 NVOutputPrivatePtr nv_output = output->driver_private;
1040 ScrnInfoPtr pScrn = output->scrn;
1044 * Setup scaling mode property.
1046 scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
1048 error = RRConfigureOutputProperty(output->randr_output,
1049 scaling_mode_atom, TRUE, FALSE, FALSE,
1053 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1054 "RRConfigureOutputProperty error, %d\n", error);
1057 error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
1058 XA_STRING, 8, PropModeReplace,
1059 strlen(scaling_mode_names[nv_output->scaling_mode]),
1060 scaling_mode_names[nv_output->scaling_mode],
1064 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1065 "Failed to set scaling mode, %d\n", error);
1070 nv_tmds_set_property(xf86OutputPtr output, Atom property,
1071 RRPropertyValuePtr value)
1073 NVOutputPrivatePtr nv_output = output->driver_private;
1075 if (property == scaling_mode_atom) {
1079 if (value->type != XA_STRING || value->format != 8)
1082 name = (char*) value->data;
1084 /* Match a string to a scaling mode */
1085 ret = nv_scaling_mode_lookup(name, value->size);
1089 nv_output->scaling_mode = ret;
1096 #endif /* RANDR_12_INTERFACE */
1098 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
1099 .dpms = nv_tmds_output_dpms,
1100 .save = nv_output_save,
1101 .restore = nv_output_restore,
1102 .mode_valid = nv_output_mode_valid,
1103 .mode_fixup = nv_output_mode_fixup,
1104 .mode_set = nv_output_mode_set,
1105 .detect = nv_tmds_output_detect,
1106 .get_modes = nv_output_get_modes,
1107 .destroy = nv_output_destroy,
1108 .prepare = nv_output_prepare,
1109 .commit = nv_output_commit,
1110 #ifdef RANDR_12_INTERFACE
1111 .create_resources = nv_tmds_create_resources,
1112 .set_property = nv_tmds_set_property,
1113 #endif /* RANDR_12_INTERFACE */
1116 static int nv_lvds_output_mode_valid
1117 (xf86OutputPtr output, DisplayModePtr pMode)
1119 NVOutputPrivatePtr nv_output = output->driver_private;
1121 /* No modes > panel's native res */
1122 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
1125 return nv_output_mode_valid(output, pMode);
1128 static xf86OutputStatus
1129 nv_lvds_output_detect(xf86OutputPtr output)
1131 ScrnInfoPtr pScrn = output->scrn;
1132 NVPtr pNv = NVPTR(pScrn);
1134 if (pNv->fp_native_mode || nv_ddc_detect(output))
1135 return XF86OutputStatusConnected;
1137 return XF86OutputStatusDisconnected;
1140 static DisplayModePtr
1141 nv_lvds_output_get_modes(xf86OutputPtr output)
1143 ScrnInfoPtr pScrn = output->scrn;
1144 NVPtr pNv = NVPTR(pScrn);
1145 NVOutputPrivatePtr nv_output = output->driver_private;
1146 DisplayModePtr modes;
1148 if ((modes = nv_output_get_modes(output)))
1151 /* it is possible to set up a mode from what we can read from the
1152 * RAMDAC registers, but if we can't read the BIOS table correctly
1153 * we might as well give up */
1154 if (pNv->fp_native_mode == NULL)
1157 nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1158 nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1159 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1161 if (pNv->fp_native_mode->HDisplay != nv_output->fpWidth ||
1162 pNv->fp_native_mode->VDisplay != nv_output->fpHeight) {
1163 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1164 "Panel size mismatch; ignoring RAMDAC\n");
1165 nv_output->fpWidth = pNv->fp_native_mode->HDisplay;
1166 nv_output->fpHeight = pNv->fp_native_mode->VDisplay;
1169 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1170 nv_output->fpWidth, nv_output->fpHeight);
1172 nv_output->native_mode = xf86DuplicateMode(pNv->fp_native_mode);
1174 return xf86DuplicateMode(pNv->fp_native_mode);
1177 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1178 .dpms = nv_lvds_output_dpms,
1179 .save = nv_output_save,
1180 .restore = nv_output_restore,
1181 .mode_valid = nv_lvds_output_mode_valid,
1182 .mode_fixup = nv_output_mode_fixup,
1183 .mode_set = nv_output_mode_set,
1184 .detect = nv_lvds_output_detect,
1185 .get_modes = nv_lvds_output_get_modes,
1186 .destroy = nv_output_destroy,
1187 .prepare = nv_output_prepare,
1188 .commit = nv_output_commit,
1191 static void nv_add_analog_output(ScrnInfoPtr pScrn, int dcb_entry, Bool dvi_pair)
1193 NVPtr pNv = NVPTR(pScrn);
1194 xf86OutputPtr output;
1195 NVOutputPrivatePtr nv_output;
1196 char outputname[20];
1197 Bool create_output = TRUE;
1198 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1200 /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1202 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1205 sprintf(outputname, "VGA-%d", pNv->vga_count);
1209 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1214 nv_output->dcb_entry = dcb_entry;
1216 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1217 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1219 nv_output->type = OUTPUT_ANALOG;
1222 * bit0: RAMDAC_0 valid
1223 * bit1: RAMDAC_1 valid
1224 * So lowest order has highest priority.
1225 * Below is guesswork:
1226 * bit2: All ramdac's valid?
1227 * FIXME: this probably wrong
1229 nv_output->valid_ramdac = ffs(pNv->dcb_table.entry[dcb_entry].or);
1231 if (!create_output) {
1236 /* Delay creation of output until we actually know we want it */
1237 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1241 output->driver_private = nv_output;
1243 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1245 nv_output->ramdac = -1;
1247 /* This is only to facilitate proper output routing for dvi */
1248 /* See sel_clk assignment in nv_crtc.c */
1249 if (nv_output->valid_ramdac & RAMDAC_1) {
1250 nv_output->preferred_ramdac = 1;
1252 nv_output->preferred_ramdac = 0;
1255 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1257 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1260 static void nv_add_digital_output(ScrnInfoPtr pScrn, int dcb_entry, int lvds)
1262 NVPtr pNv = NVPTR(pScrn);
1263 xf86OutputPtr output;
1264 NVOutputPrivatePtr nv_output;
1265 char outputname[20];
1266 Bool create_output = TRUE;
1267 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1270 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1273 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1277 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1283 nv_output->dcb_entry = dcb_entry;
1285 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1286 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1288 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1291 * bit0: RAMDAC_0 valid
1292 * bit1: RAMDAC_1 valid
1293 * So lowest order has highest priority.
1294 * Below is guesswork:
1295 * bit2: All ramdac's valid?
1296 * FIXME: this probably wrong
1298 nv_output->valid_ramdac = ffs(pNv->dcb_table.entry[dcb_entry].or);
1301 nv_output->type = OUTPUT_LVDS;
1302 /* comment below two lines to test LVDS under RandR12.
1303 * If your screen "blooms" or "bleeds" (i.e. has a developing
1304 * white / psychedelic pattern) then KILL X IMMEDIATELY
1305 * (ctrl+alt+backspace) & if the effect continues reset power */
1306 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1307 create_output = FALSE;
1309 nv_output->type = OUTPUT_TMDS;
1312 if (!create_output) {
1317 /* Delay creation of output until we are certain is desirable */
1319 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1321 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1325 output->driver_private = nv_output;
1327 nv_output->ramdac = -1;
1329 /* This is only to facilitate proper output routing for dvi */
1330 /* See sel_clk assignment in nv_crtc.c */
1331 if (nv_output->valid_ramdac & RAMDAC_1) {
1332 nv_output->preferred_ramdac = 1;
1334 nv_output->preferred_ramdac = 0;
1337 if (pNv->fpScaler) {
1339 nv_output->scaling_mode = 0;
1341 /* "Panel mode" fully filled */
1342 nv_output->scaling_mode = 1;
1345 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1347 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1350 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1352 NVPtr pNv = NVPTR(pScrn);
1353 int i, type, bus_count[0xf], digital_counter = 0;
1355 memset(bus_count, 0, sizeof(bus_count));
1356 for (i = 0 ; i < pNv->dcb_table.entries; i++)
1357 bus_count[pNv->dcb_table.entry[i].bus]++;
1359 /* we setup the outputs up from the BIOS table */
1360 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1361 type = pNv->dcb_table.entry[i].type;
1363 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1367 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry %d: type: %d, i2c_index: %d, heads: %d, bus: %d, or: %d\n", i, type, pNv->dcb_table.entry[i].i2c_index, pNv->dcb_table.entry[i].heads, pNv->dcb_table.entry[i].bus, pNv->dcb_table.entry[i].or);
1371 nv_add_analog_output(pScrn, i, (bus_count[pNv->dcb_table.entry[i].bus] > 1));
1374 nv_add_digital_output(pScrn, i, 0);
1378 nv_add_digital_output(pScrn, i, 1);
1379 /* I'm assuming that lvds+dvi has the same effect as dual dvi */
1387 if (digital_counter > 1) {
1388 pNv->dual_dvi = TRUE;
1390 pNv->dual_dvi = FALSE;
1394 void NvSetupOutputs(ScrnInfoPtr pScrn)
1396 NVPtr pNv = NVPTR(pScrn);
1398 pNv->Television = FALSE;
1400 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1401 NvDCBSetupOutputs(pScrn);
1404 /*************************************************************************** \
1406 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1408 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1409 |* international laws. Users and possessors of this source code are *|
1410 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1411 |* use this code in individual and commercial software. *|
1413 |* Any use of this source code must include, in the user documenta- *|
1414 |* tion and internal comments to the code, notices to the end user *|
1417 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1419 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1420 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1421 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1422 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1423 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1424 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1425 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1426 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1427 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1428 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1429 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1431 |* U.S. Government End Users. This source code is a "commercial *|
1432 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1433 |* consisting of "commercial computer software" and "commercial *|
1434 |* computer software documentation," as such terms are used in *|
1435 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1436 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1437 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1438 |* all U.S. Government End Users acquire the source code with only *|
1439 |* those rights set forth herein. *|
1441 \***************************************************************************/