2 * Copyright 2006 Dave Airlie
3 * Copyright 2007 Maarten Maathuis
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
26 * 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] = {
70 * TMDS registers are indirect 8 bit registers.
71 * Reading is straightforward, writing a bit odd.
72 * Reading: Write adress (+write protect bit, do not forget this), then read value.
73 * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
76 void NVWriteTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
78 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
79 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
81 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
83 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
84 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
85 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
88 CARD8 NVReadTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg)
90 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
91 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
93 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
96 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
98 NVOutputPrivatePtr nv_output = output->driver_private;
99 ScrnInfoPtr pScrn = output->scrn;
100 NVPtr pNv = NVPTR(pScrn);
103 /* Is TMDS programmed on a different output? */
104 /* Always choose the prefered ramdac, since that one contains the tmds stuff */
105 /* Assumption: there is always once output that can only run of the primary ramdac */
106 if (nv_output->valid_ramdac & RAMDAC_1) {
112 NVWriteTMDS(pNv, ramdac, tmds_reg, val);
115 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
117 NVOutputPrivatePtr nv_output = output->driver_private;
118 ScrnInfoPtr pScrn = output->scrn;
119 NVPtr pNv = NVPTR(pScrn);
122 /* Is TMDS programmed on a different output? */
123 /* Always choose the prefered ramdac, since that one contains the tmds stuff */
124 /* Assumption: there is always once output that can only run of the primary ramdac */
125 if (nv_output->valid_ramdac & RAMDAC_1) {
131 return NVReadTMDS(pNv, ramdac, tmds_reg);
134 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
136 NVOutputPrivatePtr nv_output = output->driver_private;
137 ScrnInfoPtr pScrn = output->scrn;
138 NVPtr pNv = NVPTR(pScrn);
140 nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val);
143 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
145 NVOutputPrivatePtr nv_output = output->driver_private;
146 ScrnInfoPtr pScrn = output->scrn;
147 NVPtr pNv = NVPTR(pScrn);
149 return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg);
152 static void nv_output_backlight_enable(xf86OutputPtr output, Bool on)
154 ScrnInfoPtr pScrn = output->scrn;
155 NVPtr pNv = NVPTR(pScrn);
157 /* This is done differently on each laptop. Here we
158 define the ones we know for sure. */
160 #if defined(__powerpc__)
161 if((pNv->Chipset == 0x10DE0179) ||
162 (pNv->Chipset == 0x10DE0189) ||
163 (pNv->Chipset == 0x10DE0329))
165 /* NV17,18,34 Apple iMac, iBook, PowerBook */
166 CARD32 tmp_pmc, tmp_pcrt;
167 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
168 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
170 tmp_pmc |= (1 << 31);
173 nvWriteMC(pNv, 0x10F0, tmp_pmc);
174 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
178 if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
179 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
183 nv_panel_output_dpms(xf86OutputPtr output, int mode)
187 case DPMSModeStandby:
188 case DPMSModeSuspend:
190 nv_output_backlight_enable(output, 0);
193 nv_output_backlight_enable(output, 1);
200 nv_analog_output_dpms(xf86OutputPtr output, int mode)
202 xf86CrtcPtr crtc = output->crtc;
205 NVPtr pNv = NVPTR(output->scrn);
206 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
208 /* We are going for modesetting, so we must reset the ramdacs */
209 if (mode == DPMSModeOff) {
210 ScrnInfoPtr pScrn = output->scrn;
211 NVPtr pNv = NVPTR(pScrn);
212 NVOutputPrivatePtr nv_output = output->driver_private;
213 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
215 /* We no longer have ramdac, which will be reassigned soon enough */
216 pNv->ramdac_active[nv_output->ramdac] = FALSE;
217 nv_output->ramdac_assigned = FALSE;
218 nv_output->ramdac = -1;
221 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
226 nv_digital_output_dpms(xf86OutputPtr output, int mode)
228 xf86CrtcPtr crtc = output->crtc;
229 NVOutputPrivatePtr nv_output = output->driver_private;
231 /* Are we assigned a ramdac already?, else we will be activeted during mode set */
232 if (crtc && nv_output->ramdac_assigned) {
233 NVPtr pNv = NVPTR(output->scrn);
234 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
236 ErrorF("nv_digital_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
238 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
240 case DPMSModeStandby:
241 case DPMSModeSuspend:
243 /* cut the TMDS output */
244 fpcontrol |= 0x20000022;
247 /* disable cutting the TMDS output */
248 fpcontrol &= ~0x20000022;
251 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
253 /* We are going for modesetting, so we must reset the ramdacs */
254 if (mode == DPMSModeOff) {
255 ScrnInfoPtr pScrn = output->scrn;
256 NVPtr pNv = NVPTR(pScrn);
257 NVOutputPrivatePtr nv_output = output->driver_private;
258 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
260 /* We no longer have ramdac, which will be reassigned soon enough */
261 pNv->ramdac_active[nv_output->ramdac] = FALSE;
262 nv_output->ramdac_assigned = FALSE;
263 nv_output->ramdac = -1;
268 int tmds_regs[] = { 0x4, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x3a };
270 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
272 NVOutputPrivatePtr nv_output = output->driver_private;
273 ScrnInfoPtr pScrn = output->scrn;
274 NVPtr pNv = NVPTR(pScrn);
278 regp = &state->dac_reg[nv_output->ramdac];
279 regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
280 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
281 regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
282 regp->debug_1 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
283 regp->debug_2 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
284 regp->sel_clk = NVOutputReadRAMDAC(output, NV_RAMDAC_SEL_CLK);
285 state->config = nvReadFB(pNv, NV_PFB_CFG0);
287 regp->unk_a20 = NVOutputReadRAMDAC(output, NV_RAMDAC_A20);
288 regp->unk_a24 = NVOutputReadRAMDAC(output, NV_RAMDAC_A24);
289 regp->unk_a34 = NVOutputReadRAMDAC(output, NV_RAMDAC_A34);
291 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
293 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
294 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
295 } else if (pNv->twoHeads) {
296 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
298 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
300 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
301 regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
304 /* The regs below are 0 for non-flatpanels, so you can load and save them */
306 for (i = 0; i < 7; i++) {
307 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
308 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
311 for (i = 0; i < 7; i++) {
312 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
313 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
316 regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
317 regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
318 regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
319 regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
322 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
324 NVOutputPrivatePtr nv_output = output->driver_private;
325 ScrnInfoPtr pScrn = output->scrn;
326 NVPtr pNv = NVPTR(pScrn);
330 regp = &state->dac_reg[nv_output->ramdac];
332 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
333 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
334 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
335 NVOutputWriteRAMDAC(output, NV_RAMDAC_SEL_CLK, regp->sel_clk);
336 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
337 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
339 NVOutputWriteRAMDAC(output, NV_RAMDAC_A20, regp->unk_a20);
340 NVOutputWriteRAMDAC(output, NV_RAMDAC_A24, regp->unk_a24);
341 NVOutputWriteRAMDAC(output, NV_RAMDAC_A34, regp->unk_a34);
343 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
344 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
345 } else if (pNv->twoHeads) {
346 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
349 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
350 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
352 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
353 NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
356 /* The regs below are 0 for non-flatpanels, so you can load and save them */
358 for (i = 0; i < 7; i++) {
359 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
360 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
363 for (i = 0; i < 7; i++) {
364 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
365 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
368 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
369 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
370 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
371 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
374 /* NOTE: Don't rely on this data for anything other than restoring VT's */
377 nv_output_save (xf86OutputPtr output)
379 ScrnInfoPtr pScrn = output->scrn;
380 NVPtr pNv = NVPTR(pScrn);
381 RIVA_HW_STATE *state;
382 NVOutputPrivatePtr nv_output = output->driver_private;
383 int ramdac_backup = nv_output->ramdac;
385 ErrorF("nv_output_save is called\n");
387 /* This is early init and we have not yet been assigned a ramdac */
388 /* Always choose the prefered ramdac, for consistentcy */
389 /* Assumption: there is always once output that can only run of the primary ramdac */
390 if (nv_output->valid_ramdac & RAMDAC_1) {
391 nv_output->ramdac = 1;
393 nv_output->ramdac = 0;
396 state = &pNv->SavedReg;
398 /* Due to strange mapping of outputs we could have swapped analog and digital */
399 /* So we force save all the registers */
400 nv_output_save_state_ext(output, state, TRUE);
402 /* restore previous state */
403 nv_output->ramdac = ramdac_backup;
407 nv_output_restore (xf86OutputPtr output)
409 ScrnInfoPtr pScrn = output->scrn;
410 NVPtr pNv = NVPTR(pScrn);
411 RIVA_HW_STATE *state;
412 NVOutputPrivatePtr nv_output = output->driver_private;
413 int ramdac_backup = nv_output->ramdac;
415 ErrorF("nv_output_restore is called\n");
417 /* We want consistent mode restoring and the ramdac entry is variable */
418 /* Always choose the prefered ramdac, for consistentcy */
419 /* Assumption: there is always once output that can only run of the primary ramdac */
420 if (nv_output->valid_ramdac & RAMDAC_1) {
421 nv_output->ramdac = 1;
423 nv_output->ramdac = 0;
426 state = &pNv->SavedReg;
428 /* Due to strange mapping of outputs we could have swapped analog and digital */
429 /* So we force load all the registers */
430 nv_output_load_state_ext(output, state, TRUE);
432 /* restore previous state */
433 nv_output->ramdac = ramdac_backup;
437 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
439 if (pMode->Flags & V_DBLSCAN)
440 return MODE_NO_DBLESCAN;
442 if (pMode->Clock > 400000 || pMode->Clock < 25000)
443 return MODE_CLOCK_RANGE;
450 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
451 DisplayModePtr adjusted_mode)
453 ErrorF("nv_output_mode_fixup is called\n");
459 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
461 NVOutputPrivatePtr nv_output = output->driver_private;
462 ScrnInfoPtr pScrn = output->scrn;
463 NVPtr pNv = NVPTR(pScrn);
467 regp = &state->dac_reg[nv_output->ramdac];
468 if (pNv->usePanelTweak) {
469 tweak = pNv->PanelTweak;
471 /* begin flat panel hacks */
472 /* This is unfortunate, but some chips need this register
473 tweaked or else you get artifacts where adjacent pixels are
474 swapped. There are no hard rules for what to set here so all
475 we can do is experiment and apply hacks. */
477 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
478 /* At least one NV34 laptop needs this workaround. */
482 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
485 /* end flat panel hacks */
491 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
493 NVOutputPrivatePtr nv_output = output->driver_private;
494 ScrnInfoPtr pScrn = output->scrn;
496 NVPtr pNv = NVPTR(pScrn);
497 NVFBLayout *pLayout = &pNv->CurrentLayout;
498 RIVA_HW_STATE *state, *sv_state;
500 NVOutputRegPtr regp, regp2, savep;
501 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
502 float aspect_ratio, panel_ratio;
503 uint32_t h_scale, v_scale;
506 state = &pNv->ModeReg;
507 regp = &state->dac_reg[nv_output->ramdac];
508 /* The other ramdac */
509 regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
511 sv_state = &pNv->SavedReg;
512 savep = &sv_state->dac_reg[nv_output->ramdac];
514 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
517 /* Do we need to set the native mode or not? */
519 /* We can set the mode as usual if we let the panel scale */
520 regp->fp_horiz_regs[REG_DISP_END] = mode->HDisplay - 1;
521 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->HTotal - 1;
522 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->HDisplay;
523 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->HSyncStart - 1;
524 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->HSyncEnd - 1;
525 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->HSkew;
526 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->HDisplay - 1;
528 regp->fp_vert_regs[REG_DISP_END] = mode->VDisplay - 1;
529 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->VTotal - 1;
530 regp->fp_vert_regs[REG_DISP_CRTC] = mode->VDisplay;
531 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->VSyncStart - 1;
532 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->VSyncEnd - 1;
533 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
534 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->VDisplay - 1;
536 /* For gpu scaling we need the native mode */
537 /* Let's find our native mode amongst all the ddc modes */
538 DisplayModePtr native = nv_output->monitor_modes;
540 /* assumption: each mode has it's unique clock */
541 if (nv_output->clock == native->Clock) {
544 } while (native = native->next);
545 regp->fp_horiz_regs[REG_DISP_END] = native->HDisplay - 1;
546 regp->fp_horiz_regs[REG_DISP_TOTAL] = native->HTotal - 1;
547 regp->fp_horiz_regs[REG_DISP_CRTC] = native->HDisplay;
548 regp->fp_horiz_regs[REG_DISP_SYNC_START] = native->HSyncStart - 1;
549 regp->fp_horiz_regs[REG_DISP_SYNC_END] = native->HSyncEnd - 1;
550 regp->fp_horiz_regs[REG_DISP_VALID_START] = native->HSkew;
551 regp->fp_horiz_regs[REG_DISP_VALID_END] = native->HDisplay - 1;
553 regp->fp_vert_regs[REG_DISP_END] = native->VDisplay - 1;
554 regp->fp_vert_regs[REG_DISP_TOTAL] = native->VTotal - 1;
555 regp->fp_vert_regs[REG_DISP_CRTC] = native->VDisplay;
556 regp->fp_vert_regs[REG_DISP_SYNC_START] = native->VSyncStart - 1;
557 regp->fp_vert_regs[REG_DISP_SYNC_END] = native->VSyncEnd - 1;
558 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
559 regp->fp_vert_regs[REG_DISP_VALID_END] = native->VDisplay - 1;
562 ErrorF("Horizontal:\n");
563 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_END]);
564 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_horiz_regs[REG_DISP_TOTAL]);
565 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_horiz_regs[REG_DISP_CRTC]);
566 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_START]);
567 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_END]);
568 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_START]);
569 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_END]);
571 ErrorF("Vertical:\n");
572 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_END]);
573 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_vert_regs[REG_DISP_TOTAL]);
574 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_vert_regs[REG_DISP_CRTC]);
575 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_START]);
576 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_END]);
577 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_START]);
578 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_END]);
581 /* This register is only used on the primary ramdac */
582 /* The value 0x40000 is not acceptable in text mode, but seems to do no harm in X mode */
583 /* The blob does this often, the exact purpose is not exactly known */
584 if (nv_output->ramdac == 0) {
585 regp->sel_clk = nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) | (1 << 18);
588 /* This seems to be a common mode
589 * bit0: positive vsync
590 * bit4: positive hsync
591 * bit8: enable panel scaling
592 * This must also be set for non-flatpanels
594 regp->fp_control = 0x11100000;
596 /* Deal with vsync/hsync polarity */
597 if (mode->Flags & V_PVSYNC) {
598 regp->fp_control |= (1 << 0);
601 if (mode->Flags & V_PHSYNC) {
602 regp->fp_control |= (1 << 4);
606 ErrorF("Pre-panel scaling\n");
607 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
608 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
609 ErrorF("panel_ratio=%f\n", panel_ratio);
610 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
611 ErrorF("aspect_ratio=%f\n", aspect_ratio);
612 /* Scale factors is the so called 20.12 format, taken from Haiku */
613 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
614 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
615 ErrorF("h_scale=%d\n", h_scale);
616 ErrorF("v_scale=%d\n", v_scale);
618 /* Don't limit last fetched line */
621 /* We want automatic scaling */
624 regp->fp_hvalid_start = 0;
625 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
627 regp->fp_vvalid_start = 0;
628 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
631 ErrorF("Flat panel is doing the scaling.\n");
632 regp->fp_control |= (1 << 8);
634 ErrorF("GPU is doing the scaling.\n");
635 /* GPU scaling happens automaticly at a ratio of 1:33 */
636 /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
637 if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
640 ErrorF("Scaling resolution on a widescreen panel\n");
642 /* Scaling in both directions needs to the same */
645 /* Set a new horizontal scale factor and enable testmode (bit12) */
646 regp->debug_1 = ((h_scale >> 1) & 0xfff) | (1 << 12);
648 diff = nv_output->fpWidth - (((1 << 12) * mode->HDisplay)/h_scale);
649 regp->fp_hvalid_start = diff/2;
650 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
653 /* Same scaling, just for panels with aspect ratio's smaller than 1 */
654 /* This may be broken */
655 if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
658 ErrorF("Scaling resolution on a portrait panel\n");
660 /* Scaling in both directions needs to the same */
663 /* Is this ok, since haiku only does widescreen panels? */
664 regp->debug_1 = ((v_scale >> 1) & 0xfff) | (1 << 12);
666 diff = nv_output->fpHeight - (((1 << 12) * mode->VDisplay)/v_scale);
667 regp->fp_vvalid_start = diff/2;
668 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
672 ErrorF("Post-panel scaling\n");
675 if (pNv->Architecture >= NV_ARCH_10) {
676 /* Bios and blob don't seem to do anything (else) */
677 regp->nv10_cursync = (1<<25);
680 /* These are the common blob values, minus a few fp specific bit's */
681 /* The OR mask is in case the powerdown switch was enabled from the other output */
682 regp->debug_0 |= 0x1101111;
685 /* I am not completely certain, but seems to be set only for dfp's */
686 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED;
689 /* We must ensure that we never disable the wrong tmds control */
690 /* Assumption: one output can only run of ramdac 0 */
691 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)) {
693 regp2->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
695 regp2->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
699 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
701 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
705 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
707 /* This is just a guess, there are probably more registers which need setting */
708 /* But we must start somewhere ;-) */
710 regp->TMDS[0x4] = 0x80;
711 /* Enable crosswired mode */
712 /* As far as i know, this may never be set on ramdac 0 tmds registers (ramdac 1 -> crosswired -> ramdac 0 tmds regs) */
713 /* This will upset the monitor, trust me, i know it :-( */
714 /* Restricting to cards that had this setup at bootup time, until i am certain it's ok to use */
715 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)
716 && pNv->output_info & OUTPUT_1_CROSSWIRED_TMDS) {
717 regp->TMDS[0x4] |= (1 << 3);
721 /* Completely unknown TMDS registers:
728 /* The TMDS game begins */
729 /* A few registers are also programmed on non-tmds monitors */
730 /* At the moment i can't give rationale for these values */
732 regp->TMDS[0x2e] = 0x80;
733 regp->TMDS[0x2f] = 0xff;
734 regp->TMDS[0x33] = 0xfe;
736 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
737 regp->TMDS[0x2b] = 0x7d;
738 regp->TMDS[0x2c] = 0x0;
739 if (nv_crtc->head == 1) {
740 regp->TMDS[0x2e] = 0x81;
742 regp->TMDS[0x2e] = 0x85;
744 regp->TMDS[0x2f] = 0x21;
745 regp->TMDS[0x30] = 0x0;
746 regp->TMDS[0x31] = 0x0;
747 regp->TMDS[0x32] = 0x0;
748 regp->TMDS[0x33] = 0xf0;
749 regp->TMDS[0x3a] = 0x80;
752 /* Flatpanel support needs at least a NV10 */
754 /* Instead of 1, several other values are also used: 2, 7, 9 */
755 /* The purpose is unknown */
757 regp->dither = 0x00010000;
761 if(pLayout->depth < 24) {
762 bpp = pLayout->depth;
767 /* Kindly borrowed from haiku driver */
768 /* bit4 and bit5 activate indirect mode trough color palette */
769 switch (pLayout->depth) {
772 regp->general = 0x00101130;
776 regp->general = 0x00100130;
780 regp->general = 0x00101100;
784 if (pNv->alphaCursor) {
785 regp->general |= (1<<29);
788 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
790 /* Some values the blob sets */
791 /* This may apply to the real ramdac that is being used (for crosswired situations) */
792 /* Nevertheless, it's unlikely to cause many problems, since the values are equal for both */
794 regp->unk_a24 = 0xfffff;
798 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
802 for (i = 0; i < config->num_output; i++) {
803 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
805 /* is it this output ?? */
806 if (config->output[i] == output)
809 /* it the output connected */
810 if (config->output[i]->crtc == NULL)
814 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
822 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
825 if (nv_crtc->head == 1) {
826 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
828 regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_CRTC1;
831 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);
836 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
837 DisplayModePtr adjusted_mode)
839 ScrnInfoPtr pScrn = output->scrn;
840 NVPtr pNv = NVPTR(pScrn);
841 RIVA_HW_STATE *state;
843 ErrorF("nv_output_mode_set is called\n");
845 state = &pNv->ModeReg;
847 nv_output_mode_set_regs(output, mode);
848 nv_output_load_state_ext(output, state, FALSE);
852 nv_ddc_detect(xf86OutputPtr output)
854 /* no use for shared DDC output */
855 NVOutputPrivatePtr nv_output = output->driver_private;
857 ScrnInfoPtr pScrn = output->scrn;
859 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
863 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
866 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
870 if (nv_output->type == OUTPUT_DIGITAL) {
872 for (i = 0; i < 4; i++) {
873 /* Filter out the stupid entries */
874 if (ddc_mon->det_mon[i].section.d_timings.h_active > 4096)
876 if (ddc_mon->det_mon[i].section.d_timings.v_active > 4096)
878 /* Selecting only based on width ok? */
879 if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
880 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
881 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
882 /* ddc clocks are in Hz, while mode clocks are in kHz */
883 nv_output->clock = ddc_mon->det_mon[i].section.d_timings.clock/1000;
884 /* Find the matchig native refresh rate */
885 for (j = 0; i < 5; i++) {
886 if (ddc_mon->det_mon[i].section.std_t[j].hsize == nv_output->fpWidth &&
887 ddc_mon->det_mon[i].section.std_t[j].vsize == nv_output->fpHeight) {
889 nv_output->refresh = ddc_mon->det_mon[i].section.std_t[j].refresh;
893 nv_output->monitor_modes = xf86DDCGetModes(pScrn->scrnIndex, ddc_mon);
902 nv_crt_load_detect(xf86OutputPtr output)
904 ScrnInfoPtr pScrn = output->scrn;
905 CARD32 reg_output, reg_test_ctrl, temp;
908 reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
909 reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
911 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
913 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
916 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
917 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1);
919 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140);
920 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
921 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
925 present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
927 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
928 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
930 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output);
931 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
933 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n",
940 static xf86OutputStatus
941 nv_digital_output_detect(xf86OutputPtr output)
943 NVOutputPrivatePtr nv_output = output->driver_private;
945 ErrorF("nv_digital_output_detect is called\n");
947 if (nv_ddc_detect(output))
948 return XF86OutputStatusConnected;
950 return XF86OutputStatusDisconnected;
954 static xf86OutputStatus
955 nv_analog_output_detect(xf86OutputPtr output)
957 NVOutputPrivatePtr nv_output = output->driver_private;
959 ErrorF("nv_analog_output_detect is called\n");
961 if (nv_ddc_detect(output))
962 return XF86OutputStatusConnected;
964 /* Disabled for now, since we don't actually have a ramdac yet and i need time to figure out a nice way to do this ;-) */
965 /* seems a bit flaky on ramdac 1 */
966 //if ((nv_output->ramdac==0) && nv_crt_load_detect(output))
967 //return XF86OutputStatusConnected;
969 return XF86OutputStatusDisconnected;
972 static DisplayModePtr
973 nv_output_get_modes(xf86OutputPtr output)
975 ScrnInfoPtr pScrn = output->scrn;
976 NVOutputPrivatePtr nv_output = output->driver_private;
978 DisplayModePtr ddc_modes, mode;
980 ErrorF("nv_output_get_modes is called\n");
982 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
984 if (ddc_mon == NULL) {
985 xf86OutputSetEDID(output, ddc_mon);
989 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
990 xf86OutputSetEDID(output, NULL);
994 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
995 xf86OutputSetEDID(output, NULL);
999 xf86OutputSetEDID(output, ddc_mon);
1001 ddc_modes = xf86OutputGetEDIDModes (output);
1007 nv_output_destroy (xf86OutputPtr output)
1009 ErrorF("nv_output_destroy is called\n");
1010 if (output->driver_private)
1011 xfree (output->driver_private);
1016 nv_output_prepare(xf86OutputPtr output)
1018 ErrorF("nv_output_prepare is called\n");
1019 NVOutputPrivatePtr nv_output = output->driver_private;
1020 ScrnInfoPtr pScrn = output->scrn;
1021 NVPtr pNv = NVPTR(pScrn);
1023 if (nv_output->ramdac_assigned) {
1024 ErrorF("We already have a ramdac, what went wrong?\n");
1028 if ((nv_output->valid_ramdac & RAMDAC_0) && !(pNv->ramdac_active[0])) {
1029 pNv->ramdac_active[0] = TRUE;
1030 nv_output->ramdac = 0;
1031 } else if ((nv_output->valid_ramdac & RAMDAC_1) && !(pNv->ramdac_active[1])) {
1032 pNv->ramdac_active[1] = TRUE;
1033 nv_output->ramdac = 1;
1036 if (nv_output->ramdac != -1)
1037 nv_output->ramdac_assigned = TRUE;
1041 nv_output_commit(xf86OutputPtr output)
1043 ErrorF("nv_output_commit is called\n");
1046 static const xf86OutputFuncsRec nv_analog_output_funcs = {
1047 .dpms = nv_analog_output_dpms,
1048 .save = nv_output_save,
1049 .restore = nv_output_restore,
1050 .mode_valid = nv_output_mode_valid,
1051 .mode_fixup = nv_output_mode_fixup,
1052 .mode_set = nv_output_mode_set,
1053 .detect = nv_analog_output_detect,
1054 .get_modes = nv_output_get_modes,
1055 .destroy = nv_output_destroy,
1056 .prepare = nv_output_prepare,
1057 .commit = nv_output_commit,
1060 static const xf86OutputFuncsRec nv_digital_output_funcs = {
1061 .dpms = nv_digital_output_dpms,
1062 .save = nv_output_save,
1063 .restore = nv_output_restore,
1064 .mode_valid = nv_output_mode_valid,
1065 .mode_fixup = nv_output_mode_fixup,
1066 .mode_set = nv_output_mode_set,
1067 .detect = nv_digital_output_detect,
1068 .get_modes = nv_output_get_modes,
1069 .destroy = nv_output_destroy,
1070 .prepare = nv_output_prepare,
1071 .commit = nv_output_commit,
1074 static xf86OutputStatus
1075 nv_output_lvds_detect(xf86OutputPtr output)
1077 return XF86OutputStatusUnknown;
1080 static DisplayModePtr
1081 nv_output_lvds_get_modes(xf86OutputPtr output)
1083 ScrnInfoPtr pScrn = output->scrn;
1084 NVOutputPrivatePtr nv_output = output->driver_private;
1086 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1087 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1088 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1089 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
1090 // nv_output->fpWidth, nv_output->fpHeight);
1096 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1097 .dpms = nv_panel_output_dpms,
1098 .save = nv_output_save,
1099 .restore = nv_output_restore,
1100 .mode_valid = nv_output_mode_valid,
1101 .mode_fixup = nv_output_mode_fixup,
1102 .mode_set = nv_output_mode_set,
1103 .detect = nv_output_lvds_detect,
1104 .get_modes = nv_output_lvds_get_modes,
1105 .destroy = nv_output_destroy,
1106 .prepare = nv_output_prepare,
1107 .commit = nv_output_commit,
1111 static void nv_add_analog_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dvi_pair)
1113 NVPtr pNv = NVPTR(pScrn);
1114 xf86OutputPtr output;
1115 NVOutputPrivatePtr nv_output;
1116 char outputname[20];
1117 int crtc_mask = (1<<0) | (1<<1);
1119 Bool create_output = TRUE;
1121 sprintf(outputname, "Analog-%d", pNv->analog_count);
1122 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1127 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1128 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1130 nv_output->type = OUTPUT_ANALOG;
1133 * bit0: RAMDAC_0 valid
1134 * bit1: RAMDAC_1 valid
1135 * So lowest order has highest priority.
1137 nv_output->valid_ramdac = order + 1;
1139 if (!create_output) {
1144 /* Delay creation of output until we actually know we want it */
1145 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1149 output->driver_private = nv_output;
1151 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1153 output->possible_crtcs = crtc_mask;
1154 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1156 pNv->analog_count++;
1160 static void nv_add_digital_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dual_dvi, int lvds)
1162 NVPtr pNv = NVPTR(pScrn);
1163 xf86OutputPtr output;
1164 NVOutputPrivatePtr nv_output;
1165 char outputname[20];
1166 int crtc_mask = (1<<0) | (1<<1);
1167 Bool create_output = TRUE;
1168 int index = i2c_index;
1170 sprintf(outputname, "Digital-%d", pNv->digital_count);
1171 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1177 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1178 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1180 nv_output->type = OUTPUT_DIGITAL;
1183 * bit0: RAMDAC_0 valid
1184 * bit1: RAMDAC_1 valid
1185 * So lowest order has highest priority.
1187 nv_output->valid_ramdac = order + 1;
1189 /* Sorry, i don't know what to do with lvds */
1192 /* Is anyone crosswired?, pick the other index */
1193 if (pNv->output_info & OUTPUT_0_CROSSWIRED_TMDS ||
1194 pNv->output_info & OUTPUT_1_CROSSWIRED_TMDS) {
1196 real_index = (~index) & 1;
1201 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1203 /* This detection may be flawed, it will corrected as soon as i have a good idea */
1205 /* At the moment something must be already active, before we do anything */
1206 if (nvReadRAMDAC(pNv, real_index, NV_RAMDAC_FP_DEBUG_0) & NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED) {
1207 /* We're not supposed to be LVDS */
1208 /* Using index, because this is part of the TMDS programming */
1209 if (pNv->output_info & (OUTPUT_0_LVDS << index)) {
1210 ErrorF("Output refused because this is supposed to be TMDS, not LVDS.\n");
1211 create_output = FALSE;
1213 /* we should be slaved to a ramdac, otherwise we don't exist */
1214 if (!(pNv->output_info & (OUTPUT_0_SLAVED << real_index))) {
1215 ErrorF("Output refused because the output is not slaved, which is needed for a DFP.\n");
1216 create_output = FALSE;
1219 ErrorF("Output refused because the DFP doesn't seem to be active.\n");
1220 ErrorF("Debug info:\n");
1221 ErrorF("Ramdac index: %d\n", real_index);
1222 ErrorF("Ramdac0: NV_RAMDAC_FP_DEBUG_0: 0x%X\n", nvReadRAMDAC(pNv, 0, NV_RAMDAC_FP_DEBUG_0));
1223 ErrorF("Ramdac1: NV_RAMDAC_FP_DEBUG_0: 0x%X\n", nvReadRAMDAC(pNv, 1, NV_RAMDAC_FP_DEBUG_0));
1224 create_output = FALSE;
1227 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1228 create_output = FALSE;
1231 if (!create_output) {
1236 /* Delay creation of output until we are certain is desirable */
1238 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1240 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
1244 output->driver_private = nv_output;
1246 output->possible_crtcs = crtc_mask;
1247 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1249 pNv->digital_count++;
1252 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1254 unsigned char type, i2c_index, or;
1255 NVPtr pNv = NVPTR(pScrn);
1257 int num_digital = 0;
1258 Bool dual_dvi = FALSE;
1259 Bool dvi_pair = FALSE;
1261 /* check how many TMDS ports there are */
1262 if (pNv->dcb_table.entries) {
1263 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1264 type = pNv->dcb_table.connection[i] & 0xf;
1265 i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1267 if (type == 2 && i2c_index != 0xf) {
1273 if (num_digital > 1) {
1277 /* It's time to gather some information */
1279 /* Being slaved indicates we're a flatpanel (or tv-out) */
1280 if (NVReadVGA0(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1281 pNv->output_info |= OUTPUT_0_SLAVED;
1283 if (NVReadVGA1(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1284 pNv->output_info |= OUTPUT_1_SLAVED;
1286 /* This is an educated guess */
1287 if (NVReadTMDS(pNv, 0, 0x4) & (1 << 3)) {
1288 pNv->output_info |= OUTPUT_0_CROSSWIRED_TMDS;
1290 if (NVReadTMDS(pNv, 1, 0x4) & (1 << 3)) {
1291 pNv->output_info |= OUTPUT_1_CROSSWIRED_TMDS;
1294 if (NVReadTMDS(pNv, 0, 0x4) & (1 << 0)) {
1295 pNv->output_info |= OUTPUT_0_LVDS;
1297 if (NVReadTMDS(pNv, 1, 0x4) & (1 << 0)) {
1298 pNv->output_info |= OUTPUT_1_LVDS;
1301 /* we setup the outputs up from the BIOS table */
1302 if (pNv->dcb_table.entries) {
1303 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1304 type = pNv->dcb_table.connection[i] & 0xf;
1305 i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1306 or = ffs((pNv->dcb_table.connection[i] >> 24) & 0xf) - 1;
1309 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, i2c_index: %d, or: %d\n", i, pNv->dcb_table.connection[i], type, i2c_index, or);
1312 case OUTPUT_ANALOG: /* Analogue VGA */
1313 nv_add_analog_output(pScrn, or, i2c_index, dvi_pair);
1316 case OUTPUT_DIGITAL: /* TMDS */
1318 nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 0);
1320 case OUTPUT_PANEL: /* LVDS */
1321 nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 1);
1331 void NvSetupOutputs(ScrnInfoPtr pScrn)
1334 NVPtr pNv = NVPTR(pScrn);
1336 pNv->Television = FALSE;
1338 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1339 NvDCBSetupOutputs(pScrn);
1342 xf86OutputPtr output;
1343 NVOutputPrivatePtr nv_output;
1346 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
1350 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
1352 xf86OutputDestroy(output);
1356 output->driver_private = nv_output;
1357 nv_output->type = output_type;
1359 output->possible_crtcs = i ? 1 : crtc_mask;
1364 #endif /* ENABLE_RANDR12 */
1366 /*************************************************************************** \
1368 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1370 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1371 |* international laws. Users and possessors of this source code are *|
1372 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1373 |* use this code in individual and commercial software. *|
1375 |* Any use of this source code must include, in the user documenta- *|
1376 |* tion and internal comments to the code, notices to the end user *|
1379 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1381 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1382 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1383 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1384 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1385 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1386 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1387 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1388 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1389 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1390 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1391 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1393 |* U.S. Government End Users. This source code is a "commercial *|
1394 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1395 |* consisting of "commercial computer software" and "commercial *|
1396 |* computer software documentation," as such terms are used in *|
1397 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1398 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1399 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1400 |* all U.S. Government End Users acquire the source code with only *|
1401 |* those rights set forth herein. *|
1403 \***************************************************************************/