diff mbox series

[v4,06/30] drm/dp_mst: Allow DSC in any Synaptics last branch device

Message ID 20231030155843.2251023-7-imre.deak@intel.com (mailing list archive)
State New, archived
Headers show
Series None | expand

Commit Message

Imre Deak Oct. 30, 2023, 3:58 p.m. UTC
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(-)

Comments

Lyude Paul Nov. 7, 2023, 10:35 p.m. UTC | #1
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 mbox series

Patch

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;
 	}
 
 	/*