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 regp->debug_1 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
178 regp->debug_2 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
179 state->config = nvReadFB(pNv, NV_PFB_CFG0);
181 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
183 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
184 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
185 } else if(pNv->twoHeads) {
186 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
188 // regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC);
189 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
191 if (nv_output->type == OUTPUT_DIGITAL) {
194 for (i = 0; i < 7; i++) {
195 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
197 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
200 for (i = 0; i < 7; i++) {
201 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
203 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
206 regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
207 regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
208 regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
209 regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
214 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
216 NVOutputPrivatePtr nv_output = output->driver_private;
217 ScrnInfoPtr pScrn = output->scrn;
218 NVPtr pNv = NVPTR(pScrn);
221 regp = &state->dac_reg[nv_output->ramdac];
223 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
224 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
225 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
226 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
227 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
228 // NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync);
231 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
232 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
233 } else if(pNv->twoHeads) {
234 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
237 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
238 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
240 if (nv_output->type == OUTPUT_DIGITAL) {
243 for (i = 0; i < 7; i++) {
244 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
245 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
248 for (i = 0; i < 7; i++) {
249 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
251 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
254 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
255 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
256 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
257 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
264 nv_output_save (xf86OutputPtr output)
266 ScrnInfoPtr pScrn = output->scrn;
267 NVPtr pNv = NVPTR(pScrn);
268 RIVA_HW_STATE *state;
270 state = &pNv->SavedReg;
272 nv_output_save_state_ext(output, state);
277 nv_output_restore (xf86OutputPtr output)
279 ScrnInfoPtr pScrn = output->scrn;
280 NVPtr pNv = NVPTR(pScrn);
281 RIVA_HW_STATE *state;
283 state = &pNv->SavedReg;
285 nv_output_load_state_ext(output, state);
289 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
291 if (pMode->Flags & V_DBLSCAN)
292 return MODE_NO_DBLESCAN;
294 if (pMode->Clock > 400000 || pMode->Clock < 25000)
295 return MODE_CLOCK_RANGE;
302 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
303 DisplayModePtr adjusted_mode)
309 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
311 NVOutputPrivatePtr nv_output = output->driver_private;
312 ScrnInfoPtr pScrn = output->scrn;
313 NVPtr pNv = NVPTR(pScrn);
317 regp = &state->dac_reg[nv_output->ramdac];
318 if (pNv->usePanelTweak) {
319 tweak = pNv->PanelTweak;
321 /* begin flat panel hacks */
322 /* This is unfortunate, but some chips need this register
323 tweaked or else you get artifacts where adjacent pixels are
324 swapped. There are no hard rules for what to set here so all
325 we can do is experiment and apply hacks. */
327 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
328 /* At least one NV34 laptop needs this workaround. */
332 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
335 /* end flat panel hacks */
341 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
343 NVOutputPrivatePtr nv_output = output->driver_private;
344 ScrnInfoPtr pScrn = output->scrn;
346 NVPtr pNv = NVPTR(pScrn);
347 NVFBLayout *pLayout = &pNv->CurrentLayout;
348 RIVA_HW_STATE *state, *sv_state;
350 NVOutputRegPtr regp, savep;
351 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
352 float aspect_ratio, panel_ratio;
353 uint32_t h_scale, v_scale;
356 state = &pNv->ModeReg;
357 regp = &state->dac_reg[nv_output->ramdac];
359 sv_state = &pNv->SavedReg;
360 savep = &sv_state->dac_reg[nv_output->ramdac];
362 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
365 for (i = 0; i < 7; i++) {
366 regp->fp_horiz_regs[i] = savep->fp_horiz_regs[i];
367 regp->fp_vert_regs[i] = savep->fp_vert_regs[i];
370 regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
371 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
372 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
373 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
374 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
375 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
376 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
378 regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
379 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
380 regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
381 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
382 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
383 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
384 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
388 ErrorF("Pre-panel scaling\n");
389 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
390 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
391 ErrorF("panel_ratio=%f\n", panel_ratio);
392 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
393 ErrorF("aspect_ratio=%f\n", aspect_ratio);
394 /* Scale factors is the so called 20.12 format, taken from Haiku */
395 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
396 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
397 ErrorF("h_scale=%d\n", h_scale);
398 ErrorF("v_scale=%d\n", v_scale);
400 /* Enable full width and height on the flat panel */
401 regp->fp_hvalid_start = 0;
402 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
404 regp->fp_vvalid_start = 0;
405 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
407 /* When doing vertical scaling, limit the last fetched line */
408 if (v_scale != (1 << 12)) {
409 regp->debug_2 = (1 << 28) | ((mode->VDisplay - 1) << 16);
414 /* Tell the panel not to scale */
415 regp->fp_control = savep->fp_control & 0xfffffeff;
417 /* GPU scaling happens automaticly at a ratio of 1:33 */
418 /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
419 if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
422 ErrorF("Scaling resolution on a widescreen panel\n");
424 /* Scaling in both directions needs to the same */
426 diff = nv_output->fpWidth - ((1 << 12) * mode->HDisplay)/h_scale;
427 regp->fp_hvalid_start = diff/2;
428 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
431 /* Same scaling, just for panels with aspect ratio's smaller than 1 */
432 if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
435 ErrorF("Scaling resolution on a portrait panel\n");
437 /* Scaling in both directions needs to the same */
439 diff = nv_output->fpHeight - ((1 << 12) * mode->VDisplay)/v_scale;
440 regp->fp_vvalid_start = diff/2;
441 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
444 ErrorF("Post-panel scaling\n");
446 /* copy a bunch of things from the current state for non-dfp's */
447 regp->fp_control = savep->fp_control & 0xfff000ff;
448 regp->debug_2 = savep->debug_2;
451 if (pNv->Architecture >= NV_ARCH_10) {
452 regp->nv10_cursync = savep->nv10_cursync | (1<<25);
455 regp->debug_0 = savep->debug_0;
456 regp->debug_1 = savep->debug_1;
458 regp->crtcSync = savep->crtcSync;
459 //regp->crtcSync += nv_output_tweak_panel(output, state);
461 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
463 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
466 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
469 if(pNv->NVArch == 0x11) {
470 regp->dither = savep->dither & ~0x00010000;
472 regp->dither |= 0x00010000;
475 ErrorF("savep->dither %08X\n", savep->dither);
476 regp->dither = savep->dither & ~1;
483 if(pLayout->depth < 24) {
484 bpp = pLayout->depth;
489 regp->general = bpp == 16 ? 0x00101100 : 0x00100100;
491 if (pNv->alphaCursor) {
492 regp->general |= (1<<29);
495 if(bpp != 8) {/* DirectColor */
496 regp->general |= 0x00000030;
499 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
502 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
506 for (i = 0; i < config->num_output; i++) {
507 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
509 /* is it this output ?? */
510 if (config->output[i] == output)
513 /* it the output connected */
514 if (config->output[i]->crtc == NULL)
518 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
526 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
529 if (nv_crtc->crtc == 1 && two_mon) {
530 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2;
533 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);
538 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
539 DisplayModePtr adjusted_mode)
541 ScrnInfoPtr pScrn = output->scrn;
542 NVPtr pNv = NVPTR(pScrn);
543 RIVA_HW_STATE *state;
545 state = &pNv->ModeReg;
547 nv_output_mode_set_regs(output, mode);
548 nv_output_load_state_ext(output, state);
552 nv_ddc_detect(xf86OutputPtr output)
554 /* no use for shared DDC output */
555 NVOutputPrivatePtr nv_output = output->driver_private;
558 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
562 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
565 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
569 xf86PrintEDID(ddc_mon);
571 if (nv_output->type == OUTPUT_DIGITAL) {
573 for (i = 0; i < 8; i++) {
574 if ((ddc_mon->timings2[i].hsize > nv_output->fpWidth) ||
575 (ddc_mon->timings2[i].vsize > nv_output->fpHeight)) {
577 nv_output->fpWidth = ddc_mon->timings2[i].hsize;
578 nv_output->fpHeight = ddc_mon->timings2[i].vsize;
587 nv_crt_load_detect(xf86OutputPtr output)
589 ScrnInfoPtr pScrn = output->scrn;
590 CARD32 reg_output, reg_test_ctrl, temp;
593 reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
594 reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
596 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
598 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
601 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
602 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
604 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
605 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
606 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
610 present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
612 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
613 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
615 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
616 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
618 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
625 static xf86OutputStatus
626 nv_digital_output_detect(xf86OutputPtr output)
628 NVOutputPrivatePtr nv_output = output->driver_private;
630 if (nv_ddc_detect(output))
631 return XF86OutputStatusConnected;
633 return XF86OutputStatusDisconnected;
637 static xf86OutputStatus
638 nv_analog_output_detect(xf86OutputPtr output)
640 NVOutputPrivatePtr nv_output = output->driver_private;
642 if (nv_ddc_detect(output))
643 return XF86OutputStatusConnected;
645 /* seems a bit flaky on ramdac 1 */
646 if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
647 return XF86OutputStatusConnected;
649 return XF86OutputStatusDisconnected;
652 static DisplayModePtr
653 nv_output_get_modes(xf86OutputPtr output)
655 ScrnInfoPtr pScrn = output->scrn;
656 NVOutputPrivatePtr nv_output = output->driver_private;
658 DisplayModePtr ddc_modes, mode;
662 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
664 if (ddc_mon == NULL) {
665 xf86OutputSetEDID(output, ddc_mon);
669 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
670 xf86OutputSetEDID(output, NULL);
674 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
675 xf86OutputSetEDID(output, NULL);
679 xf86OutputSetEDID(output, ddc_mon);
681 ddc_modes = xf86OutputGetEDIDModes (output);
687 nv_output_destroy (xf86OutputPtr output)
689 if (output->driver_private)
690 xfree (output->driver_private);
695 nv_output_prepare(xf86OutputPtr output)
701 nv_output_commit(xf86OutputPtr output)
707 static const xf86OutputFuncsRec nv_analog_output_funcs = {
708 .dpms = nv_analog_output_dpms,
709 .save = nv_output_save,
710 .restore = nv_output_restore,
711 .mode_valid = nv_output_mode_valid,
712 .mode_fixup = nv_output_mode_fixup,
713 .mode_set = nv_output_mode_set,
714 .detect = nv_analog_output_detect,
715 .get_modes = nv_output_get_modes,
716 .destroy = nv_output_destroy,
717 .prepare = nv_output_prepare,
718 .commit = nv_output_commit,
721 static const xf86OutputFuncsRec nv_digital_output_funcs = {
722 .dpms = nv_digital_output_dpms,
723 .save = nv_output_save,
724 .restore = nv_output_restore,
725 .mode_valid = nv_output_mode_valid,
726 .mode_fixup = nv_output_mode_fixup,
727 .mode_set = nv_output_mode_set,
728 .detect = nv_digital_output_detect,
729 .get_modes = nv_output_get_modes,
730 .destroy = nv_output_destroy,
731 .prepare = nv_output_prepare,
732 .commit = nv_output_commit,
735 static xf86OutputStatus
736 nv_output_lvds_detect(xf86OutputPtr output)
738 return XF86OutputStatusUnknown;
741 static DisplayModePtr
742 nv_output_lvds_get_modes(xf86OutputPtr output)
744 ScrnInfoPtr pScrn = output->scrn;
745 NVOutputPrivatePtr nv_output = output->driver_private;
747 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
748 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
749 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
750 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
751 // nv_output->fpWidth, nv_output->fpHeight);
757 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
758 .dpms = nv_panel_output_dpms,
759 .save = nv_output_save,
760 .restore = nv_output_restore,
761 .mode_valid = nv_output_mode_valid,
762 .mode_fixup = nv_output_mode_fixup,
763 .mode_set = nv_output_mode_set,
764 .detect = nv_output_lvds_detect,
765 .get_modes = nv_output_lvds_get_modes,
766 .destroy = nv_output_destroy,
767 .prepare = nv_output_prepare,
768 .commit = nv_output_commit,
772 static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
774 NVPtr pNv = NVPTR(pScrn);
775 xf86OutputPtr output;
776 NVOutputPrivatePtr nv_output;
778 int crtc_mask = (1<<0) | (1<<1);
780 sprintf(outputname, "Analog-%d", pNv->analog_count);
781 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
784 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
787 xf86OutputDestroy (output);
791 output->driver_private = nv_output;
792 nv_output->type = OUTPUT_ANALOG;
794 nv_output->ramdac = pNv->analog_count;
796 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
798 output->possible_crtcs = crtc_mask;
799 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
805 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index, int lvds)
807 NVPtr pNv = NVPTR(pScrn);
808 xf86OutputPtr output;
809 NVOutputPrivatePtr nv_output;
811 int crtc_mask = (1<<0) | (1<<1);
813 sprintf(outputname, "Digital-%d", pNv->digital_count);
815 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
817 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
820 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
823 xf86OutputDestroy (output);
827 output->driver_private = nv_output;
828 nv_output->type = OUTPUT_DIGITAL;
830 nv_output->ramdac = pNv->digital_count;
832 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
834 output->possible_crtcs = crtc_mask;
835 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
837 pNv->digital_count++;
840 * Set up the outputs according to what type of chip we are.
842 * Some outputs may not initialize, due to allocation failure or because a
843 * controller chip isn't found.
846 void Nv20SetupOutputs(ScrnInfoPtr pScrn)
848 NVPtr pNv = NVPTR(pScrn);
849 xf86OutputPtr output;
850 NVOutputPrivatePtr nv_output;
852 int num_analog_outputs = pNv->twoHeads ? 2 : 1;
853 int num_digital_outputs = 1;
855 for (i = 0 ; i < num_analog_outputs; i++) {
856 nv_add_analog_output(pScrn, i);
859 for (i = 0 ; i < num_digital_outputs; i++) {
860 nv_add_digital_output(pScrn, i, 0);
864 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
866 unsigned char type, port, or;
867 NVPtr pNv = NVPTR(pScrn);
870 /* we setup the outputs up from the BIOS table */
871 if (pNv->dcb_entries) {
872 for (i = 0 ; i < pNv->dcb_entries; i++) {
873 type = pNv->dcb_table[i] & 0xf;
874 port = (pNv->dcb_table[i] >> 4) & 0xf;
875 or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1;
878 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or);
879 if (type < 4 && port != 0xf) {
882 nv_add_analog_output(pScrn, port);
885 nv_add_digital_output(pScrn, port, 0);
888 nv_add_digital_output(pScrn, port, 1);
896 Nv20SetupOutputs(pScrn);
900 struct nv_i2c_struct {
909 void NvSetupOutputs(ScrnInfoPtr pScrn)
912 NVPtr pNv = NVPTR(pScrn);
913 xf86OutputPtr output;
914 NVOutputPrivatePtr nv_output;
916 int num_outputs = pNv->twoHeads ? 2 : 1;
918 pNv->Television = FALSE;
920 /* add the 3 I2C buses */
921 for (i = 0; i < NV_I2C_BUSES; i++) {
922 NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name);
925 NvDCBSetupOutputs(pScrn);
929 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
933 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
935 xf86OutputDestroy(output);
939 output->driver_private = nv_output;
940 nv_output->type = output_type;
942 output->possible_crtcs = i ? 1 : crtc_mask;
948 /*************************************************************************** \
950 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
952 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
953 |* international laws. Users and possessors of this source code are *|
954 |* hereby granted a nonexclusive, royalty-free copyright license to *|
955 |* use this code in individual and commercial software. *|
957 |* Any use of this source code must include, in the user documenta- *|
958 |* tion and internal comments to the code, notices to the end user *|
961 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
963 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
964 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
965 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
966 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
967 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
968 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
969 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
970 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
971 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
972 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
973 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
975 |* U.S. Government End Users. This source code is a "commercial *|
976 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
977 |* consisting of "commercial computer software" and "commercial *|
978 |* computer software documentation," as such terms are used in *|
979 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
980 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
981 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
982 |* all U.S. Government End Users acquire the source code with only *|
983 |* those rights set forth herein. *|
985 \***************************************************************************/