[Intel-gfx] [PATCH] drm/i915: crt load pipe detection sync up with 2D driver
Eric Anholt
eric at anholt.net
Fri May 22 21:15:59 CEST 2009
On Fri, 2009-05-22 at 17:50 +0800, Ma Ling wrote:
> Two approaches for VGA detections: hot plug detection for 945G onwards
> and load pipe detection for Pre-945G. load pipe detection will get one free
> pipe ,and set border color as red and blue, then check CRT status by
> swf register.
>
> Signed-off-by: Ma Ling <ling.ma at intel.com>
> ---
> drivers/gpu/drm/i915/intel_crt.c | 164 ++++++++++++++++++++++++++++++++++++--
> 1 files changed, 157 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index 19148c3..60f979f 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -198,22 +198,172 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
> return intel_ddc_probe(intel_output);
> }
>
> +static enum drm_connector_status
> +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
> +{
> + struct drm_encoder *encoder = &intel_output->enc;
> + struct drm_device *dev = encoder->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + uint32_t pipe = intel_crtc->pipe;
> + uint32_t save_bclrpat;
> + uint32_t save_vtotal;
> + uint32_t vtotal, vactive;
> + uint32_t vsample;
> + uint32_t vblank, vblank_start, vblank_end;
> + uint32_t dsl;
> + uint32_t bclrpat_reg;
> + uint32_t vtotal_reg;
> + uint32_t vblank_reg;
> + uint32_t vsync_reg;
> + uint32_t pipeconf_reg;
> + uint32_t pipe_dsl_reg;
> + uint8_t st00;
> + enum drm_connector_status status;
> +
> + if (pipe == 0) {
> + bclrpat_reg = BCLRPAT_A;
> + vtotal_reg = VTOTAL_A;
> + vblank_reg = VBLANK_A;
> + vsync_reg = VSYNC_A;
> + pipeconf_reg = PIPEACONF;
> + /* Display Scan Line for PIPE A */
> + pipe_dsl_reg = 0x70000;
> + } else {
> + bclrpat_reg = BCLRPAT_B;
> + vtotal_reg = VTOTAL_B;
> + vblank_reg = VBLANK_B;
> + vsync_reg = VSYNC_B;
> + pipeconf_reg = PIPEBCONF;
> + /* Display Scan Line for PIPE B */
> + pipe_dsl_reg = 0x71000;
Register definitions go in the register header.
> + }
> +
> + save_bclrpat = I915_READ(bclrpat_reg);
> + save_vtotal = I915_READ(vtotal_reg);
> + vblank = I915_READ(vblank_reg);
> +
> + vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
> + vactive = (save_vtotal & 0x7ff) + 1;
> +
> + vblank_start = (vblank & 0xfff) + 1;
> + vblank_end = ((vblank >> 16) & 0xfff) + 1;
> +
> + /* Set the border color to purple. */
> + I915_WRITE(bclrpat_reg, 0x500050);
> +
> + if (IS_I9XX(dev)) {
> + uint32_t pipeconf = I915_READ(pipeconf_reg);
> + I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
> + /* Wait for next Vblank to substitue
> + * border color for Color info */
> + intel_wait_for_vblank(dev);
> + st00 = I915_READ8(VGA_MSR_WRITE);
> + status = ((st00 & (1 << 4)) != 0) ?
> + connector_status_connected :
> + connector_status_disconnected;
> +
> + I915_WRITE(pipeconf_reg, pipeconf);
> + } else {
> + bool restore_vblank = false;
> + int count, detect;
> +
> + /*
> + * If there isn't any border, add some.
> + * Yes, this will flicker
> + */
> + if (vblank_start <= vactive && vblank_end >= vtotal) {
> + uint32_t vsync = I915_READ(vsync_reg);
> + uint32_t vsync_start = (vsync & 0xffff) + 1;
> +
> + vblank_start = vsync_start;
> + I915_WRITE(vblank_reg,
> + (vblank_start - 1) |
> + ((vblank_end - 1) << 16));
> + restore_vblank = true;
> + }
> + /* 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;
> +
> + /*
> + * Wait for the border to be displayed
> + */
> + while (I915_READ(pipe_dsl_reg) >= vactive)
> + ;
> + while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample)
> + ;
> + /*
> + * Watch ST00 for an entire scanline
> + */
> + detect = 0;
> + count = 0;
> + do {
> + count++;
> + /* Read the ST00 VGA status register */
> + st00 = I915_READ8(VGA_MSR_WRITE);
> + if (st00 & (1 << 4))
> + detect++;
> + } while ((I915_READ(pipe_dsl_reg) == dsl));
> +
> + /* restore vblank if necessary */
> + if (restore_vblank)
> + I915_WRITE(vblank_reg, vblank);
> + /*
> + * If more than 3/4 of the scanline detected a monitor,
> + * then it is assumed to be present. This works even on i830,
> + * where there isn't any way to force the border color across
> + * the screen
> + */
> + status = detect * 4 > count * 3 ?
> + connector_status_connected :
> + connector_status_disconnected;
> + }
> +
> + /* Restore previous settings */
> + I915_WRITE(bclrpat_reg, save_bclrpat);
> +
> + return status;
> +}
> +
> static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
> {
> struct drm_device *dev = connector->dev;
> + struct intel_output *intel_output = to_intel_output(connector);
> + struct drm_encoder *encoder = &intel_output->enc;
> + struct drm_crtc *crtc;
> + int dpms_mode;
> + enum drm_connector_status status = connector_status_disconnected;
>
> if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
> if (intel_crt_detect_hotplug(connector))
> - return connector_status_connected;
> - else
> - return connector_status_disconnected;
> + status = connector_status_connected;
> +
> + goto end;
> + }
> +
> + if (intel_crt_detect_ddc(connector)) {
> + status = connector_status_connected;
> + goto end;
> }
>
> - if (intel_crt_detect_ddc(connector))
> - return connector_status_connected;
> + /* for pre-945g platforms use load detect */
> + if (encoder->crtc && encoder->crtc->enabled) {
> + status = intel_crt_load_detect(encoder->crtc, intel_output);
> + } else {
> + crtc = intel_get_load_detect_pipe(intel_output,
> + NULL, &dpms_mode);
> + if (crtc) {
> + status = intel_crt_load_detect(crtc, intel_output);
> + intel_release_load_detect_pipe(intel_output, dpms_mode);
> + } else
> + status = connector_status_unknown;
> + }
>
> - /* TODO use load detect */
> - return connector_status_unknown;
> +end:
> + return status;
> }
If there's no other teardown, please replace these gotos to the return
with just returns.
--
Eric Anholt
eric at anholt.net eric.anholt at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090522/d0094eed/attachment.sig>
More information about the Intel-gfx
mailing list