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 xf86CrtcPtr crtc = output->crtc;
146 NVPtr pNv = NVPTR(output->scrn);
147 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
149 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL);
151 case DPMSModeStandby:
152 case DPMSModeSuspend:
154 /* cut the TMDS output */
155 fpcontrol |= 0x20000022;
158 /* disable cutting the TMDS output */
159 fpcontrol &= ~0x20000022;
162 nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL, fpcontrol);
166 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
168 NVOutputPrivatePtr nv_output = output->driver_private;
169 ScrnInfoPtr pScrn = output->scrn;
170 NVPtr pNv = NVPTR(pScrn);
173 regp = &state->dac_reg[nv_output->ramdac];
174 regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
175 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
176 regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
177 state->config = nvReadFB(pNv, NV_PFB_CFG0);
179 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
181 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
182 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
183 } else if(pNv->twoHeads) {
184 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
186 // regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC);
187 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
189 if (nv_output->type == OUTPUT_DIGITAL) {
192 for (i = 0; i < 7; i++) {
193 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
195 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
198 for (i = 0; i < 7; i++) {
199 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
201 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
207 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
209 NVOutputPrivatePtr nv_output = output->driver_private;
210 ScrnInfoPtr pScrn = output->scrn;
211 NVPtr pNv = NVPTR(pScrn);
214 regp = &state->dac_reg[nv_output->ramdac];
216 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
217 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
218 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
219 // NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync);
222 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
223 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
224 } else if(pNv->twoHeads) {
225 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
228 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
229 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
231 if (nv_output->type == OUTPUT_DIGITAL) {
234 for (i = 0; i < 7; i++) {
235 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
236 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
239 for (i = 0; i < 7; i++) {
240 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
242 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
250 nv_output_save (xf86OutputPtr output)
252 ScrnInfoPtr pScrn = output->scrn;
253 NVPtr pNv = NVPTR(pScrn);
254 RIVA_HW_STATE *state;
256 state = &pNv->SavedReg;
258 nv_output_save_state_ext(output, state);
263 nv_output_restore (xf86OutputPtr output)
265 ScrnInfoPtr pScrn = output->scrn;
266 NVPtr pNv = NVPTR(pScrn);
267 RIVA_HW_STATE *state;
269 state = &pNv->SavedReg;
271 nv_output_load_state_ext(output, state);
275 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
277 if (pMode->Flags & V_DBLSCAN)
278 return MODE_NO_DBLESCAN;
280 if (pMode->Clock > 400000 || pMode->Clock < 25000)
281 return MODE_CLOCK_RANGE;
288 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
289 DisplayModePtr adjusted_mode)
295 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
297 NVOutputPrivatePtr nv_output = output->driver_private;
298 ScrnInfoPtr pScrn = output->scrn;
299 NVPtr pNv = NVPTR(pScrn);
303 regp = &state->dac_reg[nv_output->ramdac];
304 if (pNv->usePanelTweak) {
305 tweak = pNv->PanelTweak;
307 /* begin flat panel hacks */
308 /* This is unfortunate, but some chips need this register
309 tweaked or else you get artifacts where adjacent pixels are
310 swapped. There are no hard rules for what to set here so all
311 we can do is experiment and apply hacks. */
313 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
314 /* At least one NV34 laptop needs this workaround. */
318 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
321 /* end flat panel hacks */
327 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
329 NVOutputPrivatePtr nv_output = output->driver_private;
330 ScrnInfoPtr pScrn = output->scrn;
332 NVPtr pNv = NVPTR(pScrn);
333 NVFBLayout *pLayout = &pNv->CurrentLayout;
334 RIVA_HW_STATE *state, *sv_state;
336 NVOutputRegPtr regp, savep;
337 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
340 state = &pNv->ModeReg;
341 regp = &state->dac_reg[nv_output->ramdac];
343 sv_state = &pNv->SavedReg;
344 savep = &sv_state->dac_reg[nv_output->ramdac];
346 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL))
350 for (i = 0; i < 7; i++) {
351 regp->fp_horiz_regs[i] = savep->fp_horiz_regs[i];
352 regp->fp_vert_regs[i] = savep->fp_vert_regs[i];
355 regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
356 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
357 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
358 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
359 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
360 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
361 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
363 regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
364 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
365 regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
366 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
367 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
368 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
369 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
373 if (pNv->Architecture >= NV_ARCH_10)
374 regp->nv10_cursync = savep->nv10_cursync | (1<<25);
376 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
378 regp->debug_0 = savep->debug_0;
379 regp->fp_control = savep->fp_control & 0xfff000ff;
381 if(!pNv->fpScaler || (nv_output->fpWidth <= mode->HDisplay)
382 || (nv_output->fpHeight <= mode->VDisplay))
384 regp->fp_control |= (1 << 8) ;
386 regp->crtcSync = savep->crtcSync;
387 regp->crtcSync += nv_output_tweak_panel(output, state);
389 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
392 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
394 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
397 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
398 regp->dither = savep->dither & ~0x00010000;
400 regp->dither |= 0x00010000;
402 ErrorF("savep->dither %08X\n", savep->dither);
403 regp->dither = savep->dither & ~1;
409 if(pLayout->depth < 24)
410 bpp = pLayout->depth;
413 regp->general = bpp == 16 ? 0x00101100 : 0x00100100;
415 if (pNv->alphaCursor)
416 regp->general |= (1<<29);
418 if(bpp != 8) /* DirectColor */
419 regp->general |= 0x00000030;
422 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
426 for (i = 0; i < config->num_output; i++) {
427 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
429 /* is it this output ?? */
430 if (config->output[i] == output)
433 /* it the output connected */
434 if (config->output[i]->crtc == NULL)
438 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG))
445 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
447 if (nv_crtc->crtc == 1 && two_mon)
448 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2;
450 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);
455 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
456 DisplayModePtr adjusted_mode)
458 ScrnInfoPtr pScrn = output->scrn;
459 NVPtr pNv = NVPTR(pScrn);
460 RIVA_HW_STATE *state;
462 state = &pNv->ModeReg;
464 nv_output_mode_set_regs(output, mode);
465 nv_output_load_state_ext(output, state);
469 nv_ddc_detect(xf86OutputPtr output)
471 /* no use for shared DDC output */
472 NVOutputPrivatePtr nv_output = output->driver_private;
475 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
479 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
482 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL))
489 nv_crt_load_detect(xf86OutputPtr output)
491 ScrnInfoPtr pScrn = output->scrn;
492 CARD32 reg_output, reg_test_ctrl, temp;
495 reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
496 reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
498 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
500 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
503 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
504 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
506 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
507 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
508 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
512 present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
514 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
515 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
517 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
518 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
520 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
527 static xf86OutputStatus
528 nv_digital_output_detect(xf86OutputPtr output)
530 NVOutputPrivatePtr nv_output = output->driver_private;
532 if (nv_ddc_detect(output))
533 return XF86OutputStatusConnected;
535 return XF86OutputStatusDisconnected;
539 static xf86OutputStatus
540 nv_analog_output_detect(xf86OutputPtr output)
542 NVOutputPrivatePtr nv_output = output->driver_private;
544 if (nv_ddc_detect(output))
545 return XF86OutputStatusConnected;
547 /* seems a bit flaky on ramdac 1 */
548 if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
549 return XF86OutputStatusConnected;
551 return XF86OutputStatusDisconnected;
554 static DisplayModePtr
555 nv_output_get_modes(xf86OutputPtr output)
557 ScrnInfoPtr pScrn = output->scrn;
558 NVOutputPrivatePtr nv_output = output->driver_private;
560 DisplayModePtr ddc_modes, mode;
564 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
566 if (ddc_mon == NULL) {
567 xf86OutputSetEDID(output, ddc_mon);
571 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
572 xf86OutputSetEDID(output, NULL);
576 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
577 xf86OutputSetEDID(output, NULL);
581 xf86OutputSetEDID(output, ddc_mon);
583 ddc_modes = xf86OutputGetEDIDModes (output);
589 nv_output_destroy (xf86OutputPtr output)
591 if (output->driver_private)
592 xfree (output->driver_private);
597 nv_output_prepare(xf86OutputPtr output)
603 nv_output_commit(xf86OutputPtr output)
609 static const xf86OutputFuncsRec nv_analog_output_funcs = {
610 .dpms = nv_analog_output_dpms,
611 .save = nv_output_save,
612 .restore = nv_output_restore,
613 .mode_valid = nv_output_mode_valid,
614 .mode_fixup = nv_output_mode_fixup,
615 .mode_set = nv_output_mode_set,
616 .detect = nv_analog_output_detect,
617 .get_modes = nv_output_get_modes,
618 .destroy = nv_output_destroy,
619 .prepare = nv_output_prepare,
620 .commit = nv_output_commit,
623 static const xf86OutputFuncsRec nv_digital_output_funcs = {
624 .dpms = nv_digital_output_dpms,
625 .save = nv_output_save,
626 .restore = nv_output_restore,
627 .mode_valid = nv_output_mode_valid,
628 .mode_fixup = nv_output_mode_fixup,
629 .mode_set = nv_output_mode_set,
630 .detect = nv_digital_output_detect,
631 .get_modes = nv_output_get_modes,
632 .destroy = nv_output_destroy,
633 .prepare = nv_output_prepare,
634 .commit = nv_output_commit,
637 static xf86OutputStatus
638 nv_output_lvds_detect(xf86OutputPtr output)
640 return XF86OutputStatusUnknown;
643 static DisplayModePtr
644 nv_output_lvds_get_modes(xf86OutputPtr output)
646 ScrnInfoPtr pScrn = output->scrn;
647 NVOutputPrivatePtr nv_output = output->driver_private;
649 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
650 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
651 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
652 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
653 // nv_output->fpWidth, nv_output->fpHeight);
659 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
660 .dpms = nv_panel_output_dpms,
661 .save = nv_output_save,
662 .restore = nv_output_restore,
663 .mode_valid = nv_output_mode_valid,
664 .mode_fixup = nv_output_mode_fixup,
665 .mode_set = nv_output_mode_set,
666 .detect = nv_output_lvds_detect,
667 .get_modes = nv_output_lvds_get_modes,
668 .destroy = nv_output_destroy,
669 .prepare = nv_output_prepare,
670 .commit = nv_output_commit,
674 static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
676 NVPtr pNv = NVPTR(pScrn);
677 xf86OutputPtr output;
678 NVOutputPrivatePtr nv_output;
680 int crtc_mask = (1<<0) | (1<<1);
682 sprintf(outputname, "Analog-%d", pNv->analog_count);
683 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
686 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
689 xf86OutputDestroy (output);
693 output->driver_private = nv_output;
694 nv_output->type = OUTPUT_ANALOG;
696 nv_output->ramdac = pNv->analog_count;
698 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
700 output->possible_crtcs = crtc_mask;
701 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
707 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index, int lvds)
709 NVPtr pNv = NVPTR(pScrn);
710 xf86OutputPtr output;
711 NVOutputPrivatePtr nv_output;
713 int crtc_mask = (1<<0) | (1<<1);
715 sprintf(outputname, "Digital-%d", pNv->digital_count);
717 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
719 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
722 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
725 xf86OutputDestroy (output);
729 output->driver_private = nv_output;
730 nv_output->type = OUTPUT_DIGITAL;
732 nv_output->ramdac = pNv->digital_count;
734 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
736 output->possible_crtcs = crtc_mask;
737 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
739 pNv->digital_count++;
742 * Set up the outputs according to what type of chip we are.
744 * Some outputs may not initialize, due to allocation failure or because a
745 * controller chip isn't found.
748 void Nv20SetupOutputs(ScrnInfoPtr pScrn)
750 NVPtr pNv = NVPTR(pScrn);
751 xf86OutputPtr output;
752 NVOutputPrivatePtr nv_output;
754 int num_analog_outputs = pNv->twoHeads ? 2 : 1;
755 int num_digital_outputs = 1;
757 for (i = 0 ; i < num_analog_outputs; i++) {
758 nv_add_analog_output(pScrn, i);
761 for (i = 0 ; i < num_digital_outputs; i++) {
762 nv_add_digital_output(pScrn, i, 0);
766 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
768 unsigned char type, port, or;
769 NVPtr pNv = NVPTR(pScrn);
772 /* we setup the outputs up from the BIOS table */
773 if (pNv->dcb_entries) {
774 for (i = 0 ; i < pNv->dcb_entries; i++) {
775 type = pNv->dcb_table[i] & 0xf;
776 port = (pNv->dcb_table[i] >> 4) & 0xf;
777 or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1;
780 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or);
781 if (type < 4 && port != 0xf) {
784 nv_add_analog_output(pScrn, port);
787 nv_add_digital_output(pScrn, port, 0);
790 nv_add_digital_output(pScrn, port, 1);
798 Nv20SetupOutputs(pScrn);
802 struct nv_i2c_struct {
812 void NvSetupOutputs(ScrnInfoPtr pScrn)
815 NVPtr pNv = NVPTR(pScrn);
816 xf86OutputPtr output;
817 NVOutputPrivatePtr nv_output;
819 int num_outputs = pNv->twoHeads ? 2 : 1;
821 pNv->Television = FALSE;
823 /* add the 3 I2C buses */
824 for (i = 0; i < NV_I2C_BUSES; i++) {
825 NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name);
828 NvDCBSetupOutputs(pScrn);
832 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
836 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
838 xf86OutputDestroy(output);
842 output->driver_private = nv_output;
843 nv_output->type = output_type;
845 output->possible_crtcs = i ? 1 : crtc_mask;
851 /*************************************************************************** \
853 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
855 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
856 |* international laws. Users and possessors of this source code are *|
857 |* hereby granted a nonexclusive, royalty-free copyright license to *|
858 |* use this code in individual and commercial software. *|
860 |* Any use of this source code must include, in the user documenta- *|
861 |* tion and internal comments to the code, notices to the end user *|
864 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
866 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
867 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
868 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
869 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
870 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
871 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
872 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
873 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
874 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
875 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
876 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
878 |* U.S. Government End Users. This source code is a "commercial *|
879 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
880 |* consisting of "commercial computer software" and "commercial *|
881 |* computer software documentation," as such terms are used in *|
882 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
883 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
884 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
885 |* all U.S. Government End Users acquire the source code with only *|
886 |* those rights set forth herein. *|
888 \***************************************************************************/