diff options
-rw-r--r-- | src/i830_crt.c | 36 | ||||
-rw-r--r-- | src/i830_display.c | 13 | ||||
-rw-r--r-- | src/i830_dvo.c | 4 | ||||
-rw-r--r-- | src/i830_tv.c | 7 |
4 files changed, 46 insertions, 14 deletions
diff --git a/src/i830_crt.c b/src/i830_crt.c index d9f4ee60..6d70f39a 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -201,15 +201,16 @@ i830_crt_detect_load (xf86CrtcPtr crtc, ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr i830_crtc = I830CrtcPrivate(crtc); - I830OutputPrivatePtr intel_output = output->driver_private; CARD32 save_bclrpat; CARD32 save_vtotal; CARD32 vtotal, vactive; CARD32 vsample; + CARD32 vblank, vblank_start, vblank_end; CARD32 dsl; CARD8 st00; int bclrpat_reg, pipeconf_reg, pipe_dsl_reg; int vtotal_reg; + int vblank_reg; int pipe = i830_crtc->pipe; int count, detect; Bool present; @@ -218,6 +219,7 @@ i830_crt_detect_load (xf86CrtcPtr crtc, { bclrpat_reg = BCLRPAT_A; vtotal_reg = VTOTAL_A; + vblank_reg = VBLANK_A; pipeconf_reg = PIPEACONF; pipe_dsl_reg = PIPEA_DSL; } @@ -225,18 +227,26 @@ i830_crt_detect_load (xf86CrtcPtr crtc, { bclrpat_reg = BCLRPAT_B; vtotal_reg = VTOTAL_B; + vblank_reg = VBLANK_B; pipeconf_reg = PIPEBCONF; pipe_dsl_reg = PIPEB_DSL; } save_bclrpat = INREG(bclrpat_reg); save_vtotal = INREG(vtotal_reg); + vblank = INREG(vblank_reg); + + vtotal = ((save_vtotal >> 16) & 0xfff) + 1; + vactive = (save_vtotal & 0x7ff) + 1; - vtotal = (save_vtotal >> 16) & 0xfff; - vactive = save_vtotal & 0x7ff; + vblank_start = (vblank & 0xfff) + 1; + vblank_end = ((vblank >> 16) & 0xfff) + 1; - /* sample the middle of the blanking interval */ - vsample = ((vtotal - 3) + (vactive)) >> 1; + /* sample in the vertical border, selecting the larger one */ + if (vblank_start - vactive >= vtotal - vblank_end) + vsample = (vblank_start + vactive) >> 1; + else + vsample = (vtotal + vblank_end) >> 1; /* Set the border color to purple. */ OUTREG(bclrpat_reg, 0x500050); @@ -271,8 +281,6 @@ i830_crt_detect_load (xf86CrtcPtr crtc, * the screen */ present = detect * 4 > count * 3; - xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "present: %s (%d of %d) at %ld desired %ld temp %d\n", - present ? "TRUE" : "FALSE", detect, count, dsl, vsample, intel_output->load_detect_temp); return present; } @@ -341,11 +349,16 @@ i830_crt_detect(xf86OutputPtr output) Bool connected; I830OutputPrivatePtr intel_output = output->driver_private; - if (intel_output->load_detect_temp) + if (!crtc->enabled) { xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0); } + else if (intel_output->load_detect_temp) + { + output->funcs->mode_set (output, &crtc->mode, &crtc->mode); + output->funcs->commit (output); + } connected = i830_crt_detect_load (crtc, output); i830ReleaseLoadDetectPipe (output); @@ -384,6 +397,7 @@ i830_crt_init(ScrnInfoPtr pScrn) { xf86OutputPtr output; I830OutputPrivatePtr i830_output; + I830Ptr pI830 = I830PTR(pScrn); output = xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA"); if (!output) @@ -395,7 +409,11 @@ i830_crt_init(ScrnInfoPtr pScrn) return; } i830_output->type = I830_OUTPUT_ANALOG; - i830_output->pipe_mask = ((1 << 0) | (1 << 1)); + /* i830 (almador) cannot place the analog adaptor on pipe B */ + if (IS_I830(pI830)) + i830_output->pipe_mask = (1 << 0); + else + i830_output->pipe_mask = ((1 << 0) | (1 << 1)); i830_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) | (1 << I830_OUTPUT_DVO_TMDS)); diff --git a/src/i830_display.c b/src/i830_display.c index 16ef2cc8..aba86ae7 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -1054,6 +1054,14 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, ((adjusted_mode->CrtcHSyncEnd - 1) << 16)); OUTREG(vtot_reg, (adjusted_mode->CrtcVDisplay - 1) | ((adjusted_mode->CrtcVTotal - 1) << 16)); + + /* + * Give us some border at the bottom for load detection + */ + adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVSyncStart; + if (adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVBlankStart < 3) + adjusted_mode->CrtcVBlankStart = adjusted_mode->CrtcVBlankEnd - 3; + OUTREG(vblank_reg, (adjusted_mode->CrtcVBlankStart - 1) | ((adjusted_mode->CrtcVBlankEnd - 1) << 16)); OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) | @@ -1322,7 +1330,7 @@ i830GetLoadDetectPipe(xf86OutputPtr output) return output->crtc; for (i = 0; i < xf86_config->num_crtc; i++) - if (!xf86CrtcInUse (xf86_config->crtc[i])) + if (output->possible_crtcs & (1 << i)) break; if (i == xf86_config->num_crtc) @@ -1344,9 +1352,10 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr output) if (intel_output->load_detect_temp) { - output->crtc->enabled = FALSE; + xf86CrtcPtr crtc = output->crtc; output->crtc = NULL; intel_output->load_detect_temp = FALSE; + crtc->enabled = xf86CrtcInUse (crtc); xf86DisableUnusedFunctions(pScrn); } } diff --git a/src/i830_dvo.c b/src/i830_dvo.c index 2521ee3d..cb461d79 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -462,13 +462,13 @@ i830_dvo_init(ScrnInfoPtr pScrn) "TMDS"); break; case I830_OUTPUT_DVO_LVDS: - intel_output->pipe_mask = (1 << 1); + intel_output->pipe_mask = ((1 << 0) | (1 << 1)); intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS); output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs, "LVDS"); break; case I830_OUTPUT_DVO_TVOUT: - intel_output->pipe_mask = (1 << 1); + intel_output->pipe_mask = ((1 << 0) | (1 << 1)); intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT); output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs, "TV"); diff --git a/src/i830_tv.c b/src/i830_tv.c index b95986f0..1c818bae 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -1357,13 +1357,18 @@ i830_tv_detect(xf86OutputPtr output) crtc = i830GetLoadDetectPipe (output); if (crtc) { - if (intel_output->load_detect_temp) + if (!crtc->enabled) { /* we only need the pixel clock set correctly here */ mode = reported_modes[0]; xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0); } + else if (intel_output->load_detect_temp) + { + output->funcs->mode_set (output, &crtc->mode, &crtc->mode); + output->funcs->commit (output); + } i830_tv_detect_type (crtc, output); i830ReleaseLoadDetectPipe (output); } |