[PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support

2021-10-21 Thread Bhawanpreet Lakha
From: Fangzhi Zuo 

[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 
Signed-off-by: Bhawanpreet Lakha 
---
 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)
_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,
+   _table);
+#else
link, pipe_ctx->stream_res.stream_enc, 
_table);
+#endif
}
else
DC_LOG_WARNING("Failed to update"
@@ -3430,23 +3447,56 @@ enum dc_status dc_link_allocate_mst_payload(struct 
pip

[PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support

2021-10-20 Thread Bhawanpreet Lakha
From: Fangzhi Zuo 

[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 
Signed-off-by: Bhawanpreet Lakha 
---
 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)
_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,
+   _table);
+#else
link, pipe_ctx->stream_res.stream_enc, 
_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-&

[PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-20 Thread 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 
Signed-off-by: Fangzhi Zuo 
Reviewed-by: Lyude Paul 
---
 .../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(>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, _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_atomi

[PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support

2021-10-20 Thread 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 
Signed-off-by: Fangzhi Zuo 
---
 .../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, );
+   drm_for_each_connector_iter(connector, ) {
+   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();
+
+   }
+#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



[PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support

2021-10-20 Thread Bhawanpreet Lakha
From: Fangzhi Zuo 

Signed-off-by: Fangzhi Zuo 
---
 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)
_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,
+   _table);
+#else
link, pipe_ctx->stream_res.stream_enc, 
_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 *) 

[PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-20 Thread 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 
Signed-off-by: Fangzhi Zuo 
Reviewed-by: Lyude Paul 
---
 .../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(>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, _state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -52

[PATCH 1/4] drm: Remove slot checks in dp mst topology during commit

2021-10-20 Thread 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 
Reviewed-by: Lyude Paul 
---
 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, >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



[PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support

2021-10-20 Thread Bhawanpreet Lakha
From: Fangzhi Zuo 

Signed-off-by: Fangzhi Zuo 
---
 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)
_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,
+   _table);
+#else
link, pipe_ctx->stream_res.stream_enc, 
_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 *) 

[PATCH 1/4] drm: Remove slot checks in dp mst topology during commit

2021-10-20 Thread 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 
---
 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, >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



[PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support

2021-10-20 Thread 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 
Signed-off-by: Fangzhi Zuo 
---
 .../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, );
+   drm_for_each_connector_iter(connector, ) {
+   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();
+
+   }
+#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



[PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-20 Thread 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)

Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Fangzhi Zuo 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c | 34 ---
 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, 40 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..d188a5269070 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,9 @@ 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 +3366,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(>payload_lock);
@@ -4503,6 +4506,26 @@ 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_ecoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, 
uint8_t link_ecoding_cap)
+{
+   if (link_ecoding_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 ecoding format on mst_state 0x%p\n",
+   (link_ecoding_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 +5245,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, _state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5274,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",
-

[PATCH 3/4] drm/amd/display: Add DP 2.0 MST DC Support

2021-10-19 Thread Bhawanpreet Lakha
From: Fangzhi Zuo 

Signed-off-by: Fangzhi Zuo 
---
 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)
_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,
+   _table);
+#else
link, pipe_ctx->stream_res.stream_enc, 
_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 *) 

[PATCH 4/4] drm/amd/display: Add DP 2.0 MST DM Support

2021-10-19 Thread 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 
Signed-off-by: Fangzhi Zuo 
---
 .../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, );
+   drm_for_each_connector_iter(connector, ) {
+   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();
+
+   }
+#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



[PATCH 1/4] drm: Remove slot checks in dp mst topology during commit

2021-10-19 Thread 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 
---
 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, >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



[PATCH 2/4] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-19 Thread 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)

Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Fangzhi Zuo 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c | 34 ---
 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, 40 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..d188a5269070 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3353,6 +3353,9 @@ 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 +3366,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(>payload_lock);
