All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm: Remove slot checks in dp mst topology during commit
@ 2021-10-20 19:47 ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	intel-gfx, Bhawanpreet Lakha

This code path is used during commit, and we dont expect things to fail
during the commit stage, so remove this.

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..5ab3b3a46e89 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -4332,10 +4332,6 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 {
 	int ret;
 
-	/* max. time slots - one slot for MTP header */
-	if (slots > 63)
-		return -ENOSPC;
-
 	vcpi->pbn = pbn;
 	vcpi->aligned_pbn = slots * mgr->pbn_div;
 	vcpi->num_slots = slots;
@@ -4538,7 +4534,7 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
 	if (ret) {
-		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
+		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d ret=%d\n",
 			    DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
 		drm_dp_mst_topology_put_port(port);
 		goto out;
-- 
2.25.1


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

* [Intel-gfx] [PATCH 1/4] drm: Remove slot checks in dp mst topology during commit
@ 2021-10-20 19:47 ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	intel-gfx, Bhawanpreet Lakha

This code path is used during commit, and we dont expect things to fail
during the commit stage, so remove this.

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..5ab3b3a46e89 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -4332,10 +4332,6 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 {
 	int ret;
 
-	/* max. time slots - one slot for MTP header */
-	if (slots > 63)
-		return -ENOSPC;
-
 	vcpi->pbn = pbn;
 	vcpi->aligned_pbn = slots * mgr->pbn_div;
 	vcpi->num_slots = slots;
@@ -4538,7 +4534,7 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 
 	ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
 	if (ret) {
-		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 ret=%d\n",
+		drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d ret=%d\n",
 			    DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
 		drm_dp_mst_topology_put_port(port);
 		goto out;
-- 
2.25.1


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

* [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-20 19:47 ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-20 19:47   ` Bhawanpreet Lakha
  -1 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	intel-gfx, Bhawanpreet Lakha

8b/10b encoding format requires to reserve the first slot for
recording metadata. Real data transmission starts from the second slot,
with a total of available 63 slots available.

In 128b/132b encoding format, metadata is transmitted separately
in LLCP packet before MTP. Real data transmission starts from
the first slot, with a total of 64 slots available.

v2:
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

v3:
* Only keep the slot info on the mst_state
* add a start_slot parameter to the payload function, to facilitate non
  atomic drivers (this is a temporary workaround and should be removed when
  we are moving out the non atomic driver helpers)

v4:
*fixed typo and formatting

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c         | 38 ++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  2 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  4 +-
 include/drm/drm_dp_mst_helper.h               |  5 ++-
 6 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ff0f91c93ba4..6169488e2011 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr);
+	drm_dp_update_payload_part1(mst_mgr, 1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5ab3b3a46e89..82ee6791576c 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,10 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 /**
  * drm_dp_update_payload_part1() - Execute payload update part 1
  * @mgr: manager to use.
+ * @start_slot: this is the cur slot
+ *
+ * NOTE: start_slot is a temporary workaround for non-atomic drivers,
+ * this will be removed when non-atomic mst helpers are moved out of the helper
  *
  * This iterates over all proposed virtual channels, and tries to
  * allocate space in the link for them. For 0->slots transitions,
@@ -3360,15 +3364,15 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
  * transitions, this writes the updated VCPIs and removes the
  * remote VC payloads.
  *
- * after calling this the driver should generate ACT and payload
+ *after calling this the driver should generate ACT and payload
  * packets.
  */
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot)
 {
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = start_slot;
 	bool skip;
 
 	mutex_lock(&mgr->payload_lock);
@@ -4503,6 +4507,27 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/**
+ * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format
+ * @mst_state: mst_state to update
+ * @link_encoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)
+{
+	if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
+		mst_state->total_avail_slots = 64;
+		mst_state->start_slot = 0;
+	} else {
+		mst_state->total_avail_slots = 63;
+		mst_state->start_slot = 1;
+	}
+
+	DRM_DEBUG_KMS("%s encoding format on mst_state 0x%p\n",
+			(link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
+			mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_slots);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -5222,7 +5247,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mst_state->total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5276,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 		}
 	}
 	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-		       mgr, mst_state, avail_slots, 63 - avail_slots);
+		       mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5528,6 +5553,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (mst_state == NULL)
 		return -ENOMEM;
 
+	mst_state->total_avail_slots = 63;
+	mst_state->start_slot = 1;
+
 	mst_state->mgr = mgr;
 	INIT_LIST_HEAD(&mst_state->vcpis);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..d3a24189a12c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -368,7 +368,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
 	}
@@ -516,7 +516,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 
 	intel_dp->active_mst_links++;
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 
 	/*
 	 * Before Gen 12 this is not done as part of
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index f949767698fc..6c8c59c26dbf 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1413,7 +1413,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
 	int ret;
 
 	NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
-	ret = drm_dp_update_payload_part1(&mstm->mgr);
+	ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
 
 	drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
 		if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index ec867fa880a4..751c2c075e09 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
 					 radeon_connector->port,
 					 mst_enc->pbn, slots);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		radeon_dp_mst_set_be_cntl(primary, mst_enc,
 					  radeon_connector->mst_port->hpd.hpd, true);
@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 			return;
 
 		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
 		/* and this can also fail */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..78044ac5b59b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
 	struct drm_private_state base;
 	struct list_head vcpis;
 	struct drm_dp_mst_topology_mgr *mgr;
+	u8 total_avail_slots;
+	u8 start_slot;
 };
 
 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -806,6 +808,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 			   int pbn);
 
 
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot);
 
 
 int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
-- 
2.25.1


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

* [Intel-gfx] [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-10-20 19:47   ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	intel-gfx, Bhawanpreet Lakha

8b/10b encoding format requires to reserve the first slot for
recording metadata. Real data transmission starts from the second slot,
with a total of available 63 slots available.

In 128b/132b encoding format, metadata is transmitted separately
in LLCP packet before MTP. Real data transmission starts from
the first slot, with a total of 64 slots available.

v2:
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

v3:
* Only keep the slot info on the mst_state
* add a start_slot parameter to the payload function, to facilitate non
  atomic drivers (this is a temporary workaround and should be removed when
  we are moving out the non atomic driver helpers)

v4:
*fixed typo and formatting

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c         | 38 ++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  2 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  4 +-
 include/drm/drm_dp_mst_helper.h               |  5 ++-
 6 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ff0f91c93ba4..6169488e2011 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr);
+	drm_dp_update_payload_part1(mst_mgr, 1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5ab3b3a46e89..82ee6791576c 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,10 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 /**
  * drm_dp_update_payload_part1() - Execute payload update part 1
  * @mgr: manager to use.
+ * @start_slot: this is the cur slot
+ *
+ * NOTE: start_slot is a temporary workaround for non-atomic drivers,
+ * this will be removed when non-atomic mst helpers are moved out of the helper
  *
  * This iterates over all proposed virtual channels, and tries to
  * allocate space in the link for them. For 0->slots transitions,
@@ -3360,15 +3364,15 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
  * transitions, this writes the updated VCPIs and removes the
  * remote VC payloads.
  *
- * after calling this the driver should generate ACT and payload
+ *after calling this the driver should generate ACT and payload
  * packets.
  */
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot)
 {
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = start_slot;
 	bool skip;
 
 	mutex_lock(&mgr->payload_lock);
@@ -4503,6 +4507,27 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/**
+ * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format
+ * @mst_state: mst_state to update
+ * @link_encoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)
+{
+	if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
+		mst_state->total_avail_slots = 64;
+		mst_state->start_slot = 0;
+	} else {
+		mst_state->total_avail_slots = 63;
+		mst_state->start_slot = 1;
+	}
+
+	DRM_DEBUG_KMS("%s encoding format on mst_state 0x%p\n",
+			(link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
+			mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_slots);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -5222,7 +5247,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mst_state->total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5276,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 		}
 	}
 	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-		       mgr, mst_state, avail_slots, 63 - avail_slots);
+		       mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5528,6 +5553,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (mst_state == NULL)
 		return -ENOMEM;
 
+	mst_state->total_avail_slots = 63;
+	mst_state->start_slot = 1;
+
 	mst_state->mgr = mgr;
 	INIT_LIST_HEAD(&mst_state->vcpis);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..d3a24189a12c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -368,7 +368,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
 	}
@@ -516,7 +516,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 
 	intel_dp->active_mst_links++;
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 
 	/*
 	 * Before Gen 12 this is not done as part of
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index f949767698fc..6c8c59c26dbf 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1413,7 +1413,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
 	int ret;
 
 	NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
-	ret = drm_dp_update_payload_part1(&mstm->mgr);
+	ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
 
 	drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
 		if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index ec867fa880a4..751c2c075e09 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
 					 radeon_connector->port,
 					 mst_enc->pbn, slots);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		radeon_dp_mst_set_be_cntl(primary, mst_enc,
 					  radeon_connector->mst_port->hpd.hpd, true);
@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 			return;
 
 		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
 		/* and this can also fail */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..78044ac5b59b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
 	struct drm_private_state base;
 	struct list_head vcpis;
 	struct drm_dp_mst_topology_mgr *mgr;
+	u8 total_avail_slots;
+	u8 start_slot;
 };
 
 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -806,6 +808,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 			   int pbn);
 
 
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot);
 
 
 int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
-- 
2.25.1


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

* [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-20 19:47 ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-20 19:47   ` Bhawanpreet Lakha
  -1 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski, intel-gfx

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..b23972b6a27c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
+
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
 
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [Intel-gfx] [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-20 19:47   ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski, intel-gfx

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..b23972b6a27c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
+
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
 
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support
  2021-10-20 19:47 ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-20 19:47   ` Bhawanpreet Lakha
  -1 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	intel-gfx, Bhawanpreet Lakha

[Why]
Add DP2 MST and debugfs support

[How]
Update the slot info based on the link encoding format

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 29 +++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |  3 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  5 +++-
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e56f73e299ef..875425ee91d0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10741,6 +10741,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	struct dsc_mst_fairness_vars vars[MAX_PIPES];
 #endif
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_topology_mgr *mgr;
 
 	trace_amdgpu_dm_atomic_check_begin(state);
 
@@ -10948,6 +10950,33 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		lock_and_validation_needed = true;
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	/* set the slot info for each mst_state based on the link encoding format */
+	for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
+		struct amdgpu_dm_connector *aconnector;
+		struct drm_connector *connector;
+		struct drm_connector_list_iter iter;
+		u8 link_coding_cap;
+
+		if (!mgr->mst_state )
+			continue;
+
+		drm_connector_list_iter_begin(dev, &iter);
+		drm_for_each_connector_iter(connector, &iter) {
+			int id = connector->index;
+
+			if (id == mst_state->mgr->conn_base_id) {
+				aconnector = to_amdgpu_dm_connector(connector);
+				link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+				drm_dp_mst_update_slots(mst_state, link_coding_cap);
+
+				break;
+			}
+		}
+		drm_connector_list_iter_end(&iter);
+
+	}
+#endif
 	/**
 	 * Streams and planes are reset when there are changes that affect
 	 * bandwidth. Anything that affects bandwidth needs to go through
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 9b3ad56607bb..1a68a674913c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -294,6 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
 	case LINK_RATE_RBR2:
 	case LINK_RATE_HIGH2:
 	case LINK_RATE_HIGH3:
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	case LINK_RATE_UHBR10:
+#endif
 		break;
 	default:
 		valid_input = false;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 6169488e2011..53b5cc7b0679 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -219,6 +219,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	struct drm_dp_mst_topology_mgr *mst_mgr;
 	struct drm_dp_mst_port *mst_port;
 	bool ret;
+	u8 link_coding_cap;
 
 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
 	/* Accessing the connector state is required for vcpi_slots allocation
@@ -238,6 +239,8 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
 	mst_port = aconnector->port;
 
+	link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+
 	if (enable) {
 
 		ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port,
@@ -251,7 +254,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr, 1);
+	drm_dp_update_payload_part1(mst_mgr, (link_coding_cap == DP_CAP_ANSI_128B132B) ? 0:1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
-- 
2.25.1


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

* [Intel-gfx] [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support
@ 2021-10-20 19:47   ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:47 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski,
	intel-gfx, Bhawanpreet Lakha

[Why]
Add DP2 MST and debugfs support

[How]
Update the slot info based on the link encoding format

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 29 +++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |  3 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  5 +++-
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e56f73e299ef..875425ee91d0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10741,6 +10741,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	struct dsc_mst_fairness_vars vars[MAX_PIPES];
 #endif
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_topology_mgr *mgr;
 
 	trace_amdgpu_dm_atomic_check_begin(state);
 
@@ -10948,6 +10950,33 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		lock_and_validation_needed = true;
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	/* set the slot info for each mst_state based on the link encoding format */
+	for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
+		struct amdgpu_dm_connector *aconnector;
+		struct drm_connector *connector;
+		struct drm_connector_list_iter iter;
+		u8 link_coding_cap;
+
+		if (!mgr->mst_state )
+			continue;
+
+		drm_connector_list_iter_begin(dev, &iter);
+		drm_for_each_connector_iter(connector, &iter) {
+			int id = connector->index;
+
+			if (id == mst_state->mgr->conn_base_id) {
+				aconnector = to_amdgpu_dm_connector(connector);
+				link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+				drm_dp_mst_update_slots(mst_state, link_coding_cap);
+
+				break;
+			}
+		}
+		drm_connector_list_iter_end(&iter);
+
+	}
+#endif
 	/**
 	 * Streams and planes are reset when there are changes that affect
 	 * bandwidth. Anything that affects bandwidth needs to go through
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 9b3ad56607bb..1a68a674913c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -294,6 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
 	case LINK_RATE_RBR2:
 	case LINK_RATE_HIGH2:
 	case LINK_RATE_HIGH3:
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	case LINK_RATE_UHBR10:
+#endif
 		break;
 	default:
 		valid_input = false;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 6169488e2011..53b5cc7b0679 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -219,6 +219,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	struct drm_dp_mst_topology_mgr *mst_mgr;
 	struct drm_dp_mst_port *mst_port;
 	bool ret;
+	u8 link_coding_cap;
 
 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
 	/* Accessing the connector state is required for vcpi_slots allocation
@@ -238,6 +239,8 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
 	mst_port = aconnector->port;
 
+	link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
+
 	if (enable) {
 
 		ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port,
@@ -251,7 +254,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr, 1);
+	drm_dp_update_payload_part1(mst_mgr, (link_coding_cap == DP_CAP_ANSI_128B132B) ? 0:1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
-- 
2.25.1


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

* [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format
  2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-20 19:53     ` Bhawanpreet Lakha
  -1 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:53 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: intel-gfx, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Mikita.Lipski, Bhawanpreet Lakha

8b/10b encoding format requires to reserve the first slot for
recording metadata. Real data transmission starts from the second slot,
with a total of available 63 slots available.

In 128b/132b encoding format, metadata is transmitted separately
in LLCP packet before MTP. Real data transmission starts from
the first slot, with a total of 64 slots available.

v2:
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

v3:
* Only keep the slot info on the mst_state
* add a start_slot parameter to the payload function, to facilitate non
  atomic drivers (this is a temporary workaround and should be removed when
  we are moving out the non atomic driver helpers)

v4:
*fixed typo and formatting

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c         | 36 ++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +--
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  2 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  4 +--
 include/drm/drm_dp_mst_helper.h               |  5 ++-
 6 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ff0f91c93ba4..6169488e2011 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr);
+	drm_dp_update_payload_part1(mst_mgr, 1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5ab3b3a46e89..857c5d15e81d 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,10 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 /**
  * drm_dp_update_payload_part1() - Execute payload update part 1
  * @mgr: manager to use.
+ * @start_slot: this is the cur slot
+ *
+ * NOTE: start_slot is a temporary workaround for non-atomic drivers,
+ * this will be removed when non-atomic mst helpers are moved out of the helper
  *
  * This iterates over all proposed virtual channels, and tries to
  * allocate space in the link for them. For 0->slots transitions,
@@ -3363,12 +3367,12 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
  * after calling this the driver should generate ACT and payload
  * packets.
  */
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot)
 {
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = start_slot;
 	bool skip;
 
 	mutex_lock(&mgr->payload_lock);
@@ -4503,6 +4507,27 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/**
+ * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format
+ * @mst_state: mst_state to update
+ * @link_encoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)
+{
+	if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
+		mst_state->total_avail_slots = 64;
+		mst_state->start_slot = 0;
+	} else {
+		mst_state->total_avail_slots = 63;
+		mst_state->start_slot = 1;
+	}
+
+	DRM_DEBUG_KMS("%s encoding format on mst_state 0x%p\n",
+			(link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
+			mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_slots);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -5222,7 +5247,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mst_state->total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5276,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 		}
 	}
 	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-		       mgr, mst_state, avail_slots, 63 - avail_slots);
+		       mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5528,6 +5553,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (mst_state == NULL)
 		return -ENOMEM;
 
+	mst_state->total_avail_slots = 63;
+	mst_state->start_slot = 1;
+
 	mst_state->mgr = mgr;
 	INIT_LIST_HEAD(&mst_state->vcpis);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..d3a24189a12c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -368,7 +368,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
 	}
@@ -516,7 +516,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 
 	intel_dp->active_mst_links++;
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 
 	/*
 	 * Before Gen 12 this is not done as part of
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index f949767698fc..6c8c59c26dbf 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1413,7 +1413,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
 	int ret;
 
 	NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
-	ret = drm_dp_update_payload_part1(&mstm->mgr);
+	ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
 
 	drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
 		if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index ec867fa880a4..751c2c075e09 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
 					 radeon_connector->port,
 					 mst_enc->pbn, slots);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		radeon_dp_mst_set_be_cntl(primary, mst_enc,
 					  radeon_connector->mst_port->hpd.hpd, true);
@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 			return;
 
 		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
 		/* and this can also fail */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..78044ac5b59b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
 	struct drm_private_state base;
 	struct list_head vcpis;
 	struct drm_dp_mst_topology_mgr *mgr;
+	u8 total_avail_slots;
+	u8 start_slot;
 };
 
 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -806,6 +808,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 			   int pbn);
 
 
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot);
 
 
 int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
-- 
2.25.1


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

* [Intel-gfx] [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format
@ 2021-10-20 19:53     ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 19:53 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: intel-gfx, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Mikita.Lipski, Bhawanpreet Lakha

8b/10b encoding format requires to reserve the first slot for
recording metadata. Real data transmission starts from the second slot,
with a total of available 63 slots available.

In 128b/132b encoding format, metadata is transmitted separately
in LLCP packet before MTP. Real data transmission starts from
the first slot, with a total of 64 slots available.

v2:
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

v3:
* Only keep the slot info on the mst_state
* add a start_slot parameter to the payload function, to facilitate non
  atomic drivers (this is a temporary workaround and should be removed when
  we are moving out the non atomic driver helpers)

v4:
*fixed typo and formatting

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c         | 36 ++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +--
 drivers/gpu/drm/nouveau/dispnv50/disp.c       |  2 +-
 drivers/gpu/drm/radeon/radeon_dp_mst.c        |  4 +--
 include/drm/drm_dp_mst_helper.h               |  5 ++-
 6 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ff0f91c93ba4..6169488e2011 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -251,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 	}
 
 	/* It's OK for this to fail */
-	drm_dp_update_payload_part1(mst_mgr);
+	drm_dp_update_payload_part1(mst_mgr, 1);
 
 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 5ab3b3a46e89..857c5d15e81d 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,10 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
 /**
  * drm_dp_update_payload_part1() - Execute payload update part 1
  * @mgr: manager to use.
+ * @start_slot: this is the cur slot
+ *
+ * NOTE: start_slot is a temporary workaround for non-atomic drivers,
+ * this will be removed when non-atomic mst helpers are moved out of the helper
  *
  * This iterates over all proposed virtual channels, and tries to
  * allocate space in the link for them. For 0->slots transitions,
@@ -3363,12 +3367,12 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
  * after calling this the driver should generate ACT and payload
  * packets.
  */
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot)
 {
 	struct drm_dp_payload req_payload;
 	struct drm_dp_mst_port *port;
 	int i, j;
-	int cur_slots = 1;
+	int cur_slots = start_slot;
 	bool skip;
 
 	mutex_lock(&mgr->payload_lock);
@@ -4503,6 +4507,27 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+/**
+ * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format
+ * @mst_state: mst_state to update
+ * @link_encoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)
+{
+	if (link_encoding_cap == DP_CAP_ANSI_128B132B) {
+		mst_state->total_avail_slots = 64;
+		mst_state->start_slot = 0;
+	} else {
+		mst_state->total_avail_slots = 63;
+		mst_state->start_slot = 1;
+	}
+
+	DRM_DEBUG_KMS("%s encoding format on mst_state 0x%p\n",
+			(link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",
+			mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_slots);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -5222,7 +5247,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 					 struct drm_dp_mst_topology_state *mst_state)
 {
 	struct drm_dp_vcpi_allocation *vcpi;
-	int avail_slots = 63, payload_count = 0;
+	int avail_slots = mst_state->total_avail_slots, payload_count = 0;
 
 	list_for_each_entry(vcpi, &mst_state->vcpis, next) {
 		/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5276,7 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
 		}
 	}
 	drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
-		       mgr, mst_state, avail_slots, 63 - avail_slots);
+		       mgr, mst_state, avail_slots, mst_state->total_avail_slots - avail_slots);
 
 	return 0;
 }
@@ -5528,6 +5553,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	if (mst_state == NULL)
 		return -ENOMEM;
 
+	mst_state->total_avail_slots = 63;
+	mst_state->start_slot = 1;
+
 	mst_state->mgr = mgr;
 	INIT_LIST_HEAD(&mst_state->vcpis);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..d3a24189a12c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -368,7 +368,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
 	}
@@ -516,7 +516,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 
 	intel_dp->active_mst_links++;
 
-	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
 
 	/*
 	 * Before Gen 12 this is not done as part of
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index f949767698fc..6c8c59c26dbf 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1413,7 +1413,7 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
 	int ret;
 
 	NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name);
-	ret = drm_dp_update_payload_part1(&mstm->mgr);
+	ret = drm_dp_update_payload_part1(&mstm->mgr, 1);
 
 	drm_for_each_encoder(encoder, mstm->outp->base.base.dev) {
 		if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index ec867fa880a4..751c2c075e09 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -423,7 +423,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
 					 radeon_connector->port,
 					 mst_enc->pbn, slots);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		radeon_dp_mst_set_be_cntl(primary, mst_enc,
 					  radeon_connector->mst_port->hpd.hpd, true);
@@ -452,7 +452,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
 			return;
 
 		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
-		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
+		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);
 
 		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
 		/* and this can also fail */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..78044ac5b59b 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -554,6 +554,8 @@ struct drm_dp_mst_topology_state {
 	struct drm_private_state base;
 	struct list_head vcpis;
 	struct drm_dp_mst_topology_mgr *mgr;
+	u8 total_avail_slots;
+	u8 start_slot;
 };
 
 #define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
@@ -806,6 +808,7 @@ int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
 
 void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap);
 
 void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 				struct drm_dp_mst_port *port);
@@ -815,7 +818,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
 			   int pbn);
 
 
