[Intel-gfx] [PATCH RESEND] drm: i915: Don't try detecting sinks on ports already in use
Manasi Navare
manasi.d.navare at intel.com
Thu May 4 22:07:41 UTC 2017
On Thu, May 04, 2017 at 05:36:49PM -0300, Gabriel Krisman Bertazi wrote:
> On systems where more than one connector is attached to the same port,
> the HPD pin is also shared, and attaching one connector will trigger a
> hotplug on every other connector on that port. But, according to the
> documentation, connectors sharing the port cannot be enabled
> simultaneously, such that we can abort the detection process early if
> another connector was detected succesfully.
>
> This has the good side effect of preventing DP timeouts whenever
> something else is connected to the shared port, like below:
>
> [drm:intel_dp_aux_ch [i915]] dp_aux_ch timeout status 0x7143003f
> [drm:drm_dp_dpcd_access] Too many retries, giving up. First error: -110
>
> Since this reduces the overhead of the i915_hotplug_work_func, it may
> address the following vblank misses detected by the CI:
>
> https://bugs.freedesktop.org/show_bug.cgi?id=100215
> https://bugs.freedesktop.org/show_bug.cgi?id=100558
>
> Signed-off-by: Gabriel Krisman Bertazi <krisman at collabora.co.uk>
> ---
> drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_dp.c | 3 +++
> drivers/gpu/drm/i915/intel_drv.h | 1 +
> drivers/gpu/drm/i915/intel_hdmi.c | 3 +++
> 4 files changed, 33 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 85b9e2f521a0..618b5138c0c7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11270,6 +11270,32 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
> return true;
> }
>
> +bool intel_shared_digital_port_in_use(struct drm_connector *conn)
> +{
> + struct drm_connector *peer;
> + struct drm_connector_list_iter iter;
> + struct intel_encoder *enc = to_intel_connector(conn)->encoder;
> + int ret = false;
> +
> + drm_connector_list_iter_begin(conn->dev, &iter);
> + drm_for_each_connector_iter(peer, &iter) {
> + struct intel_encoder *peer_enc;
> +
> + if (peer == conn ||
> + peer->status != connector_status_connected)
> + continue;
So here, you are trying to find another connector in the list
of connectors that is not same as the passed connector but it is connected, right?
> +
> + peer_enc = to_intel_connector(peer)->encoder;
> + if (peer_enc->port == enc->port) {
> + ret = true;
> + break;
And the intention for this check is to see the connector that just
got hotplugged is connected to the same port as the port that already
has a connector connected?
How does this handle the case where displays are cloned? Guess it would be same encoder
but still different ports?
Manasi
> + }
> + }
> + drm_connector_list_iter_end(&iter);
> +
> + return ret;
> +}
> +
> static void
> clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
> {
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 08834f74d396..0823c588575f 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4628,6 +4628,9 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
>
> WARN_ON(!drm_modeset_is_locked(&connector->dev->mode_config.connection_mutex));
>
> + if (intel_shared_digital_port_in_use(connector))
> + return connector_status_disconnected;
> +
> intel_display_power_get(to_i915(dev), intel_dp->aux_power_domain);
>
> /* Can't disconnect eDP, but you can close the lid... */
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 54f3ff840812..fd5f2517bede 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1411,6 +1411,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
> const struct dpll *dpll);
> void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
> int lpt_get_iclkip(struct drm_i915_private *dev_priv);
> +bool intel_shared_digital_port_in_use(struct drm_connector *conn);
>
> /* modesetting asserts */
> void assert_panel_unlocked(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 52f0b2d5fad2..9ce0b1f45cde 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1532,6 +1532,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> connector->base.id, connector->name);
>
> + if (intel_shared_digital_port_in_use(connector))
> + return connector_status_disconnected;;
> +
> intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
>
> intel_hdmi_unset_edid(connector);
> --
> 2.11.0
>
More information about the Intel-gfx
mailing list