@@ -4503,6 +4506,26 @@ 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_ecoding_cap: the ecoding format on the link
+ */
+void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, 
uint8_t link_ecoding_cap)
+{
+   if (link_ecoding_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 ecoding format on mst_state 0x%p\n",
+   (link_ecoding_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 +5245,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, _state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -5251,7 +5274,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",
-

Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-18 Thread Bhawanpreet Lakha
I understand the mst_state argument its just that most of the mst 
functions are using mst_mgr/port structs and there is no easy way to 
extract the mst_state using mgr/port in these places 
(drm_dp_update_payload_part1, drm_dp_mst_allocate_vcpi, drm_dp_init_vcpi 
etc) where we need the slot info.


So either we need to keep a copy of the slots in the mgr because that's 
what most of the code is using right now or pass around the atomic state 
to get the mgr->state mapping. (I don't have much experience with the 
mst code so maybe I am missing some key detail here?)



Thanks,

Bhawan


On 2021-10-15 4:41 p.m., Lyude Paul wrote:

[more snip]

On Fri, 2021-10-15 at 15:43 -0400, Bhawanpreet Lakha wrote:

Thanks for the response,

That function is per port so not sure how that will work. Also we only
need to check this inside drm_dp_mst_atomic_check_vcpi_alloc_limit(),
which doesn't have a state.

We could add the slots(or some DP version indicator) inside the
drm_connector, and add a parameter to
drm_dp_mst_atomic_check_vcpi_alloc_limit(int slots)? and call it with
this info via drm_dp_mst_atomic_check() and then update the mgr->slot in
commit.

TBH - I think we can actually just get away with having all of this info in
drm_dp_mst_topology_state



Bhawan


  ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr-

mst_primary,

  mst_state);
  mutex_unlock(>lock);
@@ -5527,11 +5543,16 @@ int drm_dp_mst_topology_mgr_init(struct
drm_dp_mst_topology_mgr *mgr,
  if (!mgr->proposed_vcpis)
  return -ENOMEM;
  set_bit(0, >payload_mask);
+   mgr->total_avail_slots = 63;
+   mgr->start_slot = 1;
   
  mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);

  if (mst_state == NULL)
  return -ENOMEM;
   
+   mst_state->total_avail_slots = 63;

+   mst_state->start_slot = 1;
+
  mst_state->mgr = mgr;
  INIT_LIST_HEAD(_state->vcpis);
   
diff --git a/include/drm/drm_dp_mst_helper.h

b/include/drm/drm_dp_mst_helper.h
index ddb9231d0309..f8152dfb34ed 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)
@@ -661,6 +663,16 @@ struct drm_dp_mst_topology_mgr {
   */
  int pbn_div;
   
+   /**

+    * @total_avail_slots: 63 for 8b/10b, 64 for 128/132b
+    */
+   u8 total_avail_slots;
+
+   /**
+    * @start_slot: 1 for 8b/10b, 0 for 128/132b
+    */
+   u8 start_slot;
+
  /**
   * @funcs: Atomic helper callbacks
   */
@@ -806,6 +818,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_coding_cap(struct drm_dp_mst_topology_state

*mst_state, uint8_t link_coding_cap);
   
   void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,

  struct drm_dp_mst_port *port);


Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-15 Thread Bhawanpreet Lakha



On 2021-10-13 6:25 p.m., Lyude Paul wrote:

Some comments below (also, sorry again for the mixup on the last review!)

On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:

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:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo 
Signed-off-by: Bhawanpreet Lakha 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++
  drivers/gpu/drm/drm_dp_mst_topology.c | 35 +++
  include/drm/drm_dp_mst_helper.h   | 13 +++
  3 files changed, 69 insertions(+), 7 deletions(-)

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 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,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);
  
@@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device

*dev,
 lock_and_validation_needed = true;
 }
  
+#if defined(CONFIG_DRM_AMD_DC_DCN)

+   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;

extraneous space


+
+   drm_connector_list_iter_begin(dev, );
+   drm_for_each_connector_iter(connector, ) {
+   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_coding_cap(mst_state,
link_coding_cap);
+
+   break;
+   }
+   }
+   drm_connector_list_iter_end();
+
+   }
+#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/drm_dp_mst_topology.c
b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
drm_dp_mst_topology_mgr *mgr)
 struct drm_dp_payload req_payload;
 struct drm_dp_mst_port *port;
 int i, j;
-   int cur_slots = 1;
+   int cur_slots = mgr->start_slot;
 bool skip;
  
 mutex_lock(>payload_lock);

@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
drm_dp_mst_topology_mgr *mgr,
 num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
  
 /* max. time slots - one slot for MTP header */

-   if (num_slots > 63)
+   if (num_slots > mgr->total_avail_slots)
 return -ENOSPC;

For reasons I will explain a little further in this email, we might want to
drop this…


 return num_slots;
  }
@@ -4333,7 +4333,7 @@ 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)
+   if (slots > mgr->total_avail_slots)

…and this


 return -ENOSPC;
  
 vcpi->pbn = pbn;

@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
drm_atomic_state *state,
  }
  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
  
+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state

*mst_state, uint8_t link_coding_cap)

Need some kdocs here


+{
+   if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+   mst_state->total_avail_slots = 64;
+   mst_state->start_slot = 0;
+   }
+
+   DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
+   (link_coding_cap == DP_CAP_ANSI_128B132B) ?
"128b/132b":"8b/10b", mst_state->mgr);

need to fix indenting here, and wrap this to 100 chars


+}

Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-14 Thread Bhawanpreet Lakha

Adding Mikita aswell

On 2021-10-14 4:21 p.m., Bhawanpreet Lakha wrote:


On 2021-10-13 6:25 p.m., Lyude Paul wrote:
Some comments below (also, sorry again for the mixup on the last 
review!)


On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:

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:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo 
Signed-off-by: Bhawanpreet Lakha 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++
  drivers/gpu/drm/drm_dp_mst_topology.c | 35 
+++

  include/drm/drm_dp_mst_helper.h   | 13 +++
  3 files changed, 69 insertions(+), 7 deletions(-)

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 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,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);
  @@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct 
drm_device

*dev,
 lock_and_validation_needed = true;
 }
  +#if defined(CONFIG_DRM_AMD_DC_DCN)
+   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;

extraneous space


