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_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
142 DisplayModePtr adjusted_mode);
144 static DisplayModePtr last_mode;
147 nv_digital_output_dpms(xf86OutputPtr output, int mode)
149 NVOutputPrivatePtr nv_output = output->driver_private;
150 xf86CrtcPtr crtc = output->crtc;
151 ScrnInfoPtr pScrn = output->scrn;
152 NVPtr pNv = NVPTR(pScrn);
153 NVCrtcPrivatePtr nv_crtc;
158 nv_crtc = crtc->driver_private;
160 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL) & 0xCfffffCC;
162 case DPMSModeStandby:
163 case DPMSModeSuspend:
165 /* cut the TMDS output */
166 fpcontrol |= 0x20000022;
167 nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL, fpcontrol);
170 /* restore previous mode */
171 nv_output_mode_set(output, last_mode, NULL);
177 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
179 NVOutputPrivatePtr nv_output = output->driver_private;
180 ScrnInfoPtr pScrn = output->scrn;
181 NVPtr pNv = NVPTR(pScrn);
184 regp = &state->dac_reg[nv_output->ramdac];
185 regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
186 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
187 regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
188 state->config = nvReadFB(pNv, NV_PFB_CFG0);
190 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
192 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
193 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
194 } else if(pNv->twoHeads) {
195 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
197 // regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC);
198 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
200 if (nv_output->type == OUTPUT_DIGITAL) {
203 for (i = 0; i < 7; i++) {
204 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
206 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
209 for (i = 0; i < 7; i++) {
210 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
212 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
218 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
220 NVOutputPrivatePtr nv_output = output->driver_private;
221 ScrnInfoPtr pScrn = output->scrn;
222 NVPtr pNv = NVPTR(pScrn);
225 regp = &state->dac_reg[nv_output->ramdac];
227 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
228 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
229 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
230 // NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync);
233 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
234 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
235 } else if(pNv->twoHeads) {
236 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
239 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
240 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
242 if (nv_output->type == OUTPUT_DIGITAL) {
245 for (i = 0; i < 7; i++) {
246 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
247 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
250 for (i = 0; i < 7; i++) {
251 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
253 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
261 nv_output_save (xf86OutputPtr output)
263 ScrnInfoPtr pScrn = output->scrn;
264 NVPtr pNv = NVPTR(pScrn);
265 RIVA_HW_STATE *state;
267 state = &pNv->SavedReg;
269 nv_output_save_state_ext(output, state);
274 nv_output_restore (xf86OutputPtr output)
276 ScrnInfoPtr pScrn = output->scrn;
277 NVPtr pNv = NVPTR(pScrn);
278 RIVA_HW_STATE *state;
280 state = &pNv->SavedReg;
282 nv_output_load_state_ext(output, state);
286 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
288 if (pMode->Flags & V_DBLSCAN)
289 return MODE_NO_DBLESCAN;
291 if (pMode->Clock > 400000 || pMode->Clock < 25000)
292 return MODE_CLOCK_RANGE;
299 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
300 DisplayModePtr adjusted_mode)
306 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
308 NVOutputPrivatePtr nv_output = output->driver_private;
309 ScrnInfoPtr pScrn = output->scrn;
310 NVPtr pNv = NVPTR(pScrn);
314 regp = &state->dac_reg[nv_output->ramdac];
315 if (pNv->usePanelTweak) {
316 tweak = pNv->PanelTweak;
318 /* begin flat panel hacks */
319 /* This is unfortunate, but some chips need this register
320 tweaked or else you get artifacts where adjacent pixels are
321 swapped. There are no hard rules for what to set here so all
322 we can do is experiment and apply hacks. */
324 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
325 /* At least one NV34 laptop needs this workaround. */
329 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
332 /* end flat panel hacks */
338 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
340 NVOutputPrivatePtr nv_output = output->driver_private;
341 ScrnInfoPtr pScrn = output->scrn;
343 NVPtr pNv = NVPTR(pScrn);
344 NVFBLayout *pLayout = &pNv->CurrentLayout;
346 RIVA_HW_STATE *state, *sv_state;
348 NVOutputRegPtr regp, savep;
349 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
352 state = &pNv->ModeReg;
353 regp = &state->dac_reg[nv_output->ramdac];
355 sv_state = &pNv->SavedReg;
356 savep = &sv_state->dac_reg[nv_output->ramdac];
358 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL))
362 for (i = 0; i < 7; i++) {
363 regp->fp_horiz_regs[i] = savep->fp_horiz_regs[i];
364 regp->fp_vert_regs[i] = savep->fp_vert_regs[i];
367 regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
368 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
369 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
370 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
371 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
372 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
373 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
375 regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
376 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
377 regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
378 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
379 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
380 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
381 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
385 if (pNv->Architecture >= NV_ARCH_10)
386 regp->nv10_cursync = savep->nv10_cursync | (1<<25);
388 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
390 regp->debug_0 = savep->debug_0;
391 regp->fp_control = savep->fp_control & 0xfff000ff;
393 if(!pNv->fpScaler || (nv_output->fpWidth <= mode->HDisplay)
394 || (nv_output->fpHeight <= mode->VDisplay))
396 regp->fp_control |= (1 << 8) ;
398 regp->crtcSync = savep->crtcSync;
399 regp->crtcSync += nv_output_tweak_panel(output, state);
401 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
404 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
406 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
409 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
410 regp->dither = savep->dither & ~0x00010000;
412 regp->dither |= 0x00010000;
414 ErrorF("savep->dither %08X\n", savep->dither);
415 regp->dither = savep->dither & ~1;
421 if(pLayout->depth < 24)
422 bpp = pLayout->depth;
425 regp->general = bpp == 16 ? 0x00101100 : 0x00100100;
427 if (pNv->alphaCursor)
428 regp->general |= (1<<29);
430 if(bpp != 8) /* DirectColor */
431 regp->general |= 0x00000030;
434 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
438 for (i = 0; i < config->num_output; i++) {
439 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
441 /* is it this output ?? */
442 if (config->output[i] == output)
445 /* it the output connected */
446 if (config->output[i]->crtc == NULL)
450 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG))
457 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
459 if (nv_crtc->crtc == 1 && two_mon)
460 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2;
462 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);
467 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
468 DisplayModePtr adjusted_mode)
470 ScrnInfoPtr pScrn = output->scrn;
471 NVPtr pNv = NVPTR(pScrn);
472 RIVA_HW_STATE *state;
474 state = &pNv->ModeReg;
476 nv_output_mode_set_regs(output, mode);
477 nv_output_load_state_ext(output, state);
481 nv_ddc_detect(xf86OutputPtr output)
483 /* no use for shared DDC output */
484 NVOutputPrivatePtr nv_output = output->driver_private;
487 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
491 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
494 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL))
501 nv_crt_load_detect(xf86OutputPtr output)
503 ScrnInfoPtr pScrn = output->scrn;
504 CARD32 reg_output, reg_test_ctrl, temp;
507 reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
508 reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
510 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
512 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
515 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
516 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
518 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
519 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
520 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
524 present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
526 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
527 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
529 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
530 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
532 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
539 static xf86OutputStatus
540 nv_digital_output_detect(xf86OutputPtr output)
542 NVOutputPrivatePtr nv_output = output->driver_private;
544 if (nv_ddc_detect(output))
545 return XF86OutputStatusConnected;
547 return XF86OutputStatusDisconnected;
551 static xf86OutputStatus
552 nv_analog_output_detect(xf86OutputPtr output)
554 NVOutputPrivatePtr nv_output = output->driver_private;
556 if (nv_ddc_detect(output))
557 return XF86OutputStatusConnected;
559 /* seems a bit flaky on ramdac 1 */
560 if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
561 return XF86OutputStatusConnected;
563 return XF86OutputStatusDisconnected;
566 static DisplayModePtr
567 nv_output_get_modes(xf86OutputPtr output)
569 ScrnInfoPtr pScrn = output->scrn;
570 NVOutputPrivatePtr nv_output = output->driver_private;
572 DisplayModePtr ddc_modes, mode;
576 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
578 if (ddc_mon == NULL) {
579 xf86OutputSetEDID(output, ddc_mon);
583 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
584 xf86OutputSetEDID(output, NULL);
588 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
589 xf86OutputSetEDID(output, NULL);
593 xf86OutputSetEDID(output, ddc_mon);
595 ddc_modes = xf86OutputGetEDIDModes (output);
601 nv_output_destroy (xf86OutputPtr output)
603 if (output->driver_private)
604 xfree (output->driver_private);
609 nv_output_prepare(xf86OutputPtr output)
615 nv_output_commit(xf86OutputPtr output)
621 static const xf86OutputFuncsRec nv_analog_output_funcs = {
622 .dpms = nv_analog_output_dpms,
623 .save = nv_output_save,
624 .restore = nv_output_restore,
625 .mode_valid = nv_output_mode_valid,
626 .mode_fixup = nv_output_mode_fixup,
627 .mode_set = nv_output_mode_set,
628 .detect = nv_analog_output_detect,
629 .get_modes = nv_output_get_modes,
630 .destroy = nv_output_destroy,
631 .prepare = nv_output_prepare,
632 .commit = nv_output_commit,
635 static const xf86OutputFuncsRec nv_digital_output_funcs = {
636 .dpms = nv_digital_output_dpms,
637 .save = nv_output_save,
638 .restore = nv_output_restore,
639 .mode_valid = nv_output_mode_valid,
640 .mode_fixup = nv_output_mode_fixup,
641 .mode_set = nv_output_mode_set,
642 .detect = nv_digital_output_detect,
643 .get_modes = nv_output_get_modes,
644 .destroy = nv_output_destroy,
645 .prepare = nv_output_prepare,
646 .commit = nv_output_commit,
649 static xf86OutputStatus
650 nv_output_lvds_detect(xf86OutputPtr output)
652 return XF86OutputStatusUnknown;
655 static DisplayModePtr
656 nv_output_lvds_get_modes(xf86OutputPtr output)
658 ScrnInfoPtr pScrn = output->scrn;
659 NVOutputPrivatePtr nv_output = output->driver_private;
661 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
662 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
663 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
664 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
665 // nv_output->fpWidth, nv_output->fpHeight);
671 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
672 .dpms = nv_panel_output_dpms,
673 .save = nv_output_save,
674 .restore = nv_output_restore,
675 .mode_valid = nv_output_mode_valid,
676 .mode_fixup = nv_output_mode_fixup,
677 .mode_set = nv_output_mode_set,
678 .detect = nv_output_lvds_detect,
679 .get_modes = nv_output_lvds_get_modes,
680 .destroy = nv_output_destroy,
681 .prepare = nv_output_prepare,
682 .commit = nv_output_commit,
686 static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
688 NVPtr pNv = NVPTR(pScrn);
689 xf86OutputPtr output;
690 NVOutputPrivatePtr nv_output;
692 int crtc_mask = (1<<0) | (1<<1);
694 sprintf(outputname, "Analog-%d", pNv->analog_count);
695 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
698 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
701 xf86OutputDestroy (output);
705 output->driver_private = nv_output;
706 nv_output->type = OUTPUT_ANALOG;
708 nv_output->ramdac = pNv->analog_count;
710 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
712 output->possible_crtcs = crtc_mask;
713 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
719 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index)
721 NVPtr pNv = NVPTR(pScrn);
722 xf86OutputPtr output;
723 NVOutputPrivatePtr nv_output;
725 int crtc_mask = (1<<0) | (1<<1);
727 sprintf(outputname, "Digital-%d", pNv->digital_count);
728 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
731 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
734 xf86OutputDestroy (output);
738 output->driver_private = nv_output;
739 nv_output->type = OUTPUT_DIGITAL;
741 nv_output->ramdac = pNv->digital_count;
743 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
745 output->possible_crtcs = crtc_mask;
746 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
748 pNv->digital_count++;
751 * Set up the outputs according to what type of chip we are.
753 * Some outputs may not initialize, due to allocation failure or because a
754 * controller chip isn't found.
757 void Nv20SetupOutputs(ScrnInfoPtr pScrn)
759 NVPtr pNv = NVPTR(pScrn);
760 xf86OutputPtr output;
761 NVOutputPrivatePtr nv_output;
763 int num_analog_outputs = pNv->twoHeads ? 2 : 1;
764 int num_digital_outputs = 1;
766 for (i = 0 ; i < num_analog_outputs; i++) {
767 nv_add_analog_output(pScrn, i);
770 for (i = 0 ; i < num_digital_outputs; i++) {
771 nv_add_digital_output(pScrn, i);
775 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
777 unsigned char type, port, or;
778 NVPtr pNv = NVPTR(pScrn);
781 /* we setup the outputs up from the BIOS table */
782 if (pNv->dcb_entries) {
783 for (i = 0 ; i < pNv->dcb_entries; i++) {
784 type = pNv->dcb_table[i] & 0xf;
785 port = (pNv->dcb_table[i] >> 4) & 0xf;
786 or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1;
789 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or);
790 if (type < 4 && port != 0xf) {
793 nv_add_analog_output(pScrn, port);
796 nv_add_digital_output(pScrn, port);
803 Nv20SetupOutputs(pScrn);
807 struct nv_i2c_struct {
817 void NvSetupOutputs(ScrnInfoPtr pScrn)
820 NVPtr pNv = NVPTR(pScrn);
821 xf86OutputPtr output;
822 NVOutputPrivatePtr nv_output;
824 int num_outputs = pNv->twoHeads ? 2 : 1;
826 pNv->Television = FALSE;
828 /* add the 3 I2C buses */
829 for (i = 0; i < NV_I2C_BUSES; i++) {
830 NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name);
833 NvDCBSetupOutputs(pScrn);
837 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
841 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
843 xf86OutputDestroy(output);
847 output->driver_private = nv_output;
848 nv_output->type = output_type;
850 output->possible_crtcs = i ? 1 : crtc_mask;
856 /*************************************************************************** \
858 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
860 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
861 |* international laws. Users and possessors of this source code are *|
862 |* hereby granted a nonexclusive, royalty-free copyright license to *|
863 |* use this code in individual and commercial software. *|
865 |* Any use of this source code must include, in the user documenta- *|
866 |* tion and internal comments to the code, notices to the end user *|
869 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
871 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
872 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
873 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
874 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
875 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
876 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
877 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
878 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
879 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
880 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
881 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
883 |* U.S. Government End Users. This source code is a "commercial *|
884 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
885 |* consisting of "commercial computer software" and "commercial *|
886 |* computer software documentation," as such terms are used in *|
887 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
888 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
889 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
890 |* all U.S. Government End Users acquire the source code with only *|
891 |* those rights set forth herein. *|
893 \***************************************************************************/