2 * Copyright 2006 Dave Airlie
3 * Copyright 2007 Maarten Maathuis
4 * Copyright 2007 Stuart Bennett
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
27 * decleration is at the bottom of this file as it is rather ugly
41 #include "mipointer.h"
42 #include "windowstr.h"
44 #include <X11/extensions/render.h>
45 #include "X11/Xatom.h"
48 #include "nv_include.h"
50 const char *OutputType[] = {
59 const char *MonTypeName[7] = {
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).
76 void NVWriteTMDS(NVPtr pNv, int ramdac, uint32_t tmds_reg, uint32_t val)
78 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
79 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
81 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
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);
88 uint8_t NVReadTMDS(NVPtr pNv, int ramdac, uint32_t tmds_reg)
90 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
91 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
93 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
96 /* Two register sets exist, this one is only used for dual link dvi/lvds */
98 void NVWriteTMDS2(NVPtr pNv, int ramdac, uint32_t tmds_reg, uint32_t val)
100 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
101 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
103 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2, val & 0xff);
105 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, tmds_reg & 0xff);
106 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
107 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
110 uint8_t NVReadTMDS2(NVPtr pNv, int ramdac, uint32_t tmds_reg)
112 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
113 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
115 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2) & 0xff);
118 void NVOutputWriteTMDS(xf86OutputPtr output, uint32_t tmds_reg, uint32_t val)
120 NVOutputPrivatePtr nv_output = output->driver_private;
121 ScrnInfoPtr pScrn = output->scrn;
122 NVPtr pNv = NVPTR(pScrn);
124 /* We must write to the "bus" of the output */
125 NVWriteTMDS(pNv, nv_output->preferred_output, tmds_reg, val);
128 uint8_t NVOutputReadTMDS(xf86OutputPtr output, uint32_t tmds_reg)
130 NVOutputPrivatePtr nv_output = output->driver_private;
131 ScrnInfoPtr pScrn = output->scrn;
132 NVPtr pNv = NVPTR(pScrn);
134 /* We must read from the "bus" of the output */
135 return NVReadTMDS(pNv, nv_output->preferred_output, tmds_reg);
138 void NVOutputWriteTMDS2(xf86OutputPtr output, uint32_t tmds_reg, uint32_t val)
140 NVOutputPrivatePtr nv_output = output->driver_private;
141 ScrnInfoPtr pScrn = output->scrn;
142 NVPtr pNv = NVPTR(pScrn);
144 /* We must write to the "bus" of the output */
145 NVWriteTMDS2(pNv, nv_output->preferred_output, tmds_reg, val);
148 uint8_t NVOutputReadTMDS2(xf86OutputPtr output, uint32_t tmds_reg)
150 NVOutputPrivatePtr nv_output = output->driver_private;
151 ScrnInfoPtr pScrn = output->scrn;
152 NVPtr pNv = NVPTR(pScrn);
154 /* We must read from the "bus" of the output */
155 return NVReadTMDS2(pNv, nv_output->preferred_output, tmds_reg);
158 /* These functions now write into the output, instead of a specific ramdac */
160 void NVOutputWriteRAMDAC(xf86OutputPtr output, uint32_t ramdac_reg, uint32_t val)
162 NVOutputPrivatePtr nv_output = output->driver_private;
163 ScrnInfoPtr pScrn = output->scrn;
164 NVPtr pNv = NVPTR(pScrn);
166 nvWriteRAMDAC(pNv, nv_output->preferred_output, ramdac_reg, val);
169 uint32_t NVOutputReadRAMDAC(xf86OutputPtr output, uint32_t ramdac_reg)
171 NVOutputPrivatePtr nv_output = output->driver_private;
172 ScrnInfoPtr pScrn = output->scrn;
173 NVPtr pNv = NVPTR(pScrn);
175 return nvReadRAMDAC(pNv, nv_output->preferred_output, ramdac_reg);
178 static Bool dpms_common(xf86OutputPtr output, int mode)
180 NVOutputPrivatePtr nv_output = output->driver_private;
182 if (nv_output->last_dpms == mode) /* Don't do unnecesary mode changes. */
185 nv_output->last_dpms = mode;
187 NVPtr pNv = NVPTR(output->scrn);
188 xf86CrtcPtr crtc = output->crtc;
189 if (!crtc) /* we need nv_crtc, so give up */
191 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
193 if (pNv->NVArch >= 0x17 && pNv->twoHeads) {
194 /* We may be going for modesetting, so we must reset our output binding */
195 if (mode == DPMSModeOff) {
196 NVWriteVGACR5758(pNv, nv_crtc->head, 0, 0x7f);
197 NVWriteVGACR5758(pNv, nv_crtc->head, 2, 0);
199 NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
200 NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
208 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
210 ScrnInfoPtr pScrn = output->scrn;
211 NVPtr pNv = NVPTR(pScrn);
212 NVOutputPrivatePtr nv_output = output->driver_private;
214 ErrorF("nv_lvds_output_dpms is called with mode %d\n", mode);
216 if (!dpms_common(output, mode))
219 if (pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_power_scripts) {
220 xf86CrtcPtr crtc = output->crtc;
221 if (!crtc) /* we need nv_crtc, so give up */
223 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
224 int pclk = nv_get_clock_from_crtc(pScrn, &pNv->ModeReg, nv_crtc->head);
227 case DPMSModeStandby:
228 case DPMSModeSuspend:
229 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_BACKLIGHT_OFF, pclk);
232 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_OFF, pclk);
235 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_ON, pclk);
243 nv_analog_output_dpms(xf86OutputPtr output, int mode)
245 ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
247 dpms_common(output, mode);
251 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
253 xf86CrtcPtr crtc = output->crtc;
255 ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
257 if (!dpms_common(output, mode))
260 /* Are we assigned a ramdac already?, else we will be activated during mode set */
262 NVPtr pNv = NVPTR(output->scrn);
263 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
265 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->head, mode);
267 uint32_t fpcontrol = nvReadRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL);
269 case DPMSModeStandby:
270 case DPMSModeSuspend:
272 /* cut the TMDS output */
273 fpcontrol |= 0x20000022;
276 /* disable cutting the TMDS output */
277 fpcontrol &= ~0x20000022;
280 nvWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, fpcontrol);
284 static void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
286 NVPtr pNv = NVPTR(output->scrn);
288 /* This exists purely for proper text mode restore */
289 if (override && pNv->twoHeads) {
290 NVOutputPrivatePtr nv_output = output->driver_private;
291 NVOutputRegPtr regp = &state->dac_reg[nv_output->output_resource];
293 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
297 /* NOTE: Don't rely on this data for anything other than restoring VT's */
300 nv_output_save (xf86OutputPtr output)
302 NVPtr pNv = NVPTR(output->scrn);
303 NVOutputPrivatePtr nv_output = output->driver_private;
306 ErrorF("nv_output_save is called\n");
308 /* Due to strange mapping of outputs we could have swapped analog and digital */
309 /* So we force save all the registers */
310 regp = &pNv->SavedReg.dac_reg[nv_output->output_resource];
313 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
315 /* NV11's don't seem to like this, so let's restrict it to digital outputs only. */
316 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
319 /* Store the registers for helping with VT restore */
320 for (i = 0; i < 0xFF; i++)
321 regp->TMDS[i] = NVOutputReadTMDS(output, i);
324 // disabled, as nothing uses the TMDS2 regs currently
325 for (i = 0; i < 0xFF; i++)
326 regp->TMDS2[i] = NVOutputReadTMDS2(output, i);
331 uint32_t nv_get_clock_from_crtc(ScrnInfoPtr pScrn, RIVA_HW_STATE *state, uint8_t crtc)
333 NVPtr pNv = NVPTR(pScrn);
334 Bool vpllb_disabled = FALSE;
335 uint32_t vplla = crtc ? state->vpll2_a : state->vpll1_a;
336 uint32_t vpllb = crtc ? state->vpll2_b : state->vpll1_b;
338 if (!pNv->twoStagePLL)
339 vpllb_disabled = TRUE;
341 /* This is the dummy value nvidia sets when vpll is disabled */
342 if ((vpllb & 0xFFFF) == 0x11F)
343 vpllb_disabled = TRUE;
345 if (!(vpllb & NV31_RAMDAC_ENABLE_VCO2) && pNv->NVArch != 0x30)
346 vpllb_disabled = TRUE;
348 if (!(vplla & NV30_RAMDAC_ENABLE_VCO2) && pNv->NVArch == 0x30)
349 vpllb_disabled = TRUE;
351 uint8_t m1, m2, n1, n2, p;
353 if (pNv->NVArch == 0x30) {
355 n1 = (vplla >> 8) & 0xFF;
356 p = (vplla >> 16) & 0x7;
359 n1 = (vplla >> 8) & 0xFF;
360 p = (vplla >> 16) & 0x7;
363 if (vpllb_disabled) {
367 if (pNv->NVArch == 0x30) {
368 m2 = (vplla >> 4) & 0x7;
369 n2 = ((vplla >> 19) & 0x7) | (((vplla >> 24) & 0x3) << 3);
372 n2 = (vpllb >> 8) & 0xFF;
376 /* avoid div by 0, if used on pNv->ModeReg before ModeReg set up */
380 uint32_t clock = ((pNv->CrystalFreqKHz * n1 * n2)/(m1 * m2)) >> p;
381 ErrorF("The clock seems to be %d kHz\n", clock);
385 uint32_t nv_calc_tmds_clock_from_pll(xf86OutputPtr output)
387 ScrnInfoPtr pScrn = output->scrn;
388 NVPtr pNv = NVPTR(pScrn);
389 RIVA_HW_STATE *state;
391 NVOutputPrivatePtr nv_output = output->driver_private;
393 state = &pNv->SavedReg;
394 /* Registers are stored by their preferred ramdac */
395 /* So or = 3 still means it uses the "ramdac0" regs. */
396 regp = &state->dac_reg[nv_output->preferred_output];
398 Bool swapped_clock = FALSE;
399 /* Bit3 swaps crtc (clocks are bound to crtc) and output */
400 if (regp->TMDS[0x4] & (1 << 3)) {
401 swapped_clock = TRUE;
404 uint8_t vpll_num = swapped_clock ^ nv_output->preferred_output;
406 return nv_get_clock_from_crtc(pScrn, state, vpll_num);
409 void nv_set_tmds_registers(xf86OutputPtr output, uint32_t clock, Bool override, Bool crosswired)
411 ScrnInfoPtr pScrn = output->scrn;
412 NVPtr pNv = NVPTR(pScrn);
413 NVOutputPrivatePtr nv_output = output->driver_private;
414 xf86CrtcPtr crtc = output->crtc;
415 /* We have no crtc, so what are we supposed to do now? */
416 /* This can only happen during VT restore */
417 if (crtc && !override) {
418 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
420 * Resetting all registers is a bad idea, it seems to work fine without it.
422 if (nv_output->type == OUTPUT_TMDS)
423 run_tmds_table(pScrn, nv_output->dcb_entry, nv_crtc->head, clock);
424 /* on panels where we do reset after pclk change, DPMS on will do this */
425 else if (!pNv->VBIOS.fp.reset_after_pclk_change)
426 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_RESET, clock);
429 * We have no crtc, but we do know what output we are and if we were crosswired.
430 * We can determine our crtc from this.
432 if (nv_output->type == OUTPUT_TMDS)
433 run_tmds_table(pScrn, nv_output->dcb_entry, nv_output->preferred_output ^ crosswired, clock);
435 if (!pNv->VBIOS.fp.reset_after_pclk_change)
436 call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_RESET, clock);
437 call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_PANEL_ON, clock);
443 nv_output_restore (xf86OutputPtr output)
445 ScrnInfoPtr pScrn = output->scrn;
446 NVPtr pNv = NVPTR(pScrn);
447 RIVA_HW_STATE *state;
448 NVOutputPrivatePtr nv_output = output->driver_private;
449 ErrorF("nv_output_restore is called\n");
451 state = &pNv->SavedReg;
453 /* Due to strange mapping of outputs we could have swapped analog and digital */
454 /* So we force load all the registers */
455 nv_output_load_state_ext(output, state, TRUE);
457 nv_output->last_dpms = NV_DPMS_CLEARED;
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 NVOutputPrivatePtr nv_output = output->driver_private;
478 ErrorF("nv_output_mode_fixup is called\n");
480 /* For internal panels and gpu scaling on DVI we need the native mode */
481 if ((nv_output->type == OUTPUT_LVDS || (nv_output->type == OUTPUT_TMDS && nv_output->scaling_mode != SCALE_PANEL))) {
482 adjusted_mode->HDisplay = nv_output->native_mode->HDisplay;
483 adjusted_mode->HSkew = nv_output->native_mode->HSkew;
484 adjusted_mode->HSyncStart = nv_output->native_mode->HSyncStart;
485 adjusted_mode->HSyncEnd = nv_output->native_mode->HSyncEnd;
486 adjusted_mode->HTotal = nv_output->native_mode->HTotal;
487 adjusted_mode->VDisplay = nv_output->native_mode->VDisplay;
488 adjusted_mode->VScan = nv_output->native_mode->VScan;
489 adjusted_mode->VSyncStart = nv_output->native_mode->VSyncStart;
490 adjusted_mode->VSyncEnd = nv_output->native_mode->VSyncEnd;
491 adjusted_mode->VTotal = nv_output->native_mode->VTotal;
492 adjusted_mode->Clock = nv_output->native_mode->Clock;
493 adjusted_mode->Flags = nv_output->native_mode->Flags;
495 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
502 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
504 NVOutputPrivatePtr nv_output = output->driver_private;
505 ScrnInfoPtr pScrn = output->scrn;
506 //RIVA_HW_STATE *state;
507 //NVOutputRegPtr regp, savep;
509 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
512 /* It's getting quiet here, not removing function just yet, we may still need it */
514 //state = &pNv->ModeReg;
515 //regp = &state->dac_reg[nv_output->output_resource];
517 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
521 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
525 for (i = 0; i < config->num_output; i++) {
526 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
528 /* is it this output ?? */
529 if (config->output[i] == output)
532 /* it the output connected */
533 if (config->output[i]->crtc == NULL)
537 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
542 ErrorF("%d: crtc %d output %d twocrt %d twomon %d\n", is_fp, nv_crtc->head, nv_output->output_resource, two_crt, two_mon);
546 /* Only return if output is active (=have a crtc). */
549 nv_have_duallink(ScrnInfoPtr pScrn)
551 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
552 NVPtr pNv = NVPTR(pScrn);
555 for (i = 0; i < xf86_config->num_output; i++) {
556 xf86OutputPtr output = xf86_config->output[i];
557 NVOutputPrivatePtr nv_output = output->driver_private;
558 if (pNv->dcb_table.entry[nv_output->dcb_entry].duallink_possible &&
559 (pNv->dcb_table.entry[nv_output->dcb_entry].type == OUTPUT_LVDS ||
560 pNv->dcb_table.entry[nv_output->dcb_entry].type == OUTPUT_TMDS) &&
571 nv_output_mode_set_routing(xf86OutputPtr output, Bool bios_restore)
573 xf86CrtcPtr crtc = output->crtc;
574 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
575 ScrnInfoPtr pScrn = output->scrn;
576 NVPtr pNv = NVPTR(pScrn);
579 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
580 NVOutputPrivatePtr nv_output = output->driver_private;
581 Bool strange_mode = FALSE;
582 uint32_t output_reg[2] = {0, 0};
585 for (i = 0; i < xf86_config->num_output; i++) {
586 xf86OutputPtr output2 = xf86_config->output[i];
587 NVOutputPrivatePtr nv_output2 = output2->driver_private;
588 if (output2->crtc) { /* enabled? */
589 uint8_t ors = nv_output2->output_resource;
590 if (nv_output2->type == OUTPUT_ANALOG)
591 output_reg[ors] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
592 if (ors != nv_output2->preferred_output)
593 if (pNv->Architecture == NV_ARCH_40)
598 /* Some (most?) pre-NV30 cards have switchable crtc's. */
599 if (pNv->switchable_crtc) {
600 uint8_t crtc0_index = nv_output->output_resource ^ nv_crtc->head;
601 output_reg[~(crtc0_index) & 1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
604 output_reg[crtc0_index] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
607 ErrorF("output reg: 0x%X 0x%X\n", output_reg[0], output_reg[1]);
609 /* The registers can't be considered seperately on most cards */
610 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT, output_reg[0]);
611 nvWriteRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT, output_reg[1]);
614 /* This could use refinement for flatpanels, but it should work this way */
615 if (pNv->NVArch < 0x44) {
616 nvWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_TEST_CONTROL, 0xf0000000);
617 if (pNv->Architecture == NV_ARCH_40)
618 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0xf0000000);
620 nvWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_TEST_CONTROL, 0x00100000);
621 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0x00100000);
626 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
627 DisplayModePtr adjusted_mode)
629 ScrnInfoPtr pScrn = output->scrn;
630 NVPtr pNv = NVPTR(pScrn);
631 NVOutputPrivatePtr nv_output = output->driver_private;
632 RIVA_HW_STATE *state;
634 ErrorF("nv_output_mode_set is called\n");
636 state = &pNv->ModeReg;
638 nv_output_mode_set_regs(output, mode, adjusted_mode);
639 nv_output_load_state_ext(output, state, FALSE);
640 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
641 nv_set_tmds_registers(output, adjusted_mode->Clock, FALSE, FALSE);
643 nv_output_mode_set_routing(output, NVMatchModePrivate(mode, NV_MODE_CONSOLE));
647 nv_get_edid(xf86OutputPtr output)
649 /* no use for shared DDC output */
650 NVOutputPrivatePtr nv_output = output->driver_private;
653 if (nv_output->pDDCBus == NULL)
656 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
660 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
663 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
664 nv_output->type == OUTPUT_LVDS))
675 nv_ddc_detect(xf86OutputPtr output)
677 xf86MonPtr m = nv_get_edid(output);
687 nv_load_detect(xf86OutputPtr output)
689 ScrnInfoPtr pScrn = output->scrn;
690 NVOutputPrivatePtr nv_output = output->driver_private;
691 NVPtr pNv = NVPTR(pScrn);
692 uint32_t testval, regoffset = 0;
693 uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, saved_rtest_ctrl, temp;
696 if (nv_output->pDDCBus != NULL) {
697 xf86MonPtr ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
698 /* Is there a digital flatpanel on this channel? */
699 if (ddc_mon && ddc_mon->features.input_type) {
704 #define RGB_TEST_DATA(r,g,b) (r << 0 | g << 10 | b << 20)
705 testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
706 if (pNv->VBIOS.dactestval)
707 testval = pNv->VBIOS.dactestval;
709 /* something more clever than this, using output_resource, might be
710 * required, as we might not be on the preferred output */
711 switch (pNv->dcb_table.entry[nv_output->dcb_entry].or) {
719 /* this gives rise to RAMDAC_670 and RAMDAC_594 */
724 saved_rtest_ctrl = nvReadRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL + regoffset);
725 nvWriteRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl & ~0x00010000);
727 if (pNv->NVArch >= 0x17) {
728 saved_powerctrl_2 = nvReadMC(pNv, NV_PBUS_POWERCTRL_2);
730 nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
731 if (regoffset == 0x68) {
732 saved_powerctrl_4 = nvReadMC(pNv, NV_PBUS_POWERCTRL_4);
733 nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
739 saved_routput = nvReadRAMDAC0(pNv, NV_RAMDAC_OUTPUT + regoffset);
740 /* nv driver and nv31 use 0xfffffeee
741 * nv34 and 6600 use 0xfffffece */
742 nvWriteRAMDAC0(pNv, NV_RAMDAC_OUTPUT + regoffset, saved_routput & 0xfffffece);
745 temp = nvReadRAMDAC0(pNv, NV_RAMDAC_OUTPUT + regoffset);
746 nvWriteRAMDAC0(pNv, NV_RAMDAC_OUTPUT + regoffset, temp | 1);
748 /* no regoffset on purpose */
749 nvWriteRAMDAC0(pNv, NV_RAMDAC_TEST_DATA, 1 << 31 | testval);
750 temp = nvReadRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL);
751 nvWriteRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
754 present = nvReadRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL + regoffset) & (1 << 28);
756 /* no regoffset on purpose */
757 temp = nvReadRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL);
758 nvWriteRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL, temp & 0xffffefff);
759 nvWriteRAMDAC0(pNv, NV_RAMDAC_TEST_DATA, 0);
761 /* bios does something more complex for restoring, but I think this is good enough */
762 nvWriteRAMDAC0(pNv, NV_RAMDAC_OUTPUT + regoffset, saved_routput);
763 nvWriteRAMDAC0(pNv, NV_RAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
764 if (pNv->NVArch >= 0x17) {
765 if (regoffset == 0x68)
766 nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
767 nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
771 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Load detected on output %d\n", nv_output->preferred_output);
778 static xf86OutputStatus
779 nv_tmds_output_detect(xf86OutputPtr output)
781 ErrorF("nv_tmds_output_detect is called\n");
783 if (nv_ddc_detect(output))
784 return XF86OutputStatusConnected;
786 return XF86OutputStatusDisconnected;
790 static xf86OutputStatus
791 nv_analog_output_detect(xf86OutputPtr output)
793 NVPtr pNv = NVPTR(output->scrn);
795 ErrorF("nv_analog_output_detect is called\n");
797 /* assume a CRT connection on non dualhead cards */
799 return XF86OutputStatusConnected;
801 if (nv_ddc_detect(output))
802 return XF86OutputStatusConnected;
804 if (pNv->NVArch >= 0x17 && pNv->twoHeads && nv_load_detect(output))
805 return XF86OutputStatusConnected;
807 return XF86OutputStatusDisconnected;
810 static DisplayModePtr
811 nv_output_get_modes(xf86OutputPtr output, xf86MonPtr mon)
813 NVOutputPrivatePtr nv_output = output->driver_private;
814 DisplayModePtr ddc_modes;
816 ErrorF("nv_output_get_modes is called\n");
818 xf86OutputSetEDID(output, mon);
820 ddc_modes = xf86OutputGetEDIDModes(output);
822 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
826 for (i = 0; i < DET_TIMINGS; i++) {
827 /* We only look at detailed timings atm */
828 if (mon->det_mon[i].type != DT)
830 /* Selecting only based on width ok? */
831 if (mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
832 nv_output->fpWidth = mon->det_mon[i].section.d_timings.h_active;
833 nv_output->fpHeight = mon->det_mon[i].section.d_timings.v_active;
836 if (!(nv_output->fpWidth && nv_output->fpHeight)) {
837 ErrorF("No EDID detailed timings available, bailing out.\n");
841 if (nv_output->native_mode)
842 xfree(nv_output->native_mode);
844 /* Prefer ddc modes. */
845 DisplayModePtr chosen_mode = NULL;
846 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
847 if (mode->HDisplay == nv_output->fpWidth &&
848 mode->VDisplay == nv_output->fpHeight) {
849 /* Take the preferred mode when it exists. */
850 if (mode->type & M_T_PREFERRED) {
854 /* Find the highest refresh mode otherwise. */
855 if (!chosen_mode || (mode->VRefresh > chosen_mode->VRefresh))
859 chosen_mode->type |= M_T_PREFERRED;
860 nv_output->native_mode = xf86DuplicateMode(chosen_mode);
863 // this code can be removed, if the above remains as is, since it guarantees a native mode
864 /* Only fall back to cvt mode when needed. */
865 if (!nv_output->native_mode && nv_output->type == OUTPUT_TMDS) {
866 DisplayModePtr cvtmode;
867 /* Reduced blanking should be fine on DVI monitor */
868 cvtmode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
869 cvtmode->type = M_T_DRIVER | M_T_PREFERRED;
871 /* can xf86CVTMode generate invalid modes? */
872 if (output->funcs->mode_valid(output, cvtmode) == MODE_OK) {
873 ddc_modes = xf86ModesAdd(ddc_modes, cvtmode);
874 nv_output->native_mode = xf86DuplicateMode(cvtmode);
876 xf86DeleteMode(&cvtmode, cvtmode);
885 static DisplayModePtr
886 nv_output_get_ddc_modes(xf86OutputPtr output)
890 ErrorF("nv_output_get_ddc_modes is called\n");
892 ddc_mon = nv_get_edid(output);
897 return nv_output_get_modes(output, ddc_mon);
901 nv_output_destroy (xf86OutputPtr output)
903 ErrorF("nv_output_destroy is called\n");
904 NVOutputPrivatePtr nv_output = output->driver_private;
907 if (nv_output->native_mode)
908 xfree(nv_output->native_mode);
909 xfree(output->driver_private);
914 nv_output_prepare(xf86OutputPtr output)
916 ErrorF("nv_output_prepare is called\n");
917 NVOutputPrivatePtr nv_output = output->driver_private;
918 ScrnInfoPtr pScrn = output->scrn;
919 xf86CrtcPtr crtc = output->crtc;
920 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
921 NVPtr pNv = NVPTR(pScrn);
922 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
923 Bool reset_other_crtc = FALSE;
926 output->funcs->dpms(output, DPMSModeOff);
929 * Here we detect output resource conflicts.
930 * We do this based on connected monitors, since we need to catch this before something important happens.
933 uint8_t output_resource_mask = 0;
934 for (i = 0; i < xf86_config->num_output; i++) {
935 xf86OutputPtr output2 = xf86_config->output[i];
936 NVOutputPrivatePtr nv_output2 = output2->driver_private;
938 /* I don't know how well this will deal with triple connected output situations. */
939 if (output2 != output && output2->crtc) { /* output in use? */
940 output_resource_mask |= (nv_output2->output_resource + 1); /* +1 to actually get a non-zero value */
944 uint8_t or = pNv->dcb_table.entry[nv_output->dcb_entry].or;
945 /* Do we have a output resource conflict? */
946 if (output_resource_mask & (nv_output->output_resource + 1)) {
947 if (or == (1 << (ffs(or) - 1))) { /* we need this output resource */
948 for (i = 0; i < xf86_config->num_output; i++) { /* let's find the other */
949 xf86OutputPtr output2 = xf86_config->output[i];
950 NVOutputPrivatePtr nv_output2 = output2->driver_private;
952 if (output2 != output && output2->status == XF86OutputStatusConnected) {
953 if (nv_output->output_resource == nv_output2->output_resource) {
954 nv_output2->output_resource ^= 1;
955 reset_other_crtc = TRUE;
956 break; /* We don't deal with triple outputs yet */
960 } else { /* we have alternatives */
961 nv_output->output_resource ^= 1;
962 reset_other_crtc = TRUE;
966 if (nv_output->output_resource != nv_output->preferred_output) {
967 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
968 /* Observed on a NV31M, some regs are claimed by one output/crtc. */
969 if (nv_crtc->head == 1) {
970 pNv->fp_regs_owner[0] = 1;
975 /* Output resource changes require resetting the other crtc as well. */
976 if (reset_other_crtc) {
977 uint8_t other_crtc = (~nv_crtc->head) & 1;
978 xf86CrtcPtr crtc2 = nv_find_crtc_by_index(pScrn, other_crtc);
979 /* Only do this when the other crtc is in it's desired mode, when hotplugging something. */
980 if (crtc2 && xf86ModesEqual(&crtc2->mode, &crtc2->desiredMode))
981 NVCrtcModeFix(crtc2);
986 nv_output_commit(xf86OutputPtr output)
988 ErrorF("nv_output_commit is called\n");
990 output->funcs->dpms(output, DPMSModeOn);
993 static const xf86OutputFuncsRec nv_analog_output_funcs = {
994 .dpms = nv_analog_output_dpms,
995 .save = nv_output_save,
996 .restore = nv_output_restore,
997 .mode_valid = nv_output_mode_valid,
998 .mode_fixup = nv_output_mode_fixup,
999 .mode_set = nv_output_mode_set,
1000 .detect = nv_analog_output_detect,
1001 .get_modes = nv_output_get_ddc_modes,
1002 .destroy = nv_output_destroy,
1003 .prepare = nv_output_prepare,
1004 .commit = nv_output_commit,
1008 * Several scaling modes exist, let the user choose.
1010 #define SCALING_MODE_NAME "SCALING_MODE"
1011 static const struct {
1013 enum scaling_modes mode;
1014 } scaling_mode[] = {
1015 { "panel", SCALE_PANEL },
1016 { "fullscreen", SCALE_FULLSCREEN },
1017 { "aspect", SCALE_ASPECT },
1018 { "noscale", SCALE_NOSCALE },
1019 { NULL, SCALE_INVALID}
1021 static Atom scaling_mode_atom;
1024 nv_scaling_mode_lookup(char *name, int size)
1028 /* for when name is zero terminated */
1030 size = strlen(name);
1032 for (i = 0; scaling_mode[i].name; i++)
1033 /* We're getting non-terminated strings */
1034 if (strlen(scaling_mode[i].name) >= size &&
1035 !strncasecmp(name, scaling_mode[i].name, size))
1038 return scaling_mode[i].mode;
1042 nv_digital_output_create_resources(xf86OutputPtr output)
1044 NVOutputPrivatePtr nv_output = output->driver_private;
1045 ScrnInfoPtr pScrn = output->scrn;
1049 * Setup scaling mode property.
1051 scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
1053 error = RRConfigureOutputProperty(output->randr_output,
1054 scaling_mode_atom, TRUE, FALSE, FALSE,
1058 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1059 "RRConfigureOutputProperty error, %d\n", error);
1062 char *existing_scale_name = NULL;
1063 for (i = 0; scaling_mode[i].name; i++)
1064 if (scaling_mode[i].mode == nv_output->scaling_mode)
1065 existing_scale_name = scaling_mode[i].name;
1067 error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
1068 XA_STRING, 8, PropModeReplace,
1069 strlen(existing_scale_name),
1070 existing_scale_name, FALSE, TRUE);
1073 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1074 "Failed to set scaling mode, %d\n", error);
1079 nv_digital_output_set_property(xf86OutputPtr output, Atom property,
1080 RRPropertyValuePtr value)
1082 NVOutputPrivatePtr nv_output = output->driver_private;
1084 if (property == scaling_mode_atom) {
1088 if (value->type != XA_STRING || value->format != 8)
1091 name = (char *) value->data;
1093 /* Match a string to a scaling mode */
1094 ret = nv_scaling_mode_lookup(name, value->size);
1095 if (ret == SCALE_INVALID)
1098 /* LVDS must always use gpu scaling. */
1099 if (ret == SCALE_PANEL && nv_output->type == OUTPUT_LVDS)
1102 nv_output->scaling_mode = ret;
1110 nv_tmds_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
1112 ScrnInfoPtr pScrn = output->scrn;
1113 NVPtr pNv = NVPTR(pScrn);
1114 NVOutputPrivatePtr nv_output = output->driver_private;
1116 /* We can't exceed the native mode.*/
1117 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
1120 if (pNv->dcb_table.entry[nv_output->dcb_entry].duallink_possible) {
1121 if (pMode->Clock > 330000) /* 2x165 MHz */
1122 return MODE_CLOCK_RANGE;
1124 if (pMode->Clock > 165000) /* 165 MHz */
1125 return MODE_CLOCK_RANGE;
1128 return nv_output_mode_valid(output, pMode);
1131 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
1132 .dpms = nv_tmds_output_dpms,
1133 .save = nv_output_save,
1134 .restore = nv_output_restore,
1135 .mode_valid = nv_tmds_output_mode_valid,
1136 .mode_fixup = nv_output_mode_fixup,
1137 .mode_set = nv_output_mode_set,
1138 .detect = nv_tmds_output_detect,
1139 .get_modes = nv_output_get_ddc_modes,
1140 .destroy = nv_output_destroy,
1141 .prepare = nv_output_prepare,
1142 .commit = nv_output_commit,
1143 .create_resources = nv_digital_output_create_resources,
1144 .set_property = nv_digital_output_set_property,
1147 static int nv_lvds_output_mode_valid
1148 (xf86OutputPtr output, DisplayModePtr pMode)
1150 NVOutputPrivatePtr nv_output = output->driver_private;
1152 /* No modes > panel's native res */
1153 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
1156 return nv_output_mode_valid(output, pMode);
1159 static xf86OutputStatus
1160 nv_lvds_output_detect(xf86OutputPtr output)
1162 ErrorF("nv_lvds_output_detect is called\n");
1163 ScrnInfoPtr pScrn = output->scrn;
1164 NVPtr pNv = NVPTR(pScrn);
1165 NVOutputPrivatePtr nv_output = output->driver_private;
1167 if (pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode &&
1168 pNv->VBIOS.fp.native_mode)
1169 return XF86OutputStatusConnected;
1170 if (nv_ddc_detect(output))
1171 return XF86OutputStatusConnected;
1172 if (pNv->VBIOS.fp.edid)
1173 return XF86OutputStatusConnected;
1175 return XF86OutputStatusDisconnected;
1178 static DisplayModePtr
1179 nv_lvds_output_get_modes(xf86OutputPtr output)
1181 ErrorF("nv_lvds_output_get_modes is called\n");
1182 ScrnInfoPtr pScrn = output->scrn;
1183 NVPtr pNv = NVPTR(pScrn);
1184 NVOutputPrivatePtr nv_output = output->driver_private;
1185 DisplayModePtr modes;
1187 if ((modes = nv_output_get_ddc_modes(output)))
1190 if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode ||
1191 (pNv->VBIOS.fp.native_mode == NULL)) {
1192 if (!pNv->VBIOS.fp.edid)
1195 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using hardcoded BIOS FP EDID\n");
1196 xf86MonPtr edid_mon = xf86InterpretEDID(pScrn->scrnIndex, pNv->VBIOS.fp.edid);
1197 return nv_output_get_modes(output, edid_mon);
1200 nv_output->fpWidth = pNv->VBIOS.fp.native_mode->HDisplay;
1201 nv_output->fpHeight = pNv->VBIOS.fp.native_mode->VDisplay;
1203 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1204 nv_output->fpWidth, nv_output->fpHeight);
1206 nv_output->native_mode = xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
1208 return xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
1211 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1212 .dpms = nv_lvds_output_dpms,
1213 .save = nv_output_save,
1214 .restore = nv_output_restore,
1215 .mode_valid = nv_lvds_output_mode_valid,
1216 .mode_fixup = nv_output_mode_fixup,
1217 .mode_set = nv_output_mode_set,
1218 .detect = nv_lvds_output_detect,
1219 .get_modes = nv_lvds_output_get_modes,
1220 .destroy = nv_output_destroy,
1221 .prepare = nv_output_prepare,
1222 .commit = nv_output_commit,
1223 .create_resources = nv_digital_output_create_resources,
1224 .set_property = nv_digital_output_set_property,
1227 static void nv_add_output(ScrnInfoPtr pScrn, int dcb_entry, const xf86OutputFuncsRec *output_funcs, char *outputname)
1229 NVPtr pNv = NVPTR(pScrn);
1230 xf86OutputPtr output;
1231 NVOutputPrivatePtr nv_output;
1233 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1234 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1235 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1237 if (!(output = xf86OutputCreate(pScrn, output_funcs, outputname)))
1240 if (!(nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1)))
1243 output->driver_private = nv_output;
1245 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1246 nv_output->dcb_entry = dcb_entry;
1247 nv_output->type = pNv->dcb_table.entry[dcb_entry].type;
1248 nv_output->last_dpms = NV_DPMS_CLEARED;
1251 * bit0: OUTPUT_0 valid
1252 * bit1: OUTPUT_1 valid
1253 * So lowest order has highest priority.
1254 * Below is guesswork:
1255 * bit2: All outputs valid
1257 /* We choose the preferred output resource initially. */
1258 if (ffs(pNv->dcb_table.entry[dcb_entry].or) & OUTPUT_1) {
1259 nv_output->preferred_output = 1;
1260 nv_output->output_resource = 1;
1262 nv_output->preferred_output = 0;
1263 nv_output->output_resource = 0;
1266 if (nv_output->type == OUTPUT_LVDS || nv_output->type == OUTPUT_TMDS) {
1267 if (pNv->fpScaler) /* GPU Scaling */
1268 nv_output->scaling_mode = SCALE_ASPECT;
1269 else /* Panel scaling */
1270 nv_output->scaling_mode = SCALE_PANEL;
1272 if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
1273 nv_output->scaling_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
1274 if (nv_output->scaling_mode == SCALE_INVALID)
1275 nv_output->scaling_mode = SCALE_ASPECT; /* default */
1279 /* Due to serious problems we have to restrict the crtc's for certain types of outputs. */
1280 /* This is a result of problems with G70 cards that have a dvi with ffs(or) == 1 */
1281 /* Anyone know what the solution for this is? */
1282 /* This does not apply to NV31 LVDS with or == 3. */
1283 if ((nv_output->type == OUTPUT_LVDS || nv_output->type == OUTPUT_TMDS) && nv_output->preferred_output == 0 && pNv->Architecture == NV_ARCH_40) {
1284 output->possible_crtcs = (1 << 0);
1286 if (pNv->switchable_crtc)
1287 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1289 output->possible_crtcs = (1 << nv_output->preferred_output);
1292 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Added output %s\n", outputname);
1295 void NvSetupOutputs(ScrnInfoPtr pScrn)
1297 NVPtr pNv = NVPTR(pScrn);
1298 int i, type, i2c_count[0xf];
1299 char outputname[20];
1300 int vga_count = 0, tv_count = 0, dvia_count = 0, dvid_count = 0, lvds_count = 0;
1302 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1304 pNv->switchable_crtc = FALSE;
1305 if (pNv->NVArch > 0x11 && pNv->twoHeads)
1306 pNv->switchable_crtc = TRUE;
1308 memset(i2c_count, 0, sizeof(i2c_count));
1309 for (i = 0 ; i < pNv->dcb_table.entries; i++)
1310 i2c_count[pNv->dcb_table.entry[i].i2c_index]++;
1312 /* we setup the outputs up from the BIOS table */
1313 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1314 type = pNv->dcb_table.entry[i].type;
1316 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);
1320 if (i2c_count[pNv->dcb_table.entry[i].i2c_index] == 1)
1321 sprintf(outputname, "VGA-%d", vga_count++);
1323 sprintf(outputname, "DVI-A-%d", dvia_count++);
1324 nv_add_output(pScrn, i, &nv_analog_output_funcs, outputname);
1327 sprintf(outputname, "DVI-D-%d", dvid_count++);
1328 nv_add_output(pScrn, i, &nv_tmds_output_funcs, outputname);
1331 sprintf(outputname, "TV-%d", tv_count++);
1332 // nv_add_output(pScrn, i, &nv_tv_output_funcs, outputname);
1335 sprintf(outputname, "LVDS-%d", lvds_count++);
1336 nv_add_output(pScrn, i, &nv_lvds_output_funcs, outputname);
1339 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1345 /*************************************************************************** \
1347 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1349 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1350 |* international laws. Users and possessors of this source code are *|
1351 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1352 |* use this code in individual and commercial software. *|
1354 |* Any use of this source code must include, in the user documenta- *|
1355 |* tion and internal comments to the code, notices to the end user *|
1358 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1360 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1361 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1362 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1363 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1364 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1365 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1366 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1367 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1368 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1369 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1370 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1372 |* U.S. Government End Users. This source code is a "commercial *|
1373 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1374 |* consisting of "commercial computer software" and "commercial *|
1375 |* computer software documentation," as such terms are used in *|
1376 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1377 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1378 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1379 |* all U.S. Government End Users acquire the source code with only *|
1380 |* those rights set forth herein. *|
1382 \***************************************************************************/