[Intel-gfx] [PATCH 2/6] drm/i915/hdmi: Read the HPD status before trying to read the EDID
Jani Nikula
jani.nikula at linux.intel.com
Fri Dec 14 10:34:51 CET 2012
On Thu, 13 Dec 2012, Damien Lespiau <damien.lespiau at gmail.com> wrote:
> From: Damien Lespiau <damien.lespiau at intel.com>
>
> If you unplug the hdmi connector slowly enough, the hotplug interrupt
> fires but then the kernel code tries to read the EDID and succeeds
> (because the connector is still half connected, the HPD pin is shorter
> than the others, and DDC works). Since EDID succeeds it thinks the
> monitor is still connected.
>
> To prevent that, read the live HPD status in the hotplug handler before
> trying to read the EDID.
>
> v2: Rename the function to ibx_ (Chris Wilson)
The name's a bit funny in the intermediate step because the patch
doesn't really do anything for IBX before patch 5/6... :) I don't mind,
just an observation, and perhaps Daniel will fold the two together once
we get tested-by on ILK+IBX.
Reviewed-by: Jani Nikula <jani.nikula at intel.com>
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=55372
> Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 33 +++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_drv.h | 3 +++
> drivers/gpu/drm/i915/intel_hdmi.c | 9 +++++++--
> 3 files changed, 43 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 115bf62..21fedf7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -994,6 +994,39 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
> }
> }
>
> +/*
> + * ibx_digital_port_connected - is the specified port connected?
> + * @dev_priv: i915 private structure
> + * @port: the port to test
> + *
> + * Returns true if @port is connected, false otherwise.
> + */
> +bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
> + struct intel_digital_port *port)
> +{
> + u32 bit;
> +
> + /* XXX: IBX has different SDEISR bits */
> + if (HAS_PCH_IBX(dev_priv->dev))
> + return true;
> +
> + switch(port->port) {
> + case PORT_B:
> + bit = SDE_PORTB_HOTPLUG_CPT;
> + break;
> + case PORT_C:
> + bit = SDE_PORTC_HOTPLUG_CPT;
> + break;
> + case PORT_D:
> + bit = SDE_PORTD_HOTPLUG_CPT;
> + break;
> + default:
> + return true;
> + }
> +
> + return I915_READ(SDEISR) & bit;
> +}
> +
> static const char *state_string(bool enabled)
> {
> return enabled ? "on" : "off";
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 22728f2..53d4c8f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -545,6 +545,9 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
> return container_of(intel_hdmi, struct intel_digital_port, hdmi);
> }
>
> +bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
> + struct intel_digital_port *port);
> +
> extern void intel_connector_attach_encoder(struct intel_connector *connector,
> struct intel_encoder *encoder);
> extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 53df0a8..9f834d3 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -793,16 +793,21 @@ static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi)
> static enum drm_connector_status
> intel_hdmi_detect(struct drm_connector *connector, bool force)
> {
> + struct drm_device *dev = connector->dev;
> struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> struct intel_digital_port *intel_dig_port =
> hdmi_to_dig_port(intel_hdmi);
> struct intel_encoder *intel_encoder = &intel_dig_port->base;
> - struct drm_i915_private *dev_priv = connector->dev->dev_private;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> struct edid *edid;
> enum drm_connector_status status = connector_status_disconnected;
>
> - if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi))
> +
> + if (IS_G4X(dev) && !g4x_hdmi_connected(intel_hdmi))
> return status;
> + else if (HAS_PCH_SPLIT(dev) &&
> + !ibx_digital_port_connected(dev_priv, intel_dig_port))
> + return status;
>
> intel_hdmi->has_hdmi_sink = false;
> intel_hdmi->has_audio = false;
> --
> 1.7.11.7
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list