All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/1] drm/drm_mst: Use Extended Base Receiver Capability
@ 2021-04-28 23:43 ` Nikola Cornij
  0 siblings, 0 replies; 27+ messages in thread
From: Nikola Cornij @ 2021-04-28 23:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski

Change history:

v8:
 - Chaged link lanes and rate parameters to u8
 
v7:
 - Fixed formatting
 - Fixed 'unused variable' compile warning
 - Fixed comment format
 
v6:
 - Submited from (hopefully) the correct repo to fix build error

v5:
 - Fixed min_t() macro arguments

v4:
 - Fixed drm/radeon/ lane count and rate

v3:
 - Fixed check-patch errors

v2:
 - No changes, this was my mistaken reply to my patch

v1:
 - Initial revision

Nikola Cornij (1):
  drm/drm_mst: Use Extended Base Receiver Capability DPCD space

 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
 include/drm/drm_dp_mst_helper.h               | 12 ++++++-
 8 files changed, 71 insertions(+), 15 deletions(-)

-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Intel-gfx] [PATCH v8 0/1] drm/drm_mst: Use Extended Base Receiver Capability
@ 2021-04-28 23:43 ` Nikola Cornij
  0 siblings, 0 replies; 27+ messages in thread
From: Nikola Cornij @ 2021-04-28 23:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski

Change history:

v8:
 - Chaged link lanes and rate parameters to u8
 
v7:
 - Fixed formatting
 - Fixed 'unused variable' compile warning
 - Fixed comment format
 
v6:
 - Submited from (hopefully) the correct repo to fix build error

v5:
 - Fixed min_t() macro arguments

v4:
 - Fixed drm/radeon/ lane count and rate

v3:
 - Fixed check-patch errors

v2:
 - No changes, this was my mistaken reply to my patch

v1:
 - Initial revision

Nikola Cornij (1):
  drm/drm_mst: Use Extended Base Receiver Capability DPCD space

 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
 include/drm/drm_dp_mst_helper.h               | 12 ++++++-
 8 files changed, 71 insertions(+), 15 deletions(-)

-- 
2.25.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v8 0/1] drm/drm_mst: Use Extended Base Receiver Capability
@ 2021-04-28 23:43 ` Nikola Cornij
  0 siblings, 0 replies; 27+ messages in thread
From: Nikola Cornij @ 2021-04-28 23:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski, ville.syrjala

Change history:

v8:
 - Chaged link lanes and rate parameters to u8
 
v7:
 - Fixed formatting
 - Fixed 'unused variable' compile warning
 - Fixed comment format
 
v6:
 - Submited from (hopefully) the correct repo to fix build error

v5:
 - Fixed min_t() macro arguments

v4:
 - Fixed drm/radeon/ lane count and rate

v3:
 - Fixed check-patch errors

v2:
 - No changes, this was my mistaken reply to my patch

v1:
 - Initial revision

Nikola Cornij (1):
  drm/drm_mst: Use Extended Base Receiver Capability DPCD space

 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
 include/drm/drm_dp_mst_helper.h               | 12 ++++++-
 8 files changed, 71 insertions(+), 15 deletions(-)

-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-04-28 23:43 ` [Intel-gfx] " Nikola Cornij
  (?)
@ 2021-04-28 23:43   ` Nikola Cornij
  -1 siblings, 0 replies; 27+ messages in thread
From: Nikola Cornij @ 2021-04-28 23:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski

[why]
DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
set, Extended Base Receiver Capability DPCD space must be used. Without
doing that, the three DPCD values that differ will be wrong, leading to
incorrect or limited functionality. MST link rate, for example, could
have a lower value. Also, Synaptics quirk wouldn't work out well when
Extended DPCD was not read, resulting in no DSC for such hubs.

[how]
Modify MST topology manager to use the values from Extended DPCD where
applicable.

To prevent regression on the sources that have a lower maximum link rate
capability than MAX_LINK_RATE from Extended DPCD, have the drivers
supply maximum lane count and rate at initialization time.

This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
extended DPCD caps for topology manager")', brining the change back to
the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
caps for topology manager")'.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
 include/drm/drm_dp_mst_helper.h               | 12 ++++++-
 8 files changed, 71 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 997567f6f0ba..b7e01b6fb328 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 				       struct amdgpu_dm_connector *aconnector,
 				       int link_index)
 {
+	struct dc_link_settings max_link_enc_cap = {0};
+
 	aconnector->dm_dp_aux.aux.name =
 		kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
 			  link_index);
@@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 	if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
 		return;
 
+	dc_link_dp_get_max_link_enc_cap(aconnector->dc_link, &max_link_enc_cap);
 	aconnector->mst_mgr.cbs = &dm_mst_cbs;
 	drm_dp_mst_topology_mgr_init(
 		&aconnector->mst_mgr,
@@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 		&aconnector->dm_dp_aux.aux,
 		16,
 		4,
+		max_link_enc_cap.lane_count,
+		max_link_enc_cap.link_rate,
 		aconnector->connector_id);
 
 	drm_connector_attach_dp_subconnector_property(&aconnector->base);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 7d2e433c2275..6fe66b7ee53e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
 	return true;
 }
 
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
+{
+	if (!max_link_enc_cap) {
+		DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__);
+		return false;
+	}
+
+	if (link->link_enc->funcs->get_max_link_cap) {
+		link->link_enc->funcs->get_max_link_cap(link->link_enc, max_link_enc_cap);
+		return true;
+	}
+
+	DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
+	max_link_enc_cap->lane_count = 1;
+	max_link_enc_cap->link_rate = 6;
+	return false;
+}
+
 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 {
 	struct dc_link_settings max_link_cap = {0};
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index b0013e674864..cb6d0543d839 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
 	const unsigned char *p_custom_pattern,
 	unsigned int cust_pattern_size);
 
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap);
+
 void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
 
 bool dc_link_is_dp_sink_present(struct dc_link *link);
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5539a91b4031..31d9f3ff0d39 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
 	/* set the device into MST mode */
 	if (mst_state) {
 		struct drm_dp_payload reset_pay;
+		int lane_count;
+		int link_rate;
 
 		WARN_ON(mgr->mst_primary);
 
 		/* get dpcd info */
-		ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
-		if (ret != DP_RECEIVER_CAP_SIZE) {
-			drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
+		ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
+		if (ret < 0) {
+			drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret %d\n",
+				    mgr->aux->name, ret);
 			goto out_unlock;
 		}
 
+		lane_count = min_t(int, mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
+		link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
 		mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
-							drm_dp_bw_code_to_link_rate(mgr->dpcd[1]),
-							mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
+							drm_dp_bw_code_to_link_rate(link_rate),
+							lane_count);
 		if (mgr->pbn_div == 0) {
 			ret = -EINVAL;
 			goto out_unlock;
@@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
  * @aux: DP helper aux channel to talk to this device
  * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
  * @max_payloads: maximum number of payloads this GPU can source
+ * @max_lane_count: maximum number of lanes this GPU supports
+ * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
  * @conn_base_id: the connector object ID the MST device is connected to.
  *
  * Return 0 for success, or negative error code on failure
  */
 int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_device *dev, struct drm_dp_aux *aux,
-				 int max_dpcd_transaction_bytes,
-				 int max_payloads, int conn_base_id)
+				 int max_dpcd_transaction_bytes, int max_payloads,
+				 int max_lane_count, int max_link_rate,
+				 int conn_base_id)
 {
 	struct drm_dp_mst_topology_state *mst_state;
 
@@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	mgr->aux = aux;
 	mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
 	mgr->max_payloads = max_payloads;
+	mgr->max_lane_count = max_lane_count;
+	mgr->max_link_rate = max_link_rate;
 	mgr->conn_base_id = conn_base_id;
 	if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
 	    max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
@@ -5896,14 +5906,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 	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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
 
-		if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
-				     &downstreamport, 1) < 0)
+		if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
 			return NULL;
 
-		if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
-		   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
+		if ((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;
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 860381d68d9d..a4245eb48ef4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
 	struct intel_dp *intel_dp = &dig_port->dp;
 	enum port port = dig_port->base.port;
 	int ret;
+	int bios_max_link_rate;
 
 	if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
 		return 0;
@@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
 
 	/* create encoders */
 	intel_dp_create_fake_mst_encoders(dig_port);
+	bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
 	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
-					   &intel_dp->aux, 16, 3, conn_base_id);
+					   &intel_dp->aux, 16, 3,
+					   dig_port->max_lanes,
+					   bios_max_link_rate / 27000, conn_base_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 1c9c0cdf85db..e02f9d2d74eb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
 	mstm->mgr.cbs = &nv50_mstm;
 
 	ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
-					   max_payloads, conn_base_id);
+					   max_payloads, outp->dcb->dpconf.link_nr,
+					   outp->dcb->dpconf.link_bw, conn_base_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 59cf1d288465..8f0b2dccd199 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -629,13 +629,20 @@ int
 radeon_dp_mst_init(struct radeon_connector *radeon_connector)
 {
 	struct drm_device *dev = radeon_connector->base.dev;
+	int max_link_rate;
 
 	if (!radeon_connector->ddc_bus->has_aux)
 		return 0;
 
+	if (radeon_connector_is_dp12_capable(&radeon_connector->base))
+		max_link_rate = 0x14;
+	else
+		max_link_rate = 0x0a;
+
 	radeon_connector->mst_mgr.cbs = &mst_cbs;
 	return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
 					    &radeon_connector->ddc_bus->aux, 16, 6,
+					    4, max_link_rate,
 					    radeon_connector->base.base.id);
 }
 
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 20dc705642bd..b5b0bf37813b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
 	 * @max_payloads: maximum number of payloads the GPU can generate.
 	 */
 	int max_payloads;
+	/**
+	 * @max_lane_count: maximum number of lanes the GPU can drive.
+	 */
+	int max_lane_count;
+	/**
+	 * @max_link_rate: maximum link rate per lane GPU can output.
+	 */
+	int max_link_rate;
 	/**
 	 * @conn_base_id: DRM connector ID this mgr is connected to. Only used
 	 * to build the MST connector path value.
@@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
 int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_device *dev, struct drm_dp_aux *aux,
 				 int max_dpcd_transaction_bytes,
-				 int max_payloads, int conn_base_id);
+				 int max_payloads,
+				 int max_lane_count, int max_link_rate,
+				 int conn_base_id);
 
 void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Intel-gfx] [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-28 23:43   ` Nikola Cornij
  0 siblings, 0 replies; 27+ messages in thread
From: Nikola Cornij @ 2021-04-28 23:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski

[why]
DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
set, Extended Base Receiver Capability DPCD space must be used. Without
doing that, the three DPCD values that differ will be wrong, leading to
incorrect or limited functionality. MST link rate, for example, could
have a lower value. Also, Synaptics quirk wouldn't work out well when
Extended DPCD was not read, resulting in no DSC for such hubs.

[how]
Modify MST topology manager to use the values from Extended DPCD where
applicable.

To prevent regression on the sources that have a lower maximum link rate
capability than MAX_LINK_RATE from Extended DPCD, have the drivers
supply maximum lane count and rate at initialization time.

This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
extended DPCD caps for topology manager")', brining the change back to
the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
caps for topology manager")'.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
 include/drm/drm_dp_mst_helper.h               | 12 ++++++-
 8 files changed, 71 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 997567f6f0ba..b7e01b6fb328 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 				       struct amdgpu_dm_connector *aconnector,
 				       int link_index)
 {
+	struct dc_link_settings max_link_enc_cap = {0};
+
 	aconnector->dm_dp_aux.aux.name =
 		kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
 			  link_index);
@@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 	if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
 		return;
 
+	dc_link_dp_get_max_link_enc_cap(aconnector->dc_link, &max_link_enc_cap);
 	aconnector->mst_mgr.cbs = &dm_mst_cbs;
 	drm_dp_mst_topology_mgr_init(
 		&aconnector->mst_mgr,
@@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 		&aconnector->dm_dp_aux.aux,
 		16,
 		4,
+		max_link_enc_cap.lane_count,
+		max_link_enc_cap.link_rate,
 		aconnector->connector_id);
 
 	drm_connector_attach_dp_subconnector_property(&aconnector->base);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 7d2e433c2275..6fe66b7ee53e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
 	return true;
 }
 
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
+{
+	if (!max_link_enc_cap) {
+		DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__);
+		return false;
+	}
+
+	if (link->link_enc->funcs->get_max_link_cap) {
+		link->link_enc->funcs->get_max_link_cap(link->link_enc, max_link_enc_cap);
+		return true;
+	}
+
+	DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
+	max_link_enc_cap->lane_count = 1;
+	max_link_enc_cap->link_rate = 6;
+	return false;
+}
+
 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 {
 	struct dc_link_settings max_link_cap = {0};
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index b0013e674864..cb6d0543d839 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
 	const unsigned char *p_custom_pattern,
 	unsigned int cust_pattern_size);
 
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap);
+
 void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
 
 bool dc_link_is_dp_sink_present(struct dc_link *link);
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5539a91b4031..31d9f3ff0d39 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
 	/* set the device into MST mode */
 	if (mst_state) {
 		struct drm_dp_payload reset_pay;
+		int lane_count;
+		int link_rate;
 
 		WARN_ON(mgr->mst_primary);
 
 		/* get dpcd info */
-		ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
-		if (ret != DP_RECEIVER_CAP_SIZE) {
-			drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
+		ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
+		if (ret < 0) {
+			drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret %d\n",
+				    mgr->aux->name, ret);
 			goto out_unlock;
 		}
 
+		lane_count = min_t(int, mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
+		link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
 		mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
-							drm_dp_bw_code_to_link_rate(mgr->dpcd[1]),
-							mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
+							drm_dp_bw_code_to_link_rate(link_rate),
+							lane_count);
 		if (mgr->pbn_div == 0) {
 			ret = -EINVAL;
 			goto out_unlock;
@@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
  * @aux: DP helper aux channel to talk to this device
  * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
  * @max_payloads: maximum number of payloads this GPU can source
+ * @max_lane_count: maximum number of lanes this GPU supports
+ * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
  * @conn_base_id: the connector object ID the MST device is connected to.
  *
  * Return 0 for success, or negative error code on failure
  */
 int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_device *dev, struct drm_dp_aux *aux,
-				 int max_dpcd_transaction_bytes,
-				 int max_payloads, int conn_base_id)
+				 int max_dpcd_transaction_bytes, int max_payloads,
+				 int max_lane_count, int max_link_rate,
+				 int conn_base_id)
 {
 	struct drm_dp_mst_topology_state *mst_state;
 
@@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	mgr->aux = aux;
 	mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
 	mgr->max_payloads = max_payloads;
+	mgr->max_lane_count = max_lane_count;
+	mgr->max_link_rate = max_link_rate;
 	mgr->conn_base_id = conn_base_id;
 	if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
 	    max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
@@ -5896,14 +5906,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 	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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
 
-		if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
-				     &downstreamport, 1) < 0)
+		if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
 			return NULL;
 
-		if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
-		   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
+		if ((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;
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 860381d68d9d..a4245eb48ef4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
 	struct intel_dp *intel_dp = &dig_port->dp;
 	enum port port = dig_port->base.port;
 	int ret;
+	int bios_max_link_rate;
 
 	if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
 		return 0;
@@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
 
 	/* create encoders */
 	intel_dp_create_fake_mst_encoders(dig_port);
+	bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
 	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
-					   &intel_dp->aux, 16, 3, conn_base_id);
+					   &intel_dp->aux, 16, 3,
+					   dig_port->max_lanes,
+					   bios_max_link_rate / 27000, conn_base_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 1c9c0cdf85db..e02f9d2d74eb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
 	mstm->mgr.cbs = &nv50_mstm;
 
 	ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
-					   max_payloads, conn_base_id);
+					   max_payloads, outp->dcb->dpconf.link_nr,
+					   outp->dcb->dpconf.link_bw, conn_base_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 59cf1d288465..8f0b2dccd199 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -629,13 +629,20 @@ int
 radeon_dp_mst_init(struct radeon_connector *radeon_connector)
 {
 	struct drm_device *dev = radeon_connector->base.dev;
+	int max_link_rate;
 
 	if (!radeon_connector->ddc_bus->has_aux)
 		return 0;
 
+	if (radeon_connector_is_dp12_capable(&radeon_connector->base))
+		max_link_rate = 0x14;
+	else
+		max_link_rate = 0x0a;
+
 	radeon_connector->mst_mgr.cbs = &mst_cbs;
 	return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
 					    &radeon_connector->ddc_bus->aux, 16, 6,
+					    4, max_link_rate,
 					    radeon_connector->base.base.id);
 }
 
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 20dc705642bd..b5b0bf37813b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
 	 * @max_payloads: maximum number of payloads the GPU can generate.
 	 */
 	int max_payloads;
+	/**
+	 * @max_lane_count: maximum number of lanes the GPU can drive.
+	 */
+	int max_lane_count;
+	/**
+	 * @max_link_rate: maximum link rate per lane GPU can output.
+	 */
+	int max_link_rate;
 	/**
 	 * @conn_base_id: DRM connector ID this mgr is connected to. Only used
 	 * to build the MST connector path value.
@@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
 int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_device *dev, struct drm_dp_aux *aux,
 				 int max_dpcd_transaction_bytes,
-				 int max_payloads, int conn_base_id);
+				 int max_payloads,
+				 int max_lane_count, int max_link_rate,
+				 int conn_base_id);
 
 void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.25.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-28 23:43   ` Nikola Cornij
  0 siblings, 0 replies; 27+ messages in thread
From: Nikola Cornij @ 2021-04-28 23:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski, ville.syrjala

[why]
DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
set, Extended Base Receiver Capability DPCD space must be used. Without
doing that, the three DPCD values that differ will be wrong, leading to
incorrect or limited functionality. MST link rate, for example, could
have a lower value. Also, Synaptics quirk wouldn't work out well when
Extended DPCD was not read, resulting in no DSC for such hubs.

[how]
Modify MST topology manager to use the values from Extended DPCD where
applicable.

To prevent regression on the sources that have a lower maximum link rate
capability than MAX_LINK_RATE from Extended DPCD, have the drivers
supply maximum lane count and rate at initialization time.

This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
extended DPCD caps for topology manager")', brining the change back to
the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
caps for topology manager")'.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
 drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
 include/drm/drm_dp_mst_helper.h               | 12 ++++++-
 8 files changed, 71 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 997567f6f0ba..b7e01b6fb328 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 				       struct amdgpu_dm_connector *aconnector,
 				       int link_index)
 {
+	struct dc_link_settings max_link_enc_cap = {0};
+
 	aconnector->dm_dp_aux.aux.name =
 		kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
 			  link_index);
@@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 	if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
 		return;
 
+	dc_link_dp_get_max_link_enc_cap(aconnector->dc_link, &max_link_enc_cap);
 	aconnector->mst_mgr.cbs = &dm_mst_cbs;
 	drm_dp_mst_topology_mgr_init(
 		&aconnector->mst_mgr,
@@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 		&aconnector->dm_dp_aux.aux,
 		16,
 		4,
+		max_link_enc_cap.lane_count,
+		max_link_enc_cap.link_rate,
 		aconnector->connector_id);
 
 	drm_connector_attach_dp_subconnector_property(&aconnector->base);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 7d2e433c2275..6fe66b7ee53e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
 	return true;
 }
 
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
+{
+	if (!max_link_enc_cap) {
+		DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__);
+		return false;
+	}
+
+	if (link->link_enc->funcs->get_max_link_cap) {
+		link->link_enc->funcs->get_max_link_cap(link->link_enc, max_link_enc_cap);
+		return true;
+	}
+
+	DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
+	max_link_enc_cap->lane_count = 1;
+	max_link_enc_cap->link_rate = 6;
+	return false;
+}
+
 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 {
 	struct dc_link_settings max_link_cap = {0};
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index b0013e674864..cb6d0543d839 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
 	const unsigned char *p_custom_pattern,
 	unsigned int cust_pattern_size);
 
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap);
+
 void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
 
 bool dc_link_is_dp_sink_present(struct dc_link *link);
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5539a91b4031..31d9f3ff0d39 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
 	/* set the device into MST mode */
 	if (mst_state) {
 		struct drm_dp_payload reset_pay;
+		int lane_count;
+		int link_rate;
 
 		WARN_ON(mgr->mst_primary);
 
 		/* get dpcd info */
-		ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
-		if (ret != DP_RECEIVER_CAP_SIZE) {
-			drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
+		ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
+		if (ret < 0) {
+			drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret %d\n",
+				    mgr->aux->name, ret);
 			goto out_unlock;
 		}
 
+		lane_count = min_t(int, mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
+		link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
 		mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
-							drm_dp_bw_code_to_link_rate(mgr->dpcd[1]),
-							mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
+							drm_dp_bw_code_to_link_rate(link_rate),
+							lane_count);
 		if (mgr->pbn_div == 0) {
 			ret = -EINVAL;
 			goto out_unlock;
@@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
  * @aux: DP helper aux channel to talk to this device
  * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
  * @max_payloads: maximum number of payloads this GPU can source
+ * @max_lane_count: maximum number of lanes this GPU supports
+ * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
  * @conn_base_id: the connector object ID the MST device is connected to.
  *
  * Return 0 for success, or negative error code on failure
  */
 int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_device *dev, struct drm_dp_aux *aux,
-				 int max_dpcd_transaction_bytes,
-				 int max_payloads, int conn_base_id)
+				 int max_dpcd_transaction_bytes, int max_payloads,
+				 int max_lane_count, int max_link_rate,
+				 int conn_base_id)
 {
 	struct drm_dp_mst_topology_state *mst_state;
 
@@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	mgr->aux = aux;
 	mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
 	mgr->max_payloads = max_payloads;
+	mgr->max_lane_count = max_lane_count;
+	mgr->max_link_rate = max_link_rate;
 	mgr->conn_base_id = conn_base_id;
 	if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
 	    max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
@@ -5896,14 +5906,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 	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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
 
-		if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
-				     &downstreamport, 1) < 0)
+		if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
 			return NULL;
 
-		if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
-		   ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
+		if ((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;
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 860381d68d9d..a4245eb48ef4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
 	struct intel_dp *intel_dp = &dig_port->dp;
 	enum port port = dig_port->base.port;
 	int ret;
+	int bios_max_link_rate;
 
 	if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
 		return 0;
@@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
 
 	/* create encoders */
 	intel_dp_create_fake_mst_encoders(dig_port);
+	bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
 	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
-					   &intel_dp->aux, 16, 3, conn_base_id);
+					   &intel_dp->aux, 16, 3,
+					   dig_port->max_lanes,
+					   bios_max_link_rate / 27000, conn_base_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 1c9c0cdf85db..e02f9d2d74eb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
 	mstm->mgr.cbs = &nv50_mstm;
 
 	ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
-					   max_payloads, conn_base_id);
+					   max_payloads, outp->dcb->dpconf.link_nr,
+					   outp->dcb->dpconf.link_bw, conn_base_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 59cf1d288465..8f0b2dccd199 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -629,13 +629,20 @@ int
 radeon_dp_mst_init(struct radeon_connector *radeon_connector)
 {
 	struct drm_device *dev = radeon_connector->base.dev;
+	int max_link_rate;
 
 	if (!radeon_connector->ddc_bus->has_aux)
 		return 0;
 
+	if (radeon_connector_is_dp12_capable(&radeon_connector->base))
+		max_link_rate = 0x14;
+	else
+		max_link_rate = 0x0a;
+
 	radeon_connector->mst_mgr.cbs = &mst_cbs;
 	return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
 					    &radeon_connector->ddc_bus->aux, 16, 6,
+					    4, max_link_rate,
 					    radeon_connector->base.base.id);
 }
 
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 20dc705642bd..b5b0bf37813b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
 	 * @max_payloads: maximum number of payloads the GPU can generate.
 	 */
 	int max_payloads;