+
+   drm_connector_list_iter_begin(dev, );
+   drm_for_each_connector_iter(connector, ) {
+   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_coding_cap(mst_state,
link_coding_cap);
+
+   break;
+   }
+   }
+   drm_connector_list_iter_end();
+
+   }
+#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/drm_dp_mst_topology.c
b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
drm_dp_mst_topology_mgr *mgr)
 struct drm_dp_payload req_payload;
 struct drm_dp_mst_port *port;
 int i, j;
-   int cur_slots = 1;
+   int cur_slots = mgr->start_slot;
 bool skip;
   mutex_lock(>payload_lock);
@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
drm_dp_mst_topology_mgr *mgr,
 num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
   /* max. time slots - one slot for MTP header */
-   if (num_slots > 63)
+   if (num_slots > mgr->total_avail_slots)
 return -ENOSPC;
For reasons I will explain a little further in this email, we might 
want to

drop this…


 return num_slots;
  }
@@ -4333,7 +4333,7 @@ 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)
+   if (slots > mgr->total_avail_slots)

…and this


 return -ENOSPC;
   vcpi->pbn = pbn;
@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
drm_atomic_state *state,
  }
  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
  +void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state
*mst_state, uint8_t link_coding_cap)

Need some kdocs here


+{
+   if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+   mst_state->total_avail_slots = 64;
+   mst_state->start_slot = 0;
+   }
+
+   DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
+   (link_coding_cap == DP_CAP_ANSI_128B132B) ?
"128b/132b":"8b/10b", mst_state-&

Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-14 Thread Bhawanpreet Lakha



On 2021-10-13 6:25 p.m., Lyude Paul wrote:

Some comments below (also, sorry again for the mixup on the last review!)

On Tue, 2021-10-12 at 17:58 -0400, Bhawanpreet Lakha wrote:

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:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo 
Signed-off-by: Bhawanpreet Lakha 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++
  drivers/gpu/drm/drm_dp_mst_topology.c | 35 +++
  include/drm/drm_dp_mst_helper.h   | 13 +++
  3 files changed, 69 insertions(+), 7 deletions(-)

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 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,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);
  
@@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device

*dev,
 lock_and_validation_needed = true;
 }
  
+#if defined(CONFIG_DRM_AMD_DC_DCN)

+   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;

extraneous space


+
+   drm_connector_list_iter_begin(dev, );
+   drm_for_each_connector_iter(connector, ) {
+   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_coding_cap(mst_state,
link_coding_cap);
+
+   break;
+   }
+   }
+   drm_connector_list_iter_end();
+
+   }
+#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/drm_dp_mst_topology.c
b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct
drm_dp_mst_topology_mgr *mgr)
 struct drm_dp_payload req_payload;
 struct drm_dp_mst_port *port;
 int i, j;
-   int cur_slots = 1;
+   int cur_slots = mgr->start_slot;
 bool skip;
  
 mutex_lock(>payload_lock);

@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct
drm_dp_mst_topology_mgr *mgr,
 num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
  
 /* max. time slots - one slot for MTP header */

-   if (num_slots > 63)
+   if (num_slots > mgr->total_avail_slots)
 return -ENOSPC;

For reasons I will explain a little further in this email, we might want to
drop this…


 return num_slots;
  }
@@ -4333,7 +4333,7 @@ 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)
+   if (slots > mgr->total_avail_slots)

…and this


 return -ENOSPC;
  
 vcpi->pbn = pbn;

@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct
drm_atomic_state *state,
  }
  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
  
+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state

*mst_state, uint8_t link_coding_cap)

Need some kdocs here


+{
+   if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+   mst_state->total_avail_slots = 64;
+   mst_state->start_slot = 0;
+   }
+
+   DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
+   (link_coding_cap == DP_CAP_ANSI_128B132B) ?
"128b/132b":"8b/10b", mst_state->mgr);

need to fix indenting here, and wrap this to 100 chars


+}

Re: [PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-13 Thread Bhawanpreet Lakha



On 2021-10-13 12:09 p.m., Jani Nikula wrote:

On Tue, 12 Oct 2021, Bhawanpreet Lakha  wrote:

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:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo 
Signed-off-by: Bhawanpreet Lakha 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++
  drivers/gpu/drm/drm_dp_mst_topology.c | 35 +++
  include/drm/drm_dp_mst_helper.h   | 13 +++
  3 files changed, 69 insertions(+), 7 deletions(-)

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 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,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);
  
@@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,

lock_and_validation_needed = true;
}
  
+#if defined(CONFIG_DRM_AMD_DC_DCN)

+   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, );
+   drm_for_each_connector_iter(connector, ) {
+   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_coding_cap(mst_state, 
link_coding_cap);
+
+   break;
+   }
+   }
+   drm_connector_list_iter_end();
+
+   }
+#endif

I wonder if we could split this to separate drm dp helper and amd driver
patches?

I believe that was the original structure but, lyude recommended to put 
them into the same patch to see how it is being used

/**
 * 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/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
struct drm_dp_payload req_payload;
struct drm_dp_mst_port *port;
int i, j;
-   int cur_slots = 1;
+   int cur_slots = mgr->start_slot;
bool skip;
  
  	mutex_lock(>payload_lock);

@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr 
*mgr,
num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
  
  	/* max. time slots - one slot for MTP header */

