[PATCH v4 3/6] drm/dp_mst: Add drm_dp_set_mst_topology_link_status()

Lyude Paul lyude at redhat.com
Wed Aug 30 21:32:17 UTC 2023


On Thu, 2023-08-24 at 16:50 -0400, Gil Dekel wrote:
> Unlike SST, MST can support multiple displays connected to a single
> connector. However, this also means that if the DisplayPort link to the
> top-level MST branch device becomes unstable, then every single branch
> device has an unstable link.
> 
> Since there are multiple downstream ports per connector, setting the
> link status of the parent mstb's port to BAD is not enough. All of the
> downstream mstb ports must also have their link status set to BAD.
> 
> This aligns to how the DP link status logic in DRM works. We notify
> userspace that all of the mstb ports need retraining and apply new lower
> bandwidth constraints to all future atomic commits on the topology that
> follow.
> 
> Since any driver supporting MST needs to figure out which connectors
> live downstream on an MST topology and update their link status in order
> to retrain MST links properly, we add the
> drm_dp_set_mst_topology_link_status() helper. This helper simply marks
> the link status of all connectors living in that topology as bad. We
> will make use of this helper in i915 later in this series.
> 
> Credit: this patch is a refactor of Lyude Pual's original patch:
> https://patchwork.kernel.org/project/dri-devel/patch/20180308232421.14049-5-lyude@redhat.com/

s/Pual/Paul/ (probably want to fix this on the other patches in the series as
well)

> 
> Signed-off-by: Gil Dekel <gildekel at chromium.org>
> ---
>  drivers/gpu/drm/display/drm_dp_mst_topology.c | 39 +++++++++++++++++++
>  include/drm/display/drm_dp_mst_helper.h       |  3 ++
>  2 files changed, 42 insertions(+)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index ed96cfcfa304..17cbadfb6ccb 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -3566,6 +3566,45 @@ int drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
>  }
>  EXPORT_SYMBOL(drm_dp_get_vc_payload_bw);
> 
> +/**
> + * drm_dp_set_mst_topology_link_status() - set all downstream MST ports' link status
> + * @mgr: MST topology manager to set state for
> + * @status: The new status to set the MST topology to
> + *
> + * Set all downstream ports' link-status within the topology to the given status.
> + */
> +void drm_dp_set_mst_topology_link_status(struct drm_dp_mst_topology_mgr *mgr,
> +					 enum drm_link_status status)
> +{
> +	struct drm_dp_mst_port *port;
> +	struct drm_dp_mst_branch *rmstb;
> +	struct drm_dp_mst_branch *mstb =
> +		drm_dp_mst_topology_get_mstb_validated(mgr, mgr->mst_primary);
> +
> +	list_for_each_entry_reverse(port, &mstb->ports, next) {
> +		struct drm_connector *connector = port->connector;
> +
> +		if (connector) {
> +			mutex_lock(&connector->dev->mode_config.mutex);
> +			drm_dbg_kms(
> +				connector->dev,
> +				"[MST-CONNECTOR:%d:%s] link status %d -> %d\n",
> +				connector->base.id, connector->name,
> +				connector->state->link_status, status);
> +			connector->state->link_status = status;
> +			mutex_unlock(&connector->dev->mode_config.mutex);
> +		}
> +
> +		rmstb = drm_dp_mst_topology_get_mstb_validated(mstb->mgr,
> +							       port->mstb);
> +		if (rmstb) {
> +			drm_dp_set_mst_topology_link_status(rmstb->mgr, status);
> +			drm_dp_mst_topology_put_mstb(rmstb);
> +		}
> +	}
> +}
> +EXPORT_SYMBOL(drm_dp_set_mst_topology_link_status);
> +
>  /**
>   * drm_dp_read_mst_cap() - check whether or not a sink supports MST
>   * @aux: The DP AUX channel to use
> diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
> index ed5c9660563c..855d488bf364 100644
> --- a/include/drm/display/drm_dp_mst_helper.h
> +++ b/include/drm/display/drm_dp_mst_helper.h
> @@ -832,6 +832,9 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector,
>  int drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
>  			     int link_rate, int link_lane_count);
> 
> +void drm_dp_set_mst_topology_link_status(struct drm_dp_mst_topology_mgr *mgr,
> +					 enum drm_link_status status);
> +
>  int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc);
> 
>  void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap);
> --
> Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



More information about the dri-devel mailing list