Message ID | 20231030155843.2251023-7-imre.deak@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Improve BW management on MST links | expand |
Reviewed-by: Lyude Paul <lyude@redhat.com> On Mon, 2023-10-30 at 17:58 +0200, Imre Deak wrote: > The Synaptics MST branch devices support DSC decompression on all their > output ports, provided that they are last branch devices (with their > output ports connected to the sinks). The Thinkpad 40B0 TBT dock for > instance has two such branch devices, a secondary one connected to one > of the output ports of the primary; hence the decompression needs to be > enabled in both branch devices to enable decompression for all the > sinks. > > Based on the above add support for enabling decompression in last > Synaptics branch devices. > > Cc: Lyude Paul <lyude@redhat.com> > Cc: dri-devel@lists.freedesktop.org > Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> > Signed-off-by: Imre Deak <imre.deak@intel.com> > --- > drivers/gpu/drm/display/drm_dp_mst_topology.c | 21 ++++++++++++------- > 1 file changed, 13 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c > index 5972c93615f18..cc0a8fe84d290 100644 > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c > @@ -5994,6 +5994,7 @@ static bool drm_dp_mst_is_virtual_dpcd(struct drm_dp_mst_port *port) > struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) > { > struct drm_dp_mst_port *immediate_upstream_port; > + struct drm_dp_aux *immediate_upstream_aux; > struct drm_dp_mst_port *fec_port; > struct drm_dp_desc desc = {}; > u8 endpoint_fec; > @@ -6058,21 +6059,25 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) > * - Port is on primary branch device > * - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG) > */ > - if (drm_dp_read_desc(port->mgr->aux, &desc, true)) > + if (immediate_upstream_port) > + immediate_upstream_aux = &immediate_upstream_port->aux; > + else > + immediate_upstream_aux = port->mgr->aux; > + > + if (drm_dp_read_desc(immediate_upstream_aux, &desc, true)) > return NULL; > > - if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) && > - port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 && > - port->parent == port->mgr->mst_primary) { > + if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) { > u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; > > - if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0) > + if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0) > return NULL; > > - if ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) && > + if (dpcd_ext[DP_DPCD_REV] >= DP_DPCD_REV_14 && > + ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) && > ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) > - != DP_DWN_STRM_PORT_TYPE_ANALOG)) > - return port->mgr->aux; > + != DP_DWN_STRM_PORT_TYPE_ANALOG))) > + return immediate_upstream_aux; > } > > /*
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 5972c93615f18..cc0a8fe84d290 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -5994,6 +5994,7 @@ static bool drm_dp_mst_is_virtual_dpcd(struct drm_dp_mst_port *port) struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) { struct drm_dp_mst_port *immediate_upstream_port; + struct drm_dp_aux *immediate_upstream_aux; struct drm_dp_mst_port *fec_port; struct drm_dp_desc desc = {}; u8 endpoint_fec; @@ -6058,21 +6059,25 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) * - Port is on primary branch device * - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG) */ - if (drm_dp_read_desc(port->mgr->aux, &desc, true)) + if (immediate_upstream_port) + immediate_upstream_aux = &immediate_upstream_port->aux; + else + immediate_upstream_aux = port->mgr->aux; + + if (drm_dp_read_desc(immediate_upstream_aux, &desc, true)) return NULL; - if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) && - port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 && - port->parent == port->mgr->mst_primary) { + if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) { u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; - if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0) + if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0) return NULL; - if ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) && + if (dpcd_ext[DP_DPCD_REV] >= DP_DPCD_REV_14 && + ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) && ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) - != DP_DWN_STRM_PORT_TYPE_ANALOG)) - return port->mgr->aux; + != DP_DWN_STRM_PORT_TYPE_ANALOG))) + return immediate_upstream_aux; } /*