[Intel-gfx] [PATCH] drm/dp_mst: Use the correct DPCD space in Synaptics quirk

Nikola Cornij nikola.cornij at amd.com
Fri Apr 23 20:05:52 UTC 2021


[why]
Two conditions that were part of this fix did not go through:

1. DPCD revision has to be v1.4 and up
   This was because wrong DPCD space was used to get the values

2. Downstream port must not be VGA converter
   This was because for MST the topology manager AUX has to be used,
   due to the way MST AUX reads are done.

[how]
- Use Extended Receiver Capability DPCD space if
DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is set
- Use MST topology manager AUX to get port DPCD

Signed-off-by: Nikola Cornij <nikola.cornij at amd.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 33 ++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index de5124ce42cb..69fd16ce2cb3 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -5878,18 +5878,35 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 		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) {
-		u8 downstreamport;
+		u8 training_aux_rd_interval = 0;
+		u8 dpcd_rev = 0;
+		unsigned int dpcd_caps_offset = 0;
 
-		if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
-				     &downstreamport, 1) < 0)
+		if (drm_dp_dpcd_read(port->mgr->aux, DP_TRAINING_AUX_RD_INTERVAL,
+				     &training_aux_rd_interval, 1) < 1)
 			return NULL;
 
-		if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
-		   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
-		     != DP_DWN_STRM_PORT_TYPE_ANALOG))
-			return port->mgr->aux;
+		/* If DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is set, the Extended Receiver Capability field has to be used */
+		if (training_aux_rd_interval & DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT)
+			dpcd_caps_offset = 0x02200;
+
+		if (drm_dp_dpcd_read(port->mgr->aux, dpcd_caps_offset + DP_DPCD_REV,
+				     &dpcd_rev, 1) < 1)
+			return NULL;
+
+		if (dpcd_rev >= DP_DPCD_REV_14) {
+			u8 downstreamport = 0;
+
+			if (drm_dp_dpcd_read(port->mgr->aux, dpcd_caps_offset + DP_DOWNSTREAMPORT_PRESENT,
+					     &downstreamport, 1) < 1)
+				return NULL;
+
+			if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
+			   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
+			     != DP_DWN_STRM_PORT_TYPE_ANALOG))
+				return port->mgr->aux;
+		}
 	}
 
 	/*
-- 
2.25.1



More information about the Intel-gfx mailing list