-   if (num_slots > 63)
+   if (num_slots > mgr->total_avail_slots)
return -ENOSPC;
return num_slots;
  }
@@ -4333,7 +4333,7 @@ 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)
+   if (slots > mgr->total_avail_slots)
return -ENOSPC;
  
  	vcpi->pbn = pbn;

@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct 
drm_atomic_state *state,
  }
  EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
  
+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, uint8_t link_coding_cap)

+{
+   if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+   mst_state->total_avail_slots = 64;
+   mst_state->start_slot = 0;
+   }

The values never change AFAICT, should we store the channel encoding
instead, and use that information to initialize the values?

(Alternatively, why aren't the 8b/10b values initialized here if
128b/132b are?)
I agree, 8b/10 are the default, but in case where we switch from 
128b/132 -> 8b/10b we should be u

[PATCH] drm: Update MST First Link Slot Information Based on Encoding Format

2021-10-12 Thread 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:
* Remove get_mst_link_encoding_cap
* Move total/start slots to mst_state, and copy it to mst_mgr in
atomic_check

Signed-off-by: Fangzhi Zuo 
Signed-off-by: Bhawanpreet Lakha 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++
 drivers/gpu/drm/drm_dp_mst_topology.c | 35 +++
 include/drm/drm_dp_mst_helper.h   | 13 +++
 3 files changed, 69 insertions(+), 7 deletions(-)

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 5020f2d36fe1..4ad50eb0091a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10612,6 +10612,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);
 
@@ -10819,6 +10821,32 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
lock_and_validation_needed = true;
}
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+   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, );
+   drm_for_each_connector_iter(connector, ) {
+   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_coding_cap(mst_state, 
link_coding_cap);
+
+   break;
+   }
+   }
+   drm_connector_list_iter_end();
+
+   }
+#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/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index ad0795afc21c..fb5c47c4cb2e 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3368,7 +3368,7 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
struct drm_dp_payload req_payload;
struct drm_dp_mst_port *port;
int i, j;
-   int cur_slots = 1;
+   int cur_slots = mgr->start_slot;
bool skip;
 
mutex_lock(>payload_lock);
@@ -4321,7 +4321,7 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr 
*mgr,
num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
 
/* max. time slots - one slot for MTP header */
-   if (num_slots > 63)
+   if (num_slots > mgr->total_avail_slots)
return -ENOSPC;
return num_slots;
 }
@@ -4333,7 +4333,7 @@ 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)
+   if (slots > mgr->total_avail_slots)
return -ENOSPC;
 
vcpi->pbn = pbn;
@@ -4507,6 +4507,18 @@ int drm_dp_atomic_release_vcpi_slots(struct 
drm_atomic_state *state,
 }
 EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 
+void drm_dp_mst_update_coding_cap(struct drm_dp_mst_topology_state *mst_state, 
uint8_t link_coding_cap)
+{
+   if (link_coding_cap == DP_CAP_ANSI_128B132B) {
+   mst_state->total_avail_slots = 64;
+   mst_state->start_slot = 0;
+   }
+
+   DRM_DEBUG_KMS("%s coding format on mgr 0x%p\n",
+   (link_coding_cap == DP_CAP_ANSI_128B132B) ? 
"128b/132b":"8b/10b", mst_state->mgr);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_coding_cap);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -4538,8 +4550,8 @@ bool drm_dp_mst_allocate_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
 
