summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@dulcimer.keithp.com>2007-06-30 12:45:24 -0700
committerKeith Packard <keithp@dulcimer.keithp.com>2007-06-30 12:45:24 -0700
commit1e2e301348b4168aeed38b3fdc6b0e43d5678a86 (patch)
tree018eab1524887b06193a5e5c55f4f8ea84e2c1c9 /src
parent11862c2e1f23b77b56d7bd8b384579b5e3ae377b (diff)
Fix load detection to use border region instead of blanking.
Make sure there is some border area to use by changing how the pipe is configured, then pick a scanline in the middle of the border for load detection. This lets the load detect code use an active pipe instead of requiring an idle one.
Diffstat (limited to 'src')
-rw-r--r--src/i830_crt.c36
-rw-r--r--src/i830_display.c13
-rw-r--r--src/i830_dvo.c4
-rw-r--r--src/i830_tv.c7
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);
}