[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