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 /* These functions now write into the output, instead of a specific ramdac */
159 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
161 NVOutputPrivatePtr nv_output = output->driver_private;
162 ScrnInfoPtr pScrn = output->scrn;
163 NVPtr pNv = NVPTR(pScrn);
165 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, ramdac_reg, val);
168 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
170 NVOutputPrivatePtr nv_output = output->driver_private;
171 ScrnInfoPtr pScrn = output->scrn;
172 NVPtr pNv = NVPTR(pScrn);
174 return nvReadRAMDAC(pNv, nv_output->preferred_ramdac, ramdac_reg);
177 static void dpms_update_output_ramdac(xf86OutputPtr output, int mode)
179 NVOutputPrivatePtr nv_output = output->driver_private;
180 ScrnInfoPtr pScrn = output->scrn;
181 NVPtr pNv = NVPTR(pScrn);
182 xf86CrtcPtr crtc = output->crtc;
183 NVCrtcPrivatePtr nv_crtc = NULL;
184 if (crtc) nv_crtc = crtc->driver_private;
186 /* We may be going for modesetting, so we must reset our output binding */
187 if (mode == DPMSModeOff) {
189 NVWriteVGACR5758(pNv, nv_crtc->head, 0, 0x7f);
190 NVWriteVGACR5758(pNv, nv_crtc->head, 2, 0);
195 /* The previous call was not a modeset, but a normal dpms call */
197 NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
198 NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
203 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
205 NVOutputPrivatePtr nv_output = output->driver_private;
206 NVPtr pNv = NVPTR(output->scrn);
207 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
209 ErrorF("nv_lvds_output_dpms is called with mode %d\n", mode);
211 dpms_update_output_ramdac(output, mode);
213 if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_power_scripts)
217 case DPMSModeStandby:
218 case DPMSModeSuspend:
219 call_lvds_script(output->scrn, nv_crtc->head, LVDS_BACKLIGHT_OFF);
222 call_lvds_script(output->scrn, nv_crtc->head, LVDS_PANEL_OFF);
225 call_lvds_script(output->scrn, nv_crtc->head, LVDS_PANEL_ON);
232 nv_analog_output_dpms(xf86OutputPtr output, int mode)
234 xf86CrtcPtr crtc = output->crtc;
236 ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
238 dpms_update_output_ramdac(output, mode);
241 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
243 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
248 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
250 xf86CrtcPtr crtc = output->crtc;
251 NVOutputPrivatePtr nv_output = output->driver_private;
252 NVPtr pNv = NVPTR(output->scrn);
254 ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
256 dpms_update_output_ramdac(output, mode);
258 /* Are we assigned a ramdac already?, else we will be activated during mode set */
260 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
262 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
264 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_FP_CONTROL);
266 case DPMSModeStandby:
267 case DPMSModeSuspend:
269 /* cut the TMDS output */
270 fpcontrol |= 0x20000022;
273 /* disable cutting the TMDS output */
274 fpcontrol &= ~0x20000022;
277 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
281 /* This sequence is an optimized/shortened version of what the blob does */
282 /* 0x40 and 0x43 are dual link dvi/lvds related, so don't touch them for now */
283 uint32_t tmds_regs_nv40[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, /* 0x40, 0x43,*/ 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a, 0x2b };
284 uint32_t tmds_regs_nv30[] = { 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x29, 0x2a, 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x3a, 0x2b };
286 #define TMDS_REGS(index) ( tmds_regs(pNv, index) )
288 uint32_t tmds_regs(NVPtr pNv, int i)
290 if (pNv->Architecture == NV_ARCH_40) {
291 return tmds_regs_nv40[i];
293 return tmds_regs_nv30[i];
297 #define TMDS_SIZE ( tmds_size(pNv) )
299 uint32_t tmds_size(NVPtr pNv)
301 if (pNv->Architecture == NV_ARCH_40) {
302 return(sizeof(tmds_regs_nv40)/sizeof(tmds_regs_nv40[0]));
304 return(sizeof(tmds_regs_nv30)/sizeof(tmds_regs_nv30[0]));
308 /* Does anyone know the precise purpose of this second register set? */
309 uint32_t tmds2_regs_nv40[] = { 0x2b };
310 uint32_t tmds2_regs_nv30[] = { 0x2b };
312 #define TMDS2_REGS(index) ( tmds2_regs(pNv, index) )
314 uint32_t tmds2_regs(NVPtr pNv, int i)
316 if (pNv->Architecture == NV_ARCH_40) {
317 return tmds2_regs_nv40[i];
319 return tmds2_regs_nv30[i];
323 #define TMDS2_SIZE ( tmds2_size(pNv) )
325 uint32_t tmds2_size(NVPtr pNv)
327 if (pNv->Architecture == NV_ARCH_40) {
328 return(sizeof(tmds2_regs_nv40)/sizeof(tmds2_regs_nv40[0]));
330 return(sizeof(tmds2_regs_nv30)/sizeof(tmds2_regs_nv30[0]));
334 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
336 NVOutputPrivatePtr nv_output = output->driver_private;
340 regp = &state->dac_reg[nv_output->preferred_ramdac];
342 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
344 /* Store the registers in case we need them again for something (like data for VT restore) */
345 for (i = 0; i < 0xFF; i++) {
346 regp->TMDS[i] = NVOutputReadTMDS(output, i);
349 for (i = 0; i < 0xFF; i++) {
350 regp->TMDS2[i] = NVOutputReadTMDS2(output, i);
354 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
356 NVOutputPrivatePtr nv_output = output->driver_private;
359 regp = &state->dac_reg[nv_output->preferred_ramdac];
361 /* This exists purely for proper text mode restore */
362 if (override) NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
365 /* NOTE: Don't rely on this data for anything other than restoring VT's */
368 nv_output_save (xf86OutputPtr output)
370 ScrnInfoPtr pScrn = output->scrn;
371 NVPtr pNv = NVPTR(pScrn);
372 RIVA_HW_STATE *state;
374 ErrorF("nv_output_save is called\n");
375 state = &pNv->SavedReg;
377 /* Due to strange mapping of outputs we could have swapped analog and digital */
378 /* So we force save all the registers */
379 nv_output_save_state_ext(output, state);
382 uint32_t nv_calc_clock_from_pll(xf86OutputPtr output)
384 ScrnInfoPtr pScrn = output->scrn;
385 NVPtr pNv = NVPTR(pScrn);
386 RIVA_HW_STATE *state;
388 NVOutputPrivatePtr nv_output = output->driver_private;
390 state = &pNv->SavedReg;
391 /* Registers are stored by their preferred ramdac */
392 regp = &state->dac_reg[nv_output->preferred_ramdac];
394 /* Only do it once for a dvi-d/dvi-a pair */
395 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
396 Bool swapped_clock = FALSE;
397 Bool vpllb_disabled = FALSE;
398 /* Bit3 swaps crtc (clocks are bound to crtc) and output */
399 if (regp->TMDS[0x4] & (1 << 3)) {
400 swapped_clock = TRUE;
403 uint8_t vpll_num = swapped_clock ^ nv_output->preferred_ramdac;
408 /* For the moment the syntax is the same for NV40 and earlier */
409 if (pNv->Architecture == NV_ARCH_40) {
410 vplla = vpll_num ? state->vpll2_a : state->vpll1_a;
411 vpllb = vpll_num ? state->vpll2_b : state->vpll1_b;
413 vplla = vpll_num ? state->vpll2 : state->vpll;
414 if (pNv->twoStagePLL)
415 vpllb = vpll_num ? state->vpll2B : state->vpllB;
418 if (!pNv->twoStagePLL)
419 vpllb_disabled = TRUE;
421 /* This is the dummy value nvidia sets when vpll is disabled */
422 if ((vpllb & 0xFFFF) == 0x11F)
423 vpllb_disabled = TRUE;
425 uint8_t m1, m2, n1, n2, p;
428 n1 = (vplla >> 8) & 0xFF;
429 p = (vplla >> 16) & 0x7;
431 if (vpllb_disabled) {
436 n2 = (vpllb >> 8) & 0xFF;
439 uint32_t clock = ((pNv->CrystalFreqKHz * n1 * n2)/(m1 * m2)) >> p;
440 ErrorF("The original bios clock seems to have been %d kHz\n", clock);
447 void nv_set_tmds_registers(xf86OutputPtr output, uint32_t clock, Bool override, Bool crosswired)
449 NVOutputPrivatePtr nv_output = output->driver_private;
455 * Resetting all registers is a bad idea, it seems to work fine without it.
458 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
459 ScrnInfoPtr pScrn = output->scrn;
460 NVPtr pNv = NVPTR(pScrn);
461 xf86CrtcPtr crtc = output->crtc;
462 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
464 parse_t_table(pScrn, &pNv->VBIOS, nv_output->dcb_entry, nv_crtc->head, clock/10);
467 /* We don't know the right switch in the bios */
468 /* Luckily we do know the values ;-) */
469 /* Bit 3 crosswires output and crtc */
470 /* For VT restore we must always restore the right thing */
471 if ((override && crosswired) || (!override && nv_crtc->head != nv_output->preferred_ramdac)) {
476 if (nv_output->type == OUTPUT_LVDS)
478 NVOutputWriteTMDS(output, 0x4, reg04);
483 nv_output_restore (xf86OutputPtr output)
485 ScrnInfoPtr pScrn = output->scrn;
486 NVPtr pNv = NVPTR(pScrn);
487 RIVA_HW_STATE *state;
488 NVOutputPrivatePtr nv_output = output->driver_private;
490 ErrorF("nv_output_restore is called\n");
492 state = &pNv->SavedReg;
493 regp = &state->dac_reg[nv_output->preferred_ramdac];
495 /* Due to strange mapping of outputs we could have swapped analog and digital */
496 /* So we force load all the registers */
497 nv_output_load_state_ext(output, state, TRUE);
501 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
503 if (pMode->Flags & V_DBLSCAN)
504 return MODE_NO_DBLESCAN;
506 if (pMode->Clock > 400000 || pMode->Clock < 25000)
507 return MODE_CLOCK_RANGE;
514 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
515 DisplayModePtr adjusted_mode)
517 ErrorF("nv_output_mode_fixup is called\n");
523 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
525 NVOutputPrivatePtr nv_output = output->driver_private;
526 ScrnInfoPtr pScrn = output->scrn;
527 //RIVA_HW_STATE *state;
528 //NVOutputRegPtr regp, savep;
530 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
533 /* It's getting quiet here, not removing function just yet, we may still need it */
535 //state = &pNv->ModeReg;
536 //regp = &state->dac_reg[nv_output->preferred_ramdac];
538 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
542 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
546 for (i = 0; i < config->num_output; i++) {
547 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
549 /* is it this output ?? */
550 if (config->output[i] == output)
553 /* it the output connected */
554 if (config->output[i]->crtc == NULL)
558 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
563 ErrorF("%d: crtc %d output %d twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->preferred_ramdac, two_crt, two_mon);
568 nv_output_mode_set_routing(xf86OutputPtr output)
570 NVOutputPrivatePtr nv_output = output->driver_private;
571 xf86CrtcPtr crtc = output->crtc;
572 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
573 ScrnInfoPtr pScrn = output->scrn;
574 NVPtr pNv = NVPTR(pScrn);
577 uint32_t output_reg[2];
579 if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
583 if (pNv->Architecture == NV_ARCH_40) {
584 /* NV4x cards have strange ways of dealing with dualhead */
585 /* Also see reg594 in nv_crtc.c */
586 output_reg[0] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
587 /* So far only dual dvi cards(or lvds + dvi i think) seem to use (and need?) this */
589 output_reg[1] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
592 output_reg[nv_output->preferred_ramdac] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
594 output_reg[nv_output->preferred_ramdac] = 0x0;
598 /* Only one can be on crtc1 */
599 if (nv_crtc->head == 1) {
600 output_reg[nv_output->preferred_ramdac] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
602 output_reg[(~nv_output->preferred_ramdac) & 1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
605 if (pNv->Architecture == NV_ARCH_40) {
606 /* The registers can't be considered seperately on nv40 */
607 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT, output_reg[0]);
608 nvWriteRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT, output_reg[1]);
610 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT, output_reg[nv_output->preferred_ramdac]);
613 /* This could use refinement for flatpanels, but it should work this way */
614 if (pNv->NVArch < 0x44) {
615 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, 0xf0000000);
616 if (pNv->Architecture == NV_ARCH_40)
617 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0xf0000000);
619 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, 0x00100000);
620 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0x00100000);
625 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
626 DisplayModePtr adjusted_mode)
628 ScrnInfoPtr pScrn = output->scrn;
629 NVPtr pNv = NVPTR(pScrn);
630 RIVA_HW_STATE *state;
632 ErrorF("nv_output_mode_set is called\n");
634 state = &pNv->ModeReg;
636 nv_output_mode_set_regs(output, mode, adjusted_mode);
637 nv_output_load_state_ext(output, state, FALSE);
638 nv_set_tmds_registers(output, adjusted_mode->Clock, FALSE, FALSE);
639 nv_output_mode_set_routing(output);
643 nv_get_edid(xf86OutputPtr output)
645 /* no use for shared DDC output */
646 NVOutputPrivatePtr nv_output = output->driver_private;
649 if (nv_output->pDDCBus == NULL)
652 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
656 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
659 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
660 nv_output->type == OUTPUT_LVDS))
671 nv_ddc_detect(xf86OutputPtr output)
673 xf86MonPtr m = nv_get_edid(output);
683 nv_crt_load_detect(xf86OutputPtr output)
685 ScrnInfoPtr pScrn = output->scrn;
686 NVOutputPrivatePtr nv_output = output->driver_private;
687 NVPtr pNv = NVPTR(pScrn);
688 CARD32 reg_output, reg_test_ctrl, temp;
689 Bool present = FALSE;
691 /* For some reason we get false positives on output 1, maybe due tv-out? */
692 if (nv_output->preferred_ramdac == 1) {
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 reg_output = nvReadRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT);
705 reg_test_ctrl = nvReadRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL);
707 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
709 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
712 temp = nvReadRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT);
713 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT, temp | 1);
715 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
716 temp = nvReadRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL);
717 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
721 present = (nvReadRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
723 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
724 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
726 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_OUTPUT, reg_output);
727 nvWriteRAMDAC(pNv, nv_output->preferred_ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
730 ErrorF("A crt was detected on output %d with no ddc support\n", nv_output->preferred_ramdac);
737 static xf86OutputStatus
738 nv_tmds_output_detect(xf86OutputPtr output)
740 ErrorF("nv_tmds_output_detect is called\n");
742 if (nv_ddc_detect(output))
743 return XF86OutputStatusConnected;
745 return XF86OutputStatusDisconnected;
749 static xf86OutputStatus
750 nv_analog_output_detect(xf86OutputPtr output)
752 ErrorF("nv_analog_output_detect is called\n");
754 if (nv_ddc_detect(output))
755 return XF86OutputStatusConnected;
757 if (nv_crt_load_detect(output))
758 return XF86OutputStatusConnected;
760 return XF86OutputStatusDisconnected;
763 static DisplayModePtr
764 nv_output_get_modes(xf86OutputPtr output)
766 NVOutputPrivatePtr nv_output = output->driver_private;
768 DisplayModePtr ddc_modes;
770 ErrorF("nv_output_get_modes is called\n");
772 ddc_mon = nv_get_edid(output);
774 xf86OutputSetEDID(output, ddc_mon);
779 ddc_modes = xf86OutputGetEDIDModes (output);
781 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
785 for (i = 0; i < 4; i++) {
786 /* We only look at detailed timings atm */
787 if (ddc_mon->det_mon[i].type != DT)
789 /* Selecting only based on width ok? */
790 if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
791 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
792 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
796 /* Add a native resolution mode that is preferred */
797 /* Reduced blanking should be fine on DVI monitor */
798 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
799 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
800 /* We want the new mode to be preferred */
801 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
802 if (mode->type & M_T_PREFERRED) {
803 mode->type &= ~M_T_PREFERRED;
806 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
813 nv_output_destroy (xf86OutputPtr output)
815 ErrorF("nv_output_destroy is called\n");
816 if (output->driver_private)
817 xfree (output->driver_private);
821 nv_output_prepare(xf86OutputPtr output)
823 ErrorF("nv_output_prepare is called\n");
824 NVOutputPrivatePtr nv_output = output->driver_private;
825 ScrnInfoPtr pScrn = output->scrn;
826 xf86CrtcPtr crtc = output->crtc;
827 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
828 NVPtr pNv = NVPTR(pScrn);
830 output->funcs->dpms(output, DPMSModeOff);
832 /* Set our output type and output routing possibilities to the right registers */
833 NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
834 NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
838 nv_output_commit(xf86OutputPtr output)
840 ErrorF("nv_output_commit is called\n");
842 output->funcs->dpms(output, DPMSModeOn);
845 static const xf86OutputFuncsRec nv_analog_output_funcs = {
846 .dpms = nv_analog_output_dpms,
847 .save = nv_output_save,
848 .restore = nv_output_restore,
849 .mode_valid = nv_output_mode_valid,
850 .mode_fixup = nv_output_mode_fixup,
851 .mode_set = nv_output_mode_set,
852 .detect = nv_analog_output_detect,
853 .get_modes = nv_output_get_modes,
854 .destroy = nv_output_destroy,
855 .prepare = nv_output_prepare,
856 .commit = nv_output_commit,
859 #ifdef RANDR_12_INTERFACE
861 * Several scaling modes exist, let the user choose.
863 #define SCALING_MODE_NAME "SCALING_MODE"
864 #define NUM_SCALING_METHODS 3
865 static char *scaling_mode_names[] = {
870 static Atom scaling_mode_atom;
873 nv_scaling_mode_lookup(char *name, int size)
877 for (i = 0; i < NUM_SCALING_METHODS; i++) {
878 if (!strncmp(name, scaling_mode_names[i], size))
886 nv_tmds_create_resources(xf86OutputPtr output)
888 NVOutputPrivatePtr nv_output = output->driver_private;
889 ScrnInfoPtr pScrn = output->scrn;
893 * Setup scaling mode property.
895 scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
897 error = RRConfigureOutputProperty(output->randr_output,
898 scaling_mode_atom, TRUE, FALSE, FALSE,
902 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
903 "RRConfigureOutputProperty error, %d\n", error);
906 error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
907 XA_STRING, 8, PropModeReplace,
908 strlen(scaling_mode_names[nv_output->scaling_mode]),
909 scaling_mode_names[nv_output->scaling_mode],
913 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
914 "Failed to set scaling mode, %d\n", error);
919 nv_tmds_set_property(xf86OutputPtr output, Atom property,
920 RRPropertyValuePtr value)
922 NVOutputPrivatePtr nv_output = output->driver_private;
924 if (property == scaling_mode_atom) {
928 if (value->type != XA_STRING || value->format != 8)
931 name = (char*) value->data;
933 /* Match a string to a scaling mode */
934 ret = nv_scaling_mode_lookup(name, value->size);
938 nv_output->scaling_mode = ret;
945 #endif /* RANDR_12_INTERFACE */
947 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
948 .dpms = nv_tmds_output_dpms,
949 .save = nv_output_save,
950 .restore = nv_output_restore,
951 .mode_valid = nv_output_mode_valid,
952 .mode_fixup = nv_output_mode_fixup,
953 .mode_set = nv_output_mode_set,
954 .detect = nv_tmds_output_detect,
955 .get_modes = nv_output_get_modes,
956 .destroy = nv_output_destroy,
957 .prepare = nv_output_prepare,
958 .commit = nv_output_commit,
959 #ifdef RANDR_12_INTERFACE
960 .create_resources = nv_tmds_create_resources,
961 .set_property = nv_tmds_set_property,
962 #endif /* RANDR_12_INTERFACE */
965 static int nv_lvds_output_mode_valid
966 (xf86OutputPtr output, DisplayModePtr pMode)
968 NVOutputPrivatePtr nv_output = output->driver_private;
970 /* No modes > panel's native res */
971 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
974 return nv_output_mode_valid(output, pMode);
977 static xf86OutputStatus
978 nv_lvds_output_detect(xf86OutputPtr output)
980 ScrnInfoPtr pScrn = output->scrn;
981 NVPtr pNv = NVPTR(pScrn);
982 NVOutputPrivatePtr nv_output = output->driver_private;
984 if (pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode &&
985 pNv->VBIOS.fp.native_mode)
986 return XF86OutputStatusConnected;
987 if (nv_ddc_detect(output))
988 return XF86OutputStatusConnected;
990 return XF86OutputStatusDisconnected;
993 static DisplayModePtr
994 nv_lvds_output_get_modes(xf86OutputPtr output)
996 ScrnInfoPtr pScrn = output->scrn;
997 NVPtr pNv = NVPTR(pScrn);
998 NVOutputPrivatePtr nv_output = output->driver_private;
999 DisplayModePtr modes;
1001 if ((modes = nv_output_get_modes(output)))
1004 /* it is possible to set up a mode from what we can read from the
1005 * RAMDAC registers, but if we can't read the BIOS table correctly
1006 * we might as well give up */
1007 if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode ||
1008 (pNv->VBIOS.fp.native_mode == NULL))
1011 nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1012 nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1013 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1015 if (pNv->VBIOS.fp.native_mode->HDisplay != nv_output->fpWidth ||
1016 pNv->VBIOS.fp.native_mode->VDisplay != nv_output->fpHeight) {
1017 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1018 "Panel size mismatch; ignoring RAMDAC\n");
1019 nv_output->fpWidth = pNv->VBIOS.fp.native_mode->HDisplay;
1020 nv_output->fpHeight = pNv->VBIOS.fp.native_mode->VDisplay;
1023 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1024 nv_output->fpWidth, nv_output->fpHeight);
1026 nv_output->native_mode = xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
1028 return xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
1031 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1032 .dpms = nv_lvds_output_dpms,
1033 .save = nv_output_save,
1034 .restore = nv_output_restore,
1035 .mode_valid = nv_lvds_output_mode_valid,
1036 .mode_fixup = nv_output_mode_fixup,
1037 .mode_set = nv_output_mode_set,
1038 .detect = nv_lvds_output_detect,
1039 .get_modes = nv_lvds_output_get_modes,
1040 .destroy = nv_output_destroy,
1041 .prepare = nv_output_prepare,
1042 .commit = nv_output_commit,
1045 static void nv_add_analog_output(ScrnInfoPtr pScrn, int dcb_entry, Bool dvi_pair)
1047 NVPtr pNv = NVPTR(pScrn);
1048 xf86OutputPtr output;
1049 NVOutputPrivatePtr nv_output;
1050 char outputname[20];
1051 Bool create_output = TRUE;
1052 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1054 /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1056 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1059 sprintf(outputname, "VGA-%d", pNv->vga_count);
1063 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1068 nv_output->dcb_entry = dcb_entry;
1070 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1071 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1073 nv_output->type = OUTPUT_ANALOG;
1076 * bit0: OUTPUT_0 valid
1077 * bit1: OUTPUT_1 valid
1078 * So lowest order has highest priority.
1079 * Below is guesswork:
1080 * bit2: All outputs valid
1082 nv_output->valid_ramdac = ffs(pNv->dcb_table.entry[dcb_entry].or);
1084 if (!create_output) {
1089 /* Delay creation of output until we actually know we want it */
1090 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1094 output->driver_private = nv_output;
1096 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1098 /* This also facilitates proper output routing for dvi */
1099 /* See sel_clk assignment in nv_crtc.c */
1100 if (nv_output->valid_ramdac & OUTPUT_1) {
1101 nv_output->preferred_ramdac = 1;
1103 nv_output->preferred_ramdac = 0;
1106 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1108 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1111 static void nv_add_digital_output(ScrnInfoPtr pScrn, int dcb_entry, int lvds)
1113 NVPtr pNv = NVPTR(pScrn);
1114 xf86OutputPtr output;
1115 NVOutputPrivatePtr nv_output;
1116 char outputname[20];
1117 Bool create_output = TRUE;
1118 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1121 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1124 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1128 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1134 nv_output->dcb_entry = dcb_entry;
1136 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1137 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1139 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1142 * bit0: OUTPUT_0 valid
1143 * bit1: OUTPUT_1 valid
1144 * So lowest order has highest priority.
1145 * Below is guesswork:
1146 * bit2: All outputs valid
1148 nv_output->valid_ramdac = ffs(pNv->dcb_table.entry[dcb_entry].or);
1151 nv_output->type = OUTPUT_LVDS;
1152 /* comment below two lines to test LVDS under RandR12.
1153 * If your screen "blooms" or "bleeds" (i.e. has a developing
1154 * white / psychedelic pattern) then KILL X IMMEDIATELY
1155 * (ctrl+alt+backspace) & if the effect continues reset power */
1156 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1157 create_output = FALSE;
1159 nv_output->type = OUTPUT_TMDS;
1162 if (!create_output) {
1167 /* Delay creation of output until we are certain is desirable */
1169 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1171 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1175 output->driver_private = nv_output;
1177 /* This also facilitates proper output routing for dvi */
1178 /* See sel_clk assignment in nv_crtc.c */
1179 if (nv_output->valid_ramdac & OUTPUT_1) {
1180 nv_output->preferred_ramdac = 1;
1182 nv_output->preferred_ramdac = 0;
1185 if (pNv->fpScaler) {
1187 nv_output->scaling_mode = 2;
1189 /* "Panel mode" fully filled */
1190 nv_output->scaling_mode = 0;
1193 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1195 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1198 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1200 NVPtr pNv = NVPTR(pScrn);
1201 int i, type, bus_count[0xf], digital_counter = 0;
1203 memset(bus_count, 0, sizeof(bus_count));
1204 for (i = 0 ; i < pNv->dcb_table.entries; i++)
1205 bus_count[pNv->dcb_table.entry[i].bus]++;
1207 /* we setup the outputs up from the BIOS table */
1208 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1209 type = pNv->dcb_table.entry[i].type;
1211 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1215 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);
1219 nv_add_analog_output(pScrn, i, (bus_count[pNv->dcb_table.entry[i].bus] > 1));
1222 nv_add_digital_output(pScrn, i, 0);
1226 nv_add_digital_output(pScrn, i, 1);
1227 /* I'm assuming that lvds+dvi has the same effect as dual dvi */
1235 if (digital_counter > 1) {
1236 pNv->dual_dvi = TRUE;
1238 pNv->dual_dvi = FALSE;
1242 void NvSetupOutputs(ScrnInfoPtr pScrn)
1244 NVPtr pNv = NVPTR(pScrn);
1246 pNv->Television = FALSE;
1248 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1249 NvDCBSetupOutputs(pScrn);
1252 /*************************************************************************** \
1254 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1256 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1257 |* international laws. Users and possessors of this source code are *|
1258 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1259 |* use this code in individual and commercial software. *|
1261 |* Any use of this source code must include, in the user documenta- *|
1262 |* tion and internal comments to the code, notices to the end user *|
1265 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1267 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1268 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1269 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1270 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1271 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1272 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1273 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1274 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1275 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1276 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1277 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1279 |* U.S. Government End Users. This source code is a "commercial *|
1280 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1281 |* consisting of "commercial computer software" and "commercial *|
1282 |* computer software documentation," as such terms are used in *|
1283 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1284 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1285 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1286 |* all U.S. Government End Users acquire the source code with only *|
1287 |* those rights set forth herein. *|
1289 \***************************************************************************/