+	/**
+	 * @max_lane_count: maximum number of lanes the GPU can drive.
+	 */
+	int max_lane_count;
+	/**
+	 * @max_link_rate: maximum link rate per lane GPU can output.
+	 */
+	int max_link_rate;
 	/**
 	 * @conn_base_id: DRM connector ID this mgr is connected to. Only used
 	 * to build the MST connector path value.
@@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
 int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_device *dev, struct drm_dp_aux *aux,
 				 int max_dpcd_transaction_bytes,
-				 int max_payloads, int conn_base_id);
+				 int max_payloads,
+				 int max_lane_count, int max_link_rate,
+				 int conn_base_id);
 
 void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
 
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/drm_mst: Use Extended Base Receiver Capability (rev6)
  2021-04-28 23:43 ` [Intel-gfx] " Nikola Cornij
                   ` (2 preceding siblings ...)
  (?)
@ 2021-04-29  0:24 ` Patchwork
  -1 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2021-04-29  0:24 UTC (permalink / raw)
  To: Lyude Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/drm_mst: Use Extended Base Receiver Capability (rev6)
URL   : https://patchwork.freedesktop.org/series/89590/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
b5ab5edcae7a drm/drm_mst: Use Extended Base Receiver Capability DPCD space
-:22: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit 2dcab875e763 ("Revert "drm/dp_mst: Retrieve extended DPCD caps for topology manager"")'
#22: 
This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve

-:67: WARNING:LONG_LINE: line length of 107 exceeds 100 columns
#67: FILE: drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c:1897:
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)

-:96: WARNING:LONG_LINE: line length of 108 exceeds 100 columns
#96: FILE: drivers/gpu/drm/amd/display/dc/dc_link.h:349:
+bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap);

total: 1 errors, 2 warnings, 0 checks, 201 lines checked


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/drm_mst: Use Extended Base Receiver Capability (rev6)
  2021-04-28 23:43 ` [Intel-gfx] " Nikola Cornij
                   ` (3 preceding siblings ...)
  (?)
@ 2021-04-29  0:55 ` Patchwork
  -1 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2021-04-29  0:55 UTC (permalink / raw)
  To: Lyude Paul; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2111 bytes --]

== Series Details ==

Series: drm/drm_mst: Use Extended Base Receiver Capability (rev6)
URL   : https://patchwork.freedesktop.org/series/89590/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10023 -> Patchwork_20024
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/index.html

Known issues
------------

  Here are the changes found in Patchwork_20024 that come from known issues:

### IGT changes ###

#### Possible fixes ####

  * igt@kms_frontbuffer_tracking@basic:
    - {fi-rkl-11500t}:    [SKIP][1] ([i915#1849] / [i915#3180]) -> [PASS][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/fi-rkl-11500t/igt@kms_frontbuffer_tracking@basic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/fi-rkl-11500t/igt@kms_frontbuffer_tracking@basic.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [i915#1222]: https://gitlab.freedesktop.org/drm/intel/issues/1222
  [i915#1849]: https://gitlab.freedesktop.org/drm/intel/issues/1849
  [i915#3180]: https://gitlab.freedesktop.org/drm/intel/issues/3180
  [i915#3303]: https://gitlab.freedesktop.org/drm/intel/issues/3303


Participating hosts (44 -> 40)
------------------------------

  Missing    (4): fi-ilk-m540 fi-bsw-cyan fi-bdw-samus fi-hsw-4200u 


Build changes
-------------

  * Linux: CI_DRM_10023 -> Patchwork_20024

  CI-20190529: 20190529
  CI_DRM_10023: a8bf9e284933fa5c1cb821b48ba95821e5d1cc3f @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6076: 9ab0820dbd07781161c1ace6973ea222fd24e53a @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_20024: b5ab5edcae7a2347312cef42a07e71e39312b73c @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

b5ab5edcae7a drm/drm_mst: Use Extended Base Receiver Capability DPCD space

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/index.html

[-- Attachment #1.2: Type: text/html, Size: 2574 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Intel-gfx] ✗ Fi.CI.IGT: failure for drm/drm_mst: Use Extended Base Receiver Capability (rev6)
  2021-04-28 23:43 ` [Intel-gfx] " Nikola Cornij
                   ` (4 preceding siblings ...)
  (?)
@ 2021-04-29  2:12 ` Patchwork
  -1 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2021-04-29  2:12 UTC (permalink / raw)
  To: Lyude Paul; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 29622 bytes --]

== Series Details ==

Series: drm/drm_mst: Use Extended Base Receiver Capability (rev6)
URL   : https://patchwork.freedesktop.org/series/89590/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10023_full -> Patchwork_20024_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_20024_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_20024_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_20024_full:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_ccs@pipe-b-bad-rotation-90:
    - shard-tglb:         [PASS][1] -> [DMESG-WARN][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-tglb1/igt@kms_ccs@pipe-b-bad-rotation-90.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-tglb5/igt@kms_ccs@pipe-b-bad-rotation-90.html

  
Known issues
------------

  Here are the changes found in Patchwork_20024_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_create@create-massive:
    - shard-snb:          NOTRUN -> [DMESG-WARN][3] ([i915#3002])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-snb2/igt@gem_create@create-massive.html
    - shard-kbl:          NOTRUN -> [DMESG-WARN][4] ([i915#3002])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl1/igt@gem_create@create-massive.html

  * igt@gem_ctx_persistence@clone:
    - shard-snb:          NOTRUN -> [SKIP][5] ([fdo#109271] / [i915#1099]) +3 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-snb2/igt@gem_ctx_persistence@clone.html

  * igt@gem_ctx_shared@q-in-order:
    - shard-snb:          NOTRUN -> [SKIP][6] ([fdo#109271]) +272 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-snb6/igt@gem_ctx_shared@q-in-order.html

  * igt@gem_eio@in-flight-suspend:
    - shard-kbl:          [PASS][7] -> [DMESG-WARN][8] ([i915#180]) +2 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl3/igt@gem_eio@in-flight-suspend.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl4/igt@gem_eio@in-flight-suspend.html

  * igt@gem_eio@unwedge-stress:
    - shard-tglb:         [PASS][9] -> [TIMEOUT][10] ([i915#2369] / [i915#3063])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-tglb5/igt@gem_eio@unwedge-stress.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-tglb3/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_capture@pi@vecs0:
    - shard-skl:          NOTRUN -> [INCOMPLETE][11] ([i915#198] / [i915#2624])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl6/igt@gem_exec_capture@pi@vecs0.html

  * igt@gem_exec_fair@basic-deadline:
    - shard-apl:          NOTRUN -> [FAIL][12] ([i915#2846])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl8/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - shard-kbl:          NOTRUN -> [FAIL][13] ([i915#2842]) +1 similar issue
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl4/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-none@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][14] ([i915#2842])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb1/igt@gem_exec_fair@basic-none@vcs1.html

  * igt@gem_huc_copy@huc-copy:
    - shard-tglb:         [PASS][15] -> [SKIP][16] ([i915#2190])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-tglb5/igt@gem_huc_copy@huc-copy.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-tglb6/igt@gem_huc_copy@huc-copy.html

  * igt@gem_mmap_gtt@cpuset-big-copy-xy:
    - shard-iclb:         [PASS][17] -> [FAIL][18] ([i915#307])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb6/igt@gem_mmap_gtt@cpuset-big-copy-xy.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb2/igt@gem_mmap_gtt@cpuset-big-copy-xy.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-snb:          NOTRUN -> [WARN][19] ([i915#2658])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-snb6/igt@gem_pwrite@basic-exhaustion.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-kbl:          [PASS][20] -> [DMESG-WARN][21] ([i915#1436] / [i915#716])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl6/igt@gen9_exec_parse@allowed-all.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl6/igt@gen9_exec_parse@allowed-all.html

  * igt@gen9_exec_parse@bb-large:
    - shard-apl:          NOTRUN -> [FAIL][22] ([i915#3296])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@gen9_exec_parse@bb-large.html

  * igt@i915_pm_rpm@modeset-lpsp-stress-no-wait:
    - shard-kbl:          NOTRUN -> [SKIP][23] ([fdo#109271]) +139 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl2/igt@i915_pm_rpm@modeset-lpsp-stress-no-wait.html

  * igt@i915_selftest@live@blt:
    - shard-skl:          NOTRUN -> [FAIL][24] ([i915#2927])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl2/igt@i915_selftest@live@blt.html

  * igt@i915_selftest@live@gt_pm:
    - shard-skl:          NOTRUN -> [DMESG-FAIL][25] ([i915#1886] / [i915#2291])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl2/igt@i915_selftest@live@gt_pm.html

  * igt@kms_big_joiner@basic:
    - shard-apl:          NOTRUN -> [SKIP][26] ([fdo#109271] / [i915#2705])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@kms_big_joiner@basic.html

  * igt@kms_chamelium@dp-audio-edid:
    - shard-skl:          NOTRUN -> [SKIP][27] ([fdo#109271] / [fdo#111827]) +7 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl6/igt@kms_chamelium@dp-audio-edid.html

  * igt@kms_chamelium@hdmi-hpd-with-enabled-mode:
    - shard-snb:          NOTRUN -> [SKIP][28] ([fdo#109271] / [fdo#111827]) +16 similar issues
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-snb6/igt@kms_chamelium@hdmi-hpd-with-enabled-mode.html

  * igt@kms_chamelium@vga-hpd-enable-disable-mode:
    - shard-apl:          NOTRUN -> [SKIP][29] ([fdo#109271] / [fdo#111827]) +16 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl8/igt@kms_chamelium@vga-hpd-enable-disable-mode.html

  * igt@kms_color_chamelium@pipe-a-ctm-0-75:
    - shard-kbl:          NOTRUN -> [SKIP][30] ([fdo#109271] / [fdo#111827]) +11 similar issues
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl3/igt@kms_color_chamelium@pipe-a-ctm-0-75.html

  * igt@kms_content_protection@atomic-dpms:
    - shard-apl:          NOTRUN -> [TIMEOUT][31] ([i915#1319])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl7/igt@kms_content_protection@atomic-dpms.html
    - shard-kbl:          NOTRUN -> [TIMEOUT][32] ([i915#1319])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl3/igt@kms_content_protection@atomic-dpms.html

  * igt@kms_content_protection@uevent:
    - shard-kbl:          NOTRUN -> [FAIL][33] ([i915#2105])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl4/igt@kms_content_protection@uevent.html

  * igt@kms_cursor_crc@pipe-a-cursor-suspend:
    - shard-apl:          NOTRUN -> [DMESG-WARN][34] ([i915#180])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@kms_cursor_crc@pipe-a-cursor-suspend.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-skl:          [PASS][35] -> [FAIL][36] ([i915#2346])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl5/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_cursor_legacy@pipe-d-single-bo:
    - shard-kbl:          NOTRUN -> [SKIP][37] ([fdo#109271] / [i915#533]) +1 similar issue
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl3/igt@kms_cursor_legacy@pipe-d-single-bo.html

  * igt@kms_flip@flip-vs-suspend-interruptible@c-dp1:
    - shard-apl:          [PASS][38] -> [DMESG-WARN][39] ([i915#180]) +1 similar issue
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile:
    - shard-apl:          NOTRUN -> [SKIP][40] ([fdo#109271] / [i915#2642])
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-cpu:
    - shard-skl:          NOTRUN -> [SKIP][41] ([fdo#109271]) +56 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl6/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-cpu.html

  * igt@kms_hdr@bpc-switch:
    - shard-skl:          [PASS][42] -> [FAIL][43] ([i915#1188])
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl7/igt@kms_hdr@bpc-switch.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl1/igt@kms_hdr@bpc-switch.html

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-d:
    - shard-skl:          NOTRUN -> [SKIP][44] ([fdo#109271] / [i915#533])
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl6/igt@kms_pipe_crc_basic@hang-read-crc-pipe-d.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-d:
    - shard-apl:          NOTRUN -> [SKIP][45] ([fdo#109271] / [i915#533]) +1 similar issue
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl8/igt@kms_pipe_crc_basic@read-crc-pipe-d.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
    - shard-skl:          [PASS][46] -> [INCOMPLETE][47] ([i915#198])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl4/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl8/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
    - shard-apl:          NOTRUN -> [FAIL][48] ([fdo#108145] / [i915#265]) +2 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl3/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html
    - shard-kbl:          NOTRUN -> [FAIL][49] ([fdo#108145] / [i915#265]) +1 similar issue
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl3/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-transparent-fb:
    - shard-apl:          NOTRUN -> [FAIL][50] ([i915#265])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@kms_plane_alpha_blend@pipe-b-alpha-transparent-fb.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-1:
    - shard-apl:          NOTRUN -> [SKIP][51] ([fdo#109271] / [i915#658]) +3 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-1.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-2:
    - shard-kbl:          NOTRUN -> [SKIP][52] ([fdo#109271] / [i915#658]) +3 similar issues
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl3/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-2.html

  * igt@kms_psr2_su@page_flip:
    - shard-skl:          NOTRUN -> [SKIP][53] ([fdo#109271] / [i915#658])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl6/igt@kms_psr2_su@page_flip.html

  * igt@kms_psr@psr2_sprite_blt:
    - shard-iclb:         [PASS][54] -> [SKIP][55] ([fdo#109441]) +2 similar issues
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb2/igt@kms_psr@psr2_sprite_blt.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb4/igt@kms_psr@psr2_sprite_blt.html

  * igt@kms_vblank@pipe-d-ts-continuation-idle:
    - shard-apl:          NOTRUN -> [SKIP][56] ([fdo#109271]) +188 similar issues
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl3/igt@kms_vblank@pipe-d-ts-continuation-idle.html

  * igt@kms_writeback@writeback-invalid-parameters:
    - shard-kbl:          NOTRUN -> [SKIP][57] ([fdo#109271] / [i915#2437])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl1/igt@kms_writeback@writeback-invalid-parameters.html

  * igt@sysfs_clients@fair-7:
    - shard-kbl:          NOTRUN -> [SKIP][58] ([fdo#109271] / [i915#2994]) +1 similar issue
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl4/igt@sysfs_clients@fair-7.html

  * igt@sysfs_clients@split-50:
    - shard-apl:          NOTRUN -> [SKIP][59] ([fdo#109271] / [i915#2994])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl8/igt@sysfs_clients@split-50.html

  
#### Possible fixes ####

  * igt@gem_create@create-clear:
    - shard-iclb:         [FAIL][60] ([i915#3160]) -> [PASS][61]
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb1/igt@gem_create@create-clear.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb1/igt@gem_create@create-clear.html

  * igt@gem_exec_fair@basic-flow@rcs0:
    - shard-tglb:         [FAIL][62] ([i915#2842]) -> [PASS][63] +2 similar issues
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-tglb3/igt@gem_exec_fair@basic-flow@rcs0.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-tglb2/igt@gem_exec_fair@basic-flow@rcs0.html

  * igt@gem_exec_fair@basic-none-rrul@rcs0:
    - shard-glk:          [FAIL][64] ([i915#2842]) -> [PASS][65]
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-glk2/igt@gem_exec_fair@basic-none-rrul@rcs0.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-glk7/igt@gem_exec_fair@basic-none-rrul@rcs0.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-apl:          [FAIL][66] ([i915#2842]) -> [PASS][67]
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl6/igt@gem_exec_fair@basic-none@vecs0.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl7/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@gem_mmap_gtt@cpuset-basic-small-copy-xy:
    - shard-glk:          [FAIL][68] ([i915#307]) -> [PASS][69]
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-glk4/igt@gem_mmap_gtt@cpuset-basic-small-copy-xy.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-glk6/igt@gem_mmap_gtt@cpuset-basic-small-copy-xy.html

  * igt@i915_selftest@live@hangcheck:
    - shard-snb:          [INCOMPLETE][70] ([i915#2782]) -> [PASS][71]
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-snb6/igt@i915_selftest@live@hangcheck.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-snb2/igt@i915_selftest@live@hangcheck.html

  * igt@i915_suspend@fence-restore-untiled:
    - shard-apl:          [DMESG-WARN][72] ([i915#180]) -> [PASS][73]
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl1/igt@i915_suspend@fence-restore-untiled.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl7/igt@i915_suspend@fence-restore-untiled.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [INCOMPLETE][74] ([i915#180]) -> [PASS][75]
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl6/igt@kms_fbcon_fbt@fbc-suspend.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl8/igt@kms_fbcon_fbt@fbc-suspend.html
    - shard-kbl:          [INCOMPLETE][76] ([i915#155] / [i915#180] / [i915#636]) -> [PASS][77]
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl3/igt@kms_fbcon_fbt@fbc-suspend.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl2/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@flip-vs-expired-vblank@b-edp1:
    - shard-skl:          [FAIL][78] ([i915#79]) -> [PASS][79]
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl1/igt@kms_flip@flip-vs-expired-vblank@b-edp1.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl4/igt@kms_flip@flip-vs-expired-vblank@b-edp1.html

  * igt@kms_flip@flip-vs-suspend-interruptible@a-dp1:
    - shard-kbl:          [DMESG-WARN][80] ([i915#180]) -> [PASS][81] +7 similar issues
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl6/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl2/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html

  * igt@kms_flip@flip-vs-wf_vblank-interruptible@a-edp1:
    - shard-skl:          [FAIL][82] ([i915#2122]) -> [PASS][83]
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl7/igt@kms_flip@flip-vs-wf_vblank-interruptible@a-edp1.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl8/igt@kms_flip@flip-vs-wf_vblank-interruptible@a-edp1.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          [FAIL][84] ([i915#1188]) -> [PASS][85]
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl1/igt@kms_hdr@bpc-switch-dpms.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl10/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][86] ([fdo#108145] / [i915#265]) -> [PASS][87] +1 similar issue
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl2/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl8/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_render:
    - shard-iclb:         [SKIP][88] ([fdo#109441]) -> [PASS][89] +1 similar issue
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb6/igt@kms_psr@psr2_cursor_render.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb2/igt@kms_psr@psr2_cursor_render.html

  * igt@kms_universal_plane@universal-plane-gen9-features-pipe-a:
    - shard-skl:          [DMESG-WARN][90] ([i915#1982]) -> [PASS][91]
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl3/igt@kms_universal_plane@universal-plane-gen9-features-pipe-a.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl5/igt@kms_universal_plane@universal-plane-gen9-features-pipe-a.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-kbl:          [DMESG-WARN][92] ([i915#180] / [i915#295]) -> [PASS][93]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl1/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl7/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  
#### Warnings ####

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-iclb:         [WARN][94] ([i915#2684]) -> [WARN][95] ([i915#1804] / [i915#2684])
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb5/igt@i915_pm_rc6_residency@rc6-idle.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb7/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-4:
    - shard-iclb:         [SKIP][96] ([i915#658]) -> [SKIP][97] ([i915#2920]) +1 similar issue
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb6/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-4.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb2/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-4.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-4:
    - shard-iclb:         [SKIP][98] ([i915#2920]) -> [SKIP][99] ([i915#658]) +1 similar issue
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-iclb2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-4.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-iclb8/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-4.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][100], [FAIL][101], [FAIL][102], [FAIL][103], [FAIL][104], [FAIL][105], [FAIL][106], [FAIL][107], [FAIL][108], [FAIL][109], [FAIL][110]) ([i915#1436] / [i915#180] / [i915#1814] / [i915#2292] / [i915#2505] / [i915#3002] / [i915#602] / [i915#92]) -> ([FAIL][111], [FAIL][112], [FAIL][113], [FAIL][114], [FAIL][115], [FAIL][116], [FAIL][117], [FAIL][118], [FAIL][119]) ([fdo#109271] / [i915#1436] / [i915#180] / [i915#1814] / [i915#2505] / [i915#3002] / [i915#716])
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl3/igt@runner@aborted.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl3/igt@runner@aborted.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl7/igt@runner@aborted.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl7/igt@runner@aborted.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl4/igt@runner@aborted.html
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl1/igt@runner@aborted.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl6/igt@runner@aborted.html
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl6/igt@runner@aborted.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl4/igt@runner@aborted.html
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl1/igt@runner@aborted.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-kbl4/igt@runner@aborted.html
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl6/igt@runner@aborted.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl4/igt@runner@aborted.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl6/igt@runner@aborted.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl6/igt@runner@aborted.html
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl2/igt@runner@aborted.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl1/igt@runner@aborted.html
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl6/igt@runner@aborted.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl4/igt@runner@aborted.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-kbl7/igt@runner@aborted.html
    - shard-apl:          ([FAIL][120], [FAIL][121], [FAIL][122], [FAIL][123]) ([i915#180] / [i915#3002]) -> ([FAIL][124], [FAIL][125], [FAIL][126], [FAIL][127], [FAIL][128]) ([fdo#109271] / [i915#180] / [i915#1814] / [i915#3002])
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl1/igt@runner@aborted.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl6/igt@runner@aborted.html
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl6/igt@runner@aborted.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-apl1/igt@runner@aborted.html
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl6/igt@runner@aborted.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl6/igt@runner@aborted.html
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@runner@aborted.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl2/igt@runner@aborted.html
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-apl1/igt@runner@aborted.html
    - shard-skl:          ([FAIL][129], [FAIL][130]) ([i915#2029] / [i915#3002]) -> ([FAIL][131], [FAIL][132], [FAIL][133], [FAIL][134]) ([i915#1436] / [i915#1814] / [i915#2029] / [i915#3002])
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl3/igt@runner@aborted.html
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10023/shard-skl3/igt@runner@aborted.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl3/igt@runner@aborted.html
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl2/igt@runner@aborted.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl3/igt@runner@aborted.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/shard-skl5/igt@runner@aborted.html

  
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1099]: https://gitlab.freedesktop.org/drm/intel/issues/1099
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#155]: https://gitlab.freedesktop.org/drm/intel/issues/155
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1804]: https://gitlab.freedesktop.org/drm/intel/issues/1804
  [i915#1814]: https://gitlab.freedesktop.org/drm/intel/issues/1814
  [i915#1886]: https://gitlab.freedesktop.org/drm/intel/issues/1886
  [i915#198]: https://gitlab.freedesktop.org/drm/intel/issues/198
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2029]: https://gitlab.freedesktop.org/drm/intel/issues/2029
  [i915#2105]: https://gitlab.freedesktop.org/drm/intel/issues/2105
  [i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2291]: https://gitlab.freedesktop.org/drm/intel/issues/2291
  [i915#2292]: https://gitlab.freedesktop.org/drm/intel/issues/2292
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2369]: https://gitlab.freedesktop.org/drm/intel/issues/2369
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2505]: https://gitlab.freedesktop.org/drm/intel/issues/2505
  [i915#2624]: https://gitlab.freedesktop.org/drm/intel/issues/2624
  [i915#2642]: https://gitlab.freedesktop.org/drm/intel/issues/2642
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
  [i915#2684]: https://gitlab.freedesktop.org/drm/intel/issues/2684
  [i915#2705]: https://gitlab.freedesktop.org/drm/intel/issues/2705
  [i915#2782]: https://gitlab.freedesktop.org/drm/intel/issues/2782
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
  [i915#2920]: https://gitlab.freedesktop.org/drm/intel/issues/2920
  [i915#2927]: https://gitlab.freedesktop.org/drm/intel/issues/2927
  [i915#295]: https://gitlab.freedesktop.org/drm/intel/issues/295
  [i915#2994]: https://gitlab.freedesktop.org/drm/intel/issues/2994
  [i915#3002]: https://gitlab.freedesktop.org/drm/intel/issues/3002
  [i915#3063]: https://gitlab.freedesktop.org/drm/intel/issues/3063
  [i915#307]: https://gitlab.freedesktop.org/drm/intel/issues/307
  [i915#3160]: https://gitlab.freedesktop.org/drm/intel/issues/3160
  [i915#3296]: https://gitlab.freedesktop.org/drm/intel/issues/3296
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#602]: https://gitlab.freedesktop.org/drm/intel/issues/602
  [i915#636]: https://gitlab.freedesktop.org/drm/intel/issues/636
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92


Participating hosts (11 -> 11)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * Linux: CI_DRM_10023 -> Patchwork_20024

  CI-20190529: 20190529
  CI_DRM_10023: a8bf9e284933fa5c1cb821b48ba95821e5d1cc3f @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6076: 9ab0820dbd07781161c1ace6973ea222fd24e53a @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_20024: b5ab5edcae7a2347312cef42a07e71e39312b73c @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20024/index.html

[-- Attachment #1.2: Type: text/html, Size: 37202 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-04-28 23:43   ` [Intel-gfx] " Nikola Cornij
  (?)
@ 2021-04-29 19:00     ` Lyude Paul
  -1 siblings, 0 replies; 27+ messages in thread
From: Lyude Paul @ 2021-04-29 19:00 UTC (permalink / raw)
  To: Nikola Cornij, amd-gfx, Jani Nikula, Ben Skeggs
  Cc: intel-gfx, dri-devel, koba.ko, aurabindo.pillai, mikita.lipski

JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
today if there's no objections

On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
> [why]
> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> set, Extended Base Receiver Capability DPCD space must be used. Without
> doing that, the three DPCD values that differ will be wrong, leading to
> incorrect or limited functionality. MST link rate, for example, could
> have a lower value. Also, Synaptics quirk wouldn't work out well when
> Extended DPCD was not read, resulting in no DSC for such hubs.
> 
> [how]
> Modify MST topology manager to use the values from Extended DPCD where
> applicable.
> 
> To prevent regression on the sources that have a lower maximum link rate
> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> supply maximum lane count and rate at initialization time.
> 
> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> extended DPCD caps for topology manager")', brining the change back to
> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> caps for topology manager")'.
> 
> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>  8 files changed, 71 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 997567f6f0ba..b7e01b6fb328 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>                                        struct amdgpu_dm_connector
> *aconnector,
>                                        int link_index)
>  {
> +       struct dc_link_settings max_link_enc_cap = {0};
> +
>         aconnector->dm_dp_aux.aux.name =
>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>                           link_index);
> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>                 return;
>  
> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
> &max_link_enc_cap);
>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>         drm_dp_mst_topology_mgr_init(
>                 &aconnector->mst_mgr,
> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>                 &aconnector->dm_dp_aux.aux,
>                 16,
>                 4,
> +               max_link_enc_cap.lane_count,
> +               max_link_enc_cap.link_rate,
>                 aconnector->connector_id);
>  
>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> index 7d2e433c2275..6fe66b7ee53e 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
> bool link_down)
>         return true;
>  }
>  
> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> dc_link_settings *max_link_enc_cap)
> +{
> +       if (!max_link_enc_cap) {
> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
> __func__);
> +               return false;
> +       }
> +
> +       if (link->link_enc->funcs->get_max_link_cap) {
> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
> max_link_enc_cap);
> +               return true;
> +       }
> +
> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
> +       max_link_enc_cap->lane_count = 1;
> +       max_link_enc_cap->link_rate = 6;
> +       return false;
> +}
> +
>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>  {
>         struct dc_link_settings max_link_cap = {0};
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
> b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index b0013e674864..cb6d0543d839 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>         const unsigned char *p_custom_pattern,
>         unsigned int cust_pattern_size);
>  
> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> dc_link_settings *max_link_enc_cap);
> +
>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>  
>  bool dc_link_is_dp_sink_present(struct dc_link *link);
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 5539a91b4031..31d9f3ff0d39 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
> drm_dp_mst_topology_mgr *mgr, bool ms
>         /* set the device into MST mode */
>         if (mst_state) {
>                 struct drm_dp_payload reset_pay;
> +               int lane_count;
> +               int link_rate;
>  
>                 WARN_ON(mgr->mst_primary);
>  
>                 /* get dpcd info */
> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> DP_RECEIVER_CAP_SIZE);
> -               if (ret != DP_RECEIVER_CAP_SIZE) {
> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
> +               if (ret < 0) {
> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
> %d\n",
> +                                   mgr->aux->name, ret);
>                         goto out_unlock;
>                 }
>  
> +               lane_count = min_t(int, mgr->dpcd[2] &
> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
> -
>                                                        drm_dp_bw_code_to_link
> _rate(mgr->dpcd[1]),
> -                                                       mgr->dpcd[2] &
> DP_MAX_LANE_COUNT_MASK);
> +                                                       drm_dp_bw_code_to_li
> nk_rate(link_rate),
> +                                                       lane_count);
>                 if (mgr->pbn_div == 0) {
>                         ret = -EINVAL;
>                         goto out_unlock;
> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>   * @aux: DP helper aux channel to talk to this device
>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>   * @max_payloads: maximum number of payloads this GPU can source
> + * @max_lane_count: maximum number of lanes this GPU supports
> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>   * @conn_base_id: the connector object ID the MST device is connected to.
>   *
>   * Return 0 for success, or negative error code on failure
>   */
>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_device *dev, struct drm_dp_aux
> *aux,
> -                                int max_dpcd_transaction_bytes,
> -                                int max_payloads, int conn_base_id)
> +                                int max_dpcd_transaction_bytes, int
> max_payloads,
> +                                int max_lane_count, int max_link_rate,
> +                                int conn_base_id)
>  {
>         struct drm_dp_mst_topology_state *mst_state;
>  
> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         mgr->aux = aux;
>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>         mgr->max_payloads = max_payloads;
> +       mgr->max_lane_count = max_lane_count;
> +       mgr->max_link_rate = max_link_rate;
>         mgr->conn_base_id = conn_base_id;
>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>  
> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> -                                    &downstreamport, 1) < 0)
> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>                         return NULL;
>  
> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> +               if ((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;
>         }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 860381d68d9d..a4245eb48ef4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> *dig_port, int conn_base_id)
>         struct intel_dp *intel_dp = &dig_port->dp;
>         enum port port = dig_port->base.port;
>         int ret;
> +       int bios_max_link_rate;
>  
>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>                 return 0;
> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> *dig_port, int conn_base_id)
>  
>         /* create encoders */
>         intel_dp_create_fake_mst_encoders(dig_port);
> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> -                                          &intel_dp->aux, 16, 3,
> conn_base_id);
> +                                          &intel_dp->aux, 16, 3,
> +                                          dig_port->max_lanes,
> +                                          bios_max_link_rate / 27000,
> conn_base_id);
>         if (ret)
>                 return ret;
>  
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 1c9c0cdf85db..e02f9d2d74eb 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
> drm_dp_aux *aux, int aux_max,
>         mstm->mgr.cbs = &nv50_mstm;
>  
>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
> -                                          max_payloads, conn_base_id);
> +                                          max_payloads, outp->dcb-
> >dpconf.link_nr,
> +                                          outp->dcb->dpconf.link_bw,
> conn_base_id);
>         if (ret)
>                 return ret;
>  
> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> index 59cf1d288465..8f0b2dccd199 100644
> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> @@ -629,13 +629,20 @@ int
>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>  {
>         struct drm_device *dev = radeon_connector->base.dev;
> +       int max_link_rate;
>  
>         if (!radeon_connector->ddc_bus->has_aux)
>                 return 0;
>  
> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
> +               max_link_rate = 0x14;
> +       else
> +               max_link_rate = 0x0a;
> +
>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>                                             &radeon_connector->ddc_bus->aux,
> 16, 6,
> +                                           4, max_link_rate,
>                                             radeon_connector->base.base.id);
>  }
>  
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index 20dc705642bd..b5b0bf37813b 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>          * @max_payloads: maximum number of payloads the GPU can generate.
>          */
>         int max_payloads;
> +       /**
> +        * @max_lane_count: maximum number of lanes the GPU can drive.
> +        */
> +       int max_lane_count;
> +       /**
> +        * @max_link_rate: maximum link rate per lane GPU can output.
> +        */
> +       int max_link_rate;
>         /**
>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
> used
>          * to build the MST connector path value.
> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_device *dev, struct drm_dp_aux
> *aux,
>                                  int max_dpcd_transaction_bytes,
> -                                int max_payloads, int conn_base_id);
> +                                int max_payloads,
> +                                int max_lane_count, int max_link_rate,
> +                                int conn_base_id);
>  
>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>  

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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Intel-gfx] [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-29 19:00     ` Lyude Paul
  0 siblings, 0 replies; 27+ messages in thread
From: Lyude Paul @ 2021-04-29 19:00 UTC (permalink / raw)
  To: Nikola Cornij, amd-gfx, Jani Nikula, Ben Skeggs
  Cc: intel-gfx, dri-devel, koba.ko, aurabindo.pillai, mikita.lipski

JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
today if there's no objections

On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
> [why]
> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> set, Extended Base Receiver Capability DPCD space must be used. Without
> doing that, the three DPCD values that differ will be wrong, leading to
> incorrect or limited functionality. MST link rate, for example, could
> have a lower value. Also, Synaptics quirk wouldn't work out well when
> Extended DPCD was not read, resulting in no DSC for such hubs.
> 
> [how]
> Modify MST topology manager to use the values from Extended DPCD where
> applicable.
> 
> To prevent regression on the sources that have a lower maximum link rate
> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> supply maximum lane count and rate at initialization time.
> 
> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> extended DPCD caps for topology manager")', brining the change back to
> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> caps for topology manager")'.
> 
> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>  8 files changed, 71 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 997567f6f0ba..b7e01b6fb328 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>                                        struct amdgpu_dm_connector
> *aconnector,
>                                        int link_index)
>  {
> +       struct dc_link_settings max_link_enc_cap = {0};
> +
>         aconnector->dm_dp_aux.aux.name =
>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>                           link_index);
> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>                 return;
>  
> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
> &max_link_enc_cap);
>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>         drm_dp_mst_topology_mgr_init(
>                 &aconnector->mst_mgr,
> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>                 &aconnector->dm_dp_aux.aux,
>                 16,
>                 4,
> +               max_link_enc_cap.lane_count,
> +               max_link_enc_cap.link_rate,
>                 aconnector->connector_id);
>  
>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> index 7d2e433c2275..6fe66b7ee53e 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
> bool link_down)
>         return true;
>  }
>  
> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> dc_link_settings *max_link_enc_cap)
> +{
> +       if (!max_link_enc_cap) {
> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
> __func__);
> +               return false;
> +       }
> +
> +       if (link->link_enc->funcs->get_max_link_cap) {
> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
> max_link_enc_cap);
> +               return true;
> +       }
> +
> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
> +       max_link_enc_cap->lane_count = 1;
> +       max_link_enc_cap->link_rate = 6;
> +       return false;
> +}
> +
>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>  {
>         struct dc_link_settings max_link_cap = {0};
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
> b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index b0013e674864..cb6d0543d839 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>         const unsigned char *p_custom_pattern,
>         unsigned int cust_pattern_size);
>  
> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> dc_link_settings *max_link_enc_cap);
> +
>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>  
>  bool dc_link_is_dp_sink_present(struct dc_link *link);
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 5539a91b4031..31d9f3ff0d39 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
> drm_dp_mst_topology_mgr *mgr, bool ms
>         /* set the device into MST mode */
>         if (mst_state) {
>                 struct drm_dp_payload reset_pay;
> +               int lane_count;
> +               int link_rate;
>  
>                 WARN_ON(mgr->mst_primary);
>  
>                 /* get dpcd info */
> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> DP_RECEIVER_CAP_SIZE);
> -               if (ret != DP_RECEIVER_CAP_SIZE) {
> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
> +               if (ret < 0) {
> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
> %d\n",
> +                                   mgr->aux->name, ret);
>                         goto out_unlock;
>                 }
>  
> +               lane_count = min_t(int, mgr->dpcd[2] &
> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
> -
>                                                        drm_dp_bw_code_to_link
> _rate(mgr->dpcd[1]),
> -                                                       mgr->dpcd[2] &
> DP_MAX_LANE_COUNT_MASK);
> +                                                       drm_dp_bw_code_to_li
> nk_rate(link_rate),
> +                                                       lane_count);
>                 if (mgr->pbn_div == 0) {
>                         ret = -EINVAL;
>                         goto out_unlock;
> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>   * @aux: DP helper aux channel to talk to this device
>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>   * @max_payloads: maximum number of payloads this GPU can source
> + * @max_lane_count: maximum number of lanes this GPU supports
> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>   * @conn_base_id: the connector object ID the MST device is connected to.
>   *
>   * Return 0 for success, or negative error code on failure
>   */
>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_device *dev, struct drm_dp_aux
> *aux,
> -                                int max_dpcd_transaction_bytes,
> -                                int max_payloads, int conn_base_id)
> +                                int max_dpcd_transaction_bytes, int
> max_payloads,
> +                                int max_lane_count, int max_link_rate,
> +                                int conn_base_id)
>  {
>         struct drm_dp_mst_topology_state *mst_state;
>  
> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         mgr->aux = aux;
>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>         mgr->max_payloads = max_payloads;
> +       mgr->max_lane_count = max_lane_count;
> +       mgr->max_link_rate = max_link_rate;
>         mgr->conn_base_id = conn_base_id;
>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>  
> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> -                                    &downstreamport, 1) < 0)
> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>                         return NULL;
>  
> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> +               if ((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;
>         }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 860381d68d9d..a4245eb48ef4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> *dig_port, int conn_base_id)
>         struct intel_dp *intel_dp = &dig_port->dp;
>         enum port port = dig_port->base.port;
>         int ret;
> +       int bios_max_link_rate;
>  
>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>                 return 0;
> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> *dig_port, int conn_base_id)
>  
>         /* create encoders */
>         intel_dp_create_fake_mst_encoders(dig_port);
> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> -                                          &intel_dp->aux, 16, 3,
> conn_base_id);
> +                                          &intel_dp->aux, 16, 3,
> +                                          dig_port->max_lanes,
> +                                          bios_max_link_rate / 27000,
> conn_base_id);
>         if (ret)
>                 return ret;
>  
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 1c9c0cdf85db..e02f9d2d74eb 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
> drm_dp_aux *aux, int aux_max,
>         mstm->mgr.cbs = &nv50_mstm;
>  
>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
> -                                          max_payloads, conn_base_id);
> +                                          max_payloads, outp->dcb-
> >dpconf.link_nr,
> +                                          outp->dcb->dpconf.link_bw,
> conn_base_id);
>         if (ret)
>                 return ret;
>  
> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> index 59cf1d288465..8f0b2dccd199 100644
> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> @@ -629,13 +629,20 @@ int
>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>  {
>         struct drm_device *dev = radeon_connector->base.dev;
> +       int max_link_rate;
>  
>         if (!radeon_connector->ddc_bus->has_aux)
>                 return 0;
>  
> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
> +               max_link_rate = 0x14;
> +       else
> +               max_link_rate = 0x0a;
> +
>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>                                             &radeon_connector->ddc_bus->aux,
> 16, 6,
> +                                           4, max_link_rate,
>                                             radeon_connector->base.base.id);
>  }
>  
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index 20dc705642bd..b5b0bf37813b 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>          * @max_payloads: maximum number of payloads the GPU can generate.
>          */
>         int max_payloads;
> +       /**
> +        * @max_lane_count: maximum number of lanes the GPU can drive.
> +        */
> +       int max_lane_count;
> +       /**
> +        * @max_link_rate: maximum link rate per lane GPU can output.
> +        */
> +       int max_link_rate;
>         /**
>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
> used
>          * to build the MST connector path value.
> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_device *dev, struct drm_dp_aux
> *aux,
>                                  int max_dpcd_transaction_bytes,
> -                                int max_payloads, int conn_base_id);
> +                                int max_payloads,
> +                                int max_lane_count, int max_link_rate,
> +                                int conn_base_id);
>  
>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>  

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-29 19:00     ` Lyude Paul
  0 siblings, 0 replies; 27+ messages in thread
From: Lyude Paul @ 2021-04-29 19:00 UTC (permalink / raw)
  To: Nikola Cornij, amd-gfx, Jani Nikula, Ben Skeggs
  Cc: intel-gfx, dri-devel, koba.ko, aurabindo.pillai, mikita.lipski,
	ville.syrjala

JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
today if there's no objections

On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
> [why]
> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> set, Extended Base Receiver Capability DPCD space must be used. Without
> doing that, the three DPCD values that differ will be wrong, leading to
> incorrect or limited functionality. MST link rate, for example, could
> have a lower value. Also, Synaptics quirk wouldn't work out well when
> Extended DPCD was not read, resulting in no DSC for such hubs.
> 
> [how]
> Modify MST topology manager to use the values from Extended DPCD where
> applicable.
> 
> To prevent regression on the sources that have a lower maximum link rate
> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> supply maximum lane count and rate at initialization time.
> 
> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> extended DPCD caps for topology manager")', brining the change back to
> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> caps for topology manager")'.
> 
> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>  8 files changed, 71 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 997567f6f0ba..b7e01b6fb328 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>                                        struct amdgpu_dm_connector
> *aconnector,
>                                        int link_index)
>  {
> +       struct dc_link_settings max_link_enc_cap = {0};
> +
>         aconnector->dm_dp_aux.aux.name =
>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>                           link_index);
> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>                 return;
>  
> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
> &max_link_enc_cap);
>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>         drm_dp_mst_topology_mgr_init(
>                 &aconnector->mst_mgr,
> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> amdgpu_display_manager *dm,
>                 &aconnector->dm_dp_aux.aux,
>                 16,
>                 4,
> +               max_link_enc_cap.lane_count,
> +               max_link_enc_cap.link_rate,
>                 aconnector->connector_id);
>  
>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> index 7d2e433c2275..6fe66b7ee53e 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
> bool link_down)
>         return true;
>  }
>  
> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> dc_link_settings *max_link_enc_cap)
> +{
> +       if (!max_link_enc_cap) {
> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
> __func__);
> +               return false;
> +       }
> +
> +       if (link->link_enc->funcs->get_max_link_cap) {
> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
> max_link_enc_cap);
> +               return true;
> +       }
> +
> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
> +       max_link_enc_cap->lane_count = 1;
> +       max_link_enc_cap->link_rate = 6;
> +       return false;
> +}
> +
>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>  {
>         struct dc_link_settings max_link_cap = {0};
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
> b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index b0013e674864..cb6d0543d839 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>         const unsigned char *p_custom_pattern,
>         unsigned int cust_pattern_size);
>  
> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> dc_link_settings *max_link_enc_cap);
> +
>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>  
>  bool dc_link_is_dp_sink_present(struct dc_link *link);
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 5539a91b4031..31d9f3ff0d39 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
> drm_dp_mst_topology_mgr *mgr, bool ms
>         /* set the device into MST mode */
>         if (mst_state) {
>                 struct drm_dp_payload reset_pay;
> +               int lane_count;
> +               int link_rate;
>  
>                 WARN_ON(mgr->mst_primary);
>  
>                 /* get dpcd info */
> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> DP_RECEIVER_CAP_SIZE);
> -               if (ret != DP_RECEIVER_CAP_SIZE) {
> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
> +               if (ret < 0) {
> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
> %d\n",
> +                                   mgr->aux->name, ret);
>                         goto out_unlock;
>                 }
>  
> +               lane_count = min_t(int, mgr->dpcd[2] &
> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
> -
>                                                        drm_dp_bw_code_to_link
> _rate(mgr->dpcd[1]),
> -                                                       mgr->dpcd[2] &
> DP_MAX_LANE_COUNT_MASK);
> +                                                       drm_dp_bw_code_to_li
> nk_rate(link_rate),
> +                                                       lane_count);
>                 if (mgr->pbn_div == 0) {
>                         ret = -EINVAL;
>                         goto out_unlock;
> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>   * @aux: DP helper aux channel to talk to this device
>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>   * @max_payloads: maximum number of payloads this GPU can source
> + * @max_lane_count: maximum number of lanes this GPU supports
> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>   * @conn_base_id: the connector object ID the MST device is connected to.
>   *
>   * Return 0 for success, or negative error code on failure
>   */
>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_device *dev, struct drm_dp_aux
> *aux,
> -                                int max_dpcd_transaction_bytes,
> -                                int max_payloads, int conn_base_id)
> +                                int max_dpcd_transaction_bytes, int
> max_payloads,
> +                                int max_lane_count, int max_link_rate,
> +                                int conn_base_id)
>  {
>         struct drm_dp_mst_topology_state *mst_state;
>  
> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
> drm_dp_mst_topology_mgr *mgr,
>         mgr->aux = aux;
>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>         mgr->max_payloads = max_payloads;
> +       mgr->max_lane_count = max_lane_count;
> +       mgr->max_link_rate = max_link_rate;
>         mgr->conn_base_id = conn_base_id;
>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>  
> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> -                                    &downstreamport, 1) < 0)
> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>                         return NULL;
>  
> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> +               if ((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;
>         }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 860381d68d9d..a4245eb48ef4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> *dig_port, int conn_base_id)
>         struct intel_dp *intel_dp = &dig_port->dp;
>         enum port port = dig_port->base.port;
>         int ret;
> +       int bios_max_link_rate;
>  
>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>                 return 0;
> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> *dig_port, int conn_base_id)
>  
>         /* create encoders */
>         intel_dp_create_fake_mst_encoders(dig_port);
> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> -                                          &intel_dp->aux, 16, 3,
> conn_base_id);
> +                                          &intel_dp->aux, 16, 3,
> +                                          dig_port->max_lanes,
> +                                          bios_max_link_rate / 27000,
> conn_base_id);
>         if (ret)
>                 return ret;
>  
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 1c9c0cdf85db..e02f9d2d74eb 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
> drm_dp_aux *aux, int aux_max,
>         mstm->mgr.cbs = &nv50_mstm;
>  
>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
> -                                          max_payloads, conn_base_id);
> +                                          max_payloads, outp->dcb-
> >dpconf.link_nr,
> +                                          outp->dcb->dpconf.link_bw,
> conn_base_id);
>         if (ret)
>                 return ret;
>  
> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> index 59cf1d288465..8f0b2dccd199 100644
> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> @@ -629,13 +629,20 @@ int
>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>  {
>         struct drm_device *dev = radeon_connector->base.dev;
> +       int max_link_rate;
>  
>         if (!radeon_connector->ddc_bus->has_aux)
>                 return 0;
>  
> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
> +               max_link_rate = 0x14;
> +       else
> +               max_link_rate = 0x0a;
> +
>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>                                             &radeon_connector->ddc_bus->aux,
> 16, 6,
> +                                           4, max_link_rate,
>                                             radeon_connector->base.base.id);
>  }
>  
> diff --git a/include/drm/drm_dp_mst_helper.h
> b/include/drm/drm_dp_mst_helper.h
> index 20dc705642bd..b5b0bf37813b 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>          * @max_payloads: maximum number of payloads the GPU can generate.
>          */
>         int max_payloads;
> +       /**
> +        * @max_lane_count: maximum number of lanes the GPU can drive.
> +        */
> +       int max_lane_count;
> +       /**
> +        * @max_link_rate: maximum link rate per lane GPU can output.
> +        */
> +       int max_link_rate;
>         /**
>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
> used
>          * to build the MST connector path value.
> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>                                  struct drm_device *dev, struct drm_dp_aux
> *aux,
>                                  int max_dpcd_transaction_bytes,
> -                                int max_payloads, int conn_base_id);
> +                                int max_payloads,
> +                                int max_lane_count, int max_link_rate,
> +                                int conn_base_id);
>  
>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>  

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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-04-28 23:43   ` [Intel-gfx] " Nikola Cornij
  (?)
@ 2021-04-30  5:43     ` Jani Nikula
  -1 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-04-30  5:43 UTC (permalink / raw)
  To: Nikola Cornij, amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski

On Wed, 28 Apr 2021, Nikola Cornij <nikola.cornij@amd.com> wrote:
> [why]
> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> set, Extended Base Receiver Capability DPCD space must be used. Without
> doing that, the three DPCD values that differ will be wrong, leading to
> incorrect or limited functionality. MST link rate, for example, could
> have a lower value. Also, Synaptics quirk wouldn't work out well when
> Extended DPCD was not read, resulting in no DSC for such hubs.
>
> [how]
> Modify MST topology manager to use the values from Extended DPCD where
> applicable.
>
> To prevent regression on the sources that have a lower maximum link rate
> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> supply maximum lane count and rate at initialization time.
>
> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> extended DPCD caps for topology manager")', brining the change back to
> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> caps for topology manager")'.
>
> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>  8 files changed, 71 insertions(+), 15 deletions(-)


> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 860381d68d9d..a4245eb48ef4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
>  	struct intel_dp *intel_dp = &dig_port->dp;
>  	enum port port = dig_port->base.port;
>  	int ret;
> +	int bios_max_link_rate;
>  
>  	if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>  		return 0;
> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
>  
>  	/* create encoders */
>  	intel_dp_create_fake_mst_encoders(dig_port);
> +	bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);

