2 * Copyright 2006 Dave Airlie
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
27 * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
28 * decleration is at the bottom of this file as it is rather ugly
42 #include "mipointer.h"
43 #include "windowstr.h"
45 #include <X11/extensions/render.h>
48 #include "nv_include.h"
50 const char *OutputType[] = {
59 const char *MonTypeName[7] = {
69 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
71 NVOutputPrivatePtr nv_output = output->driver_private;
72 ScrnInfoPtr pScrn = output->scrn;
73 NVPtr pNv = NVPTR(pScrn);
75 nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
78 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
80 NVOutputPrivatePtr nv_output = output->driver_private;
81 ScrnInfoPtr pScrn = output->scrn;
82 NVPtr pNv = NVPTR(pScrn);
84 return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
87 static void nv_output_backlight_enable(xf86OutputPtr output, Bool on)
89 ScrnInfoPtr pScrn = output->scrn;
90 NVPtr pNv = NVPTR(pScrn);
92 /* This is done differently on each laptop. Here we
93 define the ones we know for sure. */
95 #if defined(__powerpc__)
96 if((pNv->Chipset == 0x10DE0179) ||
97 (pNv->Chipset == 0x10DE0189) ||
98 (pNv->Chipset == 0x10DE0329))
100 /* NV17,18,34 Apple iMac, iBook, PowerBook */
101 CARD32 tmp_pmc, tmp_pcrt;
102 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
103 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
105 tmp_pmc |= (1 << 31);
108 nvWriteMC(pNv, 0x10F0, tmp_pmc);
109 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
113 if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
114 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
118 nv_panel_output_dpms(xf86OutputPtr output, int mode)
122 case DPMSModeStandby:
123 case DPMSModeSuspend:
125 nv_output_backlight_enable(output, 0);
128 nv_output_backlight_enable(output, 1);
135 nv_analog_output_dpms(xf86OutputPtr output, int mode)
141 nv_digital_output_dpms(xf86OutputPtr output, int mode)
143 NVOutputPrivatePtr nv_output = output->driver_private;
144 xf86CrtcPtr crtc = output->crtc;
145 ScrnInfoPtr pScrn = output->scrn;
146 NVPtr pNv = NVPTR(pScrn);
147 NVCrtcPrivatePtr nv_crtc;
152 nv_crtc = crtc->driver_private;
154 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL) & 0xCfffffCC;
156 case DPMSModeStandby:
157 case DPMSModeSuspend:
159 /* cut the TMDS output */
160 fpcontrol |= 0x20000022;
163 fpcontrol |= nv_output->fpSyncs;
166 nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL, fpcontrol);
170 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
172 NVOutputPrivatePtr nv_output = output->driver_private;
173 ScrnInfoPtr pScrn = output->scrn;
174 NVPtr pNv = NVPTR(pScrn);
177 regp = &state->dac_reg[nv_output->ramdac];
178 regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
179 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
180 regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
181 state->config = nvReadFB(pNv, NV_PFB_CFG0);
183 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
185 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
186 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
187 } else if(pNv->twoHeads) {
188 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
190 // regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC);
191 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
193 if (nv_output->type == OUTPUT_DIGITAL) {
196 for (i = 0; i < 7; i++) {
197 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
199 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
202 for (i = 0; i < 7; i++) {
203 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
205 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
211 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
213 NVOutputPrivatePtr nv_output = output->driver_private;
214 ScrnInfoPtr pScrn = output->scrn;
215 NVPtr pNv = NVPTR(pScrn);
218 regp = &state->dac_reg[nv_output->ramdac];
220 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
221 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
222 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
223 // NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync);
226 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
227 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
228 } else if(pNv->twoHeads) {
229 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
232 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
233 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
235 if (nv_output->type == OUTPUT_DIGITAL) {
238 for (i = 0; i < 7; i++) {
239 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
240 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
243 for (i = 0; i < 7; i++) {
244 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
246 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
254 nv_output_save (xf86OutputPtr output)
256 ScrnInfoPtr pScrn = output->scrn;
257 NVPtr pNv = NVPTR(pScrn);
258 RIVA_HW_STATE *state;
260 state = &pNv->SavedReg;
262 nv_output_save_state_ext(output, state);
267 nv_output_restore (xf86OutputPtr output)
269 ScrnInfoPtr pScrn = output->scrn;
270 NVPtr pNv = NVPTR(pScrn);
271 RIVA_HW_STATE *state;
273 state = &pNv->SavedReg;
275 nv_output_load_state_ext(output, state);
279 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
281 if (pMode->Flags & V_DBLSCAN)
282 return MODE_NO_DBLESCAN;
284 if (pMode->Clock > 400000 || pMode->Clock < 25000)
285 return MODE_CLOCK_RANGE;
292 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
293 DisplayModePtr adjusted_mode)
299 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
301 NVOutputPrivatePtr nv_output = output->driver_private;
302 ScrnInfoPtr pScrn = output->scrn;
303 NVPtr pNv = NVPTR(pScrn);
307 regp = &state->dac_reg[nv_output->ramdac];
308 if (pNv->usePanelTweak) {
309 tweak = pNv->PanelTweak;
311 /* begin flat panel hacks */
312 /* This is unfortunate, but some chips need this register
313 tweaked or else you get artifacts where adjacent pixels are
314 swapped. There are no hard rules for what to set here so all
315 we can do is experiment and apply hacks. */
317 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
318 /* At least one NV34 laptop needs this workaround. */
322 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
325 /* end flat panel hacks */
331 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
333 NVOutputPrivatePtr nv_output = output->driver_private;
334 ScrnInfoPtr pScrn = output->scrn;
336 NVPtr pNv = NVPTR(pScrn);
337 NVFBLayout *pLayout = &pNv->CurrentLayout;
338 RIVA_HW_STATE *state, *sv_state;
340 NVOutputRegPtr regp, savep;
341 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
344 state = &pNv->ModeReg;
345 regp = &state->dac_reg[nv_output->ramdac];
347 sv_state = &pNv->SavedReg;
348 savep = &sv_state->dac_reg[nv_output->ramdac];
350 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL))
354 for (i = 0; i < 7; i++) {
355 regp->fp_horiz_regs[i] = savep->fp_horiz_regs[i];
356 regp->fp_vert_regs[i] = savep->fp_vert_regs[i];
359 regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
360 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
361 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
362 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
363 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
364 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
365 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
367 regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
368 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
369 regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
370 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
371 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
372 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
373 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
377 if (pNv->Architecture >= NV_ARCH_10)
378 regp->nv10_cursync = savep->nv10_cursync | (1<<25);
380 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
382 regp->debug_0 = savep->debug_0;
383 regp->fp_control = savep->fp_control & 0xfff000ff;
385 if(!pNv->fpScaler || (nv_output->fpWidth <= mode->HDisplay)
386 || (nv_output->fpHeight <= mode->VDisplay))
388 regp->fp_control |= (1 << 8) ;
390 regp->crtcSync = savep->crtcSync;
391 regp->crtcSync += nv_output_tweak_panel(output, state);
393 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
396 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
398 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
401 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
402 regp->dither = savep->dither & ~0x00010000;
404 regp->dither |= 0x00010000;
406 ErrorF("savep->dither %08X\n", savep->dither);
407 regp->dither = savep->dither & ~1;
413 if(pLayout->depth < 24)
414 bpp = pLayout->depth;
417 regp->general = bpp == 16 ? 0x00101100 : 0x00100100;
419 if (pNv->alphaCursor)
420 regp->general |= (1<<29);
422 if(bpp != 8) /* DirectColor */
423 regp->general |= 0x00000030;
426 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
430 for (i = 0; i < config->num_output; i++) {
431 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
433 /* is it this output ?? */
434 if (config->output[i] == output)
437 /* it the output connected */
438 if (config->output[i]->crtc == NULL)
442 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG))
449 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
451 if (nv_crtc->crtc == 1 && two_mon)
452 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2;
454 ErrorF("%d: crtc %d output%d: %04X: twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->ramdac, regp->output, two_crt, two_mon);
459 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
460 DisplayModePtr adjusted_mode)
462 ScrnInfoPtr pScrn = output->scrn;
463 NVPtr pNv = NVPTR(pScrn);
464 RIVA_HW_STATE *state;
466 state = &pNv->ModeReg;
468 nv_output_mode_set_regs(output, mode);
469 nv_output_load_state_ext(output, state);
473 nv_ddc_detect(xf86OutputPtr output)
475 /* no use for shared DDC output */
476 NVOutputPrivatePtr nv_output = output->driver_private;
479 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
483 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
486 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL))
493 nv_crt_load_detect(xf86OutputPtr output)
495 ScrnInfoPtr pScrn = output->scrn;
496 CARD32 reg_output, reg_test_ctrl, temp;
499 reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
500 reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
502 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
504 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
507 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
508 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
510 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
511 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
512 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
516 present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
518 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
519 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
521 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
522 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
524 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
531 static xf86OutputStatus
532 nv_digital_output_detect(xf86OutputPtr output)
534 NVOutputPrivatePtr nv_output = output->driver_private;
536 if (nv_ddc_detect(output))
537 return XF86OutputStatusConnected;
539 return XF86OutputStatusDisconnected;
543 static xf86OutputStatus
544 nv_analog_output_detect(xf86OutputPtr output)
546 NVOutputPrivatePtr nv_output = output->driver_private;
548 if (nv_ddc_detect(output))
549 return XF86OutputStatusConnected;
551 /* seems a bit flaky on ramdac 1 */
552 if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
553 return XF86OutputStatusConnected;
555 return XF86OutputStatusDisconnected;
558 static DisplayModePtr
559 nv_output_get_modes(xf86OutputPtr output)
561 ScrnInfoPtr pScrn = output->scrn;
562 NVOutputPrivatePtr nv_output = output->driver_private;
564 DisplayModePtr ddc_modes, mode;
568 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
570 if (ddc_mon == NULL) {
571 xf86OutputSetEDID(output, ddc_mon);
575 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
576 xf86OutputSetEDID(output, NULL);
580 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
581 xf86OutputSetEDID(output, NULL);
585 xf86OutputSetEDID(output, ddc_mon);
587 ddc_modes = xf86OutputGetEDIDModes (output);
593 nv_output_destroy (xf86OutputPtr output)
595 if (output->driver_private)
596 xfree (output->driver_private);
601 nv_output_prepare(xf86OutputPtr output)
607 nv_output_commit(xf86OutputPtr output)
613 static const xf86OutputFuncsRec nv_analog_output_funcs = {
614 .dpms = nv_analog_output_dpms,
615 .save = nv_output_save,
616 .restore = nv_output_restore,
617 .mode_valid = nv_output_mode_valid,
618 .mode_fixup = nv_output_mode_fixup,
619 .mode_set = nv_output_mode_set,
620 .detect = nv_analog_output_detect,
621 .get_modes = nv_output_get_modes,
622 .destroy = nv_output_destroy,
623 .prepare = nv_output_prepare,
624 .commit = nv_output_commit,
627 static const xf86OutputFuncsRec nv_digital_output_funcs = {
628 .dpms = nv_digital_output_dpms,
629 .save = nv_output_save,
630 .restore = nv_output_restore,
631 .mode_valid = nv_output_mode_valid,
632 .mode_fixup = nv_output_mode_fixup,
633 .mode_set = nv_output_mode_set,
634 .detect = nv_digital_output_detect,
635 .get_modes = nv_output_get_modes,
636 .destroy = nv_output_destroy,
637 .prepare = nv_output_prepare,
638 .commit = nv_output_commit,
641 static xf86OutputStatus
642 nv_output_lvds_detect(xf86OutputPtr output)
644 return XF86OutputStatusUnknown;
647 static DisplayModePtr
648 nv_output_lvds_get_modes(xf86OutputPtr output)
650 ScrnInfoPtr pScrn = output->scrn;
651 NVOutputPrivatePtr nv_output = output->driver_private;
653 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
654 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
655 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
656 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
657 // nv_output->fpWidth, nv_output->fpHeight);
663 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
664 .dpms = nv_panel_output_dpms,
665 .save = nv_output_save,
666 .restore = nv_output_restore,
667 .mode_valid = nv_output_mode_valid,
668 .mode_fixup = nv_output_mode_fixup,
669 .mode_set = nv_output_mode_set,
670 .detect = nv_output_lvds_detect,
671 .get_modes = nv_output_lvds_get_modes,
672 .destroy = nv_output_destroy,
673 .prepare = nv_output_prepare,
674 .commit = nv_output_commit,
678 static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
680 NVPtr pNv = NVPTR(pScrn);
681 xf86OutputPtr output;
682 NVOutputPrivatePtr nv_output;
684 int crtc_mask = (1<<0) | (1<<1);
686 sprintf(outputname, "Analog-%d", pNv->analog_count);
687 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
690 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
693 xf86OutputDestroy (output);
697 output->driver_private = nv_output;
698 nv_output->type = OUTPUT_ANALOG;
700 nv_output->ramdac = pNv->analog_count;
702 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
704 output->possible_crtcs = crtc_mask;
705 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
711 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index)
713 NVPtr pNv = NVPTR(pScrn);
714 xf86OutputPtr output;
715 NVOutputPrivatePtr nv_output;
717 int crtc_mask = (1<<0) | (1<<1);
719 sprintf(outputname, "Digital-%d", pNv->digital_count);
720 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
723 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
726 xf86OutputDestroy (output);
730 output->driver_private = nv_output;
731 nv_output->type = OUTPUT_DIGITAL;
733 nv_output->ramdac = pNv->digital_count;
735 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
737 output->possible_crtcs = crtc_mask;
738 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
740 pNv->digital_count++;
743 * Set up the outputs according to what type of chip we are.
745 * Some outputs may not initialize, due to allocation failure or because a
746 * controller chip isn't found.
749 void Nv20SetupOutputs(ScrnInfoPtr pScrn)
751 NVPtr pNv = NVPTR(pScrn);
752 xf86OutputPtr output;
753 NVOutputPrivatePtr nv_output;
755 int num_analog_outputs = pNv->twoHeads ? 2 : 1;
756 int num_digital_outputs = 1;
758 for (i = 0 ; i < num_analog_outputs; i++) {
759 nv_add_analog_output(pScrn, i);
762 for (i = 0 ; i < num_digital_outputs; i++) {
763 nv_add_digital_output(pScrn, i);
767 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
769 unsigned char type, port, or;
770 NVPtr pNv = NVPTR(pScrn);
773 /* we setup the outputs up from the BIOS table */
774 if (pNv->dcb_entries) {
775 for (i = 0 ; i < pNv->dcb_entries; i++) {
776 type = pNv->dcb_table[i] & 0xf;
777 port = (pNv->dcb_table[i] >> 4) & 0xf;
778 or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1;
781 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or);
782 if (type < 4 && port != 0xf) {
785 nv_add_analog_output(pScrn, port);
788 nv_add_digital_output(pScrn, port);
795 Nv20SetupOutputs(pScrn);
799 struct nv_i2c_struct {
809 void NvSetupOutputs(ScrnInfoPtr pScrn)
812 NVPtr pNv = NVPTR(pScrn);
813 xf86OutputPtr output;
814 NVOutputPrivatePtr nv_output;
816 int num_outputs = pNv->twoHeads ? 2 : 1;
818 pNv->Television = FALSE;
820 /* add the 3 I2C buses */
821 for (i = 0; i < NV_I2C_BUSES; i++) {
822 NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name);
825 NvDCBSetupOutputs(pScrn);
829 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
833 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
835 xf86OutputDestroy(output);
839 output->driver_private = nv_output;
840 nv_output->type = output_type;
842 output->possible_crtcs = i ? 1 : crtc_mask;
848 /*************************************************************************** \
850 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
852 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
853 |* international laws. Users and possessors of this source code are *|
854 |* hereby granted a nonexclusive, royalty-free copyright license to *|
855 |* use this code in individual and commercial software. *|
857 |* Any use of this source code must include, in the user documenta- *|
858 |* tion and internal comments to the code, notices to the end user *|
861 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
863 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
864 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
865 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
866 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
867 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
868 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
869 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
870 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
871 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
872 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
873 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
875 |* U.S. Government End Users. This source code is a "commercial *|
876 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
877 |* consisting of "commercial computer software" and "commercial *|
878 |* computer software documentation," as such terms are used in *|
879 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
880 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
881 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
882 |* all U.S. Government End Users acquire the source code with only *|
883 |* those rights set forth herein. *|
885 \***************************************************************************/