ret = drm_dp_init_vcpi(mgr, >vcpi, pbn, slots);
if (ret) {
-   drm_dbg_kms(mgr->dev, "failed to init vcpi slots=%d max=63 
ret=%d\n",
-  

[PATCH] drm/dp_mst: Don't return error code when crtc is null

2020-08-14 Thread Bhawanpreet Lakha
[Why]
In certain cases the crtc can be NULL and returning -EINVAL causes
atomic check to fail when it shouln't. This leads to valid
configurations failing because atomic check fails.

[How]
Don't early return if crtc is null

Signed-off-by: Bhawanpreet Lakha 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 70c4b7afed12..bc90a1485699 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -5037,8 +5037,8 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct 
drm_atomic_state *state, struct drm
 
crtc = conn_state->crtc;
 
-   if (WARN_ON(!crtc))
-   return -EINVAL;
+   if (!crtc)
+   continue;
 
if (!drm_dp_mst_dsc_aux_for_port(pos->port))
continue;
-- 
2.17.1

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


[PATCH 4/6] drm/amd/display: Load srm before enabling HDCP

2020-01-22 Thread Bhawanpreet Lakha
[Why]
we need to load SRM before we start HDCP. Because for S3 case the sysfs call 
will be
after we have already enabled HDCP, so we might not be using the latest SRM

[How]
Set srm before starting HDCP.

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 074243a2f808..e6a89cd7ed57 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -136,6 +136,13 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
 
if (enable_encryption) {
+   /* Explicitly set the saved SRM as sysfs call will be 
after we already enabled hdcp
+* (s3 resume case)
+*/
+   if (hdcp_work->srm_size > 0)
+   psp_set_srm(hdcp_work->hdcp.config.psp.handle, 
hdcp_work->srm, hdcp_work->srm_size,
+   _work->srm_version);
+
display->adjust.disable = 0;
if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0)
hdcp_w->link.adjust.hdcp2.force_type = 
MOD_HDCP_FORCE_TYPE_0;
-- 
2.17.1

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


[PATCH 2/6] drm/amd/display: update psp interface header

2020-01-22 Thread Bhawanpreet Lakha
[Why]
We need to support SRM(System Renewability Message)
As per hdcp spec (5.Renewability) SRM needs to be storage in a non-volatile
memory.

PSP owns the checking of SRM but doesn't have the ability to store it in a
non-volatile memory. So we need the kernel driver to facilitate it using the
interface provided by PSP

[How]
Add the interface to the header file, so the driver can use them

v2: update commit description

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Rodrigo Siqueira 
---
 .../drm/amd/display/modules/hdcp/hdcp_psp.h   | 26 ++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
index 82a5e997d573..d5cb3f46606f 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
@@ -117,6 +117,8 @@ struct ta_dtm_shared_memory {
 int psp_cmd_submit_buf(struct psp_context *psp, struct amdgpu_firmware_info 
*ucode, struct psp_gfx_cmd_resp *cmd,
uint64_t fence_mc_addr);
 
+enum { PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE = 5120 };
+
 enum ta_hdcp_command {
TA_HDCP_COMMAND__INITIALIZE,
TA_HDCP_COMMAND__HDCP1_CREATE_SESSION,
@@ -134,7 +136,10 @@ enum ta_hdcp_command {
TA_HDCP_COMMAND__UNUSED_3,
TA_HDCP_COMMAND__HDCP2_CREATE_SESSION_V2,
TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2,
-   TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION
+   TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION,
+   TA_HDCP_COMMAND__HDCP_DESTROY_ALL_SESSIONS,
+   TA_HDCP_COMMAND__HDCP_SET_SRM,
+   TA_HDCP_COMMAND__HDCP_GET_SRM
 };
 
 enum ta_hdcp2_msg_id {
@@ -415,6 +420,22 @@ struct ta_hdcp_cmd_hdcp2_enable_dp_stream_encryption_input 
{
uint32_t display_handle;
 };
 
+struct ta_hdcp_cmd_set_srm_input {
+   uint32_t srm_buf_size;
+   uint8_t srm_buf[PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE];
+};
+
+struct ta_hdcp_cmd_set_srm_output {
+   uint8_t valid_signature;
+   uint32_t srm_version;
+};
+
+struct ta_hdcp_cmd_get_srm_output {
+   uint32_t srm_version;
+   uint32_t srm_buf_size;
+   uint8_t srm_buf[PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE];
+};
+
 /**/
 /* Common input structure for HDCP callbacks */
 union ta_hdcp_cmd_input {
@@ -432,6 +453,7 @@ union ta_hdcp_cmd_input {
struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2
hdcp2_prepare_process_authentication_message_v2;
struct ta_hdcp_cmd_hdcp2_enable_dp_stream_encryption_input 
hdcp2_enable_dp_stream_encryption;
+   struct ta_hdcp_cmd_set_srm_input hdcp_set_srm;
 };
 
 /* Common output structure for HDCP callbacks */
@@ -444,6 +466,8 @@ union ta_hdcp_cmd_output {
struct ta_hdcp_cmd_hdcp2_create_session_output_v2 
hdcp2_create_session_v2;
struct 
ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2
hdcp2_prepare_process_authentication_message_v2;
+   struct ta_hdcp_cmd_set_srm_output hdcp_set_srm;
+   struct ta_hdcp_cmd_get_srm_output hdcp_get_srm;
 };
 /**/
 
-- 
2.17.1

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


[PATCH 0/6] HDCP SRM interface v2

2020-01-22 Thread Bhawanpreet Lakha
These patches adds support for SRM loading. SRM has to be saved in a
non-volatile memory(spec) and PSP can't do that directly so we need to
use the driver to do this

Since the kernel cannot directly write to system storage we need to provide an
interface so that the usermode can do it for us

v2
-update commit descriptions
  drm/amd/display: Add sysfs interface for set/get srm
  drm/amd/display: update psp interface header
-update comment for sysfs
  drm/amd/display: Add sysfs interface for set/get srm
-use define instead of a magic number
  drm/amd/display: call psp set/get interfaces

Bhawanpreet Lakha (6):
  drm/amd/display: Pass amdgpu_device instead of psp_context
  drm/amd/display: update psp interface header
  drm/amd/display: Add sysfs interface for set/get srm
  drm/amd/display: Load srm before enabling HDCP
  drm/amd/display: call psp set/get interfaces
  drm/amd/display: REFERENCE for srm interface patches

 REFERENCE |  49 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 238 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|   9 +-
 .../drm/amd/display/modules/hdcp/hdcp_psp.h   |  26 +-
 5 files changed, 317 insertions(+), 7 deletions(-)
 create mode 100644 REFERENCE

-- 
2.17.1

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


[PATCH 6/6] drm/amd/display: REFERENCE for srm interface patches

2020-01-22 Thread Bhawanpreet Lakha
This is just a reference for the patches. not to be merged

Signed-off-by: Bhawanpreet Lakha 
---
 REFERENCE | 49 +
 1 file changed, 49 insertions(+)
 create mode 100644 REFERENCE

diff --git a/REFERENCE b/REFERENCE
new file mode 100644
index ..2e53f9cc82ff
--- /dev/null
+++ b/REFERENCE
@@ -0,0 +1,49 @@
+SRM interface Reference Usermode scripts for ubuntu. 
+These are just reference sciprts to facilitate the SRM interface for amdgpu.
+
++-+
+| Main script, this is called on boot/shutdown/suspend/resume , it calls the 
sysfs to get/set the SRM |
+| FILE: /home/amdgpu_hdcp_srm_script.sh
   |
++-+
+#!/bin/bash
+
+SRMFILE="/home/SRM"
+sudo cat "$SRMFILE" > /sys/class/drm/card0/device/hdcp_srm
+sudo cat /sys/class/drm/card0/device/hdcp_srm > "$SRMFILE"
+
+
+
+
+
++-+
+| .service file, This is placed into /etc/systemd/system/ so it runs the main 
script on boot/shutdown |
+| FILE: /etc/systemd/system/amdgpu_hdc_srm_boot_shutdown.service   
   |
++-+
+[Unit]
+Description=HDCP SRM boot and shutdown save/load
+
+[Service]
+Type=simple
+ExecStart=/home/amdgpu_hdcp_srm_script.sh
+ExecStop=/home/amdgpu_hdcp_srm_script.sh
+
+[Install]
+WantedBy=multi-user.target
+
+
+
++-+
+| To run the script on boot/start run  
  |
++-+
+sudo systemctl start amdgpu_hdc_srm_boot_shutdown
+sudo systemctl enable amdgpu_hdc_srm_boot_shutdown
+
+
+
++-+
+| To symlnk the files (adding to these directory will run the script on 
suspend/resume|
++-+
+sudo ln -s $SCRIPTFILE /lib/systemd/system-sleep/amdgpu_hdcp_srm
+sudo ln -s $SCRIPTFILE /usr/lib/pm-utils/sleep.d/95amdgpu_hdcp_srm
+
+
-- 
2.17.1

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


[PATCH 5/6] drm/amd/display: call psp set/get interfaces

2020-01-22 Thread Bhawanpreet Lakha
Call the cmd ids for set/get srm according to the sysfs call

v2: Use define for the magic number

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Rodrigo Siqueira 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 50 ++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index e6a89cd7ed57..1768a33b1dc3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -30,6 +30,11 @@
 #include 
 #include "hdcp_psp.h"
 
+/*
+ * If the SRM version being loaded is less than or equal to the
+ * currently loaded SRM, psp will return 0x as the version
+ */
+#define PSP_SRM_VERSION_MAX 0x
 
 static bool
 lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, uint32_t 
size)
@@ -71,11 +76,54 @@ lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, 
uint32_t size)
 
 static uint8_t *psp_get_srm(struct psp_context *psp, uint32_t *srm_version, 
uint32_t *srm_size)
 {
-   return NULL;
+
+   struct ta_hdcp_shared_memory *hdcp_cmd;
+
+   if (!psp->hdcp_context.hdcp_initialized) {
+   DRM_WARN("Failed to get hdcp srm. HDCP TA is not initialized.");
+   return NULL;
+   }
+
+   hdcp_cmd = (struct ta_hdcp_shared_memory 
*)psp->hdcp_context.hdcp_shared_buf;
+   memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
+
+   hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP_GET_SRM;
+   psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
+
+   if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
+   return NULL;
+
+   *srm_version = hdcp_cmd->out_msg.hdcp_get_srm.srm_version;
+   *srm_size = hdcp_cmd->out_msg.hdcp_get_srm.srm_buf_size;
+
+
+   return hdcp_cmd->out_msg.hdcp_get_srm.srm_buf;
 }
 
 static int psp_set_srm(struct psp_context *psp, uint8_t *srm, uint32_t 
srm_size, uint32_t *srm_version)
 {
+
+   struct ta_hdcp_shared_memory *hdcp_cmd;
+
+   if (!psp->hdcp_context.hdcp_initialized) {
+   DRM_WARN("Failed to get hdcp srm. HDCP TA is not initialized.");
+   return -EINVAL;
+   }
+
+   hdcp_cmd = (struct ta_hdcp_shared_memory 
*)psp->hdcp_context.hdcp_shared_buf;
+   memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
+
+   memcpy(hdcp_cmd->in_msg.hdcp_set_srm.srm_buf, srm, srm_size);
+   hdcp_cmd->in_msg.hdcp_set_srm.srm_buf_size = srm_size;
+   hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP_SET_SRM;
+
+   psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
+
+   if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || 
hdcp_cmd->out_msg.hdcp_set_srm.valid_signature != 1 ||
+   hdcp_cmd->out_msg.hdcp_set_srm.srm_version == PSP_SRM_VERSION_MAX)
+   return -EINVAL;
+
+   *srm_version = hdcp_cmd->out_msg.hdcp_set_srm.srm_version;
return 0;
 }
 
-- 
2.17.1

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


[PATCH 3/6] drm/amd/display: Add sysfs interface for set/get srm

2020-01-22 Thread Bhawanpreet Lakha
[Why]
PSP doesn't have the ability to store SRM in a non-volatile memory.  And since
the kernel cannot write to the storage directly, we need usermode to facilitate
this

As per spec the SRM needs to be persistent so this interface is to be
called by the usermode anytime the system goes down/powers on

*boot/resume: load from storage
*shutdown/suspend: save to storage

[How]
Provide a sysfs interface so that the usermode can set/get srm at the right 
times

save to storage: call "cat /sys/class/drm/card0/device/hdcp_srm > file" after 
boot and resume
-driver calls psp_get_srm() to get the stored srm and outputs it

load from storage: call "cat file > /sys/class/drm/card0/device/hdcp_srm" 
before shutdown and suspend
-driver reads the file from sysfs and calls psp_set_srm() to send the 
SRM to PSP

v2:
-update commit description
-add comment about sysfs file handling in the code

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Rodrigo Siqueira 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c| 179 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h|   6 +
 2 files changed, 183 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index a269916f7dd6..074243a2f808 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -28,6 +28,8 @@
 #include "amdgpu_dm.h"
 #include "dm_helpers.h"
 #include 
+#include "hdcp_psp.h"
+
 
 static bool
 lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, uint32_t 
size)
@@ -67,6 +69,16 @@ lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, 
uint32_t size)
return dm_helpers_dp_read_dpcd(link->ctx, link, address, data, size);
 }
 
+static uint8_t *psp_get_srm(struct psp_context *psp, uint32_t *srm_version, 
uint32_t *srm_size)
+{
+   return NULL;
+}
+
+static int psp_set_srm(struct psp_context *psp, uint8_t *srm, uint32_t 
srm_size, uint32_t *srm_version)
+{
+   return 0;
+}
+
 static void process_output(struct hdcp_workqueue *hdcp_work)
 {
struct mod_hdcp_output output = hdcp_work->output;
@@ -88,6 +100,18 @@ static void process_output(struct hdcp_workqueue *hdcp_work)
schedule_delayed_work(_work->property_validate_dwork, 
msecs_to_jiffies(0));
 }
 
+static void link_lock(struct hdcp_workqueue *work, bool lock)
+{
+
+   int i = 0;
+
+   for (i = 0; i < work->max_link; i++) {
+   if (lock)
+   mutex_lock([i].mutex);
+   else
+   mutex_unlock([i].mutex);
+   }
+}
 void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
 unsigned int link_index,
 struct amdgpu_dm_connector *aconnector,
@@ -302,7 +326,8 @@ void hdcp_destroy(struct hdcp_workqueue *hdcp_work)
}
 
