[Intel-gfx] [PATCH v3 2/2] drm/i915: Enable hotplug retry
Imre Deak
imre.deak at intel.com
Wed Jul 10 14:12:06 UTC 2019
On Fri, Jun 28, 2019 at 02:39:21PM -0700, José Roberto de Souza wrote:
> Right now we are aware of two cases that needs another hotplug retry:
> - Unpowered type-c dongles
> - HDMI slow unplug
>
> Both have a complete explanation in the code to schedule another run
> of the hotplug handler.
>
> It could have more checks to just trigger the retry in those two
> specific cases but why would sink signal a long pulse if there is
> no change? Also the drawback of running the hotplug handler again
> is really low and that could fix another cases that we are not
> aware.
>
> Also retrying for old DP ports(non-DDI) to make it consistent and not
> cause CI failures if those systems are connected to chamelium boards
> that will be used to simulate the issues reported in here.
>
> v2: Also retrying for old DP ports(non-DDI)(Imre)
>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Cc: Imre Deak <imre.deak at intel.com>
> Cc: Jani Nikula <jani.nikula at intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza at intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_ddi.c | 21 +++++++++++++++++
> drivers/gpu/drm/i915/display/intel_dp.c | 3 +++
> drivers/gpu/drm/i915/display/intel_hdmi.c | 28 ++++++++++++++++++++++-
> 3 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 53009984e046..d7df1940b826 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4086,6 +4086,7 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
> struct intel_connector *connector,
> bool irq_received)
> {
> + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
> struct drm_modeset_acquire_ctx ctx;
> enum intel_hotplug_state state;
> int ret;
> @@ -4112,6 +4113,26 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
> drm_modeset_acquire_fini(&ctx);
> WARN(ret, "Acquiring modeset locks failed with %i\n", ret);
>
> + /*
> + * Unpowered type-c dongles can take some time to boot and be
> + * responsible, so here giving some time to those dongles to power up
> + * and then retrying the probe.
> + *
> + * On many platforms the HDMI live state signal is known to be
> + * unreliable, so we can't use it to detect if a sink is connected or
> + * not. Instead we detect if it's connected based on whether we can
> + * read the EDID or not. That in turn has a problem during disconnect,
> + * since the HPD interrupt may be raised before the DDC lines get
> + * disconnected (due to how the required length of DDC vs. HPD
> + * connector pins are specified) and so we'll still be able to get a
> + * valid EDID. To solve this schedule another detection cycle if this
> + * time around we didn't detect any change in the sink's connection
> + * status.
> + */
> + if (state == INTEL_HOTPLUG_NOCHANGE && irq_received &&
> + !dig_port->dp.is_mst)
> + state = INTEL_HOTPLUG_RETRY;
> +
> return state;
> }
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 95d0da9d1bac..8eb479daa8a8 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4906,6 +4906,9 @@ intel_dp_hotplug(struct intel_encoder *encoder,
> drm_modeset_acquire_fini(&ctx);
> WARN(ret, "Acquiring modeset locks failed with %i\n", ret);
Nit: could add a short comment, that a long HPD interrupt that doesn't
result in a connector state change could be just a transient state, so
we retry the detection.
> + if (state == INTEL_HOTPLUG_NOCHANGE && irq_received)
> + state = INTEL_HOTPLUG_RETRY;
> +
> return state;
> }
>
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index 0ebec69bbbfc..5ed91caf3b4d 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3143,6 +3143,32 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> DRM_DEBUG_KMS("CEC notifier get failed\n");
> }
>
> +static enum intel_hotplug_state
> +intel_hdmi_hotplug(struct intel_encoder *encoder,
> + struct intel_connector *connector, bool irq_received)
> +{
> + enum intel_hotplug_state state;
> +
> + state = intel_encoder_hotplug(encoder, connector, irq_received);
> +
> + /*
> + * On many platforms the HDMI live state signal is known to be
> + * unreliable, so we can't use it to detect if a sink is connected or
> + * not. Instead we detect if it's connected based on whether we can
> + * read the EDID or not. That in turn has a problem during disconnect,
> + * since the HPD interrupt may be raised before the DDC lines get
> + * disconnected (due to how the required length of DDC vs. HPD
> + * connector pins are specified) and so we'll still be able to get a
> + * valid EDID. To solve this schedule another detection cycle if this
> + * time around we didn't detect any change in the sink's connection
> + * status.
> + */
This is the same description of the issue that DDI encoders have, so
could be just replaced with a reference to the intel_ddi_hotplug() func.
Looks ok:
Reviewed-by: Imre Deak <imre.deak at intel.com>
> + if (state == INTEL_HOTPLUG_NOCHANGE && irq_received)
> + state = INTEL_HOTPLUG_RETRY;
> +
> + return state;
> +}
> +
> void intel_hdmi_init(struct drm_i915_private *dev_priv,
> i915_reg_t hdmi_reg, enum port port)
> {
> @@ -3166,7 +3192,7 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
> &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
> "HDMI %c", port_name(port));
>
> - intel_encoder->hotplug = intel_encoder_hotplug;
> + intel_encoder->hotplug = intel_hdmi_hotplug;
> intel_encoder->compute_config = intel_hdmi_compute_config;
> if (HAS_PCH_SPLIT(dev_priv)) {
> intel_encoder->disable = pch_disable_hdmi;
> --
> 2.22.0
>
More information about the Intel-gfx
mailing list