-int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr, int start_slot);
 
 
 int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr);
-- 
2.25.1


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

* Re: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-20 19:55     ` Alex Deucher
  -1 siblings, 0 replies; 26+ messages in thread
From: Alex Deucher @ 2021-10-20 19:55 UTC (permalink / raw)
  To: Bhawanpreet Lakha
  Cc: Jerry Zuo, Maling list - DRI developers, Lyude, Wentland, Harry,
	Wayne Lin, Kazlauskas, Nicholas, Lipski, Mikita,
	Intel Graphics Development

On Wed, Oct 20, 2021 at 3:50 PM Bhawanpreet Lakha
<Bhawanpreet.Lakha@amd.com> wrote:
>
> From: Fangzhi Zuo <Jerry.Zuo@amd.com>

Please include a patch description.

Alex

>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
>  5 files changed, 333 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 8be04be19124..935a50d6e933 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
>                 if (stream_update->dsc_config)
>                         su_flags->bits.dsc_changed = 1;
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               if (stream_update->mst_bw_update)
> +                       su_flags->bits.mst_bw = 1;
> +#endif
> +
>                 if (su_flags->raw != 0)
>                         overall_type = UPDATE_TYPE_FULL;
>
> @@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
>                         if (stream_update->dsc_config)
>                                 dp_update_dsc_config(pipe_ctx);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                       if (stream_update->mst_bw_update) {
> +                               if (stream_update->mst_bw_update->is_increase)
> +                                       dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                               else
> +                                       dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                       }
> +#endif
> +
>                         if (stream_update->pending_test_pattern) {
>                                 dc_link_dp_set_test_pattern(stream->link,
>                                         stream->test_pattern.type,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index e5d6cbd7ea78..b23972b6a27c 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
>  static void update_mst_stream_alloc_table(
>         struct dc_link *link,
>         struct stream_encoder *stream_enc,
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
> +#endif
>         const struct dp_mst_stream_allocation_table *proposed_table)
>  {
>         struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
> @@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
>                         work_table[i].slot_count =
>                                 proposed_table->stream_allocations[i].slot_count;
>                         work_table[i].stream_enc = stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                       work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
> +#endif
>                 }
>         }
>
> @@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>         struct dc_link *link = stream->link;
>         struct link_encoder *link_encoder = NULL;
>         struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +       struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>         struct dp_mst_stream_allocation_table proposed_table = {0};
>         struct fixed31_32 avg_time_slots_per_mtp;
>         struct fixed31_32 pbn;
> @@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                 &proposed_table,
>                 true)) {
>                 update_mst_stream_alloc_table(
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                                       link,
> +                                       pipe_ctx->stream_res.stream_enc,
> +                                       pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                       &proposed_table);
> +#else
>                                         link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>         }
>         else
>                 DC_LOG_WARNING("Failed to update"
> @@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                         link->mst_stream_alloc_table.stream_count);
>
>         for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +               "stream[%d].hpo_dp_stream_enc: %p      "
> +               "stream[%d].vcp_id: %d      "
> +               "stream[%d].slot_count: %d\n",
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>                 DC_LOG_MST("stream_enc[%d]: %p      "
>                 "stream[%d].vcp_id: %d      "
>                 "stream[%d].slot_count: %d\n",
> @@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>                 i,
>                 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>         }
>
>         ASSERT(proposed_table.stream_count > 0);
>
>         /* program DP source TX for payload */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                               hpo_dp_link_encoder,
> +                               &link->mst_stream_alloc_table);
> +               break;
> +       }
> +#else
>         link_encoder->funcs->update_mst_stream_allocation_table(
>                 link_encoder,
>                 &link->mst_stream_alloc_table);
> +#endif
>
>         /* send down message */
>         ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> @@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>         pbn = get_pbn_from_timing(pipe_ctx);
>         avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               stream_encoder->funcs->set_throttled_vcp_size(
> +                       stream_encoder,
> +                       avg_time_slots_per_mtp);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                               hpo_dp_link_encoder,
> +                               hpo_dp_stream_encoder->inst,
> +                               avg_time_slots_per_mtp);
> +               break;
> +       }
> +#else
>         stream_encoder->funcs->set_throttled_vcp_size(
>                 stream_encoder,
>                 avg_time_slots_per_mtp);
> +#endif
> +
> +       return DC_OK;
> +
> +}
> +
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
> +{
> +       struct dc_stream_state *stream = pipe_ctx->stream;
> +       struct dc_link *link = stream->link;
> +       struct fixed31_32 avg_time_slots_per_mtp;
> +       struct fixed31_32 pbn;
> +       struct fixed31_32 pbn_per_slot;
> +       struct link_encoder *link_encoder = link->link_enc;
> +       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +       struct dp_mst_stream_allocation_table proposed_table = {0};
> +       uint8_t i;
> +       enum act_return_status ret;
> +       DC_LOGGER_INIT(link->ctx->logger);
> +
> +       /* decrease throttled vcp size */
> +       pbn_per_slot = get_pbn_per_slot(stream);
> +       pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +       stream_encoder->funcs->set_throttled_vcp_size(
> +                               stream_encoder,
> +                               avg_time_slots_per_mtp);
> +
> +       /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +       dm_helpers_dp_mst_send_payload_allocation(
> +                       stream->ctx,
> +                       stream,
> +                       true);
> +
> +       /* notify immediate branch device table update */
> +       if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                       stream->ctx,
> +                       stream,
> +                       &proposed_table,
> +                       true)) {
> +               /* update mst stream allocation table software state */
> +               update_mst_stream_alloc_table(
> +                               link,
> +                               pipe_ctx->stream_res.stream_enc,
> +                               pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                               &proposed_table);
> +       } else {
> +               DC_LOG_WARNING("Failed to update"
> +                               "MST allocation table for"
> +                               "pipe idx:%d\n",
> +                               pipe_ctx->pipe_idx);
> +       }
> +
> +       DC_LOG_MST("%s  "
> +                       "stream_count: %d: \n ",
> +                       __func__,
> +                       link->mst_stream_alloc_table.stream_count);
> +
> +       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +                               "stream[%d].vcp_id: %d      "
> +                               "stream[%d].slot_count: %d\n",
> +                               i,
> +                               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +       }
> +
> +       ASSERT(proposed_table.stream_count > 0);
> +
> +       /* update mst stream allocation table hardware state */
> +       link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +
> +       /* poll for immediate branch device ACT handled */
> +       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                       stream->ctx,
> +                       stream);
>
>         return DC_OK;
> +}
> +
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
> +{
> +       struct dc_stream_state *stream = pipe_ctx->stream;
> +       struct dc_link *link = stream->link;
> +       struct fixed31_32 avg_time_slots_per_mtp;
> +       struct fixed31_32 pbn;
> +       struct fixed31_32 pbn_per_slot;
> +       struct link_encoder *link_encoder = link->link_enc;
> +       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +       struct dp_mst_stream_allocation_table proposed_table = {0};
> +       uint8_t i;
> +       enum act_return_status ret;
> +       DC_LOGGER_INIT(link->ctx->logger);
> +
> +       /* notify immediate branch device table update */
> +       if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                               stream->ctx,
> +                               stream,
> +                               &proposed_table,
> +                               true)) {
> +               /* update mst stream allocation table software state */
> +               update_mst_stream_alloc_table(
> +                               link,
> +                               pipe_ctx->stream_res.stream_enc,
> +                               pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                               &proposed_table);
> +       }
> +
> +       DC_LOG_MST("%s  "
> +                       "stream_count: %d: \n ",
> +                       __func__,
> +                       link->mst_stream_alloc_table.stream_count);
> +
> +       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +                               "stream[%d].vcp_id: %d      "
> +                               "stream[%d].slot_count: %d\n",
> +                               i,
> +                               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +       }
> +
> +       ASSERT(proposed_table.stream_count > 0);
> +
> +       /* update mst stream allocation table hardware state */
> +       link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +
> +       /* poll for immediate branch device ACT handled */
> +       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                       stream->ctx,
> +                       stream);
> +
> +       if (ret != ACT_LINK_LOST) {
> +               /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +               dm_helpers_dp_mst_send_payload_allocation(
> +                               stream->ctx,
> +                               stream,
> +                               true);
> +       }
> +
> +       /* increase throttled vcp size */
> +       pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +       pbn_per_slot = get_pbn_per_slot(stream);
> +       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +       stream_encoder->funcs->set_throttled_vcp_size(
> +                               stream_encoder,
> +                               avg_time_slots_per_mtp);
>
> +       return DC_OK;
>  }
> +#endif
>
>  static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>  {
> @@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>         struct dc_link *link = stream->link;
>         struct link_encoder *link_encoder = NULL;
>         struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +       struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>         struct dp_mst_stream_allocation_table proposed_table = {0};
>         struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
>         int i;
> @@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>          */
>
>         /* slot X.Y */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               stream_encoder->funcs->set_throttled_vcp_size(
> +                       stream_encoder,
> +                       avg_time_slots_per_mtp);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                               hpo_dp_link_encoder,
> +                               hpo_dp_stream_encoder->inst,
> +                               avg_time_slots_per_mtp);
> +               break;
> +       }
> +#else
>         stream_encoder->funcs->set_throttled_vcp_size(
>                 stream_encoder,
>                 avg_time_slots_per_mtp);
> +#endif
>
>         /* TODO: which component is responsible for remove payload table? */
>         if (mst_mode) {
> @@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                                 &proposed_table,
>                                 false)) {
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                       update_mst_stream_alloc_table(
> +                                               link,
> +                                               pipe_ctx->stream_res.stream_enc,
> +                                               pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                               &proposed_table);
> +#else
>                         update_mst_stream_alloc_table(
>                                 link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>                 }
>                 else {
>                                 DC_LOG_WARNING("Failed to update"
> @@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                         link->mst_stream_alloc_table.stream_count);
>
>         for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +               "stream[%d].hpo_dp_stream_enc: %p      "
> +               "stream[%d].vcp_id: %d      "
> +               "stream[%d].slot_count: %d\n",
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>                 DC_LOG_MST("stream_enc[%d]: %p      "
>                 "stream[%d].vcp_id: %d      "
>                 "stream[%d].slot_count: %d\n",
> @@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>                 i,
>                 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>         }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                               hpo_dp_link_encoder,
> +                               &link->mst_stream_alloc_table);
> +               break;
> +       }
> +#else
>         link_encoder->funcs->update_mst_stream_allocation_table(
>                 link_encoder,
>                 &link->mst_stream_alloc_table);
> +#endif
>
>         if (mst_mode) {
>                 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> 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 296b0defcd1c..bb96e4e9ccfc 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
> @@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
>  }
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
> +{
> +       struct dc_link_settings link_settings = {0};
> +
> +       if (!dc_is_dp_signal(link->connector_signal))
> +               return DP_UNKNOWN_ENCODING;
> +
> +       if (link->preferred_link_setting.lane_count !=
> +                       LANE_COUNT_UNKNOWN &&
> +                       link->preferred_link_setting.link_rate !=
> +                                       LINK_RATE_UNKNOWN) {
> +               link_settings = link->preferred_link_setting;
> +       } else {
> +               decide_mst_link_settings(link, &link_settings);
> +       }
> +
> +       return dp_get_link_encoding_format(&link_settings);
> +}
> +
>  // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
>  static void get_lane_status(
>         struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index a73d64b1fd33..08815310d85b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -295,6 +295,10 @@ enum dc_detect_reason {
>  bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
>  bool dc_link_get_hpd_state(struct dc_link *dc_link);
>  enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
> +#endif
>
>  /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
>   * Return:
> @@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
>  bool dc_link_is_fec_supported(const struct dc_link *link);
>  bool dc_link_should_enable_fec(const struct dc_link *link);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
> +#endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index b8ebc1f09538..e37c4a10bfd5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -115,6 +115,13 @@ struct periodic_interrupt_config {
>         int lines_offset;
>  };
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +struct dc_mst_stream_bw_update {
> +       bool is_increase; // is bandwidth reduced or increased
> +       uint32_t mst_stream_bw; // new mst bandwidth in kbps
> +};
> +#endif
> +
>  union stream_update_flags {
>         struct {
>                 uint32_t scaling:1;
> @@ -125,6 +132,9 @@ union stream_update_flags {
>                 uint32_t gamut_remap:1;
>                 uint32_t wb_update:1;
>                 uint32_t dsc_changed : 1;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               uint32_t mst_bw : 1;
> +#endif
>         } bits;
>
>         uint32_t raw;
> @@ -278,6 +288,9 @@ struct dc_stream_update {
>
>         struct dc_writeback_update *wb_update;
>         struct dc_dsc_config *dsc_config;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct dc_mst_stream_bw_update *mst_bw_update;
> +#endif
>         struct dc_transfer_func *func_shaper;
>         struct dc_3dlut *lut3d_func;
>
> --
> 2.25.1
>

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

* Re: [Intel-gfx] [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-20 19:55     ` Alex Deucher
  0 siblings, 0 replies; 26+ messages in thread