kfree(hdcp_work);
-
+   kfree(hdcp_work->srm);
+   kfree(hdcp_work->srm_temp);
 }
 
 static void update_config(void *handle, struct cp_psp_stream_config *config)
@@ -338,6 +363,139 @@ static void update_config(void *handle, struct 
cp_psp_stream_config *config)
hdcp_update_display(hdcp_work, link_index, aconnector, 
DRM_MODE_HDCP_CONTENT_TYPE0, false);
 }
 
+
+/* NOTE: From the usermodes prospective you only need to call write *ONCE*, 
the kernel
+ *  will automatically call once or twice depending on the size
+ *
+ * call: "cat file > /sys/class/drm/card0/device/hdcp_srm" from usermode no 
matter what the size is
+ *
+ * The kernel can only send PAGE_SIZE at once and since MAX_SRM_FILE(5120) > 
PAGE_SIZE(4096),
+ * srm_data_write can be called multiple times.
+ *
+ * sysfs interface doesn't tell us the size we will get so we are sending 
partial SRMs to psp and on
+ * the last call we will send the full SRM. PSP will fail on every call before 
the last.
+ *
+ * This means we don't know if the SRM is good until the last call. And 
because of this limitation we
+ * cannot throw errors early as it will stop the kernel from writing to sysfs
+ *
+ * Example 1:
+ * Good SRM size = 5096
+ * first call to write 4096 -> PSP fails
+ * Second call to write 1000 -> PSP Pass -> SRM is set
+ *
+ * Example 2:
+ * Bad SRM size = 4096
+ * first call to write 4096 -> PSP fails (This is the same as above, but 
we don't know if this
+ * is the last call)
+ *
+ * Solution?:
+ * 1: Parse the SRM? -> It is signed so we don't know the EOF
+ * 2: We can have another sysfs that passes the size before calling set. 
-> simpler solution
+ * below
+ *
+ * Easy Solution:
+ * Always call get after Set to verify if set was successful.
+ * +--+
+ * |   Why it works:  |
+ * +--+
+ * PSP will only update its srm if its older than the one we are tr

[PATCH 1/6] drm/amd/display: Pass amdgpu_device instead of psp_context

2020-01-22 Thread Bhawanpreet Lakha
[Why]
We need this to create sysfs (followup patch)

[How]
Change the parameter

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 2 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 4 ++--
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

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 fe80d6ef9a8f..30e19dc390c8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -960,7 +960,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 
 #ifdef CONFIG_DRM_AMD_DC_HDCP
if (adev->asic_type >= CHIP_RAVEN) {
-   adev->dm.hdcp_workqueue = hdcp_create_workqueue(>psp, 
_params.cp_psp, adev->dm.dc);
+   adev->dm.hdcp_workqueue = hdcp_create_workqueue(adev, 
_params.cp_psp, adev->dm.dc);
 
if (!adev->dm.hdcp_workqueue)
DRM_ERROR("amdgpu: failed to initialize 
hdcp_workqueue.\n");
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 0acd3409dd6c..a269916f7dd6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -338,7 +338,7 @@ static void update_config(void *handle, struct 
cp_psp_stream_config *config)
hdcp_update_display(hdcp_work, link_index, aconnector, 
DRM_MODE_HDCP_CONTENT_TYPE0, false);
 }
 
-struct hdcp_workqueue *hdcp_create_workqueue(void *psp_context, struct cp_psp 
*cp_psp, struct dc *dc)
+struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, 
struct cp_psp *cp_psp, struct dc *dc)
 {
 
int max_caps = dc->caps.max_links;
@@ -360,7 +360,7 @@ struct hdcp_workqueue *hdcp_create_workqueue(void 
*psp_context, struct cp_psp *c
INIT_DELAYED_WORK(_work[i].watchdog_timer_dwork, 
event_watchdog_timer);
INIT_DELAYED_WORK(_work[i].property_validate_dwork, 
event_property_validate);
 
-   hdcp_work[i].hdcp.config.psp.handle =  psp_context;
+   hdcp_work[i].hdcp.config.psp.handle = >psp;
hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, 
i);
hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c;
hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
index 6abde86bce4a..331b50825510 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
@@ -30,6 +30,7 @@
 #include "hdcp.h"
 #include "dc.h"
 #include "dm_cp_psp.h"
+#include "amdgpu.h"
 
 struct mod_hdcp;
 struct mod_hdcp_link;
@@ -64,6 +65,6 @@ void hdcp_reset_display(struct hdcp_workqueue *work, unsigned 
int link_index);
 void hdcp_handle_cpirq(struct hdcp_workqueue *work, unsigned int link_index);
 void hdcp_destroy(struct hdcp_workqueue *work);
 
-struct hdcp_workqueue *hdcp_create_workqueue(void *psp_context, struct cp_psp 
*cp_psp, struct dc *dc);
+struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, 
struct cp_psp *cp_psp, struct dc *dc);
 
 #endif /* AMDGPU_DM_AMDGPU_DM_HDCP_H_ */
