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 ErrorF("nv_output_backlight_enable is called for output %s to turn %s\n", output->name, on ? "on" : "off");
159 /* This is done differently on each laptop. Here we
160 * define the ones we know for sure. */
162 #if defined(__powerpc__)
163 if ((pNv->Chipset == 0x10DE0179) ||
164 (pNv->Chipset == 0x10DE0189) ||
165 (pNv->Chipset == 0x10DE0329)) {
166 /* NV17,18,34 Apple iMac, iBook, PowerBook */
167 CARD32 tmp_pmc, tmp_pcrt;
168 tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
169 tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
171 tmp_pmc |= (1 << 31);
174 nvWriteMC(pNv, 0x10F0, tmp_pmc);
175 nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
179 if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11))
180 nvWriteMC(pNv, 0x130C, on ? 3 : 7);
184 nv_lvds_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;
203 NVOutputPrivatePtr nv_output = output->driver_private;
204 NVPtr pNv = NVPTR(output->scrn);
206 ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
208 if (nv_output->ramdac != -1) {
209 /* We are going for modesetting, so we must reset the ramdacs */
210 if (mode == DPMSModeOff) {
211 /* We no longer have ramdac, which will be reassigned soon enough */
212 pNv->ramdac_active[nv_output->ramdac] = FALSE;
213 ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
214 nv_output->ramdac_assigned = FALSE;
216 pNv->ramdac_active[nv_output->ramdac] = TRUE;
217 ErrorF("Activating ramdac %d\n", nv_output->ramdac);
218 nv_output->ramdac_assigned = TRUE;
223 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
225 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
230 nv_digital_output_dpms(xf86OutputPtr output, int mode)
232 xf86CrtcPtr crtc = output->crtc;
233 NVOutputPrivatePtr nv_output = output->driver_private;
234 NVPtr pNv = NVPTR(output->scrn);
236 ErrorF("nv_digital_output_dpms is called with mode %d\n", mode);
238 /* We just woke up again from an actual monitor dpms and not a modeset prepare */
239 /* Put here since we actually need our ramdac to wake up again ;-) */
240 if (nv_output->ramdac != -1 && mode != DPMSModeOff) {
241 pNv->ramdac_active[nv_output->ramdac] = TRUE;
242 nv_output->ramdac_assigned = TRUE;
243 ErrorF("Activating ramdac %d\n", nv_output->ramdac);
246 /* Are we assigned a ramdac already?, else we will be activated during mode set */
247 if (crtc && nv_output->ramdac != -1) {
248 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
250 ErrorF("nv_digital_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
252 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL);
254 case DPMSModeStandby:
255 case DPMSModeSuspend:
257 /* cut the TMDS output */
258 fpcontrol |= 0x20000022;
261 /* disable cutting the TMDS output */
262 fpcontrol &= ~0x20000022;
265 nvWriteRAMDAC(pNv, nv_output->ramdac, NV_RAMDAC_FP_CONTROL, fpcontrol);
268 if (nv_output->ramdac != -1 && mode == DPMSModeOff) {
269 /* We no longer have ramdac, which will be reassigned soon enough */
270 pNv->ramdac_active[nv_output->ramdac] = FALSE;
271 nv_output->ramdac_assigned = FALSE;
272 ErrorF("Deactivating ramdac %d\n", nv_output->ramdac);
276 /* Some registers are not set, because they are zero. */
277 /* This sequence matters, this is how the blob does it */
278 int tmds_regs[] = { 0x2f, 0x2e, 0x33, 0x04, 0x05, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x01, 0x02, 0x2e, 0x2f, 0x04, 0x3a, 0x33, 0x04 };
280 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
282 NVOutputPrivatePtr nv_output = output->driver_private;
283 ScrnInfoPtr pScrn = output->scrn;
284 NVPtr pNv = NVPTR(pScrn);
288 regp = &state->dac_reg[nv_output->ramdac];
289 regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL);
290 regp->test_control = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
291 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL);
292 regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0);
293 regp->debug_1 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_1);
294 regp->debug_2 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_2);
295 regp->sel_clk = NVOutputReadRAMDAC(output, NV_RAMDAC_SEL_CLK);
296 state->config = nvReadFB(pNv, NV_PFB_CFG0);
298 regp->unk_a20 = NVOutputReadRAMDAC(output, NV_RAMDAC_A20);
299 regp->unk_a24 = NVOutputReadRAMDAC(output, NV_RAMDAC_A24);
300 regp->unk_a34 = NVOutputReadRAMDAC(output, NV_RAMDAC_A34);
302 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
304 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
305 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11);
306 } else if (pNv->twoHeads) {
307 regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER);
309 regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC);
311 if (nv_output->type == OUTPUT_DIGITAL)
312 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
313 regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
316 /* The regs below are 0 for non-flatpanels, so you can load and save them */
318 for (i = 0; i < 7; i++) {
319 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
320 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
323 for (i = 0; i < 7; i++) {
324 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
325 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
328 regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
329 regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
330 regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
331 regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
334 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
336 NVOutputPrivatePtr nv_output = output->driver_private;
337 ScrnInfoPtr pScrn = output->scrn;
338 NVPtr pNv = NVPTR(pScrn);
342 regp = &state->dac_reg[nv_output->ramdac];
344 if (nv_output->type == OUTPUT_PANEL) {
345 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_0\n", regp->debug_0);
346 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_1\n", regp->debug_1);
347 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_2\n", regp->debug_2);
348 ErrorF("Writing %08X to RAMDAC_OUTPUT\n", regp->output);
349 ErrorF("Writing %08X to RAMDAC_FP_CONTROL\n", regp->fp_control);
351 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
352 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
353 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
354 NVOutputWriteRAMDAC(output, NV_RAMDAC_SEL_CLK, regp->sel_clk);
355 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
356 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
358 NVOutputWriteRAMDAC(output, NV_RAMDAC_A20, regp->unk_a20);
359 NVOutputWriteRAMDAC(output, NV_RAMDAC_A24, regp->unk_a24);
360 NVOutputWriteRAMDAC(output, NV_RAMDAC_A34, regp->unk_a34);
362 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
363 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
364 } else if (pNv->twoHeads) {
365 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
368 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
369 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, regp->test_control);
370 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
372 if (nv_output->type == OUTPUT_DIGITAL)
373 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
374 NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
377 /* The regs below are 0 for non-flatpanels, so you can load and save them */
379 for (i = 0; i < 7; i++) {
380 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
381 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
384 for (i = 0; i < 7; i++) {
385 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
386 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
389 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
390 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
391 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
392 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
395 /* NOTE: Don't rely on this data for anything other than restoring VT's */
398 nv_output_save (xf86OutputPtr output)
400 ScrnInfoPtr pScrn = output->scrn;
401 NVPtr pNv = NVPTR(pScrn);
402 RIVA_HW_STATE *state;
403 NVOutputPrivatePtr nv_output = output->driver_private;
404 int ramdac_backup = nv_output->ramdac;
406 ErrorF("nv_output_save is called\n");
408 /* This is early init and we have not yet been assigned a ramdac */
409 /* Always choose the prefered ramdac, for consistentcy */
410 /* Assumption: there is always once output that can only run of the primary ramdac */
411 if (nv_output->valid_ramdac & RAMDAC_1) {
412 nv_output->ramdac = 1;
414 nv_output->ramdac = 0;
417 state = &pNv->SavedReg;
419 /* Due to strange mapping of outputs we could have swapped analog and digital */
420 /* So we force save all the registers */
421 nv_output_save_state_ext(output, state, TRUE);
423 /* restore previous state */
424 nv_output->ramdac = ramdac_backup;
428 nv_output_restore (xf86OutputPtr output)
430 ScrnInfoPtr pScrn = output->scrn;
431 NVPtr pNv = NVPTR(pScrn);
432 RIVA_HW_STATE *state;
433 NVOutputPrivatePtr nv_output = output->driver_private;
434 int ramdac_backup = nv_output->ramdac;
436 ErrorF("nv_output_restore is called\n");
438 /* We want consistent mode restoring and the ramdac entry is variable */
439 /* Always choose the prefered ramdac, for consistentcy */
440 /* Assumption: there is always once output that can only run of the primary ramdac */
441 if (nv_output->valid_ramdac & RAMDAC_1) {
442 nv_output->ramdac = 1;
444 nv_output->ramdac = 0;
447 state = &pNv->SavedReg;
449 /* Due to strange mapping of outputs we could have swapped analog and digital */
450 /* So we force load all the registers */
451 nv_output_load_state_ext(output, state, TRUE);
453 /* restore previous state */
454 nv_output->ramdac = ramdac_backup;
458 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
460 NVOutputPrivatePtr nv_output = output->driver_private;
461 ScrnInfoPtr pScrn = output->scrn;
462 NVPtr pNv = NVPTR(pScrn);
464 if (pMode->Flags & V_DBLSCAN)
465 return MODE_NO_DBLESCAN;
467 if (pMode->Clock > 400000 || pMode->Clock < 25000)
468 return MODE_CLOCK_RANGE;
475 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
476 DisplayModePtr adjusted_mode)
478 ErrorF("nv_output_mode_fixup is called\n");
484 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
486 NVOutputPrivatePtr nv_output = output->driver_private;
487 ScrnInfoPtr pScrn = output->scrn;
488 NVPtr pNv = NVPTR(pScrn);
492 regp = &state->dac_reg[nv_output->ramdac];
493 if (pNv->usePanelTweak) {
494 tweak = pNv->PanelTweak;
496 /* begin flat panel hacks */
497 /* This is unfortunate, but some chips need this register
498 tweaked or else you get artifacts where adjacent pixels are
499 swapped. There are no hard rules for what to set here so all
500 we can do is experiment and apply hacks. */
502 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
503 /* At least one NV34 laptop needs this workaround. */
507 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
510 /* end flat panel hacks */
516 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
518 NVOutputPrivatePtr nv_output = output->driver_private;
519 ScrnInfoPtr pScrn = output->scrn;
521 NVPtr pNv = NVPTR(pScrn);
522 NVFBLayout *pLayout = &pNv->CurrentLayout;
523 RIVA_HW_STATE *state, *sv_state;
525 NVOutputRegPtr regp, regp2, savep;
526 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
527 float aspect_ratio, panel_ratio;
528 uint32_t h_scale, v_scale;
531 state = &pNv->ModeReg;
532 regp = &state->dac_reg[nv_output->ramdac];
533 /* The other ramdac */
534 regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
536 sv_state = &pNv->SavedReg;
537 savep = &sv_state->dac_reg[nv_output->ramdac];
539 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
542 /* Do we need to set the native mode or not? */
544 /* We can set the mode as usual if we let the panel scale */
545 regp->fp_horiz_regs[REG_DISP_END] = mode->HDisplay - 1;
546 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->HTotal - 1;
547 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->HDisplay;
548 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->HSyncStart - 1;
549 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->HSyncEnd - 1;
550 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->HSkew;
551 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->HDisplay - 1;
553 regp->fp_vert_regs[REG_DISP_END] = mode->VDisplay - 1;
554 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->VTotal - 1;
555 regp->fp_vert_regs[REG_DISP_CRTC] = mode->VDisplay;
556 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->VSyncStart - 1;
557 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->VSyncEnd - 1;
558 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
559 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->VDisplay - 1;
561 /* For gpu scaling we need the native mode */
562 DisplayModePtr native = nv_output->native_mode;
563 regp->fp_horiz_regs[REG_DISP_END] = native->HDisplay - 1;
564 regp->fp_horiz_regs[REG_DISP_TOTAL] = native->HTotal - 1;
565 regp->fp_horiz_regs[REG_DISP_CRTC] = native->HDisplay;
566 regp->fp_horiz_regs[REG_DISP_SYNC_START] = native->HSyncStart - 1;
567 regp->fp_horiz_regs[REG_DISP_SYNC_END] = native->HSyncEnd - 1;
568 regp->fp_horiz_regs[REG_DISP_VALID_START] = native->HSkew;
569 regp->fp_horiz_regs[REG_DISP_VALID_END] = native->HDisplay - 1;
571 regp->fp_vert_regs[REG_DISP_END] = native->VDisplay - 1;
572 regp->fp_vert_regs[REG_DISP_TOTAL] = native->VTotal - 1;
573 regp->fp_vert_regs[REG_DISP_CRTC] = native->VDisplay;
574 regp->fp_vert_regs[REG_DISP_SYNC_START] = native->VSyncStart - 1;
575 regp->fp_vert_regs[REG_DISP_SYNC_END] = native->VSyncEnd - 1;
576 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
577 regp->fp_vert_regs[REG_DISP_VALID_END] = native->VDisplay - 1;
580 ErrorF("Horizontal:\n");
581 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_END]);
582 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_horiz_regs[REG_DISP_TOTAL]);
583 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_horiz_regs[REG_DISP_CRTC]);
584 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_START]);
585 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_END]);
586 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_START]);
587 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_END]);
589 ErrorF("Vertical:\n");
590 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_END]);
591 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_vert_regs[REG_DISP_TOTAL]);
592 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_vert_regs[REG_DISP_CRTC]);
593 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_START]);
594 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_END]);
595 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_START]);
596 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_END]);
599 /* This register is only used on the primary ramdac */
600 /* The value 0x40000 is not acceptable in text mode, but seems to do no harm in X mode */
601 /* The blob does this often, the exact purpose is not exactly known */
602 if (nv_output->ramdac == 0) {
603 regp->sel_clk = nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) | (1 << 18);
606 /* This seems to be a common mode
607 * bit0: positive vsync
608 * bit4: positive hsync
609 * bit8: enable panel scaling
610 * bit31: sometimes seen on LVDS panels
611 * This must also be set for non-flatpanels
613 regp->fp_control = 0x11100000;
614 if (nv_output->type == OUTPUT_PANEL);
615 regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0xfff00000;
617 /* Deal with vsync/hsync polarity */
618 if (mode->Flags & V_PVSYNC) {
619 regp->fp_control |= (1 << 0);
622 if (mode->Flags & V_PHSYNC) {
623 regp->fp_control |= (1 << 4);
627 ErrorF("Pre-panel scaling\n");
628 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
629 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
630 ErrorF("panel_ratio=%f\n", panel_ratio);
631 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
632 ErrorF("aspect_ratio=%f\n", aspect_ratio);
633 /* Scale factors is the so called 20.12 format, taken from Haiku */
634 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
635 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
636 ErrorF("h_scale=%d\n", h_scale);
637 ErrorF("v_scale=%d\n", v_scale);
639 /* Don't limit last fetched line */
642 /* We want automatic scaling */
645 regp->fp_hvalid_start = 0;
646 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
648 regp->fp_vvalid_start = 0;
649 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
652 ErrorF("Flat panel is doing the scaling.\n");
653 regp->fp_control |= (1 << 8);
655 ErrorF("GPU is doing the scaling.\n");
656 /* GPU scaling happens automaticly at a ratio of 1:33 */
657 /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
658 if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
661 ErrorF("Scaling resolution on a widescreen panel\n");
663 /* Scaling in both directions needs to the same */
666 /* Set a new horizontal scale factor and enable testmode (bit12) */
667 regp->debug_1 = ((h_scale >> 1) & 0xfff) | (1 << 12);
669 diff = nv_output->fpWidth - (((1 << 12) * mode->HDisplay)/h_scale);
670 regp->fp_hvalid_start = diff/2;
671 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
674 /* Same scaling, just for panels with aspect ratio's smaller than 1 */
675 /* This may be broken */
676 if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
679 ErrorF("Scaling resolution on a portrait panel\n");
681 /* Scaling in both directions needs to the same */
684 /* Is this ok, since haiku only does widescreen panels? */
685 regp->debug_1 = ((v_scale >> 1) & 0xfff) | (1 << 12);
687 diff = nv_output->fpHeight - (((1 << 12) * mode->VDisplay)/v_scale);
688 regp->fp_vvalid_start = diff/2;
689 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
693 ErrorF("Post-panel scaling\n");
696 if (pNv->Architecture >= NV_ARCH_10) {
697 /* Bios and blob don't seem to do anything (else) */
698 regp->nv10_cursync = (1<<25);
701 /* These are the common blob values, minus a few fp specific bit's */
702 /* The OR mask is in case the powerdown switch was enabled from the other output */
703 regp->debug_0 |= 0x1101111;
706 /* I am not completely certain, but seems to be set only for dfp's */
707 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED;
710 /* We must ensure that we never disable the wrong tmds control */
711 /* Assumption: one output can only run of ramdac 0 */
712 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)) {
714 regp2->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
716 regp2->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
720 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
722 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
726 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
728 /* This is just a guess, there are probably more registers which need setting */
729 /* But we must start somewhere ;-) */
731 regp->TMDS[0x4] = 0x80;
732 /* Enable crosswired mode */
733 /* As far as i know, this may never be set on ramdac 0 tmds registers (ramdac 1 -> crosswired -> ramdac 0 tmds regs) */
734 /* This will upset the monitor, trust me, i know it :-( */
735 /* Restricting to cards that had this setup at bootup time, until i am certain it's ok to use */
736 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)
737 && pNv->output_info & OUTPUT_1_CROSSWIRED_TMDS) {
738 regp->TMDS[0x4] |= (1 << 3);
742 /* The TMDS game begins */
743 /* A few registers are also programmed on non-tmds monitors */
744 /* At the moment i can't give rationale for these values */
746 regp->TMDS[0x2e] = 0x80;
747 regp->TMDS[0x2f] = 0xff;
748 regp->TMDS[0x33] = 0xfe;
750 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
751 uint32_t pll_setup_control = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SETUP_CONTROL);
752 regp->TMDS[0x2b] = 0x7d;
753 regp->TMDS[0x2c] = 0x0;
754 if (nv_crtc->head == 1) {
755 regp->TMDS[0x2e] = 0x81;
757 regp->TMDS[0x2e] = 0x85;
759 regp->TMDS[0x2f] = 0x21;
760 regp->TMDS[0x30] = 0x0;
761 regp->TMDS[0x31] = 0x0;
762 regp->TMDS[0x32] = 0x0;
763 regp->TMDS[0x33] = 0xf0;
764 regp->TMDS[0x3a] = 0x80;
766 /* Here starts the registers that may cause problems for some */
767 /* This an educated guess */
768 if (pNv->misc_info.reg_c040 & (1 << 10)) {
769 regp->TMDS[0x5] = 0x68;
771 regp->TMDS[0x5] = 0x6e;
774 /* This seems to be related to PLL_SETUP_CONTROL */
775 /* When PLL_SETUP_CONTROL ends with 0x1c, then this value is 0xc1 */
777 if ((pll_setup_control & 0xff) == 0x1c) {
778 regp->TMDS[0x0] = 0xc1;
780 regp->TMDS[0x0] = 0xf1;
783 /* This is also related to PLL_SETUP_CONTROL, exactly how is unknown */
784 if (pll_setup_control == 0) {
785 regp->TMDS[0x1] = 0x0;
787 if (nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) & (1<<12)) {
788 regp->TMDS[0x1] = 0x41;
790 regp->TMDS[0x1] = 0x42;
794 if (pll_setup_control == 0x0) {
795 regp->TMDS[0x2] = 0x90;
797 regp->TMDS[0x2] = 0x89;
799 /* This test is not needed for me although the blob sets this value */
800 /* It may be wrong, but i'm leaving it for historical reference */
801 /*if (pNv->misc_info.reg_c040 == 0x3c0bc003 || pNv->misc_info.reg_c040 == 0x3c0bc333) {
802 regp->TMDS[0x2] = 0xa9;
806 /* Flatpanel support needs at least a NV10 */
808 /* Instead of 1, several other values are also used: 2, 7, 9 */
809 /* The purpose is unknown */
811 regp->dither = 0x00010000;
815 if(pLayout->depth < 24) {
816 bpp = pLayout->depth;
821 /* Kindly borrowed from haiku driver */
822 /* bit4 and bit5 activate indirect mode trough color palette */
823 switch (pLayout->depth) {
826 regp->general = 0x00101130;
830 regp->general = 0x00100130;
834 regp->general = 0x00101100;
838 if (pNv->alphaCursor) {
839 regp->general |= (1<<29);
842 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
844 /* Some values the blob sets */
845 /* This may apply to the real ramdac that is being used (for crosswired situations) */
846 /* Nevertheless, it's unlikely to cause many problems, since the values are equal for both */
848 regp->unk_a24 = 0xfffff;
851 /* Put test control into what seems to be the neutral position */
852 regp->test_control = 0xf0000000;
855 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
859 for (i = 0; i < config->num_output; i++) {
860 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
862 /* is it this output ?? */
863 if (config->output[i] == output)
866 /* it the output connected */
867 if (config->output[i]->crtc == NULL)
871 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
879 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
882 if (nv_crtc->head == 1) {
883 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
885 regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_CRTC1;
888 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);
893 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
894 DisplayModePtr adjusted_mode)
896 ScrnInfoPtr pScrn = output->scrn;
897 NVPtr pNv = NVPTR(pScrn);
898 RIVA_HW_STATE *state;
900 ErrorF("nv_output_mode_set is called\n");
902 state = &pNv->ModeReg;
904 nv_output_mode_set_regs(output, mode);
905 nv_output_load_state_ext(output, state, FALSE);
909 nv_ddc_detect(xf86OutputPtr output)
911 /* no use for shared DDC output */
912 NVOutputPrivatePtr nv_output = output->driver_private;
914 ScrnInfoPtr pScrn = output->scrn;
916 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
920 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
923 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
927 if (nv_output->type == OUTPUT_DIGITAL) {
929 for (i = 0; i < 4; i++) {
930 /* We only look at detailed timings atm */
931 if (ddc_mon->det_mon[i].type != DT)
933 /* Selecting only based on width ok? */
934 if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
935 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
936 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
945 nv_crt_load_detect(xf86OutputPtr output)
947 ScrnInfoPtr pScrn = output->scrn;
948 NVOutputPrivatePtr nv_output = output->driver_private;
949 NVPtr pNv = NVPTR(pScrn);
950 CARD32 reg_output, reg_test_ctrl, temp;
956 /* Restrict to primary ramdac for now, because i get false positives on the secondary */
957 for (ramdac = 0; ramdac < 1; ramdac++) {
958 reg_output = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
959 reg_test_ctrl = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
961 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
963 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
966 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
967 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, temp | 1);
969 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
970 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
971 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
975 present[ramdac] = (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
977 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
978 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
980 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, reg_output);
981 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
984 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d for ramdac0\n", present[0]);
985 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d for ramdac1\n", present[1]);
987 /* Can we only be ramdac0 ?*/
988 if (!(nv_output->valid_ramdac & RAMDAC_1)) {
994 /* What do with a secondary output running of the primary ramdac? */
1000 static xf86OutputStatus
1001 nv_digital_output_detect(xf86OutputPtr output)
1003 NVOutputPrivatePtr nv_output = output->driver_private;
1005 ErrorF("nv_digital_output_detect is called\n");
1007 if (nv_ddc_detect(output))
1008 return XF86OutputStatusConnected;
1010 return XF86OutputStatusDisconnected;
1014 static xf86OutputStatus
1015 nv_analog_output_detect(xf86OutputPtr output)
1017 NVOutputPrivatePtr nv_output = output->driver_private;
1019 ErrorF("nv_analog_output_detect is called\n");
1021 if (nv_ddc_detect(output))
1022 return XF86OutputStatusConnected;
1024 /* This may not work in all cases, but it's the best that can be done */
1025 /* Example: Secondary output running of primary ramdac, what to do? */
1026 if (nv_crt_load_detect(output))
1027 return XF86OutputStatusConnected;
1029 return XF86OutputStatusDisconnected;
1032 static DisplayModePtr
1033 nv_output_get_modes(xf86OutputPtr output)
1035 ScrnInfoPtr pScrn = output->scrn;
1036 NVOutputPrivatePtr nv_output = output->driver_private;
1038 DisplayModePtr ddc_modes;
1040 ErrorF("nv_output_get_modes is called\n");
1042 if (nv_output->pDDCBus == NULL)
1045 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
1047 if (ddc_mon == NULL) {
1048 xf86OutputSetEDID(output, ddc_mon);
1052 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
1053 xf86OutputSetEDID(output, NULL);
1057 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL || nv_output->type == OUTPUT_PANEL)) {
1058 xf86OutputSetEDID(output, NULL);
1062 xf86OutputSetEDID(output, ddc_mon);
1064 ddc_modes = xf86OutputGetEDIDModes (output);
1066 /* Add a native resolution mode that is prefered */
1067 if (nv_output->type == OUTPUT_DIGITAL || nv_output->type == OUTPUT_PANEL) {
1068 DisplayModePtr mode;
1069 /* Reduced blanking should be fine on DVI monitor */
1070 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
1071 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
1072 /* We want the new mode to be prefered */
1073 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
1074 if (mode->type & M_T_PREFERRED) {
1075 mode->type &= ~M_T_PREFERRED;
1078 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
1085 nv_output_destroy (xf86OutputPtr output)
1087 ErrorF("nv_output_destroy is called\n");
1088 if (output->driver_private)
1089 xfree (output->driver_private);
1093 nv_clear_ramdac_from_outputs(xf86OutputPtr output, int ramdac)
1096 ScrnInfoPtr pScrn = output->scrn;
1097 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1098 xf86OutputPtr output2;
1099 NVOutputPrivatePtr nv_output2;
1100 for (i = 0; i < xf86_config->num_output; i++) {
1101 output2 = xf86_config->output[i];
1102 nv_output2 = output2->driver_private;
1103 if (nv_output2->ramdac == ramdac && output != output2) {
1104 nv_output2->ramdac = -1;
1105 nv_output2->ramdac_assigned = FALSE;
1112 nv_output_prepare(xf86OutputPtr output)
1114 ErrorF("nv_output_prepare is called\n");
1115 NVOutputPrivatePtr nv_output = output->driver_private;
1116 ScrnInfoPtr pScrn = output->scrn;
1117 NVPtr pNv = NVPTR(pScrn);
1119 output->funcs->dpms(output, DPMSModeOff);
1121 if (nv_output->ramdac_assigned) {
1122 ErrorF("We already have a ramdac.\n");
1126 /* We need this ramdac, so let's steal it */
1127 if (!(nv_output->valid_ramdac & RAMDAC_1) && pNv->ramdac_active[0]) {
1128 ErrorF("Stealing ramdac0 ;-)\n");
1130 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1131 xf86OutputPtr output2;
1132 NVOutputPrivatePtr nv_output2;
1133 for (i = 0; i < xf86_config->num_output; i++) {
1134 output2 = xf86_config->output[i];
1135 nv_output2 = output2->driver_private;
1136 if (nv_output2->ramdac == 0 && output != output2) {
1137 nv_output2->ramdac = -1;
1138 nv_output2->ramdac_assigned = FALSE;
1142 pNv->ramdac_active[0] = FALSE;
1145 if ((nv_output->valid_ramdac & RAMDAC_0) && !(pNv->ramdac_active[0])) {
1146 ErrorF("Activating ramdac %d\n", 0);
1147 pNv->ramdac_active[0] = TRUE;
1148 nv_output->ramdac = 0;
1149 } else if ((nv_output->valid_ramdac & RAMDAC_1) && !(pNv->ramdac_active[1])) {
1150 ErrorF("Activating ramdac %d\n", 1);
1151 pNv->ramdac_active[1] = TRUE;
1152 nv_output->ramdac = 1;
1155 if (nv_output->ramdac != -1) {
1156 nv_output->ramdac_assigned = TRUE;
1157 nv_clear_ramdac_from_outputs(output, nv_output->ramdac);
1162 nv_output_commit(xf86OutputPtr output)
1164 ErrorF("nv_output_commit is called\n");
1166 output->funcs->dpms(output, DPMSModeOn);
1169 static const xf86OutputFuncsRec nv_analog_output_funcs = {
1170 .dpms = nv_analog_output_dpms,
1171 .save = nv_output_save,
1172 .restore = nv_output_restore,
1173 .mode_valid = nv_output_mode_valid,
1174 .mode_fixup = nv_output_mode_fixup,
1175 .mode_set = nv_output_mode_set,
1176 .detect = nv_analog_output_detect,
1177 .get_modes = nv_output_get_modes,
1178 .destroy = nv_output_destroy,
1179 .prepare = nv_output_prepare,
1180 .commit = nv_output_commit,
1183 static const xf86OutputFuncsRec nv_digital_output_funcs = {
1184 .dpms = nv_digital_output_dpms,
1185 .save = nv_output_save,
1186 .restore = nv_output_restore,
1187 .mode_valid = nv_output_mode_valid,
1188 .mode_fixup = nv_output_mode_fixup,
1189 .mode_set = nv_output_mode_set,
1190 .detect = nv_digital_output_detect,
1191 .get_modes = nv_output_get_modes,
1192 .destroy = nv_output_destroy,
1193 .prepare = nv_output_prepare,
1194 .commit = nv_output_commit,
1197 static int nv_lvds_output_mode_valid
1198 (xf86OutputPtr output, DisplayModePtr pMode)
1200 NVOutputPrivatePtr nv_output = output->driver_private;
1202 /* No modes > panel's native res */
1203 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
1206 return nv_output_mode_valid(output, pMode);
1210 nv_lvds_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
1212 NVOutputPrivatePtr nv_output = output->driver_private;
1214 adjusted_mode->HDisplay = nv_output->native_mode->HDisplay;
1215 adjusted_mode->HSyncStart = nv_output->native_mode->HSyncStart;
1216 adjusted_mode->HSyncEnd = nv_output->native_mode->HSyncEnd;
1217 adjusted_mode->HTotal = nv_output->native_mode->HTotal;
1218 adjusted_mode->VDisplay = nv_output->native_mode->VDisplay;
1219 adjusted_mode->VSyncStart = nv_output->native_mode->VSyncStart;
1220 adjusted_mode->VSyncEnd = nv_output->native_mode->VSyncEnd;
1221 adjusted_mode->VTotal = nv_output->native_mode->VTotal;
1222 adjusted_mode->Clock = nv_output->native_mode->Clock;
1224 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
1229 static xf86OutputStatus
1230 nv_lvds_output_detect(xf86OutputPtr output)
1232 return XF86OutputStatusConnected;
1235 static DisplayModePtr
1236 nv_lvds_output_get_modes(xf86OutputPtr output)
1238 ScrnInfoPtr pScrn = output->scrn;
1239 NVPtr pNv = NVPTR(pScrn);
1240 NVOutputPrivatePtr nv_output = output->driver_private;
1241 DisplayModePtr modes;
1243 /* this is currently broken, as this code path has not run nv_ddc_detect
1244 * to get fpWidth / fpHeight. That code should probably be moved into
1245 * nv_output_get_modes anyway
1246 if (modes = nv_output_get_modes(output))
1249 /* it is possible to set up a mode from what we can read from the
1250 * RAMDAC registers, but if we can't read the BIOS table correctly
1251 * we might as well give up */
1252 if (pNv->fp_native_mode == NULL)
1255 nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1256 nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1257 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1259 if (pNv->fp_native_mode->HDisplay != nv_output->fpWidth ||
1260 pNv->fp_native_mode->VDisplay != nv_output->fpHeight) {
1261 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1262 "Panel size mismatch; ignoring RAMDAC\n");
1263 nv_output->fpWidth = pNv->fp_native_mode->HDisplay;
1264 nv_output->fpHeight = pNv->fp_native_mode->VDisplay;
1267 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %lu x %lu\n",
1268 nv_output->fpWidth, nv_output->fpHeight);
1270 nv_output->native_mode = xf86DuplicateMode(pNv->fp_native_mode);
1272 return xf86DuplicateMode(pNv->fp_native_mode);
1275 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1276 .dpms = nv_lvds_output_dpms,
1277 .save = nv_output_save,
1278 .restore = nv_output_restore,
1279 .mode_valid = nv_lvds_output_mode_valid,
1280 .mode_fixup = nv_lvds_output_mode_fixup,
1281 .mode_set = nv_output_mode_set,
1282 .detect = nv_lvds_output_detect,
1283 .get_modes = nv_lvds_output_get_modes,
1284 .destroy = nv_output_destroy,
1285 .prepare = nv_output_prepare,
1286 .commit = nv_output_commit,
1289 static void nv_add_analog_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dvi_pair)
1291 NVPtr pNv = NVPTR(pScrn);
1292 xf86OutputPtr output;
1293 NVOutputPrivatePtr nv_output;
1294 char outputname[20];
1295 int crtc_mask = (1<<0);
1297 Bool create_output = TRUE;
1299 sprintf(outputname, "Analog-%d", pNv->analog_count);
1300 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1305 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1306 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1308 nv_output->type = OUTPUT_ANALOG;
1311 * bit0: RAMDAC_0 valid
1312 * bit1: RAMDAC_1 valid
1313 * So lowest order has highest priority.
1315 nv_output->valid_ramdac = order + 1;
1317 /* Restricting this will cause a full mode set when trying to squeeze in the primary mode */
1318 if (nv_output->valid_ramdac & RAMDAC_1)
1319 crtc_mask |= (1<<1);
1321 if (!create_output) {
1326 /* Delay creation of output until we actually know we want it */
1327 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1331 output->driver_private = nv_output;
1333 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1335 nv_output->ramdac = -1;
1337 output->possible_crtcs = crtc_mask;
1338 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1340 pNv->analog_count++;
1344 static void nv_add_digital_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dual_dvi, int lvds)
1346 NVPtr pNv = NVPTR(pScrn);
1347 xf86OutputPtr output;
1348 NVOutputPrivatePtr nv_output;
1349 char outputname[20];
1350 int crtc_mask = (1<<0);
1351 Bool create_output = TRUE;
1352 int index = i2c_index;
1354 sprintf(outputname, "Digital-%d", pNv->digital_count);
1355 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1361 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1362 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1364 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1367 * bit0: RAMDAC_0 valid
1368 * bit1: RAMDAC_1 valid
1369 * So lowest order has highest priority.
1371 nv_output->valid_ramdac = order + 1;
1373 /* Restricting this will cause a full mode set when trying to squeeze in the primary mode */
1374 if (nv_output->valid_ramdac & RAMDAC_1)
1375 crtc_mask |= (1<<1);
1378 nv_output->type = OUTPUT_PANEL;
1379 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1380 create_output = FALSE;
1382 nv_output->type = OUTPUT_DIGITAL;
1385 if (!create_output) {
1390 /* Delay creation of output until we are certain is desirable */
1392 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1394 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
1398 output->driver_private = nv_output;
1400 nv_output->ramdac = -1;
1402 output->possible_crtcs = crtc_mask;
1403 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1405 pNv->digital_count++;
1408 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1410 unsigned char type, i2c_index, or;
1411 NVPtr pNv = NVPTR(pScrn);
1413 int num_digital = 0;
1414 Bool dual_dvi = FALSE;
1415 Bool dvi_pair = FALSE;
1417 /* check how many TMDS ports there are */
1418 if (pNv->dcb_table.entries) {
1419 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1420 type = pNv->dcb_table.connection[i] & 0xf;
1421 i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1423 if (type == 2 && i2c_index != 0xf) {
1429 if (num_digital > 1) {
1433 /* It's time to gather some information */
1435 /* Being slaved indicates we're a flatpanel (or tv-out) */
1436 if (NVReadVGA0(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1437 pNv->output_info |= OUTPUT_0_SLAVED;
1439 if (NVReadVGA1(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1440 pNv->output_info |= OUTPUT_1_SLAVED;
1442 /* This is an educated guess */
1443 if (NVReadTMDS(pNv, 0, 0x4) & (1 << 3)) {
1444 pNv->output_info |= OUTPUT_0_CROSSWIRED_TMDS;
1446 if (NVReadTMDS(pNv, 1, 0x4) & (1 << 3)) {
1447 pNv->output_info |= OUTPUT_1_CROSSWIRED_TMDS;
1450 if (NVReadTMDS(pNv, 0, 0x4) & (1 << 0)) {
1451 pNv->output_info |= OUTPUT_0_LVDS;
1453 if (NVReadTMDS(pNv, 1, 0x4) & (1 << 0)) {
1454 pNv->output_info |= OUTPUT_1_LVDS;
1457 /* we setup the outputs up from the BIOS table */
1458 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1459 type = pNv->dcb_table.connection[i] & 0xf;
1460 i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1461 or = ffs((pNv->dcb_table.connection[i] >> 24) & 0xf) - 1;
1464 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);
1467 case OUTPUT_ANALOG: /* Analogue VGA */
1468 nv_add_analog_output(pScrn, or, i2c_index, dvi_pair);
1471 case OUTPUT_DIGITAL: /* TMDS */
1473 nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 0);
1475 case OUTPUT_PANEL: /* LVDS */
1476 nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 1);
1485 void NvSetupOutputs(ScrnInfoPtr pScrn)
1488 NVPtr pNv = NVPTR(pScrn);
1490 pNv->Television = FALSE;
1492 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1493 NvDCBSetupOutputs(pScrn);
1496 xf86OutputPtr output;
1497 NVOutputPrivatePtr nv_output;
1500 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
1504 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
1506 xf86OutputDestroy(output);
1510 output->driver_private = nv_output;
1511 nv_output->type = output_type;
1513 output->possible_crtcs = i ? 1 : crtc_mask;
1518 #endif /* ENABLE_RANDR12 */
1520 /*************************************************************************** \
1522 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1524 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1525 |* international laws. Users and possessors of this source code are *|
1526 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1527 |* use this code in individual and commercial software. *|
1529 |* Any use of this source code must include, in the user documenta- *|
1530 |* tion and internal comments to the code, notices to the end user *|
1533 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1535 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1536 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1537 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1538 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1539 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1540 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1541 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1542 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1543 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1544 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1545 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1547 |* U.S. Government End Users. This source code is a "commercial *|
1548 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1549 |* consisting of "commercial computer software" and "commercial *|
1550 |* computer software documentation," as such terms are used in *|
1551 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1552 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1553 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1554 |* all U.S. Government End Users acquire the source code with only *|
1555 |* those rights set forth herein. *|
1557 \***************************************************************************/