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@xxxxxxxxxx/ s/Pual/Paul/ (probably want to fix this on the other patches in the series as well) > > Signed-off-by: Gil Dekel <gildekel@xxxxxxxxxxxx> > --- > 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