Wait, what? This can return 0, and usually does. This is an optional
limitation, and is generally only used if there's a need to have a
smaller max link rate than the max the platform supports. We call this
in one single place, and are not looking to add another call site.

I haven't had my doze of coffee this morning, but at a glance, I think
this will break MST for most i915 users.

See intel_dp->source_rates[] and intel_dp->num_source_rates for all the
rates the source supports, initialized at encoder
init. intel_dp->source_rates[intel_dp->num_source_rates - 1] would be
the max.

Also, I suggest using kHz for rates throughout, and specifically not the
DPCD "units". Otherwise, this is just another thing that needs fixing
with the DP 2.0 UHBR rates where the bandwidth codes don't follow the
same pattern.

Ten versions of the patch, with a benign looking subject, and none of
the i915 maintainers in Cc. Not cool.


BR,
Jani.


>  	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> -					   &intel_dp->aux, 16, 3, conn_base_id);
> +					   &intel_dp->aux, 16, 3,
> +					   dig_port->max_lanes,
> +					   bios_max_link_rate / 27000, conn_base_id);
>  	if (ret)
>  		return ret;
>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-30  5:43     ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-04-30  5:43 UTC (permalink / raw)
  To: Nikola Cornij, amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski

On Wed, 28 Apr 2021, Nikola Cornij <nikola.cornij@amd.com> wrote:
> [why]
> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> set, Extended Base Receiver Capability DPCD space must be used. Without
> doing that, the three DPCD values that differ will be wrong, leading to
> incorrect or limited functionality. MST link rate, for example, could
> have a lower value. Also, Synaptics quirk wouldn't work out well when
> Extended DPCD was not read, resulting in no DSC for such hubs.
>
> [how]
> Modify MST topology manager to use the values from Extended DPCD where
> applicable.
>
> To prevent regression on the sources that have a lower maximum link rate
> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> supply maximum lane count and rate at initialization time.
>
> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> extended DPCD caps for topology manager")', brining the change back to
> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> caps for topology manager")'.
>
> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>  8 files changed, 71 insertions(+), 15 deletions(-)


> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 860381d68d9d..a4245eb48ef4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
>  	struct intel_dp *intel_dp = &dig_port->dp;
>  	enum port port = dig_port->base.port;
>  	int ret;
> +	int bios_max_link_rate;
>  
>  	if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>  		return 0;
> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
>  
>  	/* create encoders */
>  	intel_dp_create_fake_mst_encoders(dig_port);
> +	bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);

Wait, what? This can return 0, and usually does. This is an optional
limitation, and is generally only used if there's a need to have a
smaller max link rate than the max the platform supports. We call this
in one single place, and are not looking to add another call site.

I haven't had my doze of coffee this morning, but at a glance, I think
this will break MST for most i915 users.

See intel_dp->source_rates[] and intel_dp->num_source_rates for all the
rates the source supports, initialized at encoder
init. intel_dp->source_rates[intel_dp->num_source_rates - 1] would be
the max.

Also, I suggest using kHz for rates throughout, and specifically not the
DPCD "units". Otherwise, this is just another thing that needs fixing
with the DP 2.0 UHBR rates where the bandwidth codes don't follow the
same pattern.

Ten versions of the patch, with a benign looking subject, and none of
the i915 maintainers in Cc. Not cool.


BR,
Jani.


>  	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> -					   &intel_dp->aux, 16, 3, conn_base_id);
> +					   &intel_dp->aux, 16, 3,
> +					   dig_port->max_lanes,
> +					   bios_max_link_rate / 27000, conn_base_id);
>  	if (ret)
>  		return ret;
>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-30  5:43     ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-04-30  5:43 UTC (permalink / raw)
  To: Nikola Cornij, amd-gfx
  Cc: intel-gfx, dri-devel, Nikola Cornij, koba.ko, aurabindo.pillai,
	mikita.lipski, Ville Syrjälä

On Wed, 28 Apr 2021, Nikola Cornij <nikola.cornij@amd.com> wrote:
> [why]
> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> set, Extended Base Receiver Capability DPCD space must be used. Without
> doing that, the three DPCD values that differ will be wrong, leading to
> incorrect or limited functionality. MST link rate, for example, could
> have a lower value. Also, Synaptics quirk wouldn't work out well when
> Extended DPCD was not read, resulting in no DSC for such hubs.
>
> [how]
> Modify MST topology manager to use the values from Extended DPCD where
> applicable.
>
> To prevent regression on the sources that have a lower maximum link rate
> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> supply maximum lane count and rate at initialization time.
>
> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> extended DPCD caps for topology manager")', brining the change back to
> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> caps for topology manager")'.
>
> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>  8 files changed, 71 insertions(+), 15 deletions(-)


> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 860381d68d9d..a4245eb48ef4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
>  	struct intel_dp *intel_dp = &dig_port->dp;
>  	enum port port = dig_port->base.port;
>  	int ret;
> +	int bios_max_link_rate;
>  
>  	if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>  		return 0;
> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
>  
>  	/* create encoders */
>  	intel_dp_create_fake_mst_encoders(dig_port);
> +	bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);

Wait, what? This can return 0, and usually does. This is an optional
limitation, and is generally only used if there's a need to have a
smaller max link rate than the max the platform supports. We call this
in one single place, and are not looking to add another call site.

I haven't had my doze of coffee this morning, but at a glance, I think
this will break MST for most i915 users.

See intel_dp->source_rates[] and intel_dp->num_source_rates for all the
rates the source supports, initialized at encoder
init. intel_dp->source_rates[intel_dp->num_source_rates - 1] would be
the max.

Also, I suggest using kHz for rates throughout, and specifically not the
DPCD "units". Otherwise, this is just another thing that needs fixing
with the DP 2.0 UHBR rates where the bandwidth codes don't follow the
same pattern.

Ten versions of the patch, with a benign looking subject, and none of
the i915 maintainers in Cc. Not cool.


BR,
Jani.


>  	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> -					   &intel_dp->aux, 16, 3, conn_base_id);
> +					   &intel_dp->aux, 16, 3,
> +					   dig_port->max_lanes,
> +					   bios_max_link_rate / 27000, conn_base_id);
>  	if (ret)
>  		return ret;
>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-04-29 19:00     ` [Intel-gfx] " Lyude Paul
  (?)
@ 2021-04-30  5:44       ` Jani Nikula
  -1 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-04-30  5:44 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: intel-gfx, dri-devel, koba.ko, aurabindo.pillai, mikita.lipski

On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
> today if there's no objections

Thanks for the heads-up, I think this breaks i915. See my review
comments elsewhere in the thread.

BR,
Jani.