From: Alex Deucher @ 2021-10-20 19:55 UTC (permalink / raw)
  To: Bhawanpreet Lakha
  Cc: Jerry Zuo, Maling list - DRI developers, Lyude, Wentland, Harry,
	Wayne Lin, Kazlauskas, Nicholas, Lipski, Mikita,
	Intel Graphics Development

On Wed, Oct 20, 2021 at 3:50 PM Bhawanpreet Lakha
<Bhawanpreet.Lakha@amd.com> wrote:
>
> From: Fangzhi Zuo <Jerry.Zuo@amd.com>

Please include a patch description.

Alex

>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
>  5 files changed, 333 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 8be04be19124..935a50d6e933 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
>                 if (stream_update->dsc_config)
>                         su_flags->bits.dsc_changed = 1;
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               if (stream_update->mst_bw_update)
> +                       su_flags->bits.mst_bw = 1;
> +#endif
> +
>                 if (su_flags->raw != 0)
>                         overall_type = UPDATE_TYPE_FULL;
>
> @@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
>                         if (stream_update->dsc_config)
>                                 dp_update_dsc_config(pipe_ctx);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                       if (stream_update->mst_bw_update) {
> +                               if (stream_update->mst_bw_update->is_increase)
> +                                       dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                               else
> +                                       dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                       }
> +#endif
> +
>                         if (stream_update->pending_test_pattern) {
>                                 dc_link_dp_set_test_pattern(stream->link,
>                                         stream->test_pattern.type,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index e5d6cbd7ea78..b23972b6a27c 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
>  static void update_mst_stream_alloc_table(
>         struct dc_link *link,
>         struct stream_encoder *stream_enc,
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
> +#endif
>         const struct dp_mst_stream_allocation_table *proposed_table)
>  {
>         struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
> @@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
>                         work_table[i].slot_count =
>                                 proposed_table->stream_allocations[i].slot_count;
>                         work_table[i].stream_enc = stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                       work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
> +#endif
>                 }
>         }
>
> @@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>         struct dc_link *link = stream->link;
>         struct link_encoder *link_encoder = NULL;
>         struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +       struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>         struct dp_mst_stream_allocation_table proposed_table = {0};
>         struct fixed31_32 avg_time_slots_per_mtp;
>         struct fixed31_32 pbn;
> @@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                 &proposed_table,
>                 true)) {
>                 update_mst_stream_alloc_table(
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                                       link,
> +                                       pipe_ctx->stream_res.stream_enc,
> +                                       pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                       &proposed_table);
> +#else
>                                         link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>         }
>         else
>                 DC_LOG_WARNING("Failed to update"
> @@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                         link->mst_stream_alloc_table.stream_count);
>
>         for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +               "stream[%d].hpo_dp_stream_enc: %p      "
> +               "stream[%d].vcp_id: %d      "
> +               "stream[%d].slot_count: %d\n",
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>                 DC_LOG_MST("stream_enc[%d]: %p      "
>                 "stream[%d].vcp_id: %d      "
>                 "stream[%d].slot_count: %d\n",
> @@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>                 i,
>                 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>         }
>
>         ASSERT(proposed_table.stream_count > 0);
>
>         /* program DP source TX for payload */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                               hpo_dp_link_encoder,
> +                               &link->mst_stream_alloc_table);
> +               break;
> +       }
> +#else
>         link_encoder->funcs->update_mst_stream_allocation_table(
>                 link_encoder,
>                 &link->mst_stream_alloc_table);
> +#endif
>
>         /* send down message */
>         ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> @@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>         pbn = get_pbn_from_timing(pipe_ctx);
>         avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               stream_encoder->funcs->set_throttled_vcp_size(
> +                       stream_encoder,
> +                       avg_time_slots_per_mtp);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                               hpo_dp_link_encoder,
> +                               hpo_dp_stream_encoder->inst,
> +                               avg_time_slots_per_mtp);
> +               break;
> +       }
> +#else
>         stream_encoder->funcs->set_throttled_vcp_size(
>                 stream_encoder,
>                 avg_time_slots_per_mtp);
> +#endif
> +
> +       return DC_OK;
> +
> +}
> +
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
> +{
> +       struct dc_stream_state *stream = pipe_ctx->stream;
> +       struct dc_link *link = stream->link;
> +       struct fixed31_32 avg_time_slots_per_mtp;
> +       struct fixed31_32 pbn;
> +       struct fixed31_32 pbn_per_slot;
> +       struct link_encoder *link_encoder = link->link_enc;
> +       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +       struct dp_mst_stream_allocation_table proposed_table = {0};
> +       uint8_t i;
> +       enum act_return_status ret;
> +       DC_LOGGER_INIT(link->ctx->logger);
> +
> +       /* decrease throttled vcp size */
> +       pbn_per_slot = get_pbn_per_slot(stream);
> +       pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +       stream_encoder->funcs->set_throttled_vcp_size(
> +                               stream_encoder,
> +                               avg_time_slots_per_mtp);
> +
> +       /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +       dm_helpers_dp_mst_send_payload_allocation(
> +                       stream->ctx,
> +                       stream,
> +                       true);
> +
> +       /* notify immediate branch device table update */
> +       if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                       stream->ctx,
> +                       stream,
> +                       &proposed_table,
> +                       true)) {
> +               /* update mst stream allocation table software state */
> +               update_mst_stream_alloc_table(
> +                               link,
> +                               pipe_ctx->stream_res.stream_enc,
> +                               pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                               &proposed_table);
> +       } else {
> +               DC_LOG_WARNING("Failed to update"
> +                               "MST allocation table for"
> +                               "pipe idx:%d\n",
> +                               pipe_ctx->pipe_idx);
> +       }
> +
> +       DC_LOG_MST("%s  "
> +                       "stream_count: %d: \n ",
> +                       __func__,
> +                       link->mst_stream_alloc_table.stream_count);
> +
> +       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +                               "stream[%d].vcp_id: %d      "
> +                               "stream[%d].slot_count: %d\n",
> +                               i,
> +                               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +       }
> +
> +       ASSERT(proposed_table.stream_count > 0);
> +
> +       /* update mst stream allocation table hardware state */
> +       link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +
> +       /* poll for immediate branch device ACT handled */
> +       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                       stream->ctx,
> +                       stream);
>
>         return DC_OK;
> +}
> +
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
> +{
> +       struct dc_stream_state *stream = pipe_ctx->stream;
> +       struct dc_link *link = stream->link;
> +       struct fixed31_32 avg_time_slots_per_mtp;
> +       struct fixed31_32 pbn;
> +       struct fixed31_32 pbn_per_slot;
> +       struct link_encoder *link_encoder = link->link_enc;
> +       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +       struct dp_mst_stream_allocation_table proposed_table = {0};
> +       uint8_t i;
> +       enum act_return_status ret;
> +       DC_LOGGER_INIT(link->ctx->logger);
> +
> +       /* notify immediate branch device table update */
> +       if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                               stream->ctx,
> +                               stream,
> +                               &proposed_table,
> +                               true)) {
> +               /* update mst stream allocation table software state */
> +               update_mst_stream_alloc_table(
> +                               link,
> +                               pipe_ctx->stream_res.stream_enc,
> +                               pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                               &proposed_table);
> +       }
> +
> +       DC_LOG_MST("%s  "
> +                       "stream_count: %d: \n ",
> +                       __func__,
> +                       link->mst_stream_alloc_table.stream_count);
> +
> +       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +                               "stream[%d].vcp_id: %d      "
> +                               "stream[%d].slot_count: %d\n",
> +                               i,
> +                               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                               i,
> +                               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +       }
> +
> +       ASSERT(proposed_table.stream_count > 0);
> +
> +       /* update mst stream allocation table hardware state */
> +       link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +
> +       /* poll for immediate branch device ACT handled */
> +       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                       stream->ctx,
> +                       stream);
> +
> +       if (ret != ACT_LINK_LOST) {
> +               /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +               dm_helpers_dp_mst_send_payload_allocation(
> +                               stream->ctx,
> +                               stream,
> +                               true);
> +       }
> +
> +       /* increase throttled vcp size */
> +       pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +       pbn_per_slot = get_pbn_per_slot(stream);
> +       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +       stream_encoder->funcs->set_throttled_vcp_size(
> +                               stream_encoder,
> +                               avg_time_slots_per_mtp);
>
> +       return DC_OK;
>  }
> +#endif
>
>  static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>  {
> @@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>         struct dc_link *link = stream->link;
>         struct link_encoder *link_encoder = NULL;
>         struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +       struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>         struct dp_mst_stream_allocation_table proposed_table = {0};
>         struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
>         int i;
> @@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>          */
>
>         /* slot X.Y */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               stream_encoder->funcs->set_throttled_vcp_size(
> +                       stream_encoder,
> +                       avg_time_slots_per_mtp);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                               hpo_dp_link_encoder,
> +                               hpo_dp_stream_encoder->inst,
> +                               avg_time_slots_per_mtp);
> +               break;
> +       }
> +#else
>         stream_encoder->funcs->set_throttled_vcp_size(
>                 stream_encoder,
>                 avg_time_slots_per_mtp);
> +#endif
>
>         /* TODO: which component is responsible for remove payload table? */
>         if (mst_mode) {
> @@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                                 &proposed_table,
>                                 false)) {
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                       update_mst_stream_alloc_table(
> +                                               link,
> +                                               pipe_ctx->stream_res.stream_enc,
> +                                               pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                               &proposed_table);
> +#else
>                         update_mst_stream_alloc_table(
>                                 link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>                 }
>                 else {
>                                 DC_LOG_WARNING("Failed to update"
> @@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                         link->mst_stream_alloc_table.stream_count);
>
>         for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               DC_LOG_MST("stream_enc[%d]: %p      "
> +               "stream[%d].hpo_dp_stream_enc: %p      "
> +               "stream[%d].vcp_id: %d      "
> +               "stream[%d].slot_count: %d\n",
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +               i,
> +               (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +               i,
> +               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>                 DC_LOG_MST("stream_enc[%d]: %p      "
>                 "stream[%d].vcp_id: %d      "
>                 "stream[%d].slot_count: %d\n",
> @@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                 link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>                 i,
>                 link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>         }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +       case DP_8b_10b_ENCODING:
> +               link_encoder->funcs->update_mst_stream_allocation_table(
> +                       link_encoder,
> +                       &link->mst_stream_alloc_table);
> +               break;
> +       case DP_128b_132b_ENCODING:
> +               hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                               hpo_dp_link_encoder,
> +                               &link->mst_stream_alloc_table);
> +               break;
> +       }
> +#else
>         link_encoder->funcs->update_mst_stream_allocation_table(
>                 link_encoder,
>                 &link->mst_stream_alloc_table);
> +#endif
>
>         if (mst_mode) {
>                 dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> 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 296b0defcd1c..bb96e4e9ccfc 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
> @@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
>  }
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
> +{
> +       struct dc_link_settings link_settings = {0};
> +
> +       if (!dc_is_dp_signal(link->connector_signal))
> +               return DP_UNKNOWN_ENCODING;
> +
> +       if (link->preferred_link_setting.lane_count !=
> +                       LANE_COUNT_UNKNOWN &&
> +                       link->preferred_link_setting.link_rate !=
> +                                       LINK_RATE_UNKNOWN) {
> +               link_settings = link->preferred_link_setting;
> +       } else {
> +               decide_mst_link_settings(link, &link_settings);
> +       }
> +
> +       return dp_get_link_encoding_format(&link_settings);
> +}
> +
>  // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
>  static void get_lane_status(
>         struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index a73d64b1fd33..08815310d85b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -295,6 +295,10 @@ enum dc_detect_reason {
>  bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
>  bool dc_link_get_hpd_state(struct dc_link *dc_link);
>  enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
> +#endif
>
>  /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
>   * Return:
> @@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
>  bool dc_link_is_fec_supported(const struct dc_link *link);
>  bool dc_link_should_enable_fec(const struct dc_link *link);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
> +#endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index b8ebc1f09538..e37c4a10bfd5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -115,6 +115,13 @@ struct periodic_interrupt_config {
>         int lines_offset;
>  };
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +struct dc_mst_stream_bw_update {
> +       bool is_increase; // is bandwidth reduced or increased
> +       uint32_t mst_stream_bw; // new mst bandwidth in kbps
> +};
> +#endif
> +
>  union stream_update_flags {
>         struct {
>                 uint32_t scaling:1;
> @@ -125,6 +132,9 @@ union stream_update_flags {
>                 uint32_t gamut_remap:1;
>                 uint32_t wb_update:1;
>                 uint32_t dsc_changed : 1;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +               uint32_t mst_bw : 1;
> +#endif
>         } bits;
>
>         uint32_t raw;
> @@ -278,6 +288,9 @@ struct dc_stream_update {
>
>         struct dc_writeback_update *wb_update;
>         struct dc_dsc_config *dsc_config;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +       struct dc_mst_stream_bw_update *mst_bw_update;
> +#endif
>         struct dc_transfer_func *func_shaper;
>         struct dc_3dlut *lut3d_func;
>
> --
> 2.25.1
>

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

* [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-20 19:55     ` [Intel-gfx] " Alex Deucher
@ 2021-10-20 20:05       ` Bhawanpreet Lakha
  -1 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 20:05 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: intel-gfx, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Mikita.Lipski, Bhawanpreet Lakha

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

[Why]
configure/call DC interface for DP2 mst support. This is needed to make DP2
mst work.

[How]
- add encoding type, logging, mst update/reduce payload functions

Use the link encoding to determine the DP type (1.4 or 2.0) and add a
flag to dc_stream_update to determine whether to increase/reduce
payloads.

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..b23972b6a27c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
+
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
 
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [Intel-gfx] [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-20 20:05       ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 20:05 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: intel-gfx, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Mikita.Lipski, Bhawanpreet Lakha

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

[Why]
configure/call DC interface for DP2 mst support. This is needed to make DP2
mst work.

[How]
- add encoding type, logging, mst update/reduce payload functions

Use the link encoding to determine the DP type (1.4 or 2.0) and add a
flag to dc_stream_update to determine whether to increase/reduce
payloads.

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..b23972b6a27c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
+
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
 
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/4] drm: Remove slot checks in dp mst topology during commit (rev3)
  2021-10-20 19:47 ` [Intel-gfx] " Bhawanpreet Lakha
                   ` (3 preceding siblings ...)
  (?)
@ 2021-10-20 22:31 ` Patchwork
  -1 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2021-10-20 22:31 UTC (permalink / raw)
  To: Bhawanpreet Lakha; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/4] drm: Remove slot checks in dp mst topology during commit (rev3)
URL   : https://patchwork.freedesktop.org/series/96079/
State : failure

== Summary ==

Applying: drm: Remove slot checks in dp mst topology during commit
Applying: drm: Update MST First Link Slot Information Based on Encoding Format
Applying: drm/amd/display: Add DP 2.0 MST DC Support
error: sha1 information is lacking or useless (drivers/gpu/drm/amd/display/dc/core/dc.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0003 drm/amd/display: Add DP 2.0 MST DC Support
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".



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

* RE: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-21 10:21     ` Lin, Wayne
  -1 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-21 10:21 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel, lyude
  Cc: Wentland, Harry, Kazlauskas, Nicholas, Lipski, Mikita, intel-gfx

[Public]

> -----Original Message-----
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: Thursday, October 21, 2021 3:47 AM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org; lyude@redhat.com
> Cc: Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas, Nicholas
> <Nicholas.Kazlauskas@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; intel-gfx@lists.freedesktop.org
> Subject: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
>
> From: Fangzhi Zuo <Jerry.Zuo@amd.com>
>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
>  5 files changed, 333 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 8be04be19124..935a50d6e933 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
>               if (stream_update->dsc_config)
>                       su_flags->bits.dsc_changed = 1;
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             if (stream_update->mst_bw_update)
> +                     su_flags->bits.mst_bw = 1;
> +#endif
> +
>               if (su_flags->raw != 0)
>                       overall_type = UPDATE_TYPE_FULL;
>
> @@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
>                       if (stream_update->dsc_config)
>                               dp_update_dsc_config(pipe_ctx);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     if (stream_update->mst_bw_update) {
> +                             if (stream_update->mst_bw_update->is_increase)
> +                                     dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                             else
> +                                     dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                     }
> +#endif
> +
>                       if (stream_update->pending_test_pattern) {
>                               dc_link_dp_set_test_pattern(stream->link,
>                                       stream->test_pattern.type,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index e5d6cbd7ea78..b23972b6a27c 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)  static void
> update_mst_stream_alloc_table(
>       struct dc_link *link,
>       struct stream_encoder *stream_enc,
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
> +#endif
>       const struct dp_mst_stream_allocation_table *proposed_table)  {
>       struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 }; @@ -3267,6 +3270,9 @@ static void
> update_mst_stream_alloc_table(
>                       work_table[i].slot_count =
>                               proposed_table->stream_allocations[i].slot_count;
>                       work_table[i].stream_enc = stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc; #endif
>               }
>       }
>
> @@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp;
>       struct fixed31_32 pbn;
> @@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               &proposed_table,
>               true)) {
>               update_mst_stream_alloc_table(
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                                     link,
> +                                     pipe_ctx->stream_res.stream_enc,
> +                                     pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                     &proposed_table);
> +#else
>                                       link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>       }
>       else
>               DC_LOG_WARNING("Failed to update"
> @@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>               DC_LOG_MST("stream_enc[%d]: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
> @@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
>       ASSERT(proposed_table.stream_count > 0);
>
>       /* program DP source TX for payload */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;

Hi Bhawan,
dp_get_link_encoding_format() could also return DP_UNKNOWN_ENCODING case. Probably should also catch that case.
Thanks!

> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       /* send down message */
>       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> @@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       pbn = get_pbn_from_timing(pipe_ctx);
>       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
> +
> +     return DC_OK;
> +
> +}
> +
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* decrease throttled vcp size */
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
> +
> +     /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +     dm_helpers_dp_mst_send_payload_allocation(
> +                     stream->ctx,
> +                     stream,
> +                     true);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                     stream->ctx,
> +                     stream,
> +                     &proposed_table,
> +                     true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     } else {
> +             DC_LOG_WARNING("Failed to update"
> +                             "MST allocation table for"
> +                             "pipe idx:%d\n",
> +                             pipe_ctx->pipe_idx);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
>
>       return DC_OK;
> +}
> +
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                             stream->ctx,
> +                             stream,
> +                             &proposed_table,
> +                             true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
> +
> +     if (ret != ACT_LINK_LOST) {
> +             /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +             dm_helpers_dp_mst_send_payload_allocation(
> +                             stream->ctx,
> +                             stream,
> +                             true);
> +     }
> +
> +     /* increase throttled vcp size */
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
>
> +     return DC_OK;
>  }
> +#endif
>
>  static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)  { @@ -3483,6 +3705,10 @@ static enum dc_status
> deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
>       int i;
> @@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>        */
>
>       /* slot X.Y */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
>
>       /* TODO: which component is responsible for remove payload table? */
>       if (mst_mode) {
> @@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                               &proposed_table,
>                               false)) {
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     update_mst_stream_alloc_table(
> +                                             link,
> +                                             pipe_ctx->stream_res.stream_enc,
> +                                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                             &proposed_table);
> +#else
>                       update_mst_stream_alloc_table(
>                               link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>               }
>               else {
>                               DC_LOG_WARNING("Failed to update"
> @@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>               DC_LOG_MST("stream_enc[%d]: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
> @@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;
> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       if (mst_mode) {
>               dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> 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 296b0defcd1c..bb96e4e9ccfc 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
> @@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings  }
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link) {
> +     struct dc_link_settings link_settings = {0};
> +
> +     if (!dc_is_dp_signal(link->connector_signal))
> +             return DP_UNKNOWN_ENCODING;
> +
> +     if (link->preferred_link_setting.lane_count !=
> +                     LANE_COUNT_UNKNOWN &&
> +                     link->preferred_link_setting.link_rate !=
> +                                     LINK_RATE_UNKNOWN) {
> +             link_settings = link->preferred_link_setting;
> +     } else {
> +             decide_mst_link_settings(link, &link_settings);
> +     }
> +
> +     return dp_get_link_encoding_format(&link_settings);
> +}
> +
>  // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)  static void get_lane_status(
>       struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index a73d64b1fd33..08815310d85b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -295,6 +295,10 @@ enum dc_detect_reason {  bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);  bool
> dc_link_get_hpd_state(struct dc_link *dc_link);  enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t req_pbn); enum dc_status dc_link_increase_mst_payload(struct
> +pipe_ctx *pipe_ctx, uint32_t req_pbn); #endif
>
>  /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
>   * Return:
> @@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(  bool dc_link_is_fec_supported(const struct dc_link *link);  bool
> dc_link_should_enable_fec(const struct dc_link *link);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link); #endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index b8ebc1f09538..e37c4a10bfd5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -115,6 +115,13 @@ struct periodic_interrupt_config {
>       int lines_offset;
>  };
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +struct dc_mst_stream_bw_update {
> +     bool is_increase; // is bandwidth reduced or increased
> +     uint32_t mst_stream_bw; // new mst bandwidth in kbps }; #endif
> +
>  union stream_update_flags {
>       struct {
>               uint32_t scaling:1;
> @@ -125,6 +132,9 @@ union stream_update_flags {
>               uint32_t gamut_remap:1;
>               uint32_t wb_update:1;
>               uint32_t dsc_changed : 1;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             uint32_t mst_bw : 1;
> +#endif
>       } bits;
>
>       uint32_t raw;
> @@ -278,6 +288,9 @@ struct dc_stream_update {
>
>       struct dc_writeback_update *wb_update;
>       struct dc_dsc_config *dsc_config;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct dc_mst_stream_bw_update *mst_bw_update; #endif
>       struct dc_transfer_func *func_shaper;
>       struct dc_3dlut *lut3d_func;
>
> --
> 2.25.1
--
Regards,
Wayne Lin

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

* Re: [Intel-gfx] [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-21 10:21     ` Lin, Wayne
  0 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-21 10:21 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel, lyude
  Cc: Wentland, Harry, Kazlauskas, Nicholas, Lipski, Mikita, intel-gfx

[Public]

> -----Original Message-----
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: Thursday, October 21, 2021 3:47 AM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org; lyude@redhat.com
> Cc: Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas, Nicholas
> <Nicholas.Kazlauskas@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; intel-gfx@lists.freedesktop.org
> Subject: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
>
> From: Fangzhi Zuo <Jerry.Zuo@amd.com>
>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
>  5 files changed, 333 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 8be04be19124..935a50d6e933 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
>               if (stream_update->dsc_config)
>                       su_flags->bits.dsc_changed = 1;
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             if (stream_update->mst_bw_update)
> +                     su_flags->bits.mst_bw = 1;
> +#endif
> +
>               if (su_flags->raw != 0)
>                       overall_type = UPDATE_TYPE_FULL;
>
> @@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
>                       if (stream_update->dsc_config)
>                               dp_update_dsc_config(pipe_ctx);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     if (stream_update->mst_bw_update) {
> +                             if (stream_update->mst_bw_update->is_increase)
> +                                     dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                             else
> +                                     dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                     }
> +#endif
> +
>                       if (stream_update->pending_test_pattern) {
>                               dc_link_dp_set_test_pattern(stream->link,
>                                       stream->test_pattern.type,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index e5d6cbd7ea78..b23972b6a27c 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)  static void
> update_mst_stream_alloc_table(
>       struct dc_link *link,
>       struct stream_encoder *stream_enc,
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
> +#endif
>       const struct dp_mst_stream_allocation_table *proposed_table)  {
>       struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 }; @@ -3267,6 +3270,9 @@ static void
> update_mst_stream_alloc_table(
>                       work_table[i].slot_count =
>                               proposed_table->stream_allocations[i].slot_count;
>                       work_table[i].stream_enc = stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc; #endif
>               }
>       }
>
> @@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp;
>       struct fixed31_32 pbn;
> @@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               &proposed_table,
>               true)) {
>               update_mst_stream_alloc_table(
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                                     link,
> +                                     pipe_ctx->stream_res.stream_enc,
> +                                     pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                     &proposed_table);
> +#else
>                                       link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>       }
>       else
>               DC_LOG_WARNING("Failed to update"
> @@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>               DC_LOG_MST("stream_enc[%d]: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
> @@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
>       ASSERT(proposed_table.stream_count > 0);
>
>       /* program DP source TX for payload */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;

Hi Bhawan,
dp_get_link_encoding_format() could also return DP_UNKNOWN_ENCODING case. Probably should also catch that case.
Thanks!

> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       /* send down message */
>       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> @@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       pbn = get_pbn_from_timing(pipe_ctx);
>       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
> +
> +     return DC_OK;
> +
> +}
> +
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* decrease throttled vcp size */
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
> +
> +     /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +     dm_helpers_dp_mst_send_payload_allocation(
> +                     stream->ctx,
> +                     stream,
> +                     true);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                     stream->ctx,
> +                     stream,
> +                     &proposed_table,
> +                     true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     } else {
> +             DC_LOG_WARNING("Failed to update"
> +                             "MST allocation table for"
> +                             "pipe idx:%d\n",
> +                             pipe_ctx->pipe_idx);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
>
>       return DC_OK;
> +}
> +
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                             stream->ctx,
> +                             stream,
> +                             &proposed_table,
> +                             true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
> +
> +     if (ret != ACT_LINK_LOST) {
> +             /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +             dm_helpers_dp_mst_send_payload_allocation(
> +                             stream->ctx,
> +                             stream,
> +                             true);
> +     }
> +
> +     /* increase throttled vcp size */
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
>
> +     return DC_OK;
>  }
> +#endif
>
>  static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)  { @@ -3483,6 +3705,10 @@ static enum dc_status
> deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
>       int i;
> @@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>        */
>
>       /* slot X.Y */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
>
>       /* TODO: which component is responsible for remove payload table? */
>       if (mst_mode) {
> @@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                               &proposed_table,
>                               false)) {
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     update_mst_stream_alloc_table(
> +                                             link,
> +                                             pipe_ctx->stream_res.stream_enc,
> +                                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                             &proposed_table);
> +#else
>                       update_mst_stream_alloc_table(
>                               link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>               }
>               else {
>                               DC_LOG_WARNING("Failed to update"
> @@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>               DC_LOG_MST("stream_enc[%d]: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
> @@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;
> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       if (mst_mode) {
>               dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> 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 296b0defcd1c..bb96e4e9ccfc 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
> @@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings  }
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link) {
> +     struct dc_link_settings link_settings = {0};
> +
> +     if (!dc_is_dp_signal(link->connector_signal))
> +             return DP_UNKNOWN_ENCODING;
> +
> +     if (link->preferred_link_setting.lane_count !=
> +                     LANE_COUNT_UNKNOWN &&
> +                     link->preferred_link_setting.link_rate !=
> +                                     LINK_RATE_UNKNOWN) {
> +             link_settings = link->preferred_link_setting;
> +     } else {
> +             decide_mst_link_settings(link, &link_settings);
> +     }
> +
> +     return dp_get_link_encoding_format(&link_settings);
> +}
> +
>  // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)  static void get_lane_status(
>       struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index a73d64b1fd33..08815310d85b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -295,6 +295,10 @@ enum dc_detect_reason {  bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);  bool
> dc_link_get_hpd_state(struct dc_link *dc_link);  enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t req_pbn); enum dc_status dc_link_increase_mst_payload(struct
> +pipe_ctx *pipe_ctx, uint32_t req_pbn); #endif
>
>  /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
>   * Return:
> @@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(  bool dc_link_is_fec_supported(const struct dc_link *link);  bool
> dc_link_should_enable_fec(const struct dc_link *link);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link); #endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index b8ebc1f09538..e37c4a10bfd5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -115,6 +115,13 @@ struct periodic_interrupt_config {
>       int lines_offset;
>  };
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +struct dc_mst_stream_bw_update {
> +     bool is_increase; // is bandwidth reduced or increased
> +     uint32_t mst_stream_bw; // new mst bandwidth in kbps }; #endif
> +
>  union stream_update_flags {
>       struct {
>               uint32_t scaling:1;
> @@ -125,6 +132,9 @@ union stream_update_flags {
>               uint32_t gamut_remap:1;
>               uint32_t wb_update:1;
>               uint32_t dsc_changed : 1;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             uint32_t mst_bw : 1;
> +#endif
>       } bits;
>
>       uint32_t raw;
> @@ -278,6 +288,9 @@ struct dc_stream_update {
>
>       struct dc_writeback_update *wb_update;
>       struct dc_dsc_config *dsc_config;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct dc_mst_stream_bw_update *mst_bw_update; #endif
>       struct dc_transfer_func *func_shaper;
>       struct dc_3dlut *lut3d_func;
>
> --
> 2.25.1
--
Regards,
Wayne Lin

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

* [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-21 10:21     ` [Intel-gfx] " Lin, Wayne
@ 2021-10-21 15:15       ` Bhawanpreet Lakha
  -1 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-21 15:15 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: intel-gfx, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Mikita.Lipski, Bhawanpreet Lakha

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

[Why]
configure/call DC interface for DP2 mst support. This is needed to make DP2
mst work.

[How]
- add encoding type, logging, mst update/reduce payload functions

Use the link encoding to determine the DP type (1.4 or 2.0) and add a
flag to dc_stream_update to determine whether to increase/reduce
payloads.

v2:
* add DP_UNKNOWN_ENCODING handling

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 292 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 345 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..ec5f107bc85a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,23 +3447,56 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
 		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
 		i,
 		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
 		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3519,191 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
 
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3711,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3736,28 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3767,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3792,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3815,30 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [Intel-gfx] [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-21 15:15       ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-21 15:15 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: intel-gfx, Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas,
	Mikita.Lipski, Bhawanpreet Lakha

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

[Why]
configure/call DC interface for DP2 mst support. This is needed to make DP2
mst work.

[How]
- add encoding type, logging, mst update/reduce payload functions

Use the link encoding to determine the DP type (1.4 or 2.0) and add a
flag to dc_stream_update to determine whether to increase/reduce
payloads.

v2:
* add DP_UNKNOWN_ENCODING handling

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 292 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 345 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..ec5f107bc85a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,23 +3447,56 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
 		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
 		i,
 		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
 		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3519,191 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
 
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3711,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3736,28 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3767,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3792,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3815,30 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	case DP_UNKNOWN_ENCODING:
+		DC_LOG_ERROR("Failure: unknown encoding format\n");
+		return DC_ERROR_UNEXPECTED;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/4] drm: Remove slot checks in dp mst topology during commit (rev4)
  2021-10-20 19:47 ` [Intel-gfx] " Bhawanpreet Lakha
                   ` (4 preceding siblings ...)
  (?)
@ 2021-10-21 16:29 ` Patchwork
  -1 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2021-10-21 16:29 UTC (permalink / raw)
  To: Bhawanpreet Lakha; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/4] drm: Remove slot checks in dp mst topology during commit (rev4)
URL   : https://patchwork.freedesktop.org/series/96079/
State : failure

== Summary ==

Applying: drm: Remove slot checks in dp mst topology during commit
Applying: drm: Update MST First Link Slot Information Based on Encoding Format
Applying: drm/amd/display: Add DP 2.0 MST DC Support
error: sha1 information is lacking or useless (drivers/gpu/drm/amd/display/dc/core/dc.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0003 drm/amd/display: Add DP 2.0 MST DC Support
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".



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

* RE: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-21 15:15       ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-22  8:46         ` Lin, Wayne
  -1 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-22  8:46 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel, lyude
  Cc: intel-gfx, Wentland, Harry, Kazlauskas, Nicholas, Lipski, Mikita,
	Lakha, Bhawanpreet

[Public]

Hi Bhawan,
It looks good to me. Thanks!
Reviewed-by: Wayne Lin <Wayne.Lin@amd.com>

Regards,
Wayne
> -----Original Message-----
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: Thursday, October 21, 2021 11:16 PM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org; lyude@redhat.com
> Cc: intel-gfx@lists.freedesktop.org; Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas,
> Nicholas <Nicholas.Kazlauskas@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; Lakha, Bhawanpreet
> <Bhawanpreet.Lakha@amd.com>
> Subject: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
>
> From: Fangzhi Zuo <Jerry.Zuo@amd.com>
>
> [Why]
> configure/call DC interface for DP2 mst support. This is needed to make DP2 mst work.
>
> [How]
> - add encoding type, logging, mst update/reduce payload functions
>
> Use the link encoding to determine the DP type (1.4 or 2.0) and add a flag to dc_stream_update to determine whether to increase/reduce
> payloads.
>
> v2:
> * add DP_UNKNOWN_ENCODING handling
>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 292 ++++++++++++++++++  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
>  5 files changed, 345 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 8be04be19124..935a50d6e933 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
>               if (stream_update->dsc_config)
>                       su_flags->bits.dsc_changed = 1;
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             if (stream_update->mst_bw_update)
> +                     su_flags->bits.mst_bw = 1;
> +#endif
> +
>               if (su_flags->raw != 0)
>                       overall_type = UPDATE_TYPE_FULL;
>
> @@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
>                       if (stream_update->dsc_config)
>                               dp_update_dsc_config(pipe_ctx);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     if (stream_update->mst_bw_update) {
> +                             if (stream_update->mst_bw_update->is_increase)
> +                                     dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                             else
> +                                     dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                     }
> +#endif
> +
>                       if (stream_update->pending_test_pattern) {
>                               dc_link_dp_set_test_pattern(stream->link,
>                                       stream->test_pattern.type,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index e5d6cbd7ea78..ec5f107bc85a 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)  static void
> update_mst_stream_alloc_table(
>       struct dc_link *link,
>       struct stream_encoder *stream_enc,
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
> +#endif
>       const struct dp_mst_stream_allocation_table *proposed_table)  {
>       struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 }; @@ -3267,6 +3270,9 @@ static void
> update_mst_stream_alloc_table(
>                       work_table[i].slot_count =
>                               proposed_table->stream_allocations[i].slot_count;
>                       work_table[i].stream_enc = stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc; #endif
>               }
>       }
>
> @@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp;
>       struct fixed31_32 pbn;
> @@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               &proposed_table,
>               true)) {
>               update_mst_stream_alloc_table(
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                                     link,
> +                                     pipe_ctx->stream_res.stream_enc,
> +                                     pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                     &proposed_table);
> +#else
>                                       link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>       }
>       else
>               DC_LOG_WARNING("Failed to update"
> @@ -3430,23 +3447,56 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
>               DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
>               i,
>               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
>               i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
>       ASSERT(proposed_table.stream_count > 0);
>
>       /* program DP source TX for payload */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       /* send down message */
>       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> @@ -3469,13 +3519,191 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       pbn = get_pbn_from_timing(pipe_ctx);
>       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
> +
> +     return DC_OK;
> +
> +}
> +
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* decrease throttled vcp size */
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
> +
> +     /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +     dm_helpers_dp_mst_send_payload_allocation(
> +                     stream->ctx,
> +                     stream,
> +                     true);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                     stream->ctx,
> +                     stream,
> +                     &proposed_table,
> +                     true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     } else {
> +             DC_LOG_WARNING("Failed to update"
> +                             "MST allocation table for"
> +                             "pipe idx:%d\n",
> +                             pipe_ctx->pipe_idx);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
>
>       return DC_OK;
> +}
> +
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                             stream->ctx,
> +                             stream,
> +                             &proposed_table,
> +                             true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
> +
> +     if (ret != ACT_LINK_LOST) {
> +             /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +             dm_helpers_dp_mst_send_payload_allocation(
> +                             stream->ctx,
> +                             stream,
> +                             true);
> +     }
>
> +     /* increase throttled vcp size */
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
> +
> +     return DC_OK;
>  }
> +#endif
>
>  static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)  { @@ -3483,6 +3711,10 @@ static enum dc_status
> deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
>       int i;
> @@ -3504,9 +3736,28 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>        */
>
>       /* slot X.Y */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
>
>       /* TODO: which component is responsible for remove payload table? */
>       if (mst_mode) {
> @@ -3516,8 +3767,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                               &proposed_table,
>                               false)) {
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     update_mst_stream_alloc_table(
> +                                             link,
> +                                             pipe_ctx->stream_res.stream_enc,
> +                                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                             &proposed_table);
> +#else
>                       update_mst_stream_alloc_table(
>                               link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>               }
>               else {
>                               DC_LOG_WARNING("Failed to update"
> @@ -3533,6 +3792,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>               DC_LOG_MST("stream_enc[%d]: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
> @@ -3542,11 +3815,30 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       if (mst_mode) {
>               dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> 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 296b0defcd1c..bb96e4e9ccfc 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
> @@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings  }
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link) {
> +     struct dc_link_settings link_settings = {0};
> +
> +     if (!dc_is_dp_signal(link->connector_signal))
> +             return DP_UNKNOWN_ENCODING;
> +
> +     if (link->preferred_link_setting.lane_count !=
> +                     LANE_COUNT_UNKNOWN &&
> +                     link->preferred_link_setting.link_rate !=
> +                                     LINK_RATE_UNKNOWN) {
> +             link_settings = link->preferred_link_setting;
> +     } else {
> +             decide_mst_link_settings(link, &link_settings);
> +     }
> +
> +     return dp_get_link_encoding_format(&link_settings);
> +}
> +
>  // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)  static void get_lane_status(
>       struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index a73d64b1fd33..08815310d85b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -295,6 +295,10 @@ enum dc_detect_reason {  bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);  bool
> dc_link_get_hpd_state(struct dc_link *dc_link);  enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t req_pbn); enum dc_status dc_link_increase_mst_payload(struct
> +pipe_ctx *pipe_ctx, uint32_t req_pbn); #endif
>
>  /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
>   * Return:
> @@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(  bool dc_link_is_fec_supported(const struct dc_link *link);  bool
> dc_link_should_enable_fec(const struct dc_link *link);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link); #endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index b8ebc1f09538..e37c4a10bfd5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -115,6 +115,13 @@ struct periodic_interrupt_config {
>       int lines_offset;
>  };
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +struct dc_mst_stream_bw_update {
> +     bool is_increase; // is bandwidth reduced or increased
> +     uint32_t mst_stream_bw; // new mst bandwidth in kbps }; #endif
> +
>  union stream_update_flags {
>       struct {
>               uint32_t scaling:1;
> @@ -125,6 +132,9 @@ union stream_update_flags {
>               uint32_t gamut_remap:1;
>               uint32_t wb_update:1;
>               uint32_t dsc_changed : 1;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             uint32_t mst_bw : 1;
> +#endif
>       } bits;
>
>       uint32_t raw;
> @@ -278,6 +288,9 @@ struct dc_stream_update {
>
>       struct dc_writeback_update *wb_update;
>       struct dc_dsc_config *dsc_config;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct dc_mst_stream_bw_update *mst_bw_update; #endif
>       struct dc_transfer_func *func_shaper;
>       struct dc_3dlut *lut3d_func;
>
> --
> 2.25.1


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

* Re: [Intel-gfx] [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-22  8:46         ` Lin, Wayne
  0 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-22  8:46 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel, lyude
  Cc: intel-gfx, Wentland, Harry, Kazlauskas, Nicholas, Lipski, Mikita,
	Lakha, Bhawanpreet

[Public]

Hi Bhawan,
It looks good to me. Thanks!
Reviewed-by: Wayne Lin <Wayne.Lin@amd.com>

Regards,
Wayne
> -----Original Message-----
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: Thursday, October 21, 2021 11:16 PM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org; lyude@redhat.com
> Cc: intel-gfx@lists.freedesktop.org; Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas,
> Nicholas <Nicholas.Kazlauskas@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; Lakha, Bhawanpreet
> <Bhawanpreet.Lakha@amd.com>
> Subject: [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
>
> From: Fangzhi Zuo <Jerry.Zuo@amd.com>
>
> [Why]
> configure/call DC interface for DP2 mst support. This is needed to make DP2 mst work.
>
> [How]
> - add encoding type, logging, mst update/reduce payload functions
>
> Use the link encoding to determine the DP type (1.4 or 2.0) and add a flag to dc_stream_update to determine whether to increase/reduce
> payloads.
>
> v2:
> * add DP_UNKNOWN_ENCODING handling
>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 292 ++++++++++++++++++  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
>  5 files changed, 345 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 8be04be19124..935a50d6e933 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
>               if (stream_update->dsc_config)
>                       su_flags->bits.dsc_changed = 1;
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             if (stream_update->mst_bw_update)
> +                     su_flags->bits.mst_bw = 1;
> +#endif
> +
>               if (su_flags->raw != 0)
>                       overall_type = UPDATE_TYPE_FULL;
>
> @@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
>                       if (stream_update->dsc_config)
>                               dp_update_dsc_config(pipe_ctx);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     if (stream_update->mst_bw_update) {
> +                             if (stream_update->mst_bw_update->is_increase)
> +                                     dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                             else
> +                                     dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
> +                     }
> +#endif
> +
>                       if (stream_update->pending_test_pattern) {
>                               dc_link_dp_set_test_pattern(stream->link,
>                                       stream->test_pattern.type,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index e5d6cbd7ea78..ec5f107bc85a 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)  static void
> update_mst_stream_alloc_table(
>       struct dc_link *link,
>       struct stream_encoder *stream_enc,
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
> +#endif
>       const struct dp_mst_stream_allocation_table *proposed_table)  {
>       struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 }; @@ -3267,6 +3270,9 @@ static void
> update_mst_stream_alloc_table(
>                       work_table[i].slot_count =
>                               proposed_table->stream_allocations[i].slot_count;
>                       work_table[i].stream_enc = stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc; #endif
>               }
>       }
>
> @@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp;
>       struct fixed31_32 pbn;
> @@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               &proposed_table,
>               true)) {
>               update_mst_stream_alloc_table(
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                                     link,
> +                                     pipe_ctx->stream_res.stream_enc,
> +                                     pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                     &proposed_table);
> +#else
>                                       link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>       }
>       else
>               DC_LOG_WARNING("Failed to update"
> @@ -3430,23 +3447,56 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
>               DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
>               i,
>               (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
>               i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
>       ASSERT(proposed_table.stream_count > 0);
>
>       /* program DP source TX for payload */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       /* send down message */
>       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> @@ -3469,13 +3519,191 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       pbn = get_pbn_from_timing(pipe_ctx);
>       avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
> +
> +     return DC_OK;
> +
> +}
> +
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* decrease throttled vcp size */
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
> +
> +     /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +     dm_helpers_dp_mst_send_payload_allocation(
> +                     stream->ctx,
> +                     stream,
> +                     true);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                     stream->ctx,
> +                     stream,
> +                     &proposed_table,
> +                     true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     } else {
> +             DC_LOG_WARNING("Failed to update"
> +                             "MST allocation table for"
> +                             "pipe idx:%d\n",
> +                             pipe_ctx->pipe_idx);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
>
>       return DC_OK;
> +}
> +
> +enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t bw_in_kbps) {
> +     struct dc_stream_state *stream = pipe_ctx->stream;
> +     struct dc_link *link = stream->link;
> +     struct fixed31_32 avg_time_slots_per_mtp;
> +     struct fixed31_32 pbn;
> +     struct fixed31_32 pbn_per_slot;
> +     struct link_encoder *link_encoder = link->link_enc;
> +     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +     struct dp_mst_stream_allocation_table proposed_table = {0};
> +     uint8_t i;
> +     enum act_return_status ret;
> +     DC_LOGGER_INIT(link->ctx->logger);
> +
> +     /* notify immediate branch device table update */
> +     if (dm_helpers_dp_mst_write_payload_allocation_table(
> +                             stream->ctx,
> +                             stream,
> +                             &proposed_table,
> +                             true)) {
> +             /* update mst stream allocation table software state */
> +             update_mst_stream_alloc_table(
> +                             link,
> +                             pipe_ctx->stream_res.stream_enc,
> +                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                             &proposed_table);
> +     }
> +
> +     DC_LOG_MST("%s  "
> +                     "stream_count: %d: \n ",
> +                     __func__,
> +                     link->mst_stream_alloc_table.stream_count);
> +
> +     for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +                             "stream[%d].vcp_id: %d      "
> +                             "stream[%d].slot_count: %d\n",
> +                             i,
> +                             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +                             i,
> +                             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +     }
> +
> +     ASSERT(proposed_table.stream_count > 0);
> +
> +     /* update mst stream allocation table hardware state */
> +     link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +
> +     /* poll for immediate branch device ACT handled */
> +     ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> +                     stream->ctx,
> +                     stream);
> +
> +     if (ret != ACT_LINK_LOST) {
> +             /* send ALLOCATE_PAYLOAD sideband message with updated pbn */
> +             dm_helpers_dp_mst_send_payload_allocation(
> +                             stream->ctx,
> +                             stream,
> +                             true);
> +     }
>
> +     /* increase throttled vcp size */
> +     pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
> +     pbn_per_slot = get_pbn_per_slot(stream);
> +     avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
> +
> +     stream_encoder->funcs->set_throttled_vcp_size(
> +                             stream_encoder,
> +                             avg_time_slots_per_mtp);
> +
> +     return DC_OK;
>  }
> +#endif
>
>  static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)  { @@ -3483,6 +3711,10 @@ static enum dc_status
> deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>       struct dc_link *link = stream->link;
>       struct link_encoder *link_encoder = NULL;
>       struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
> +     struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
> +pipe_ctx->stream_res.hpo_dp_stream_enc;
> +#endif
>       struct dp_mst_stream_allocation_table proposed_table = {0};
>       struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
>       int i;
> @@ -3504,9 +3736,28 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>        */
>
>       /* slot X.Y */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             stream_encoder->funcs->set_throttled_vcp_size(
> +                     stream_encoder,
> +                     avg_time_slots_per_mtp);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
> +                             hpo_dp_link_encoder,
> +                             hpo_dp_stream_encoder->inst,
> +                             avg_time_slots_per_mtp);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       stream_encoder->funcs->set_throttled_vcp_size(
>               stream_encoder,
>               avg_time_slots_per_mtp);
> +#endif
>
>       /* TODO: which component is responsible for remove payload table? */
>       if (mst_mode) {
> @@ -3516,8 +3767,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                               &proposed_table,
>                               false)) {
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +                     update_mst_stream_alloc_table(
> +                                             link,
> +                                             pipe_ctx->stream_res.stream_enc,
> +                                             pipe_ctx->stream_res.hpo_dp_stream_enc,
> +                                             &proposed_table);
> +#else
>                       update_mst_stream_alloc_table(
>                               link, pipe_ctx->stream_res.stream_enc, &proposed_table);
> +#endif
>               }
>               else {
>                               DC_LOG_WARNING("Failed to update"
> @@ -3533,6 +3792,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>                       link->mst_stream_alloc_table.stream_count);
>
>       for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             DC_LOG_MST("stream_enc[%d]: %p      "
> +             "stream[%d].hpo_dp_stream_enc: %p      "
> +             "stream[%d].vcp_id: %d      "
> +             "stream[%d].slot_count: %d\n",
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
> +             i,
> +             (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
> +             i,
> +             link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#else
>               DC_LOG_MST("stream_enc[%d]: %p      "
>               "stream[%d].vcp_id: %d      "
>               "stream[%d].slot_count: %d\n",
> @@ -3542,11 +3815,30 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
>               link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
>               i,
>               link->mst_stream_alloc_table.stream_allocations[i].slot_count);
> +#endif
>       }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
> +     case DP_8b_10b_ENCODING:
> +             link_encoder->funcs->update_mst_stream_allocation_table(
> +                     link_encoder,
> +                     &link->mst_stream_alloc_table);
> +             break;
> +     case DP_128b_132b_ENCODING:
> +             hpo_dp_link_encoder->funcs->update_stream_allocation_table(
> +                             hpo_dp_link_encoder,
> +                             &link->mst_stream_alloc_table);
> +             break;
> +     case DP_UNKNOWN_ENCODING:
> +             DC_LOG_ERROR("Failure: unknown encoding format\n");
> +             return DC_ERROR_UNEXPECTED;
> +     }
> +#else
>       link_encoder->funcs->update_mst_stream_allocation_table(
>               link_encoder,
>               &link->mst_stream_alloc_table);
> +#endif
>
>       if (mst_mode) {
>               dm_helpers_dp_mst_poll_for_allocation_change_trigger(
> 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 296b0defcd1c..bb96e4e9ccfc 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
> @@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings  }
>
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link) {
> +     struct dc_link_settings link_settings = {0};
> +
> +     if (!dc_is_dp_signal(link->connector_signal))
> +             return DP_UNKNOWN_ENCODING;
> +
> +     if (link->preferred_link_setting.lane_count !=
> +                     LANE_COUNT_UNKNOWN &&
> +                     link->preferred_link_setting.link_rate !=
> +                                     LINK_RATE_UNKNOWN) {
> +             link_settings = link->preferred_link_setting;
> +     } else {
> +             decide_mst_link_settings(link, &link_settings);
> +     }
> +
> +     return dp_get_link_encoding_format(&link_settings);
> +}
> +
>  // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)  static void get_lane_status(
>       struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index a73d64b1fd33..08815310d85b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -295,6 +295,10 @@ enum dc_detect_reason {  bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);  bool
> dc_link_get_hpd_state(struct dc_link *dc_link);  enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx,
> +uint32_t req_pbn); enum dc_status dc_link_increase_mst_payload(struct
> +pipe_ctx *pipe_ctx, uint32_t req_pbn); #endif
>
>  /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
>   * Return:
> @@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(  bool dc_link_is_fec_supported(const struct dc_link *link);  bool
> dc_link_should_enable_fec(const struct dc_link *link);
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const
> +struct dc_link *link); #endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index b8ebc1f09538..e37c4a10bfd5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -115,6 +115,13 @@ struct periodic_interrupt_config {
>       int lines_offset;
>  };
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +struct dc_mst_stream_bw_update {
> +     bool is_increase; // is bandwidth reduced or increased
> +     uint32_t mst_stream_bw; // new mst bandwidth in kbps }; #endif
> +
>  union stream_update_flags {
>       struct {
>               uint32_t scaling:1;
> @@ -125,6 +132,9 @@ union stream_update_flags {
>               uint32_t gamut_remap:1;
>               uint32_t wb_update:1;
>               uint32_t dsc_changed : 1;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +             uint32_t mst_bw : 1;
> +#endif
>       } bits;
>
>       uint32_t raw;
> @@ -278,6 +288,9 @@ struct dc_stream_update {
>
>       struct dc_writeback_update *wb_update;
>       struct dc_dsc_config *dsc_config;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     struct dc_mst_stream_bw_update *mst_bw_update; #endif
>       struct dc_transfer_func *func_shaper;
>       struct dc_3dlut *lut3d_func;
>
> --
> 2.25.1


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

* RE: [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support
  2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
@ 2021-10-22  8:55     ` Lin, Wayne
  -1 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-22  8:55 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel, lyude
  Cc: Wentland, Harry, Kazlauskas, Nicholas, Lipski, Mikita, intel-gfx,
	Lakha, Bhawanpreet

[AMD Official Use Only]

Hi Bhawan,
Just a nitpick below. With that fixed, feel free to add:
Reviewed-by: Wayne Lin <Wayne.Lin@amd.com>

Thanks!

Regards,
Wayne
> -----Original Message-----
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: Thursday, October 21, 2021 3:47 AM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org; lyude@redhat.com
> Cc: Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas, Nicholas
> <Nicholas.Kazlauskas@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; intel-gfx@lists.freedesktop.org; Lakha, Bhawanpreet
> <Bhawanpreet.Lakha@amd.com>
> Subject: [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support
>
> [Why]
> Add DP2 MST and debugfs support
>
> [How]
> Update the slot info based on the link encoding format
>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 29 +++++++++++++++++++  .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
> 3 ++  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  5 +++-
>  3 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index e56f73e299ef..875425ee91d0 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10741,6 +10741,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,  #if defined(CONFIG_DRM_AMD_DC_DCN)
>       struct dsc_mst_fairness_vars vars[MAX_PIPES];  #endif
> +     struct drm_dp_mst_topology_state *mst_state;
> +     struct drm_dp_mst_topology_mgr *mgr;
>
>       trace_amdgpu_dm_atomic_check_begin(state);
>
> @@ -10948,6 +10950,33 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>               lock_and_validation_needed = true;
>       }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     /* set the slot info for each mst_state based on the link encoding format */
> +     for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
> +             struct amdgpu_dm_connector *aconnector;
> +             struct drm_connector *connector;
> +             struct drm_connector_list_iter iter;
> +             u8 link_coding_cap;
> +
> +             if (!mgr->mst_state )
> +                     continue;
> +
> +             drm_connector_list_iter_begin(dev, &iter);
> +             drm_for_each_connector_iter(connector, &iter) {
> +                     int id = connector->index;
> +
> +                     if (id == mst_state->mgr->conn_base_id) {
> +                             aconnector = to_amdgpu_dm_connector(connector);
> +                             link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +                             drm_dp_mst_update_slots(mst_state, link_coding_cap);
> +
> +                             break;
> +                     }
> +             }
> +             drm_connector_list_iter_end(&iter);
> +
> +     }
> +#endif
>       /**
>        * Streams and planes are reset when there are changes that affect
>        * bandwidth. Anything that affects bandwidth needs to go through diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
> index 9b3ad56607bb..1a68a674913c 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
> @@ -294,6 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
>       case LINK_RATE_RBR2:
>       case LINK_RATE_HIGH2:
>       case LINK_RATE_HIGH3:
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     case LINK_RATE_UHBR10:
> +#endif
>               break;
>       default:
>               valid_input = false;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 6169488e2011..53b5cc7b0679 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -219,6 +219,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
>       struct drm_dp_mst_topology_mgr *mst_mgr;
>       struct drm_dp_mst_port *mst_port;
>       bool ret;
> +     u8 link_coding_cap;
>
>       aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
>       /* Accessing the connector state is required for vcpi_slots allocation @@ -238,6 +239,8 @@ bool
> dm_helpers_dp_mst_write_payload_allocation_table(
>
>       mst_port = aconnector->port;
>
> +     link_coding_cap =
> +dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +
>       if (enable) {
>
>               ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, @@ -251,7 +254,7 @@ bool
> dm_helpers_dp_mst_write_payload_allocation_table(
>       }
>
>       /* It's OK for this to fail */
> -     drm_dp_update_payload_part1(mst_mgr, 1);
> +     drm_dp_update_payload_part1(mst_mgr, (link_coding_cap ==
> +DP_CAP_ANSI_128B132B) ? 0:1);
I think should have format warning here that we need space between the number and the colon .
i.e. should be "0 : 1"

>
>       /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
>        * AUX message. The sequence is slot 1-63 allocated sequence for each
> --
> 2.25.1


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

* Re: [Intel-gfx] [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support
@ 2021-10-22  8:55     ` Lin, Wayne
  0 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-22  8:55 UTC (permalink / raw)
  To: Lakha, Bhawanpreet, Zuo, Jerry, dri-devel, lyude
  Cc: Wentland, Harry, Kazlauskas, Nicholas, Lipski, Mikita, intel-gfx,
	Lakha, Bhawanpreet

[AMD Official Use Only]

Hi Bhawan,
Just a nitpick below. With that fixed, feel free to add:
Reviewed-by: Wayne Lin <Wayne.Lin@amd.com>

Thanks!

Regards,
Wayne
> -----Original Message-----
> From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Sent: Thursday, October 21, 2021 3:47 AM
> To: Zuo, Jerry <Jerry.Zuo@amd.com>; dri-devel@lists.freedesktop.org; lyude@redhat.com
> Cc: Wentland, Harry <Harry.Wentland@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Kazlauskas, Nicholas
> <Nicholas.Kazlauskas@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; intel-gfx@lists.freedesktop.org; Lakha, Bhawanpreet
> <Bhawanpreet.Lakha@amd.com>
> Subject: [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support
>
> [Why]
> Add DP2 MST and debugfs support
>
> [How]
> Update the slot info based on the link encoding format
>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 29 +++++++++++++++++++  .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
> 3 ++  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  5 +++-
>  3 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index e56f73e299ef..875425ee91d0 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10741,6 +10741,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,  #if defined(CONFIG_DRM_AMD_DC_DCN)
>       struct dsc_mst_fairness_vars vars[MAX_PIPES];  #endif
> +     struct drm_dp_mst_topology_state *mst_state;
> +     struct drm_dp_mst_topology_mgr *mgr;
>
>       trace_amdgpu_dm_atomic_check_begin(state);
>
> @@ -10948,6 +10950,33 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>               lock_and_validation_needed = true;
>       }
>
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     /* set the slot info for each mst_state based on the link encoding format */
> +     for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
> +             struct amdgpu_dm_connector *aconnector;
> +             struct drm_connector *connector;
> +             struct drm_connector_list_iter iter;
> +             u8 link_coding_cap;
> +
> +             if (!mgr->mst_state )
> +                     continue;
> +
> +             drm_connector_list_iter_begin(dev, &iter);
> +             drm_for_each_connector_iter(connector, &iter) {
> +                     int id = connector->index;
> +
> +                     if (id == mst_state->mgr->conn_base_id) {
> +                             aconnector = to_amdgpu_dm_connector(connector);
> +                             link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +                             drm_dp_mst_update_slots(mst_state, link_coding_cap);
> +
> +                             break;
> +                     }
> +             }
> +             drm_connector_list_iter_end(&iter);
> +
> +     }
> +#endif
>       /**
>        * Streams and planes are reset when there are changes that affect
>        * bandwidth. Anything that affects bandwidth needs to go through diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
> index 9b3ad56607bb..1a68a674913c 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
> @@ -294,6 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
>       case LINK_RATE_RBR2:
>       case LINK_RATE_HIGH2:
>       case LINK_RATE_HIGH3:
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +     case LINK_RATE_UHBR10:
> +#endif
>               break;
>       default:
>               valid_input = false;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 6169488e2011..53b5cc7b0679 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -219,6 +219,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
>       struct drm_dp_mst_topology_mgr *mst_mgr;
>       struct drm_dp_mst_port *mst_port;
>       bool ret;
> +     u8 link_coding_cap;
>
>       aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
>       /* Accessing the connector state is required for vcpi_slots allocation @@ -238,6 +239,8 @@ bool
> dm_helpers_dp_mst_write_payload_allocation_table(
>
>       mst_port = aconnector->port;
>
> +     link_coding_cap =
> +dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link);
> +
>       if (enable) {
>
>               ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, @@ -251,7 +254,7 @@ bool
> dm_helpers_dp_mst_write_payload_allocation_table(
>       }
>
>       /* It's OK for this to fail */
> -     drm_dp_update_payload_part1(mst_mgr, 1);
> +     drm_dp_update_payload_part1(mst_mgr, (link_coding_cap ==
> +DP_CAP_ANSI_128B132B) ? 0:1);
I think should have format warning here that we need space between the number and the colon .
i.e. should be "0 : 1"

>
>       /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
>        * AUX message. The sequence is slot 1-63 allocated sequence for each
> --
> 2.25.1


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

* [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
  2021-10-20 14:16 [PATCH 1/4] drm: Remove slot checks in dp mst topology during commit Bhawanpreet Lakha
@ 2021-10-20 14:16 ` Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-20 14:16 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski, intel-gfx

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..b23972b6a27c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
+
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
 
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

* [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support
@ 2021-10-19 18:12 Bhawanpreet Lakha
  0 siblings, 0 replies; 26+ messages in thread
From: Bhawanpreet Lakha @ 2021-10-19 18:12 UTC (permalink / raw)
  To: Jerry.Zuo, dri-devel, lyude
  Cc: Harry.Wentland, Wayne.Lin, Nicholas.Kazlauskas, Mikita.Lipski

From: Fangzhi Zuo <Jerry.Zuo@amd.com>

Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  14 +
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 280 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  19 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   7 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  13 +
 5 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..935a50d6e933 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2354,6 +2354,11 @@ static enum surface_update_type check_update_surfaces_for_stream(
 		if (stream_update->dsc_config)
 			su_flags->bits.dsc_changed = 1;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		if (stream_update->mst_bw_update)
+			su_flags->bits.mst_bw = 1;
+#endif
+
 		if (su_flags->raw != 0)
 			overall_type = UPDATE_TYPE_FULL;
 
@@ -2731,6 +2736,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
 			if (stream_update->dsc_config)
 				dp_update_dsc_config(pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			if (stream_update->mst_bw_update) {
+				if (stream_update->mst_bw_update->is_increase)
+					dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+				else
+					dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+			}
+#endif
+
 			if (stream_update->pending_test_pattern) {
 				dc_link_dp_set_test_pattern(stream->link,
 					stream->test_pattern.type,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..b23972b6a27c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3232,6 +3232,9 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
 static void update_mst_stream_alloc_table(
 	struct dc_link *link,
 	struct stream_encoder *stream_enc,
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
+#endif
 	const struct dp_mst_stream_allocation_table *proposed_table)
 {
 	struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3267,6 +3270,9 @@ static void update_mst_stream_alloc_table(
 			work_table[i].slot_count =
 				proposed_table->stream_allocations[i].slot_count;
 			work_table[i].stream_enc = stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
+#endif
 		}
 	}
 
@@ -3389,6 +3395,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
 	struct fixed31_32 pbn;
@@ -3416,7 +3426,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		&proposed_table,
 		true)) {
 		update_mst_stream_alloc_table(
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+					link,
+					pipe_ctx->stream_res.stream_enc,
+					pipe_ctx->stream_res.hpo_dp_stream_enc,
+					&proposed_table);
+#else
 					link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 	}
 	else
 		DC_LOG_WARNING("Failed to update"
@@ -3430,6 +3447,20 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3439,14 +3470,30 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
 	ASSERT(proposed_table.stream_count > 0);
 
 	/* program DP source TX for payload */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	/* send down message */
 	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3469,13 +3516,188 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	pbn = get_pbn_from_timing(pipe_ctx);
 	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
+
+	return DC_OK;
+
+}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* decrease throttled vcp size */
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
+
+	/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+	dm_helpers_dp_mst_send_payload_allocation(
+			stream->ctx,
+			stream,
+			true);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+			stream->ctx,
+			stream,
+			&proposed_table,
+			true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	} else {
+		DC_LOG_WARNING("Failed to update"
+				"MST allocation table for"
+				"pipe idx:%d\n",
+				pipe_ctx->pipe_idx);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
 
 	return DC_OK;
+}
+
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
+{
+	struct dc_stream_state *stream = pipe_ctx->stream;
+	struct dc_link *link = stream->link;
+	struct fixed31_32 avg_time_slots_per_mtp;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
+	struct link_encoder *link_encoder = link->link_enc;
+	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+	struct dp_mst_stream_allocation_table proposed_table = {0};
+	uint8_t i;
+	enum act_return_status ret;
+	DC_LOGGER_INIT(link->ctx->logger);
+
+	/* notify immediate branch device table update */
+	if (dm_helpers_dp_mst_write_payload_allocation_table(
+				stream->ctx,
+				stream,
+				&proposed_table,
+				true)) {
+		/* update mst stream allocation table software state */
+		update_mst_stream_alloc_table(
+				link,
+				pipe_ctx->stream_res.stream_enc,
+				pipe_ctx->stream_res.hpo_dp_stream_enc,
+				&proposed_table);
+	}
+
+	DC_LOG_MST("%s  "
+			"stream_count: %d: \n ",
+			__func__,
+			link->mst_stream_alloc_table.stream_count);
+
+	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+		DC_LOG_MST("stream_enc[%d]: %p      "
+				"stream[%d].vcp_id: %d      "
+				"stream[%d].slot_count: %d\n",
+				i,
+				(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+				i,
+				link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+	}
+
+	ASSERT(proposed_table.stream_count > 0);
+
+	/* update mst stream allocation table hardware state */
+	link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+
+	/* poll for immediate branch device ACT handled */
+	ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+			stream->ctx,
+			stream);
+
+	if (ret != ACT_LINK_LOST) {
+		/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
+		dm_helpers_dp_mst_send_payload_allocation(
+				stream->ctx,
+				stream,
+				true);
+	}
+
+	/* increase throttled vcp size */
+	pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
+
+	stream_encoder->funcs->set_throttled_vcp_size(
+				stream_encoder,
+				avg_time_slots_per_mtp);
 
+	return DC_OK;
 }
+#endif
 
 static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 {
@@ -3483,6 +3705,10 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	struct dc_link *link = stream->link;
 	struct link_encoder *link_encoder = NULL;
 	struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct hpo_dp_link_encoder *hpo_dp_link_encoder = link->hpo_dp_link_enc;
+	struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
+#endif
 	struct dp_mst_stream_allocation_table proposed_table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
 	int i;
@@ -3504,9 +3730,25 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 	 */
 
 	/* slot X.Y */
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		stream_encoder->funcs->set_throttled_vcp_size(
+			stream_encoder,
+			avg_time_slots_per_mtp);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
+				hpo_dp_link_encoder,
+				hpo_dp_stream_encoder->inst,
+				avg_time_slots_per_mtp);
+		break;
+	}
+#else
 	stream_encoder->funcs->set_throttled_vcp_size(
 		stream_encoder,
 		avg_time_slots_per_mtp);
+#endif
 
 	/* TODO: which component is responsible for remove payload table? */
 	if (mst_mode) {
@@ -3516,8 +3758,16 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 				&proposed_table,
 				false)) {
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+			update_mst_stream_alloc_table(
+						link,
+						pipe_ctx->stream_res.stream_enc,
+						pipe_ctx->stream_res.hpo_dp_stream_enc,
+						&proposed_table);
+#else
 			update_mst_stream_alloc_table(
 				link, pipe_ctx->stream_res.stream_enc, &proposed_table);
+#endif
 		}
 		else {
 				DC_LOG_WARNING("Failed to update"
@@ -3533,6 +3783,20 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 			link->mst_stream_alloc_table.stream_count);
 
 	for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		DC_LOG_MST("stream_enc[%d]: %p      "
+		"stream[%d].hpo_dp_stream_enc: %p      "
+		"stream[%d].vcp_id: %d      "
+		"stream[%d].slot_count: %d\n",
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
+		i,
+		(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
+		i,
+		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#else
 		DC_LOG_MST("stream_enc[%d]: %p      "
 		"stream[%d].vcp_id: %d      "
 		"stream[%d].slot_count: %d\n",
@@ -3542,11 +3806,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 		link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
 		i,
 		link->mst_stream_alloc_table.stream_allocations[i].slot_count);
+#endif
 	}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
+	case DP_8b_10b_ENCODING:
+		link_encoder->funcs->update_mst_stream_allocation_table(
+			link_encoder,
+			&link->mst_stream_alloc_table);
+		break;
+	case DP_128b_132b_ENCODING:
+		hpo_dp_link_encoder->funcs->update_stream_allocation_table(
+				hpo_dp_link_encoder,
+				&link->mst_stream_alloc_table);
+		break;
+	}
+#else
 	link_encoder->funcs->update_mst_stream_allocation_table(
 		link_encoder,
 		&link->mst_stream_alloc_table);
+#endif
 
 	if (mst_mode) {
 		dm_helpers_dp_mst_poll_for_allocation_change_trigger(
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 296b0defcd1c..bb96e4e9ccfc 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
@@ -5993,6 +5993,25 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
+{
+	struct dc_link_settings link_settings = {0};
+
+	if (!dc_is_dp_signal(link->connector_signal))
+		return DP_UNKNOWN_ENCODING;
+
+	if (link->preferred_link_setting.lane_count !=
+			LANE_COUNT_UNKNOWN &&
+			link->preferred_link_setting.link_rate !=
+					LINK_RATE_UNKNOWN) {
+		link_settings = link->preferred_link_setting;
+	} else {
+		decide_mst_link_settings(link, &link_settings);
+	}
+
+	return dp_get_link_encoding_format(&link_settings);
+}
+
 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
 static void get_lane_status(
 	struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..08815310d85b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -295,6 +295,10 @@ enum dc_detect_reason {
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
 enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+#endif
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
@@ -424,4 +428,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 bool dc_link_is_fec_supported(const struct dc_link *link);
 bool dc_link_should_enable_fec(const struct dc_link *link);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
+#endif
 #endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index b8ebc1f09538..e37c4a10bfd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,6 +115,13 @@ struct periodic_interrupt_config {
 	int lines_offset;
 };
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct dc_mst_stream_bw_update {
+	bool is_increase; // is bandwidth reduced or increased
+	uint32_t mst_stream_bw; // new mst bandwidth in kbps
+};
+#endif
+
 union stream_update_flags {
 	struct {
 		uint32_t scaling:1;
@@ -125,6 +132,9 @@ union stream_update_flags {
 		uint32_t gamut_remap:1;
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		uint32_t mst_bw : 1;
+#endif
 	} bits;
 
 	uint32_t raw;
@@ -278,6 +288,9 @@ struct dc_stream_update {
 
 	struct dc_writeback_update *wb_update;
 	struct dc_dsc_config *dsc_config;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	struct dc_mst_stream_bw_update *mst_bw_update;
+#endif
 	struct dc_transfer_func *func_shaper;
 	struct dc_3dlut *lut3d_func;
 
-- 
2.25.1


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

end of thread, other threads:[~2021-10-22 13:08 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-20 19:47 [PATCH 1/4] drm: Remove slot checks in dp mst topology during commit Bhawanpreet Lakha
2021-10-20 19:47 ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-20 19:47 ` [PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format Bhawanpreet Lakha
2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-20 19:53   ` Bhawanpreet Lakha
2021-10-20 19:53     ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-20 19:47 ` [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support Bhawanpreet Lakha
2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-20 19:55   ` Alex Deucher
2021-10-20 19:55     ` [Intel-gfx] " Alex Deucher
2021-10-20 20:05     ` Bhawanpreet Lakha
2021-10-20 20:05       ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-21 10:21   ` Lin, Wayne
2021-10-21 10:21     ` [Intel-gfx] " Lin, Wayne
2021-10-21 15:15     ` Bhawanpreet Lakha
2021-10-21 15:15       ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-22  8:46       ` Lin, Wayne
2021-10-22  8:46         ` [Intel-gfx] " Lin, Wayne
2021-10-20 19:47 ` [PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support Bhawanpreet Lakha
2021-10-20 19:47   ` [Intel-gfx] " Bhawanpreet Lakha
2021-10-22  8:55   ` Lin, Wayne
2021-10-22  8:55     ` [Intel-gfx] " Lin, Wayne
2021-10-20 22:31 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/4] drm: Remove slot checks in dp mst topology during commit (rev3) Patchwork
2021-10-21 16:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/4] drm: Remove slot checks in dp mst topology during commit (rev4) Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2021-10-20 14:16 [PATCH 1/4] drm: Remove slot checks in dp mst topology during commit Bhawanpreet Lakha
2021-10-20 14:16 ` [PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support Bhawanpreet Lakha
2021-10-19 18:12 Bhawanpreet Lakha

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.