* [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.