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 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
312 regp->TMDS[tmds_regs[i]] = NVOutputReadTMDS(output, tmds_regs[i]);
315 /* The regs below are 0 for non-flatpanels, so you can load and save them */
317 for (i = 0; i < 7; i++) {
318 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
319 regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
322 for (i = 0; i < 7; i++) {
323 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
324 regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg);
327 regp->fp_hvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_START);
328 regp->fp_hvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HVALID_END);
329 regp->fp_vvalid_start = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_START);
330 regp->fp_vvalid_end = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VVALID_END);
333 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
335 NVOutputPrivatePtr nv_output = output->driver_private;
336 ScrnInfoPtr pScrn = output->scrn;
337 NVPtr pNv = NVPTR(pScrn);
341 regp = &state->dac_reg[nv_output->ramdac];
343 if (nv_output->type == OUTPUT_PANEL) {
344 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_0\n", regp->debug_0);
345 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_1\n", regp->debug_1);
346 ErrorF("Writing %08X to RAMDAC_FP_DEBUG_2\n", regp->debug_2);
347 ErrorF("Writing %08X to RAMDAC_OUTPUT\n", regp->output);
348 ErrorF("Writing %08X to RAMDAC_FP_CONTROL\n", regp->fp_control);
350 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0);
351 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_1, regp->debug_1);
352 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_2, regp->debug_2);
353 NVOutputWriteRAMDAC(output, NV_RAMDAC_SEL_CLK, regp->sel_clk);
354 NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
355 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control);
357 NVOutputWriteRAMDAC(output, NV_RAMDAC_A20, regp->unk_a20);
358 NVOutputWriteRAMDAC(output, NV_RAMDAC_A24, regp->unk_a24);
359 NVOutputWriteRAMDAC(output, NV_RAMDAC_A34, regp->unk_a34);
361 if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
362 NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither);
363 } else if (pNv->twoHeads) {
364 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither);
367 NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general);
368 NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, regp->test_control);
369 NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
371 for (i = 0; i < sizeof(tmds_regs)/sizeof(tmds_regs[0]); i++) {
372 NVOutputWriteTMDS(output, tmds_regs[i], regp->TMDS[tmds_regs[i]]);
375 /* The regs below are 0 for non-flatpanels, so you can load and save them */
377 for (i = 0; i < 7; i++) {
378 uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4);
379 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]);
382 for (i = 0; i < 7; i++) {
383 uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4);
384 NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]);
387 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_START, regp->fp_hvalid_start);
388 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HVALID_END, regp->fp_hvalid_end);
389 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_START, regp->fp_vvalid_start);
390 NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_VVALID_END, regp->fp_vvalid_end);
393 /* NOTE: Don't rely on this data for anything other than restoring VT's */
396 nv_output_save (xf86OutputPtr output)
398 ScrnInfoPtr pScrn = output->scrn;
399 NVPtr pNv = NVPTR(pScrn);
400 RIVA_HW_STATE *state;
401 NVOutputPrivatePtr nv_output = output->driver_private;
402 int ramdac_backup = nv_output->ramdac;
404 ErrorF("nv_output_save is called\n");
406 /* This is early init and we have not yet been assigned a ramdac */
407 /* Always choose the prefered ramdac, for consistentcy */
408 /* Assumption: there is always once output that can only run of the primary ramdac */
409 if (nv_output->valid_ramdac & RAMDAC_1) {
410 nv_output->ramdac = 1;
412 nv_output->ramdac = 0;
415 state = &pNv->SavedReg;
417 /* Due to strange mapping of outputs we could have swapped analog and digital */
418 /* So we force save all the registers */
419 nv_output_save_state_ext(output, state, TRUE);
421 /* restore previous state */
422 nv_output->ramdac = ramdac_backup;
426 nv_output_restore (xf86OutputPtr output)
428 ScrnInfoPtr pScrn = output->scrn;
429 NVPtr pNv = NVPTR(pScrn);
430 RIVA_HW_STATE *state;
431 NVOutputPrivatePtr nv_output = output->driver_private;
432 int ramdac_backup = nv_output->ramdac;
434 ErrorF("nv_output_restore is called\n");
436 /* We want consistent mode restoring and the ramdac entry is variable */
437 /* Always choose the prefered ramdac, for consistentcy */
438 /* Assumption: there is always once output that can only run of the primary ramdac */
439 if (nv_output->valid_ramdac & RAMDAC_1) {
440 nv_output->ramdac = 1;
442 nv_output->ramdac = 0;
445 state = &pNv->SavedReg;
447 /* Due to strange mapping of outputs we could have swapped analog and digital */
448 /* So we force load all the registers */
449 nv_output_load_state_ext(output, state, TRUE);
451 /* restore previous state */
452 nv_output->ramdac = ramdac_backup;
456 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
458 NVOutputPrivatePtr nv_output = output->driver_private;
459 ScrnInfoPtr pScrn = output->scrn;
460 NVPtr pNv = NVPTR(pScrn);
462 if (pMode->Flags & V_DBLSCAN)
463 return MODE_NO_DBLESCAN;
465 if (pMode->Clock > 400000 || pMode->Clock < 25000)
466 return MODE_CLOCK_RANGE;
473 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
474 DisplayModePtr adjusted_mode)
476 ErrorF("nv_output_mode_fixup is called\n");
482 nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state)
484 NVOutputPrivatePtr nv_output = output->driver_private;
485 ScrnInfoPtr pScrn = output->scrn;
486 NVPtr pNv = NVPTR(pScrn);
490 regp = &state->dac_reg[nv_output->ramdac];
491 if (pNv->usePanelTweak) {
492 tweak = pNv->PanelTweak;
494 /* begin flat panel hacks */
495 /* This is unfortunate, but some chips need this register
496 tweaked or else you get artifacts where adjacent pixels are
497 swapped. There are no hard rules for what to set here so all
498 we can do is experiment and apply hacks. */
500 if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) {
501 /* At least one NV34 laptop needs this workaround. */
505 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
508 /* end flat panel hacks */
514 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode)
516 NVOutputPrivatePtr nv_output = output->driver_private;
517 ScrnInfoPtr pScrn = output->scrn;
519 NVPtr pNv = NVPTR(pScrn);
520 NVFBLayout *pLayout = &pNv->CurrentLayout;
521 RIVA_HW_STATE *state, *sv_state;
523 NVOutputRegPtr regp, regp2, savep;
524 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
525 float aspect_ratio, panel_ratio;
526 uint32_t h_scale, v_scale;
529 state = &pNv->ModeReg;
530 regp = &state->dac_reg[nv_output->ramdac];
531 /* The other ramdac */
532 regp2 = &state->dac_reg[(~(nv_output->ramdac)) & 1];
534 sv_state = &pNv->SavedReg;
535 savep = &sv_state->dac_reg[nv_output->ramdac];
537 if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) {
540 /* Do we need to set the native mode or not? */
542 /* We can set the mode as usual if we let the panel scale */
543 regp->fp_horiz_regs[REG_DISP_END] = mode->HDisplay - 1;
544 regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->HTotal - 1;
545 regp->fp_horiz_regs[REG_DISP_CRTC] = mode->HDisplay;
546 regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->HSyncStart - 1;
547 regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->HSyncEnd - 1;
548 regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->HSkew;
549 regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->HDisplay - 1;
551 regp->fp_vert_regs[REG_DISP_END] = mode->VDisplay - 1;
552 regp->fp_vert_regs[REG_DISP_TOTAL] = mode->VTotal - 1;
553 regp->fp_vert_regs[REG_DISP_CRTC] = mode->VDisplay;
554 regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->VSyncStart - 1;
555 regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->VSyncEnd - 1;
556 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
557 regp->fp_vert_regs[REG_DISP_VALID_END] = mode->VDisplay - 1;
559 /* For gpu scaling we need the native mode */
560 DisplayModePtr native = nv_output->native_mode;
561 regp->fp_horiz_regs[REG_DISP_END] = native->HDisplay - 1;
562 regp->fp_horiz_regs[REG_DISP_TOTAL] = native->HTotal - 1;
563 regp->fp_horiz_regs[REG_DISP_CRTC] = native->HDisplay;
564 regp->fp_horiz_regs[REG_DISP_SYNC_START] = native->HSyncStart - 1;
565 regp->fp_horiz_regs[REG_DISP_SYNC_END] = native->HSyncEnd - 1;
566 regp->fp_horiz_regs[REG_DISP_VALID_START] = native->HSkew;
567 regp->fp_horiz_regs[REG_DISP_VALID_END] = native->HDisplay - 1;
569 regp->fp_vert_regs[REG_DISP_END] = native->VDisplay - 1;
570 regp->fp_vert_regs[REG_DISP_TOTAL] = native->VTotal - 1;
571 regp->fp_vert_regs[REG_DISP_CRTC] = native->VDisplay;
572 regp->fp_vert_regs[REG_DISP_SYNC_START] = native->VSyncStart - 1;
573 regp->fp_vert_regs[REG_DISP_SYNC_END] = native->VSyncEnd - 1;
574 regp->fp_vert_regs[REG_DISP_VALID_START] = 0;
575 regp->fp_vert_regs[REG_DISP_VALID_END] = native->VDisplay - 1;
578 ErrorF("Horizontal:\n");
579 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_END]);
580 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_horiz_regs[REG_DISP_TOTAL]);
581 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_horiz_regs[REG_DISP_CRTC]);
582 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_START]);
583 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_SYNC_END]);
584 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_START]);
585 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_horiz_regs[REG_DISP_VALID_END]);
587 ErrorF("Vertical:\n");
588 ErrorF("REG_DISP_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_END]);
589 ErrorF("REG_DISP_TOTAL: 0x%X\n", regp->fp_vert_regs[REG_DISP_TOTAL]);
590 ErrorF("REG_DISP_CRTC: 0x%X\n", regp->fp_vert_regs[REG_DISP_CRTC]);
591 ErrorF("REG_DISP_SYNC_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_START]);
592 ErrorF("REG_DISP_SYNC_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_SYNC_END]);
593 ErrorF("REG_DISP_VALID_START: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_START]);
594 ErrorF("REG_DISP_VALID_END: 0x%X\n", regp->fp_vert_regs[REG_DISP_VALID_END]);
597 /* This register is only used on the primary ramdac */
598 /* The value 0x40000 is not acceptable in text mode, but seems to do no harm in X mode */
599 /* The blob does this often, the exact purpose is not exactly known */
600 if (nv_output->ramdac == 0) {
601 regp->sel_clk = nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) | (1 << 18);
604 /* This seems to be a common mode
605 * bit0: positive vsync
606 * bit4: positive hsync
607 * bit8: enable panel scaling
608 * This must also be set for non-flatpanels
610 regp->fp_control = 0x11100000;
612 /* Deal with vsync/hsync polarity */
613 if (mode->Flags & V_PVSYNC) {
614 regp->fp_control |= (1 << 0);
617 if (mode->Flags & V_PHSYNC) {
618 regp->fp_control |= (1 << 4);
622 ErrorF("Pre-panel scaling\n");
623 ErrorF("panel-size:%dx%d\n", nv_output->fpWidth, nv_output->fpHeight);
624 panel_ratio = (nv_output->fpWidth)/(float)(nv_output->fpHeight);
625 ErrorF("panel_ratio=%f\n", panel_ratio);
626 aspect_ratio = (mode->HDisplay)/(float)(mode->VDisplay);
627 ErrorF("aspect_ratio=%f\n", aspect_ratio);
628 /* Scale factors is the so called 20.12 format, taken from Haiku */
629 h_scale = ((1 << 12) * mode->HDisplay)/nv_output->fpWidth;
630 v_scale = ((1 << 12) * mode->VDisplay)/nv_output->fpHeight;
631 ErrorF("h_scale=%d\n", h_scale);
632 ErrorF("v_scale=%d\n", v_scale);
634 /* Don't limit last fetched line */
637 /* We want automatic scaling */
640 regp->fp_hvalid_start = 0;
641 regp->fp_hvalid_end = (nv_output->fpWidth - 1);
643 regp->fp_vvalid_start = 0;
644 regp->fp_vvalid_end = (nv_output->fpHeight - 1);
647 ErrorF("Flat panel is doing the scaling.\n");
648 regp->fp_control |= (1 << 8);
650 ErrorF("GPU is doing the scaling.\n");
651 /* GPU scaling happens automaticly at a ratio of 1:33 */
652 /* A 1280x1024 panel has a ratio of 1:25, we don't want to scale that at 4:3 resolutions */
653 if (h_scale != (1 << 12) && (panel_ratio > (aspect_ratio + 0.10))) {
656 ErrorF("Scaling resolution on a widescreen panel\n");
658 /* Scaling in both directions needs to the same */
661 /* Set a new horizontal scale factor and enable testmode (bit12) */
662 regp->debug_1 = ((h_scale >> 1) & 0xfff) | (1 << 12);
664 diff = nv_output->fpWidth - (((1 << 12) * mode->HDisplay)/h_scale);
665 regp->fp_hvalid_start = diff/2;
666 regp->fp_hvalid_end = nv_output->fpWidth - (diff/2) - 1;
669 /* Same scaling, just for panels with aspect ratio's smaller than 1 */
670 /* This may be broken */
671 if (v_scale != (1 << 12) && (panel_ratio < (aspect_ratio - 0.10))) {
674 ErrorF("Scaling resolution on a portrait panel\n");
676 /* Scaling in both directions needs to the same */
679 /* Is this ok, since haiku only does widescreen panels? */
680 regp->debug_1 = ((v_scale >> 1) & 0xfff) | (1 << 12);
682 diff = nv_output->fpHeight - (((1 << 12) * mode->VDisplay)/v_scale);
683 regp->fp_vvalid_start = diff/2;
684 regp->fp_vvalid_end = nv_output->fpHeight - (diff/2) - 1;
688 ErrorF("Post-panel scaling\n");
691 if (pNv->Architecture >= NV_ARCH_10) {
692 /* Bios and blob don't seem to do anything (else) */
693 regp->nv10_cursync = (1<<25);
696 /* These are the common blob values, minus a few fp specific bit's */
697 /* The OR mask is in case the powerdown switch was enabled from the other output */
698 regp->debug_0 |= 0x1101111;
701 /* I am not completely certain, but seems to be set only for dfp's */
702 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED;
705 /* We must ensure that we never disable the wrong tmds control */
706 /* Assumption: one output can only run of ramdac 0 */
707 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)) {
709 regp2->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
711 regp2->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
715 regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
717 regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH;
721 ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0);
723 /* This is just a guess, there are probably more registers which need setting */
724 /* But we must start somewhere ;-) */
726 regp->TMDS[0x4] = 0x80;
727 /* Enable crosswired mode */
728 /* As far as i know, this may never be set on ramdac 0 tmds registers (ramdac 1 -> crosswired -> ramdac 0 tmds regs) */
729 /* This will upset the monitor, trust me, i know it :-( */
730 /* Restricting to cards that had this setup at bootup time, until i am certain it's ok to use */
731 if ((nv_output->ramdac == 0) && (nv_output->valid_ramdac & RAMDAC_1)
732 && pNv->output_info & OUTPUT_1_CROSSWIRED_TMDS) {
733 regp->TMDS[0x4] |= (1 << 3);
737 /* The TMDS game begins */
738 /* A few registers are also programmed on non-tmds monitors */
739 /* At the moment i can't give rationale for these values */
741 regp->TMDS[0x2e] = 0x80;
742 regp->TMDS[0x2f] = 0xff;
743 regp->TMDS[0x33] = 0xfe;
745 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
746 uint32_t pll_setup_control = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SETUP_CONTROL);
747 regp->TMDS[0x2b] = 0x7d;
748 regp->TMDS[0x2c] = 0x0;
749 if (nv_crtc->head == 1) {
750 regp->TMDS[0x2e] = 0x81;
752 regp->TMDS[0x2e] = 0x85;
754 regp->TMDS[0x2f] = 0x21;
755 regp->TMDS[0x30] = 0x0;
756 regp->TMDS[0x31] = 0x0;
757 regp->TMDS[0x32] = 0x0;
758 regp->TMDS[0x33] = 0xf0;
759 regp->TMDS[0x3a] = 0x80;
761 /* Here starts the registers that may cause problems for some */
762 /* This an educated guess */
763 if (pNv->misc_info.reg_c040 & (1 << 10)) {
764 regp->TMDS[0x5] = 0x68;
766 regp->TMDS[0x5] = 0x6e;
769 /* This seems to be related to PLL_SETUP_CONTROL */
770 /* When PLL_SETUP_CONTROL ends with 0x1c, then this value is 0xc1 */
772 if ((pll_setup_control & 0xff) == 0x1c) {
773 regp->TMDS[0x0] = 0xc1;
775 regp->TMDS[0x0] = 0xf1;
778 /* This is also related to PLL_SETUP_CONTROL, exactly how is unknown */
779 if (pll_setup_control == 0) {
780 regp->TMDS[0x1] = 0x0;
782 if (nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK) & (1<<12)) {
783 regp->TMDS[0x1] = 0x41;
785 regp->TMDS[0x1] = 0x42;
789 if (pll_setup_control == 0x0) {
790 regp->TMDS[0x2] = 0x90;
792 regp->TMDS[0x2] = 0x89;
794 /* This test is not needed for me although the blob sets this value */
795 /* It may be wrong, but i'm leaving it for historical reference */
796 /*if (pNv->misc_info.reg_c040 == 0x3c0bc003 || pNv->misc_info.reg_c040 == 0x3c0bc333) {
797 regp->TMDS[0x2] = 0xa9;
801 /* Flatpanel support needs at least a NV10 */
803 /* Instead of 1, several other values are also used: 2, 7, 9 */
804 /* The purpose is unknown */
806 regp->dither = 0x00010000;
810 if(pLayout->depth < 24) {
811 bpp = pLayout->depth;
816 /* Kindly borrowed from haiku driver */
817 /* bit4 and bit5 activate indirect mode trough color palette */
818 switch (pLayout->depth) {
821 regp->general = 0x00101130;
825 regp->general = 0x00100130;
829 regp->general = 0x00101100;
833 if (pNv->alphaCursor) {
834 regp->general |= (1<<29);
837 regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
839 /* Some values the blob sets */
840 /* This may apply to the real ramdac that is being used (for crosswired situations) */
841 /* Nevertheless, it's unlikely to cause many problems, since the values are equal for both */
843 regp->unk_a24 = 0xfffff;
846 /* Put test control into what seems to be the neutral position */
847 regp->test_control = 0xf0000000;
850 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
854 for (i = 0; i < config->num_output; i++) {
855 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
857 /* is it this output ?? */
858 if (config->output[i] == output)
861 /* it the output connected */
862 if (config->output[i]->crtc == NULL)
866 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
874 regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE;
877 if (nv_crtc->head == 1) {
878 regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
880 regp->output &= ~NV_RAMDAC_OUTPUT_SELECT_CRTC1;
883 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);
888 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
889 DisplayModePtr adjusted_mode)
891 ScrnInfoPtr pScrn = output->scrn;
892 NVPtr pNv = NVPTR(pScrn);
893 RIVA_HW_STATE *state;
895 ErrorF("nv_output_mode_set is called\n");
897 state = &pNv->ModeReg;
899 nv_output_mode_set_regs(output, mode);
900 nv_output_load_state_ext(output, state, FALSE);
904 nv_ddc_detect(xf86OutputPtr output)
906 /* no use for shared DDC output */
907 NVOutputPrivatePtr nv_output = output->driver_private;
909 ScrnInfoPtr pScrn = output->scrn;
911 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
915 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
918 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
922 if (nv_output->type == OUTPUT_DIGITAL) {
924 for (i = 0; i < 4; i++) {
925 /* We only look at detailed timings atm */
926 if (ddc_mon->det_mon[i].type != DT)
928 /* Selecting only based on width ok? */
929 if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
930 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
931 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
940 nv_crt_load_detect(xf86OutputPtr output)
942 ScrnInfoPtr pScrn = output->scrn;
943 NVOutputPrivatePtr nv_output = output->driver_private;
944 NVPtr pNv = NVPTR(pScrn);
945 CARD32 reg_output, reg_test_ctrl, temp;
951 /* Restrict to primary ramdac for now, because i get false positives on the secondary */
952 for (ramdac = 0; ramdac < 1; ramdac++) {
953 reg_output = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
954 reg_test_ctrl = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
956 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
958 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
961 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT);
962 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, temp | 1);
964 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_DATA, 0x94050140);
965 temp = nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL);
966 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
970 present[ramdac] = (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
972 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
973 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
975 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_OUTPUT, reg_output);
976 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
979 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d for ramdac0\n", present[0]);
980 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d for ramdac1\n", present[1]);
982 /* Can we only be ramdac0 ?*/
983 if (!(nv_output->valid_ramdac & RAMDAC_1)) {
989 /* What do with a secondary output running of the primary ramdac? */
995 static xf86OutputStatus
996 nv_digital_output_detect(xf86OutputPtr output)
998 NVOutputPrivatePtr nv_output = output->driver_private;
1000 ErrorF("nv_digital_output_detect is called\n");
1002 if (nv_ddc_detect(output))
1003 return XF86OutputStatusConnected;
1005 return XF86OutputStatusDisconnected;
1009 static xf86OutputStatus
1010 nv_analog_output_detect(xf86OutputPtr output)
1012 NVOutputPrivatePtr nv_output = output->driver_private;
1014 ErrorF("nv_analog_output_detect is called\n");
1016 if (nv_ddc_detect(output))
1017 return XF86OutputStatusConnected;
1019 /* This may not work in all cases, but it's the best that can be done */
1020 /* Example: Secondary output running of primary ramdac, what to do? */
1021 if (nv_crt_load_detect(output))
1022 return XF86OutputStatusConnected;
1024 return XF86OutputStatusDisconnected;
1027 static DisplayModePtr
1028 nv_output_get_modes(xf86OutputPtr output)
1030 ScrnInfoPtr pScrn = output->scrn;
1031 NVOutputPrivatePtr nv_output = output->driver_private;
1033 DisplayModePtr ddc_modes;
1035 ErrorF("nv_output_get_modes is called\n");
1037 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
1039 if (ddc_mon == NULL) {
1040 xf86OutputSetEDID(output, ddc_mon);
1044 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) {
1045 xf86OutputSetEDID(output, NULL);
1049 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) {
1050 xf86OutputSetEDID(output, NULL);
1054 xf86OutputSetEDID(output, ddc_mon);
1056 ddc_modes = xf86OutputGetEDIDModes (output);
1058 /* Add a native resolution mode that is prefered */
1059 if (nv_output->type == OUTPUT_DIGITAL) {
1060 DisplayModePtr mode;
1061 /* Reduced blanking should be fine on DVI monitor */
1062 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
1063 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
1064 /* We want the new mode to be prefered */
1065 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
1066 if (mode->type & M_T_PREFERRED) {
1067 mode->type &= ~M_T_PREFERRED;
1070 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
1077 nv_output_destroy (xf86OutputPtr output)
1079 ErrorF("nv_output_destroy is called\n");
1080 if (output->driver_private)
1081 xfree (output->driver_private);
1085 nv_clear_ramdac_from_outputs(xf86OutputPtr output, int ramdac)
1088 ScrnInfoPtr pScrn = output->scrn;
1089 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1090 xf86OutputPtr output2;
1091 NVOutputPrivatePtr nv_output2;
1092 for (i = 0; i < xf86_config->num_output; i++) {
1093 output2 = xf86_config->output[i];
1094 nv_output2 = output2->driver_private;
1095 if (nv_output2->ramdac == ramdac && output != output2) {
1096 nv_output2->ramdac = -1;
1097 nv_output2->ramdac_assigned = FALSE;
1104 nv_output_prepare(xf86OutputPtr output)
1106 ErrorF("nv_output_prepare is called\n");
1107 NVOutputPrivatePtr nv_output = output->driver_private;
1108 ScrnInfoPtr pScrn = output->scrn;
1109 NVPtr pNv = NVPTR(pScrn);
1111 output->funcs->dpms(output, DPMSModeOff);
1113 if (nv_output->ramdac_assigned) {
1114 ErrorF("We already have a ramdac.\n");
1118 /* We need this ramdac, so let's steal it */
1119 if (!(nv_output->valid_ramdac & RAMDAC_1) && pNv->ramdac_active[0]) {
1120 ErrorF("Stealing ramdac0 ;-)\n");
1122 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1123 xf86OutputPtr output2;
1124 NVOutputPrivatePtr nv_output2;
1125 for (i = 0; i < xf86_config->num_output; i++) {
1126 output2 = xf86_config->output[i];
1127 nv_output2 = output2->driver_private;
1128 if (nv_output2->ramdac == 0 && output != output2) {
1129 nv_output2->ramdac = -1;
1130 nv_output2->ramdac_assigned = FALSE;
1134 pNv->ramdac_active[0] = FALSE;
1137 if ((nv_output->valid_ramdac & RAMDAC_0) && !(pNv->ramdac_active[0])) {
1138 ErrorF("Activating ramdac %d\n", 0);
1139 pNv->ramdac_active[0] = TRUE;
1140 nv_output->ramdac = 0;
1141 } else if ((nv_output->valid_ramdac & RAMDAC_1) && !(pNv->ramdac_active[1])) {
1142 ErrorF("Activating ramdac %d\n", 1);
1143 pNv->ramdac_active[1] = TRUE;
1144 nv_output->ramdac = 1;
1147 if (nv_output->ramdac != -1) {
1148 nv_output->ramdac_assigned = TRUE;
1149 nv_clear_ramdac_from_outputs(output, nv_output->ramdac);
1154 nv_output_commit(xf86OutputPtr output)
1156 ErrorF("nv_output_commit is called\n");
1158 output->funcs->dpms(output, DPMSModeOn);
1161 static const xf86OutputFuncsRec nv_analog_output_funcs = {
1162 .dpms = nv_analog_output_dpms,
1163 .save = nv_output_save,
1164 .restore = nv_output_restore,
1165 .mode_valid = nv_output_mode_valid,
1166 .mode_fixup = nv_output_mode_fixup,
1167 .mode_set = nv_output_mode_set,
1168 .detect = nv_analog_output_detect,
1169 .get_modes = nv_output_get_modes,
1170 .destroy = nv_output_destroy,
1171 .prepare = nv_output_prepare,
1172 .commit = nv_output_commit,
1175 static const xf86OutputFuncsRec nv_digital_output_funcs = {
1176 .dpms = nv_digital_output_dpms,
1177 .save = nv_output_save,
1178 .restore = nv_output_restore,
1179 .mode_valid = nv_output_mode_valid,
1180 .mode_fixup = nv_output_mode_fixup,
1181 .mode_set = nv_output_mode_set,
1182 .detect = nv_digital_output_detect,
1183 .get_modes = nv_output_get_modes,
1184 .destroy = nv_output_destroy,
1185 .prepare = nv_output_prepare,
1186 .commit = nv_output_commit,
1189 static xf86OutputStatus
1190 nv_lvds_output_detect(xf86OutputPtr output)
1192 return XF86OutputStatusConnected;
1195 static DisplayModePtr
1196 nv_lvds_output_get_modes(xf86OutputPtr output)
1198 ScrnInfoPtr pScrn = output->scrn;
1199 NVOutputPrivatePtr nv_output = output->driver_private;
1201 // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1202 // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1203 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1205 // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n",
1206 // nv_output->fpWidth, nv_output->fpHeight);
1211 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1212 .dpms = nv_lvds_output_dpms,
1213 .save = nv_output_save,
1214 .restore = nv_output_restore,
1215 .mode_valid = nv_output_mode_valid,
1216 .mode_fixup = nv_output_mode_fixup,
1217 .mode_set = nv_output_mode_set,
1218 .detect = nv_lvds_output_detect,
1219 .get_modes = nv_lvds_output_get_modes,
1220 .destroy = nv_output_destroy,
1221 .prepare = nv_output_prepare,
1222 .commit = nv_output_commit,
1226 static void nv_add_analog_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dvi_pair)
1228 NVPtr pNv = NVPTR(pScrn);
1229 xf86OutputPtr output;
1230 NVOutputPrivatePtr nv_output;
1231 char outputname[20];
1232 int crtc_mask = (1<<0);
1234 Bool create_output = TRUE;
1236 sprintf(outputname, "Analog-%d", pNv->analog_count);
1237 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1242 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1243 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1245 nv_output->type = OUTPUT_ANALOG;
1248 * bit0: RAMDAC_0 valid
1249 * bit1: RAMDAC_1 valid
1250 * So lowest order has highest priority.
1252 nv_output->valid_ramdac = order + 1;
1254 /* Restricting this will cause a full mode set when trying to squeeze in the primary mode */
1255 if (nv_output->valid_ramdac & RAMDAC_1)
1256 crtc_mask |= (1<<1);
1258 if (!create_output) {
1263 /* Delay creation of output until we actually know we want it */
1264 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1268 output->driver_private = nv_output;
1270 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1272 nv_output->ramdac = -1;
1274 output->possible_crtcs = crtc_mask;
1275 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1277 pNv->analog_count++;
1281 static void nv_add_digital_output(ScrnInfoPtr pScrn, int order, int i2c_index, Bool dual_dvi, int lvds)
1283 NVPtr pNv = NVPTR(pScrn);
1284 xf86OutputPtr output;
1285 NVOutputPrivatePtr nv_output;
1286 char outputname[20];
1287 int crtc_mask = (1<<0);
1288 Bool create_output = TRUE;
1289 int index = i2c_index;
1291 sprintf(outputname, "Digital-%d", pNv->digital_count);
1292 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1298 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1299 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1301 nv_output->type = OUTPUT_DIGITAL;
1304 * bit0: RAMDAC_0 valid
1305 * bit1: RAMDAC_1 valid
1306 * So lowest order has highest priority.
1308 nv_output->valid_ramdac = order + 1;
1310 /* Restricting this will cause a full mode set when trying to squeeze in the primary mode */
1311 if (nv_output->valid_ramdac & RAMDAC_1)
1312 crtc_mask |= (1<<1);
1314 /* Sorry, i don't know what to do with lvds */
1316 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1318 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1319 create_output = FALSE;
1322 if (!create_output) {
1327 /* Delay creation of output until we are certain is desirable */
1329 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1331 output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname);
1335 output->driver_private = nv_output;
1337 nv_output->ramdac = -1;
1339 output->possible_crtcs = crtc_mask;
1340 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1342 pNv->digital_count++;
1345 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1347 unsigned char type, i2c_index, or;
1348 NVPtr pNv = NVPTR(pScrn);
1350 int num_digital = 0;
1351 Bool dual_dvi = FALSE;
1352 Bool dvi_pair = FALSE;
1354 /* check how many TMDS ports there are */
1355 if (pNv->dcb_table.entries) {
1356 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1357 type = pNv->dcb_table.connection[i] & 0xf;
1358 i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1360 if (type == 2 && i2c_index != 0xf) {
1366 if (num_digital > 1) {
1370 /* It's time to gather some information */
1372 /* Being slaved indicates we're a flatpanel (or tv-out) */
1373 if (NVReadVGA0(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1374 pNv->output_info |= OUTPUT_0_SLAVED;
1376 if (NVReadVGA1(pNv, NV_VGA_CRTCX_PIXEL) & 0x80) {
1377 pNv->output_info |= OUTPUT_1_SLAVED;
1379 /* This is an educated guess */
1380 if (NVReadTMDS(pNv, 0, 0x4) & (1 << 3)) {
1381 pNv->output_info |= OUTPUT_0_CROSSWIRED_TMDS;
1383 if (NVReadTMDS(pNv, 1, 0x4) & (1 << 3)) {
1384 pNv->output_info |= OUTPUT_1_CROSSWIRED_TMDS;
1387 if (NVReadTMDS(pNv, 0, 0x4) & (1 << 0)) {
1388 pNv->output_info |= OUTPUT_0_LVDS;
1390 if (NVReadTMDS(pNv, 1, 0x4) & (1 << 0)) {
1391 pNv->output_info |= OUTPUT_1_LVDS;
1394 /* we setup the outputs up from the BIOS table */
1395 if (pNv->dcb_table.entries) {
1396 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1397 type = pNv->dcb_table.connection[i] & 0xf;
1398 i2c_index = (pNv->dcb_table.connection[i] >> 4) & 0xf;
1399 or = ffs((pNv->dcb_table.connection[i] >> 24) & 0xf) - 1;
1402 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);
1405 case OUTPUT_ANALOG: /* Analogue VGA */
1406 nv_add_analog_output(pScrn, or, i2c_index, dvi_pair);
1409 case OUTPUT_DIGITAL: /* TMDS */
1411 nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 0);
1413 case OUTPUT_PANEL: /* LVDS */
1414 nv_add_digital_output(pScrn, or, i2c_index, dual_dvi, 1);
1424 void NvSetupOutputs(ScrnInfoPtr pScrn)
1427 NVPtr pNv = NVPTR(pScrn);
1429 pNv->Television = FALSE;
1431 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1432 NvDCBSetupOutputs(pScrn);
1435 xf86OutputPtr output;
1436 NVOutputPrivatePtr nv_output;
1439 output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]);
1443 nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1);
1445 xf86OutputDestroy(output);
1449 output->driver_private = nv_output;
1450 nv_output->type = output_type;
1452 output->possible_crtcs = i ? 1 : crtc_mask;
1457 #endif /* ENABLE_RANDR12 */
1459 /*************************************************************************** \
1461 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1463 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1464 |* international laws. Users and possessors of this source code are *|
1465 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1466 |* use this code in individual and commercial software. *|
1468 |* Any use of this source code must include, in the user documenta- *|
1469 |* tion and internal comments to the code, notices to the end user *|
1472 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1474 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1475 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1476 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1477 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1478 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1479 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1480 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1481 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1482 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1483 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1484 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1486 |* U.S. Government End Users. This source code is a "commercial *|
1487 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1488 |* consisting of "commercial computer software" and "commercial *|
1489 |* computer software documentation," as such terms are used in *|
1490 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1491 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1492 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1493 |* all U.S. Government End Users acquire the source code with only *|
1494 |* those rights set forth herein. *|
1496 \***************************************************************************/