>
> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>> [why]
>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>> set, Extended Base Receiver Capability DPCD space must be used. Without
>> doing that, the three DPCD values that differ will be wrong, leading to
>> incorrect or limited functionality. MST link rate, for example, could
>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>> Extended DPCD was not read, resulting in no DSC for such hubs.
>> 
>> [how]
>> Modify MST topology manager to use the values from Extended DPCD where
>> applicable.
>> 
>> To prevent regression on the sources that have a lower maximum link rate
>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>> supply maximum lane count and rate at initialization time.
>> 
>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>> extended DPCD caps for topology manager")', brining the change back to
>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>> caps for topology manager")'.
>> 
>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>> ---
>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>  8 files changed, 71 insertions(+), 15 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> index 997567f6f0ba..b7e01b6fb328 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>                                        struct amdgpu_dm_connector
>> *aconnector,
>>                                        int link_index)
>>  {
>> +       struct dc_link_settings max_link_enc_cap = {0};
>> +
>>         aconnector->dm_dp_aux.aux.name =
>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>                           link_index);
>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>                 return;
>>  
>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>> &max_link_enc_cap);
>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>         drm_dp_mst_topology_mgr_init(
>>                 &aconnector->mst_mgr,
>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>                 &aconnector->dm_dp_aux.aux,
>>                 16,
>>                 4,
>> +               max_link_enc_cap.lane_count,
>> +               max_link_enc_cap.link_rate,
>>                 aconnector->connector_id);
>>  
>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> index 7d2e433c2275..6fe66b7ee53e 100644
>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>> bool link_down)
>>         return true;
>>  }
>>  
>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>> dc_link_settings *max_link_enc_cap)
>> +{
>> +       if (!max_link_enc_cap) {
>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>> __func__);
>> +               return false;
>> +       }
>> +
>> +       if (link->link_enc->funcs->get_max_link_cap) {
>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>> max_link_enc_cap);
>> +               return true;
>> +       }
>> +
>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>> +       max_link_enc_cap->lane_count = 1;
>> +       max_link_enc_cap->link_rate = 6;
>> +       return false;
>> +}
>> +
>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>  {
>>         struct dc_link_settings max_link_cap = {0};
>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>> index b0013e674864..cb6d0543d839 100644
>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>         const unsigned char *p_custom_pattern,
>>         unsigned int cust_pattern_size);
>>  
>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>> dc_link_settings *max_link_enc_cap);
>> +
>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>  
>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>> index 5539a91b4031..31d9f3ff0d39 100644
>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>> drm_dp_mst_topology_mgr *mgr, bool ms
>>         /* set the device into MST mode */
>>         if (mst_state) {
>>                 struct drm_dp_payload reset_pay;
>> +               int lane_count;
>> +               int link_rate;
>>  
>>                 WARN_ON(mgr->mst_primary);
>>  
>>                 /* get dpcd info */
>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>> DP_RECEIVER_CAP_SIZE);
>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>> +               if (ret < 0) {
>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>> %d\n",
>> +                                   mgr->aux->name, ret);
>>                         goto out_unlock;
>>                 }
>>  
>> +               lane_count = min_t(int, mgr->dpcd[2] &
>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>> -
>>                                                        drm_dp_bw_code_to_link
>> _rate(mgr->dpcd[1]),
>> -                                                       mgr->dpcd[2] &
>> DP_MAX_LANE_COUNT_MASK);
>> +                                                       drm_dp_bw_code_to_li
>> nk_rate(link_rate),
>> +                                                       lane_count);
>>                 if (mgr->pbn_div == 0) {
>>                         ret = -EINVAL;
>>                         goto out_unlock;
>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>   * @aux: DP helper aux channel to talk to this device
>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>   * @max_payloads: maximum number of payloads this GPU can source
>> + * @max_lane_count: maximum number of lanes this GPU supports
>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>   *
>>   * Return 0 for success, or negative error code on failure
>>   */
>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_device *dev, struct drm_dp_aux
>> *aux,
>> -                                int max_dpcd_transaction_bytes,
>> -                                int max_payloads, int conn_base_id)
>> +                                int max_dpcd_transaction_bytes, int
>> max_payloads,
>> +                                int max_lane_count, int max_link_rate,
>> +                                int conn_base_id)
>>  {
>>         struct drm_dp_mst_topology_state *mst_state;
>>  
>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>> drm_dp_mst_topology_mgr *mgr,
>>         mgr->aux = aux;
>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>         mgr->max_payloads = max_payloads;
>> +       mgr->max_lane_count = max_lane_count;
>> +       mgr->max_link_rate = max_link_rate;
>>         mgr->conn_base_id = conn_base_id;
>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>  
>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>> -                                    &downstreamport, 1) < 0)
>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>                         return NULL;
>>  
>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>> +               if ((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;
>>         }
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> index 860381d68d9d..a4245eb48ef4 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>> *dig_port, int conn_base_id)
>>         struct intel_dp *intel_dp = &dig_port->dp;
>>         enum port port = dig_port->base.port;
>>         int ret;
>> +       int bios_max_link_rate;
>>  
>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>                 return 0;
>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>> *dig_port, int conn_base_id)
>>  
>>         /* create encoders */
>>         intel_dp_create_fake_mst_encoders(dig_port);
>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>> -                                          &intel_dp->aux, 16, 3,
>> conn_base_id);
>> +                                          &intel_dp->aux, 16, 3,
>> +                                          dig_port->max_lanes,
>> +                                          bios_max_link_rate / 27000,
>> conn_base_id);
>>         if (ret)
>>                 return ret;
>>  
>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>> drm_dp_aux *aux, int aux_max,
>>         mstm->mgr.cbs = &nv50_mstm;
>>  
>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>> -                                          max_payloads, conn_base_id);
>> +                                          max_payloads, outp->dcb-
>> >dpconf.link_nr,
>> +                                          outp->dcb->dpconf.link_bw,
>> conn_base_id);
>>         if (ret)
>>                 return ret;
>>  
>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> index 59cf1d288465..8f0b2dccd199 100644
>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> @@ -629,13 +629,20 @@ int
>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>  {
>>         struct drm_device *dev = radeon_connector->base.dev;
>> +       int max_link_rate;
>>  
>>         if (!radeon_connector->ddc_bus->has_aux)
>>                 return 0;
>>  
>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>> +               max_link_rate = 0x14;
>> +       else
>> +               max_link_rate = 0x0a;
>> +
>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>                                             &radeon_connector->ddc_bus->aux,
>> 16, 6,
>> +                                           4, max_link_rate,
>>                                             radeon_connector->base.base.id);
>>  }
>>  
>> diff --git a/include/drm/drm_dp_mst_helper.h
>> b/include/drm/drm_dp_mst_helper.h
>> index 20dc705642bd..b5b0bf37813b 100644
>> --- a/include/drm/drm_dp_mst_helper.h
>> +++ b/include/drm/drm_dp_mst_helper.h
>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>          */
>>         int max_payloads;
>> +       /**
>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>> +        */
>> +       int max_lane_count;
>> +       /**
>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>> +        */
>> +       int max_link_rate;
>>         /**
>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>> used
>>          * to build the MST connector path value.
>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_device *dev, struct drm_dp_aux
>> *aux,
>>                                  int max_dpcd_transaction_bytes,
>> -                                int max_payloads, int conn_base_id);
>> +                                int max_payloads,
>> +                                int max_lane_count, int max_link_rate,
>> +                                int conn_base_id);
>>  
>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-30  5:44       ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-04-30  5:44 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: intel-gfx, dri-devel, koba.ko, aurabindo.pillai, mikita.lipski

On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
> today if there's no objections

Thanks for the heads-up, I think this breaks i915. See my review
comments elsewhere in the thread.

BR,
Jani.


>
> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>> [why]
>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>> set, Extended Base Receiver Capability DPCD space must be used. Without
>> doing that, the three DPCD values that differ will be wrong, leading to
>> incorrect or limited functionality. MST link rate, for example, could
>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>> Extended DPCD was not read, resulting in no DSC for such hubs.
>> 
>> [how]
>> Modify MST topology manager to use the values from Extended DPCD where
>> applicable.
>> 
>> To prevent regression on the sources that have a lower maximum link rate
>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>> supply maximum lane count and rate at initialization time.
>> 
>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>> extended DPCD caps for topology manager")', brining the change back to
>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>> caps for topology manager")'.
>> 
>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>> ---
>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>  8 files changed, 71 insertions(+), 15 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> index 997567f6f0ba..b7e01b6fb328 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>                                        struct amdgpu_dm_connector
>> *aconnector,
>>                                        int link_index)
>>  {
>> +       struct dc_link_settings max_link_enc_cap = {0};
>> +
>>         aconnector->dm_dp_aux.aux.name =
>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>                           link_index);
>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>                 return;
>>  
>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>> &max_link_enc_cap);
>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>         drm_dp_mst_topology_mgr_init(
>>                 &aconnector->mst_mgr,
>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>                 &aconnector->dm_dp_aux.aux,
>>                 16,
>>                 4,
>> +               max_link_enc_cap.lane_count,
>> +               max_link_enc_cap.link_rate,
>>                 aconnector->connector_id);
>>  
>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> index 7d2e433c2275..6fe66b7ee53e 100644
>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>> bool link_down)
>>         return true;
>>  }
>>  
>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>> dc_link_settings *max_link_enc_cap)
>> +{
>> +       if (!max_link_enc_cap) {
>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>> __func__);
>> +               return false;
>> +       }
>> +
>> +       if (link->link_enc->funcs->get_max_link_cap) {
>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>> max_link_enc_cap);
>> +               return true;
>> +       }
>> +
>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>> +       max_link_enc_cap->lane_count = 1;
>> +       max_link_enc_cap->link_rate = 6;
>> +       return false;
>> +}
>> +
>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>  {
>>         struct dc_link_settings max_link_cap = {0};
>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>> index b0013e674864..cb6d0543d839 100644
>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>         const unsigned char *p_custom_pattern,
>>         unsigned int cust_pattern_size);
>>  
>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>> dc_link_settings *max_link_enc_cap);
>> +
>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>  
>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>> index 5539a91b4031..31d9f3ff0d39 100644
>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>> drm_dp_mst_topology_mgr *mgr, bool ms
>>         /* set the device into MST mode */
>>         if (mst_state) {
>>                 struct drm_dp_payload reset_pay;
>> +               int lane_count;
>> +               int link_rate;
>>  
>>                 WARN_ON(mgr->mst_primary);
>>  
>>                 /* get dpcd info */
>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>> DP_RECEIVER_CAP_SIZE);
>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>> +               if (ret < 0) {
>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>> %d\n",
>> +                                   mgr->aux->name, ret);
>>                         goto out_unlock;
>>                 }
>>  
>> +               lane_count = min_t(int, mgr->dpcd[2] &
>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>> -
>>                                                        drm_dp_bw_code_to_link
>> _rate(mgr->dpcd[1]),
>> -                                                       mgr->dpcd[2] &
>> DP_MAX_LANE_COUNT_MASK);
>> +                                                       drm_dp_bw_code_to_li
>> nk_rate(link_rate),
>> +                                                       lane_count);
>>                 if (mgr->pbn_div == 0) {
>>                         ret = -EINVAL;
>>                         goto out_unlock;
>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>   * @aux: DP helper aux channel to talk to this device
>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>   * @max_payloads: maximum number of payloads this GPU can source
>> + * @max_lane_count: maximum number of lanes this GPU supports
>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>   *
>>   * Return 0 for success, or negative error code on failure
>>   */
>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_device *dev, struct drm_dp_aux
>> *aux,
>> -                                int max_dpcd_transaction_bytes,
>> -                                int max_payloads, int conn_base_id)
>> +                                int max_dpcd_transaction_bytes, int
>> max_payloads,
>> +                                int max_lane_count, int max_link_rate,
>> +                                int conn_base_id)
>>  {
>>         struct drm_dp_mst_topology_state *mst_state;
>>  
>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>> drm_dp_mst_topology_mgr *mgr,
>>         mgr->aux = aux;
>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>         mgr->max_payloads = max_payloads;
>> +       mgr->max_lane_count = max_lane_count;
>> +       mgr->max_link_rate = max_link_rate;
>>         mgr->conn_base_id = conn_base_id;
>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>  
>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>> -                                    &downstreamport, 1) < 0)
>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>                         return NULL;
>>  
>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>> +               if ((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;
>>         }
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> index 860381d68d9d..a4245eb48ef4 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>> *dig_port, int conn_base_id)
>>         struct intel_dp *intel_dp = &dig_port->dp;
>>         enum port port = dig_port->base.port;
>>         int ret;
>> +       int bios_max_link_rate;
>>  
>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>                 return 0;
>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>> *dig_port, int conn_base_id)
>>  
>>         /* create encoders */
>>         intel_dp_create_fake_mst_encoders(dig_port);
>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>> -                                          &intel_dp->aux, 16, 3,
>> conn_base_id);
>> +                                          &intel_dp->aux, 16, 3,
>> +                                          dig_port->max_lanes,
>> +                                          bios_max_link_rate / 27000,
>> conn_base_id);
>>         if (ret)
>>                 return ret;
>>  
>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>> drm_dp_aux *aux, int aux_max,
>>         mstm->mgr.cbs = &nv50_mstm;
>>  
>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>> -                                          max_payloads, conn_base_id);
>> +                                          max_payloads, outp->dcb-
>> >dpconf.link_nr,
>> +                                          outp->dcb->dpconf.link_bw,
>> conn_base_id);
>>         if (ret)
>>                 return ret;
>>  
>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> index 59cf1d288465..8f0b2dccd199 100644
>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> @@ -629,13 +629,20 @@ int
>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>  {
>>         struct drm_device *dev = radeon_connector->base.dev;
>> +       int max_link_rate;
>>  
>>         if (!radeon_connector->ddc_bus->has_aux)
>>                 return 0;
>>  
>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>> +               max_link_rate = 0x14;
>> +       else
>> +               max_link_rate = 0x0a;
>> +
>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>                                             &radeon_connector->ddc_bus->aux,
>> 16, 6,
>> +                                           4, max_link_rate,
>>                                             radeon_connector->base.base.id);
>>  }
>>  
>> diff --git a/include/drm/drm_dp_mst_helper.h
>> b/include/drm/drm_dp_mst_helper.h
>> index 20dc705642bd..b5b0bf37813b 100644
>> --- a/include/drm/drm_dp_mst_helper.h
>> +++ b/include/drm/drm_dp_mst_helper.h
>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>          */
>>         int max_payloads;
>> +       /**
>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>> +        */
>> +       int max_lane_count;
>> +       /**
>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>> +        */
>> +       int max_link_rate;
>>         /**
>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>> used
>>          * to build the MST connector path value.
>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_device *dev, struct drm_dp_aux
>> *aux,
>>                                  int max_dpcd_transaction_bytes,
>> -                                int max_payloads, int conn_base_id);
>> +                                int max_payloads,
>> +                                int max_lane_count, int max_link_rate,
>> +                                int conn_base_id);
>>  
>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-04-30  5:44       ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-04-30  5:44 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: intel-gfx, dri-devel, koba.ko, aurabindo.pillai, mikita.lipski,
	ville.syrjala

On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
> today if there's no objections

Thanks for the heads-up, I think this breaks i915. See my review
comments elsewhere in the thread.

BR,
Jani.


>
> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>> [why]
>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>> set, Extended Base Receiver Capability DPCD space must be used. Without
>> doing that, the three DPCD values that differ will be wrong, leading to
>> incorrect or limited functionality. MST link rate, for example, could
>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>> Extended DPCD was not read, resulting in no DSC for such hubs.
>> 
>> [how]
>> Modify MST topology manager to use the values from Extended DPCD where
>> applicable.
>> 
>> To prevent regression on the sources that have a lower maximum link rate
>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>> supply maximum lane count and rate at initialization time.
>> 
>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>> extended DPCD caps for topology manager")', brining the change back to
>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>> caps for topology manager")'.
>> 
>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>> ---
>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>  8 files changed, 71 insertions(+), 15 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> index 997567f6f0ba..b7e01b6fb328 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>                                        struct amdgpu_dm_connector
>> *aconnector,
>>                                        int link_index)
>>  {
>> +       struct dc_link_settings max_link_enc_cap = {0};
>> +
>>         aconnector->dm_dp_aux.aux.name =
>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>                           link_index);
>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>                 return;
>>  
>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>> &max_link_enc_cap);
>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>         drm_dp_mst_topology_mgr_init(
>>                 &aconnector->mst_mgr,
>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>> amdgpu_display_manager *dm,
>>                 &aconnector->dm_dp_aux.aux,
>>                 16,
>>                 4,
>> +               max_link_enc_cap.lane_count,
>> +               max_link_enc_cap.link_rate,
>>                 aconnector->connector_id);
>>  
>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> index 7d2e433c2275..6fe66b7ee53e 100644
>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>> bool link_down)
>>         return true;
>>  }
>>  
>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>> dc_link_settings *max_link_enc_cap)
>> +{
>> +       if (!max_link_enc_cap) {
>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>> __func__);
>> +               return false;
>> +       }
>> +
>> +       if (link->link_enc->funcs->get_max_link_cap) {
>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>> max_link_enc_cap);
>> +               return true;
>> +       }
>> +
>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>> +       max_link_enc_cap->lane_count = 1;
>> +       max_link_enc_cap->link_rate = 6;
>> +       return false;
>> +}
>> +
>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>  {
>>         struct dc_link_settings max_link_cap = {0};
>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>> index b0013e674864..cb6d0543d839 100644
>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>         const unsigned char *p_custom_pattern,
>>         unsigned int cust_pattern_size);
>>  
>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>> dc_link_settings *max_link_enc_cap);
>> +
>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>  
>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>> index 5539a91b4031..31d9f3ff0d39 100644
>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>> drm_dp_mst_topology_mgr *mgr, bool ms
>>         /* set the device into MST mode */
>>         if (mst_state) {
>>                 struct drm_dp_payload reset_pay;
>> +               int lane_count;
>> +               int link_rate;
>>  
>>                 WARN_ON(mgr->mst_primary);
>>  
>>                 /* get dpcd info */
>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>> DP_RECEIVER_CAP_SIZE);
>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>> +               if (ret < 0) {
>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>> %d\n",
>> +                                   mgr->aux->name, ret);
>>                         goto out_unlock;
>>                 }
>>  
>> +               lane_count = min_t(int, mgr->dpcd[2] &
>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>> -
>>                                                        drm_dp_bw_code_to_link
>> _rate(mgr->dpcd[1]),
>> -                                                       mgr->dpcd[2] &
>> DP_MAX_LANE_COUNT_MASK);
>> +                                                       drm_dp_bw_code_to_li
>> nk_rate(link_rate),
>> +                                                       lane_count);
>>                 if (mgr->pbn_div == 0) {
>>                         ret = -EINVAL;
>>                         goto out_unlock;
>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>   * @aux: DP helper aux channel to talk to this device
>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>   * @max_payloads: maximum number of payloads this GPU can source
>> + * @max_lane_count: maximum number of lanes this GPU supports
>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>   *
>>   * Return 0 for success, or negative error code on failure
>>   */
>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_device *dev, struct drm_dp_aux
>> *aux,
>> -                                int max_dpcd_transaction_bytes,
>> -                                int max_payloads, int conn_base_id)
>> +                                int max_dpcd_transaction_bytes, int
>> max_payloads,
>> +                                int max_lane_count, int max_link_rate,
>> +                                int conn_base_id)
>>  {
>>         struct drm_dp_mst_topology_state *mst_state;
>>  
>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>> drm_dp_mst_topology_mgr *mgr,
>>         mgr->aux = aux;
>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>         mgr->max_payloads = max_payloads;
>> +       mgr->max_lane_count = max_lane_count;
>> +       mgr->max_link_rate = max_link_rate;
>>         mgr->conn_base_id = conn_base_id;
>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>  
>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>> -                                    &downstreamport, 1) < 0)
>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>                         return NULL;
>>  
>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>> +               if ((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;
>>         }
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> index 860381d68d9d..a4245eb48ef4 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>> *dig_port, int conn_base_id)
>>         struct intel_dp *intel_dp = &dig_port->dp;
>>         enum port port = dig_port->base.port;
>>         int ret;
>> +       int bios_max_link_rate;
>>  
>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>                 return 0;
>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>> *dig_port, int conn_base_id)
>>  
>>         /* create encoders */
>>         intel_dp_create_fake_mst_encoders(dig_port);
>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>> -                                          &intel_dp->aux, 16, 3,
>> conn_base_id);
>> +                                          &intel_dp->aux, 16, 3,
>> +                                          dig_port->max_lanes,
>> +                                          bios_max_link_rate / 27000,
>> conn_base_id);
>>         if (ret)
>>                 return ret;
>>  
>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>> drm_dp_aux *aux, int aux_max,
>>         mstm->mgr.cbs = &nv50_mstm;
>>  
>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>> -                                          max_payloads, conn_base_id);
>> +                                          max_payloads, outp->dcb-
>> >dpconf.link_nr,
>> +                                          outp->dcb->dpconf.link_bw,
>> conn_base_id);
>>         if (ret)
>>                 return ret;
>>  
>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> index 59cf1d288465..8f0b2dccd199 100644
>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>> @@ -629,13 +629,20 @@ int
>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>  {
>>         struct drm_device *dev = radeon_connector->base.dev;
>> +       int max_link_rate;
>>  
>>         if (!radeon_connector->ddc_bus->has_aux)
>>                 return 0;
>>  
>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>> +               max_link_rate = 0x14;
>> +       else
>> +               max_link_rate = 0x0a;
>> +
>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>                                             &radeon_connector->ddc_bus->aux,
>> 16, 6,
>> +                                           4, max_link_rate,
>>                                             radeon_connector->base.base.id);
>>  }
>>  
>> diff --git a/include/drm/drm_dp_mst_helper.h
>> b/include/drm/drm_dp_mst_helper.h
>> index 20dc705642bd..b5b0bf37813b 100644
>> --- a/include/drm/drm_dp_mst_helper.h
>> +++ b/include/drm/drm_dp_mst_helper.h
>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>          */
>>         int max_payloads;
>> +       /**
>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>> +        */
>> +       int max_lane_count;
>> +       /**
>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>> +        */
>> +       int max_link_rate;
>>         /**
>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>> used
>>          * to build the MST connector path value.
>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>                                  struct drm_device *dev, struct drm_dp_aux
>> *aux,
>>                                  int max_dpcd_transaction_bytes,
>> -                                int max_payloads, int conn_base_id);
>> +                                int max_payloads,
>> +                                int max_lane_count, int max_link_rate,
>> +                                int conn_base_id);
>>  
>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-04-30  5:44       ` [Intel-gfx] " Jani Nikula
  (?)
@ 2021-05-03  8:33         ` Jani Nikula
  -1 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-05-03  8:33 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: Daniel Vetter, intel-gfx, dri-devel, koba.ko, aurabindo.pillai,
	Lankhorst, Maarten, Thomas Zimmermann, mikita.lipski

On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
>> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
>> today if there's no objections
>
> Thanks for the heads-up, I think this breaks i915. See my review
> comments elsewhere in the thread.

Looks like this was merged anyway.

98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")

I'm not happy how this played out.

1) You need to Cc relevant people

2) You need to get the ack before merging changes

3) You need to give people more than a day to react, with time zones and
all; I replied as soon as I saw the heads-up, but it was already too
late

It's broken on i915, and perhaps that could be fixed.

However I also think using DP spec rate codes and calling them "rate" is
a bad interface, especially when the unit breaks down with DP 2.0 rate
codes. It's confusing and it's not future proof. Fixing that afterwards
falls to whoever comes next to pick up the pieces.

I'd rather just see this reverted and redone.


BR,
Jani.


>
> BR,
> Jani.
>
>
>>
>> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>>> [why]
>>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>>> set, Extended Base Receiver Capability DPCD space must be used. Without
>>> doing that, the three DPCD values that differ will be wrong, leading to
>>> incorrect or limited functionality. MST link rate, for example, could
>>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>>> Extended DPCD was not read, resulting in no DSC for such hubs.
>>> 
>>> [how]
>>> Modify MST topology manager to use the values from Extended DPCD where
>>> applicable.
>>> 
>>> To prevent regression on the sources that have a lower maximum link rate
>>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>>> supply maximum lane count and rate at initialization time.
>>> 
>>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>>> extended DPCD caps for topology manager")', brining the change back to
>>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>>> caps for topology manager")'.
>>> 
>>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>>> ---
>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>>  8 files changed, 71 insertions(+), 15 deletions(-)
>>> 
>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> index 997567f6f0ba..b7e01b6fb328 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>                                        struct amdgpu_dm_connector
>>> *aconnector,
>>>                                        int link_index)
>>>  {
>>> +       struct dc_link_settings max_link_enc_cap = {0};
>>> +
>>>         aconnector->dm_dp_aux.aux.name =
>>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>>                           link_index);
>>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>>                 return;
>>>  
>>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>>> &max_link_enc_cap);
>>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>>         drm_dp_mst_topology_mgr_init(
>>>                 &aconnector->mst_mgr,
>>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>                 &aconnector->dm_dp_aux.aux,
>>>                 16,
>>>                 4,
>>> +               max_link_enc_cap.lane_count,
>>> +               max_link_enc_cap.link_rate,
>>>                 aconnector->connector_id);
>>>  
>>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> index 7d2e433c2275..6fe66b7ee53e 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>>> bool link_down)
>>>         return true;
>>>  }
>>>  
>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>> dc_link_settings *max_link_enc_cap)
>>> +{
>>> +       if (!max_link_enc_cap) {
>>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>>> __func__);
>>> +               return false;
>>> +       }
>>> +
>>> +       if (link->link_enc->funcs->get_max_link_cap) {
>>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>>> max_link_enc_cap);
>>> +               return true;
>>> +       }
>>> +
>>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>>> +       max_link_enc_cap->lane_count = 1;
>>> +       max_link_enc_cap->link_rate = 6;
>>> +       return false;
>>> +}
>>> +
>>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>>  {
>>>         struct dc_link_settings max_link_cap = {0};
>>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> index b0013e674864..cb6d0543d839 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>>         const unsigned char *p_custom_pattern,
>>>         unsigned int cust_pattern_size);
>>>  
>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>> dc_link_settings *max_link_enc_cap);
>>> +
>>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>>  
>>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> index 5539a91b4031..31d9f3ff0d39 100644
>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>>> drm_dp_mst_topology_mgr *mgr, bool ms
>>>         /* set the device into MST mode */
>>>         if (mst_state) {
>>>                 struct drm_dp_payload reset_pay;
>>> +               int lane_count;
>>> +               int link_rate;
>>>  
>>>                 WARN_ON(mgr->mst_primary);
>>>  
>>>                 /* get dpcd info */
>>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>>> DP_RECEIVER_CAP_SIZE);
>>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>>> +               if (ret < 0) {
>>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>>> %d\n",
>>> +                                   mgr->aux->name, ret);
>>>                         goto out_unlock;
>>>                 }
>>>  
>>> +               lane_count = min_t(int, mgr->dpcd[2] &
>>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>>> -
>>>                                                        drm_dp_bw_code_to_link
>>> _rate(mgr->dpcd[1]),
>>> -                                                       mgr->dpcd[2] &
>>> DP_MAX_LANE_COUNT_MASK);
>>> +                                                       drm_dp_bw_code_to_li
>>> nk_rate(link_rate),
>>> +                                                       lane_count);
>>>                 if (mgr->pbn_div == 0) {
>>>                         ret = -EINVAL;
>>>                         goto out_unlock;
>>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>>   * @aux: DP helper aux channel to talk to this device
>>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>>   * @max_payloads: maximum number of payloads this GPU can source
>>> + * @max_lane_count: maximum number of lanes this GPU supports
>>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>>   *
>>>   * Return 0 for success, or negative error code on failure
>>>   */
>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>                                  struct drm_device *dev, struct drm_dp_aux
>>> *aux,
>>> -                                int max_dpcd_transaction_bytes,
>>> -                                int max_payloads, int conn_base_id)
>>> +                                int max_dpcd_transaction_bytes, int
>>> max_payloads,
>>> +                                int max_lane_count, int max_link_rate,
>>> +                                int conn_base_id)
>>>  {
>>>         struct drm_dp_mst_topology_state *mst_state;
>>>  
>>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>         mgr->aux = aux;
>>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>>         mgr->max_payloads = max_payloads;
>>> +       mgr->max_lane_count = max_lane_count;
>>> +       mgr->max_link_rate = max_link_rate;
>>>         mgr->conn_base_id = conn_base_id;
>>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>>  
>>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>>> -                                    &downstreamport, 1) < 0)
>>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>>                         return NULL;
>>>  
>>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>>> +               if ((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;
>>>         }
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> index 860381d68d9d..a4245eb48ef4 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>> *dig_port, int conn_base_id)
>>>         struct intel_dp *intel_dp = &dig_port->dp;
>>>         enum port port = dig_port->base.port;
>>>         int ret;
>>> +       int bios_max_link_rate;
>>>  
>>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>>                 return 0;
>>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>> *dig_port, int conn_base_id)
>>>  
>>>         /* create encoders */
>>>         intel_dp_create_fake_mst_encoders(dig_port);
>>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>>> -                                          &intel_dp->aux, 16, 3,
>>> conn_base_id);
>>> +                                          &intel_dp->aux, 16, 3,
>>> +                                          dig_port->max_lanes,
>>> +                                          bios_max_link_rate / 27000,
>>> conn_base_id);
>>>         if (ret)
>>>                 return ret;
>>>  
>>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>>> drm_dp_aux *aux, int aux_max,
>>>         mstm->mgr.cbs = &nv50_mstm;
>>>  
>>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>>> -                                          max_payloads, conn_base_id);
>>> +                                          max_payloads, outp->dcb-
>>> >dpconf.link_nr,
>>> +                                          outp->dcb->dpconf.link_bw,
>>> conn_base_id);
>>>         if (ret)
>>>                 return ret;
>>>  
>>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> index 59cf1d288465..8f0b2dccd199 100644
>>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> @@ -629,13 +629,20 @@ int
>>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>>  {
>>>         struct drm_device *dev = radeon_connector->base.dev;
>>> +       int max_link_rate;
>>>  
>>>         if (!radeon_connector->ddc_bus->has_aux)
>>>                 return 0;
>>>  
>>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>>> +               max_link_rate = 0x14;
>>> +       else
>>> +               max_link_rate = 0x0a;
>>> +
>>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>>                                             &radeon_connector->ddc_bus->aux,
>>> 16, 6,
>>> +                                           4, max_link_rate,
>>>                                             radeon_connector->base.base.id);
>>>  }
>>>  
>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>> b/include/drm/drm_dp_mst_helper.h
>>> index 20dc705642bd..b5b0bf37813b 100644
>>> --- a/include/drm/drm_dp_mst_helper.h
>>> +++ b/include/drm/drm_dp_mst_helper.h
>>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>>          */
>>>         int max_payloads;
>>> +       /**
>>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>>> +        */
>>> +       int max_lane_count;
>>> +       /**
>>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>>> +        */
>>> +       int max_link_rate;
>>>         /**
>>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>>> used
>>>          * to build the MST connector path value.
>>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>                                  struct drm_device *dev, struct drm_dp_aux
>>> *aux,
>>>                                  int max_dpcd_transaction_bytes,
>>> -                                int max_payloads, int conn_base_id);
>>> +                                int max_payloads,
>>> +                                int max_lane_count, int max_link_rate,
>>> +                                int conn_base_id);
>>>  
>>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-05-03  8:33         ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-05-03  8:33 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: Maxime Ripard, Daniel Vetter, intel-gfx, dri-devel, koba.ko,
	aurabindo.pillai, Lankhorst, Maarten, Thomas Zimmermann,
	mikita.lipski

On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
>> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
>> today if there's no objections
>
> Thanks for the heads-up, I think this breaks i915. See my review
> comments elsewhere in the thread.

Looks like this was merged anyway.

98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")

I'm not happy how this played out.

1) You need to Cc relevant people

2) You need to get the ack before merging changes

3) You need to give people more than a day to react, with time zones and
all; I replied as soon as I saw the heads-up, but it was already too
late

It's broken on i915, and perhaps that could be fixed.

However I also think using DP spec rate codes and calling them "rate" is
a bad interface, especially when the unit breaks down with DP 2.0 rate
codes. It's confusing and it's not future proof. Fixing that afterwards
falls to whoever comes next to pick up the pieces.

I'd rather just see this reverted and redone.


BR,
Jani.


>
> BR,
> Jani.
>
>
>>
>> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>>> [why]
>>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>>> set, Extended Base Receiver Capability DPCD space must be used. Without
>>> doing that, the three DPCD values that differ will be wrong, leading to
>>> incorrect or limited functionality. MST link rate, for example, could
>>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>>> Extended DPCD was not read, resulting in no DSC for such hubs.
>>> 
>>> [how]
>>> Modify MST topology manager to use the values from Extended DPCD where
>>> applicable.
>>> 
>>> To prevent regression on the sources that have a lower maximum link rate
>>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>>> supply maximum lane count and rate at initialization time.
>>> 
>>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>>> extended DPCD caps for topology manager")', brining the change back to
>>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>>> caps for topology manager")'.
>>> 
>>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>>> ---
>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>>  8 files changed, 71 insertions(+), 15 deletions(-)
>>> 
>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> index 997567f6f0ba..b7e01b6fb328 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>                                        struct amdgpu_dm_connector
>>> *aconnector,
>>>                                        int link_index)
>>>  {
>>> +       struct dc_link_settings max_link_enc_cap = {0};
>>> +
>>>         aconnector->dm_dp_aux.aux.name =
>>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>>                           link_index);
>>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>>                 return;
>>>  
>>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>>> &max_link_enc_cap);
>>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>>         drm_dp_mst_topology_mgr_init(
>>>                 &aconnector->mst_mgr,
>>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>                 &aconnector->dm_dp_aux.aux,
>>>                 16,
>>>                 4,
>>> +               max_link_enc_cap.lane_count,
>>> +               max_link_enc_cap.link_rate,
>>>                 aconnector->connector_id);
>>>  
>>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> index 7d2e433c2275..6fe66b7ee53e 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>>> bool link_down)
>>>         return true;
>>>  }
>>>  
>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>> dc_link_settings *max_link_enc_cap)
>>> +{
>>> +       if (!max_link_enc_cap) {
>>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>>> __func__);
>>> +               return false;
>>> +       }
>>> +
>>> +       if (link->link_enc->funcs->get_max_link_cap) {
>>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>>> max_link_enc_cap);
>>> +               return true;
>>> +       }
>>> +
>>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>>> +       max_link_enc_cap->lane_count = 1;
>>> +       max_link_enc_cap->link_rate = 6;
>>> +       return false;
>>> +}
>>> +
>>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>>  {
>>>         struct dc_link_settings max_link_cap = {0};
>>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> index b0013e674864..cb6d0543d839 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>>         const unsigned char *p_custom_pattern,
>>>         unsigned int cust_pattern_size);
>>>  
>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>> dc_link_settings *max_link_enc_cap);
>>> +
>>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>>  
>>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> index 5539a91b4031..31d9f3ff0d39 100644
>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>>> drm_dp_mst_topology_mgr *mgr, bool ms
>>>         /* set the device into MST mode */
>>>         if (mst_state) {
>>>                 struct drm_dp_payload reset_pay;
>>> +               int lane_count;
>>> +               int link_rate;
>>>  
>>>                 WARN_ON(mgr->mst_primary);
>>>  
>>>                 /* get dpcd info */
>>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>>> DP_RECEIVER_CAP_SIZE);
>>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>>> +               if (ret < 0) {
>>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>>> %d\n",
>>> +                                   mgr->aux->name, ret);
>>>                         goto out_unlock;
>>>                 }
>>>  
>>> +               lane_count = min_t(int, mgr->dpcd[2] &
>>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>>> -
>>>                                                        drm_dp_bw_code_to_link
>>> _rate(mgr->dpcd[1]),
>>> -                                                       mgr->dpcd[2] &
>>> DP_MAX_LANE_COUNT_MASK);
>>> +                                                       drm_dp_bw_code_to_li
>>> nk_rate(link_rate),
>>> +                                                       lane_count);
>>>                 if (mgr->pbn_div == 0) {
>>>                         ret = -EINVAL;
>>>                         goto out_unlock;
>>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>>   * @aux: DP helper aux channel to talk to this device
>>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>>   * @max_payloads: maximum number of payloads this GPU can source
>>> + * @max_lane_count: maximum number of lanes this GPU supports
>>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>>   *
>>>   * Return 0 for success, or negative error code on failure
>>>   */
>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>                                  struct drm_device *dev, struct drm_dp_aux
>>> *aux,
>>> -                                int max_dpcd_transaction_bytes,
>>> -                                int max_payloads, int conn_base_id)
>>> +                                int max_dpcd_transaction_bytes, int
>>> max_payloads,
>>> +                                int max_lane_count, int max_link_rate,
>>> +                                int conn_base_id)
>>>  {
>>>         struct drm_dp_mst_topology_state *mst_state;
>>>  
>>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>         mgr->aux = aux;
>>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>>         mgr->max_payloads = max_payloads;
>>> +       mgr->max_lane_count = max_lane_count;
>>> +       mgr->max_link_rate = max_link_rate;
>>>         mgr->conn_base_id = conn_base_id;
>>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>>  
>>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>>> -                                    &downstreamport, 1) < 0)
>>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>>                         return NULL;
>>>  
>>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>>> +               if ((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;
>>>         }
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> index 860381d68d9d..a4245eb48ef4 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>> *dig_port, int conn_base_id)
>>>         struct intel_dp *intel_dp = &dig_port->dp;
>>>         enum port port = dig_port->base.port;
>>>         int ret;
>>> +       int bios_max_link_rate;
>>>  
>>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>>                 return 0;
>>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>> *dig_port, int conn_base_id)
>>>  
>>>         /* create encoders */
>>>         intel_dp_create_fake_mst_encoders(dig_port);
>>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>>> -                                          &intel_dp->aux, 16, 3,
>>> conn_base_id);
>>> +                                          &intel_dp->aux, 16, 3,
>>> +                                          dig_port->max_lanes,
>>> +                                          bios_max_link_rate / 27000,
>>> conn_base_id);
>>>         if (ret)
>>>                 return ret;
>>>  
>>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>>> drm_dp_aux *aux, int aux_max,
>>>         mstm->mgr.cbs = &nv50_mstm;
>>>  
>>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>>> -                                          max_payloads, conn_base_id);
>>> +                                          max_payloads, outp->dcb-
>>> >dpconf.link_nr,
>>> +                                          outp->dcb->dpconf.link_bw,
>>> conn_base_id);
>>>         if (ret)
>>>                 return ret;
>>>  
>>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> index 59cf1d288465..8f0b2dccd199 100644
>>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> @@ -629,13 +629,20 @@ int
>>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>>  {
>>>         struct drm_device *dev = radeon_connector->base.dev;
>>> +       int max_link_rate;
>>>  
>>>         if (!radeon_connector->ddc_bus->has_aux)
>>>                 return 0;
>>>  
>>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>>> +               max_link_rate = 0x14;
>>> +       else
>>> +               max_link_rate = 0x0a;
>>> +
>>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>>                                             &radeon_connector->ddc_bus->aux,
>>> 16, 6,
>>> +                                           4, max_link_rate,
>>>                                             radeon_connector->base.base.id);
>>>  }
>>>  
>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>> b/include/drm/drm_dp_mst_helper.h
>>> index 20dc705642bd..b5b0bf37813b 100644
>>> --- a/include/drm/drm_dp_mst_helper.h
>>> +++ b/include/drm/drm_dp_mst_helper.h
>>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>>          */
>>>         int max_payloads;
>>> +       /**
>>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>>> +        */
>>> +       int max_lane_count;
>>> +       /**
>>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>>> +        */
>>> +       int max_link_rate;
>>>         /**
>>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>>> used
>>>          * to build the MST connector path value.
>>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>                                  struct drm_device *dev, struct drm_dp_aux
>>> *aux,
>>>                                  int max_dpcd_transaction_bytes,
>>> -                                int max_payloads, int conn_base_id);
>>> +                                int max_payloads,
>>> +                                int max_lane_count, int max_link_rate,
>>> +                                int conn_base_id);
>>>  
>>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-05-03  8:33         ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-05-03  8:33 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: Maxime Ripard, Daniel Vetter, intel-gfx, dri-devel, koba.ko,
	aurabindo.pillai, Lankhorst, Maarten, Thomas Zimmermann,
	mikita.lipski, Dave Airlie, ville.syrjala

On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
>> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
>> today if there's no objections
>
> Thanks for the heads-up, I think this breaks i915. See my review
> comments elsewhere in the thread.

Looks like this was merged anyway.

98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")

I'm not happy how this played out.

1) You need to Cc relevant people

2) You need to get the ack before merging changes

3) You need to give people more than a day to react, with time zones and
all; I replied as soon as I saw the heads-up, but it was already too
late

It's broken on i915, and perhaps that could be fixed.

However I also think using DP spec rate codes and calling them "rate" is
a bad interface, especially when the unit breaks down with DP 2.0 rate
codes. It's confusing and it's not future proof. Fixing that afterwards
falls to whoever comes next to pick up the pieces.

I'd rather just see this reverted and redone.


BR,
Jani.


>
> BR,
> Jani.
>
>
>>
>> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>>> [why]
>>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>>> set, Extended Base Receiver Capability DPCD space must be used. Without
>>> doing that, the three DPCD values that differ will be wrong, leading to
>>> incorrect or limited functionality. MST link rate, for example, could
>>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>>> Extended DPCD was not read, resulting in no DSC for such hubs.
>>> 
>>> [how]
>>> Modify MST topology manager to use the values from Extended DPCD where
>>> applicable.
>>> 
>>> To prevent regression on the sources that have a lower maximum link rate
>>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>>> supply maximum lane count and rate at initialization time.
>>> 
>>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>>> extended DPCD caps for topology manager")', brining the change back to
>>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>>> caps for topology manager")'.
>>> 
>>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>>> ---
>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>>  8 files changed, 71 insertions(+), 15 deletions(-)
>>> 
>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> index 997567f6f0ba..b7e01b6fb328 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>                                        struct amdgpu_dm_connector
>>> *aconnector,
>>>                                        int link_index)
>>>  {
>>> +       struct dc_link_settings max_link_enc_cap = {0};
>>> +
>>>         aconnector->dm_dp_aux.aux.name =
>>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>>                           link_index);
>>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>>                 return;
>>>  
>>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>>> &max_link_enc_cap);
>>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>>         drm_dp_mst_topology_mgr_init(
>>>                 &aconnector->mst_mgr,
>>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>> amdgpu_display_manager *dm,
>>>                 &aconnector->dm_dp_aux.aux,
>>>                 16,
>>>                 4,
>>> +               max_link_enc_cap.lane_count,
>>> +               max_link_enc_cap.link_rate,
>>>                 aconnector->connector_id);
>>>  
>>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> index 7d2e433c2275..6fe66b7ee53e 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>>> bool link_down)
>>>         return true;
>>>  }
>>>  
>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>> dc_link_settings *max_link_enc_cap)
>>> +{
>>> +       if (!max_link_enc_cap) {
>>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>>> __func__);
>>> +               return false;
>>> +       }
>>> +
>>> +       if (link->link_enc->funcs->get_max_link_cap) {
>>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>>> max_link_enc_cap);
>>> +               return true;
>>> +       }
>>> +
>>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>>> +       max_link_enc_cap->lane_count = 1;
>>> +       max_link_enc_cap->link_rate = 6;
>>> +       return false;
>>> +}
>>> +
>>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>>  {
>>>         struct dc_link_settings max_link_cap = {0};
>>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> index b0013e674864..cb6d0543d839 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>>         const unsigned char *p_custom_pattern,
>>>         unsigned int cust_pattern_size);
>>>  
>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>> dc_link_settings *max_link_enc_cap);
>>> +
>>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>>  
>>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> index 5539a91b4031..31d9f3ff0d39 100644
>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>>> drm_dp_mst_topology_mgr *mgr, bool ms
>>>         /* set the device into MST mode */
>>>         if (mst_state) {
>>>                 struct drm_dp_payload reset_pay;
>>> +               int lane_count;
>>> +               int link_rate;
>>>  
>>>                 WARN_ON(mgr->mst_primary);
>>>  
>>>                 /* get dpcd info */
>>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>>> DP_RECEIVER_CAP_SIZE);
>>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>>> +               if (ret < 0) {
>>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>>> %d\n",
>>> +                                   mgr->aux->name, ret);
>>>                         goto out_unlock;
>>>                 }
>>>  
>>> +               lane_count = min_t(int, mgr->dpcd[2] &
>>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>>> -
>>>                                                        drm_dp_bw_code_to_link
>>> _rate(mgr->dpcd[1]),
>>> -                                                       mgr->dpcd[2] &
>>> DP_MAX_LANE_COUNT_MASK);
>>> +                                                       drm_dp_bw_code_to_li
>>> nk_rate(link_rate),
>>> +                                                       lane_count);
>>>                 if (mgr->pbn_div == 0) {
>>>                         ret = -EINVAL;
>>>                         goto out_unlock;
>>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>>   * @aux: DP helper aux channel to talk to this device
>>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>>   * @max_payloads: maximum number of payloads this GPU can source
>>> + * @max_lane_count: maximum number of lanes this GPU supports
>>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>>   *
>>>   * Return 0 for success, or negative error code on failure
>>>   */
>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>                                  struct drm_device *dev, struct drm_dp_aux
>>> *aux,
>>> -                                int max_dpcd_transaction_bytes,
>>> -                                int max_payloads, int conn_base_id)
>>> +                                int max_dpcd_transaction_bytes, int
>>> max_payloads,
>>> +                                int max_lane_count, int max_link_rate,
>>> +                                int conn_base_id)
>>>  {
>>>         struct drm_dp_mst_topology_state *mst_state;
>>>  
>>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>>> drm_dp_mst_topology_mgr *mgr,
>>>         mgr->aux = aux;
>>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>>         mgr->max_payloads = max_payloads;
>>> +       mgr->max_lane_count = max_lane_count;
>>> +       mgr->max_link_rate = max_link_rate;
>>>         mgr->conn_base_id = conn_base_id;
>>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>>  
>>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>>> -                                    &downstreamport, 1) < 0)
>>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>>                         return NULL;
>>>  
>>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>>> +               if ((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;
>>>         }
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> index 860381d68d9d..a4245eb48ef4 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>> *dig_port, int conn_base_id)
>>>         struct intel_dp *intel_dp = &dig_port->dp;
>>>         enum port port = dig_port->base.port;
>>>         int ret;
>>> +       int bios_max_link_rate;
>>>  
>>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>>                 return 0;
>>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>> *dig_port, int conn_base_id)
>>>  
>>>         /* create encoders */
>>>         intel_dp_create_fake_mst_encoders(dig_port);
>>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>>> -                                          &intel_dp->aux, 16, 3,
>>> conn_base_id);
>>> +                                          &intel_dp->aux, 16, 3,
>>> +                                          dig_port->max_lanes,
>>> +                                          bios_max_link_rate / 27000,
>>> conn_base_id);
>>>         if (ret)
>>>                 return ret;
>>>  
>>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>>> drm_dp_aux *aux, int aux_max,
>>>         mstm->mgr.cbs = &nv50_mstm;
>>>  
>>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>>> -                                          max_payloads, conn_base_id);
>>> +                                          max_payloads, outp->dcb-
>>> >dpconf.link_nr,
>>> +                                          outp->dcb->dpconf.link_bw,
>>> conn_base_id);
>>>         if (ret)
>>>                 return ret;
>>>  
>>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> index 59cf1d288465..8f0b2dccd199 100644
>>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>> @@ -629,13 +629,20 @@ int
>>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>>  {
>>>         struct drm_device *dev = radeon_connector->base.dev;
>>> +       int max_link_rate;
>>>  
>>>         if (!radeon_connector->ddc_bus->has_aux)
>>>                 return 0;
>>>  
>>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>>> +               max_link_rate = 0x14;
>>> +       else
>>> +               max_link_rate = 0x0a;
>>> +
>>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>>                                             &radeon_connector->ddc_bus->aux,
>>> 16, 6,
>>> +                                           4, max_link_rate,
>>>                                             radeon_connector->base.base.id);
>>>  }
>>>  
>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>> b/include/drm/drm_dp_mst_helper.h
>>> index 20dc705642bd..b5b0bf37813b 100644
>>> --- a/include/drm/drm_dp_mst_helper.h
>>> +++ b/include/drm/drm_dp_mst_helper.h
>>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>>          */
>>>         int max_payloads;
>>> +       /**
>>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>>> +        */
>>> +       int max_lane_count;
>>> +       /**
>>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>>> +        */
>>> +       int max_link_rate;
>>>         /**
>>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>>> used
>>>          * to build the MST connector path value.
>>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>                                  struct drm_device *dev, struct drm_dp_aux
>>> *aux,
>>>                                  int max_dpcd_transaction_bytes,
>>> -                                int max_payloads, int conn_base_id);
>>> +                                int max_payloads,
>>> +                                int max_lane_count, int max_link_rate,
>>> +                                int conn_base_id);
>>>  
>>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-05-03  8:33         ` [Intel-gfx] " Jani Nikula
  (?)
@ 2021-05-03  8:41           ` Jani Nikula
  -1 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-05-03  8:41 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: Daniel Vetter, intel-gfx, dri-devel, koba.ko, aurabindo.pillai,
	Lankhorst, Maarten, Thomas Zimmermann, mikita.lipski

On Mon, 03 May 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
>> On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
>>> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
>>> today if there's no objections
>>
>> Thanks for the heads-up, I think this breaks i915. See my review
>> comments elsewhere in the thread.
>
> Looks like this was merged anyway.
>
> 98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")
>
> I'm not happy how this played out.
>
> 1) You need to Cc relevant people
>
> 2) You need to get the ack before merging changes
>
> 3) You need to give people more than a day to react, with time zones and
> all; I replied as soon as I saw the heads-up, but it was already too
> late
>
> It's broken on i915, and perhaps that could be fixed.
>
> However I also think using DP spec rate codes and calling them "rate" is
> a bad interface, especially when the unit breaks down with DP 2.0 rate
> codes. It's confusing and it's not future proof. Fixing that afterwards
> falls to whoever comes next to pick up the pieces.
>
> I'd rather just see this reverted and redone.

Okay, just saw that you'd fixed i915 already. Thanks. Let's roll with
that then.

BR,
Jani.


>
>
> BR,
> Jani.
>
>
>>
>> BR,
>> Jani.
>>
>>
>>>
>>> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>>>> [why]
>>>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>>>> set, Extended Base Receiver Capability DPCD space must be used. Without
>>>> doing that, the three DPCD values that differ will be wrong, leading to
>>>> incorrect or limited functionality. MST link rate, for example, could
>>>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>>>> Extended DPCD was not read, resulting in no DSC for such hubs.
>>>> 
>>>> [how]
>>>> Modify MST topology manager to use the values from Extended DPCD where
>>>> applicable.
>>>> 
>>>> To prevent regression on the sources that have a lower maximum link rate
>>>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>>>> supply maximum lane count and rate at initialization time.
>>>> 
>>>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>>>> extended DPCD caps for topology manager")', brining the change back to
>>>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>>>> caps for topology manager")'.
>>>> 
>>>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>>>> ---
>>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>>>  8 files changed, 71 insertions(+), 15 deletions(-)
>>>> 
>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> index 997567f6f0ba..b7e01b6fb328 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>                                        struct amdgpu_dm_connector
>>>> *aconnector,
>>>>                                        int link_index)
>>>>  {
>>>> +       struct dc_link_settings max_link_enc_cap = {0};
>>>> +
>>>>         aconnector->dm_dp_aux.aux.name =
>>>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>>>                           link_index);
>>>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>>>                 return;
>>>>  
>>>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>>>> &max_link_enc_cap);
>>>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>>>         drm_dp_mst_topology_mgr_init(
>>>>                 &aconnector->mst_mgr,
>>>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>                 &aconnector->dm_dp_aux.aux,
>>>>                 16,
>>>>                 4,
>>>> +               max_link_enc_cap.lane_count,
>>>> +               max_link_enc_cap.link_rate,
>>>>                 aconnector->connector_id);
>>>>  
>>>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> index 7d2e433c2275..6fe66b7ee53e 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>>>> bool link_down)
>>>>         return true;
>>>>  }
>>>>  
>>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>>> dc_link_settings *max_link_enc_cap)
>>>> +{
>>>> +       if (!max_link_enc_cap) {
>>>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>>>> __func__);
>>>> +               return false;
>>>> +       }
>>>> +
>>>> +       if (link->link_enc->funcs->get_max_link_cap) {
>>>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>>>> max_link_enc_cap);
>>>> +               return true;
>>>> +       }
>>>> +
>>>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>>>> +       max_link_enc_cap->lane_count = 1;
>>>> +       max_link_enc_cap->link_rate = 6;
>>>> +       return false;
>>>> +}
>>>> +
>>>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>>>  {
>>>>         struct dc_link_settings max_link_cap = {0};
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> index b0013e674864..cb6d0543d839 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>>>         const unsigned char *p_custom_pattern,
>>>>         unsigned int cust_pattern_size);
>>>>  
>>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>>> dc_link_settings *max_link_enc_cap);
>>>> +
>>>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>>>  
>>>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> index 5539a91b4031..31d9f3ff0d39 100644
>>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>>>> drm_dp_mst_topology_mgr *mgr, bool ms
>>>>         /* set the device into MST mode */
>>>>         if (mst_state) {
>>>>                 struct drm_dp_payload reset_pay;
>>>> +               int lane_count;
>>>> +               int link_rate;
>>>>  
>>>>                 WARN_ON(mgr->mst_primary);
>>>>  
>>>>                 /* get dpcd info */
>>>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>>>> DP_RECEIVER_CAP_SIZE);
>>>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>>>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>>>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>>>> +               if (ret < 0) {
>>>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>>>> %d\n",
>>>> +                                   mgr->aux->name, ret);
>>>>                         goto out_unlock;
>>>>                 }
>>>>  
>>>> +               lane_count = min_t(int, mgr->dpcd[2] &
>>>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>>>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>>>> -
>>>>                                                        drm_dp_bw_code_to_link
>>>> _rate(mgr->dpcd[1]),
>>>> -                                                       mgr->dpcd[2] &
>>>> DP_MAX_LANE_COUNT_MASK);
>>>> +                                                       drm_dp_bw_code_to_li
>>>> nk_rate(link_rate),
>>>> +                                                       lane_count);
>>>>                 if (mgr->pbn_div == 0) {
>>>>                         ret = -EINVAL;
>>>>                         goto out_unlock;
>>>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>>>   * @aux: DP helper aux channel to talk to this device
>>>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>>>   * @max_payloads: maximum number of payloads this GPU can source
>>>> + * @max_lane_count: maximum number of lanes this GPU supports
>>>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>>>   *
>>>>   * Return 0 for success, or negative error code on failure
>>>>   */
>>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                  struct drm_device *dev, struct drm_dp_aux
>>>> *aux,
>>>> -                                int max_dpcd_transaction_bytes,
>>>> -                                int max_payloads, int conn_base_id)
>>>> +                                int max_dpcd_transaction_bytes, int
>>>> max_payloads,
>>>> +                                int max_lane_count, int max_link_rate,
>>>> +                                int conn_base_id)
>>>>  {
>>>>         struct drm_dp_mst_topology_state *mst_state;
>>>>  
>>>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>>>> drm_dp_mst_topology_mgr *mgr,
>>>>         mgr->aux = aux;
>>>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>>>         mgr->max_payloads = max_payloads;
>>>> +       mgr->max_lane_count = max_lane_count;
>>>> +       mgr->max_link_rate = max_link_rate;
>>>>         mgr->conn_base_id = conn_base_id;
>>>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>>>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>>>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>>>  
>>>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>>>> -                                    &downstreamport, 1) < 0)
>>>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>>>                         return NULL;
>>>>  
>>>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>>>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>>>> +               if ((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;
>>>>         }
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> index 860381d68d9d..a4245eb48ef4 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>>> *dig_port, int conn_base_id)
>>>>         struct intel_dp *intel_dp = &dig_port->dp;
>>>>         enum port port = dig_port->base.port;
>>>>         int ret;
>>>> +       int bios_max_link_rate;
>>>>  
>>>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>>>                 return 0;
>>>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>>> *dig_port, int conn_base_id)
>>>>  
>>>>         /* create encoders */
>>>>         intel_dp_create_fake_mst_encoders(dig_port);
>>>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>>>> -                                          &intel_dp->aux, 16, 3,
>>>> conn_base_id);
>>>> +                                          &intel_dp->aux, 16, 3,
>>>> +                                          dig_port->max_lanes,
>>>> +                                          bios_max_link_rate / 27000,
>>>> conn_base_id);
>>>>         if (ret)
>>>>                 return ret;
>>>>  
>>>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>>>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>>>> drm_dp_aux *aux, int aux_max,
>>>>         mstm->mgr.cbs = &nv50_mstm;
>>>>  
>>>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>>>> -                                          max_payloads, conn_base_id);
>>>> +                                          max_payloads, outp->dcb-
>>>> >dpconf.link_nr,
>>>> +                                          outp->dcb->dpconf.link_bw,
>>>> conn_base_id);
>>>>         if (ret)
>>>>                 return ret;
>>>>  
>>>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> index 59cf1d288465..8f0b2dccd199 100644
>>>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> @@ -629,13 +629,20 @@ int
>>>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>>>  {
>>>>         struct drm_device *dev = radeon_connector->base.dev;
>>>> +       int max_link_rate;
>>>>  
>>>>         if (!radeon_connector->ddc_bus->has_aux)
>>>>                 return 0;
>>>>  
>>>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>>>> +               max_link_rate = 0x14;
>>>> +       else
>>>> +               max_link_rate = 0x0a;
>>>> +
>>>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>>>                                             &radeon_connector->ddc_bus->aux,
>>>> 16, 6,
>>>> +                                           4, max_link_rate,
>>>>                                             radeon_connector->base.base.id);
>>>>  }
>>>>  
>>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>>> b/include/drm/drm_dp_mst_helper.h
>>>> index 20dc705642bd..b5b0bf37813b 100644
>>>> --- a/include/drm/drm_dp_mst_helper.h
>>>> +++ b/include/drm/drm_dp_mst_helper.h
>>>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>>>          */
>>>>         int max_payloads;
>>>> +       /**
>>>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>>>> +        */
>>>> +       int max_lane_count;
>>>> +       /**
>>>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>>>> +        */
>>>> +       int max_link_rate;
>>>>         /**
>>>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>>>> used
>>>>          * to build the MST connector path value.
>>>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                  struct drm_device *dev, struct drm_dp_aux
>>>> *aux,
>>>>                                  int max_dpcd_transaction_bytes,
>>>> -                                int max_payloads, int conn_base_id);
>>>> +                                int max_payloads,
>>>> +                                int max_lane_count, int max_link_rate,
>>>> +                                int conn_base_id);
>>>>  
>>>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-05-03  8:41           ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-05-03  8:41 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: Maxime Ripard, Daniel Vetter, intel-gfx, dri-devel, koba.ko,
	aurabindo.pillai, Lankhorst, Maarten, Thomas Zimmermann,
	mikita.lipski

On Mon, 03 May 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
>> On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
>>> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
>>> today if there's no objections
>>
>> Thanks for the heads-up, I think this breaks i915. See my review
>> comments elsewhere in the thread.
>
> Looks like this was merged anyway.
>
> 98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")
>
> I'm not happy how this played out.
>
> 1) You need to Cc relevant people
>
> 2) You need to get the ack before merging changes
>
> 3) You need to give people more than a day to react, with time zones and
> all; I replied as soon as I saw the heads-up, but it was already too
> late
>
> It's broken on i915, and perhaps that could be fixed.
>
> However I also think using DP spec rate codes and calling them "rate" is
> a bad interface, especially when the unit breaks down with DP 2.0 rate
> codes. It's confusing and it's not future proof. Fixing that afterwards
> falls to whoever comes next to pick up the pieces.
>
> I'd rather just see this reverted and redone.

Okay, just saw that you'd fixed i915 already. Thanks. Let's roll with
that then.

BR,
Jani.


>
>
> BR,
> Jani.
>
>
>>
>> BR,
>> Jani.
>>
>>
>>>
>>> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>>>> [why]
>>>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>>>> set, Extended Base Receiver Capability DPCD space must be used. Without
>>>> doing that, the three DPCD values that differ will be wrong, leading to
>>>> incorrect or limited functionality. MST link rate, for example, could
>>>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>>>> Extended DPCD was not read, resulting in no DSC for such hubs.
>>>> 
>>>> [how]
>>>> Modify MST topology manager to use the values from Extended DPCD where
>>>> applicable.
>>>> 
>>>> To prevent regression on the sources that have a lower maximum link rate
>>>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>>>> supply maximum lane count and rate at initialization time.
>>>> 
>>>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>>>> extended DPCD caps for topology manager")', brining the change back to
>>>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>>>> caps for topology manager")'.
>>>> 
>>>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>>>> ---
>>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>>>  8 files changed, 71 insertions(+), 15 deletions(-)
>>>> 
>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> index 997567f6f0ba..b7e01b6fb328 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>                                        struct amdgpu_dm_connector
>>>> *aconnector,
>>>>                                        int link_index)
>>>>  {
>>>> +       struct dc_link_settings max_link_enc_cap = {0};
>>>> +
>>>>         aconnector->dm_dp_aux.aux.name =
>>>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>>>                           link_index);
>>>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>>>                 return;
>>>>  
>>>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>>>> &max_link_enc_cap);
>>>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>>>         drm_dp_mst_topology_mgr_init(
>>>>                 &aconnector->mst_mgr,
>>>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>                 &aconnector->dm_dp_aux.aux,
>>>>                 16,
>>>>                 4,
>>>> +               max_link_enc_cap.lane_count,
>>>> +               max_link_enc_cap.link_rate,
>>>>                 aconnector->connector_id);
>>>>  
>>>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> index 7d2e433c2275..6fe66b7ee53e 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>>>> bool link_down)
>>>>         return true;
>>>>  }
>>>>  
>>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>>> dc_link_settings *max_link_enc_cap)
>>>> +{
>>>> +       if (!max_link_enc_cap) {
>>>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>>>> __func__);
>>>> +               return false;
>>>> +       }
>>>> +
>>>> +       if (link->link_enc->funcs->get_max_link_cap) {
>>>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>>>> max_link_enc_cap);
>>>> +               return true;
>>>> +       }
>>>> +
>>>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>>>> +       max_link_enc_cap->lane_count = 1;
>>>> +       max_link_enc_cap->link_rate = 6;
>>>> +       return false;
>>>> +}
>>>> +
>>>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>>>  {
>>>>         struct dc_link_settings max_link_cap = {0};
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> index b0013e674864..cb6d0543d839 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>>>         const unsigned char *p_custom_pattern,
>>>>         unsigned int cust_pattern_size);
>>>>  
>>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>>> dc_link_settings *max_link_enc_cap);
>>>> +
>>>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>>>  
>>>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> index 5539a91b4031..31d9f3ff0d39 100644
>>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>>>> drm_dp_mst_topology_mgr *mgr, bool ms
>>>>         /* set the device into MST mode */
>>>>         if (mst_state) {
>>>>                 struct drm_dp_payload reset_pay;
>>>> +               int lane_count;
>>>> +               int link_rate;
>>>>  
>>>>                 WARN_ON(mgr->mst_primary);
>>>>  
>>>>                 /* get dpcd info */
>>>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>>>> DP_RECEIVER_CAP_SIZE);
>>>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>>>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>>>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>>>> +               if (ret < 0) {
>>>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>>>> %d\n",
>>>> +                                   mgr->aux->name, ret);
>>>>                         goto out_unlock;
>>>>                 }
>>>>  
>>>> +               lane_count = min_t(int, mgr->dpcd[2] &
>>>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>>>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>>>> -
>>>>                                                        drm_dp_bw_code_to_link
>>>> _rate(mgr->dpcd[1]),
>>>> -                                                       mgr->dpcd[2] &
>>>> DP_MAX_LANE_COUNT_MASK);
>>>> +                                                       drm_dp_bw_code_to_li
>>>> nk_rate(link_rate),
>>>> +                                                       lane_count);
>>>>                 if (mgr->pbn_div == 0) {
>>>>                         ret = -EINVAL;
>>>>                         goto out_unlock;
>>>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>>>   * @aux: DP helper aux channel to talk to this device
>>>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>>>   * @max_payloads: maximum number of payloads this GPU can source
>>>> + * @max_lane_count: maximum number of lanes this GPU supports
>>>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>>>   *
>>>>   * Return 0 for success, or negative error code on failure
>>>>   */
>>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                  struct drm_device *dev, struct drm_dp_aux
>>>> *aux,
>>>> -                                int max_dpcd_transaction_bytes,
>>>> -                                int max_payloads, int conn_base_id)
>>>> +                                int max_dpcd_transaction_bytes, int
>>>> max_payloads,
>>>> +                                int max_lane_count, int max_link_rate,
>>>> +                                int conn_base_id)
>>>>  {
>>>>         struct drm_dp_mst_topology_state *mst_state;
>>>>  
>>>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>>>> drm_dp_mst_topology_mgr *mgr,
>>>>         mgr->aux = aux;
>>>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>>>         mgr->max_payloads = max_payloads;
>>>> +       mgr->max_lane_count = max_lane_count;
>>>> +       mgr->max_link_rate = max_link_rate;
>>>>         mgr->conn_base_id = conn_base_id;
>>>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>>>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>>>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>>>  
>>>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>>>> -                                    &downstreamport, 1) < 0)
>>>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>>>                         return NULL;
>>>>  
>>>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>>>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>>>> +               if ((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;
>>>>         }
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> index 860381d68d9d..a4245eb48ef4 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>>> *dig_port, int conn_base_id)
>>>>         struct intel_dp *intel_dp = &dig_port->dp;
>>>>         enum port port = dig_port->base.port;
>>>>         int ret;
>>>> +       int bios_max_link_rate;
>>>>  
>>>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>>>                 return 0;
>>>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>>> *dig_port, int conn_base_id)
>>>>  
>>>>         /* create encoders */
>>>>         intel_dp_create_fake_mst_encoders(dig_port);
>>>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>>>> -                                          &intel_dp->aux, 16, 3,
>>>> conn_base_id);
>>>> +                                          &intel_dp->aux, 16, 3,
>>>> +                                          dig_port->max_lanes,
>>>> +                                          bios_max_link_rate / 27000,
>>>> conn_base_id);
>>>>         if (ret)
>>>>                 return ret;
>>>>  
>>>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>>>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>>>> drm_dp_aux *aux, int aux_max,
>>>>         mstm->mgr.cbs = &nv50_mstm;
>>>>  
>>>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>>>> -                                          max_payloads, conn_base_id);
>>>> +                                          max_payloads, outp->dcb-
>>>> >dpconf.link_nr,
>>>> +                                          outp->dcb->dpconf.link_bw,
>>>> conn_base_id);
>>>>         if (ret)
>>>>                 return ret;
>>>>  
>>>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> index 59cf1d288465..8f0b2dccd199 100644
>>>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> @@ -629,13 +629,20 @@ int
>>>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>>>  {
>>>>         struct drm_device *dev = radeon_connector->base.dev;
>>>> +       int max_link_rate;
>>>>  
>>>>         if (!radeon_connector->ddc_bus->has_aux)
>>>>                 return 0;
>>>>  
>>>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>>>> +               max_link_rate = 0x14;
>>>> +       else
>>>> +               max_link_rate = 0x0a;
>>>> +
>>>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>>>                                             &radeon_connector->ddc_bus->aux,
>>>> 16, 6,
>>>> +                                           4, max_link_rate,
>>>>                                             radeon_connector->base.base.id);
>>>>  }
>>>>  
>>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>>> b/include/drm/drm_dp_mst_helper.h
>>>> index 20dc705642bd..b5b0bf37813b 100644
>>>> --- a/include/drm/drm_dp_mst_helper.h
>>>> +++ b/include/drm/drm_dp_mst_helper.h
>>>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>>>          */
>>>>         int max_payloads;
>>>> +       /**
>>>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>>>> +        */
>>>> +       int max_lane_count;
>>>> +       /**
>>>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>>>> +        */
>>>> +       int max_link_rate;
>>>>         /**
>>>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>>>> used
>>>>          * to build the MST connector path value.
>>>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                  struct drm_device *dev, struct drm_dp_aux
>>>> *aux,
>>>>                                  int max_dpcd_transaction_bytes,
>>>> -                                int max_payloads, int conn_base_id);
>>>> +                                int max_payloads,
>>>> +                                int max_lane_count, int max_link_rate,
>>>> +                                int conn_base_id);
>>>>  
>>>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-05-03  8:41           ` Jani Nikula
  0 siblings, 0 replies; 27+ messages in thread
From: Jani Nikula @ 2021-05-03  8:41 UTC (permalink / raw)
  To: Lyude Paul, Nikola Cornij, amd-gfx, Ben Skeggs
  Cc: Maxime Ripard, Daniel Vetter, intel-gfx, dri-devel, koba.ko,
	aurabindo.pillai, Lankhorst, Maarten, Thomas Zimmermann,
	mikita.lipski, Dave Airlie, ville.syrjala

On Mon, 03 May 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
>> On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
>>> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
>>> today if there's no objections
>>
>> Thanks for the heads-up, I think this breaks i915. See my review
>> comments elsewhere in the thread.
>
> Looks like this was merged anyway.
>
> 98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")
>
> I'm not happy how this played out.
>
> 1) You need to Cc relevant people
>
> 2) You need to get the ack before merging changes
>
> 3) You need to give people more than a day to react, with time zones and
> all; I replied as soon as I saw the heads-up, but it was already too
> late
>
> It's broken on i915, and perhaps that could be fixed.
>
> However I also think using DP spec rate codes and calling them "rate" is
> a bad interface, especially when the unit breaks down with DP 2.0 rate
> codes. It's confusing and it's not future proof. Fixing that afterwards
> falls to whoever comes next to pick up the pieces.
>
> I'd rather just see this reverted and redone.

Okay, just saw that you'd fixed i915 already. Thanks. Let's roll with
that then.

BR,
Jani.


>
>
> BR,
> Jani.
>
>
>>
>> BR,
>> Jani.
>>
>>
>>>
>>> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
>>>> [why]
>>>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
>>>> set, Extended Base Receiver Capability DPCD space must be used. Without
>>>> doing that, the three DPCD values that differ will be wrong, leading to
>>>> incorrect or limited functionality. MST link rate, for example, could
>>>> have a lower value. Also, Synaptics quirk wouldn't work out well when
>>>> Extended DPCD was not read, resulting in no DSC for such hubs.
>>>> 
>>>> [how]
>>>> Modify MST topology manager to use the values from Extended DPCD where
>>>> applicable.
>>>> 
>>>> To prevent regression on the sources that have a lower maximum link rate
>>>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
>>>> supply maximum lane count and rate at initialization time.
>>>> 
>>>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
>>>> extended DPCD caps for topology manager")', brining the change back to
>>>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
>>>> caps for topology manager")'.
>>>> 
>>>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
>>>> ---
>>>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
>>>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
>>>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
>>>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
>>>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
>>>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
>>>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
>>>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
>>>>  8 files changed, 71 insertions(+), 15 deletions(-)
>>>> 
>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> index 997567f6f0ba..b7e01b6fb328 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
>>>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>                                        struct amdgpu_dm_connector
>>>> *aconnector,
>>>>                                        int link_index)
>>>>  {
>>>> +       struct dc_link_settings max_link_enc_cap = {0};
>>>> +
>>>>         aconnector->dm_dp_aux.aux.name =
>>>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
>>>>                           link_index);
>>>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
>>>>                 return;
>>>>  
>>>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
>>>> &max_link_enc_cap);
>>>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
>>>>         drm_dp_mst_topology_mgr_init(
>>>>                 &aconnector->mst_mgr,
>>>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
>>>> amdgpu_display_manager *dm,
>>>>                 &aconnector->dm_dp_aux.aux,
>>>>                 16,
>>>>                 4,
>>>> +               max_link_enc_cap.lane_count,
>>>> +               max_link_enc_cap.link_rate,
>>>>                 aconnector->connector_id);
>>>>  
>>>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> index 7d2e433c2275..6fe66b7ee53e 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
>>>> bool link_down)
>>>>         return true;
>>>>  }
>>>>  
>>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>>> dc_link_settings *max_link_enc_cap)
>>>> +{
>>>> +       if (!max_link_enc_cap) {
>>>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
>>>> __func__);
>>>> +               return false;
>>>> +       }
>>>> +
>>>> +       if (link->link_enc->funcs->get_max_link_cap) {
>>>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
>>>> max_link_enc_cap);
>>>> +               return true;
>>>> +       }
>>>> +
>>>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
>>>> +       max_link_enc_cap->lane_count = 1;
>>>> +       max_link_enc_cap->link_rate = 6;
>>>> +       return false;
>>>> +}
>>>> +
>>>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
>>>>  {
>>>>         struct dc_link_settings max_link_cap = {0};
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> index b0013e674864..cb6d0543d839 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
>>>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
>>>>         const unsigned char *p_custom_pattern,
>>>>         unsigned int cust_pattern_size);
>>>>  
>>>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
>>>> dc_link_settings *max_link_enc_cap);
>>>> +
>>>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
>>>>  
>>>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
>>>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> b/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> index 5539a91b4031..31d9f3ff0d39 100644
>>>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
>>>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
>>>> drm_dp_mst_topology_mgr *mgr, bool ms
>>>>         /* set the device into MST mode */
>>>>         if (mst_state) {
>>>>                 struct drm_dp_payload reset_pay;
>>>> +               int lane_count;
>>>> +               int link_rate;
>>>>  
>>>>                 WARN_ON(mgr->mst_primary);
>>>>  
>>>>                 /* get dpcd info */
>>>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
>>>> DP_RECEIVER_CAP_SIZE);
>>>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
>>>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
>>>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
>>>> +               if (ret < 0) {
>>>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
>>>> %d\n",
>>>> +                                   mgr->aux->name, ret);
>>>>                         goto out_unlock;
>>>>                 }
>>>>  
>>>> +               lane_count = min_t(int, mgr->dpcd[2] &
>>>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
>>>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
>>>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
>>>> -
>>>>                                                        drm_dp_bw_code_to_link
>>>> _rate(mgr->dpcd[1]),
>>>> -                                                       mgr->dpcd[2] &
>>>> DP_MAX_LANE_COUNT_MASK);
>>>> +                                                       drm_dp_bw_code_to_li
>>>> nk_rate(link_rate),
>>>> +                                                       lane_count);
>>>>                 if (mgr->pbn_div == 0) {
>>>>                         ret = -EINVAL;
>>>>                         goto out_unlock;
>>>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>>>>   * @aux: DP helper aux channel to talk to this device
>>>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
>>>>   * @max_payloads: maximum number of payloads this GPU can source
>>>> + * @max_lane_count: maximum number of lanes this GPU supports
>>>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
>>>>   * @conn_base_id: the connector object ID the MST device is connected to.
>>>>   *
>>>>   * Return 0 for success, or negative error code on failure
>>>>   */
>>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                  struct drm_device *dev, struct drm_dp_aux
>>>> *aux,
>>>> -                                int max_dpcd_transaction_bytes,
>>>> -                                int max_payloads, int conn_base_id)
>>>> +                                int max_dpcd_transaction_bytes, int
>>>> max_payloads,
>>>> +                                int max_lane_count, int max_link_rate,
>>>> +                                int conn_base_id)
>>>>  {
>>>>         struct drm_dp_mst_topology_state *mst_state;
>>>>  
>>>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
>>>> drm_dp_mst_topology_mgr *mgr,
>>>>         mgr->aux = aux;
>>>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
>>>>         mgr->max_payloads = max_payloads;
>>>> +       mgr->max_lane_count = max_lane_count;
>>>> +       mgr->max_link_rate = max_link_rate;
>>>>         mgr->conn_base_id = conn_base_id;
>>>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
>>>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
>>>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
>>>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>>>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>>>>  
>>>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
>>>> -                                    &downstreamport, 1) < 0)
>>>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
>>>>                         return NULL;
>>>>  
>>>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
>>>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
>>>> +               if ((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;
>>>>         }
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> index 860381d68d9d..a4245eb48ef4 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>>>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>>> *dig_port, int conn_base_id)
>>>>         struct intel_dp *intel_dp = &dig_port->dp;
>>>>         enum port port = dig_port->base.port;
>>>>         int ret;
>>>> +       int bios_max_link_rate;
>>>>  
>>>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
>>>>                 return 0;
>>>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
>>>> *dig_port, int conn_base_id)
>>>>  
>>>>         /* create encoders */
>>>>         intel_dp_create_fake_mst_encoders(dig_port);
>>>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
>>>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
>>>> -                                          &intel_dp->aux, 16, 3,
>>>> conn_base_id);
>>>> +                                          &intel_dp->aux, 16, 3,
>>>> +                                          dig_port->max_lanes,
>>>> +                                          bios_max_link_rate / 27000,
>>>> conn_base_id);
>>>>         if (ret)
>>>>                 return ret;
>>>>  
>>>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> index 1c9c0cdf85db..e02f9d2d74eb 100644
>>>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
>>>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
>>>> drm_dp_aux *aux, int aux_max,
>>>>         mstm->mgr.cbs = &nv50_mstm;
>>>>  
>>>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
>>>> -                                          max_payloads, conn_base_id);
>>>> +                                          max_payloads, outp->dcb-
>>>> >dpconf.link_nr,
>>>> +                                          outp->dcb->dpconf.link_bw,
>>>> conn_base_id);
>>>>         if (ret)
>>>>                 return ret;
>>>>  
>>>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> index 59cf1d288465..8f0b2dccd199 100644
>>>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
>>>> @@ -629,13 +629,20 @@ int
>>>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
>>>>  {
>>>>         struct drm_device *dev = radeon_connector->base.dev;
>>>> +       int max_link_rate;
>>>>  
>>>>         if (!radeon_connector->ddc_bus->has_aux)
>>>>                 return 0;
>>>>  
>>>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
>>>> +               max_link_rate = 0x14;
>>>> +       else
>>>> +               max_link_rate = 0x0a;
>>>> +
>>>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
>>>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
>>>>                                             &radeon_connector->ddc_bus->aux,
>>>> 16, 6,
>>>> +                                           4, max_link_rate,
>>>>                                             radeon_connector->base.base.id);
>>>>  }
>>>>  
>>>> diff --git a/include/drm/drm_dp_mst_helper.h
>>>> b/include/drm/drm_dp_mst_helper.h
>>>> index 20dc705642bd..b5b0bf37813b 100644
>>>> --- a/include/drm/drm_dp_mst_helper.h
>>>> +++ b/include/drm/drm_dp_mst_helper.h
>>>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
>>>>          * @max_payloads: maximum number of payloads the GPU can generate.
>>>>          */
>>>>         int max_payloads;
>>>> +       /**
>>>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
>>>> +        */
>>>> +       int max_lane_count;
>>>> +       /**
>>>> +        * @max_link_rate: maximum link rate per lane GPU can output.
>>>> +        */
>>>> +       int max_link_rate;
>>>>         /**
>>>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
>>>> used
>>>>          * to build the MST connector path value.
>>>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
>>>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>>>>                                  struct drm_device *dev, struct drm_dp_aux
>>>> *aux,
>>>>                                  int max_dpcd_transaction_bytes,
>>>> -                                int max_payloads, int conn_base_id);
>>>> +                                int max_payloads,
>>>> +                                int max_lane_count, int max_link_rate,
>>>> +                                int conn_base_id);
>>>>  
>>>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
>>>>  

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
  2021-05-03  8:33         ` [Intel-gfx] " Jani Nikula
  (?)
@ 2021-05-04  7:43           ` Daniel Vetter
  -1 siblings, 0 replies; 27+ messages in thread
From: Daniel Vetter @ 2021-05-04  7:43 UTC (permalink / raw)
  To: Jani Nikula
  Cc: dri-devel, Daniel Vetter, intel-gfx, Lankhorst, Maarten, amd-gfx,
	Nikola Cornij, koba.ko, aurabindo.pillai, Ben Skeggs,
	Thomas Zimmermann, mikita.lipski

On Mon, May 03, 2021 at 11:33:33AM +0300, Jani Nikula wrote:
> On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> > On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
> >> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
> >> today if there's no objections
> >
> > Thanks for the heads-up, I think this breaks i915. See my review
> > comments elsewhere in the thread.
> 
> Looks like this was merged anyway.

Yeah in general rule of thumb is to let cross-driver stuff soak for a week
(assuming correctly cc'ed and all that already). I think that's the sweet
spot between maintainers who complain that it's too short and others
complaining it's too quick :-)
-Daniel

> 
> 98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")
> 
> I'm not happy how this played out.
> 
> 1) You need to Cc relevant people
> 
> 2) You need to get the ack before merging changes
> 
> 3) You need to give people more than a day to react, with time zones and
> all; I replied as soon as I saw the heads-up, but it was already too
> late
> 
> It's broken on i915, and perhaps that could be fixed.
> 
> However I also think using DP spec rate codes and calling them "rate" is
> a bad interface, especially when the unit breaks down with DP 2.0 rate
> codes. It's confusing and it's not future proof. Fixing that afterwards
> falls to whoever comes next to pick up the pieces.
> 
> I'd rather just see this reverted and redone.
> 
> 
> BR,
> Jani.
> 
> 
> >
> > BR,
> > Jani.
> >
> >
> >>
> >> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
> >>> [why]
> >>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> >>> set, Extended Base Receiver Capability DPCD space must be used. Without
> >>> doing that, the three DPCD values that differ will be wrong, leading to
> >>> incorrect or limited functionality. MST link rate, for example, could
> >>> have a lower value. Also, Synaptics quirk wouldn't work out well when
> >>> Extended DPCD was not read, resulting in no DSC for such hubs.
> >>> 
> >>> [how]
> >>> Modify MST topology manager to use the values from Extended DPCD where
> >>> applicable.
> >>> 
> >>> To prevent regression on the sources that have a lower maximum link rate
> >>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> >>> supply maximum lane count and rate at initialization time.
> >>> 
> >>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> >>> extended DPCD caps for topology manager")', brining the change back to
> >>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> >>> caps for topology manager")'.
> >>> 
> >>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> >>> ---
> >>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
> >>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
> >>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
> >>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
> >>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
> >>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
> >>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
> >>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
> >>>  8 files changed, 71 insertions(+), 15 deletions(-)
> >>> 
> >>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> index 997567f6f0ba..b7e01b6fb328 100644
> >>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>                                        struct amdgpu_dm_connector
> >>> *aconnector,
> >>>                                        int link_index)
> >>>  {
> >>> +       struct dc_link_settings max_link_enc_cap = {0};
> >>> +
> >>>         aconnector->dm_dp_aux.aux.name =
> >>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
> >>>                           link_index);
> >>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
> >>>                 return;
> >>>  
> >>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
> >>> &max_link_enc_cap);
> >>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
> >>>         drm_dp_mst_topology_mgr_init(
> >>>                 &aconnector->mst_mgr,
> >>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>                 &aconnector->dm_dp_aux.aux,
> >>>                 16,
> >>>                 4,
> >>> +               max_link_enc_cap.lane_count,
> >>> +               max_link_enc_cap.link_rate,
> >>>                 aconnector->connector_id);
> >>>  
> >>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
> >>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> index 7d2e433c2275..6fe66b7ee53e 100644
> >>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
> >>> bool link_down)
> >>>         return true;
> >>>  }
> >>>  
> >>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> >>> dc_link_settings *max_link_enc_cap)
> >>> +{
> >>> +       if (!max_link_enc_cap) {
> >>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
> >>> __func__);
> >>> +               return false;
> >>> +       }
> >>> +
> >>> +       if (link->link_enc->funcs->get_max_link_cap) {
> >>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
> >>> max_link_enc_cap);
> >>> +               return true;
> >>> +       }
> >>> +
> >>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
> >>> +       max_link_enc_cap->lane_count = 1;
> >>> +       max_link_enc_cap->link_rate = 6;
> >>> +       return false;
> >>> +}
> >>> +
> >>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
> >>>  {
> >>>         struct dc_link_settings max_link_cap = {0};
> >>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> index b0013e674864..cb6d0543d839 100644
> >>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
> >>>         const unsigned char *p_custom_pattern,
> >>>         unsigned int cust_pattern_size);
> >>>  
> >>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> >>> dc_link_settings *max_link_enc_cap);
> >>> +
> >>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
> >>>  
> >>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
> >>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> b/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> index 5539a91b4031..31d9f3ff0d39 100644
> >>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
> >>> drm_dp_mst_topology_mgr *mgr, bool ms
> >>>         /* set the device into MST mode */
> >>>         if (mst_state) {
> >>>                 struct drm_dp_payload reset_pay;
> >>> +               int lane_count;
> >>> +               int link_rate;
> >>>  
> >>>                 WARN_ON(mgr->mst_primary);
> >>>  
> >>>                 /* get dpcd info */
> >>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> >>> DP_RECEIVER_CAP_SIZE);
> >>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
> >>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
> >>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
> >>> +               if (ret < 0) {
> >>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
> >>> %d\n",
> >>> +                                   mgr->aux->name, ret);
> >>>                         goto out_unlock;
> >>>                 }
> >>>  
> >>> +               lane_count = min_t(int, mgr->dpcd[2] &
> >>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
> >>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
> >>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
> >>> -
> >>>                                                        drm_dp_bw_code_to_link
> >>> _rate(mgr->dpcd[1]),
> >>> -                                                       mgr->dpcd[2] &
> >>> DP_MAX_LANE_COUNT_MASK);
> >>> +                                                       drm_dp_bw_code_to_li
> >>> nk_rate(link_rate),
> >>> +                                                       lane_count);
> >>>                 if (mgr->pbn_div == 0) {
> >>>                         ret = -EINVAL;
> >>>                         goto out_unlock;
> >>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
> >>>   * @aux: DP helper aux channel to talk to this device
> >>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
> >>>   * @max_payloads: maximum number of payloads this GPU can source
> >>> + * @max_lane_count: maximum number of lanes this GPU supports
> >>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
> >>>   * @conn_base_id: the connector object ID the MST device is connected to.
> >>>   *
> >>>   * Return 0 for success, or negative error code on failure
> >>>   */
> >>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
> >>>                                  struct drm_device *dev, struct drm_dp_aux
> >>> *aux,
> >>> -                                int max_dpcd_transaction_bytes,
> >>> -                                int max_payloads, int conn_base_id)
> >>> +                                int max_dpcd_transaction_bytes, int
> >>> max_payloads,
> >>> +                                int max_lane_count, int max_link_rate,
> >>> +                                int conn_base_id)
> >>>  {
> >>>         struct drm_dp_mst_topology_state *mst_state;
> >>>  
> >>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
> >>> drm_dp_mst_topology_mgr *mgr,
> >>>         mgr->aux = aux;
> >>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
> >>>         mgr->max_payloads = max_payloads;
> >>> +       mgr->max_lane_count = max_lane_count;
> >>> +       mgr->max_link_rate = max_link_rate;
> >>>         mgr->conn_base_id = conn_base_id;
> >>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
> >>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
> >>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
> >>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
> >>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> >>>  
> >>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> >>> -                                    &downstreamport, 1) < 0)
> >>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
> >>>                         return NULL;
> >>>  
> >>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> >>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> >>> +               if ((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;
> >>>         }
> >>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> index 860381d68d9d..a4245eb48ef4 100644
> >>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> >>> *dig_port, int conn_base_id)
> >>>         struct intel_dp *intel_dp = &dig_port->dp;
> >>>         enum port port = dig_port->base.port;
> >>>         int ret;
> >>> +       int bios_max_link_rate;
> >>>  
> >>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
> >>>                 return 0;
> >>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> >>> *dig_port, int conn_base_id)
> >>>  
> >>>         /* create encoders */
> >>>         intel_dp_create_fake_mst_encoders(dig_port);
> >>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
> >>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> >>> -                                          &intel_dp->aux, 16, 3,
> >>> conn_base_id);
> >>> +                                          &intel_dp->aux, 16, 3,
> >>> +                                          dig_port->max_lanes,
> >>> +                                          bios_max_link_rate / 27000,
> >>> conn_base_id);
> >>>         if (ret)
> >>>                 return ret;
> >>>  
> >>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> index 1c9c0cdf85db..e02f9d2d74eb 100644
> >>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
> >>> drm_dp_aux *aux, int aux_max,
> >>>         mstm->mgr.cbs = &nv50_mstm;
> >>>  
> >>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
> >>> -                                          max_payloads, conn_base_id);
> >>> +                                          max_payloads, outp->dcb-
> >>> >dpconf.link_nr,
> >>> +                                          outp->dcb->dpconf.link_bw,
> >>> conn_base_id);
> >>>         if (ret)
> >>>                 return ret;
> >>>  
> >>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> index 59cf1d288465..8f0b2dccd199 100644
> >>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> @@ -629,13 +629,20 @@ int
> >>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
> >>>  {
> >>>         struct drm_device *dev = radeon_connector->base.dev;
> >>> +       int max_link_rate;
> >>>  
> >>>         if (!radeon_connector->ddc_bus->has_aux)
> >>>                 return 0;
> >>>  
> >>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
> >>> +               max_link_rate = 0x14;
> >>> +       else
> >>> +               max_link_rate = 0x0a;
> >>> +
> >>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
> >>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
> >>>                                             &radeon_connector->ddc_bus->aux,
> >>> 16, 6,
> >>> +                                           4, max_link_rate,
> >>>                                             radeon_connector->base.base.id);
> >>>  }
> >>>  
> >>> diff --git a/include/drm/drm_dp_mst_helper.h
> >>> b/include/drm/drm_dp_mst_helper.h
> >>> index 20dc705642bd..b5b0bf37813b 100644
> >>> --- a/include/drm/drm_dp_mst_helper.h
> >>> +++ b/include/drm/drm_dp_mst_helper.h
> >>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
> >>>          * @max_payloads: maximum number of payloads the GPU can generate.
> >>>          */
> >>>         int max_payloads;
> >>> +       /**
> >>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
> >>> +        */
> >>> +       int max_lane_count;
> >>> +       /**
> >>> +        * @max_link_rate: maximum link rate per lane GPU can output.
> >>> +        */
> >>> +       int max_link_rate;
> >>>         /**
> >>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
> >>> used
> >>>          * to build the MST connector path value.
> >>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
> >>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
> >>>                                  struct drm_device *dev, struct drm_dp_aux
> >>> *aux,
> >>>                                  int max_dpcd_transaction_bytes,
> >>> -                                int max_payloads, int conn_base_id);
> >>> +                                int max_payloads,
> >>> +                                int max_lane_count, int max_link_rate,
> >>> +                                int conn_base_id);
> >>>  
> >>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
> >>>  
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-05-04  7:43           ` Daniel Vetter
  0 siblings, 0 replies; 27+ messages in thread
From: Daniel Vetter @ 2021-05-04  7:43 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Maxime Ripard, dri-devel, Daniel Vetter, intel-gfx, Lankhorst,
	Maarten, amd-gfx, Nikola Cornij, koba.ko, aurabindo.pillai,
	Ben Skeggs, Thomas Zimmermann, mikita.lipski

On Mon, May 03, 2021 at 11:33:33AM +0300, Jani Nikula wrote:
> On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> > On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
> >> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
> >> today if there's no objections
> >
> > Thanks for the heads-up, I think this breaks i915. See my review
> > comments elsewhere in the thread.
> 
> Looks like this was merged anyway.

Yeah in general rule of thumb is to let cross-driver stuff soak for a week
(assuming correctly cc'ed and all that already). I think that's the sweet
spot between maintainers who complain that it's too short and others
complaining it's too quick :-)
-Daniel

> 
> 98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")
> 
> I'm not happy how this played out.
> 
> 1) You need to Cc relevant people
> 
> 2) You need to get the ack before merging changes
> 
> 3) You need to give people more than a day to react, with time zones and
> all; I replied as soon as I saw the heads-up, but it was already too
> late
> 
> It's broken on i915, and perhaps that could be fixed.
> 
> However I also think using DP spec rate codes and calling them "rate" is
> a bad interface, especially when the unit breaks down with DP 2.0 rate
> codes. It's confusing and it's not future proof. Fixing that afterwards
> falls to whoever comes next to pick up the pieces.
> 
> I'd rather just see this reverted and redone.
> 
> 
> BR,
> Jani.
> 
> 
> >
> > BR,
> > Jani.
> >
> >
> >>
> >> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
> >>> [why]
> >>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> >>> set, Extended Base Receiver Capability DPCD space must be used. Without
> >>> doing that, the three DPCD values that differ will be wrong, leading to
> >>> incorrect or limited functionality. MST link rate, for example, could
> >>> have a lower value. Also, Synaptics quirk wouldn't work out well when
> >>> Extended DPCD was not read, resulting in no DSC for such hubs.
> >>> 
> >>> [how]
> >>> Modify MST topology manager to use the values from Extended DPCD where
> >>> applicable.
> >>> 
> >>> To prevent regression on the sources that have a lower maximum link rate
> >>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> >>> supply maximum lane count and rate at initialization time.
> >>> 
> >>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> >>> extended DPCD caps for topology manager")', brining the change back to
> >>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> >>> caps for topology manager")'.
> >>> 
> >>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> >>> ---
> >>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
> >>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
> >>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
> >>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
> >>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
> >>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
> >>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
> >>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
> >>>  8 files changed, 71 insertions(+), 15 deletions(-)
> >>> 
> >>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> index 997567f6f0ba..b7e01b6fb328 100644
> >>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>                                        struct amdgpu_dm_connector
> >>> *aconnector,
> >>>                                        int link_index)
> >>>  {
> >>> +       struct dc_link_settings max_link_enc_cap = {0};
> >>> +
> >>>         aconnector->dm_dp_aux.aux.name =
> >>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
> >>>                           link_index);
> >>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
> >>>                 return;
> >>>  
> >>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
> >>> &max_link_enc_cap);
> >>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
> >>>         drm_dp_mst_topology_mgr_init(
> >>>                 &aconnector->mst_mgr,
> >>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>                 &aconnector->dm_dp_aux.aux,
> >>>                 16,
> >>>                 4,
> >>> +               max_link_enc_cap.lane_count,
> >>> +               max_link_enc_cap.link_rate,
> >>>                 aconnector->connector_id);
> >>>  
> >>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
> >>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> index 7d2e433c2275..6fe66b7ee53e 100644
> >>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
> >>> bool link_down)
> >>>         return true;
> >>>  }
> >>>  
> >>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> >>> dc_link_settings *max_link_enc_cap)
> >>> +{
> >>> +       if (!max_link_enc_cap) {
> >>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
> >>> __func__);
> >>> +               return false;
> >>> +       }
> >>> +
> >>> +       if (link->link_enc->funcs->get_max_link_cap) {
> >>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
> >>> max_link_enc_cap);
> >>> +               return true;
> >>> +       }
> >>> +
> >>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
> >>> +       max_link_enc_cap->lane_count = 1;
> >>> +       max_link_enc_cap->link_rate = 6;
> >>> +       return false;
> >>> +}
> >>> +
> >>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
> >>>  {
> >>>         struct dc_link_settings max_link_cap = {0};
> >>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> index b0013e674864..cb6d0543d839 100644
> >>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
> >>>         const unsigned char *p_custom_pattern,
> >>>         unsigned int cust_pattern_size);
> >>>  
> >>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> >>> dc_link_settings *max_link_enc_cap);
> >>> +
> >>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
> >>>  
> >>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
> >>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> b/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> index 5539a91b4031..31d9f3ff0d39 100644
> >>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
> >>> drm_dp_mst_topology_mgr *mgr, bool ms
> >>>         /* set the device into MST mode */
> >>>         if (mst_state) {
> >>>                 struct drm_dp_payload reset_pay;
> >>> +               int lane_count;
> >>> +               int link_rate;
> >>>  
> >>>                 WARN_ON(mgr->mst_primary);
> >>>  
> >>>                 /* get dpcd info */
> >>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> >>> DP_RECEIVER_CAP_SIZE);
> >>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
> >>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
> >>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
> >>> +               if (ret < 0) {
> >>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
> >>> %d\n",
> >>> +                                   mgr->aux->name, ret);
> >>>                         goto out_unlock;
> >>>                 }
> >>>  
> >>> +               lane_count = min_t(int, mgr->dpcd[2] &
> >>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
> >>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
> >>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
> >>> -
> >>>                                                        drm_dp_bw_code_to_link
> >>> _rate(mgr->dpcd[1]),
> >>> -                                                       mgr->dpcd[2] &
> >>> DP_MAX_LANE_COUNT_MASK);
> >>> +                                                       drm_dp_bw_code_to_li
> >>> nk_rate(link_rate),
> >>> +                                                       lane_count);
> >>>                 if (mgr->pbn_div == 0) {
> >>>                         ret = -EINVAL;
> >>>                         goto out_unlock;
> >>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
> >>>   * @aux: DP helper aux channel to talk to this device
> >>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
> >>>   * @max_payloads: maximum number of payloads this GPU can source
> >>> + * @max_lane_count: maximum number of lanes this GPU supports
> >>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
> >>>   * @conn_base_id: the connector object ID the MST device is connected to.
> >>>   *
> >>>   * Return 0 for success, or negative error code on failure
> >>>   */
> >>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
> >>>                                  struct drm_device *dev, struct drm_dp_aux
> >>> *aux,
> >>> -                                int max_dpcd_transaction_bytes,
> >>> -                                int max_payloads, int conn_base_id)
> >>> +                                int max_dpcd_transaction_bytes, int
> >>> max_payloads,
> >>> +                                int max_lane_count, int max_link_rate,
> >>> +                                int conn_base_id)
> >>>  {
> >>>         struct drm_dp_mst_topology_state *mst_state;
> >>>  
> >>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
> >>> drm_dp_mst_topology_mgr *mgr,
> >>>         mgr->aux = aux;
> >>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
> >>>         mgr->max_payloads = max_payloads;
> >>> +       mgr->max_lane_count = max_lane_count;
> >>> +       mgr->max_link_rate = max_link_rate;
> >>>         mgr->conn_base_id = conn_base_id;
> >>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
> >>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
> >>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
> >>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
> >>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> >>>  
> >>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> >>> -                                    &downstreamport, 1) < 0)
> >>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
> >>>                         return NULL;
> >>>  
> >>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> >>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> >>> +               if ((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;
> >>>         }
> >>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> index 860381d68d9d..a4245eb48ef4 100644
> >>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> >>> *dig_port, int conn_base_id)
> >>>         struct intel_dp *intel_dp = &dig_port->dp;
> >>>         enum port port = dig_port->base.port;
> >>>         int ret;
> >>> +       int bios_max_link_rate;
> >>>  
> >>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
> >>>                 return 0;
> >>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> >>> *dig_port, int conn_base_id)
> >>>  
> >>>         /* create encoders */
> >>>         intel_dp_create_fake_mst_encoders(dig_port);
> >>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
> >>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> >>> -                                          &intel_dp->aux, 16, 3,
> >>> conn_base_id);
> >>> +                                          &intel_dp->aux, 16, 3,
> >>> +                                          dig_port->max_lanes,
> >>> +                                          bios_max_link_rate / 27000,
> >>> conn_base_id);
> >>>         if (ret)
> >>>                 return ret;
> >>>  
> >>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> index 1c9c0cdf85db..e02f9d2d74eb 100644
> >>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
> >>> drm_dp_aux *aux, int aux_max,
> >>>         mstm->mgr.cbs = &nv50_mstm;
> >>>  
> >>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
> >>> -                                          max_payloads, conn_base_id);
> >>> +                                          max_payloads, outp->dcb-
> >>> >dpconf.link_nr,
> >>> +                                          outp->dcb->dpconf.link_bw,
> >>> conn_base_id);
> >>>         if (ret)
> >>>                 return ret;
> >>>  
> >>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> index 59cf1d288465..8f0b2dccd199 100644
> >>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> @@ -629,13 +629,20 @@ int
> >>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
> >>>  {
> >>>         struct drm_device *dev = radeon_connector->base.dev;
> >>> +       int max_link_rate;
> >>>  
> >>>         if (!radeon_connector->ddc_bus->has_aux)
> >>>                 return 0;
> >>>  
> >>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
> >>> +               max_link_rate = 0x14;
> >>> +       else
> >>> +               max_link_rate = 0x0a;
> >>> +
> >>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
> >>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
> >>>                                             &radeon_connector->ddc_bus->aux,
> >>> 16, 6,
> >>> +                                           4, max_link_rate,
> >>>                                             radeon_connector->base.base.id);
> >>>  }
> >>>  
> >>> diff --git a/include/drm/drm_dp_mst_helper.h
> >>> b/include/drm/drm_dp_mst_helper.h
> >>> index 20dc705642bd..b5b0bf37813b 100644
> >>> --- a/include/drm/drm_dp_mst_helper.h
> >>> +++ b/include/drm/drm_dp_mst_helper.h
> >>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
> >>>          * @max_payloads: maximum number of payloads the GPU can generate.
> >>>          */
> >>>         int max_payloads;
> >>> +       /**
> >>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
> >>> +        */
> >>> +       int max_lane_count;
> >>> +       /**
> >>> +        * @max_link_rate: maximum link rate per lane GPU can output.
> >>> +        */
> >>> +       int max_link_rate;
> >>>         /**
> >>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
> >>> used
> >>>          * to build the MST connector path value.
> >>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
> >>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
> >>>                                  struct drm_device *dev, struct drm_dp_aux
> >>> *aux,
> >>>                                  int max_dpcd_transaction_bytes,
> >>> -                                int max_payloads, int conn_base_id);
> >>> +                                int max_payloads,
> >>> +                                int max_lane_count, int max_link_rate,
> >>> +                                int conn_base_id);
> >>>  
> >>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
> >>>  
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Heads up to maintainers] Re: [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space
@ 2021-05-04  7:43           ` Daniel Vetter
  0 siblings, 0 replies; 27+ messages in thread
From: Daniel Vetter @ 2021-05-04  7:43 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Maxime Ripard, dri-devel, Daniel Vetter, intel-gfx, Lankhorst,
	Maarten, amd-gfx, Nikola Cornij, koba.ko, aurabindo.pillai,
	Ben Skeggs, Thomas Zimmermann, mikita.lipski, Dave Airlie,
	ville.syrjala

On Mon, May 03, 2021 at 11:33:33AM +0300, Jani Nikula wrote:
> On Fri, 30 Apr 2021, Jani Nikula <jani.nikula@intel.com> wrote:
> > On Thu, 29 Apr 2021, Lyude Paul <lyude@redhat.com> wrote:
> >> JFYI Jani and Ben: I will be pushing this patch to drm-misc-next sometime
> >> today if there's no objections
> >
> > Thanks for the heads-up, I think this breaks i915. See my review
> > comments elsewhere in the thread.
> 
> Looks like this was merged anyway.

Yeah in general rule of thumb is to let cross-driver stuff soak for a week
(assuming correctly cc'ed and all that already). I think that's the sweet
spot between maintainers who complain that it's too short and others
complaining it's too quick :-)
-Daniel

> 
> 98025a62cb00 ("drm/dp_mst: Use Extended Base Receiver Capability DPCD space")
> 
> I'm not happy how this played out.
> 
> 1) You need to Cc relevant people
> 
> 2) You need to get the ack before merging changes
> 
> 3) You need to give people more than a day to react, with time zones and
> all; I replied as soon as I saw the heads-up, but it was already too
> late
> 
> It's broken on i915, and perhaps that could be fixed.
> 
> However I also think using DP spec rate codes and calling them "rate" is
> a bad interface, especially when the unit breaks down with DP 2.0 rate
> codes. It's confusing and it's not future proof. Fixing that afterwards
> falls to whoever comes next to pick up the pieces.
> 
> I'd rather just see this reverted and redone.
> 
> 
> BR,
> Jani.
> 
> 
> >
> > BR,
> > Jani.
> >
> >
> >>
> >> On Wed, 2021-04-28 at 19:43 -0400, Nikola Cornij wrote:
> >>> [why]
> >>> DP 1.4a spec madates that if DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is
> >>> set, Extended Base Receiver Capability DPCD space must be used. Without
> >>> doing that, the three DPCD values that differ will be wrong, leading to
> >>> incorrect or limited functionality. MST link rate, for example, could
> >>> have a lower value. Also, Synaptics quirk wouldn't work out well when
> >>> Extended DPCD was not read, resulting in no DSC for such hubs.
> >>> 
> >>> [how]
> >>> Modify MST topology manager to use the values from Extended DPCD where
> >>> applicable.
> >>> 
> >>> To prevent regression on the sources that have a lower maximum link rate
> >>> capability than MAX_LINK_RATE from Extended DPCD, have the drivers
> >>> supply maximum lane count and rate at initialization time.
> >>> 
> >>> This also reverts 'commit 2dcab875e763 ("Revert drm/dp_mst: Retrieve
> >>> extended DPCD caps for topology manager")', brining the change back to
> >>> the original 'commit ad44c03208e4 ("drm/dp_mst: Retrieve extended DPCD
> >>> caps for topology manager")'.
> >>> 
> >>> Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
> >>> ---
> >>>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  5 +++
> >>>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 18 ++++++++++
> >>>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  2 ++
> >>>  drivers/gpu/drm/drm_dp_mst_topology.c         | 33 ++++++++++++-------
> >>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
> >>>  drivers/gpu/drm/nouveau/dispnv50/disp.c       |  3 +-
> >>>  drivers/gpu/drm/radeon/radeon_dp_mst.c        |  7 ++++
> >>>  include/drm/drm_dp_mst_helper.h               | 12 ++++++-
> >>>  8 files changed, 71 insertions(+), 15 deletions(-)
> >>> 
> >>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> index 997567f6f0ba..b7e01b6fb328 100644
> >>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> >>> @@ -429,6 +429,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>                                        struct amdgpu_dm_connector
> >>> *aconnector,
> >>>                                        int link_index)
> >>>  {
> >>> +       struct dc_link_settings max_link_enc_cap = {0};
> >>> +
> >>>         aconnector->dm_dp_aux.aux.name =
> >>>                 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
> >>>                           link_index);
> >>> @@ -443,6 +445,7 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>         if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
> >>>                 return;
> >>>  
> >>> +       dc_link_dp_get_max_link_enc_cap(aconnector->dc_link,
> >>> &max_link_enc_cap);
> >>>         aconnector->mst_mgr.cbs = &dm_mst_cbs;
> >>>         drm_dp_mst_topology_mgr_init(
> >>>                 &aconnector->mst_mgr,
> >>> @@ -450,6 +453,8 @@ void amdgpu_dm_initialize_dp_connector(struct
> >>> amdgpu_display_manager *dm,
> >>>                 &aconnector->dm_dp_aux.aux,
> >>>                 16,
> >>>                 4,
> >>> +               max_link_enc_cap.lane_count,
> >>> +               max_link_enc_cap.link_rate,
> >>>                 aconnector->connector_id);
> >>>  
> >>>         drm_connector_attach_dp_subconnector_property(&aconnector->base);
> >>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> index 7d2e433c2275..6fe66b7ee53e 100644
> >>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >>> @@ -1894,6 +1894,24 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link,
> >>> bool link_down)
> >>>         return true;
> >>>  }
> >>>  
> >>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> >>> dc_link_settings *max_link_enc_cap)
> >>> +{
> >>> +       if (!max_link_enc_cap) {
> >>> +               DC_LOG_ERROR("%s: Could not return max link encoder caps",
> >>> __func__);
> >>> +               return false;
> >>> +       }
> >>> +
> >>> +       if (link->link_enc->funcs->get_max_link_cap) {
> >>> +               link->link_enc->funcs->get_max_link_cap(link->link_enc,
> >>> max_link_enc_cap);
> >>> +               return true;
> >>> +       }
> >>> +
> >>> +       DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
> >>> +       max_link_enc_cap->lane_count = 1;
> >>> +       max_link_enc_cap->link_rate = 6;
> >>> +       return false;
> >>> +}
> >>> +
> >>>  static struct dc_link_settings get_max_link_cap(struct dc_link *link)
> >>>  {
> >>>         struct dc_link_settings max_link_cap = {0};
> >>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> b/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> index b0013e674864..cb6d0543d839 100644
> >>> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> >>> @@ -346,6 +346,8 @@ bool dc_link_dp_set_test_pattern(
> >>>         const unsigned char *p_custom_pattern,
> >>>         unsigned int cust_pattern_size);
> >>>  
> >>> +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct
> >>> dc_link_settings *max_link_enc_cap);
> >>> +
> >>>  void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
> >>>  
> >>>  bool dc_link_is_dp_sink_present(struct dc_link *link);
> >>> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> b/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> index 5539a91b4031..31d9f3ff0d39 100644
> >>> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> >>> @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct
> >>> drm_dp_mst_topology_mgr *mgr, bool ms
> >>>         /* set the device into MST mode */
> >>>         if (mst_state) {
> >>>                 struct drm_dp_payload reset_pay;
> >>> +               int lane_count;
> >>> +               int link_rate;
> >>>  
> >>>                 WARN_ON(mgr->mst_primary);
> >>>  
> >>>                 /* get dpcd info */
> >>> -               ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> >>> DP_RECEIVER_CAP_SIZE);
> >>> -               if (ret != DP_RECEIVER_CAP_SIZE) {
> >>> -                       drm_dbg_kms(mgr->dev, "failed to read DPCD\n");
> >>> +               ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);
> >>> +               if (ret < 0) {
> >>> +                       drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret
> >>> %d\n",
> >>> +                                   mgr->aux->name, ret);
> >>>                         goto out_unlock;
> >>>                 }
> >>>  
> >>> +               lane_count = min_t(int, mgr->dpcd[2] &
> >>> DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
> >>> +               link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
> >>>                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
> >>> -
> >>>                                                        drm_dp_bw_code_to_link
> >>> _rate(mgr->dpcd[1]),
> >>> -                                                       mgr->dpcd[2] &
> >>> DP_MAX_LANE_COUNT_MASK);
> >>> +                                                       drm_dp_bw_code_to_li
> >>> nk_rate(link_rate),
> >>> +                                                       lane_count);
> >>>                 if (mgr->pbn_div == 0) {
> >>>                         ret = -EINVAL;
> >>>                         goto out_unlock;
> >>> @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
> >>>   * @aux: DP helper aux channel to talk to this device
> >>>   * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
> >>>   * @max_payloads: maximum number of payloads this GPU can source
> >>> + * @max_lane_count: maximum number of lanes this GPU supports
> >>> + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD
> >>>   * @conn_base_id: the connector object ID the MST device is connected to.
> >>>   *
> >>>   * Return 0 for success, or negative error code on failure
> >>>   */
> >>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
> >>>                                  struct drm_device *dev, struct drm_dp_aux
> >>> *aux,
> >>> -                                int max_dpcd_transaction_bytes,
> >>> -                                int max_payloads, int conn_base_id)
> >>> +                                int max_dpcd_transaction_bytes, int
> >>> max_payloads,
> >>> +                                int max_lane_count, int max_link_rate,
> >>> +                                int conn_base_id)
> >>>  {
> >>>         struct drm_dp_mst_topology_state *mst_state;
> >>>  
> >>> @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct
> >>> drm_dp_mst_topology_mgr *mgr,
> >>>         mgr->aux = aux;
> >>>         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
> >>>         mgr->max_payloads = max_payloads;
> >>> +       mgr->max_lane_count = max_lane_count;
> >>> +       mgr->max_link_rate = max_link_rate;
> >>>         mgr->conn_base_id = conn_base_id;
> >>>         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
> >>>             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
> >>> @@ -5896,14 +5906,13 @@ struct drm_dp_aux
> >>> *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
> >>>         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 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> >>>  
> >>> -               if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
> >>> -                                    &downstreamport, 1) < 0)
> >>> +               if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
> >>>                         return NULL;
> >>>  
> >>> -               if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
> >>> -                  ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
> >>> +               if ((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;
> >>>         }
> >>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> index 860381d68d9d..a4245eb48ef4 100644
> >>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> >>> @@ -942,6 +942,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> >>> *dig_port, int conn_base_id)
> >>>         struct intel_dp *intel_dp = &dig_port->dp;
> >>>         enum port port = dig_port->base.port;
> >>>         int ret;
> >>> +       int bios_max_link_rate;
> >>>  
> >>>         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
> >>>                 return 0;
> >>> @@ -956,8 +957,11 @@ intel_dp_mst_encoder_init(struct intel_digital_port
> >>> *dig_port, int conn_base_id)
> >>>  
> >>>         /* create encoders */
> >>>         intel_dp_create_fake_mst_encoders(dig_port);
> >>> +       bios_max_link_rate = intel_bios_dp_max_link_rate(&dig_port->base);
> >>>         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
> >>> -                                          &intel_dp->aux, 16, 3,
> >>> conn_base_id);
> >>> +                                          &intel_dp->aux, 16, 3,
> >>> +                                          dig_port->max_lanes,
> >>> +                                          bios_max_link_rate / 27000,
> >>> conn_base_id);
> >>>         if (ret)
> >>>                 return ret;
> >>>  
> >>> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> index 1c9c0cdf85db..e02f9d2d74eb 100644
> >>> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> >>> @@ -1617,7 +1617,8 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct
> >>> drm_dp_aux *aux, int aux_max,
> >>>         mstm->mgr.cbs = &nv50_mstm;
> >>>  
> >>>         ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
> >>> -                                          max_payloads, conn_base_id);
> >>> +                                          max_payloads, outp->dcb-
> >>> >dpconf.link_nr,
> >>> +                                          outp->dcb->dpconf.link_bw,
> >>> conn_base_id);
> >>>         if (ret)
> >>>                 return ret;
> >>>  
> >>> diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> index 59cf1d288465..8f0b2dccd199 100644
> >>> --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
> >>> @@ -629,13 +629,20 @@ int
> >>>  radeon_dp_mst_init(struct radeon_connector *radeon_connector)
> >>>  {
> >>>         struct drm_device *dev = radeon_connector->base.dev;
> >>> +       int max_link_rate;
> >>>  
> >>>         if (!radeon_connector->ddc_bus->has_aux)
> >>>                 return 0;
> >>>  
> >>> +       if (radeon_connector_is_dp12_capable(&radeon_connector->base))
> >>> +               max_link_rate = 0x14;
> >>> +       else
> >>> +               max_link_rate = 0x0a;
> >>> +
> >>>         radeon_connector->mst_mgr.cbs = &mst_cbs;
> >>>         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
> >>>                                             &radeon_connector->ddc_bus->aux,
> >>> 16, 6,
> >>> +                                           4, max_link_rate,
> >>>                                             radeon_connector->base.base.id);
> >>>  }
> >>>  
> >>> diff --git a/include/drm/drm_dp_mst_helper.h
> >>> b/include/drm/drm_dp_mst_helper.h
> >>> index 20dc705642bd..b5b0bf37813b 100644
> >>> --- a/include/drm/drm_dp_mst_helper.h
> >>> +++ b/include/drm/drm_dp_mst_helper.h
> >>> @@ -593,6 +593,14 @@ struct drm_dp_mst_topology_mgr {
> >>>          * @max_payloads: maximum number of payloads the GPU can generate.
> >>>          */
> >>>         int max_payloads;
> >>> +       /**
> >>> +        * @max_lane_count: maximum number of lanes the GPU can drive.
> >>> +        */
> >>> +       int max_lane_count;
> >>> +       /**
> >>> +        * @max_link_rate: maximum link rate per lane GPU can output.
> >>> +        */
> >>> +       int max_link_rate;
> >>>         /**
> >>>          * @conn_base_id: DRM connector ID this mgr is connected to. Only
> >>> used
> >>>          * to build the MST connector path value.
> >>> @@ -765,7 +773,9 @@ struct drm_dp_mst_topology_mgr {
> >>>  int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
> >>>                                  struct drm_device *dev, struct drm_dp_aux
> >>> *aux,
> >>>                                  int max_dpcd_transaction_bytes,
> >>> -                                int max_payloads, int conn_base_id);
> >>> +                                int max_payloads,
> >>> +                                int max_lane_count, int max_link_rate,
> >>> +                                int conn_base_id);
> >>>  
> >>>  void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr);
> >>>  
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2021-05-04  7:43 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-28 23:43 [PATCH v8 0/1] drm/drm_mst: Use Extended Base Receiver Capability Nikola Cornij
2021-04-28 23:43 ` Nikola Cornij
2021-04-28 23:43 ` [Intel-gfx] " Nikola Cornij
2021-04-28 23:43 ` [PATCH v8 1/1] drm/drm_mst: Use Extended Base Receiver Capability DPCD space Nikola Cornij
2021-04-28 23:43   ` Nikola Cornij
2021-04-28 23:43   ` [Intel-gfx] " Nikola Cornij
2021-04-29 19:00   ` [Heads up to maintainers] " Lyude Paul
2021-04-29 19:00     ` Lyude Paul
2021-04-29 19:00     ` [Intel-gfx] " Lyude Paul
2021-04-30  5:44     ` Jani Nikula
2021-04-30  5:44       ` Jani Nikula
2021-04-30  5:44       ` [Intel-gfx] " Jani Nikula
2021-05-03  8:33       ` Jani Nikula
2021-05-03  8:33         ` Jani Nikula
2021-05-03  8:33         ` [Intel-gfx] " Jani Nikula
2021-05-03  8:41         ` Jani Nikula
2021-05-03  8:41           ` Jani Nikula
2021-05-03  8:41           ` [Intel-gfx] " Jani Nikula
2021-05-04  7:43         ` Daniel Vetter
2021-05-04  7:43           ` Daniel Vetter
2021-05-04  7:43           ` [Intel-gfx] " Daniel Vetter
2021-04-30  5:43   ` [Intel-gfx] " Jani Nikula
2021-04-30  5:43     ` Jani Nikula
2021-04-30  5:43     ` Jani Nikula
2021-04-29  0:24 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/drm_mst: Use Extended Base Receiver Capability (rev6) Patchwork
2021-04-29  0:55 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-04-29  2:12 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.