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
44 #include "mipointer.h"
45 #include "windowstr.h"
47 #include <X11/extensions/render.h>
50 #include "nv_include.h"
52 const char *OutputType[] = {
61 const char *MonTypeName[7] = {
72 * TMDS registers are indirect 8 bit registers.
73 * Reading is straightforward, writing a bit odd.
74 * Reading: Write adress (+write protect bit, do not forget this), then read value.
75 * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
78 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
80 NVOutputPrivatePtr nv_output = output->driver_private;
81 ScrnInfoPtr pScrn = output->scrn;
82 NVPtr pNv = NVPTR(pScrn);
84 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
85 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
87 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
89 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
90 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
91 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
94 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
96 NVOutputPrivatePtr nv_output = output->driver_private;
97 ScrnInfoPtr pScrn = output->scrn;
98 NVPtr pNv = NVPTR(pScrn);
100 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
101 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
103 return (nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
106 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
108 NVOutputPrivatePtr nv_output = output->driver_private;
109 ScrnInfoPtr pScrn = output->scrn;
110 NVPtr pNv = NVPTR(pScrn);
112 nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
115 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
117 NVOutputPrivatePtr nv_output = output->driver_private;
118 ScrnInfoPtr pScrn = output->scrn;
119 NVPtr pNv = NVPTR(pScrn);
121 return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
124 static void nv_output_backlight_enable(xf86OutputPtr output, Bool on)
126 ScrnInfoPtr pScrn = output->scrn;
127 NVPtr pNv = NVPTR(pScrn);
129 /* This is done differently on each laptop. Here we
130 define the ones we know for sure. */
132 #if defined(__powerpc__)
133 if((pNv->Chipset == 0x10DE0179) ||
134 (pNv->Chipset == 0x10DE0189) ||
135 (pNv->Chipset == 0x10DE0329))
137 /* NV17,18,34 Apple iMac, iBook, PowerBook */
138 CARD32 tmp_pmc, tmp_pcrt;
139 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
140 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
142 tmp_pmc |= (1 << 31);
145 nvWriteMC(pNv, 0x10F0, tmp_pmc);
146 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
150 if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
151 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
155 nv_panel_output_dpms(xf86OutputPtr output, int mode)
159 case DPMSModeStandby:
160 case DPMSModeSuspend:
162 nv_output_backlight_enable(output, 0);
165 nv_output_backlight_enable(output, 1);
172 nv_analog_output_dpms(xf86OutputPtr output, int mode)
178 nv_digital_output_dpms(xf86OutputPtr output, int mode)
180 xf86CrtcPtr crtc = output->crtc;
183 NVPtr pNv = NVPTR(output->scrn);
184 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
186 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL);
188 case DPMSModeStandby:
189 case DPMSModeSuspend:
191 /* cut the TMDS output */
192 fpcontrol |= 0x20000022;
195 /* disable cutting the TMDS output */
196 fpcontrol &= ~0x20000022;
199 nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL, fpcontrol);
203 int tmds_regs[] = { 0x2, 0x4, 0x2b };
205 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
207 NVOutputPrivatePtr nv_output = output->driver_private;
208 ScrnInfoPtr pScrn = output->scrn;
209 NVPtr pNv = NVPTR(pScrn);
213 regp = &state->dac_reg[nv_output->ramdac];
214 regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
215 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
216 regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
217 regp->debug_1 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
218 regp->debug_2 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
219 state->config = nvReadFB(pNv, NV_PFB_CFG0);
221 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
223 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
224 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
225 } else if (pNv->twoHeads) {
226 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
228 regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC);
229 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
231 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
232 regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
235 if (nv_output->type == OUTPUT_DIGITAL) {
237 for (i = 0; i < 7; i++) {
238 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
239 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
242 for (i = 0; i < 7; i++) {
243 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
244 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
247 regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
248 regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
249 regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
250 regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
254 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
256 NVOutputPrivatePtr nv_output = output->driver_private;
257 ScrnInfoPtr pScrn = output->scrn;
258 NVPtr pNv = NVPTR(pScrn);
262 regp = &state->dac_reg[nv_output->ramdac];
264 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
265 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
266 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
267 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
268 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
269 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync);
271 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
272 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
273 } else if (pNv->twoHeads) {
274 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
277 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
278 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
280 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
281 NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
284 if (nv_output->type == OUTPUT_DIGITAL) {
286 for (i = 0; i < 7; i++) {
287 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
288 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
291 for (i = 0; i < 7; i++) {
292 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
293 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
296 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
297 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
298 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
299 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
307 nv_output_save (xf86OutputPtr output)
309 ScrnInfoPtr pScrn = output->scrn;
310 NVPtr pNv = NVPTR(pScrn);
311 RIVA_HW_STATE *state;
313 state = &pNv->SavedReg;
315 nv_output_save_state_ext(output, state);
320 nv_output_restore (xf86OutputPtr output)
322 ScrnInfoPtr pScrn = output->scrn;
323 NVPtr pNv = NVPTR(pScrn);
324 RIVA_HW_STATE *state;
326 state = &pNv->SavedReg;
328 nv_output_load_state_ext(output, state);
332 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
334 if (pMode->Flags & V_DBLSCAN)
335 return MODE_NO_DBLESCAN;
337 if (pMode->Clock > 400000 || pMode->Clock < 25000)
338 return MODE_CLOCK_RANGE;
345 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
346 DisplayModePtr adjusted_mode)
352 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
354 NVOutputPrivatePtr nv_output = output->driver_private;
355 ScrnInfoPtr pScrn = output->scrn;
356 NVPtr pNv = NVPTR(pScrn);
360 regp = &state->dac_reg[nv_output->ramdac];
361 if (pNv->usePanelTweak) {
362 tweak = pNv->PanelTweak;
364 /* begin flat panel hacks */
365 /* This is unfortunate, but some chips need this register
366 tweaked or else you get artifacts where adjacent pixels are
367 swapped. There are no hard rules for what to set here so all
368 we can do is experiment and apply hacks. */
370 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
371 /* At least one NV34 laptop needs this workaround. */
375 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
378 /* end flat panel hacks */
384 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
386 NVOutputPrivatePtr nv_output = output->driver_private;
387 ScrnInfoPtr pScrn = output->scrn;
389 NVPtr pNv = NVPTR(pScrn);
390 NVFBLayout *pLayout = &pNv->CurrentLayout;
391 RIVA_HW_STATE *state, *sv_state;
393 NVOutputRegPtr regp, savep;
394 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
395 float aspect_ratio, panel_ratio;
396 uint32_t h_scale, v_scale;
399 state = &pNv->ModeReg;
400 regp = &state->dac_reg[nv_output->ramdac];
402 sv_state = &pNv->SavedReg;
403 savep = &sv_state->dac_reg[nv_output->ramdac];
405 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
408 regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1;
409 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1;
410 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay;
411 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1;
412 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1;
413 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew;
414 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1;
416 regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1;
417 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1;
418 regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay;
419 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1;
420 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1;
421 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
422 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1;
425 /* This seems to be a common mode
426 * bit0: positive vsync
427 * bit1: positive hsync
428 * bit8: enable panel scaling
430 regp->fp_control = 0x11100011;
433 ErrorF("Pre-panel scaling\n");
434 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
435 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
436 ErrorF("panel_ratio=%f\n", panel_ratio);
437 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
438 ErrorF("aspect_ratio=%f\n", aspect_ratio);
439 /* Scale factors is the so called 20.12 format, taken from Haiku */
440 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
441 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
442 ErrorF("h_scale=%d\n", h_scale);
443 ErrorF("v_scale=%d\n", v_scale);
445 /* Enable full width and height on the flat panel */
446 regp->fp_hvalid_start = 0;
447 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
449 regp->fp_vvalid_start = 0;
450 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
452 /* When doing vertical scaling, limit the last fetched line */
453 if (v_scale != (1 << 12)) {
454 regp->debug_2 = (1 << 28) | ((mode->VDisplay - 1) << 16);
459 /* GPU scaling happens automaticly at a ratio of 1:33 */
460 /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
461 if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
464 ErrorF("Scaling resolution on a widescreen panel\n");
466 /* Scaling in both directions needs to the same */
468 diff = nv_output->fpWidth - ((1 << 12) * mode->HDisplay)/h_scale;
469 regp->fp_hvalid_start = diff/2;
470 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
473 /* Same scaling, just for panels with aspect ratio's smaller than 1 */
474 if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
477 ErrorF("Scaling resolution on a portrait panel\n");
479 /* Scaling in both directions needs to the same */
481 diff = nv_output->fpHeight - ((1 << 12) * mode->VDisplay)/v_scale;
482 regp->fp_vvalid_start = diff/2;
483 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
486 ErrorF("Post-panel scaling\n");
488 /* copy a bunch of things from the current state for non-dfp's */
489 regp->debug_2 = savep->debug_2;
492 if (pNv->Architecture >= NV_ARCH_10) {
493 /* Bios and blob don't seem to do anything (else) */
494 regp->nv10_cursync = (1<<25);
497 /* These are the common blob values, minus a few fp specific bit's */
498 regp->debug_0 = 0x1101111;
499 regp->debug_1 = savep->debug_1;
501 /* My bios does 0x500, blob seems to do 0x4c4 or 0x4e4, all work */
502 regp->crtcSync = 0x4c4;
503 //regp->crtcSync += nv_output_tweak_panel(output, state);
505 /* I am not completely certain, but seems to be set only for dfp's */
506 regp->debug_0 |= (1<<8);
507 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
509 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
512 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
514 /* This is just a guess, there are probably more registers which need setting */
515 /* But we must start somewhere ;-) */
517 regp->TMDS[0x2] = 0x29;
518 regp->TMDS[0x4] = 0x80;
519 regp->TMDS[0x2b] = 0x7f;
522 /* Flatpanel support needs at least a NV10 */
524 /* Instead of 1, several other values are also used: 2, 7, 9 */
525 /* The purpose is unknown */
527 regp->dither = 0x00010000;
531 if(pLayout->depth < 24) {
532 bpp = pLayout->depth;
537 regp->general = bpp == 16 ? 0x00101100 : 0x00100100;
539 if (pNv->alphaCursor) {
540 regp->general |= (1<<29);
543 if(bpp != 8) {/* DirectColor */
544 regp->general |= 0x00000030;
547 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
550 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
554 for (i = 0; i < config->num_output; i++) {
555 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
557 /* is it this output ?? */
558 if (config->output[i] == output)
561 /* it the output connected */
562 if (config->output[i]->crtc == NULL)
566 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
574 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
577 if (nv_crtc->crtc == 1) {
578 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2;
580 regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_CRTC2;
583 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);
588 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
589 DisplayModePtr adjusted_mode)
591 ScrnInfoPtr pScrn = output->scrn;
592 NVPtr pNv = NVPTR(pScrn);
593 RIVA_HW_STATE *state;
595 state = &pNv->ModeReg;
597 nv_output_mode_set_regs(output, mode);
598 nv_output_load_state_ext(output, state);
602 nv_ddc_detect(xf86OutputPtr output)
604 /* no use for shared DDC output */
605 NVOutputPrivatePtr nv_output = output->driver_private;
608 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
612 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
615 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
619 xf86PrintEDID(ddc_mon);
621 if (nv_output->type == OUTPUT_DIGITAL) {
623 for (i = 0; i < 8; i++) {
624 if ((ddc_mon->timings2[i].hsize > nv_output->fpWidth) ||
625 (ddc_mon->timings2[i].vsize > nv_output->fpHeight)) {
627 nv_output->fpWidth = ddc_mon->timings2[i].hsize;
628 nv_output->fpHeight = ddc_mon->timings2[i].vsize;
637 nv_crt_load_detect(xf86OutputPtr output)
639 ScrnInfoPtr pScrn = output->scrn;
640 CARD32 reg_output, reg_test_ctrl, temp;
643 reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
644 reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
646 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
648 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
651 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
652 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
654 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
655 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
656 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
660 present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
662 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
663 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
665 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
666 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
668 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
675 static xf86OutputStatus
676 nv_digital_output_detect(xf86OutputPtr output)
678 NVOutputPrivatePtr nv_output = output->driver_private;
680 if (nv_ddc_detect(output))
681 return XF86OutputStatusConnected;
683 return XF86OutputStatusDisconnected;
687 static xf86OutputStatus
688 nv_analog_output_detect(xf86OutputPtr output)
690 NVOutputPrivatePtr nv_output = output->driver_private;
692 if (nv_ddc_detect(output))
693 return XF86OutputStatusConnected;
695 /* seems a bit flaky on ramdac 1 */
696 if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
697 return XF86OutputStatusConnected;
699 return XF86OutputStatusDisconnected;
702 static DisplayModePtr
703 nv_output_get_modes(xf86OutputPtr output)
705 ScrnInfoPtr pScrn = output->scrn;
706 NVOutputPrivatePtr nv_output = output->driver_private;
708 DisplayModePtr ddc_modes, mode;
712 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
714 if (ddc_mon == NULL) {
715 xf86OutputSetEDID(output, ddc_mon);
719 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
720 xf86OutputSetEDID(output, NULL);
724 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
725 xf86OutputSetEDID(output, NULL);
729 xf86OutputSetEDID(output, ddc_mon);
731 ddc_modes = xf86OutputGetEDIDModes (output);
737 nv_output_destroy (xf86OutputPtr output)
739 if (output->driver_private)
740 xfree (output->driver_private);
745 nv_output_prepare(xf86OutputPtr output)
751 nv_output_commit(xf86OutputPtr output)
757 static const xf86OutputFuncsRec nv_analog_output_funcs = {
758 .dpms = nv_analog_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_analog_output_detect,
765 .get_modes = nv_output_get_modes,
766 .destroy = nv_output_destroy,
767 .prepare = nv_output_prepare,
768 .commit = nv_output_commit,
771 static const xf86OutputFuncsRec nv_digital_output_funcs = {
772 .dpms = nv_digital_output_dpms,
773 .save = nv_output_save,
774 .restore = nv_output_restore,
775 .mode_valid = nv_output_mode_valid,
776 .mode_fixup = nv_output_mode_fixup,
777 .mode_set = nv_output_mode_set,
778 .detect = nv_digital_output_detect,
779 .get_modes = nv_output_get_modes,
780 .destroy = nv_output_destroy,
781 .prepare = nv_output_prepare,
782 .commit = nv_output_commit,
785 static xf86OutputStatus
786 nv_output_lvds_detect(xf86OutputPtr output)
788 return XF86OutputStatusUnknown;
791 static DisplayModePtr
792 nv_output_lvds_get_modes(xf86OutputPtr output)
794 ScrnInfoPtr pScrn = output->scrn;
795 NVOutputPrivatePtr nv_output = output->driver_private;
797 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
798 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
799 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
800 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
801 // nv_output->fpWidth, nv_output->fpHeight);
807 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
808 .dpms = nv_panel_output_dpms,
809 .save = nv_output_save,
810 .restore = nv_output_restore,
811 .mode_valid = nv_output_mode_valid,
812 .mode_fixup = nv_output_mode_fixup,
813 .mode_set = nv_output_mode_set,
814 .detect = nv_output_lvds_detect,
815 .get_modes = nv_output_lvds_get_modes,
816 .destroy = nv_output_destroy,
817 .prepare = nv_output_prepare,
818 .commit = nv_output_commit,
822 static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index)
824 NVPtr pNv = NVPTR(pScrn);
825 xf86OutputPtr output;
826 NVOutputPrivatePtr nv_output;
828 int crtc_mask = (1<<0) | (1<<1);
830 sprintf(outputname, "Analog-%d", pNv->analog_count);
831 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
834 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
836 xf86OutputDestroy (output);
840 output->driver_private = nv_output;
841 nv_output->type = OUTPUT_ANALOG;
843 /* dvi outputs share their i2c port with their analog output on the same port */
844 /* But they can never work at the same time, so it's convient to share ramdac index */
845 nv_output->ramdac = i2c_index;
847 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
849 output->possible_crtcs = crtc_mask;
850 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
856 static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index, int lvds)
858 NVPtr pNv = NVPTR(pScrn);
859 xf86OutputPtr output;
860 NVOutputPrivatePtr nv_output;
862 int crtc_mask = (1<<0) | (1<<1);
864 sprintf(outputname, "Digital-%d", pNv->digital_count);
866 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
868 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
871 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
873 xf86OutputDestroy (output);
877 output->driver_private = nv_output;
878 nv_output->type = OUTPUT_DIGITAL;
880 nv_output->ramdac = i2c_index;
882 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
884 output->possible_crtcs = crtc_mask;
885 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
887 pNv->digital_count++;
890 * Set up the outputs according to what type of chip we are.
892 * Some outputs may not initialize, due to allocation failure or because a
893 * controller chip isn't found.
896 void Nv20SetupOutputs(ScrnInfoPtr pScrn)
898 NVPtr pNv = NVPTR(pScrn);
899 xf86OutputPtr output;
900 NVOutputPrivatePtr nv_output;
902 int num_analog_outputs = pNv->twoHeads ? 2 : 1;
903 int num_digital_outputs = 1;
905 for (i = 0 ; i < num_analog_outputs; i++) {
906 nv_add_analog_output(pScrn, i);
909 for (i = 0 ; i < num_digital_outputs; i++) {
910 nv_add_digital_output(pScrn, i, 0);
914 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
916 unsigned char type, port, or, i2c_index;
917 NVPtr pNv = NVPTR(pScrn);
920 /* we setup the outputs up from the BIOS table */
921 if (pNv->dcb_entries) {
922 for (i = 0 ; i < pNv->dcb_entries; i++) {
923 type = pNv->dcb_table[i] & 0xf;
924 port = (pNv->dcb_table[i] >> 4) & 0xf;
925 or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1;
926 if (pNv->Architecture == NV_ARCH_40) {
927 /* Ports seem to be inverse on nv4x */
928 i2c_index = (~port) & 1;
934 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or);
935 if (type < 4 && port != 0xf) {
938 nv_add_analog_output(pScrn, i2c_index);
941 nv_add_digital_output(pScrn, i2c_index, 0);
944 nv_add_digital_output(pScrn, i2c_index, 1);
952 Nv20SetupOutputs(pScrn);
955 struct nv_i2c_struct {
964 void NvSetupOutputs(ScrnInfoPtr pScrn)
967 NVPtr pNv = NVPTR(pScrn);
968 xf86OutputPtr output;
969 NVOutputPrivatePtr nv_output;
971 int num_outputs = pNv->twoHeads ? 2 : 1;
973 pNv->Television = FALSE;
975 /* add the 3 I2C buses */
976 for (i = 0; i < NV_I2C_BUSES; i++) {
977 NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name);
980 NvDCBSetupOutputs(pScrn);
984 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
988 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
990 xf86OutputDestroy(output);
994 output->driver_private = nv_output;
995 nv_output->type = output_type;
997 output->possible_crtcs = i ? 1 : crtc_mask;
1002 #endif /* ENABLE_RANDR12 */
1004 /*************************************************************************** \
1006 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1008 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1009 |* international laws. Users and possessors of this source code are *|
1010 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1011 |* use this code in individual and commercial software. *|
1013 |* Any use of this source code must include, in the user documenta- *|
1014 |* tion and internal comments to the code, notices to the end user *|
1017 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1019 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1020 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1021 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1022 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1023 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1024 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1025 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1026 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1027 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1028 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1029 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1031 |* U.S. Government End Users. This source code is a "commercial *|
1032 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1033 |* consisting of "commercial computer software" and "commercial *|
1034 |* computer software documentation," as such terms are used in *|
1035 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1036 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1037 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1038 |* all U.S. Government End Users acquire the source code with only *|
1039 |* those rights set forth herein. *|
1041 \***************************************************************************/