-- 
2.17.1

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


Re: [PATCH] drm/edid: Add modes from CTA-861-G

2019-11-25 Thread Bhawanpreet Lakha

Reviewed-by: Bhawanpreet Lakha 

On 2019-11-25 1:14 p.m., Harry Wentland wrote:

+Bhawan who has been looking at this from our side.

Harry

On 2019-11-23 12:50 a.m., Thomas Anderson wrote:

The new modes are needed for exotic displays such as 8K. Verified that
modes like 8K60 and 4K120 are properly obtained from a Samsung Q900R.

Signed-off-by: Thomas Anderson 
---
  drivers/gpu/drm/drm_edid.c  | 388 +++-
  include/drm/drm_connector.h |  16 +-
  2 files changed, 391 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6b0177112e18..ff5c928516fb 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1278,6 +1278,374 @@ static const struct drm_display_mode edid_cea_modes[] = 
{
   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 108 - 1280x720@48Hz 16:9 */
+   { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
+  2280, 2500, 0, 720, 725, 730, 750, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 109 - 1280x720@48Hz 64:27 */
+   { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
+  2280, 2500, 0, 720, 725, 730, 750, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 110 - 1680x720@48Hz 64:27 */
+   { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490,
+  2530, 2750, 0, 720, 725, 730, 750, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 111 - 1920x1080@48Hz 16:9 */
+   { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
+  2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 112 - 1920x1080@48Hz 64:27 */
+   { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
+  2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 113 - 2560x1080@48Hz 64:27 */
+   { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558,
+  3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 114 - 3840x2160@48Hz 16:9 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
+  5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 115 - 4096x2160@48Hz 256:135 */
+   { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116,
+  5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48,
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+   /* 116 - 3840x2160@48Hz 64:27 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
+  5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 117 - 3840x2160@100Hz 16:9 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
+  4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 118 - 3840x2160@120Hz 16:9 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
+  4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 119 - 3840x2160@100Hz 64:27 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
+  4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 120 - 3840x2160@12

drm/edid: Add modes from CTA-861-G

2019-11-25 Thread Bhawanpreet Lakha
Everything looks good. but one concern I have is that shouldn't the 
aspect ratio be 16:9 for some of them (See below). Unless I missed 
something?


VIC 109 1280x720=*16:9*
VIC 110 1680x720=*7:3*
VIC 112 1920x1080=*16:9*
VIC 116 3840x2160=*16:9*
VIC 119 3840x2160=*16:9*
VIC 120 3840x2160=*16:9*
VIC 202-209  7680x4320=*16:9*


Bhawan

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