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

2021-10-25 Thread Lyude Paul
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 
Reviewed-by: "Lin, Wayne" 
Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Lyude Paul 
---
 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 da942e9f5142..782141ba8ac5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2356,6 +2356,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;
 
@@ -2741,6 +2746,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 ca5dc3c168ec..fd12561b70cc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3272,6 +3272,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] = {
@@ -3308,6 +3311,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
}
}
 
@@ -3430,6 +3436,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;
@@ -3457,7 +3467,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"
@@

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

2021-10-25 Thread Lyude Paul
From: Bhawanpreet Lakha 

[Why]
Add DP2 MST and debugfs support

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

Reviewed-by: "Lin, Wayne" 
Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Fangzhi Zuo 
Signed-off-by: Lyude Paul 
---
 .../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 f35561b5a465..ecdeeedb1cde 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10684,6 +10684,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);
 
@@ -10891,6 +10893,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 814f67d86a3c..3d44896149a2 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.31.1



[PATCH RESEND v5 0/4] drm/amdgpu, Add DP 2.0 MST support + drm/dp_mst helpers

2021-10-25 Thread Lyude Paul
(Sorry for the noise, had to resend because I typo'd amd's mailing list
email address by accident)

Just resubmitting this patch series from AMD with _very_ minor changes
(just a typo and fixing a debug message) so that this can be pushed
upstream with a proper patchwork link. Will be pushing this into a topic
branch and submitting to airlied in a moment.

Bhawanpreet Lakha (3):
  drm: Remove slot checks in dp mst topology during commit
  drm: Update MST First Link Slot Information Based on Encoding Format
  drm/amd/display: Add DP 2.0 MST DM Support

Fangzhi Zuo (1):
  drm/amd/display: Add DP 2.0 MST DC Support

 .../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 +-
 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 +
 drivers/gpu/drm/drm_dp_mst_topology.c |  42 ++-
 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 +-
 13 files changed, 423 insertions(+), 16 deletions(-)

-- 
2.31.1



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

2021-10-25 Thread Lyude Paul
From: 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 
Signed-off-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 86d13d6bc463..04ed34a7f71c 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -4334,10 +4334,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;
@@ -4540,7 +4536,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.31.1



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

2021-10-25 Thread Lyude Paul
From: 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

v5: (no functional changes)
* Fixed formatting in drm_dp_mst_update_slots()
* Reference mst_state instead of mst_state->mgr for debugging info

Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Fangzhi Zuo 
[v5 nitpicks]
Reviewed-by: Lyude Paul 
Signed-off-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 04ed34a7f71c..571da0c2f39f 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3355,6 +3355,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,
@@ -3365,12 +3369,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);
@@ -4505,6 +4509,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);
+}
+EXPORT_SYMBOL(drm_dp_mst_update_slots);
+
 /**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
@@ -5224,7 +5249,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 V

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

2021-10-25 Thread Lyude Paul
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 
Reviewed-by: "Lin, Wayne" 
Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Lyude Paul 
---
 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 da942e9f5142..782141ba8ac5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2356,6 +2356,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;
 
@@ -2741,6 +2746,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 ca5dc3c168ec..fd12561b70cc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3272,6 +3272,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] = {
@@ -3308,6 +3311,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
}
}
 
@@ -3430,6 +3436,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;
@@ -3457,7 +3467,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"
@@

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

2021-10-25 Thread Lyude Paul
From: Bhawanpreet Lakha 

[Why]
Add DP2 MST and debugfs support

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

Reviewed-by: "Lin, Wayne" 
Signed-off-by: Bhawanpreet Lakha 
Signed-off-by: Fangzhi Zuo 
Signed-off-by: Lyude Paul 
---
 .../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 f35561b5a465..ecdeeedb1cde 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10684,6 +10684,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);
 
@@ -10891,6 +10893,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 814f67d86a3c..3d44896149a2 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.31.1



2022 X.Org Board of Directors Elections Nomination period is NOW

2022-03-16 Thread Lyude Paul
The Board consists of directors elected from the membership.  Each year, an
election is held to bring the total number of directors to eight. The four
members receiving the highest vote totals will serve as directors for two year
terms.

The directors who received two year terms starting in 2021 were Lyude Paul,
Samuel Iglesias Gonsálvez, Manasi D Navare and Daniel Vetter. They will
continue to serve until their term ends in 2023. Current directors whose term
expires in 2022 are Emma Anholt, Keith Packard, Harry Wentland and Mark
Filion.

A director is expected to participate in the fortnightly IRC meeting to
discuss current business and to attend the annual meeting of the X.Org
Foundation, which will be held at a location determined in advance by the
Board of Directors.

A member may nominate themselves or any other member they feel is qualified.
Nominations should be sent to the Election Committee at elections at x.org.

Nominees shall be required to be current members of the X.Org Foundation, and
submit a personal statement of up to 200 words that will be provided to
prospective voters.  The collected statements, along with the statement of
contribution to the X.Org Foundation in the member's account page on
http://members.x.org, will be made available to all voters to help them make
their voting decisions.

Nominations, membership applications or renewals and completed personal
statements must be received no later than 23:59 UTC on 20th March 2022.

The slate of candidates will be published 28th March 2022 and candidate Q
will begin then. The deadline for Xorg membership applications and renewals is
31st March 2022.

Cheers,
   Lyude Paul, on behalf of the X.Org BoD



2022 X.Org Foundation Membership deadline for voting in the election

2022-03-16 Thread Lyude Paul
The 2022 X.Org Foundation elections are rapidly approaching. We will be
forwarding the election schedule and nominating process to the
membership shortly.

Please note that only current members can vote in the upcoming election,
and that the deadline for new memberships or renewals to vote in the
upcoming election is 31 March 2022 at 23:59 UTC.

If you are interested in joining the X.Org Foundation or in renewing
your membership, please visit the membership system site at:
https://members.x.org/

Lyude Paul, on behalf of the X.Org elections committee



Re: [PATCH] WIP: drm/dp_mst: Add support for dumping topology ref histories from debugfs

2022-03-15 Thread Lyude Paul
nected mst
> monitor will
> have us add new mst port to the topology and attach a new aconnector for
> that mst port,
> we'll try to create a new dc_sink to that new aconnector and break the
> sink_count
> limitation. As you can see in the log the error message : "*ERROR* Unable to
> add a
> remote sink"
> 
> (Note that different hub might influence the result. Some hubs will pull
> down the HPD
> when there is no monitor connected to its downstream ports which will run
> into different
> code flow)

by "pull down" I assume you mean doing a long HPD instead of short (or vice
versa?).

> 
> I also attach the dmesg log under different debug level (0x104 & 0x116) for
> your reference.
> 
> Please let me know if you can reproduce then : )
> 
> Sorry about that Lyude and hope this time I send to the right thread..
> Really appreciate for your help!!!
> 
> Regards,
> Wayne
> > -Original Message-
> > From: Lyude Paul 
> > Sent: Wednesday, March 2, 2022 9:10 AM
> > To: Lin, Wayne 
> > Subject: Re: [PATCH] WIP: drm/dp_mst: Add support for dumping topology ref
> > histories from debugfs
> > 
> > Ran into some issues with my system yesterday (hooray being the first to
> > find
> > a rather annoying zsh bug that broke my scripts!), but I've finally got
> > things
> > setup. I'm not able to reproduce this issue though (I've tried hotplugging
> > the
> > way you mentioned here, but nothing seems to leak), which makes me think
> > there's something special in your setup we might not have noticed.
> > 
> > Do you think you could get some drm logs with drm.debug=0x116
> > log_buf_len=50M
> > from when this happens so I can get a better idea of the drm events
> > leading up
> > to this? Also, if you've been testing this in a GUI could you confirm
> > whether
> > this happens when you're just in a plain old VT?
> > 
> > On Mon, 2022-02-28 at 16:43 -0500, Lyude Paul wrote:
> > > Alright - starting to look into this now and setting up a system to try
> > > reproducing this, will let you know as soon as I've got results. Sorry
> > > again
> > > about all of the delays
> > > 
> > > On Fri, 2022-02-25 at 15:47 -0500, Lyude Paul wrote:
> > > > I didn't get a chance yet, but I've gotten through most of my backlog
> > > > now.
> > > > Sorry about the delay - I've been catching up since I had to take two
> > > > weeks
> > > > off work very unexpectedly. I'll put aside time to look at this first
> > > > thing
> > > > monday.
> > > > 
> > > > On Fri, 2022-02-25 at 01:33 +, Lin, Wayne wrote:
> > > > > [AMD Official Use Only]
> > > > > 
> > > > > Hi Lyude,
> > > > > 
> > > > > Good day!
> > > > > Sorry to bother you, but would like to know if you can reproduce the
> > > > > issue?
> > > > > 
> > > > > Thanks!
> > > > > 
> > > > > Regards,
> > > > > Wayne
> > > > > 
> > > > > > -Original Message-
> > > > > > From: Lyude Paul 
> > > > > > Sent: Thursday, February 3, 2022 4:12 AM
> > > > > > To: Lin, Wayne 
> > > > > > Cc: dri-de...@lists.freedesktop.org
> > > > > > Subject: Re: [PATCH] WIP: drm/dp_mst: Add support for dumping
> > > > > > topology
> > > > > > ref
> > > > > > histories from debugfs
> > > > > > 
> > > > > > JFYI I should be able to respond to this soon, I think I'm
> > > > > > following
> > > > > > your
> > > > > > issue a bit more (haven't gotten to go through the patches too so
> > > > > > I'm
> > > > > > probably
> > > > > > going to see if I can reproduce it locally as well. Sorry for the
> > > > > > delay
> > > > > > -
> > > > > > dealing with some X.org stuff and work issues at the moment
> > > > > > 
> > > > > > On Tue, 2022-01-25 at 08:32 +, Lin, Wayne wrote:
> > > > > > > [Public]
> > > > > > > 
> > > > > > > Hey Lyude,
> > > > > > > 
> > > > > > > Sorry, just got chance to get back to this and BIG THANKS to
> > > > > > > elaborating
> > > > > > > in
> > > &

[Important!] 2022 X.Org Foundation Membership deadline for voting in the election

2022-02-17 Thread Lyude Paul
The 2022 X.Org Foundation elections are rapidly approaching. We will be
forwarding instructions on the nomination process to membership in the
near future.

Please note that only current members can vote in the upcoming election,
and that the deadline for new memberships or renewals to vote in the
upcoming election is March 17th 2022 at 23:59 UTC.

If you are interested in joining the X.Org Foundation or in renewing
your membership, please visit the membership system site at:

https://members.x.org/

You can find the current election schedule here:

https://www.x.org/wiki/BoardOfDirectors/Elections/2022/

Lyude Paul,
On behalf of the X.Org elections committee




2022 X.Org Board of Directors Elections Nomination period is NOW

2022-02-21 Thread Lyude Paul
We are seeking nominations for candidates for election to the X.Org Foundation
Board of Directors. All X.Org Foundation members are eligible for election to
the board.

Nominations for the 2022 election are now open and will remain open until
23:59 UTC on 06 March 2022.

The Board consists of directors elected from the membership. Each year, an
election is held to bring the total number of directors to eight. The four
members receiving the highest vote totals will serve as directors for two year
terms.

The directors who received two year terms starting in 2021 were Lyude Paul,
Samuel Iglesias Gonsálvez, Manasi D Navare and Daniel Vetter. They will
continue to serve until their term ends in 2023. Current directors whose term
expires in 2022 are Emma Anholt, Keith Packard, Harry Wentland and Mark
Filion.

A director is expected to participate in the fortnightly IRC meeting to
discuss current business and to attend the annual meeting of the X.Org
Foundation, which will be held at a location determined in advance by the
Board of Directors.

A member may nominate themselves or any other member they feel is qualified.
Nominations should be sent to the Election Committee at elections at x.org.

Nominees shall be required to be current members of the X.Org Foundation, and
submit a personal statement of up to 200 words that will be provided to
prospective voters. The collected statements, along with the statement of
contribution to the X.Org Foundation in the member's account page on
http://members.x.org, will be made available to all voters to help them make
their voting decisions.

Nominations, membership applications or renewals and completed personal
statements must be received no later than 23:59 UTC on 6th March 2022.

The slate of candidates will be published 14 March 2022 and candidate Q will
begin then. The deadline for Xorg membership applications and renewals is 17
March 2022.

Cheers, Lyude Paul, on behalf of the X.Org BoD




2022 X.Org Board of Directors Elections timeline extended, Request for nominations

2022-03-03 Thread Lyude Paul
We are seeking nominations for candidates for election to the X.org Foundation
Board of Directors. However, as we presently do not have enough nominations to
start the election - the decision has been made to extend the timeline by 2
weeks. Note this is a fairly regular part of the elections process.

The new deadline for nominations to the X.org Board of Directors is 23:59 UTC
on 20th March 2022.

The Board consists of directors elected from the membership.  Each year, an
election is held to bring the total number of directors to eight. The four
members receiving the highest vote totals will serve as directors for two year
terms.

The directors who received two year terms starting in 2021 were Lyude Paul,
Samuel Iglesias Gonsálvez, Manasi D Navare and Daniel Vetter. They will
continue to serve until their term ends in 2023. Current directors whose term
expires in 2022 are Emma Anholt, Keith Packard, Harry Wentland and Mark
Filion.

A director is expected to participate in the fortnightly IRC meeting to
discuss current business and to attend the annual meeting of the X.Org
Foundation, which will be held at a location determined in advance by the
Board of Directors.

A member may nominate themselves or any other member they feel is qualified.
Nominations should be sent to the Election Committee at elections at x.org.

Nominees shall be required to be current members of the X.Org Foundation, and
submit a personal statement of up to 200 words that will be provided to
prospective voters.  The collected statements, along with the statement of
contribution to the X.Org Foundation in the member's account page on
http://members.x.org, will be made available to all voters to help them make
their voting decisions.

Nominations, membership applications or renewals and completed personal
statements must be received no later than 23:59 UTC on 20th March 2022.

The slate of candidates will be published 28th March 2022 and candidate Q
will begin then. The deadline for Xorg membership applications and renewals is
31st March 2022.

Cheers,
   Lyude Paul, on behalf of the X.Org BoD



2022 X.org Foundation Election Candidates

2022-03-28 Thread Lyude Paul
To all X.Org Foundation Members:

The election for the X.Org Foundation Board of Directors will begin on 04 April
2022. We have 6 candidates who are running for 4 seats. They are:

Emma Anholt
Shashank Sharma
Ricardo Garcia
Mark Filion
Lucas Stach
Alyssa Rosenzweig

To be found in the link below below are the Personal Statements each candidate
submitted for your consideration along with their Statements of Contribution
that they submitted with the membership application. Please review each of the
candidates' statements to help you decide whom to vote for during the upcoming
election.

https://www.x.org/wiki/BoardOfDirectors/Elections/2022/

If you have questions of the candidates, you should feel free to ask them here
on the mailing list.

The election committee will provide detailed instructions on how the voting
system will work when the voting period begins.

Lyude Paul, on behalf of the X.Org elections committee



[Important!] 2022 X.Org Foundation Membership deadline for voting in the election

2022-02-04 Thread Lyude Paul
The 2022 X.Org Foundation elections are rapidly approaching. We will be
forwarding instructions on the nomination process to membership in the
near future.

Please note that only current members can vote in the upcoming election,
and that the deadline for new memberships or renewals to vote in the
upcoming election is March 17th 2022 at 23:59 UTC.

If you are interested in joining the X.Org Foundation or in renewing
your membership, please visit the membership system site at:

https://members.x.org/

You can find the current election schedule here:

https://www.x.org/wiki/BoardOfDirectors/Elections/2022/

    Lyude Paul,
    On behalf of the X.Org elections committee




[RFC] amdgpu MST questions, and future plans

2022-01-19 Thread Lyude Paul
Hi! I'm writing this email because I'm currently finishing up removing pretty
much all of the non-atomic MST code in drm_dp_mst_topology_mgr.c as it's
really made it difficult to maintain MST over time. As well, once that's
complete it's likely I'm going to start on the (extremely overdue) task of
moving as much of amdgpu's MST code for DSC out of amdgpu and into the DRM
code where it's supposed to live.

This brings me to two questions. The first major one being: is anyone capable
of testing the MST support in radeon.ko to figure out whether it works or not?
I've already talked with hwentlan and ag5df about this and they haven't been
able to find anyone to help with testing this. The reason I ask is because
radeon isn't an atomic driver, and is basically the only user of any of the
non-atomic parts of the MST helpers. If anyone want to prevent this from
breaking in the future, I would definitely recommend they step up to try and
help with testing it - otherwise I'm probably going to be pushing for us just
to drop the code entirely.

The second question is: is anyone willing to help me figure out how much of
the code in amdgpu related to DSC is definitely not amdgpu specific and can be
moved out? I'm honestly having a lot of trouble wrapping my head around how
some of this works, and how much of this code is even needed. As well, with
the amount of issues I've already found in it (there's numerous spots where
we're storing MST state outside of atomic state for instance, lots of
duplicates of DP helper functions that should not be here, etc.) it's quite
likely I'm going to be rewriting rather large chunks of it. If anyone would
like to volunteer please let me know, it'd be super appreciated and likely
will make reviewing the patches that will come out of this easier.
-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [RFC] amdgpu MST questions, and future plans

2022-01-19 Thread Lyude Paul
On Wed, 2022-01-19 at 17:56 -0500, Lyude Paul wrote:
> Hi! I'm writing this email because I'm currently finishing up removing
> pretty
> much all of the non-atomic MST code in drm_dp_mst_topology_mgr.c as it's
> really made it difficult to maintain MST over time. As well, once that's
> complete it's likely I'm going to start on the (extremely overdue) task of
> moving as much of amdgpu's MST code for DSC out of amdgpu and into the DRM
> code where it's supposed to live.
> 
> This brings me to two questions. The first major one being: is anyone
> capable
> of testing the MST support in radeon.ko to figure out whether it works or
> not?
> I've already talked with hwentlan and ag5df about this and they haven't been
> able to find anyone to help with testing this. The reason I ask is because
> radeon isn't an atomic driver, and is basically the only user of any of the
> non-atomic parts of the MST helpers. If anyone want to prevent this from
> breaking in the future, I would definitely recommend they step up to try and
> help with testing it - otherwise I'm probably going to be pushing for us
> just
> to drop the code entirely.
> 
> The second question is: is anyone willing to help me figure out how much of
> the code in amdgpu related to DSC is definitely not amdgpu specific and can
> be
> moved out? I'm honestly having a lot of trouble wrapping my head around how
> some of this works, and how much of this code is even needed. As well, with
> the amount of issues I've already found in it (there's numerous spots where
> we're storing MST state outside of atomic state for instance, lots of
> duplicates of DP helper functions that should not be here, etc.) it's quite
> likely I'm going to be rewriting rather large chunks of it. If anyone would

mhhh - on second thought I think I'm starting to wrap my head around this and
it's not actually too bad :), still could use some help with the radeon
testing though!

> like to volunteer please let me know, it'd be super appreciated and likely
> will make reviewing the patches that will come out of this easier.

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



Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload allocation/removement

2023-08-31 Thread Lyude Paul
On Thu, 2023-08-24 at 04:12 +, Lin, Wayne wrote:
> [Public]
> 
> Hi Lyude,
> 
> I'm afraid that I don't have the permissions to push and would like to have
> your help. Thanks!

Whoops, sorry I only just noticed this message. I set a reminder on my phone
to bug me to push it tomorrow :), sorry about the delay

> 
> > -Original Message-
> > From: Lyude Paul 
> > Sent: Thursday, August 24, 2023 5:00 AM
> > To: Lin, Wayne ; dri-de...@lists.freedesktop.org;
> > amd-gfx@lists.freedesktop.org
> > Cc: jani.nik...@intel.com; ville.syrj...@linux.intel.com; 
> > imre.d...@intel.com;
> > Wentland, Harry ; Zuo, Jerry
> > 
> > Subject: Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload
> > allocation/removement
> > 
> > Sure - you're also welcome to push the first two patches after fixing the
> > indentation if you'd like
> > 
> > On Wed, 2023-08-23 at 03:19 +, Lin, Wayne wrote:
> > > [Public]
> > > 
> > > Thanks, Lyude!
> > > Should I push another version to fix the indention?
> > > 
> > > > -Original Message-
> > > > From: Lyude Paul 
> > > > Sent: Friday, August 18, 2023 6:17 AM
> > > > To: Lin, Wayne ; dri-de...@lists.freedesktop.org;
> > > > amd-gfx@lists.freedesktop.org
> > > > Cc: jani.nik...@intel.com; ville.syrj...@linux.intel.com;
> > > > imre.d...@intel.com; Wentland, Harry ; Zuo,
> > > > Jerry 
> > > > Subject: Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload
> > > > allocation/removement
> > > > 
> > > > Two small comments:
> > > > 
> > > > On Mon, 2023-08-07 at 10:56 +0800, Wayne Lin wrote:
> > > > > [Why]
> > > > > Today, the allocation/deallocation steps and status is a bit unclear.
> > > > > 
> > > > > For instance, payload->vc_start_slot = -1 stands for "the failure
> > > > > of updating DPCD payload ID table" and can also represent as
> > > > > "payload is not allocated yet". These two cases should be handled
> > > > > differently and hence better to distinguish them for better 
> > > > > understanding.
> > > > > 
> > > > > [How]
> > > > > Define enumeration - ALLOCATION_LOCAL, ALLOCATION_DFP and
> > > > > ALLOCATION_REMOTE to distinguish different allocation status.
> > > > > Adjust the code to handle different status accordingly for better
> > > > > understanding the sequence of payload allocation and payload
> > > > removement.
> > > > > 
> > > > > For payload creation, the procedure should look like this:
> > > > > DRM part 1:
> > > > > * step 1 - update sw mst mgr variables to add a new payload
> > > > > * step 2 - add payload at immediate DFP DPCD payload table
> > > > > 
> > > > > Driver:
> > > > > * Add new payload in HW and sync up with DFP by sending ACT
> > > > > 
> > > > > DRM Part 2:
> > > > > * Send ALLOCATE_PAYLOAD sideband message to allocate bandwidth
> > > > > along
> > > > the
> > > > >   virtual channel.
> > > > > 
> > > > > And as for payload removement, the procedure should look like this:
> > > > > DRM part 1:
> > > > > * step 1 - Send ALLOCATE_PAYLOAD sideband message to release
> > bandwidth
> > > > >along the virtual channel
> > > > > * step 2 - Clear payload allocation at immediate DFP DPCD payload
> > > > > table
> > > > > 
> > > > > Driver:
> > > > > * Remove the payload in HW and sync up with DFP by sending ACT
> > > > > 
> > > > > DRM part 2:
> > > > > * update sw mst mgr variables to remove the payload
> > > > > 
> > > > > Note that it's fine to fail when communicate with the branch
> > > > > device connected at immediate downstrean-facing port, but updating
> > > > > variables of SW mst mgr and HW configuration should be conducted
> > > > > anyway. That's because it's under commit_tail and we need to
> > > > > complete the HW
> > > > programming.
> > > > > 
> > > > > Changes since v1:
> > > > > * Remove the set but not use variable 'old_payload' in function
> > > > >   'nv50_msto_prepare'.

Re: [PATCH 5/9] drm/nouveau/pm: Annotate struct nvkm_perfdom with __counted_by

2023-09-22 Thread Lyude Paul
Reviewed-by: Lyude Paul 

Thanks!

On Fri, 2023-09-22 at 10:32 -0700, Kees Cook wrote:
> Prepare for the coming implementation by GCC and Clang of the __counted_by
> attribute. Flexible array members annotated with __counted_by can have
> their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS
> (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
> functions).
> 
> As found with Coccinelle[1], add __counted_by for struct nvkm_perfdom.
> 
> [1] 
> https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci
> 
> Cc: Ben Skeggs 
> Cc: Karol Herbst 
> Cc: Lyude Paul 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: dri-de...@lists.freedesktop.org
> Cc: nouv...@lists.freedesktop.org
> Signed-off-by: Kees Cook 
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h 
> b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h
> index 6ae25d3e7f45..c011227f7052 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h
> @@ -82,7 +82,7 @@ struct nvkm_perfdom {
>   u8  mode;
>   u32 clk;
>   u16 signal_nr;
> - struct nvkm_perfsig signal[];
> + struct nvkm_perfsig signal[] __counted_by(signal_nr);
>  };
>  
>  struct nvkm_funcdom {

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



Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload allocation/removement

2023-08-17 Thread Lyude Paul
  drm_dp_destroy_payload_step1(mgr, mst_state, new_payload);
> + drm_dp_destroy_payload_at_remote_and_dfp(mgr, mst_state, 
> payload);
>   else
>   drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not 
> sending remove\n",
> - new_payload->vcpi);
> + payload->vcpi);
> +
> + payload->payload_allocation_status = 
> DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL;
> +}
> +EXPORT_SYMBOL(drm_dp_remove_payload_part1);
>  
> +/**
> + * drm_dp_remove_payload_part2() - Remove an MST payload locally
> + * @mgr: Manager to use.
> + * @mst_state: The MST atomic state
> + * @old_payload: The payload with its old state
> + * @new_payload: The payload with its latest state
> + *
> + * Updates the starting time slots of all other payloads which would have 
> been shifted towards
> + * the start of the payload ID table as a result of removing a payload. 
> Driver should call this
> + * function whenever it removes a payload in its HW. It's independent to the 
> result of payload
> + * allocation/deallocation at branch devices along the virtual channel.
> + */
> +void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
> +  struct drm_dp_mst_topology_state *mst_state,
> +  const struct drm_dp_mst_atomic_payload 
> *old_payload,
> +  struct drm_dp_mst_atomic_payload *new_payload)
> +{
> + struct drm_dp_mst_atomic_payload *pos;
> +
> + /* Remove local payload allocation */
>   list_for_each_entry(pos, _state->payloads, next) {
>   if (pos != new_payload && pos->vc_start_slot > 
> new_payload->vc_start_slot)
>   pos->vc_start_slot -= old_payload->time_slots;
> @@ -3382,9 +3409,10 @@ void drm_dp_remove_payload(struct 
> drm_dp_mst_topology_mgr *mgr,
>  
>   if (new_payload->delete)
>   drm_dp_mst_put_port_malloc(new_payload->port);
> -}
> -EXPORT_SYMBOL(drm_dp_remove_payload);
>  
> + new_payload->payload_allocation_status = 
> DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> +}
> +EXPORT_SYMBOL(drm_dp_remove_payload_part2);
>  /**
>   * drm_dp_add_payload_part2() - Execute payload update part 2
>   * @mgr: Manager to use.
> @@ -3403,17 +3431,19 @@ int drm_dp_add_payload_part2(struct 
> drm_dp_mst_topology_mgr *mgr,
>   int ret = 0;
>  
>   /* Skip failed payloads */
> - if (payload->vc_start_slot == -1) {
> - drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s 
> failed, skipping part 2\n",
> + if (payload->payload_allocation_status != 
> DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) {
> + drm_dbg_kms(state->dev, "Part 1 of payload creation for %s 
> failed, skipping part 2\n",
>   payload->port->connector->name);
>   return -EIO;
>   }
>  
> - ret = drm_dp_create_payload_step2(mgr, payload);
> - if (ret < 0) {
> + /* Allocate payload to remote end */
> + ret = drm_dp_create_payload_to_remote(mgr, payload);
> + if (ret < 0)
>   drm_err(mgr->dev, "Step 2 of creating MST payload for %p 
> failed: %d\n",
>   payload->port, ret);
> - }
> + else
> + payload->payload_allocation_status = 
> DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE;
>  
>   return ret;
>  }
> @@ -4324,6 +4354,7 @@ int drm_dp_atomic_find_time_slots(struct 
> drm_atomic_state *state,
>   drm_dp_mst_get_port_malloc(port);
>   payload->port = port;
>   payload->vc_start_slot = -1;
> + payload->payload_allocation_status = 
> DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
>   list_add(>next, _state->payloads);
>   }
>   payload->time_slots = req_slots;
> @@ -4493,7 +4524,7 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct 
> drm_atomic_state *state)
>   }
>  
>   /* Now that previous state is committed, it's safe to copy over 
> the start slot
> -  * assignments
> +  * and allocation status assignments
>*/
>   list_for_each_entry(old_payload, _mst_state->payloads, 
> next) {
>   if (old_payload->delete)
> @@ -4502,6 +4533,8 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct 
> drm_atomic_state *state)
>   new_payload = 
> drm_atomic_get_mst_payload_state(new_mst_state,
>   

Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload allocation/removement

2023-08-23 Thread Lyude Paul
Sure - you're also welcome to push the first two patches after fixing the
indentation if you'd like

On Wed, 2023-08-23 at 03:19 +, Lin, Wayne wrote:
> [Public]
> 
> Thanks, Lyude!
> Should I push another version to fix the indention?
> 
> > -Original Message-
> > From: Lyude Paul 
> > Sent: Friday, August 18, 2023 6:17 AM
> > To: Lin, Wayne ; dri-de...@lists.freedesktop.org;
> > amd-gfx@lists.freedesktop.org
> > Cc: jani.nik...@intel.com; ville.syrj...@linux.intel.com; 
> > imre.d...@intel.com;
> > Wentland, Harry ; Zuo, Jerry
> > 
> > Subject: Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload
> > allocation/removement
> > 
> > Two small comments:
> > 
> > On Mon, 2023-08-07 at 10:56 +0800, Wayne Lin wrote:
> > > [Why]
> > > Today, the allocation/deallocation steps and status is a bit unclear.
> > > 
> > > For instance, payload->vc_start_slot = -1 stands for "the failure of
> > > updating DPCD payload ID table" and can also represent as "payload is
> > > not allocated yet". These two cases should be handled differently and
> > > hence better to distinguish them for better understanding.
> > > 
> > > [How]
> > > Define enumeration - ALLOCATION_LOCAL, ALLOCATION_DFP and
> > > ALLOCATION_REMOTE to distinguish different allocation status. Adjust
> > > the code to handle different status accordingly for better
> > > understanding the sequence of payload allocation and payload
> > removement.
> > > 
> > > For payload creation, the procedure should look like this:
> > > DRM part 1:
> > > * step 1 - update sw mst mgr variables to add a new payload
> > > * step 2 - add payload at immediate DFP DPCD payload table
> > > 
> > > Driver:
> > > * Add new payload in HW and sync up with DFP by sending ACT
> > > 
> > > DRM Part 2:
> > > * Send ALLOCATE_PAYLOAD sideband message to allocate bandwidth along
> > the
> > >   virtual channel.
> > > 
> > > And as for payload removement, the procedure should look like this:
> > > DRM part 1:
> > > * step 1 - Send ALLOCATE_PAYLOAD sideband message to release bandwidth
> > >along the virtual channel
> > > * step 2 - Clear payload allocation at immediate DFP DPCD payload
> > > table
> > > 
> > > Driver:
> > > * Remove the payload in HW and sync up with DFP by sending ACT
> > > 
> > > DRM part 2:
> > > * update sw mst mgr variables to remove the payload
> > > 
> > > Note that it's fine to fail when communicate with the branch device
> > > connected at immediate downstrean-facing port, but updating variables
> > > of SW mst mgr and HW configuration should be conducted anyway. That's
> > > because it's under commit_tail and we need to complete the HW
> > programming.
> > > 
> > > Changes since v1:
> > > * Remove the set but not use variable 'old_payload' in function
> > >   'nv50_msto_prepare'. Catched by kernel test robot 
> > > 
> > > Signed-off-by: Wayne Lin 
> > > ---
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  20 ++-
> > > drivers/gpu/drm/display/drm_dp_mst_topology.c | 159 +++--
> > -
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  18 +-
> > >  drivers/gpu/drm/nouveau/dispnv50/disp.c   |  21 +--
> > >  include/drm/display/drm_dp_mst_helper.h   |  23 ++-
> > >  5 files changed, 153 insertions(+), 88 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 d9a482908380..9ad509279b0a 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,7 +219,7 @@ static void dm_helpers_construct_old_payload(
> > > /* Set correct time_slots/PBN of old payload.
> > >  * other fields (delete & dsc_enabled) in
> > >  * struct drm_dp_mst_atomic_payload are don't care fields
> > > -* while calling drm_dp_remove_payload()
> > > +* while calling drm_dp_remove_payload_part2()
> > >  */
> > > for (i = 0; i < current_link_table.stream_count; i++) {
> > > dc_alloc =
> > > @@ -262,13 +262,12 @@ bool
> > > dm_helpers_dp_mst_write_payload_allocation_table(
> >

Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()

2023-08-17 Thread Lyude Paul
 we can also simplify some codes. Especially remove
> > workaround in amd driver. In fact, DRM mst code maintains the payload
> > table and all the time slot info is in it already. We don't really
> > have to pass a new parameter.
> 
> I agree that drm_dp_remove_payload() could be simplified, but this
> should be done so that the drivers can pass the old payload state to it
> (without having to pass the new state). This would be possible if
> vc_start_slot was not tracked in the payload state (which is really not
> an atomic state that can be precomputed as all other atomic state),
> rather it would be tracked in struct drm_dp_mst_topology_mgr.

JFYI too  - I think I'm fine with us moving vc_start_slot elsewhere at this
point ;)

> 
> It looks like AMD has to reconstruct the old state in
> dm_helpers_construct_old_payload(). Could you explain why it couldn't
> instead just pass old_payload acquired by
> 
> old_mst_state = drm_atomic_get_old_mst_topology_state();
> old_payload = drm_atomic_get_mst_payload_state(old_mst_state);
> 
> ?
> 
> > > > /* Remove local payload allocation */
> > > > list_for_each_entry(pos, _state->payloads, next) {
> > > > -   if (pos != new_payload && pos->vc_start_slot > new_payload-
> > > > vc_start_slot)
> > > > -   pos->vc_start_slot -= old_payload->time_slots;
> > > > +   if (pos != payload && pos->vc_start_slot > payload-
> > > > vc_start_slot)
> > > > +   pos->vc_start_slot -= time_slots_to_remove;
> > > > }
> > > > -   new_payload->vc_start_slot = -1;
> > > > +   payload->vc_start_slot = -1;
> > > > 
> > > > mgr->payload_count--;
> > > > -   mgr->next_start_slot -= old_payload->time_slots;
> > > > +   mgr->next_start_slot -= time_slots_to_remove;
> > > > 
> > > > -   if (new_payload->delete)
> > > > -   drm_dp_mst_put_port_malloc(new_payload->port);
> > > > +   if (payload->delete)
> > > > +   drm_dp_mst_put_port_malloc(payload->port);
> > > > 
> > > > -   new_payload->payload_allocation_status =
> > > DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > > +   payload->payload_allocation_status =
> > > > +DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;
> > > >  }
> > 
> > --
> > Regards,
> > Wayne
> 

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



Re: [PATCH] WIP: drm/dp_mst: Add support for dumping topology ref histories from debugfs

2022-04-20 Thread Lyude Paul
Hey! Figured I'd check if there's been any status updates here since it's been
a while, just to make sure I haven't dropped this issue from my radar. No
problem if you're busy :)

On Wed, 2022-03-16 at 10:46 +, Lin, Wayne wrote:
> [Public]
> 
> > -Original Message-
> > From: Lyude Paul 
> > Sent: Wednesday, March 16, 2022 8:48 AM
> > To: Lin, Wayne 
> > Cc: dri-de...@lists.freedesktop.org; amd-gfx@lists.freedesktop.org
> > Subject: Re: [PATCH] WIP: drm/dp_mst: Add support for dumping topology ref
> > histories from debugfs
> > 
> > (Adding this back to the dri-devel mailing list since I didn't notice it
> > got
> > dropped from there)
> > 
> > Hm, some comments on this issue down below. Sorry for the delayed
> > response, I
> > was going to try this right after I finished the MST legacy removal but
> > that's
> > ending up taking longer than I hoped.
> > 
> > On Tue, 2022-03-08 at 01:46 +, Lin, Wayne wrote:
> > > [AMD Official Use Only]
> > > 
> > > Oops...
> > > I didn't notice that I replied to wrong mail previously : P
> > > Sorry for the confusion and reply to the correct thread.
> > > 
> > > Good day!
> > > I probably know why you can't reproduce the issue there. Please refer to
> > > the
> > > attached
> > > patch file which makes me easier to explain this.
> > > 
> > > In dm_dp_mst_get_modes(), we will create a new dc_sink by calling
> > > dc_link_add_remote_sink() and add that dc_sink into the array dc_link-
> > > > remote_sinks[].
> > > However, if we find that aconnector->dc_sink is not null, then we won't
> > > create a new
> > > dc_sink for that aconnector and won't add the sink to the array dc_link-
> > > > remote_sinks[].
> > > 
> > > When the issue that I mentioned before occurs, we won't be able to
> > > release
> > > the dc_sink
> > > for the aconnector when we unplug the sst monitor. Hence, we can't
> > > create
> > > new dc_sink
> > > for the latter on connected new stream sink of that port. Which leads to
> > > two
> > > issues
> > > 1. Unplug monitor and plug in another monitor "to the same port"
> > > =>  Since we use the same dc_sink to reflect the capability of the new
> > > connected stream
> > > sink, we might send out inappropriate stream to the new connected sink.
> > > 2. Because we can't release dc_sink in the array dc_link-
> > > >remote_sinks[],
> > > when we
> > > plug/unplug sst monitor to more than 4 different mst port, we will break
> > > the
> > > criteria
> > > "dc_link->sink_count >= MAX_SINKS_PER_LINK" in
> > > link_add_remote_sink_helper().
> > 
> > Ok, a lot of this seems to be happening in amdgpu which certainly explains
> > why
> > I had so much trouble following along with this originally (also, having
> > learned a bit more about how DC works definitely has helped a bit). I
> > already
> > see a bunch of issues though with how this code is structured that would
> > definitely break things, though note I haven't sat down and tried this on
> > a
> > real machine yet - will try tomorrow.
> > 
> > So - it seems like dc_sink == a bunch of hotplugging state for a dm
> > connector,
> > which actually tells me for one that this is definitely the wrong spot for
> > this code. get_modes() really should just handle filling out DRM modes and
> > pretty much nothing else, because callers from DRM aren't going to expect
> > side-effects like this when get_modes() is called - which could
> > potentially
> > lead to all sorts of weirdness down the line if the DRM call paths that
> > use
> > this ever change. i915 and nouveau have good examples of what these
> > functions
> > should typically look like, and amdgpu actually seems to mostly follow
> > this
> > advice for it's other get_modes() callback.
> > 
> > Note there's also another problem here: the assumption "no EDID ==
> > disconnected" isn't correct. It's totally possible to run into EDID-less
> > displays if the display is some ancient pre-historic relic, or if the ROM
> > (or
> > EEPROM? can't remember what type of chip computer displays tend to use...)
> > chip
> > in the monitor containing the EDID has died. Note that the second
> > situation is
> > suprisingly more common then one might think! I ran into a 140Hz 4k ASUS
> > display where this happened, and 

2022 X.Org Foundation Election vote results

2022-04-19 Thread Lyude Paul
The Board of Directors election and the vote on the By-laws concluded at
23:59 UTC on 18 April 2022. There are 80 current Members of the X.Org
Foundation, and 52 Members cast votes. This is a 65.0% turn out.

In the election of the Directors to the Board of the X.Org Foundation,
the results were that Emma Anholt, Alyssa Rosenzweig, Mark Filion and
Ricardo Garcia were elected for two year terms.

The old full board is: Emma Anholt, Samuel Iglesias Gonsálvez, Mark
Filion, Manasi D Navare, Keith Packard, Lyude Paul, Daniel Vetter, Harry
Wentland

The new full board is: Emma Anholt, Samuel Iglesias Gonsálvez, Mark
Filion, Manasi D Navare, Alyssa Rosenzweig, Lyude Paul, Daniel Vetter,
and Ricardo Garcia

The full election results were as follows:

   Option | Rank 1 | Rank 2 | Rank 3 | Rank 4 | Rank 5 | Rank 6 | Final 
Score
  Emma Anholt | 21 | 16 |  4 |  1 |  5 |  5 |   
  240
Alyssa Rosenzweig |  4 | 10 | 17 |  7 | 11 |  3 |   
  188
  Mark Filion |  8 | 12 |  7 | 10 |  5 | 10 |   
  186
   Ricardo Garcia |  9 |  4 |  5 | 17 | 10 |  7 |   
  172
  Lucas Stach |  4 |  5 | 14 |  9 | 11 |  9 |   
  163
  Shashank Sharma |  6 |  5 |  5 |  8 | 10 | 18 |   
  143

Lyude Paul, on behalf of the X.Org elections committee



XDC 2022: Registration & Call for Proposals now open!

2022-04-26 Thread Lyude Paul
Hello!

The 2022 X.Org Developers Conference is being held in conjunction with
the 2022 Wine Developers Conference.  This is a meeting to bring
together developers working on all things open graphics (Linux kernel,
Mesa, DRM, Wayland, X11, etc.) as well as developers for the Wine
Project, a key consumer of open graphics.

Registration & Call for Proposals are now open for both XDC 2022 and
WineConf 2022, which will take place on October 4-6, 2022 in
Minneapolis, Minnesota, USA. 

https://xdc2022.x.org
 
As usual, the conference is free of charge and open to the general
public. If you plan on attending, please make sure to register as early
as possible!
 
In order to register as attendee, you will therefore need to do it via
the XDC website:
 
https://indico.freedesktop.org/event/2/registrations/2/
 
In addition to registration, the CfP is now open for talks, workshops
and demos at XDC 2022. While any serious proposal will be gratefully
considered, topics of interest to X.Org and freedesktop.org developers
are encouraged. The program focus is on new development, ongoing
challenges and anything else that will spark discussions among
attendees in the hallway track.
 
We are open to talks across all layers of the graphics stack, from the
kernel to desktop environments / graphical applications and about how
to make things better for the developers who build them. Head to the
CfP page to learn more: 
 
https://indico.freedesktop.org/event/2/abstracts/
 
The deadline for submissions is Monday July 4th, 2022.
 
Check out our Reimbursement Policy to accept speaker
expenses for X.Org events like XDC 2022:
 
https://www.x.org/wiki/XorgFoundation/Policies/Reimbursement/

If you have any questions, please send me an email to
x...@codeweavers.com, adding on CC the X.org board (board
at foundation.x.org).
 
And don't forget, you can follow us on Twitter for all the latest
updates and to stay connected:
 
https://twitter.com/XOrgDevConf

Best regards,
Lyude Paul, on behalf of X.org



Requests For Proposals for hosting XDC 2023 are now open

2022-04-26 Thread Lyude Paul
Hello everyone!

The X.org board is soliciting proposals to host XDC in 2023. Since
XDC 2022 is being held in North America this year, XDC 2023 is expected
to be in Europe. However, the board is open to other locations,
especially if there's an interesting co-location with another
conference.

If you're considering hosting XDC, we've assembled a wiki page with
what's generally expected and needed:

https://www.x.org/wiki/Events/RFP/

When submitting your proposal, please make sure to include at least the
key information about the potential location in question, possible
dates along with estimated costs. Proposals can be submitted to board
at foundation.x.org until the deadline of *September 1st, 2022*. 

Additionally, an quirk early heads-up to the board if you're
considering hosting would be appreciated, in case we need to adjust the
schedule a bit. Also, earlier is better since there generally will be a
bit of Q with organizers.

And if you just have some questions about what organizing XDC entails,
please feel free to chat with previous organizers, or someone from the
board.

Best regards,
Lyude Paul
On behalf of X.org



Re: [PATCH 0/3] Fix issues when unplung monitor under mst scenario

2022-05-17 Thread Lyude Paul
I will try to take a look at this during this week btw

On Tue, 2022-05-10 at 17:56 +0800, Wayne Lin wrote:
> This patch set is trying to resolve issues observed when unplug monitors
> under mst scenario. Revert few commits which cause side effects and seems
> no longer needed. And propose a patch to address the issue discussed
> within the thread:
> https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg396300.html
> 
> ---
> 
> Wayne Lin (3):
>   Revert "drm/amd/display: Add flag to detect dpms force off during HPD"
>   Revert "drm/amd/display: turn DPMS off on connector unplug"
>   drm/amd/display: Release remote dc_sink under mst scenario
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 +++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
>  .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c    | 16 ++
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 18 +--
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 39 +--
>  drivers/gpu/drm/amd/display/dc/core/dc.c  | 13 -
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  1 -
>  7 files changed, 46 insertions(+), 92 deletions(-)
> 

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



Re: [PATCH 05/14] drm/nouveau: Don't register backlight when another backlight should be used

2022-05-18 Thread Lyude Paul
Reviewed-by: Lyude Paul 

Also, ack on this being pushed to drm-misc, along with any other patches I r-b

On Tue, 2022-05-17 at 17:23 +0200, Hans de Goede wrote:
> Before this commit when we want userspace to use the acpi_video backlight
> device we register both the GPU's native backlight device and acpi_video's
> firmware acpi_video# backlight device. This relies on userspace preferring
> firmware type backlight devices over native ones.
> 
> Registering 2 backlight devices for a single display really is
> undesirable, don't register the GPU's native backlight device when
> another backlight device should be used.
> 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> index daf9f87477ba..f56ff797c78c 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> @@ -34,6 +34,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #include "nouveau_drv.h"
>  #include "nouveau_reg.h"
>  #include "nouveau_encoder.h"
> @@ -404,6 +406,11 @@ nouveau_backlight_init(struct drm_connector *connector)
> goto fail_alloc;
> }
>  
> +   if (acpi_video_get_backlight_type(true) != acpi_backlight_native) {
> +   NV_INFO(drm, "Skipping nv_backlight registration\n");
> +   goto fail_alloc;
> +   }
> +
> if (!nouveau_get_backlight_name(backlight_name, bl)) {
>     NV_ERROR(drm, "Failed to retrieve a unique name for the
> backlight interface\n");
> goto fail_alloc;

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



Re: [PATCH 12/14] drm/nouveau: Register ACPI video backlight when nv_backlight registration fails

2022-05-18 Thread Lyude Paul
On Tue, 2022-05-17 at 17:23 +0200, Hans de Goede wrote:
> Typically the acpi_video driver will initialize before nouveau, which
> used to cause /sys/class/backlight/acpi_video0 to get registered and then
> nouveau would register its own nv_backlight device later. After which
> the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
> to avoid there being 2 backlight devices.
> 
> This means that userspace used to briefly see 2 devices and the
> disappearing of acpi_video0 after a brief time confuses the systemd
> backlight level save/restore code, see e.g.:
> https://bbs.archlinux.org/viewtopic.php?id=269920
> 
> To fix this the ACPI video code has been modified to make backlight class
> device registration a separate step, relying on the drm/kms driver to
> ask for the acpi_video backlight registration after it is done setting up
> its native backlight device.
> 
> Add a call to the new acpi_video_register_backlight() when native backlight
> device registration has failed / was skipped to ensure that there is a
> backlight device available before the drm_device gets registered with
> userspace.
> 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> index f56ff797c78c..0ae8793357a4 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> @@ -436,6 +436,13 @@ nouveau_backlight_init(struct drm_connector *connector)
>  
>  fail_alloc:
> kfree(bl);
> +   /*
> +    * If we get here we have an internal panel, but no nv_backlight,
> +    * try registering an ACPI video backlight device instead.
> +    */
> +   if (ret == 0)
> +   acpi_video_register_backlight();

Assuming we don't need to return the value of acpi_video_register_backlight()
here:

Reviewed-by: Lyude Paul 

> +
> return ret;
>  }
>  

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



Re: [PATCH 0/3] Fix issues when unplung monitor under mst scenario

2022-05-31 Thread Lyude Paul
For the whole series:

Acked-by: Lyude Paul 

This looks a lot better for sure :)

On Tue, 2022-05-10 at 17:56 +0800, Wayne Lin wrote:
> This patch set is trying to resolve issues observed when unplug monitors
> under mst scenario. Revert few commits which cause side effects and seems
> no longer needed. And propose a patch to address the issue discussed
> within the thread:
> https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg396300.html
> 
> ---
> 
> Wayne Lin (3):
>   Revert "drm/amd/display: Add flag to detect dpms force off during HPD"
>   Revert "drm/amd/display: turn DPMS off on connector unplug"
>   drm/amd/display: Release remote dc_sink under mst scenario
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 +++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
>  .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c    | 16 ++
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 18 +--
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 39 +--
>  drivers/gpu/drm/amd/display/dc/core/dc.c  | 13 -
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  1 -
>  7 files changed, 46 insertions(+), 92 deletions(-)
> 

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



[PATCH 3/3] drm/amdgpu/dm: Drop != NULL check in dm_mst_get_pbn_divider()

2022-06-02 Thread Lyude Paul
A lot of code in amdgpu seems to sprinkle in

  if (foo != NULL)
…

Checks pretty much all over the place, many times in locations where it's
clear foo (whatever foo may be) should never be NULL unless we've run into
a programming error. This is definitely one of those places, as
dm_mst_get_pbn_divider() should never be getting called with a NULL dc_link
pointer.

The problem with this code pattern is that many times the places I've seen
it used in amdgpu have no real error handling. This is actually quite bad,
if we try to avoid the NULL pointer and instead simply skip any code that
was expecting a valid pointer - we're already in undefined territory.
Subsequent code we execute may have expected sideaffects from the code we
skipped that are no longer present, which leads to even more unpredictable
behavior then a simple segfault. This could be silent errors or even just
another segfault somewhere else.

If we simply segfault though, that's not good either. But unlike the former
solution, no subsequent code in the kernel thread will execute - and we
will likely even get a clear backtrace from the invalid memory access. Of
course, the preferred approach is to simply handle the possibility of both
NULL and non-NULL pointers with nice error handling code. However, that's
not always desirable or even possible, and in those cases it's likely just
better to fail predictably rather than unpredictably.

This code is a nice example of that - if link is NULL, you'll return a PBN
divisor of 0. And thus, you've simply traded in your potential segfault for
a potential divide by 0 error. This was something I actually managed to hit
while working on the legacy MST removal work.

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 1259f2f7a8f9..35c7def8f2bd 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -537,9 +537,6 @@ void amdgpu_dm_initialize_dp_connector(struct 
amdgpu_display_manager *dm,
 
 int dm_mst_get_pbn_divider(struct dc_link *link)
 {
-   if (!link)
-   return 0;
-
return dc_link_bandwidth_kbps(link,
dc_link_get_link_cap(link)) / (8 * 1000 * 54);
 }
-- 
2.35.3



[PATCH 1/3] drm/amdgpu/dm/mst: Stop grabbing mst_mgr->lock in compute_mst_dsc_configs_for_state()

2022-06-02 Thread Lyude Paul
Noticed this while trying to update amdgpu for the non-atomic MST removal
changes - for some reason we appear to grab mst_mgr->lock before computing
mst DSC configs. This is wrong though - mst_mgr->lock is only needed while
traversing the actual MST topology state - which is not typically something
that DRM drivers should be doing themselves anyway.

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 9221b6690a4a..cb3b0e08acc4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -1056,13 +1056,10 @@ bool compute_mst_dsc_configs_for_state(struct 
drm_atomic_state *state,
if (!is_dsc_need_re_compute(state, dc_state, stream->link))
continue;
 
-   mutex_lock(>mst_mgr.lock);
if (!compute_mst_dsc_configs_for_link(state, dc_state, 
stream->link,
vars, _vars_start_index)) {
-   mutex_unlock(>mst_mgr.lock);
return false;
}
-   mutex_unlock(>mst_mgr.lock);
 
for (j = 0; j < dc_state->stream_count; j++) {
if (dc_state->streams[j]->link == stream->link)
-- 
2.35.3



[PATCH 2/3] drm/amdgpu/dm/mst: Stop grabbing mst_mgr->lock in pre_compute_mst_dsc_configs_for_state()

2022-06-02 Thread Lyude Paul
This lock is only needed if you're iterating through the in-memory topology
(e.g. drm_dp_mst_branch->ports, drm_dp_mst_port->mstb, etc.). This doesn't
actually seem to be what's going on here though, so we can just drop this
lock.

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index cb3b0e08acc4..1259f2f7a8f9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -1112,16 +1112,12 @@ static bool
if (!is_dsc_need_re_compute(state, dc_state, stream->link))
continue;
 
-   mutex_lock(>mst_mgr.lock);
if (!compute_mst_dsc_configs_for_link(state,
  dc_state,
  stream->link,
  vars,
- _vars_start_index)) {
-   mutex_unlock(>mst_mgr.lock);
+ _vars_start_index))
return false;
-   }
-   mutex_unlock(>mst_mgr.lock);
 
for (j = 0; j < dc_state->stream_count; j++) {
if (dc_state->streams[j]->link == stream->link)
-- 
2.35.3



[PATCH 0/3] Drive-by MST fixes for amdgpu

2022-06-02 Thread Lyude Paul
Now that I'm finishing up my work to remove the legacy MST code from the
tree, I've come across a couple of various issues that I wrote up
patches for along the way. These are some of those patches for amdgpu.

Lyude Paul (3):
  drm/amdgpu/dm/mst: Stop grabbing mst_mgr->lock in
compute_mst_dsc_configs_for_state()
  drm/amdgpu/dm/mst: Stop grabbing mst_mgr->lock in
pre_compute_mst_dsc_configs_for_state()
  drm/amdgpu/dm: Drop != NULL check in dm_mst_get_pbn_divider()

 .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c  | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

-- 
2.35.3



XDC 2022: Registration & Call for Presentations still open!

2022-06-02 Thread Lyude Paul
Hello! This is just a reminder that the CFP for XDC in 2022 is still open!

The 2022 X.Org Developers Conference is being held in conjunction with
the 2022 Wine Developers Conference.  This is a meeting to bring
together developers working on all things open graphics (Linux kernel,
Mesa, DRM, Wayland, X11, etc.) as well as developers for the Wine
Project, a key consumer of open graphics.

Registration & Call for Proposals are now open for both XDC 2022 and
WineConf 2022, which will take place on October 4-6, 2022 in
Minneapolis, Minnesota, USA. 

https://xdc2022.x.org
 
As usual, the conference is free of charge and open to the general
public. If you plan on attending, please make sure to register as early
as possible!
 
In order to register as attendee, you will therefore need to do it via
the XDC website:
 
https://indico.freedesktop.org/event/2/registrations/2/
 
In addition to registration, the CfP is now open for talks, workshops
and demos at XDC 2022. While any serious proposal will be gratefully
considered, topics of interest to X.Org and freedesktop.org developers
are encouraged. The program focus is on new development, ongoing
challenges and anything else that will spark discussions among
attendees in the hallway track.
 
We are open to talks across all layers of the graphics stack, from the
kernel to desktop environments / graphical applications and about how
to make things better for the developers who build them. Head to the
CfP page to learn more: 
 
https://indico.freedesktop.org/event/2/abstracts/
 
The deadline for submissions is Monday July 4th, 2022.
 
Check out our Reimbursement Policy to accept speaker
expenses for X.Org events like XDC 2022:
 
https://www.x.org/wiki/XorgFoundation/Policies/Reimbursement/

If you have any questions, please send me an email to
x...@codeweavers.com, adding on CC the X.org board (board
at foundation.x.org).
 
And don't forget, you can follow us on Twitter for all the latest
updates and to stay connected:
 
https://twitter.com/XOrgDevConf

Best regards,
Lyude Paul, on behalf of X.org



[RFC 03/18] drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation

2022-06-07 Thread Lyude Paul
In retrospect, the name I chose for this originally is confusing, as
there's a lot more info in here then just the VCPI. This really should be
called a payload. Let's make it more obvious that this is meant to be
related to the atomic state and is about payloads by renaming it to
drm_dp_mst_atomic_payload. Also, rename various variables throughout the
code that use atomic payloads.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 96 +--
 include/drm/display/drm_dp_mst_helper.h   |  4 +-
 2 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 67b3b9697da7..38eecb89e22d 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4381,7 +4381,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state 
*state,
  int pbn_div)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_vcpi_allocation *pos, *vcpi = NULL;
+   struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
int prev_slots, prev_bw, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
@@ -4389,11 +4389,11 @@ int drm_dp_atomic_find_vcpi_slots(struct 
drm_atomic_state *state,
return PTR_ERR(topology_state);
 
/* Find the current allocation for this port, if any */
-   list_for_each_entry(pos, _state->vcpis, next) {
+   list_for_each_entry(pos, _state->payloads, next) {
if (pos->port == port) {
-   vcpi = pos;
-   prev_slots = vcpi->vcpi;
-   prev_bw = vcpi->pbn;
+   payload = pos;
+   prev_slots = payload->vcpi;
+   prev_bw = payload->pbn;
 
/*
 * This should never happen, unless the driver tries
@@ -4410,7 +4410,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state 
*state,
break;
}
}
-   if (!vcpi) {
+   if (!payload) {
prev_slots = 0;
prev_bw = 0;
}
@@ -4428,17 +4428,17 @@ int drm_dp_atomic_find_vcpi_slots(struct 
drm_atomic_state *state,
   port, prev_bw, pbn);
 
/* Add the new allocation to the state */
-   if (!vcpi) {
-   vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL);
-   if (!vcpi)
+   if (!payload) {
+   payload = kzalloc(sizeof(*payload), GFP_KERNEL);
+   if (!payload)
return -ENOMEM;
 
drm_dp_mst_get_port_malloc(port);
-   vcpi->port = port;
-   list_add(>next, _state->vcpis);
+   payload->port = port;
+   list_add(>next, _state->payloads);
}
-   vcpi->vcpi = req_slots;
-   vcpi->pbn = pbn;
+   payload->vcpi = req_slots;
+   payload->pbn = pbn;
 
return req_slots;
 }
@@ -4475,21 +4475,21 @@ int drm_dp_atomic_release_vcpi_slots(struct 
drm_atomic_state *state,
 struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_vcpi_allocation *pos;
+   struct drm_dp_mst_atomic_payload *pos;
bool found = false;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   list_for_each_entry(pos, _state->vcpis, next) {
+   list_for_each_entry(pos, _state->payloads, next) {
if (pos->port == port) {
found = true;
break;
}
}
if (WARN_ON(!found)) {
-   drm_err(mgr->dev, "no VCPI for [MST PORT:%p] found in mst state 
%p\n",
+   drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
port, _state->base);
return -EINVAL;
}
@@ -5072,7 +5072,7 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 {
struct drm_dp_mst_topology_state *state, *old_state =
to_dp_mst_topology_state(obj->state);
-   struct drm_dp_vcpi_allocation *pos, *vcpi;
+   struct drm_dp_mst_atomic_payload *pos, *payload;
 
state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
if (!state)
@@ -5080,25 +5080,25 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 
__drm_atomic_helper_private_obj_duplicate_state(obj, >base);
 
-   INIT_LIST_HEAD(>vcpis);
+   INIT_LIST_HEAD(>

[RFC 02/18] drm/amdgpu/dm/mst: Rename get_payload_table()

2022-06-07 Thread Lyude Paul
This function isn't too confusing if you see the comment around the
call-site for it, but if you don't then it's not at all obvious this is
meant to copy DRM's payload table over to DC's internal state structs.
Seeing this function before finding that comment definitely threw me into a
loop a few times.

So, let's rename this to make it's purpose more obvious regardless of where
in the code you are.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Fangzhi Zuo 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 7 ---
 1 file changed, 4 insertions(+), 3 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 1bd70d306c22..1eaacab0334b 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
@@ -153,8 +153,9 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
return result;
 }
 
-static void get_payload_table(struct amdgpu_dm_connector *aconnector,
- struct dc_dp_mst_stream_allocation_table 
*proposed_table)
+static void
+fill_dc_mst_payload_table_from_drm(struct amdgpu_dm_connector *aconnector,
+  struct dc_dp_mst_stream_allocation_table 
*proposed_table)
 {
int i;
struct drm_dp_mst_topology_mgr *mst_mgr =
@@ -252,7 +253,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 * stream. AMD ASIC stream slot allocation should follow the same
 * sequence. copy DRM MST allocation to dc */
 
-   get_payload_table(aconnector, proposed_table);
+   fill_dc_mst_payload_table_from_drm(aconnector, proposed_table);
 
return true;
 }
-- 
2.35.3



[RFC 01/18] drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)

2022-06-07 Thread Lyude Paul
Just to make this more clear to outside contributors that these are
DC-specific structs, as this also threw me into a loop a number of times
before I figured out the purpose of this.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Fangzhi Zuo 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  9 -
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 10 +-
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |  4 ++--
 .../gpu/drm/amd/display/include/link_service_types.h  | 11 ---
 4 files changed, 19 insertions(+), 15 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 7c799ddc1d27..1bd70d306c22 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
@@ -153,9 +153,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
return result;
 }
 
-static void get_payload_table(
-   struct amdgpu_dm_connector *aconnector,
-   struct dp_mst_stream_allocation_table *proposed_table)
+static void get_payload_table(struct amdgpu_dm_connector *aconnector,
+ struct dc_dp_mst_stream_allocation_table 
*proposed_table)
 {
int i;
struct drm_dp_mst_topology_mgr *mst_mgr =
@@ -177,7 +176,7 @@ static void get_payload_table(
mst_mgr->payloads[i].payload_state ==
DP_PAYLOAD_REMOTE) {
 
-   struct dp_mst_stream_allocation *sa =
+   struct dc_dp_mst_stream_allocation *sa =
_table->stream_allocations[
proposed_table->stream_count];
 
@@ -201,7 +200,7 @@ void dm_helpers_dp_update_branch_info(
 bool dm_helpers_dp_mst_write_payload_allocation_table(
struct dc_context *ctx,
const struct dc_stream_state *stream,
-   struct dp_mst_stream_allocation_table *proposed_table,
+   struct dc_dp_mst_stream_allocation_table *proposed_table,
bool enable)
 {
struct amdgpu_dm_connector *aconnector;
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 a789ea8af27f..db0f5158a0c2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3424,7 +3424,7 @@ static void update_mst_stream_alloc_table(
struct dc_link *link,
struct stream_encoder *stream_enc,
struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename 
stream_enc to dio_stream_enc?
-   const struct dp_mst_stream_allocation_table *proposed_table)
+   const struct dc_dp_mst_stream_allocation_table *proposed_table)
 {
struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 
};
struct link_mst_stream_allocation *dc_alloc;
@@ -3586,7 +3586,7 @@ enum dc_status dc_link_allocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 {
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
@@ -3691,7 +3691,7 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx 
*pipe_ctx, uint32_t bw
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = get_link_hwss(link, 
_ctx->link_res);
@@ -3779,7 +3779,7 @@ enum dc_status dc_link_increase_mst_payload(struct 
pipe_ctx *pipe_ctx, uint32_t
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
struct link_encoder *link_encoder = link->link_enc;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = get_link_hwss(link, 
_ctx->link_res);
@@ -3855,7 +3855,7 @@ static enum dc_status deallocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 {
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
int i;
bool mst_mode = (link->type == dc_c

[RESEND RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state

2022-06-07 Thread Lyude Paul
We already open-code this quite often, and will be iterating through
payloads even more once we've moved all of the payload tracking into the
atomic state. So, let's add a helper for doing this.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 --
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index ec52f91b1f0e..0bc2c7a90c37 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct 
drm_dp_mst_port *port) {}
 #define save_port_topology_ref(port, type)
 #endif
 
+static struct drm_dp_mst_atomic_payload *
+drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
+struct drm_dp_mst_port *port)
+{
+   struct drm_dp_mst_atomic_payload *payload;
+
+   list_for_each_entry(payload, >payloads, next)
+   if (payload->port == port)
+   return payload;
+
+   return NULL;
+}
+
 static void drm_dp_destroy_mst_branch_device(struct kref *kref)
 {
struct drm_dp_mst_branch *mstb =
@@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct 
drm_atomic_state *state,
  int pbn_div)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
-   int prev_slots, prev_bw, req_slots;
+   struct drm_dp_mst_atomic_payload *payload = NULL;
+   int prev_slots = 0, prev_bw = 0, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
/* Find the current allocation for this port, if any */
-   list_for_each_entry(pos, _state->payloads, next) {
-   if (pos->port == port) {
-   payload = pos;
-   prev_slots = payload->time_slots;
-   prev_bw = payload->pbn;
-
-   /*
-* This should never happen, unless the driver tries
-* releasing and allocating the same timeslot 
allocation,
-* which is an error
-*/
-   if (WARN_ON(!prev_slots)) {
-   drm_err(mgr->dev,
-   "cannot allocate and release time slots 
on [MST PORT:%p] in the same state\n",
-   port);
-   return -EINVAL;
-   }
+   payload = drm_atomic_get_mst_payload_state(topology_state, port);
+   if (payload) {
+   prev_slots = payload->time_slots;
+   prev_bw = payload->pbn;
 
-   break;
+   /*
+* This should never happen, unless the driver tries
+* releasing and allocating the same timeslot allocation,
+* which is an error
+*/
+   if (WARN_ON(!prev_slots)) {
+   drm_err(mgr->dev,
+   "cannot allocate and release time slots on [MST 
PORT:%p] in the same state\n",
+   port);
+   return -EINVAL;
}
}
-   if (!payload) {
-   prev_slots = 0;
-   prev_bw = 0;
-   }
 
if (pbn_div <= 0)
pbn_div = mgr->pbn_div;
@@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_mst_atomic_payload *pos;
-   bool found = false;
+   struct drm_dp_mst_atomic_payload *payload;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   list_for_each_entry(pos, _state->payloads, next) {
-   if (pos->port == port) {
-   found = true;
-   break;
-   }
-   }
-   if (WARN_ON(!found)) {
+   payload = drm_atomic_get_mst_payload_state(topology_state, port);
+   if (WARN_ON(!payload)) {
drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
port, _state->base);
return -EINVAL;
}
 
-   drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, 
pos->time_slots);
-   if 

[RESEND RFC 17/18] drm/radeon: Drop legacy MST support

2022-06-07 Thread Lyude Paul
Right now, radeon is technically the only non-atomic driver still making
use of the MST helpers - and thus the final user of all of the legacy MST
helpers. Originally I was going to look into seeing if we could move legacy
MST into the radeon driver itself, however:

* SI and CIK both can use amdgpu, which still supports MST
* It currently doesn't work according to my own testing. I'm sure with some
  troubleshooting we could likely fix it, but that brings me to point #2:
* It was never actually enabled by default, and is still marked as
  experimental in the module parameter description
* If people were using it, someone probably would have probably seen a bug
  report about how it is currently not functional by now. That certainly
  doesn't appear to be the case, since before getting access to my own
  hardware I had to go out of my way to try finding someone to help test
  whether this legacy MST code even works - even amongst AMD employees.
* Getting rid of this code and only having atomic versions of the MST
  helpers to maintain is likely going to be a lot easier in the long run,
  and will make it a lot easier for others contributing to this code to
  follow along with what's happening.

FWIW - if anyone still wants this code to be in the tree and has a good
idea of how to support this without needing to maintain the legacy MST
helpers (trying to move them would probably be acceptable), I'm happy to
suggestions. But my hope is that we can just drop this code and forget
about it. I've already run this idea by Harry Wentland and Alex Deucher a
few times as well.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/radeon/Makefile|   2 +-
 drivers/gpu/drm/radeon/atombios_crtc.c |  11 +-
 drivers/gpu/drm/radeon/atombios_encoders.c |  59 --
 drivers/gpu/drm/radeon/radeon_atombios.c   |   2 -
 drivers/gpu/drm/radeon/radeon_connectors.c |  61 +-
 drivers/gpu/drm/radeon/radeon_device.c |   1 -
 drivers/gpu/drm/radeon/radeon_dp_mst.c | 778 -
 drivers/gpu/drm/radeon/radeon_drv.c|   4 -
 drivers/gpu/drm/radeon/radeon_encoders.c   |  14 +-
 drivers/gpu/drm/radeon/radeon_irq_kms.c|  10 +-
 drivers/gpu/drm/radeon/radeon_mode.h   |  40 --
 11 files changed, 7 insertions(+), 975 deletions(-)
 delete mode 100644 drivers/gpu/drm/radeon/radeon_dp_mst.c

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index ea5380e24c3c..b783ab39a075 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o 
\
trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \
ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o \
-   radeon_sync.o radeon_audio.o radeon_dp_auxch.o radeon_dp_mst.o
+   radeon_sync.o radeon_audio.o radeon_dp_auxch.o
 
 radeon-$(CONFIG_MMU_NOTIFIER) += radeon_mn.o
 
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
index c94e429e75f9..e27da31d4f62 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -616,13 +616,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
}
}
 
-   if (radeon_encoder->is_mst_encoder) {
-   struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv;
-   struct radeon_connector_atom_dig *dig_connector = 
mst_enc->connector->con_priv;
-
-   dp_clock = dig_connector->dp_clock;
-   }
-
/* use recommended ref_div for ss */
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
if (radeon_crtc->ss_enabled) {
@@ -971,9 +964,7 @@ static bool atombios_crtc_prepare_pll(struct drm_crtc 
*crtc, struct drm_display_
radeon_crtc->bpc = 8;
radeon_crtc->ss_enabled = false;
 
-   if (radeon_encoder->is_mst_encoder) {
-   radeon_dp_mst_prepare_pll(crtc, mode);
-   } else if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | 
ATOM_DEVICE_DFP_SUPPORT)) ||
+   if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | 
ATOM_DEVICE_DFP_SUPPORT)) ||
(radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != 
ENCODER_OBJECT_ID_NONE)) {
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector =
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c 
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 70bd84b7ef2b..597446a8df34 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -681,15 +681,7 @@ atombios_get_encoder_mode(struct drm_enc

[RESEND RFC 15/18] drm/display/dp_mst: Skip releasing payloads if last connected port isn't connected

2022-06-07 Thread Lyude Paul
In the past, we've ran into strange issues regarding errors in response to
trying to destroy payloads after a port has been unplugged. We fixed this
back in:

This is intended to replace the workaround that was added here:

commit 3769e4c0af5b ("drm/dp_mst: Avoid to mess up payload table by ports in 
stale topology")

which was intended fix to some of the payload leaks that were observed
before, where we would attempt to determine if the port was still connected
to the topology before updating payloads using
drm_dp_mst_port_downstream_of_branch. This wasn't a particularly good
solution, since one of the points of still having port and mstb validation
is to avoid sending messages to newly disconnected branches wherever
possible - thus the required use of drm_dp_mst_port_downstream_of_branch
would indicate something may be wrong with said validation.

It seems like it may have just been races and luck that made
drm_dp_mst_port_downstream_of_branch work however, as while I was trying to
figure out the true cause of this issue when removing the legacy MST code -
I discovered an important excerpt in section 2.14.2.3.3.6 of the DP 2.0
specs:

"BAD_PARAM - This reply is transmitted when a Message Transaction parameter
is in error; for example, the next port number is invalid or /no device is
connected/ to the port associated with the port number."

Sure enough - removing the calls to drm_dp_mst_port_downstream_of_branch()
and instead checking the ->ddps field of the parent port to see whether we
should release a given payload or not seems to totally fix the issue. This
does actually make sense to me, as it seems the implication is that given a
topology where an MSTB is removed, the payload for the MST parent's port
will be released automatically if that port is also marked as disconnected.
However, if there's another parent in the chain after that which is
connected - payloads must be released there with an ALLOCATE_PAYLOAD
message.

So, let's do that!

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 51 +++
 1 file changed, 17 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index dd314586bac3..70adb8db4335 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3137,7 +3137,7 @@ static struct drm_dp_mst_port 
*drm_dp_get_last_connected_port_to_mstb(struct drm
 static struct drm_dp_mst_branch *
 drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_branch *mstb,
-   int *port_num)
+   struct drm_dp_mst_port **last_port)
 {
struct drm_dp_mst_branch *rmstb = NULL;
struct drm_dp_mst_port *found_port;
@@ -3153,7 +3153,8 @@ drm_dp_get_last_connected_port_and_mstb(struct 
drm_dp_mst_topology_mgr *mgr,
 
if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
rmstb = found_port->parent;
-   *port_num = found_port->port_num;
+   *last_port = found_port;
+   drm_dp_mst_get_port_malloc(found_port);
} else {
/* Search again, starting from this parent */
mstb = found_port->parent;
@@ -3170,7 +3171,7 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
   int pbn)
 {
struct drm_dp_sideband_msg_tx *txmsg;
-   struct drm_dp_mst_branch *mstb;
+   struct drm_dp_mst_branch *mstb = NULL;
int ret, port_num;
u8 sinks[DRM_DP_MAX_SDP_STREAMS];
int i;
@@ -3178,12 +3179,22 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
port_num = port->port_num;
mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
if (!mstb) {
-   mstb = drm_dp_get_last_connected_port_and_mstb(mgr,
-  port->parent,
-  _num);
+   struct drm_dp_mst_port *rport = NULL;
+   bool ddps;
 
+   mstb = drm_dp_get_last_connected_port_and_mstb(mgr, 
port->parent, );
if (!mstb)
return -EINVAL;
+
+   ddps = rport->ddps;
+   port_num = rport->port_num;
+   drm_dp_mst_put_port_malloc(rport);
+
+   /* If the port is currently marked as disconnected, don't send 
a payload message */
+   if (!ddps) {
+   ret = -EINVAL;
+   goto 

[RESEND RFC 09/18] drm/display/dp_mst: Don't open code modeset checks for releasing time slots

2022-06-07 Thread Lyude Paul
I'm not sure why, but at the time I originally wrote the find/release time
slot helpers I thought we should avoid keeping modeset tracking out of the
MST helpers. In retrospect though there's no actual good reason to do
this, and the logic has ended up being identical across all the drivers
using the helpers. Also, it needs to be fixed anyway so we don't break
things when going atomic-only with MST.

So, let's just move this code into drm_dp_atomic_release_time_slots() and
stop open coding it.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 29 +++
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 21 --
 drivers/gpu/drm/i915/display/intel_dp_mst.c   | 24 +--
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 21 --
 4 files changed, 23 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index e40ff51e7be0..b447c453b58d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -353,34 +353,13 @@ dm_dp_mst_detect(struct drm_connector *connector,
 }
 
 static int dm_dp_mst_atomic_check(struct drm_connector *connector,
-   struct drm_atomic_state *state)
+ struct drm_atomic_state *state)
 {
-   struct drm_connector_state *new_conn_state =
-   drm_atomic_get_new_connector_state(state, connector);
-   struct drm_connector_state *old_conn_state =
-   drm_atomic_get_old_connector_state(state, connector);
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
-   struct drm_crtc_state *new_crtc_state;
-   struct drm_dp_mst_topology_mgr *mst_mgr;
-   struct drm_dp_mst_port *mst_port;
+   struct drm_dp_mst_topology_mgr *mst_mgr = 
>mst_port->mst_mgr;
+   struct drm_dp_mst_port *mst_port = aconnector->port;
 
-   mst_port = aconnector->port;
-   mst_mgr = >mst_port->mst_mgr;
-
-   if (!old_conn_state->crtc)
-   return 0;
-
-   if (new_conn_state->crtc) {
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
-   if (!new_crtc_state ||
-   !drm_atomic_crtc_needs_modeset(new_crtc_state) ||
-   new_crtc_state->enable)
-   return 0;
-   }
-
-   return drm_dp_atomic_release_time_slots(state,
-   mst_mgr,
-   mst_port);
+   return drm_dp_atomic_release_time_slots(state, mst_mgr, mst_port);
 }
 
 static const struct drm_connector_helper_funcs 
dm_dp_mst_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index a0ed29f83556..e73b34c0cc9e 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4484,14 +4484,29 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 {
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload;
-   struct drm_connector_state *conn_state;
+   struct drm_connector_state *old_conn_state, *new_conn_state;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, 
port->connector);
+   if (!old_conn_state->crtc)
+   return 0;
+
+   /* If the CRTC isn't disabled by this state, don't release it's payload 
*/
+   new_conn_state = drm_atomic_get_new_connector_state(state, 
port->connector);
+   if (new_conn_state->crtc) {
+   struct drm_crtc_state *crtc_state =
+   drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
+
+   if (!crtc_state ||
+   !drm_atomic_crtc_needs_modeset(crtc_state) ||
+   crtc_state->enable)
+   return 0;
+   }
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   conn_state = drm_atomic_get_old_connector_state(state, port->connector);
-   topology_state->pending_crtc_mask |= drm_crtc_mask(conn_state->crtc);
+   topology_state->pending_crtc_mask |= 
drm_crtc_mask(old_conn_state->crtc);
 
payload = drm_atomic_get_mst_payload_state(topology_state, port);
if (WARN_ON(!payload)) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 0c922667398a..4b0af3c26176 100644
--- a/drivers/gpu/drm

[RESEND RFC 14/18] drm/display/dp_mst: Drop all ports from topology on CSNs before queueing link address work

2022-06-07 Thread Lyude Paul
We want to start cutting down on all of the places that we use port
validation, so that ports may be removed from the topology as quickly as
possible to minimize the number of errors we run into as a result of being
out of sync with the current topology status. This isn't a very typical
scenario and I don't think I've ever even run into it - but since the next
commit is going to make some changes to payload updates depending on their
hotplug status I think it's a probably good idea to take precautions.

Let's do this with CSNs by moving some code around so that we only queue
link address probing work at the end of handling all CSNs - allowing us to
make sure we drop as many topology references as we can beforehand.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index a775f9437868..dd314586bac3 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -2508,7 +2508,7 @@ drm_dp_mst_handle_link_address_port(struct 
drm_dp_mst_branch *mstb,
return ret;
 }
 
-static void
+static int
 drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
struct drm_dp_connection_status_notify *conn_stat)
 {
@@ -2521,7 +2521,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch 
*mstb,
 
port = drm_dp_get_port(mstb, conn_stat->port_number);
if (!port)
-   return;
+   return 0;
 
if (port->connector) {
if (!port->input && conn_stat->input_port) {
@@ -2574,8 +2574,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch 
*mstb,
 
 out:
drm_dp_mst_topology_put_port(port);
-   if (dowork)
-   queue_work(system_long_wq, >mgr->work);
+   return dowork;
 }
 
 static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct 
drm_dp_mst_topology_mgr *mgr,
@@ -4071,7 +4070,7 @@ drm_dp_mst_process_up_req(struct drm_dp_mst_topology_mgr 
*mgr,
struct drm_dp_mst_branch *mstb = NULL;
struct drm_dp_sideband_msg_req_body *msg = _req->msg;
struct drm_dp_sideband_msg_hdr *hdr = _req->hdr;
-   bool hotplug = false;
+   bool hotplug = false, dowork = false;
 
if (hdr->broadcast) {
const u8 *guid = NULL;
@@ -4094,11 +4093,14 @@ drm_dp_mst_process_up_req(struct 
drm_dp_mst_topology_mgr *mgr,
 
/* TODO: Add missing handler for DP_RESOURCE_STATUS_NOTIFY events */
if (msg->req_type == DP_CONNECTION_STATUS_NOTIFY) {
-   drm_dp_mst_handle_conn_stat(mstb, >u.conn_stat);
+   dowork = drm_dp_mst_handle_conn_stat(mstb, >u.conn_stat);
hotplug = true;
}
 
drm_dp_mst_topology_put_mstb(mstb);
+
+   if (dowork)
+   queue_work(system_long_wq, >work);
return hotplug;
 }
 
-- 
2.35.3



[RESEND RFC 16/18] drm/display/dp_mst: Maintain time slot allocations when deleting payloads

2022-06-07 Thread Lyude Paul
Currently, we set drm_dp_atomic_payload->time_slots to 0 in order to
indicate that we're about to delete a payload in the current atomic state.
Since we're going to be dropping all of the legacy code for handling the
payload table however, we need to be able to ensure that we still keep
track of the current time slot allocations for each payload so we can reuse
this info when asking the root MST hub to delete payloads. We'll also be
using it to recalculate the start slots of each VC.

So, let's keep track of the intent of a payload in drm_dp_atomic_payload by
adding ->delete, which we set whenever we're planning on deleting a payload
during the current atomic commit.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 14 +++---
 include/drm/display/drm_dp_mst_helper.h   |  5 -
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 70adb8db4335..10d26a7e028c 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4410,7 +4410,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state 
*state,
 * releasing and allocating the same timeslot allocation,
 * which is an error
 */
-   if (WARN_ON(!prev_slots)) {
+   if (drm_WARN_ON(mgr->dev, payload->delete)) {
drm_err(mgr->dev,
"cannot allocate and release time slots on [MST 
PORT:%p] in the same state\n",
port);
@@ -4515,10 +4515,10 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
}
 
drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, 
payload->time_slots);
-   if (payload->time_slots) {
+   if (!payload->delete) {
drm_dp_mst_put_port_malloc(port);
-   payload->time_slots = 0;
payload->pbn = 0;
+   payload->delete = true;
}
 
return 0;
@@ -5234,7 +5234,7 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 
list_for_each_entry(pos, _state->payloads, next) {
/* Prune leftover freed timeslot allocations */
-   if (!pos->time_slots)
+   if (pos->delete)
continue;
 
payload = kmemdup(pos, sizeof(*payload), GFP_KERNEL);
@@ -5266,8 +5266,8 @@ static void drm_dp_mst_destroy_state(struct 
drm_private_obj *obj,
int i;
 
list_for_each_entry_safe(pos, tmp, _state->payloads, next) {
-   /* We only keep references to ports with non-zero VCPIs */
-   if (pos->time_slots)
+   /* We only keep references to ports with active payloads */
+   if (!pos->delete)
drm_dp_mst_put_port_malloc(pos->port);
kfree(pos);
}
@@ -5395,7 +5395,7 @@ drm_dp_mst_atomic_check_payload_alloc_limits(struct 
drm_dp_mst_topology_mgr *mgr
 
list_for_each_entry(payload, _state->payloads, next) {
/* Releasing payloads is always OK-even if the port is gone */
-   if (!payload->time_slots) {
+   if (payload->delete) {
drm_dbg_atomic(mgr->dev, "[MST PORT:%p] releases all 
time slots\n",
   payload->port);
continue;
diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index 690ebcabb51f..ecd130028337 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -555,8 +555,11 @@ struct drm_dp_mst_atomic_payload {
int time_slots;
/** @pbn: The payload bandwidth for this payload */
int pbn;
+
+   /** @delete: Whether or not we intend to delete this payload during 
this atomic commit */
+   bool delete : 1;
/** @dsc_enabled: Whether or not this payload has DSC enabled */
-   bool dsc_enabled;
+   bool dsc_enabled : 1;
 
/** @next: The list node for this payload */
struct list_head next;
-- 
2.35.3



[RESEND RFC 04/18] drm/display/dp_mst: Call them time slots, not VCPI slots

2022-06-07 Thread Lyude Paul
VCPI is only sort of the correct term here, originally the majority of this
code simply referred to timeslots vaguely as "slots" - and since I started
working on it and adding atomic functionality, the name "VCPI slots" has
been used to represent time slots.

Now that we actually have consistent access to the DisplayPort spec thanks
to VESA, I now know this isn't actually the proper term - as the
specification refers to these as time slots.

Since we're trying to make this code as easy to figure out as possible,
let's take this opportunity to correct this nomenclature and call them by
their proper name - timeslots. Likewise, we rename various functions
appropriately, along with replacing references in the kernel documentation
and various debugging messages.

It's important to note that this patch series leaves the legacy MST code
untouched for the most part, which is fine since we'll be removing it soon
anyhow. There should be no functional changes in this series.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  28 ++---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 106 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   5 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |   4 +-
 include/drm/display/drm_dp_mst_helper.h   |   6 +-
 6 files changed, 75 insertions(+), 76 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 ad4571190a90..f84a4ad736d8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7393,7 +7393,7 @@ static int dm_encoder_helper_atomic_check(struct 
drm_encoder *encoder,
clock = adjusted_mode->clock;
dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, 
false);
}
-   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_vcpi_slots(state,
+   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_time_slots(state,
   
mst_mgr,
   
mst_port,
   
dm_new_connector_state->pbn,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 9221b6690a4a..e40ff51e7be0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -378,7 +378,7 @@ static int dm_dp_mst_atomic_check(struct drm_connector 
*connector,
return 0;
}
 
-   return drm_dp_atomic_release_vcpi_slots(state,
+   return drm_dp_atomic_release_time_slots(state,
mst_mgr,
mst_port);
 }
@@ -689,7 +689,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
 
if (initial_slack[next_index] > fair_pbn_alloc) {
vars[next_index].pbn += fair_pbn_alloc;
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
  
params[next_index].port,
  vars[next_index].pbn,
@@ -699,7 +699,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
vars[next_index].bpp_x16 = 
bpp_x16_from_pbn(params[next_index], vars[next_index].pbn);
} else {
vars[next_index].pbn -= fair_pbn_alloc;
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
  
params[next_index].port,
  
vars[next_index].pbn,
@@ -708,7 +708,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
}
} else {
vars[next_index].pbn += initial_slack[next_index];
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
   

[RESEND RFC 11/18] drm/nouveau/kms: Cache DP encoders in nouveau_connector

2022-06-07 Thread Lyude Paul
Post-NV50, the only kind of encoder you'll find for DP connectors on Nvidia
GPUs are SORs (serial output resources). Because SORs have fixed
associations with their connectors, we can correctly assume that any DP
connector on a nvidia GPU will have exactly one SOR encoder routed to it
for DisplayPort.

Since we're going to need to be able to retrieve this fixed SOR DP encoder
much more often as a result of hooking up MST helpers for tracking
SST<->MST transitions in atomic states, let's simply cache this encoder in
nouveau_connector for any DP connectors on the system to avoid looking it
up each time. This isn't safe for NV50 since PIORs then come into play,
however there's no code pre-NV50 that would need to look this up anyhow -
so it's not really an issue.

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nouveau_connector.c | 4 +++-
 drivers/gpu/drm/nouveau/nouveau_connector.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 22b83a6577eb..ffbd8a9cf2af 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -1368,7 +1368,7 @@ nouveau_connector_create(struct drm_device *dev,
kfree(nv_connector);
return ERR_PTR(ret);
}
-   fallthrough;
+   break;
default:
funcs = _connector_funcs;
break;
@@ -1422,6 +1422,8 @@ nouveau_connector_create(struct drm_device *dev,
 
switch (type) {
case DRM_MODE_CONNECTOR_DisplayPort:
+   nv_connector->dp_encoder = find_encoder(_connector->base, 
DCB_OUTPUT_DP);
+   fallthrough;
case DRM_MODE_CONNECTOR_eDP:
drm_dp_cec_register_connector(_connector->aux, connector);
break;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h 
b/drivers/gpu/drm/nouveau/nouveau_connector.h
index b0773af5a98f..f468c181d9a3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -127,6 +127,9 @@ struct nouveau_connector {
 
struct drm_dp_aux aux;
 
+   /* The fixed DP encoder for this connector, if there is one */
+   struct nouveau_encoder *dp_encoder;
+
int dithering_mode;
int scaling_mode;
 
-- 
2.35.3



[RESEND RFC 12/18] drm/nouveau/kms: Pull mst state in for all modesets

2022-06-07 Thread Lyude Paul
Since we're going to be relying on atomic locking for payloads now (and the
MST mgr needs to track CRTCs), pull in the topology state for all modesets
in nv50_msto_atomic_check().

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 461e5e3345f8..834a5c5b77d5 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1054,7 +1054,7 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
if (ret)
return ret;
 
-   if (!crtc_state->mode_changed && !crtc_state->connectors_changed)
+   if (!drm_atomic_crtc_needs_modeset(crtc_state))
return 0;
 
/*
-- 
2.35.3



[RESEND RFC 10/18] drm/display/dp_mst: Fix modeset tracking in drm_dp_atomic_release_vcpi_slots()

2022-06-07 Thread Lyude Paul
Currently with the MST helpers we avoid releasing payloads _and_ avoid
pulling in the MST state if there aren't any actual payload changes. While
we want to keep the first step, we need to now make sure that we're always
pulling in the MST state on all modesets that can modify payloads - even if
the resulting payloads in the atomic state are identical to the previous
ones.

This is mainly to make it so that if a CRTC is still assigned to a
connector but is set to DPMS off, the CRTC still holds it's payload
allocation in the atomic state and still appropriately pulls in the MST
state for commit tracking. Otherwise, we'll occasionally forget to update
MST payloads from changes caused by non-atomic DPMS changes. Doing this
also allows us to track bandwidth limitations in a state correctly even
between DPMS changes, so that there's no chance of a simple ->active change
being rejected by the atomic check.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index e73b34c0cc9e..c5edcf2a26c8 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4485,6 +4485,7 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload;
struct drm_connector_state *old_conn_state, *new_conn_state;
+   bool update_payload = true;
 
old_conn_state = drm_atomic_get_old_connector_state(state, 
port->connector);
if (!old_conn_state->crtc)
@@ -4496,10 +4497,12 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
struct drm_crtc_state *crtc_state =
drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
 
-   if (!crtc_state ||
-   !drm_atomic_crtc_needs_modeset(crtc_state) ||
-   crtc_state->enable)
+   /* No modeset means no payload changes, so it's safe to not 
pull in the MST state */
+   if (!crtc_state || !drm_atomic_crtc_needs_modeset(crtc_state))
return 0;
+
+   if (!crtc_state->mode_changed && 
!crtc_state->connectors_changed)
+   update_payload = false;
}
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
@@ -4507,6 +4510,8 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
return PTR_ERR(topology_state);
 
topology_state->pending_crtc_mask |= 
drm_crtc_mask(old_conn_state->crtc);
+   if (!update_payload)
+   return 0;
 
payload = drm_atomic_get_mst_payload_state(topology_state, port);
if (WARN_ON(!payload)) {
-- 
2.35.3



[RESEND RFC 18/18] drm/display/dp_mst: Move all payload info into the atomic state

2022-06-07 Thread Lyude Paul
Now that we've finally gotten rid of the non-atomic MST users leftover in
the kernel, we can finally get rid of all of the legacy payload code we
have and move as much as possible into the MST atomic state structs. The
main purpose of this is to make the MST code a lot less confusing to work
on, as there's a lot of duplicated logic that doesn't really need to be
here. As well, this should make introducing features like fallback link
retraining and DSC support far easier.

Since the old payload code was pretty gnarly and there's a Lot of changes
here, I expect this might be a bit difficult to review. So to make things
as easy as possible for reviewers, I'll sum up how both the old and new
code worked here (it took me a while to figure this out too!).

The old MST code basically worked by maintaining two different payload
tables - proposed_vcpis, and payloads. proposed_vcpis would hold the
modified payload we wanted to push to the topology, while payloads held the
payload table that was currently programmed in hardware. Modifications to
proposed_vcpis would be handled through drm_dp_allocate_vcpi(),
drm_dp_mst_deallocate_vcpi(), and drm_dp_mst_reset_vcpi_slots(). Then, they
would be pushed via drm_dp_mst_update_payload_step1() and
drm_dp_mst_update_payload_step2().

Furthermore, it's important to note how adding and removing VC payloads
actually worked with drm_dp_mst_update_payload_step1(). When a VC payload
is removed from the VC table, all VC payloads which come after the removed
VC payload's slots must have their time slots shifted towards the start of
the table. The old code handles this by looping through the entire payload
table and recomputing the start slot for every payload in the topology from
scratch. While very much overkill, this ends up doing the right thing
because we always order the VCPIs for payloads from first to last starting
timeslot.

It's important to also note that drm_dp_mst_update_payload_step2() isn't
actually limited to updating a single payload - the driver can use it to
queue up multiple payload changes so that as many of them can be sent as
possible before waiting for the ACT.

drm_dp_mst_update_payload_step2() is pretty self explanatory and basically
the same between the old and new code, save for the fact we don't have a
second step for deleting payloads anymore -and thus rename it to
drm_dp_mst_add_payload_step2().

The new payload code stores all of the current payload info within the MST
atomic state and computes as much of the state as possible ahead of time.
This has the one exception of the starting timeslots for payloads, which
can't be determined at atomic check time since the starting time slots will
vary depending on what order CRTCs are enabled in the atomic state - which
varies from driver to driver. These are still stored in the atomic MST
state, but are only copied from the old MST state during atomic commit
time. Likewise, this is when new start slots are determined.

Adding/removing payloads now works much more closely to how things are
described in the spec. When we delete a payload, we loop through the
current list of payloads and update the start slots for any payloads whose
time slots came after the payload we just deleted. Determining the starting
time slots for new payloads being added is done by simply keeping track of
where the end of the VC table is in
drm_dp_mst_topology_mgr->next_start_slot. Additionally, it's worth noting
that we no longer have a single update_payload() function. Instead, we now
have drm_dp_mst_add_payload_step1|2() and drm_dp_mst_remove_payload(). As
such, it's now left it up to the driver to figure out when to add or remove
payloads. The driver already knows when it's disabling/enabling CRTCs, so
it also already knows when payloads should be added or removed. And, this
doesn't interfere with the ability to queue up multiple payload changes
before waiting for the ACT.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  56 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 107 +--
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  85 +--
 .../amd/display/include/link_service_types.h  |   7 +
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 699 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  64 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c |  24 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 163 ++--
 include/drm/display/drm_dp_mst_helper.h   | 178 ++---
 9 files changed, 536 insertions(+), 847 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 ac8648e3c1c9..93d572ea3c48 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7378,6 +7378,7 @@ static int dm_encoder_helper_atomic_check(struct 
drm_enco

[RFC 00/18] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only

2022-06-07 Thread Lyude Paul
For quite a while we've been carrying around a lot of legacy modesetting
code in the MST helpers that has been rather annoying to keep around,
and very often gets in the way of trying to implement additional
functionality in MST such as fallback link rate retraining, dynamic BPC
management and DSC support, etc. because of the fact that we can't rely
on atomic for everything.

Luckily, we only actually have one user of the legacy MST code in the
kernel - radeon. Originally I was thinking of trying to maintain this
code and keep it around in some form, but I'm pretty unconvinced anyone
is actually using this. My reasoning for that is because I've seen
nearly no issues regarding MST on radeon for quite a while now - despite
the fact my local testing seems to indicate it's quite broken. This
isn't too surprising either, as MST support in radeon.ko is gated behind
a module parameter that isn't enabled by default. This isn't to say I
wouldn't be open to alternative suggestions, but I'd rather not be the
one to have to spend time on that if at all possible! Plus, I already
floated the idea of dropping this code by AMD folks a few times and
didn't get much resistance.

As well, this series has some basic refactoring that I did along the way
and some bugs I had to fix in order to get my atomic-only MST code
working. Most of this is pretty straight forward and simply renaming
things to more closely match the DisplayPort specification, as I think
this will also make maintaining this code a lot easier in the long run
(I've gotten myself confused way too many times because of this).

So far I've tested this on all three MST drivers: amdgpu, i915 and
nouveau, along with making sure that removing the radeon MST code
doesn't break anything else. The one thing I very much could use help
with regarding testing though is making sure that this works with
amdgpu's DSC support on MST.

So, with this we should be using the atomic state as much as possible
with MST modesetting, hooray!

Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 

Lyude Paul (18):
  drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)
  drm/amdgpu/dm/mst: Rename get_payload_table()
  drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation
  drm/display/dp_mst: Call them time slots, not VCPI slots
  drm/display/dp_mst: Fix confusing docs for
drm_dp_atomic_release_time_slots()
  drm/display/dp_mst: Add some missing kdocs for atomic MST structs
  drm/display/dp_mst: Add helper for finding payloads in atomic MST
state
  drm/display/dp_mst: Add nonblocking helpers for DP MST
  drm/display/dp_mst: Don't open code modeset checks for releasing time
slots
  drm/display/dp_mst: Fix modeset tracking in
drm_dp_atomic_release_vcpi_slots()
  drm/nouveau/kms: Cache DP encoders in nouveau_connector
  drm/nouveau/kms: Pull mst state in for all modesets
  drm/display/dp_mst: Add helpers for serializing SST <-> MST
transitions
  drm/display/dp_mst: Drop all ports from topology on CSNs before
queueing link address work
  drm/display/dp_mst: Skip releasing payloads if last connected port
isn't connected
  drm/display/dp_mst: Maintain time slot allocations when deleting
payloads
  drm/radeon: Drop legacy MST support
  drm/display/dp_mst: Move all payload info into the atomic state

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   72 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  111 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  126 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |   10 +-
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |4 +-
 .../amd/display/include/link_service_types.h  |   18 +-
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 1160 -
 drivers/gpu/drm/i915/display/intel_display.c  |   11 +
 drivers/gpu/drm/i915/display/intel_dp.c   |9 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   91 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c |   24 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  202 ++-
 drivers/gpu/drm/nouveau/dispnv50/disp.h   |2 +
 drivers/gpu/drm/nouveau/nouveau_connector.c   |   18 +-
 drivers/gpu/drm/nouveau/nouveau_connector.h   |3 +
 drivers/gpu/drm/radeon/Makefile   |2 +-
 drivers/gpu/drm/radeon/atombios_crtc.c|   11 +-
 drivers/gpu/drm/radeon/atombios_encoders.c|   59 -
 drivers/gpu/drm/radeon/radeon_atombios.c  |2 -
 drivers/gpu/drm/radeon/radeon_connectors.c|   61 +-
 drivers/gpu/drm/radeon/radeon_device.c|1 -
 drivers/gpu/drm/radeon/radeon_dp_mst.c|  778 ---
 drivers/gpu/drm/radeon/radeon_drv.c   |4 -
 drivers/gpu/drm/radeon/radeon_encoders.c  |   14 +-
 drivers/gpu/drm/radeon/radeon_irq_kms.c   |   10 +-
 drivers/gpu/drm/radeon/radeon_mode.h  |   40 -
 include/drm/display/drm_dp_mst_helper.h   |  230 ++--
 27 files changed, 991 insertions(+), 2082 deletions(-)
 delet

[RFC 07/18] drm/display/dp_mst: Add helper for finding payloads in atomic MST state

2022-06-07 Thread Lyude Paul
We already open-code this quite often, and will be iterating through
payloads even more once we've moved all of the payload tracking into the
atomic state. So, let's add a helper for doing this.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 --
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index ec52f91b1f0e..0bc2c7a90c37 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -1737,6 +1737,19 @@ drm_dp_mst_dump_port_topology_history(struct 
drm_dp_mst_port *port) {}
 #define save_port_topology_ref(port, type)
 #endif
 
+static struct drm_dp_mst_atomic_payload *
+drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
+struct drm_dp_mst_port *port)
+{
+   struct drm_dp_mst_atomic_payload *payload;
+
+   list_for_each_entry(payload, >payloads, next)
+   if (payload->port == port)
+   return payload;
+
+   return NULL;
+}
+
 static void drm_dp_destroy_mst_branch_device(struct kref *kref)
 {
struct drm_dp_mst_branch *mstb =
@@ -4381,39 +4394,31 @@ int drm_dp_atomic_find_time_slots(struct 
drm_atomic_state *state,
  int pbn_div)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
-   int prev_slots, prev_bw, req_slots;
+   struct drm_dp_mst_atomic_payload *payload = NULL;
+   int prev_slots = 0, prev_bw = 0, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
/* Find the current allocation for this port, if any */
-   list_for_each_entry(pos, _state->payloads, next) {
-   if (pos->port == port) {
-   payload = pos;
-   prev_slots = payload->time_slots;
-   prev_bw = payload->pbn;
-
-   /*
-* This should never happen, unless the driver tries
-* releasing and allocating the same timeslot 
allocation,
-* which is an error
-*/
-   if (WARN_ON(!prev_slots)) {
-   drm_err(mgr->dev,
-   "cannot allocate and release time slots 
on [MST PORT:%p] in the same state\n",
-   port);
-   return -EINVAL;
-   }
+   payload = drm_atomic_get_mst_payload_state(topology_state, port);
+   if (payload) {
+   prev_slots = payload->time_slots;
+   prev_bw = payload->pbn;
 
-   break;
+   /*
+* This should never happen, unless the driver tries
+* releasing and allocating the same timeslot allocation,
+* which is an error
+*/
+   if (WARN_ON(!prev_slots)) {
+   drm_err(mgr->dev,
+   "cannot allocate and release time slots on [MST 
PORT:%p] in the same state\n",
+   port);
+   return -EINVAL;
}
}
-   if (!payload) {
-   prev_slots = 0;
-   prev_bw = 0;
-   }
 
if (pbn_div <= 0)
pbn_div = mgr->pbn_div;
@@ -4474,30 +4479,24 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_mst_atomic_payload *pos;
-   bool found = false;
+   struct drm_dp_mst_atomic_payload *payload;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   list_for_each_entry(pos, _state->payloads, next) {
-   if (pos->port == port) {
-   found = true;
-   break;
-   }
-   }
-   if (WARN_ON(!found)) {
+   payload = drm_atomic_get_mst_payload_state(topology_state, port);
+   if (WARN_ON(!payload)) {
drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
port, _state->base);
return -EINVAL;
}
 
-   drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, 
pos->time_slots);
-   if 

[RFC 05/18] drm/display/dp_mst: Fix confusing docs for drm_dp_atomic_release_time_slots()

2022-06-07 Thread Lyude Paul
For some reason we mention returning 0 if "slots have been added back to
drm_dp_mst_topology_state->avail_slots". This is totally misleading,
avail_slots is simply for figuring out the total number of slots available
in total on the topology and has no relation to the current payload
allocations.

So, let's get rid of that comment.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 702ff5d9ecc7..ec52f91b1f0e 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4467,8 +4467,7 @@ EXPORT_SYMBOL(drm_dp_atomic_find_time_slots);
  * drm_dp_mst_atomic_check()
  *
  * Returns:
- * 0 if all slots for this port were added back to
- * _dp_mst_topology_state.avail_slots or negative error code
+ * 0 on success, negative error code otherwise
  */
 int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
 struct drm_dp_mst_topology_mgr *mgr,
-- 
2.35.3



[RFC 06/18] drm/display/dp_mst: Add some missing kdocs for atomic MST structs

2022-06-07 Thread Lyude Paul
Since we're about to start adding some stuff here, we may as well fill in
any missing documentation that we forgot to write.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 include/drm/display/drm_dp_mst_helper.h | 24 
 1 file changed, 24 insertions(+)

diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index 8ab4f14f2344..eb0ea578b227 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -542,19 +542,43 @@ struct drm_dp_payload {
 
 #define to_dp_mst_topology_state(x) container_of(x, struct 
drm_dp_mst_topology_state, base)
 
+/**
+ * struct drm_dp_mst_atomic_payload - Atomic state struct for an MST payload
+ *
+ * The primary atomic state structure for a given MST payload. Stores 
information like current
+ * bandwidth allocation, intended action for this payload, etc.
+ */
 struct drm_dp_mst_atomic_payload {
+   /** @port: The MST port assigned to this payload */
struct drm_dp_mst_port *port;
+   /** @time_slots: The number of timeslots allocated to this payload */
int time_slots;
+   /** @pbn: The payload bandwidth for this payload */
int pbn;
+   /** @dsc_enabled: Whether or not this payload has DSC enabled */
bool dsc_enabled;
+
+   /** @next: The list node for this payload */
struct list_head next;
 };
 
+/**
+ * struct drm_dp_mst_topology_state - DisplayPort MST topology atomic state
+ *
+ * This struct represents the atomic state of the toplevel DisplayPort MST 
manager
+ */
 struct drm_dp_mst_topology_state {
+   /** @base: Base private state for atomic */
struct drm_private_state base;
+
+   /** @payloads: The list of payloads being created/destroyed in this 
state */
struct list_head payloads;
+   /** @mgr: The topology manager */
struct drm_dp_mst_topology_mgr *mgr;
+
+   /** @total_avail_slots: The total number of slots this topology can 
handle (63 or 64) */
u8 total_avail_slots;
+   /** @start_slot: The first usable time slot in this topology (1 or 0) */
u8 start_slot;
 };
 
-- 
2.35.3



[RESEND RFC 06/18] drm/display/dp_mst: Add some missing kdocs for atomic MST structs

2022-06-07 Thread Lyude Paul
Since we're about to start adding some stuff here, we may as well fill in
any missing documentation that we forgot to write.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 include/drm/display/drm_dp_mst_helper.h | 24 
 1 file changed, 24 insertions(+)

diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index 8ab4f14f2344..eb0ea578b227 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -542,19 +542,43 @@ struct drm_dp_payload {
 
 #define to_dp_mst_topology_state(x) container_of(x, struct 
drm_dp_mst_topology_state, base)
 
+/**
+ * struct drm_dp_mst_atomic_payload - Atomic state struct for an MST payload
+ *
+ * The primary atomic state structure for a given MST payload. Stores 
information like current
+ * bandwidth allocation, intended action for this payload, etc.
+ */
 struct drm_dp_mst_atomic_payload {
+   /** @port: The MST port assigned to this payload */
struct drm_dp_mst_port *port;
+   /** @time_slots: The number of timeslots allocated to this payload */
int time_slots;
+   /** @pbn: The payload bandwidth for this payload */
int pbn;
+   /** @dsc_enabled: Whether or not this payload has DSC enabled */
bool dsc_enabled;
+
+   /** @next: The list node for this payload */
struct list_head next;
 };
 
+/**
+ * struct drm_dp_mst_topology_state - DisplayPort MST topology atomic state
+ *
+ * This struct represents the atomic state of the toplevel DisplayPort MST 
manager
+ */
 struct drm_dp_mst_topology_state {
+   /** @base: Base private state for atomic */
struct drm_private_state base;
+
+   /** @payloads: The list of payloads being created/destroyed in this 
state */
struct list_head payloads;
+   /** @mgr: The topology manager */
struct drm_dp_mst_topology_mgr *mgr;
+
+   /** @total_avail_slots: The total number of slots this topology can 
handle (63 or 64) */
u8 total_avail_slots;
+   /** @start_slot: The first usable time slot in this topology (1 or 0) */
u8 start_slot;
 };
 
-- 
2.35.3



[RESEND RFC 05/18] drm/display/dp_mst: Fix confusing docs for drm_dp_atomic_release_time_slots()

2022-06-07 Thread Lyude Paul
For some reason we mention returning 0 if "slots have been added back to
drm_dp_mst_topology_state->avail_slots". This is totally misleading,
avail_slots is simply for figuring out the total number of slots available
in total on the topology and has no relation to the current payload
allocations.

So, let's get rid of that comment.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 702ff5d9ecc7..ec52f91b1f0e 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4467,8 +4467,7 @@ EXPORT_SYMBOL(drm_dp_atomic_find_time_slots);
  * drm_dp_mst_atomic_check()
  *
  * Returns:
- * 0 if all slots for this port were added back to
- * _dp_mst_topology_state.avail_slots or negative error code
+ * 0 on success, negative error code otherwise
  */
 int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
 struct drm_dp_mst_topology_mgr *mgr,
-- 
2.35.3



[RESEND RFC 08/18] drm/display/dp_mst: Add nonblocking helpers for DP MST

2022-06-07 Thread Lyude Paul
As Daniel Vetter pointed out, if we only use the atomic modesetting locks
with MST it's technically possible for a driver with non-blocking modesets
to race when it comes to MST displays - as we make the mistake of not doing
our own CRTC commit tracking in the topology_state object.

This could potentially cause problems if something like this happens:

* User starts non-blocking commit to disable CRTC-1 on MST topology 1
* User starts non-blocking commit to enable CRTC-2 on MST topology 1

There's no guarantee here that the commit for disabling CRTC-2 will only
occur after CRTC-1 has finished, since neither commit shares a CRTC - only
the private modesetting object for MST. Keep in mind this likely isn't a
problem for blocking modesets, only non-blocking.

So, begin fixing this by keeping track of which CRTCs on a topology have
changed by keeping track of which CRTCs we release or allocate timeslots
on. As well, add some helpers for:

* Setting up the drm_crtc_commit structs in the ->commit_setup hook
* Waiting for any CRTC dependencies from the previous topology state

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +-
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 93 +++
 drivers/gpu/drm/i915/display/intel_display.c  | 11 +++
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 12 +++
 include/drm/display/drm_dp_mst_helper.h   | 15 +++
 5 files changed, 139 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 f84a4ad736d8..d9c7393ef151 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -211,6 +211,7 @@ static int amdgpu_dm_encoder_init(struct drm_device *dev,
 static int amdgpu_dm_connector_get_modes(struct drm_connector *connector);
 
 static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state);
+static int amdgpu_dm_atomic_setup_commit(struct drm_atomic_state *state);
 
 static int amdgpu_dm_atomic_check(struct drm_device *dev,
  struct drm_atomic_state *state);
@@ -2808,7 +2809,8 @@ static const struct drm_mode_config_funcs 
amdgpu_dm_mode_funcs = {
 };
 
 static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = 
{
-   .atomic_commit_tail = amdgpu_dm_atomic_commit_tail
+   .atomic_commit_tail = amdgpu_dm_atomic_commit_tail,
+   .atomic_commit_setup = amdgpu_dm_atomic_setup_commit,
 };
 
 static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
@@ -9558,6 +9560,7 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
DRM_ERROR("Waiting for fences timed out!");
 
drm_atomic_helper_update_legacy_modeset_state(dev, state);
+   drm_dp_mst_atomic_wait_for_dependencies(state);
 
dm_state = dm_atomic_get_new_state(state);
if (dm_state && dm_state->context) {
@@ -9958,6 +9961,10 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
dc_release_state(dc_state_temp);
 }
 
+static int amdgpu_dm_atomic_setup_commit(struct drm_atomic_state *state)
+{
+   return drm_dp_mst_atomic_setup_commit(state);
+}
 
 static int dm_force_atomic_commit(struct drm_connector *connector)
 {
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 0bc2c7a90c37..a0ed29f83556 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4395,12 +4395,16 @@ int drm_dp_atomic_find_time_slots(struct 
drm_atomic_state *state,
 {
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload = NULL;
+   struct drm_connector_state *conn_state;
int prev_slots = 0, prev_bw = 0, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
+   conn_state = drm_atomic_get_new_connector_state(state, port->connector);
+   topology_state->pending_crtc_mask |= drm_crtc_mask(conn_state->crtc);
+
/* Find the current allocation for this port, if any */
payload = drm_atomic_get_mst_payload_state(topology_state, port);
if (payload) {
@@ -4480,11 +4484,15 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 {
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload;
+   struct drm_connector_state *conn_state;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
+   conn_state = drm_atomic_ge

[RESEND RFC 02/18] drm/amdgpu/dm/mst: Rename get_payload_table()

2022-06-07 Thread Lyude Paul
This function isn't too confusing if you see the comment around the
call-site for it, but if you don't then it's not at all obvious this is
meant to copy DRM's payload table over to DC's internal state structs.
Seeing this function before finding that comment definitely threw me into a
loop a few times.

So, let's rename this to make it's purpose more obvious regardless of where
in the code you are.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Fangzhi Zuo 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 7 ---
 1 file changed, 4 insertions(+), 3 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 1bd70d306c22..1eaacab0334b 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
@@ -153,8 +153,9 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
return result;
 }
 
-static void get_payload_table(struct amdgpu_dm_connector *aconnector,
- struct dc_dp_mst_stream_allocation_table 
*proposed_table)
+static void
+fill_dc_mst_payload_table_from_drm(struct amdgpu_dm_connector *aconnector,
+  struct dc_dp_mst_stream_allocation_table 
*proposed_table)
 {
int i;
struct drm_dp_mst_topology_mgr *mst_mgr =
@@ -252,7 +253,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 * stream. AMD ASIC stream slot allocation should follow the same
 * sequence. copy DRM MST allocation to dc */
 
-   get_payload_table(aconnector, proposed_table);
+   fill_dc_mst_payload_table_from_drm(aconnector, proposed_table);
 
return true;
 }
-- 
2.35.3



[RFC 04/18] drm/display/dp_mst: Call them time slots, not VCPI slots

2022-06-07 Thread Lyude Paul
VCPI is only sort of the correct term here, originally the majority of this
code simply referred to timeslots vaguely as "slots" - and since I started
working on it and adding atomic functionality, the name "VCPI slots" has
been used to represent time slots.

Now that we actually have consistent access to the DisplayPort spec thanks
to VESA, I now know this isn't actually the proper term - as the
specification refers to these as time slots.

Since we're trying to make this code as easy to figure out as possible,
let's take this opportunity to correct this nomenclature and call them by
their proper name - timeslots. Likewise, we rename various functions
appropriately, along with replacing references in the kernel documentation
and various debugging messages.

It's important to note that this patch series leaves the legacy MST code
untouched for the most part, which is fine since we'll be removing it soon
anyhow. There should be no functional changes in this series.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  28 ++---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 106 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   5 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |   4 +-
 include/drm/display/drm_dp_mst_helper.h   |   6 +-
 6 files changed, 75 insertions(+), 76 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 ad4571190a90..f84a4ad736d8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7393,7 +7393,7 @@ static int dm_encoder_helper_atomic_check(struct 
drm_encoder *encoder,
clock = adjusted_mode->clock;
dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, 
false);
}
-   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_vcpi_slots(state,
+   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_time_slots(state,
   
mst_mgr,
   
mst_port,
   
dm_new_connector_state->pbn,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 9221b6690a4a..e40ff51e7be0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -378,7 +378,7 @@ static int dm_dp_mst_atomic_check(struct drm_connector 
*connector,
return 0;
}
 
-   return drm_dp_atomic_release_vcpi_slots(state,
+   return drm_dp_atomic_release_time_slots(state,
mst_mgr,
mst_port);
 }
@@ -689,7 +689,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
 
if (initial_slack[next_index] > fair_pbn_alloc) {
vars[next_index].pbn += fair_pbn_alloc;
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
  
params[next_index].port,
  vars[next_index].pbn,
@@ -699,7 +699,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
vars[next_index].bpp_x16 = 
bpp_x16_from_pbn(params[next_index], vars[next_index].pbn);
} else {
vars[next_index].pbn -= fair_pbn_alloc;
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
  
params[next_index].port,
  
vars[next_index].pbn,
@@ -708,7 +708,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
}
} else {
vars[next_index].pbn += initial_slack[next_index];
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
   

[RESEND RFC 00/18] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only

2022-06-07 Thread Lyude Paul
Ugh, thanks ./scripts/get_maintainers.pl for confusing and breaking
git-send email <<. Sorry for the resend everyone.

For quite a while we've been carrying around a lot of legacy modesetting
code in the MST helpers that has been rather annoying to keep around,
and very often gets in the way of trying to implement additional
functionality in MST such as fallback link rate retraining, dynamic BPC
management and DSC support, etc. because of the fact that we can't rely
on atomic for everything.

Luckily, we only actually have one user of the legacy MST code in the
kernel - radeon. Originally I was thinking of trying to maintain this
code and keep it around in some form, but I'm pretty unconvinced anyone
is actually using this. My reasoning for that is because I've seen
nearly no issues regarding MST on radeon for quite a while now - despite
the fact my local testing seems to indicate it's quite broken. This
isn't too surprising either, as MST support in radeon.ko is gated behind
a module parameter that isn't enabled by default. This isn't to say I
wouldn't be open to alternative suggestions, but I'd rather not be the
one to have to spend time on that if at all possible! Plus, I already
floated the idea of dropping this code by AMD folks a few times and
didn't get much resistance.

As well, this series has some basic refactoring that I did along the way
and some bugs I had to fix in order to get my atomic-only MST code
working. Most of this is pretty straight forward and simply renaming
things to more closely match the DisplayPort specification, as I think
this will also make maintaining this code a lot easier in the long run
(I've gotten myself confused way too many times because of this).

So far I've tested this on all three MST drivers: amdgpu, i915 and
nouveau, along with making sure that removing the radeon MST code
doesn't break anything else. The one thing I very much could use help
with regarding testing though is making sure that this works with
amdgpu's DSC support on MST.

So, with this we should be using the atomic state as much as possible
with MST modesetting, hooray!

Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 

Lyude Paul (18):
  drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)
  drm/amdgpu/dm/mst: Rename get_payload_table()
  drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation
  drm/display/dp_mst: Call them time slots, not VCPI slots
  drm/display/dp_mst: Fix confusing docs for
drm_dp_atomic_release_time_slots()
  drm/display/dp_mst: Add some missing kdocs for atomic MST structs
  drm/display/dp_mst: Add helper for finding payloads in atomic MST
state
  drm/display/dp_mst: Add nonblocking helpers for DP MST
  drm/display/dp_mst: Don't open code modeset checks for releasing time
slots
  drm/display/dp_mst: Fix modeset tracking in
drm_dp_atomic_release_vcpi_slots()
  drm/nouveau/kms: Cache DP encoders in nouveau_connector
  drm/nouveau/kms: Pull mst state in for all modesets
  drm/display/dp_mst: Add helpers for serializing SST <-> MST
transitions
  drm/display/dp_mst: Drop all ports from topology on CSNs before
queueing link address work
  drm/display/dp_mst: Skip releasing payloads if last connected port
isn't connected
  drm/display/dp_mst: Maintain time slot allocations when deleting
payloads
  drm/radeon: Drop legacy MST support
  drm/display/dp_mst: Move all payload info into the atomic state

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   72 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  111 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  126 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |   10 +-
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |4 +-
 .../amd/display/include/link_service_types.h  |   18 +-
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 1160 -
 drivers/gpu/drm/i915/display/intel_display.c  |   11 +
 drivers/gpu/drm/i915/display/intel_dp.c   |9 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   91 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c |   24 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  202 ++-
 drivers/gpu/drm/nouveau/dispnv50/disp.h   |2 +
 drivers/gpu/drm/nouveau/nouveau_connector.c   |   18 +-
 drivers/gpu/drm/nouveau/nouveau_connector.h   |3 +
 drivers/gpu/drm/radeon/Makefile   |2 +-
 drivers/gpu/drm/radeon/atombios_crtc.c|   11 +-
 drivers/gpu/drm/radeon/atombios_encoders.c|   59 -
 drivers/gpu/drm/radeon/radeon_atombios.c  |2 -
 drivers/gpu/drm/radeon/radeon_connectors.c|   61 +-
 drivers/gpu/drm/radeon/radeon_device.c|1 -
 drivers/gpu/drm/radeon/radeon_dp_mst.c|  778 ---
 drivers/gpu/drm/radeon/radeon_drv.c   |4 -
 drivers/gpu/drm/radeon/radeon_encoders.c  |   14 +-
 drivers/gpu/drm/radeon/radeon_irq_kms.c   |   10 +-
 drivers/gpu/drm/radeon/radeon_mode.h  |   4

[RESEND RFC 03/18] drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation

2022-06-07 Thread Lyude Paul
In retrospect, the name I chose for this originally is confusing, as
there's a lot more info in here then just the VCPI. This really should be
called a payload. Let's make it more obvious that this is meant to be
related to the atomic state and is about payloads by renaming it to
drm_dp_mst_atomic_payload. Also, rename various variables throughout the
code that use atomic payloads.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 96 +--
 include/drm/display/drm_dp_mst_helper.h   |  4 +-
 2 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 67b3b9697da7..38eecb89e22d 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4381,7 +4381,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state 
*state,
  int pbn_div)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_vcpi_allocation *pos, *vcpi = NULL;
+   struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
int prev_slots, prev_bw, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
@@ -4389,11 +4389,11 @@ int drm_dp_atomic_find_vcpi_slots(struct 
drm_atomic_state *state,
return PTR_ERR(topology_state);
 
/* Find the current allocation for this port, if any */
-   list_for_each_entry(pos, _state->vcpis, next) {
+   list_for_each_entry(pos, _state->payloads, next) {
if (pos->port == port) {
-   vcpi = pos;
-   prev_slots = vcpi->vcpi;
-   prev_bw = vcpi->pbn;
+   payload = pos;
+   prev_slots = payload->vcpi;
+   prev_bw = payload->pbn;
 
/*
 * This should never happen, unless the driver tries
@@ -4410,7 +4410,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state 
*state,
break;
}
}
-   if (!vcpi) {
+   if (!payload) {
prev_slots = 0;
prev_bw = 0;
}
@@ -4428,17 +4428,17 @@ int drm_dp_atomic_find_vcpi_slots(struct 
drm_atomic_state *state,
   port, prev_bw, pbn);
 
/* Add the new allocation to the state */
-   if (!vcpi) {
-   vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL);
-   if (!vcpi)
+   if (!payload) {
+   payload = kzalloc(sizeof(*payload), GFP_KERNEL);
+   if (!payload)
return -ENOMEM;
 
drm_dp_mst_get_port_malloc(port);
-   vcpi->port = port;
-   list_add(>next, _state->vcpis);
+   payload->port = port;
+   list_add(>next, _state->payloads);
}
-   vcpi->vcpi = req_slots;
-   vcpi->pbn = pbn;
+   payload->vcpi = req_slots;
+   payload->pbn = pbn;
 
return req_slots;
 }
@@ -4475,21 +4475,21 @@ int drm_dp_atomic_release_vcpi_slots(struct 
drm_atomic_state *state,
 struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_vcpi_allocation *pos;
+   struct drm_dp_mst_atomic_payload *pos;
bool found = false;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   list_for_each_entry(pos, _state->vcpis, next) {
+   list_for_each_entry(pos, _state->payloads, next) {
if (pos->port == port) {
found = true;
break;
}
}
if (WARN_ON(!found)) {
-   drm_err(mgr->dev, "no VCPI for [MST PORT:%p] found in mst state 
%p\n",
+   drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
port, _state->base);
return -EINVAL;
}
@@ -5072,7 +5072,7 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 {
struct drm_dp_mst_topology_state *state, *old_state =
to_dp_mst_topology_state(obj->state);
-   struct drm_dp_vcpi_allocation *pos, *vcpi;
+   struct drm_dp_mst_atomic_payload *pos, *payload;
 
state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
if (!state)
@@ -5080,25 +5080,25 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 
__drm_atomic_helper_private_obj_duplicate_state(obj, >base);
 
-   INIT_LIST_HEAD(>vcpis);
+   INIT_LIST_HEAD(>

[RESEND RFC 01/18] drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)

2022-06-07 Thread Lyude Paul
Just to make this more clear to outside contributors that these are
DC-specific structs, as this also threw me into a loop a number of times
before I figured out the purpose of this.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Fangzhi Zuo 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  9 -
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 10 +-
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |  4 ++--
 .../gpu/drm/amd/display/include/link_service_types.h  | 11 ---
 4 files changed, 19 insertions(+), 15 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 7c799ddc1d27..1bd70d306c22 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
@@ -153,9 +153,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
return result;
 }
 
-static void get_payload_table(
-   struct amdgpu_dm_connector *aconnector,
-   struct dp_mst_stream_allocation_table *proposed_table)
+static void get_payload_table(struct amdgpu_dm_connector *aconnector,
+ struct dc_dp_mst_stream_allocation_table 
*proposed_table)
 {
int i;
struct drm_dp_mst_topology_mgr *mst_mgr =
@@ -177,7 +176,7 @@ static void get_payload_table(
mst_mgr->payloads[i].payload_state ==
DP_PAYLOAD_REMOTE) {
 
-   struct dp_mst_stream_allocation *sa =
+   struct dc_dp_mst_stream_allocation *sa =
_table->stream_allocations[
proposed_table->stream_count];
 
@@ -201,7 +200,7 @@ void dm_helpers_dp_update_branch_info(
 bool dm_helpers_dp_mst_write_payload_allocation_table(
struct dc_context *ctx,
const struct dc_stream_state *stream,
-   struct dp_mst_stream_allocation_table *proposed_table,
+   struct dc_dp_mst_stream_allocation_table *proposed_table,
bool enable)
 {
struct amdgpu_dm_connector *aconnector;
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 a789ea8af27f..db0f5158a0c2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3424,7 +3424,7 @@ static void update_mst_stream_alloc_table(
struct dc_link *link,
struct stream_encoder *stream_enc,
struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename 
stream_enc to dio_stream_enc?
-   const struct dp_mst_stream_allocation_table *proposed_table)
+   const struct dc_dp_mst_stream_allocation_table *proposed_table)
 {
struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 
};
struct link_mst_stream_allocation *dc_alloc;
@@ -3586,7 +3586,7 @@ enum dc_status dc_link_allocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 {
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
@@ -3691,7 +3691,7 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx 
*pipe_ctx, uint32_t bw
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = get_link_hwss(link, 
_ctx->link_res);
@@ -3779,7 +3779,7 @@ enum dc_status dc_link_increase_mst_payload(struct 
pipe_ctx *pipe_ctx, uint32_t
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
struct link_encoder *link_encoder = link->link_enc;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = get_link_hwss(link, 
_ctx->link_res);
@@ -3855,7 +3855,7 @@ static enum dc_status deallocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 {
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
int i;
bool mst_mode = (link->type == dc_c

[RESEND RFC 13/18] drm/display/dp_mst: Add helpers for serializing SST <-> MST transitions

2022-06-07 Thread Lyude Paul
There's another kind of situation where we could potentially race with
nonblocking modesets and MST, especially if we were to only use the locking
provided by atomic modesetting:

* Display 1 begins as enabled on DP-1 in SST mode
* Display 1 switches to MST mode, exposes one sink in MST mode
* Userspace does non-blocking modeset to disable the SST display
* Userspace does non-blocking modeset to enable the MST display with a
  different CRTC, but the SST display hasn't been fully taken down yet
* Execution order between the last two commits isn't guaranteed since they
  share no drm resources

We can fix this however, by ensuring that we always pull in the atomic
topology state whenever a connector capable of driving an MST display
performs its atomic check - and then tracking CRTC commits happening on the
SST connector in the MST topology state. So, let's add some simple helpers
for doing that and hook them up in various drivers.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 +++
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 59 +++
 drivers/gpu/drm/i915/display/intel_dp.c   |  9 +++
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  2 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.h   |  2 +
 drivers/gpu/drm/nouveau/nouveau_connector.c   | 14 +
 include/drm/display/drm_dp_mst_helper.h   |  2 +
 7 files changed, 94 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 d9c7393ef151..ac8648e3c1c9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7177,10 +7177,17 @@ amdgpu_dm_connector_atomic_check(struct drm_connector 
*conn,
drm_atomic_get_old_connector_state(state, conn);
struct drm_crtc *crtc = new_con_state->crtc;
struct drm_crtc_state *new_crtc_state;
+   struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(conn);
int ret;
 
trace_amdgpu_dm_connector_atomic_check(new_con_state);
 
+   if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+   ret = drm_dp_mst_root_conn_atomic_check(new_con_state, 
>mst_mgr);
+   if (ret < 0)
+   return ret;
+   }
+
if (!crtc)
return 0;
 
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index c5edcf2a26c8..a775f9437868 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4608,6 +4608,65 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct 
drm_atomic_state *state)
 }
 EXPORT_SYMBOL(drm_dp_mst_atomic_wait_for_dependencies);
 
+/**
+ * drm_dp_mst_root_conn_atomic_check() - Serialize CRTC commits on MST-capable 
connectors operating
+ * in SST mode
+ * @new_conn_state: The new connector state of the _connector
+ * @mgr: The MST topology manager for the _connector
+ *
+ * Since MST uses fake _encoder structs, the generic atomic modesetting 
code isn't able to
+ * serialize non-blocking commits happening on the real DP connector of an MST 
topology switching
+ * into/away from MST mode - as the CRTC on the real DP connector and the 
CRTCs on the connector's
+ * MST topology will never share the same _encoder.
+ *
+ * This function takes care of this serialization issue, by checking a root 
MST connector's atomic
+ * state to determine if it is about to have a modeset - and then pulling in 
the MST topology state
+ * if so, along with adding any relevant CRTCs to 
_dp_mst_topology_state.pending_crtc_mask.
+ *
+ * Drivers implementing MST must call this function from the
+ * _connector_helper_funcs.atomic_check hook of any physical DP 
_connector capable of
+ * driving MST sinks.
+ *
+ * Returns:
+ * 0 on success, negative error code otherwise
+ */
+int drm_dp_mst_root_conn_atomic_check(struct drm_connector_state 
*new_conn_state,
+ struct drm_dp_mst_topology_mgr *mgr)
+{
+   struct drm_atomic_state *state = new_conn_state->state;
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, 
new_conn_state->connector);
+   struct drm_crtc_state *crtc_state;
+   struct drm_dp_mst_topology_state *mst_state = NULL;
+
+   if (new_conn_state->crtc) {
+   crtc_state = drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
+   if (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)) {
+   mst_state = drm_atomic_get_mst_topology_state(state, 
mgr);
+   if (IS_ERR(mst_state))
+   return PTR_ERR(mst_state);
+
+   mst_state->

Re: [PATCH v2 00/29] drm/kms: Stop registering multiple /sys/class/backlight devs for a single display

2022-07-14 Thread Lyude Paul
--
>  drivers/platform/x86/apple-gmux.c |   3 -
>  drivers/platform/x86/asus-nb-wmi.c    |  21 -
>  drivers/platform/x86/asus-wmi.c   |  13 -
>  drivers/platform/x86/asus-wmi.h       |   2 -
>  drivers/platform/x86/eeepc-wmi.c  |  25 +-
>  drivers/platform/x86/samsung-laptop.c |  87 
>  drivers/platform/x86/toshiba_acpi.c   |  16 -
>  include/acpi/video.h  |   9 +-
>  26 files changed, 468 insertions(+), 415 deletions(-)
> 

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



Re: [PATCH v2 05/29] drm/nouveau: Don't register backlight when another backlight should be used

2022-07-14 Thread Lyude Paul
Reviewed-by: Lyude Paul 

You also have permission to push this to drm-misc-whatever

On Tue, 2022-07-12 at 21:38 +0200, Hans de Goede wrote:
> Before this commit when we want userspace to use the acpi_video backlight
> device we register both the GPU's native backlight device and acpi_video's
> firmware acpi_video# backlight device. This relies on userspace preferring
> firmware type backlight devices over native ones.
> 
> Registering 2 backlight devices for a single display really is
> undesirable, don't register the GPU's native backlight device when
> another backlight device should be used.
> 
> Reviewed-by: Lyude Paul 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> index a2141d3d9b1d..91c504c7b82c 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> @@ -34,6 +34,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #include "nouveau_drv.h"
>  #include "nouveau_reg.h"
>  #include "nouveau_encoder.h"
> @@ -405,6 +407,11 @@ nouveau_backlight_init(struct drm_connector *connector)
> goto fail_alloc;
> }
>  
> +   if (!acpi_video_backlight_use_native()) {
> +   NV_INFO(drm, "Skipping nv_backlight registration\n");
> +   goto fail_alloc;
> +   }
> +
> if (!nouveau_get_backlight_name(backlight_name, bl)) {
> NV_ERROR(drm, "Failed to retrieve a unique name for the
> backlight interface\n");
> goto fail_alloc;

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



Re: [RESEND RFC 00/18] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only

2022-07-28 Thread Lyude Paul
Sorry for taking a while on respinning this! I've been busy with trying to
review as much nouveau patches as possible before we passed the deadline for
getting pulled into the kernel, since we've got quite a lot of pending patches
coming up. The pull deadline we had from Dave has passed at this point though,
so I should have a chance to respin this in the next few business days.

On Tue, 2022-06-07 at 15:29 -0400, Lyude Paul wrote:
> Ugh, thanks ./scripts/get_maintainers.pl for confusing and breaking
> git-send email <<. Sorry for the resend everyone.
> 
> For quite a while we've been carrying around a lot of legacy modesetting
> code in the MST helpers that has been rather annoying to keep around,
> and very often gets in the way of trying to implement additional
> functionality in MST such as fallback link rate retraining, dynamic BPC
> management and DSC support, etc. because of the fact that we can't rely
> on atomic for everything.
> 
> Luckily, we only actually have one user of the legacy MST code in the
> kernel - radeon. Originally I was thinking of trying to maintain this
> code and keep it around in some form, but I'm pretty unconvinced anyone
> is actually using this. My reasoning for that is because I've seen
> nearly no issues regarding MST on radeon for quite a while now - despite
> the fact my local testing seems to indicate it's quite broken. This
> isn't too surprising either, as MST support in radeon.ko is gated behind
> a module parameter that isn't enabled by default. This isn't to say I
> wouldn't be open to alternative suggestions, but I'd rather not be the
> one to have to spend time on that if at all possible! Plus, I already
> floated the idea of dropping this code by AMD folks a few times and
> didn't get much resistance.
> 
> As well, this series has some basic refactoring that I did along the way
> and some bugs I had to fix in order to get my atomic-only MST code
> working. Most of this is pretty straight forward and simply renaming
> things to more closely match the DisplayPort specification, as I think
> this will also make maintaining this code a lot easier in the long run
> (I've gotten myself confused way too many times because of this).
> 
> So far I've tested this on all three MST drivers: amdgpu, i915 and
> nouveau, along with making sure that removing the radeon MST code
> doesn't break anything else. The one thing I very much could use help
> with regarding testing though is making sure that this works with
> amdgpu's DSC support on MST.
> 
> So, with this we should be using the atomic state as much as possible
> with MST modesetting, hooray!
> 
> Cc: Wayne Lin 
> Cc: Ville Syrjälä 
> Cc: Fangzhi Zuo 
> Cc: Jani Nikula 
> Cc: Imre Deak 
> Cc: Daniel Vetter 
> Cc: Sean Paul 
> 
> Lyude Paul (18):
>   drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)
>   drm/amdgpu/dm/mst: Rename get_payload_table()
>   drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation
>   drm/display/dp_mst: Call them time slots, not VCPI slots
>   drm/display/dp_mst: Fix confusing docs for
>     drm_dp_atomic_release_time_slots()
>   drm/display/dp_mst: Add some missing kdocs for atomic MST structs
>   drm/display/dp_mst: Add helper for finding payloads in atomic MST
>     state
>   drm/display/dp_mst: Add nonblocking helpers for DP MST
>   drm/display/dp_mst: Don't open code modeset checks for releasing time
>     slots
>   drm/display/dp_mst: Fix modeset tracking in
>     drm_dp_atomic_release_vcpi_slots()
>   drm/nouveau/kms: Cache DP encoders in nouveau_connector
>   drm/nouveau/kms: Pull mst state in for all modesets
>   drm/display/dp_mst: Add helpers for serializing SST <-> MST
>     transitions
>   drm/display/dp_mst: Drop all ports from topology on CSNs before
>     queueing link address work
>   drm/display/dp_mst: Skip releasing payloads if last connected port
>     isn't connected
>   drm/display/dp_mst: Maintain time slot allocations when deleting
>     payloads
>   drm/radeon: Drop legacy MST support
>   drm/display/dp_mst: Move all payload info into the atomic state
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   72 +-
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  111 +-
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  126 +-
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c |   10 +-
>  drivers/gpu/drm/amd/display/dc/dm_helpers.h   |    4 +-
>  .../amd/display/include/link_service_types.h  |   18 +-
>  drivers/gpu/drm/display/drm_dp_mst_topology.c | 1160 -
>  drivers/gpu/drm/i915/display/intel_display.c  |   11 +
>  drivers/gpu/drm/i915/display/intel_dp.c   |    9 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   91 +-
>  drivers/gpu/drm/i915/display/intel_hdcp

Re: Do we really need to increase/decrease MST VC payloads?

2022-05-04 Thread Lyude Paul
Some good news: I actually came up with a way of handling this in the new MST
code pretty nicely, so I think we should be able to move forward without
having to disable this (although it would be very nice to know whether or not
this is necessary for amdgpu to work, since it'd still be nice to split this
into separate changes to make reviewing my big MST patch series easier. More
comments down below:

On Mon, 2022-05-02 at 18:40 -0400, Lyude Paul wrote:
> Hi! So I kinda hate to ask this, but finding this in amdgpu completely took
> me
> by surprise and unfortunately is (while technically correct) an enormous
> pain
> and not really necessary as far as I'm aware.
> 
> So: it seems that amdgpu is currently the only driver that not only
> allocates/deallocates payloads, but it also increases/decreases the size of
> payloads as well. This was added in:
> 
>    d740e0bf8ed4 ("drm/amd/display: Add DP 2.0 MST DC Support")
> 
> This is fine, except that it's totally not at all a situation that the
> current
> payload management code we have (which, is the first place this should have
> been implemented) knows how to handle, because every other driver simply
> allocates/releases payloads. Having to increase the size of payloads means
> that we no longer can count on the payload table being contiguous, and means
> we have to resort to coming up with a more complicated solution to actually
> do
> payload management atomically.
> 
> I'm willing to try to do that (it should be doable by using bitmasks to
> track
> non-contiguous allocated slots), but considering:
>  * This isn't actually needed for DP 2.0 to work as far as I'm aware (if I'm
>    wrong please correct me! but I see no issue with just deallocating and
>    allocating payloads). It's nice to have, but not necessary.
>  * This was from the DSC MST series, which included a lot of code that I
>    mentioned at the time needed to not live in amdgpu and be moved into
> other
>    helpers. That hasn't really happened yet, and there are no signs of it
>    happening from amd's side - and I just plain do not want to have to be
> the
>    person to do that when I can help it. Going through amdgpu takes a
> serious
>    amount of energy because of all of the abstraction layers, enough so I
>    honestly didn't even notice this VC table change when I looked at the
>    series this was from. (Or maybe I did, but didn't fully grasp what was
>    changing at the time :\).
>  * Also on that note, are we even sure that this works with subsequent VC
>    changes? E.g. has anyone tested this with physical hardware? I don't know
>    that I actually have the hardware to test this out, but
>    drm_dp_update_payload*() absolutely doesn't understand non-contiguous
>    payloads which I would think could lead to the VCPI start slots getting
>    miscalculated if a payload increase/decreases (happy to give further
>    explanation on this if needed). Note if this is the case, please hold off
> a
>    bit before trying to fix it and consider just not doing this for the time
>    being.

Sorry for being a bit vague with this! I typed this email at the end of
the workday and didn't feel like going super into detail on this. So I
guess I'll do that now (hopefully I didn't misread the MST spec
somewhere):

For reference: the issue I was mentioning here was regarding the fact
that the current payload management code we have doesn't keep track of
exactly which VC slots are in use by a payload at any given time - only
the starting slots and total slot counts of each payload. Which means
that once we increase a MST payload, since the additional VC slots will
be put at the end of the VC table regardless of the start of the
payload. As such, it's possible that said payload will no longer be
contiguous. An example, note for simplicity sake this example pretends
we only have 8 VC slots instead of 64:

Payloads: #1 == 2 slots, #2 == 1 slot, #3 == 2 slots

VC table looks like this, where each number corresponds to a VCPI and
X means unused:

|1 1 2 3 3 X X X|

We decide we need to increase payload #1 from 2 slots to 3. The MST spec
mandates that new slots always are added to the end, so we end up with
this surprising VC table:

|1 1 2 3 3 1 X X|

Now, let's say we increase payload #2 to 2 slots:

|1 1 2 3 3 1 2 X|

Surprise - the monitor for payload #1 was unplugged, so we need to
remove it's payload. Note the MST spec doesn't allow holes between
allocations, and makes branches repsonsible for automatically moving
payloads to fill in the gaps which we have to keep track of locally.
Normally the handling of holes would be fine, as our current payload
management code loops through each payload to fill in any holes. But
these payloads aren't contiguous and we only kept track of their start
slots and to

Do we really need to increase/decrease MST VC payloads?

2022-05-02 Thread Lyude Paul
Hi! So I kinda hate to ask this, but finding this in amdgpu completely took me
by surprise and unfortunately is (while technically correct) an enormous pain
and not really necessary as far as I'm aware.

So: it seems that amdgpu is currently the only driver that not only
allocates/deallocates payloads, but it also increases/decreases the size of
payloads as well. This was added in:

   d740e0bf8ed4 ("drm/amd/display: Add DP 2.0 MST DC Support")

This is fine, except that it's totally not at all a situation that the current
payload management code we have (which, is the first place this should have
been implemented) knows how to handle, because every other driver simply
allocates/releases payloads. Having to increase the size of payloads means
that we no longer can count on the payload table being contiguous, and means
we have to resort to coming up with a more complicated solution to actually do
payload management atomically.

I'm willing to try to do that (it should be doable by using bitmasks to track
non-contiguous allocated slots), but considering:
 * This isn't actually needed for DP 2.0 to work as far as I'm aware (if I'm
   wrong please correct me! but I see no issue with just deallocating and
   allocating payloads). It's nice to have, but not necessary.
 * This was from the DSC MST series, which included a lot of code that I
   mentioned at the time needed to not live in amdgpu and be moved into other
   helpers. That hasn't really happened yet, and there are no signs of it
   happening from amd's side - and I just plain do not want to have to be the
   person to do that when I can help it. Going through amdgpu takes a serious
   amount of energy because of all of the abstraction layers, enough so I
   honestly didn't even notice this VC table change when I looked at the
   series this was from. (Or maybe I did, but didn't fully grasp what was
   changing at the time :\).
 * Also on that note, are we even sure that this works with subsequent VC
   changes? E.g. has anyone tested this with physical hardware? I don't know
   that I actually have the hardware to test this out, but
   drm_dp_update_payload*() absolutely doesn't understand non-contiguous
   payloads which I would think could lead to the VCPI start slots getting
   miscalculated if a payload increase/decreases (happy to give further
   explanation on this if needed). Note if this is the case, please hold off a
   bit before trying to fix it and consider just not doing this for the time
   being.

I'd /very/ much like to just disable this behavior for the time being (not the
whole commit for DP 2.0 support since that'd be unreasonable, just the
increase/decrease payload changes), and eventually have someone just implement
this the proper way by adding support for this into the MST helpers and
teaching them how to handle non-contiguous payloads. I'm happy to leave as
much of the code intact as possible (maybe with #if 0 or whatever), and
ideally just add some code somewhere to avoid increasing/decreasing payloads
without a full modeset.

FWIW, the WIP of my atomic MST work is here: 

https://gitlab.freedesktop.org/lyudess/linux/-/commits/wip/mst-atomic-only-v1

I already have i915 and nouveau working with these changes JFYI.
-- 
Cheers, Lyude Paul (she/her) Software Engineer at Red Hat



Re: Do we really need to increase/decrease MST VC payloads?

2022-05-10 Thread Lyude Paul
On Thu, 2022-05-05 at 10:02 +, Lin, Wayne wrote:
> 
> I think this shouldn't happen. Please refer to the figure 2-98 of DP spec
> 1.4.
> The payload id table should be changed to below I think.
> 
>     |1 1 1 2 3 3 X X|
> 
> I skimmed over a bit of the implementation in drm. I think it should work
> fine
> except that we have to revise function drm_dp_init_vcpi() a bit.
> Since increasing/decreasing time slots should still use the same payload id,
> we should add logic to skip trying to assign a new payload id under this
> case.

I'm not sure about that tbh, since the example you gave also still mentions VC
#1 which is supposed to be disabled here.

FWIW, I was alerted to this pecularity when I noticed Figure 2-93 from chapter
2.6.5 of the DP 2.0 spec. Notice that on the diagram it mentions time slots 1-
20 allocated to VC1, time slots 21-32 being allocated to VC2, and then
(confusingly in a different color) mentions that time slots 33-47 are
allocated to VC1 again.

At first I honestly thought this was a typo in the spec, but it's done
multiple times and it _does_ actually make sense when you think about it for a
little while. Consider that the advantage of having VC allocations work this
way would be that you're able to increase the time slots allocated to a VC
without having to even change their start slots - meaning those other payloads
don't need to be disrupted in any way. This is only as far as I can tell if
you have non-contiguous payloads.

> 
> > > 
> > >     |1 1 2 3 3 1 X X|
> > > 
> > > Now, let's say we increase payload #2 to 2 slots:
> > > 
> > >     |1 1 2 3 3 1 2 X|
> > > 
> > > Surprise - the monitor for payload #1 was unplugged, so we need to
> > > remove
> > > it's payload. Note the MST spec doesn't allow holes between allocations,
> > > and
> > > makes branches repsonsible for automatically moving payloads to fill in
> > > the
> > > gaps which we have to keep track of locally.
> > > Normally the handling of holes would be fine, as our current payload
> > > management code loops through each payload to fill in any holes. But
> > > these
> > > payloads aren't contiguous and we only kept track of their start slots
> > > and
> > > total slot counts. So we would end up thinking we now have a VC table
> > > like
> > > this:
> > > 
> > >     |2 2 3 3 X X X X|
> > > 
> > > But that's wrong, in reality the table will look like this on the MST
> > > hub:
> > > 
> > >     |2 3 3 2 X X X X|
> > > 
> > > Now things are broken, because we now have the wrong start slot for
> > > payload #3.
> > > 
> > > Just figured I'd clarify :). if anyone is curious, I ended up fixing
> > > this by adding
> > > a bitmask of assigned VC slots to our atomic payload struct - and using
> > > that
> > > to keep track of the current start slots for each payload. Since we have
> > > a max
> > > of 64 VC slots which fits into a u64, this works rather elegantly!
> > > 
> > > > 
> > > > I'd /very/ much like to just disable this behavior for the time being
> > > > (not the whole commit for DP 2.0 support since that'd be unreasonable,
> > > > just the increase/decrease payload changes), and eventually have
> > > > someone just implement this the proper way by adding support for this
> > > > into the MST helpers and teaching them how to handle non-contiguous
> > > > payloads. I'm happy to leave as much of the code intact as possible
> > > > (maybe with #if 0 or whatever), and ideally just add some code
> > > > somewhere to avoid increasing/decreasing payloads without a full
> > > > modeset.
> > > > 
> > > > FWIW, the WIP of my atomic MST work is here:
> > > > 
> > > > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl
> > > > ab.freedesktop.org%2Flyudess%2Flinux%2F-%2Fcommits%2Fwip%2Fmst-
> > > atomic-
> > > > only-
> > > v1data=05%7C01%7Cjerry.zuo%40amd.com%7Cf669121b53414c0dbc9
> > > 40
> > > > 
> > > 8da2e137e85%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6378
> > > 729585141
> > > > 
> > > 60092%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2lu
> > > MzIiLCJB
> > > > 
> > > TiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7Csdata=IBn%2BF5
> > > 0r9WIeUfG
> > > > 9MUGStbACr5Kolu3PB5K0dyiiYwg%3Dreserved=0
> > > > 
> > > > I already have i915 and nouveau working with these changes JFYI.
> > > 
> > > --
> > > Cheers,
> > >  Lyude Paul (she/her)
> > >  Software Engineer at Red Hat
> 
> --
> Regards,
> Wayne Lin
> 

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



[PATCH] drm/amdgpu: Add 'modeset' module parameter

2022-05-11 Thread Lyude Paul
Many DRM drivers feature a 'modeset' argument, which can be used to
enable/disable the entire driver (as opposed to passing nomodeset to the
kernel, which would disable modesetting globally and make it difficult to
load amdgpu afterwards). Apparently amdgpu is actually missing this
however, so let's add it!

Keep in mind that this currently just lets one enable or disable amdgpu, I
haven't bothered adding a headless mode like nouveau has - however I'm sure
someone else can add this if needed.

Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index ebd37fb19cdb..24e6fb4517cc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -872,6 +872,15 @@ MODULE_PARM_DESC(smu_pptable_id,
"specify pptable id to be used (-1 = auto(default) value, 0 = use 
pptable from vbios, > 0 = soft pptable id)");
 module_param_named(smu_pptable_id, amdgpu_smu_pptable_id, int, 0444);
 
+/**
+ * DOC: modeset (int)
+ * Used to enable/disable modesetting for amdgpu exclusively.
+ */
+bool amdgpu_enable_modeset = true;
+MODULE_PARM_DESC(modeset,
+"Enable or disable display driver (1 = on (default), 0 = off");
+module_param_named(modeset, amdgpu_enable_modeset, bool, 0444);
+
 /* These devices are not supported by amdgpu.
  * They are supported by the mach64, r128, radeon drivers
  */
@@ -2003,6 +2012,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
bool is_fw_fb;
resource_size_t base, size;
 
+   if (!amdgpu_enable_modeset) {
+   DRM_INFO("modeset=0 passed to amdgpu, driver will not be 
enabled\n");
+   return -ENODEV;
+   }
+
/* skip devices which are owned by radeon */
for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) {
if (amdgpu_unsupported_pciidlist[i] == pdev->device)
-- 
2.35.1



[RFC v4 15/17] drm/display/dp_mst: Maintain time slot allocations when deleting payloads

2022-08-24 Thread Lyude Paul
Currently, we set drm_dp_atomic_payload->time_slots to 0 in order to
indicate that we're about to delete a payload in the current atomic state.
Since we're going to be dropping all of the legacy code for handling the
payload table however, we need to be able to ensure that we still keep
track of the current time slot allocations for each payload so we can reuse
this info when asking the root MST hub to delete payloads. We'll also be
using it to recalculate the start slots of each VC.

So, let's keep track of the intent of a payload in drm_dp_atomic_payload by
adding ->delete, which we set whenever we're planning on deleting a payload
during the current atomic commit.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 14 +++---
 include/drm/display/drm_dp_mst_helper.h   |  5 -
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index a5460cadf2c8..c4073d733c59 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4407,7 +4407,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state 
*state,
 * releasing and allocating the same timeslot allocation,
 * which is an error
 */
-   if (WARN_ON(!prev_slots)) {
+   if (drm_WARN_ON(mgr->dev, payload->delete)) {
drm_err(mgr->dev,
"cannot allocate and release time slots on [MST 
PORT:%p] in the same state\n",
port);
@@ -4512,10 +4512,10 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
}
 
drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, 
payload->time_slots);
-   if (payload->time_slots) {
+   if (!payload->delete) {
drm_dp_mst_put_port_malloc(port);
-   payload->time_slots = 0;
payload->pbn = 0;
+   payload->delete = true;
}
 
return 0;
@@ -5239,7 +5239,7 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 
list_for_each_entry(pos, _state->payloads, next) {
/* Prune leftover freed timeslot allocations */
-   if (!pos->time_slots)
+   if (pos->delete)
continue;
 
payload = kmemdup(pos, sizeof(*payload), GFP_KERNEL);
@@ -5271,8 +5271,8 @@ static void drm_dp_mst_destroy_state(struct 
drm_private_obj *obj,
int i;
 
list_for_each_entry_safe(pos, tmp, _state->payloads, next) {
-   /* We only keep references to ports with non-zero VCPIs */
-   if (pos->time_slots)
+   /* We only keep references to ports with active payloads */
+   if (!pos->delete)
drm_dp_mst_put_port_malloc(pos->port);
kfree(pos);
}
@@ -5400,7 +5400,7 @@ drm_dp_mst_atomic_check_payload_alloc_limits(struct 
drm_dp_mst_topology_mgr *mgr
 
list_for_each_entry(payload, _state->payloads, next) {
/* Releasing payloads is always OK-even if the port is gone */
-   if (!payload->time_slots) {
+   if (payload->delete) {
drm_dbg_atomic(mgr->dev, "[MST PORT:%p] releases all 
time slots\n",
   payload->port);
continue;
diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index b9c361b242ea..8b847836a0b4 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -560,8 +560,11 @@ struct drm_dp_mst_atomic_payload {
int time_slots;
/** @pbn: The payload bandwidth for this payload */
int pbn;
+
+   /** @delete: Whether or not we intend to delete this payload during 
this atomic commit */
+   bool delete : 1;
/** @dsc_enabled: Whether or not this payload has DSC enabled */
-   bool dsc_enabled;
+   bool dsc_enabled : 1;
 
/** @next: The list node for this payload */
struct list_head next;
-- 
2.37.1



Re: [PATCH v4 31/31] drm/todo: Add entry about dealing with brightness control on devices with > 1 panel

2022-08-25 Thread Lyude Paul
Reviewed-by: Lyude Paul 

On Wed, 2022-08-24 at 14:15 +0200, Hans de Goede wrote:
> Add an entry summarizing the discussion about dealing with brightness
> control on devices with more then 1 internal panel.
> 
> The original discussion can be found here:
> https://lore.kernel.org/dri-devel/20220517152331.16217-1-hdego...@redhat.com/
> 
> Signed-off-by: Hans de Goede 
> ---
>  Documentation/gpu/todo.rst | 68 ++
>  1 file changed, 68 insertions(+)
> 
> diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
> index 7634c27ac562..393d218e4a0c 100644
> --- a/Documentation/gpu/todo.rst
> +++ b/Documentation/gpu/todo.rst
> @@ -679,6 +679,74 @@ Contact: Sam Ravnborg
>  
>  Level: Advanced
>  
> +Brightness handling on devices with multiple internal panels
> +
> +
> +On x86/ACPI devices there can be multiple backlight firmware interfaces:
> +(ACPI) video, vendor specific and others. As well as direct/native (PWM)
> +register programming by the KMS driver.
> +
> +To deal with this backlight drivers used on x86/ACPI call
> +acpi_video_get_backlight_type() which has heuristics (+quirks) to select
> +which backlight interface to use; and backlight drivers which do not match
> +the returned type will not register themselves, so that only one backlight
> +device gets registered (in a single GPU setup, see below).
> +
> +At the moment this more or less assumes that there will only
> +be 1 (internal) panel on a system.
> +
> +On systems with 2 panels this may be a problem, depending on
> +what interface acpi_video_get_backlight_type() selects:
> +
> +1. native: in this case the KMS driver is expected to know which backlight
> +   device belongs to which output so everything should just work.
> +2. video: this does support controlling multiple backlights, but some work
> +   will need to be done to get the output <-> backlight device mapping
> +
> +The above assumes both panels will require the same backlight interface type.
> +Things will break on systems with multiple panels where the 2 panels need
> +a different type of control. E.g. one panel needs ACPI video backlight 
> control,
> +where as the other is using native backlight control. Currently in this case
> +only one of the 2 required backlight devices will get registered, based on
> +the acpi_video_get_backlight_type() return value.
> +
> +If this (theoretical) case ever shows up, then supporting this will need some
> +work. A possible solution here would be to pass a device and connector-name
> +to acpi_video_get_backlight_type() so that it can deal with this.
> +
> +Note in a way we already have a case where userspace sees 2 panels,
> +in dual GPU laptop setups with a mux. On those systems we may see
> +either 2 native backlight devices; or 2 native backlight devices.
> +
> +Userspace already has code to deal with this by detecting if the related
> +panel is active (iow which way the mux between the GPU and the panels
> +points) and then uses that backlight device. Userspace here very much
> +assumes a single panel though. It picks only 1 of the 2 backlight devices
> +and then only uses that one.
> +
> +Note that all userspace code (that I know off) is currently hardcoded
> +to assume a single panel.
> +
> +Before the recent changes to not register multiple (e.g. video + native)
> +/sys/class/backlight devices for a single panel (on a single GPU laptop),
> +userspace would see multiple backlight devices all controlling the same
> +backlight.
> +
> +To deal with this userspace had to always picks one preferred device under
> +/sys/class/backlight and will ignore the others. So to support brightness
> +control on multiple panels userspace will need to be updated too.
> +
> +There are plans to allow brightness control through the KMS API by adding
> +a "display brightness" property to drm_connector objects for panels. This
> +solves a number of issues with the /sys/class/backlight API, including not
> +being able to map a sysfs backlight device to a specific connector. Any
> +userspace changes to add support for brightness control on devices with
> +multiple panels really should build on top of this new KMS property.
> +
> +Contact: Hans de Goede
> +
> +Level: Advanced
> +
>  Outside DRM
>  ===
>  

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



Re: [PATCH v4 05/31] drm/nouveau: Don't register backlight when another backlight should be used (v2)

2022-08-25 Thread Lyude Paul
Just one tiny nitpick below:

On Wed, 2022-08-24 at 14:14 +0200, Hans de Goede wrote:
> Before this commit when we want userspace to use the acpi_video backlight
> device we register both the GPU's native backlight device and acpi_video's
> firmware acpi_video# backlight device. This relies on userspace preferring
> firmware type backlight devices over native ones.
> 
> Registering 2 backlight devices for a single display really is
> undesirable, don't register the GPU's native backlight device when
> another backlight device should be used.
> 
> Changes in v2:
> - Add nouveau_acpi_video_backlight_use_native() wrapper to avoid unresolved
>   symbol errors on non X86
> 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/gpu/drm/nouveau/nouveau_acpi.c  | 5 +
>  drivers/gpu/drm/nouveau/nouveau_acpi.h  | 2 ++
>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 6 ++
>  3 files changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
> b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> index 6140db756d06..1592c9cd7750 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> @@ -386,3 +386,8 @@ nouveau_acpi_edid(struct drm_device *dev, struct 
> drm_connector *connector)
>  
>   return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
>  }
> +
> +bool nouveau_acpi_video_backlight_use_native(void)
> +{
> + return acpi_video_backlight_use_native();
> +}
> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
> b/drivers/gpu/drm/nouveau/nouveau_acpi.h
> index 330f9b837066..3c666c30dfca 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
> @@ -11,6 +11,7 @@ void nouveau_register_dsm_handler(void);
>  void nouveau_unregister_dsm_handler(void);
>  void nouveau_switcheroo_optimus_dsm(void);
>  void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
> +bool nouveau_acpi_video_backlight_use_native(void);
>  #else
>  static inline bool nouveau_is_optimus(void) { return false; };
>  static inline bool nouveau_is_v1_dsm(void) { return false; };
> @@ -18,6 +19,7 @@ static inline void nouveau_register_dsm_handler(void) {}
>  static inline void nouveau_unregister_dsm_handler(void) {}
>  static inline void nouveau_switcheroo_optimus_dsm(void) {}
>  static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
> drm_connector *connector) { return NULL; }
> +static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
> true; }
>  #endif
>  
>  #endif
> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> index a2141d3d9b1d..d2b8f8c13db4 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> @@ -38,6 +38,7 @@
>  #include "nouveau_reg.h"
>  #include "nouveau_encoder.h"
>  #include "nouveau_connector.h"
> +#include "nouveau_acpi.h"
>  
>  static struct ida bl_ida;
>  #define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0'
> @@ -405,6 +406,11 @@ nouveau_backlight_init(struct drm_connector *connector)
>   goto fail_alloc;
>   }
>  
> + if (!nouveau_acpi_video_backlight_use_native()) {
> + NV_INFO(drm, "Skipping nv_backlight registration\n");
> + goto fail_alloc;
> + }

We should probably make this say something like "No native backlight
interface, using ACPI instead" instead. With that fixed

Reviewed-by: Lyude Paul 

> +
>   if (!nouveau_get_backlight_name(backlight_name, bl)) {
>   NV_ERROR(drm, "Failed to retrieve a unique name for the 
> backlight interface\n");
>   goto fail_alloc;

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



Re: [PATCH v4 12/31] drm/nouveau: Register ACPI video backlight when nv_backlight registration fails (v2)

2022-08-25 Thread Lyude Paul
Reviewed-by: Lyude Paul 

On Wed, 2022-08-24 at 14:15 +0200, Hans de Goede wrote:
> Typically the acpi_video driver will initialize before nouveau, which
> used to cause /sys/class/backlight/acpi_video0 to get registered and then
> nouveau would register its own nv_backlight device later. After which
> the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
> to avoid there being 2 backlight devices.
> 
> This means that userspace used to briefly see 2 devices and the
> disappearing of acpi_video0 after a brief time confuses the systemd
> backlight level save/restore code, see e.g.:
> https://bbs.archlinux.org/viewtopic.php?id=269920
> 
> To fix this the ACPI video code has been modified to make backlight class
> device registration a separate step, relying on the drm/kms driver to
> ask for the acpi_video backlight registration after it is done setting up
> its native backlight device.
> 
> Add a call to the new acpi_video_register_backlight() when native backlight
> device registration has failed / was skipped to ensure that there is a
> backlight device available before the drm_device gets registered with
> userspace.
> 
> Changes in v2:
> - Add nouveau_acpi_video_register_backlight() wrapper to avoid unresolved
>   symbol errors on non X86
> 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/gpu/drm/nouveau/nouveau_acpi.c  | 5 +
>  drivers/gpu/drm/nouveau/nouveau_acpi.h  | 2 ++
>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +++
>  3 files changed, 14 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
> b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> index 1592c9cd7750..8cf096f841a9 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> @@ -391,3 +391,8 @@ bool nouveau_acpi_video_backlight_use_native(void)
>  {
>   return acpi_video_backlight_use_native();
>  }
> +
> +void nouveau_acpi_video_register_backlight(void)
> +{
> + acpi_video_register_backlight();
> +}
> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
> b/drivers/gpu/drm/nouveau/nouveau_acpi.h
> index 3c666c30dfca..e39dd8b94b8b 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
> @@ -12,6 +12,7 @@ void nouveau_unregister_dsm_handler(void);
>  void nouveau_switcheroo_optimus_dsm(void);
>  void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
>  bool nouveau_acpi_video_backlight_use_native(void);
> +void nouveau_acpi_video_register_backlight(void);
>  #else
>  static inline bool nouveau_is_optimus(void) { return false; };
>  static inline bool nouveau_is_v1_dsm(void) { return false; };
> @@ -20,6 +21,7 @@ static inline void nouveau_unregister_dsm_handler(void) {}
>  static inline void nouveau_switcheroo_optimus_dsm(void) {}
>  static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
> drm_connector *connector) { return NULL; }
>  static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
> true; }
> +static inline void nouveau_acpi_video_register_backlight(void) {}
>  #endif
>  
>  #endif
> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> index d2b8f8c13db4..a614582779ca 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
> @@ -436,6 +436,13 @@ nouveau_backlight_init(struct drm_connector *connector)
>  
>  fail_alloc:
>   kfree(bl);
> + /*
> +  * If we get here we have an internal panel, but no nv_backlight,
> +  * try registering an ACPI video backlight device instead.
> +  */
> + if (ret == 0)
> + nouveau_acpi_video_register_backlight();
> +
>   return ret;
>  }
>  

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



Re: [RFC v4 00/17] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only

2022-08-23 Thread Lyude Paul
Would anyone have any issues if I merged this today? The whole series is
acked, but I'm not sure if we would like to wait for R-b's?


On Wed, 2022-08-17 at 15:38 -0400, Lyude Paul wrote:
> For quite a while we've been carrying around a lot of legacy modesetting
> code in the MST helpers that has been rather annoying to keep around,
> and very often gets in the way of trying to implement additional
> functionality in MST such as fallback link rate retraining, dynamic BPC
> management and DSC support, etc. because of the fact that we can't rely
> on atomic for everything.
> 
> Luckily, we only actually have one user of the legacy MST code in the
> kernel - radeon. Originally I was thinking of trying to maintain this
> code and keep it around in some form, but I'm pretty unconvinced anyone
> is actually using this. My reasoning for that is because I've seen
> nearly no issues regarding MST on radeon for quite a while now - despite
> the fact my local testing seems to indicate it's quite broken. This
> isn't too surprising either, as MST support in radeon.ko is gated behind
> a module parameter that isn't enabled by default. This isn't to say I
> wouldn't be open to alternative suggestions, but I'd rather not be the
> one to have to spend time on that if at all possible! Plus, I already
> floated the idea of dropping this code by AMD folks a few times and
> didn't get much resistance.
> 
> As well, this series has some basic refactoring that I did along the way
> and some bugs I had to fix in order to get my atomic-only MST code
> working. Most of this is pretty straight forward and simply renaming
> things to more closely match the DisplayPort specification, as I think
> this will also make maintaining this code a lot easier in the long run
> (I've gotten myself confused way too many times because of this).
> 
> So far I've tested this on all three MST drivers: amdgpu, i915 and
> nouveau, along with making sure that removing the radeon MST code
> doesn't break anything else. The one thing I very much could use help
> with regarding testing though is making sure that this works with
> amdgpu's DSC support on MST.
> 
> So, with this we should be using the atomic state as much as possible
> with MST modesetting, hooray!
> 
> V4:
> * Get rid of fix that Wayne pointed out isn't needed
> 
> Cc: Wayne Lin 
> Cc: Ville Syrjälä 
> Cc: Fangzhi Zuo 
> Cc: Jani Nikula 
> Cc: Imre Deak 
> Cc: Daniel Vetter 
> Cc: Sean Paul 
> 
> Lyude Paul (17):
>   drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)
>   drm/amdgpu/dm/mst: Rename get_payload_table()
>   drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation
>   drm/display/dp_mst: Call them time slots, not VCPI slots
>   drm/display/dp_mst: Fix confusing docs for
> drm_dp_atomic_release_time_slots()
>   drm/display/dp_mst: Add some missing kdocs for atomic MST structs
>   drm/display/dp_mst: Add helper for finding payloads in atomic MST
> state
>   drm/display/dp_mst: Add nonblocking helpers for DP MST
>   drm/display/dp_mst: Don't open code modeset checks for releasing time
> slots
>   drm/display/dp_mst: Fix modeset tracking in
> drm_dp_atomic_release_vcpi_slots()
>   drm/nouveau/kms: Cache DP encoders in nouveau_connector
>   drm/nouveau/kms: Pull mst state in for all modesets
>   drm/display/dp_mst: Add helpers for serializing SST <-> MST
> transitions
>   drm/display/dp_mst: Drop all ports from topology on CSNs before
> queueing link address work
>   drm/display/dp_mst: Maintain time slot allocations when deleting
> payloads
>   drm/radeon: Drop legacy MST support
>   drm/display/dp_mst: Move all payload info into the atomic state
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   68 +-
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  108 +-
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  125 +-
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c |   10 +-
>  drivers/gpu/drm/amd/display/dc/dm_helpers.h   |4 +-
>  .../amd/display/include/link_service_types.h  |   14 +-
>  drivers/gpu/drm/display/drm_dp_mst_topology.c | 1137 -
>  drivers/gpu/drm/i915/display/intel_display.c  |6 +
>  drivers/gpu/drm/i915/display/intel_dp.c   |9 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   91 +-
>  drivers/gpu/drm/i915/display/intel_hdcp.c |   24 +-
>  drivers/gpu/drm/nouveau/dispnv50/disp.c   |  197 ++-
>  drivers/gpu/drm/nouveau/dispnv50/disp.h   |2 +
>  drivers/gpu/drm/nouveau/nouveau_connector.c   |   18 +-
>  drivers/gpu/drm/nouveau/nouveau_connector.h   |3 +
>  drivers/gpu/drm/radeon/Makefile   |2 +-
>  drivers/gpu/drm/radeon/atombios_crtc.c|   11 +-
>  driver

Re: [RFC v4 00/17] drm/display/dp_mst: Drop Radeon MST support, make MST atomic-only

2022-08-23 Thread Lyude Paul
Actually, talked with airlied and they suggested at this point I should just
go ahead and push. So, pushed! Have fun getting nice DSC support everyone :)

On Tue, 2022-08-23 at 13:26 -0400, Lyude Paul wrote:
> Would anyone have any issues if I merged this today? The whole series is
> acked, but I'm not sure if we would like to wait for R-b's?
> 
> 
> On Wed, 2022-08-17 at 15:38 -0400, Lyude Paul wrote:
> > For quite a while we've been carrying around a lot of legacy modesetting
> > code in the MST helpers that has been rather annoying to keep around,
> > and very often gets in the way of trying to implement additional
> > functionality in MST such as fallback link rate retraining, dynamic BPC
> > management and DSC support, etc. because of the fact that we can't rely
> > on atomic for everything.
> > 
> > Luckily, we only actually have one user of the legacy MST code in the
> > kernel - radeon. Originally I was thinking of trying to maintain this
> > code and keep it around in some form, but I'm pretty unconvinced anyone
> > is actually using this. My reasoning for that is because I've seen
> > nearly no issues regarding MST on radeon for quite a while now - despite
> > the fact my local testing seems to indicate it's quite broken. This
> > isn't too surprising either, as MST support in radeon.ko is gated behind
> > a module parameter that isn't enabled by default. This isn't to say I
> > wouldn't be open to alternative suggestions, but I'd rather not be the
> > one to have to spend time on that if at all possible! Plus, I already
> > floated the idea of dropping this code by AMD folks a few times and
> > didn't get much resistance.
> > 
> > As well, this series has some basic refactoring that I did along the way
> > and some bugs I had to fix in order to get my atomic-only MST code
> > working. Most of this is pretty straight forward and simply renaming
> > things to more closely match the DisplayPort specification, as I think
> > this will also make maintaining this code a lot easier in the long run
> > (I've gotten myself confused way too many times because of this).
> > 
> > So far I've tested this on all three MST drivers: amdgpu, i915 and
> > nouveau, along with making sure that removing the radeon MST code
> > doesn't break anything else. The one thing I very much could use help
> > with regarding testing though is making sure that this works with
> > amdgpu's DSC support on MST.
> > 
> > So, with this we should be using the atomic state as much as possible
> > with MST modesetting, hooray!
> > 
> > V4:
> > * Get rid of fix that Wayne pointed out isn't needed
> > 
> > Cc: Wayne Lin 
> > Cc: Ville Syrjälä 
> > Cc: Fangzhi Zuo 
> > Cc: Jani Nikula 
> > Cc: Imre Deak 
> > Cc: Daniel Vetter 
> > Cc: Sean Paul 
> > 
> > Lyude Paul (17):
> >   drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)
> >   drm/amdgpu/dm/mst: Rename get_payload_table()
> >   drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation
> >   drm/display/dp_mst: Call them time slots, not VCPI slots
> >   drm/display/dp_mst: Fix confusing docs for
> > drm_dp_atomic_release_time_slots()
> >   drm/display/dp_mst: Add some missing kdocs for atomic MST structs
> >   drm/display/dp_mst: Add helper for finding payloads in atomic MST
> > state
> >   drm/display/dp_mst: Add nonblocking helpers for DP MST
> >   drm/display/dp_mst: Don't open code modeset checks for releasing time
> > slots
> >   drm/display/dp_mst: Fix modeset tracking in
> > drm_dp_atomic_release_vcpi_slots()
> >   drm/nouveau/kms: Cache DP encoders in nouveau_connector
> >   drm/nouveau/kms: Pull mst state in for all modesets
> >   drm/display/dp_mst: Add helpers for serializing SST <-> MST
> > transitions
> >   drm/display/dp_mst: Drop all ports from topology on CSNs before
> > queueing link address work
> >   drm/display/dp_mst: Maintain time slot allocations when deleting
> > payloads
> >   drm/radeon: Drop legacy MST support
> >   drm/display/dp_mst: Move all payload info into the atomic state
> > 
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   68 +-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  108 +-
> >  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  125 +-
> >  drivers/gpu/drm/amd/display/dc/core/dc_link.c |   10 +-
> >  drivers/gpu/drm/amd/display/dc/dm_helpers.h   |4 +-
> >  .../amd/display/include/link_service_types.h  |   14 +-
> >  drivers/gpu/drm/display/drm_dp_mst_topology.c | 1137 -
> >  

Requests For Proposals for hosting XDC 2023 are now open

2022-08-18 Thread Lyude Paul
Hello everyone!

The X.org board is soliciting proposals to host XDC in 2023. Since
XDC 2022 is being held in North America this year, XDC 2023 is expected
to be in Europe. However, the board is open to other locations,
especially if there's an interesting co-location with another
conference.

If you're considering hosting XDC, we've assembled a wiki page with
what's generally expected and needed:

https://www.x.org/wiki/Events/RFP/

When submitting your proposal, please make sure to include at least the
key information about the potential location in question, possible
dates along with estimated costs. Proposals can be submitted to board
at foundation.x.org until the deadline of *September 1st, 2022*. 

Additionally, an quirk early heads-up to the board if you're
considering hosting would be appreciated, in case we need to adjust the
schedule a bit. Also, earlier is better since there generally will be a
bit of Q with organizers.

And if you just have some questions about what organizing XDC entails,
please feel free to chat with previous organizers, or someone from the
board.

Best regards,
Lyude Paul
On behalf of X.org

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



Re: [PATCH] drm/dp: Avoid Reading DPCD_REV Before Native Aux Read

2022-09-02 Thread Lyude Paul
Reviewed-by: Lyude Paul 

On Wed, 2022-08-31 at 18:13 -0400, Fangzhi Zuo wrote:
> The attempt to read DPCD_REV before any native aux read breaks
> majority of DP2 compliance.
> 
> The spec. requires DP_SINK_STATUS to be polled for the reset status
> DP_INTRA_HOP_AUX_REPLY_INDICATION during the clear training stage.
> 
> Polling DP_SINK_STATUS each time gets DPCD_REV read first
> that makes non link training regsiter DPCD_REV get read
> during UHBR link training. It violates DP2 compliance.
> 
> Cc: Ville Syrjala 
> Cc: Lyude Paul 
> Signed-off-by: Fangzhi Zuo 
> ---
>  drivers/gpu/drm/display/drm_dp_helper.c | 18 --
>  1 file changed, 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index e7c22c2ca90c..c7aa5bafa667 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -571,24 +571,6 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, 
> unsigned int offset,
>  {
>   int ret;
>  
> - /*
> -  * HP ZR24w corrupts the first DPCD access after entering power save
> -  * mode. Eg. on a read, the entire buffer will be filled with the same
> -  * byte. Do a throw away read to avoid corrupting anything we care
> -  * about. Afterwards things will work correctly until the monitor
> -  * gets woken up and subsequently re-enters power save mode.
> -  *
> -  * The user pressing any button on the monitor is enough to wake it
> -  * up, so there is no particularly good place to do the workaround.
> -  * We just have to do it before any DPCD access and hope that the
> -  * monitor doesn't power down exactly after the throw away read.
> -  */
> - if (!aux->is_remote) {
> - ret = drm_dp_dpcd_probe(aux, DP_DPCD_REV);
> - if (ret < 0)
> - return ret;
> - }
> -
>   if (aux->is_remote)
>   ret = drm_dp_mst_dpcd_read(aux, offset, buffer, size);
>   else

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



Re: [PATCH 6/7] nouveau/dmem: Evict device private memory during release

2022-09-26 Thread Lyude Paul
On Mon, 2022-09-26 at 16:03 +1000, Alistair Popple wrote:
> When the module is unloaded or a GPU is unbound from the module it is
> possible for device private pages to be left mapped in currently running
> processes. This leads to a kernel crash when the pages are either freed
> or accessed from the CPU because the GPU and associated data structures
> and callbacks have all been freed.
> 
> Fix this by migrating any mappings back to normal CPU memory prior to
> freeing the GPU memory chunks and associated device private pages.
> 
> Signed-off-by: Alistair Popple 
> 
> ---
> 
> I assume the AMD driver might have a similar issue. However I can't see
> where device private (or coherent) pages actually get unmapped/freed
> during teardown as I couldn't find any relevant calls to
> devm_memunmap(), memunmap(), devm_release_mem_region() or
> release_mem_region(). So it appears that ZONE_DEVICE pages are not being
> properly freed during module unload, unless I'm missing something?

I've got no idea, will poke Ben to see if they know the answer to this

> ---
>  drivers/gpu/drm/nouveau/nouveau_dmem.c | 48 +++-
>  1 file changed, 48 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c 
> b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> index 66ebbd4..3b247b8 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> @@ -369,6 +369,52 @@ nouveau_dmem_suspend(struct nouveau_drm *drm)
>   mutex_unlock(>dmem->mutex);
>  }
>  
> +/*
> + * Evict all pages mapping a chunk.
> + */
> +void
> +nouveau_dmem_evict_chunk(struct nouveau_dmem_chunk *chunk)
> +{
> + unsigned long i, npages = range_len(>pagemap.range) >> 
> PAGE_SHIFT;
> + unsigned long *src_pfns, *dst_pfns;
> + dma_addr_t *dma_addrs;
> + struct nouveau_fence *fence;
> +
> + src_pfns = kcalloc(npages, sizeof(*src_pfns), GFP_KERNEL);
> + dst_pfns = kcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL);
> + dma_addrs = kcalloc(npages, sizeof(*dma_addrs), GFP_KERNEL);
> +
> + migrate_device_range(src_pfns, chunk->pagemap.range.start >> PAGE_SHIFT,
> + npages);
> +
> + for (i = 0; i < npages; i++) {
> + if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
> + struct page *dpage;
> +
> + /*
> +  * _GFP_NOFAIL because the GPU is going away and there
> +  * is nothing sensible we can do if we can't copy the
> +  * data back.
> +  */

You'll have to excuse me for a moment since this area of nouveau isn't one of
my strongpoints, but are we sure about this? IIRC __GFP_NOFAIL means infinite
retry, in the case of a GPU hotplug event I would assume we would rather just
stop trying to migrate things to the GPU and just drop the data instead of
hanging on infinite retries.

> + dpage = alloc_page(GFP_HIGHUSER | __GFP_NOFAIL);
> + dst_pfns[i] = migrate_pfn(page_to_pfn(dpage));
> + nouveau_dmem_copy_one(chunk->drm,
> + migrate_pfn_to_page(src_pfns[i]), dpage,
> + _addrs[i]);
> + }
> + }
> +
> + nouveau_fence_new(chunk->drm->dmem->migrate.chan, false, );
> + migrate_device_pages(src_pfns, dst_pfns, npages);
> + nouveau_dmem_fence_done();
> + migrate_device_finalize(src_pfns, dst_pfns, npages);
> + kfree(src_pfns);
> + kfree(dst_pfns);
> + for (i = 0; i < npages; i++)
> + dma_unmap_page(chunk->drm->dev->dev, dma_addrs[i], PAGE_SIZE, 
> DMA_BIDIRECTIONAL);
> + kfree(dma_addrs);
> +}
> +
>  void
>  nouveau_dmem_fini(struct nouveau_drm *drm)
>  {
> @@ -380,8 +426,10 @@ nouveau_dmem_fini(struct nouveau_drm *drm)
>   mutex_lock(>dmem->mutex);
>  
>   list_for_each_entry_safe(chunk, tmp, >dmem->chunks, list) {
> + nouveau_dmem_evict_chunk(chunk);
>   nouveau_bo_unpin(chunk->bo);
>   nouveau_bo_ref(NULL, >bo);
> + WARN_ON(chunk->callocated);
>   list_del(>list);
>   memunmap_pages(>pagemap);
>   release_mem_region(chunk->pagemap.range.start,

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



Re: [PATCH 5/7] nouveau/dmem: Refactor nouveau_dmem_fault_copy_one()

2022-09-26 Thread Lyude Paul
On Mon, 2022-09-26 at 16:03 +1000, Alistair Popple wrote:
> nouveau_dmem_fault_copy_one() is used during handling of CPU faults via
> the migrate_to_ram() callback and is used to copy data from GPU to CPU
> memory. It is currently specific to fault handling, however a future
> patch implementing eviction of data during teardown needs similar
> functionality.
> 
> Refactor out the core functionality so that it is not specific to fault
> handling.
> 
> Signed-off-by: Alistair Popple 
> ---
>  drivers/gpu/drm/nouveau/nouveau_dmem.c | 59 +--
>  1 file changed, 29 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c 
> b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> index f9234ed..66ebbd4 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> @@ -139,44 +139,25 @@ static void nouveau_dmem_fence_done(struct 
> nouveau_fence **fence)
>   }
>  }
>  
> -static vm_fault_t nouveau_dmem_fault_copy_one(struct nouveau_drm *drm,
> - struct vm_fault *vmf, struct migrate_vma *args,
> - dma_addr_t *dma_addr)
> +static int nouveau_dmem_copy_one(struct nouveau_drm *drm, struct page *spage,
> + struct page *dpage, dma_addr_t *dma_addr)
>  {
>   struct device *dev = drm->dev->dev;
> - struct page *dpage, *spage;
> - struct nouveau_svmm *svmm;
> -
> - spage = migrate_pfn_to_page(args->src[0]);
> - if (!spage || !(args->src[0] & MIGRATE_PFN_MIGRATE))
> - return 0;
>  
> - dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address);
> - if (!dpage)
> - return VM_FAULT_SIGBUS;
>   lock_page(dpage);
>  
>   *dma_addr = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
>   if (dma_mapping_error(dev, *dma_addr))
> - goto error_free_page;
> + return -EIO;
>  
> - svmm = spage->zone_device_data;
> - mutex_lock(>mutex);
> - nouveau_svmm_invalidate(svmm, args->start, args->end);
>   if (drm->dmem->migrate.copy_func(drm, 1, NOUVEAU_APER_HOST, *dma_addr,
> - NOUVEAU_APER_VRAM, nouveau_dmem_page_addr(spage)))
> - goto error_dma_unmap;
> - mutex_unlock(>mutex);
> +  NOUVEAU_APER_VRAM,
> +  nouveau_dmem_page_addr(spage))) {
> + dma_unmap_page(dev, *dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
> +     return -EIO;
> + }

Feel free to just align this with the starting (, as long as it doesn't go
above 100 characters it doesn't really matter imho and would look nicer that
way.

Otherwise:

Reviewed-by: Lyude Paul 

Will look at the other patch in a moment

>  
> - args->dst[0] = migrate_pfn(page_to_pfn(dpage));
>   return 0;
> -
> -error_dma_unmap:
> - mutex_unlock(>mutex);
> - dma_unmap_page(dev, *dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
> -error_free_page:
> - __free_page(dpage);
> - return VM_FAULT_SIGBUS;
>  }
>  
>  static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
> @@ -184,9 +165,11 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct 
> vm_fault *vmf)
>   struct nouveau_drm *drm = page_to_drm(vmf->page);
>   struct nouveau_dmem *dmem = drm->dmem;
>   struct nouveau_fence *fence;
> + struct nouveau_svmm *svmm;
> + struct page *spage, *dpage;
>   unsigned long src = 0, dst = 0;
>   dma_addr_t dma_addr = 0;
> - vm_fault_t ret;
> + vm_fault_t ret = 0;
>   struct migrate_vma args = {
>   .vma= vmf->vma,
>   .start  = vmf->address,
> @@ -207,9 +190,25 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct 
> vm_fault *vmf)
>   if (!args.cpages)
>   return 0;
>  
> - ret = nouveau_dmem_fault_copy_one(drm, vmf, , _addr);
> - if (ret || dst == 0)
> + spage = migrate_pfn_to_page(src);
> + if (!spage || !(src & MIGRATE_PFN_MIGRATE))
> + goto done;
> +
> + dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address);
> + if (!dpage)
> + goto done;
> +
> + dst = migrate_pfn(page_to_pfn(dpage));
> +
> + svmm = spage->zone_device_data;
> + mutex_lock(>mutex);
> + nouveau_svmm_invalidate(svmm, args.start, args.end);
> + ret = nouveau_dmem_copy_one(drm, spage, dpage, _addr);
> + mutex_unlock(>mutex);
> + if (ret) {
> + ret = VM_FAULT_SIGBUS;
>   goto done;
> + }
>  
>   nouveau_fence_new(dmem->migrate.chan, false, );
>   migrate_vma_pages();

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



Re: [PATCH 6/7] nouveau/dmem: Evict device private memory during release

2022-09-28 Thread Lyude Paul
On Tue, 2022-09-27 at 11:39 +1000, Alistair Popple wrote:
> Felix Kuehling  writes:
> 
> > On 2022-09-26 17:35, Lyude Paul wrote:
> > > On Mon, 2022-09-26 at 16:03 +1000, Alistair Popple wrote:
> > > > When the module is unloaded or a GPU is unbound from the module it is
> > > > possible for device private pages to be left mapped in currently running
> > > > processes. This leads to a kernel crash when the pages are either freed
> > > > or accessed from the CPU because the GPU and associated data structures
> > > > and callbacks have all been freed.
> > > > 
> > > > Fix this by migrating any mappings back to normal CPU memory prior to
> > > > freeing the GPU memory chunks and associated device private pages.
> > > > 
> > > > Signed-off-by: Alistair Popple 
> > > > 
> > > > ---
> > > > 
> > > > I assume the AMD driver might have a similar issue. However I can't see
> > > > where device private (or coherent) pages actually get unmapped/freed
> > > > during teardown as I couldn't find any relevant calls to
> > > > devm_memunmap(), memunmap(), devm_release_mem_region() or
> > > > release_mem_region(). So it appears that ZONE_DEVICE pages are not being
> > > > properly freed during module unload, unless I'm missing something?
> > > I've got no idea, will poke Ben to see if they know the answer to this
> > 
> > I guess we're relying on devm to release the region. Isn't the whole point 
> > of
> > using devm_request_free_mem_region that we don't have to remember to 
> > explicitly
> > release it when the device gets destroyed? I believe we had an explicit free
> > call at some point by mistake, and that caused a double-free during module
> > unload. See this commit for reference:
> 
> Argh, thanks for that pointer. I was not so familiar with
> devm_request_free_mem_region()/devm_memremap_pages() as currently
> Nouveau explicitly manages that itself.

Mhm, TBH I feel like this was going to happen eventually anyway but there's
another reason for nouveau to start using the managed versions of these
functions at some point

> 
> > commit 22f4f4faf337d5fb2d2750aff13215726814273e
> > Author: Philip Yang 
> > Date:   Mon Sep 20 17:25:52 2021 -0400
> > 
> > drm/amdkfd: fix svm_migrate_fini warning
> >  Device manager releases device-specific resources when a driver
> > disconnects from a device, devm_memunmap_pages and
> > devm_release_mem_region calls in svm_migrate_fini are redundant.
> >  It causes below warning trace after patch "drm/amdgpu: Split
> > amdgpu_device_fini into early and late", so remove function
> > svm_migrate_fini.
> >  BUG: https://gitlab.freedesktop.org/drm/amd/-/issues/1718
> >  WARNING: CPU: 1 PID: 3646 at drivers/base/devres.c:795
> > devm_release_action+0x51/0x60
> > Call Trace:
> > ? memunmap_pages+0x360/0x360
> > svm_migrate_fini+0x2d/0x60 [amdgpu]
> > kgd2kfd_device_exit+0x23/0xa0 [amdgpu]
> > amdgpu_amdkfd_device_fini_sw+0x1d/0x30 [amdgpu]
> > amdgpu_device_fini_sw+0x45/0x290 [amdgpu]
> > amdgpu_driver_release_kms+0x12/0x30 [amdgpu]
> > drm_dev_release+0x20/0x40 [drm]
> > release_nodes+0x196/0x1e0
> > device_release_driver_internal+0x104/0x1d0
> > driver_detach+0x47/0x90
> > bus_remove_driver+0x7a/0xd0
> > pci_unregister_driver+0x3d/0x90
> > amdgpu_exit+0x11/0x20 [amdgpu]
> >  Signed-off-by: Philip Yang 
> > Reviewed-by: Felix Kuehling 
> > Signed-off-by: Alex Deucher 
> > 
> > Furthermore, I guess we are assuming that nobody is using the GPU when the
> > module is unloaded. As long as any processes have /dev/kfd open, you won't 
> > be
> > able to unload the module (except by force-unload). I suppose with 
> > ZONE_DEVICE
> > memory, we can have references to device memory pages even when user mode 
> > has
> > closed /dev/kfd. We do have a cleanup handler that runs in an 
> > MMU-free-notifier.
> > In theory that should run after all the pages in the mm_struct have been 
> > freed.
> > It releases all sorts of other device resources and needs the driver to 
> > still be
> > there. I'm not sure if there is anything preventing a module unload before 
> > the
> > free-notifier runs. I'll look into that.
> 
> Right - module unload (or device unbind) is one of the other ways we can
> hit this is

Re: [PATCH 6/7] nouveau/dmem: Evict device private memory during release

2022-09-28 Thread Lyude Paul
Re comments about infinite retry: gotcha, makes sense to me.

On Tue, 2022-09-27 at 09:45 +1000, Alistair Popple wrote:
> John Hubbard  writes:
> 
> > On 9/26/22 14:35, Lyude Paul wrote:
> > > > +   for (i = 0; i < npages; i++) {
> > > > +   if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
> > > > +   struct page *dpage;
> > > > +
> > > > +   /*
> > > > +* _GFP_NOFAIL because the GPU is going away 
> > > > and there
> > > > +* is nothing sensible we can do if we can't 
> > > > copy the
> > > > +* data back.
> > > > +*/
> > > 
> > > You'll have to excuse me for a moment since this area of nouveau isn't 
> > > one of
> > > my strongpoints, but are we sure about this? IIRC __GFP_NOFAIL means 
> > > infinite
> > > retry, in the case of a GPU hotplug event I would assume we would rather 
> > > just
> > > stop trying to migrate things to the GPU and just drop the data instead of
> > > hanging on infinite retries.
> > > 
> 
> No problem, thanks for taking a look!
> 
> > Hi Lyude!
> > 
> > Actually, I really think it's better in this case to keep trying
> > (presumably not necessarily infinitely, but only until memory becomes
> > available), rather than failing out and corrupting data.
> > 
> > That's because I'm not sure it's completely clear that this memory is
> > discardable. And at some point, we're going to make this all work with
> > file-backed memory, which will *definitely* not be discardable--I
> > realize that we're not there yet, of course.
> > 
> > But here, it's reasonable to commit to just retrying indefinitely,
> > really. Memory should eventually show up. And if it doesn't, then
> > restarting the machine is better than corrupting data, generally.
> 
> The memory is definitely not discardable here if the migration failed
> because that implies it is still mapped into some userspace process.
> 
> We could avoid restarting the machine by doing something similar to what
> happens during memory failure and killing every process that maps the
> page(s). But overall I think it's better to retry until memory is
> available, because that allows things like reclaim to work and in the
> worst case allows the OOM killer to select an appropriate task to kill.
> It also won't cause data corruption if/when we have file-backed memory.
> 
> > thanks,
> 

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



Re: [PATCH v2 7/8] nouveau/dmem: Evict device private memory during release

2022-09-28 Thread Lyude Paul
Reviewed-by: Lyude Paul 

On Wed, 2022-09-28 at 22:01 +1000, Alistair Popple wrote:
> When the module is unloaded or a GPU is unbound from the module it is
> possible for device private pages to still be mapped in currently
> running processes. This can lead to a hangs and RCU stall warnings when
> unbinding the device as memunmap_pages() will wait in an uninterruptible
> state until all device pages have been freed which may never happen.
> 
> Fix this by migrating device mappings back to normal CPU memory prior to
> freeing the GPU memory chunks and associated device private pages.
> 
> Signed-off-by: Alistair Popple 
> Cc: Lyude Paul 
> Cc: Ben Skeggs 
> Cc: Ralph Campbell 
> Cc: John Hubbard 
> ---
>  drivers/gpu/drm/nouveau/nouveau_dmem.c | 48 +++-
>  1 file changed, 48 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c 
> b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> index 65f51fb..5fe2091 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> @@ -367,6 +367,52 @@ nouveau_dmem_suspend(struct nouveau_drm *drm)
>   mutex_unlock(>dmem->mutex);
>  }
>  
> +/*
> + * Evict all pages mapping a chunk.
> + */
> +static void
> +nouveau_dmem_evict_chunk(struct nouveau_dmem_chunk *chunk)
> +{
> + unsigned long i, npages = range_len(>pagemap.range) >> 
> PAGE_SHIFT;
> + unsigned long *src_pfns, *dst_pfns;
> + dma_addr_t *dma_addrs;
> + struct nouveau_fence *fence;
> +
> + src_pfns = kcalloc(npages, sizeof(*src_pfns), GFP_KERNEL);
> + dst_pfns = kcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL);
> + dma_addrs = kcalloc(npages, sizeof(*dma_addrs), GFP_KERNEL);
> +
> + migrate_device_range(src_pfns, chunk->pagemap.range.start >> PAGE_SHIFT,
> + npages);
> +
> + for (i = 0; i < npages; i++) {
> + if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
> + struct page *dpage;
> +
> + /*
> +  * _GFP_NOFAIL because the GPU is going away and there
> +  * is nothing sensible we can do if we can't copy the
> +  * data back.
> +  */
> + dpage = alloc_page(GFP_HIGHUSER | __GFP_NOFAIL);
> + dst_pfns[i] = migrate_pfn(page_to_pfn(dpage));
> + nouveau_dmem_copy_one(chunk->drm,
> + migrate_pfn_to_page(src_pfns[i]), dpage,
> + _addrs[i]);
> + }
> + }
> +
> + nouveau_fence_new(chunk->drm->dmem->migrate.chan, false, );
> + migrate_device_pages(src_pfns, dst_pfns, npages);
> + nouveau_dmem_fence_done();
> + migrate_device_finalize(src_pfns, dst_pfns, npages);
> + kfree(src_pfns);
> + kfree(dst_pfns);
> + for (i = 0; i < npages; i++)
> + dma_unmap_page(chunk->drm->dev->dev, dma_addrs[i], PAGE_SIZE, 
> DMA_BIDIRECTIONAL);
> + kfree(dma_addrs);
> +}
> +
>  void
>  nouveau_dmem_fini(struct nouveau_drm *drm)
>  {
> @@ -378,8 +424,10 @@ nouveau_dmem_fini(struct nouveau_drm *drm)
>   mutex_lock(>dmem->mutex);
>  
>   list_for_each_entry_safe(chunk, tmp, >dmem->chunks, list) {
> + nouveau_dmem_evict_chunk(chunk);
>   nouveau_bo_unpin(chunk->bo);
>   nouveau_bo_ref(NULL, >bo);
> + WARN_ON(chunk->callocated);
>   list_del(>list);
>   memunmap_pages(>pagemap);
>   release_mem_region(chunk->pagemap.range.start,

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



Re: [PATCH] drm/amdgpu/dm/mst: Fix incorrect usage of drm_dp_add_payload_part2()

2022-10-19 Thread Lyude Paul
Gotcha, I'll take another look at this tomorrow

On Mon, 2022-10-17 at 03:09 +, Lin, Wayne wrote:
> [Public]
> 
> 
> 
> > -Original Message-----
> > From: Lyude Paul 
> > Sent: Thursday, October 6, 2022 3:37 AM
> > To: Siqueira, Rodrigo ; dri-
> > de...@lists.freedesktop.org; amd-gfx@lists.freedesktop.org
> > Cc: Wentland, Harry ; Li, Sun peng (Leo)
> > ; Deucher, Alexander
> > ; Koenig, Christian
> > ; Pan, Xinhui ; David
> > Airlie ; Daniel Vetter ; Zuo, Jerry
> > ; Lin, Wayne ; Chen, Ian
> > ; Mikita Lipski ; Mahfooz,
> > Hamza ; Claudio Suarez ; Colin
> > Ian King ; Jani Nikula ; open
> > list 
> > Subject: Re: [PATCH] drm/amdgpu/dm/mst: Fix incorrect usage of
> > drm_dp_add_payload_part2()
> > 
> > On Tue, 2022-10-04 at 16:46 -0400, Rodrigo Siqueira Jordao wrote:
> > > 
> > > On 2022-10-04 16:24, Lyude Paul wrote:
> > > > Yikes, it appears somehow I totally made a mistake here. We're
> > > > currently checking to see if drm_dp_add_payload_part2() returns a
> > > > non-zero value to indicate success. That's totally wrong though, as
> > > > this function only returns a zero value on success - not the other way
> > around.
> > > > 
> > > > So, fix that.
> > > > 
> > > > Signed-off-by: Lyude Paul 
> > > > Issue:
> > > > 
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgi
> > > > tlab.freedesktop.org%2Fdrm%2Famd%2F-
> > %2Fissues%2F2171data=05%7C0
> > > > 
> > 1%7Cwayne.lin%40amd.com%7Ccd5a63120e064f4bb6aa08daa7090baf%7C3d
> > d8961
> > > > 
> > fe4884e608e11a82d994e183d%7C0%7C0%7C638005954559719396%7CUnkno
> > wn%7CT
> > > > 
> > WFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLC
> > JXV
> > > > 
> > CI6Mn0%3D%7C3000%7C%7C%7Csdata=nMIGnUKS6EDrdKJ0rR%2BAh
> > FRa4ST0%2
> > > > BYr9bILmXv40yv0%3Dreserved=0
> > > > Fixes: 4d07b0bc4034 ("drm/display/dp_mst: Move all payload info into
> > > > the atomic state")
> > > > ---
> > > >   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2
> > +-
> > > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > 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 b8077fcd4651..00598def5b39 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
> > > > @@ -297,7 +297,7 @@ bool
> > dm_helpers_dp_mst_send_payload_allocation(
> > > > clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
> > > > }
> > > > 
> > > > -   if (enable && drm_dp_add_payload_part2(mst_mgr, mst_state-
> > > base.state, payload)) {
> > > > +   if (enable && drm_dp_add_payload_part2(mst_mgr,
> > > > +mst_state->base.state, payload) == 0) {
> 
> Hi Lyude,
> 
> This line changes the original logic a bit. The 'if' case was trying to catch 
> failure 
> while sending ALLOCATE_PAYLOAD. If the msg fails, set the set_flag to false.
> If succeed, set the set_flag to true and clear the clr_flag. 
> 
> Sorry if the code wording misleading. Thanks!
> 
> > > > amdgpu_dm_set_mst_status(>mst_status,
> > > > set_flag, false);
> > > > } else {
> > > 
> > > Hi Lyude,
> > > 
> > > Maybe I'm missing something, but I can't find the
> > > drm_dp_add_payload_part2() function on amd-staging-drm-next. Which
> > > repo are you using?
> > 
> > If it's not on amd-staging-drm-next then it likely hasn't gotten backported 
> > to
> > amd's branch yet and is in drm-misc-next
> > 
> > > 
> > > Thanks
> > > Siqueira
> > > 
> > 
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> --
> Regards,
> Wayne Lin
> 

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



[PATCH] drm/amdgpu/dm/mst: Fix incorrect usage of drm_dp_add_payload_part2()

2022-10-04 Thread Lyude Paul
Yikes, it appears somehow I totally made a mistake here. We're currently
checking to see if drm_dp_add_payload_part2() returns a non-zero value to
indicate success. That's totally wrong though, as this function only
returns a zero value on success - not the other way around.

So, fix that.

Signed-off-by: Lyude Paul 
Issue: https://gitlab.freedesktop.org/drm/amd/-/issues/2171
Fixes: 4d07b0bc4034 ("drm/display/dp_mst: Move all payload info into the atomic 
state")
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 b8077fcd4651..00598def5b39 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
@@ -297,7 +297,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
}
 
-   if (enable && drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, 
payload)) {
+   if (enable && drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, 
payload) == 0) {
amdgpu_dm_set_mst_status(>mst_status,
set_flag, false);
} else {
-- 
2.37.3



Re: [PATCH] drm/amdgpu/dm/mst: Fix incorrect usage of drm_dp_add_payload_part2()

2022-10-05 Thread Lyude Paul
On Tue, 2022-10-04 at 16:46 -0400, Rodrigo Siqueira Jordao wrote:
> 
> On 2022-10-04 16:24, Lyude Paul wrote:
> > Yikes, it appears somehow I totally made a mistake here. We're currently
> > checking to see if drm_dp_add_payload_part2() returns a non-zero value to
> > indicate success. That's totally wrong though, as this function only
> > returns a zero value on success - not the other way around.
> > 
> > So, fix that.
> > 
> > Signed-off-by: Lyude Paul 
> > Issue: https://gitlab.freedesktop.org/drm/amd/-/issues/2171
> > Fixes: 4d07b0bc4034 ("drm/display/dp_mst: Move all payload info into the 
> > atomic state")
> > ---
> >   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > 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 b8077fcd4651..00598def5b39 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
> > @@ -297,7 +297,7 @@ bool dm_helpers_dp_mst_send_payload_allocation(
> > clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
> > }
> >   
> > -   if (enable && drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, 
> > payload)) {
> > +   if (enable && drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, 
> > payload) == 0) {
> > amdgpu_dm_set_mst_status(>mst_status,
> > set_flag, false);
> > } else {
> 
> Hi Lyude,
> 
> Maybe I'm missing something, but I can't find the 
> drm_dp_add_payload_part2() function on amd-staging-drm-next. Which repo 
> are you using?

If it's not on amd-staging-drm-next then it likely hasn't gotten backported to
amd's branch yet and is in drm-misc-next

> 
> Thanks
> Siqueira
> 

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



Re: [RESEND RFC 18/18] drm/display/dp_mst: Move all payload info into the atomic state

2022-08-03 Thread Lyude Paul
On Tue, 2022-07-05 at 09:10 +, Lin, Wayne wrote:
> > +struct drm_dp_mst_port;
> > +
> >   /* DP MST stream allocation (payload bandwidth number) */
> >   struct dc_dp_mst_stream_allocation {
> >    uint8_t vcp_id;
> >    /* number of slots required for the DP stream in
> >    * transport packet */
> >    uint8_t slot_count;
> > + /* The MST port this is on, this is used to associate DC MST payloads
> > with their
> > + * respective DRM payloads allocations, and can be ignored on non-
> > Linux.
> > + */
> 
> Is it necessary for adding this new member? Since this is for setting the DC
> HW and not relating to drm.

I don't entirely know, honestly. The reasons I did it:

 * Mapping things from DRM to DC and from DC to DRM is really confusing for
   outside contributors like myself, so it wasn't even really clear to me if
   there was another way to reconstruct the DRM context from the spots where
   we call from DC up to DM (not a typo, see next point).
 * These DC structs for MST are already layer mixing as far as I can tell,
   just not in an immediately obvious way. While this struct itself is for DC,
   there's multiple spots where we pass the DC payload structs down from DM to
   DC, then pass them back up from DC to DM and have to figure out how to
   reconstruct the DRM context that we actually need to use the MST helpers
   from that. So, that kind of further complicates the confusion of where
   layers should be separated.
 * As far as I'm aware with C there shouldn't be any issue with adding a
   pointer to a struct whose contents are undefined. IMHO, this is also
   preferable to just using void* because then at least you get some hint as
   to the actual type of the data and avoid the possibility of casting it to
   the wrong type. So tl;dr, on any platform even outside of Linux with a
   reasonably compliant compiler this should still build just fine. It'll even
   give you the added bonus of warning people if they try to access the
   contents of this member in DC on non-Linux platforms. If void* is preferred
   though I'm fine with switching it to that.

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



Re: [PATCH v2 1/3] drm/dp_mst: add passthrough_aux to struct drm_dp_mst_port

2022-08-05 Thread Lyude Paul
lgtm!

Reviewed-by: Lyude Paul 

On Fri, 2022-08-05 at 17:13 -0400, Hamza Mahfooz wrote:
> Currently, there is no way to identify if DSC pass-through can be
> enabled and what aux DSC pass-through requests ought to be sent to. So,
> add a variable to struct drm_dp_mst_port that keeps track of the
> aforementioned information.
> 
> Signed-off-by: Hamza Mahfooz 
> ---
> v2: define DP_DSC_PASSTHROUGH_IS_SUPPORTED
> ---
>  drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 +++-
>  include/drm/display/drm_dp.h  | 1 +
>  include/drm/display/drm_dp_mst_helper.h   | 3 +++
>  3 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index 67b3b9697da7..71915afd9892 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -5921,8 +5921,10 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct 
> drm_dp_mst_port *port)
>   /* Enpoint decompression with DP-to-DP peer device */
>   if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&
>   (endpoint_fec & DP_FEC_CAPABLE) &&
> - (upstream_dsc & 0x2) /* DSC passthrough */)
> + (upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED)) {
> + port->passthrough_aux = _upstream_port->aux;
>   return >aux;
> + }
>  
>   /* Virtual DPCD decompression with DP-to-DP peer device */
>   return _upstream_port->aux;
> diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
> index 9e3aff7e68bb..4d0abe4c7ea9 100644
> --- a/include/drm/display/drm_dp.h
> +++ b/include/drm/display/drm_dp.h
> @@ -239,6 +239,7 @@
>  
>  #define DP_DSC_SUPPORT  0x060   /* DP 1.4 */
>  # define DP_DSC_DECOMPRESSION_IS_SUPPORTED  (1 << 0)
> +# define DP_DSC_PASSTHROUGH_IS_SUPPORTED(1 << 1)
>  
>  #define DP_DSC_REV  0x061
>  # define DP_DSC_MAJOR_MASK  (0xf << 0)
> diff --git a/include/drm/display/drm_dp_mst_helper.h 
> b/include/drm/display/drm_dp_mst_helper.h
> index 10adec068b7f..4a39c95f8afd 100644
> --- a/include/drm/display/drm_dp_mst_helper.h
> +++ b/include/drm/display/drm_dp_mst_helper.h
> @@ -86,6 +86,8 @@ struct drm_dp_vcpi {
>   * @next: link to next port on this branch device
>   * @aux: i2c aux transport to talk to device connected to this port, 
> protected
>   * by _dp_mst_topology_mgr.base.lock.
> + * @passthrough_aux: parent aux to which DSC pass-through requests should be
> + * sent, only set if DSC pass-through is possible.
>   * @parent: branch device parent of this port
>   * @vcpi: Virtual Channel Payload info for this port.
>   * @connector: DRM connector this port is connected to. Protected by
> @@ -140,6 +142,7 @@ struct drm_dp_mst_port {
>    */
>   struct drm_dp_mst_branch *mstb;
>   struct drm_dp_aux aux; /* i2c bus for this port? */
> + struct drm_dp_aux *passthrough_aux;
>   struct drm_dp_mst_branch *parent;
>  
>   struct drm_dp_vcpi vcpi;

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



Re: [PATCH v2 1/3] drm/dp_mst: add passthrough_aux to struct drm_dp_mst_port

2022-08-10 Thread Lyude Paul
On Wed, 2022-08-10 at 09:23 -0400, Hamza Mahfooz wrote:
> On 2022-08-09 18:01, Lyude Paul wrote:
> > Ah yes of course! Probably should have asked when I gave the r-b :). Also,
> > just so patchwork actually catches it I will say the magic incantation:
> > 
> > Reviewed-by: Lyude Paul 
> > 
> > Do we want to merge just this patch to drm-misc-next, or do you want to 
> > merge
> > the whole series through there? If you'd rather just merge this through 
> > amd's
> > branch I'm fine with that as well
> 
> In that case, it is preferable to have all of the patches in this series
> to get merged through amd's branch.\

Sounds totally fine to me! Just make sure to run it by Harry or another amdgpu
maintainer first, and then you should be good to go.

> 
> > 
> > On Tue, 2022-08-09 at 11:15 -0400, Hamza Mahfooz wrote:
> > > Hey Lyude,
> > > 
> > > On 2022-08-05 17:17, Lyude Paul wrote:
> > > > lgtm!
> > > > 
> > > 
> > > Any chance you can apply this to drm-misc-next?
> > > 
> > > > Reviewed-by: Lyude Paul 
> > > > 
> > > > On Fri, 2022-08-05 at 17:13 -0400, Hamza Mahfooz wrote:
> > > > > Currently, there is no way to identify if DSC pass-through can be
> > > > > enabled and what aux DSC pass-through requests ought to be sent to. 
> > > > > So,
> > > > > add a variable to struct drm_dp_mst_port that keeps track of the
> > > > > aforementioned information.
> > > > > 
> > > > > Signed-off-by: Hamza Mahfooz 
> > > > > ---
> > > > > v2: define DP_DSC_PASSTHROUGH_IS_SUPPORTED
> > > > > ---
> > > > >drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 +++-
> > > > >include/drm/display/drm_dp.h  | 1 +
> > > > >include/drm/display/drm_dp_mst_helper.h   | 3 +++
> > > > >3 files changed, 7 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > index 67b3b9697da7..71915afd9892 100644
> > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > > > @@ -5921,8 +5921,10 @@ struct drm_dp_aux 
> > > > > *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
> > > > >   /* Enpoint decompression with DP-to-DP peer device */
> > > > >   if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) 
> > > > > &&
> > > > >   (endpoint_fec & DP_FEC_CAPABLE) &&
> > > > > - (upstream_dsc & 0x2) /* DSC passthrough */)
> > > > > + (upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED)) {
> > > > > + port->passthrough_aux = 
> > > > > _upstream_port->aux;
> > > > >   return >aux;
> > > > > + }
> > > > >
> > > > >   /* Virtual DPCD decompression with DP-to-DP peer device 
> > > > > */
> > > > >   return _upstream_port->aux;
> > > > > diff --git a/include/drm/display/drm_dp.h 
> > > > > b/include/drm/display/drm_dp.h
> > > > > index 9e3aff7e68bb..4d0abe4c7ea9 100644
> > > > > --- a/include/drm/display/drm_dp.h
> > > > > +++ b/include/drm/display/drm_dp.h
> > > > > @@ -239,6 +239,7 @@
> > > > >
> > > > >#define DP_DSC_SUPPORT  0x060   /* DP 1.4 */
> > > > ># define DP_DSC_DECOMPRESSION_IS_SUPPORTED  (1 << 0)
> > > > > +# define DP_DSC_PASSTHROUGH_IS_SUPPORTED(1 << 1)
> > > > >
> > > > >#define DP_DSC_REV  0x061
> > > > ># define DP_DSC_MAJOR_MASK  (0xf << 0)
> > > > > diff --git a/include/drm/display/drm_dp_mst_helper.h 
> > > > > b/include/drm/display/drm_dp_mst_helper.h
> > > > > index 10adec068b7f..4a39c95f8afd 100644
> > > > > --- a/include/drm/display/drm_dp_mst_helper.h
> > > > > +++ b/include/drm/display/drm_dp_mst_helper.h
> > > > > @@ -86,6 +86,8 @@ struct drm_dp_vcpi {
> > > > > * @next: link to next port on this branch device
> > > > > * @aux: i2c aux transport to talk to device connected to this 
> > > > > port, protected
> > > > > * by _dp_mst_topology_mgr.base.lock.
> > > > > + * @passthrough_aux: parent aux to which DSC pass-through requests 
> > > > > should be
> > > > > + * sent, only set if DSC pass-through is possible.
> > > > > * @parent: branch device parent of this port
> > > > > * @vcpi: Virtual Channel Payload info for this port.
> > > > > * @connector: DRM connector this port is connected to. Protected 
> > > > > by
> > > > > @@ -140,6 +142,7 @@ struct drm_dp_mst_port {
> > > > >*/
> > > > >   struct drm_dp_mst_branch *mstb;
> > > > >   struct drm_dp_aux aux; /* i2c bus for this port? */
> > > > > + struct drm_dp_aux *passthrough_aux;
> > > > >   struct drm_dp_mst_branch *parent;
> > > > >
> > > > >   struct drm_dp_vcpi vcpi;
> > > > 
> > > 
> > 
> 

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



Re: [RESEND RFC 15/18] drm/display/dp_mst: Skip releasing payloads if last connected port isn't connected

2022-08-10 Thread Lyude Paul
ed for stale 
> connection status before payload deallocation completes, i.e. which will put 
> malloc krefcount to eventually destroy disconnected devices in topology 
> in-memory.
> I mean, ideally, sounds like the topology in-memory should be reliable when
> we send ALLOCATE_PAYLOAD as PBN=0. But I understand it definitely is not the
> case if we have krefcount leak.

mhm, I think you made me realize I'm overthinking this a bit now that I've
seen the excerpt you mentioned above, along with the other excerpt about only
the end devices being involved. The main reason I originally foresaw an issue
with this is because the delay with updating the in-memory topology structure
might put us slightly out of sync with the state of the hub on the other end -
causing the hub to spit out an error.

However - based on the excerpts you mentioned I think what I was seeing was
mainly just the 2 second timeout causing things to be released properly - not
specific behavior based on the location in the topology of the branch that was
just unplugged like I originally assumed. I think in that case it probably
does make more sense to go with your fix, so I'll likely drop this and rework
the topology checks you had into this.

> 
> Appreciate for your time and help Lyude!
> 

no, thank you for your help! :) There aren't a whole ton of people who are
this involved with MST so it's very useful to finally have another pair of
eyes looking at all of this. 

>   

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



Re: [PATCH v2 1/3] drm/dp_mst: add passthrough_aux to struct drm_dp_mst_port

2022-08-09 Thread Lyude Paul
Ah yes of course! Probably should have asked when I gave the r-b :). Also,
just so patchwork actually catches it I will say the magic incantation:

Reviewed-by: Lyude Paul 

Do we want to merge just this patch to drm-misc-next, or do you want to merge
the whole series through there? If you'd rather just merge this through amd's
branch I'm fine with that as well

On Tue, 2022-08-09 at 11:15 -0400, Hamza Mahfooz wrote:
> Hey Lyude,
> 
> On 2022-08-05 17:17, Lyude Paul wrote:
> > lgtm!
> > 
> 
> Any chance you can apply this to drm-misc-next?
> 
> > Reviewed-by: Lyude Paul 
> > 
> > On Fri, 2022-08-05 at 17:13 -0400, Hamza Mahfooz wrote:
> > > Currently, there is no way to identify if DSC pass-through can be
> > > enabled and what aux DSC pass-through requests ought to be sent to. So,
> > > add a variable to struct drm_dp_mst_port that keeps track of the
> > > aforementioned information.
> > > 
> > > Signed-off-by: Hamza Mahfooz 
> > > ---
> > > v2: define DP_DSC_PASSTHROUGH_IS_SUPPORTED
> > > ---
> > >   drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 +++-
> > >   include/drm/display/drm_dp.h  | 1 +
> > >   include/drm/display/drm_dp_mst_helper.h   | 3 +++
> > >   3 files changed, 7 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > index 67b3b9697da7..71915afd9892 100644
> > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> > > @@ -5921,8 +5921,10 @@ struct drm_dp_aux 
> > > *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
> > >   /* Enpoint decompression with DP-to-DP peer device */
> > >   if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) 
> > > &&
> > >   (endpoint_fec & DP_FEC_CAPABLE) &&
> > > - (upstream_dsc & 0x2) /* DSC passthrough */)
> > > + (upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED)) {
> > > + port->passthrough_aux = _upstream_port->aux;
> > >   return >aux;
> > > + }
> > >   
> > >   /* Virtual DPCD decompression with DP-to-DP peer device 
> > > */
> > >   return _upstream_port->aux;
> > > diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
> > > index 9e3aff7e68bb..4d0abe4c7ea9 100644
> > > --- a/include/drm/display/drm_dp.h
> > > +++ b/include/drm/display/drm_dp.h
> > > @@ -239,6 +239,7 @@
> > >   
> > >   #define DP_DSC_SUPPORT  0x060   /* DP 1.4 */
> > >   # define DP_DSC_DECOMPRESSION_IS_SUPPORTED  (1 << 0)
> > > +# define DP_DSC_PASSTHROUGH_IS_SUPPORTED(1 << 1)
> > >   
> > >   #define DP_DSC_REV  0x061
> > >   # define DP_DSC_MAJOR_MASK  (0xf << 0)
> > > diff --git a/include/drm/display/drm_dp_mst_helper.h 
> > > b/include/drm/display/drm_dp_mst_helper.h
> > > index 10adec068b7f..4a39c95f8afd 100644
> > > --- a/include/drm/display/drm_dp_mst_helper.h
> > > +++ b/include/drm/display/drm_dp_mst_helper.h
> > > @@ -86,6 +86,8 @@ struct drm_dp_vcpi {
> > >* @next: link to next port on this branch device
> > >* @aux: i2c aux transport to talk to device connected to this port, 
> > > protected
> > >* by _dp_mst_topology_mgr.base.lock.
> > > + * @passthrough_aux: parent aux to which DSC pass-through requests 
> > > should be
> > > + * sent, only set if DSC pass-through is possible.
> > >* @parent: branch device parent of this port
> > >* @vcpi: Virtual Channel Payload info for this port.
> > >* @connector: DRM connector this port is connected to. Protected by
> > > @@ -140,6 +142,7 @@ struct drm_dp_mst_port {
> > >*/
> > >   struct drm_dp_mst_branch *mstb;
> > >   struct drm_dp_aux aux; /* i2c bus for this port? */
> > > + struct drm_dp_aux *passthrough_aux;
> > >   struct drm_dp_mst_branch *parent;
> > >   
> > >   struct drm_dp_vcpi vcpi;
> > 
> 

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



[RFC v3] drm/display/dp_mst: Add helpers for serializing SST <-> MST transitions

2022-08-09 Thread Lyude Paul
There's another kind of situation where we could potentially race with
nonblocking modesets and MST, especially if we were to only use the locking
provided by atomic modesetting:

* Display 1 begins as enabled on DP-1 in SST mode
* Display 1 switches to MST mode, exposes one sink in MST mode
* Userspace does non-blocking modeset to disable the SST display
* Userspace does non-blocking modeset to enable the MST display with a
  different CRTC, but the SST display hasn't been fully taken down yet
* Execution order between the last two commits isn't guaranteed since they
  share no drm resources

We can fix this however, by ensuring that we always pull in the atomic
topology state whenever a connector capable of driving an MST display
performs its atomic check - and then tracking CRTC commits happening on the
SST connector in the MST topology state. So, let's add some simple helpers
for doing that and hook them up in various drivers.

v2:
* Use intel_dp_mst_source_support() to check for MST support in i915, fixes
  CI failures

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 +++
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 59 +++
 drivers/gpu/drm/i915/display/intel_dp.c   |  9 +++
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  2 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.h   |  2 +
 drivers/gpu/drm/nouveau/nouveau_connector.c   | 14 +
 include/drm/display/drm_dp_mst_helper.h   |  2 +
 7 files changed, 94 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 1739710003a4..51732bd603a9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6318,10 +6318,17 @@ amdgpu_dm_connector_atomic_check(struct drm_connector 
*conn,
drm_atomic_get_old_connector_state(state, conn);
struct drm_crtc *crtc = new_con_state->crtc;
struct drm_crtc_state *new_crtc_state;
+   struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(conn);
int ret;
 
trace_amdgpu_dm_connector_atomic_check(new_con_state);
 
+   if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+   ret = drm_dp_mst_root_conn_atomic_check(new_con_state, 
>mst_mgr);
+   if (ret < 0)
+   return ret;
+   }
+
if (!crtc)
return 0;
 
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 2f7c43f88d74..97e8f8a83ed4 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4597,6 +4597,65 @@ void drm_dp_mst_atomic_wait_for_dependencies(struct 
drm_atomic_state *state)
 }
 EXPORT_SYMBOL(drm_dp_mst_atomic_wait_for_dependencies);
 
+/**
+ * drm_dp_mst_root_conn_atomic_check() - Serialize CRTC commits on MST-capable 
connectors operating
+ * in SST mode
+ * @new_conn_state: The new connector state of the _connector
+ * @mgr: The MST topology manager for the _connector
+ *
+ * Since MST uses fake _encoder structs, the generic atomic modesetting 
code isn't able to
+ * serialize non-blocking commits happening on the real DP connector of an MST 
topology switching
+ * into/away from MST mode - as the CRTC on the real DP connector and the 
CRTCs on the connector's
+ * MST topology will never share the same _encoder.
+ *
+ * This function takes care of this serialization issue, by checking a root 
MST connector's atomic
+ * state to determine if it is about to have a modeset - and then pulling in 
the MST topology state
+ * if so, along with adding any relevant CRTCs to 
_dp_mst_topology_state.pending_crtc_mask.
+ *
+ * Drivers implementing MST must call this function from the
+ * _connector_helper_funcs.atomic_check hook of any physical DP 
_connector capable of
+ * driving MST sinks.
+ *
+ * Returns:
+ * 0 on success, negative error code otherwise
+ */
+int drm_dp_mst_root_conn_atomic_check(struct drm_connector_state 
*new_conn_state,
+ struct drm_dp_mst_topology_mgr *mgr)
+{
+   struct drm_atomic_state *state = new_conn_state->state;
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, 
new_conn_state->connector);
+   struct drm_crtc_state *crtc_state;
+   struct drm_dp_mst_topology_state *mst_state = NULL;
+
+   if (new_conn_state->crtc) {
+   crtc_state = drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
+   if (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)) {
+   mst_state = drm_atomic_get_mst_topology_state(state, 
mgr);
+   

[RFC v4 03/17] drm/display/dp_mst: Rename drm_dp_mst_vcpi_allocation

2022-08-17 Thread Lyude Paul
In retrospect, the name I chose for this originally is confusing, as
there's a lot more info in here then just the VCPI. This really should be
called a payload. Let's make it more obvious that this is meant to be
related to the atomic state and is about payloads by renaming it to
drm_dp_mst_atomic_payload. Also, rename various variables throughout the
code that use atomic payloads.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 96 +--
 include/drm/display/drm_dp_mst_helper.h   |  4 +-
 2 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 7a94a5288e8d..f448e3e5ec6e 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4370,7 +4370,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state 
*state,
  int pbn_div)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_vcpi_allocation *pos, *vcpi = NULL;
+   struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
int prev_slots, prev_bw, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
@@ -4378,11 +4378,11 @@ int drm_dp_atomic_find_vcpi_slots(struct 
drm_atomic_state *state,
return PTR_ERR(topology_state);
 
/* Find the current allocation for this port, if any */
-   list_for_each_entry(pos, _state->vcpis, next) {
+   list_for_each_entry(pos, _state->payloads, next) {
if (pos->port == port) {
-   vcpi = pos;
-   prev_slots = vcpi->vcpi;
-   prev_bw = vcpi->pbn;
+   payload = pos;
+   prev_slots = payload->vcpi;
+   prev_bw = payload->pbn;
 
/*
 * This should never happen, unless the driver tries
@@ -4399,7 +4399,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state 
*state,
break;
}
}
-   if (!vcpi) {
+   if (!payload) {
prev_slots = 0;
prev_bw = 0;
}
@@ -4417,17 +4417,17 @@ int drm_dp_atomic_find_vcpi_slots(struct 
drm_atomic_state *state,
   port, prev_bw, pbn);
 
/* Add the new allocation to the state */
-   if (!vcpi) {
-   vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL);
-   if (!vcpi)
+   if (!payload) {
+   payload = kzalloc(sizeof(*payload), GFP_KERNEL);
+   if (!payload)
return -ENOMEM;
 
drm_dp_mst_get_port_malloc(port);
-   vcpi->port = port;
-   list_add(>next, _state->vcpis);
+   payload->port = port;
+   list_add(>next, _state->payloads);
}
-   vcpi->vcpi = req_slots;
-   vcpi->pbn = pbn;
+   payload->vcpi = req_slots;
+   payload->pbn = pbn;
 
return req_slots;
 }
@@ -4464,21 +4464,21 @@ int drm_dp_atomic_release_vcpi_slots(struct 
drm_atomic_state *state,
 struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_vcpi_allocation *pos;
+   struct drm_dp_mst_atomic_payload *pos;
bool found = false;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   list_for_each_entry(pos, _state->vcpis, next) {
+   list_for_each_entry(pos, _state->payloads, next) {
if (pos->port == port) {
found = true;
break;
}
}
if (WARN_ON(!found)) {
-   drm_err(mgr->dev, "no VCPI for [MST PORT:%p] found in mst state 
%p\n",
+   drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
port, _state->base);
return -EINVAL;
}
@@ -5060,7 +5060,7 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 {
struct drm_dp_mst_topology_state *state, *old_state =
to_dp_mst_topology_state(obj->state);
-   struct drm_dp_vcpi_allocation *pos, *vcpi;
+   struct drm_dp_mst_atomic_payload *pos, *payload;
 
state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
if (!state)
@@ -5068,25 +5068,25 @@ drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
 
__drm_atomic_helper_private_obj_duplicate_state(obj, >base);
 
-   INIT_LIST_HEAD(>

[RFC v4 04/17] drm/display/dp_mst: Call them time slots, not VCPI slots

2022-08-17 Thread Lyude Paul
VCPI is only sort of the correct term here, originally the majority of this
code simply referred to timeslots vaguely as "slots" - and since I started
working on it and adding atomic functionality, the name "VCPI slots" has
been used to represent time slots.

Now that we actually have consistent access to the DisplayPort spec thanks
to VESA, I now know this isn't actually the proper term - as the
specification refers to these as time slots.

Since we're trying to make this code as easy to figure out as possible,
let's take this opportunity to correct this nomenclature and call them by
their proper name - timeslots. Likewise, we rename various functions
appropriately, along with replacing references in the kernel documentation
and various debugging messages.

It's important to note that this patch series leaves the legacy MST code
untouched for the most part, which is fine since we'll be removing it soon
anyhow. There should be no functional changes in this series.

v2:
* Add note that Wayne Lin from AMD suggested regarding slots being between
  the source DP Tx and the immediate downstream DP Rx

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  28 ++---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 106 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   5 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |   4 +-
 include/drm/display/drm_dp_mst_helper.h   |  12 +-
 6 files changed, 81 insertions(+), 76 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 85fdd6baf803..cd30b02af8ee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6401,7 +6401,7 @@ static int dm_encoder_helper_atomic_check(struct 
drm_encoder *encoder,
clock = adjusted_mode->clock;
dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, 
false);
}
-   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_vcpi_slots(state,
+   dm_new_connector_state->vcpi_slots = 
drm_dp_atomic_find_time_slots(state,
   
mst_mgr,
   
mst_port,
   
dm_new_connector_state->pbn,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 2e74ccf7df5b..655d63b20b33 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -472,7 +472,7 @@ static int dm_dp_mst_atomic_check(struct drm_connector 
*connector,
return 0;
}
 
-   return drm_dp_atomic_release_vcpi_slots(state,
+   return drm_dp_atomic_release_time_slots(state,
mst_mgr,
mst_port);
 }
@@ -785,7 +785,7 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
 
if (initial_slack[next_index] > fair_pbn_alloc) {
vars[next_index].pbn += fair_pbn_alloc;
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
  
params[next_index].port,
  vars[next_index].pbn,
@@ -795,7 +795,7 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
vars[next_index].bpp_x16 = 
bpp_x16_from_pbn(params[next_index], vars[next_index].pbn);
} else {
vars[next_index].pbn -= fair_pbn_alloc;
-   if (drm_dp_atomic_find_vcpi_slots(state,
+   if (drm_dp_atomic_find_time_slots(state,
  
params[next_index].port->mgr,
  
params[next_index].port,
  
vars[next_index].pbn,
@@ -804,7 +804,7 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
}
} else {
vars[next_index].pbn += initial_slack[next_index];
-   if (drm_dp_atomic_find_vcpi_slots(state,
+  

[RFC v4 01/17] drm/amdgpu/dc/mst: Rename dp_mst_stream_allocation(_table)

2022-08-17 Thread Lyude Paul
Just to make this more clear to outside contributors that these are
DC-specific structs, as this also threw me into a loop a number of times
before I figured out the purpose of this.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Fangzhi Zuo 
Acked-by: Jani Nikula 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  9 -
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 10 +-
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |  4 ++--
 .../gpu/drm/amd/display/include/link_service_types.h  | 11 ---
 4 files changed, 19 insertions(+), 15 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 a0154a5f7183..3aa385860eea 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
@@ -153,9 +153,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
return result;
 }
 
-static void get_payload_table(
-   struct amdgpu_dm_connector *aconnector,
-   struct dp_mst_stream_allocation_table *proposed_table)
+static void get_payload_table(struct amdgpu_dm_connector *aconnector,
+ struct dc_dp_mst_stream_allocation_table 
*proposed_table)
 {
int i;
struct drm_dp_mst_topology_mgr *mst_mgr =
@@ -177,7 +176,7 @@ static void get_payload_table(
mst_mgr->payloads[i].payload_state ==
DP_PAYLOAD_REMOTE) {
 
-   struct dp_mst_stream_allocation *sa =
+   struct dc_dp_mst_stream_allocation *sa =
_table->stream_allocations[
proposed_table->stream_count];
 
@@ -201,7 +200,7 @@ void dm_helpers_dp_update_branch_info(
 bool dm_helpers_dp_mst_write_payload_allocation_table(
struct dc_context *ctx,
const struct dc_stream_state *stream,
-   struct dp_mst_stream_allocation_table *proposed_table,
+   struct dc_dp_mst_stream_allocation_table *proposed_table,
bool enable)
 {
struct amdgpu_dm_connector *aconnector;
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 9e51338441d0..e01424fb02ba 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3516,7 +3516,7 @@ static void update_mst_stream_alloc_table(
struct dc_link *link,
struct stream_encoder *stream_enc,
struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename 
stream_enc to dio_stream_enc?
-   const struct dp_mst_stream_allocation_table *proposed_table)
+   const struct dc_dp_mst_stream_allocation_table *proposed_table)
 {
struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 
};
struct link_mst_stream_allocation *dc_alloc;
@@ -3679,7 +3679,7 @@ enum dc_status dc_link_allocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 {
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
@@ -3784,7 +3784,7 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx 
*pipe_ctx, uint32_t bw
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
const struct link_hwss *link_hwss = get_link_hwss(link, 
_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
@@ -3873,7 +3873,7 @@ enum dc_status dc_link_increase_mst_payload(struct 
pipe_ctx *pipe_ctx, uint32_t
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
const struct link_hwss *link_hwss = get_link_hwss(link, 
_ctx->link_res);
@@ -3957,7 +3957,7 @@ static enum dc_status deallocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
 {
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
-   struct dp_mst_stream_allocation_table proposed_table = {0};
+   struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
int i;
  

[RFC v4 06/17] drm/display/dp_mst: Add some missing kdocs for atomic MST structs

2022-08-17 Thread Lyude Paul
Since we're about to start adding some stuff here, we may as well fill in
any missing documentation that we forgot to write.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 include/drm/display/drm_dp_mst_helper.h | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index 9cdd2def56a1..3b155ad3eee4 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -542,7 +542,14 @@ struct drm_dp_payload {
 
 #define to_dp_mst_topology_state(x) container_of(x, struct 
drm_dp_mst_topology_state, base)
 
+/**
+ * struct drm_dp_mst_atomic_payload - Atomic state struct for an MST payload
+ *
+ * The primary atomic state structure for a given MST payload. Stores 
information like current
+ * bandwidth allocation, intended action for this payload, etc.
+ */
 struct drm_dp_mst_atomic_payload {
+   /** @port: The MST port assigned to this payload */
struct drm_dp_mst_port *port;
 
/**
@@ -551,16 +558,32 @@ struct drm_dp_mst_atomic_payload {
 * the immediate downstream DP Rx
 */
int time_slots;
+   /** @pbn: The payload bandwidth for this payload */
int pbn;
+   /** @dsc_enabled: Whether or not this payload has DSC enabled */
bool dsc_enabled;
+
+   /** @next: The list node for this payload */
struct list_head next;
 };
 
+/**
+ * struct drm_dp_mst_topology_state - DisplayPort MST topology atomic state
+ *
+ * This struct represents the atomic state of the toplevel DisplayPort MST 
manager
+ */
 struct drm_dp_mst_topology_state {
+   /** @base: Base private state for atomic */
struct drm_private_state base;
+
+   /** @payloads: The list of payloads being created/destroyed in this 
state */
struct list_head payloads;
+   /** @mgr: The topology manager */
struct drm_dp_mst_topology_mgr *mgr;
+
+   /** @total_avail_slots: The total number of slots this topology can 
handle (63 or 64) */
u8 total_avail_slots;
+   /** @start_slot: The first usable time slot in this topology (1 or 0) */
u8 start_slot;
 };
 
-- 
2.37.1



[RFC v4 08/17] drm/display/dp_mst: Add nonblocking helpers for DP MST

2022-08-17 Thread Lyude Paul
As Daniel Vetter pointed out, if we only use the atomic modesetting locks
with MST it's technically possible for a driver with non-blocking modesets
to race when it comes to MST displays - as we make the mistake of not doing
our own CRTC commit tracking in the topology_state object.

This could potentially cause problems if something like this happens:

* User starts non-blocking commit to disable CRTC-1 on MST topology 1
* User starts non-blocking commit to enable CRTC-2 on MST topology 1

There's no guarantee here that the commit for disabling CRTC-2 will only
occur after CRTC-1 has finished, since neither commit shares a CRTC - only
the private modesetting object for MST. Keep in mind this likely isn't a
problem for blocking modesets, only non-blocking.

So, begin fixing this by keeping track of which CRTCs on a topology have
changed by keeping track of which CRTCs we release or allocate timeslots
on. As well, add some helpers for:

* Setting up the drm_crtc_commit structs in the ->commit_setup hook
* Waiting for any CRTC dependencies from the previous topology state

v2:
* Use drm_dp_mst_atomic_setup_commit() directly - Jani

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  5 +-
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 93 +++
 drivers/gpu/drm/i915/display/intel_display.c  |  6 ++
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |  7 ++
 include/drm/display/drm_dp_mst_helper.h   | 15 +++
 5 files changed, 124 insertions(+), 2 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 cd30b02af8ee..c97a4d759b94 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2808,7 +2808,8 @@ static const struct drm_mode_config_funcs 
amdgpu_dm_mode_funcs = {
 };
 
 static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = 
{
-   .atomic_commit_tail = amdgpu_dm_atomic_commit_tail
+   .atomic_commit_tail = amdgpu_dm_atomic_commit_tail,
+   .atomic_commit_setup = drm_dp_mst_atomic_setup_commit,
 };
 
 static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
@@ -7959,6 +7960,7 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
DRM_ERROR("Waiting for fences timed out!");
 
drm_atomic_helper_update_legacy_modeset_state(dev, state);
+   drm_dp_mst_atomic_wait_for_dependencies(state);
 
dm_state = dm_atomic_get_new_state(state);
if (dm_state && dm_state->context) {
@@ -8357,7 +8359,6 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
dc_release_state(dc_state_temp);
 }
 
-
 static int dm_force_atomic_commit(struct drm_connector *connector)
 {
int ret = 0;
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 1c054a5e2e77..d701e5b819b8 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4384,12 +4384,16 @@ int drm_dp_atomic_find_time_slots(struct 
drm_atomic_state *state,
 {
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload = NULL;
+   struct drm_connector_state *conn_state;
int prev_slots = 0, prev_bw = 0, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
+   conn_state = drm_atomic_get_new_connector_state(state, port->connector);
+   topology_state->pending_crtc_mask |= drm_crtc_mask(conn_state->crtc);
+
/* Find the current allocation for this port, if any */
payload = drm_atomic_get_mst_payload_state(topology_state, port);
if (payload) {
@@ -4469,11 +4473,15 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 {
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload;
+   struct drm_connector_state *conn_state;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
+   conn_state = drm_atomic_get_old_connector_state(state, port->connector);
+   topology_state->pending_crtc_mask |= drm_crtc_mask(conn_state->crtc);
+
payload = drm_atomic_get_mst_payload_state(topology_state, port);
if (WARN_ON(!payload)) {
drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
@@ -4492,6 +4500,83 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *st

[RFC v4 11/17] drm/nouveau/kms: Cache DP encoders in nouveau_connector

2022-08-17 Thread Lyude Paul
Post-NV50, the only kind of encoder you'll find for DP connectors on Nvidia
GPUs are SORs (serial output resources). Because SORs have fixed
associations with their connectors, we can correctly assume that any DP
connector on a nvidia GPU will have exactly one SOR encoder routed to it
for DisplayPort.

Since we're going to need to be able to retrieve this fixed SOR DP encoder
much more often as a result of hooking up MST helpers for tracking
SST<->MST transitions in atomic states, let's simply cache this encoder in
nouveau_connector for any DP connectors on the system to avoid looking it
up each time. This isn't safe for NV50 since PIORs then come into play,
however there's no code pre-NV50 that would need to look this up anyhow -
so it's not really an issue.

Signed-off-by: Lyude Paul 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/nouveau/nouveau_connector.c | 4 +++-
 drivers/gpu/drm/nouveau/nouveau_connector.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 8100c75ee731..b8ee2173ca8f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -1368,7 +1368,7 @@ nouveau_connector_create(struct drm_device *dev,
return ERR_PTR(-ENOMEM);
}
drm_dp_aux_init(_connector->aux);
-   fallthrough;
+   break;
default:
funcs = _connector_funcs;
break;
@@ -1431,6 +1431,8 @@ nouveau_connector_create(struct drm_device *dev,
 
switch (type) {
case DRM_MODE_CONNECTOR_DisplayPort:
+   nv_connector->dp_encoder = find_encoder(_connector->base, 
DCB_OUTPUT_DP);
+   fallthrough;
case DRM_MODE_CONNECTOR_eDP:
drm_dp_cec_register_connector(_connector->aux, connector);
break;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h 
b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 4bf0c703eee7..f4e17ff68bf9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -128,6 +128,9 @@ struct nouveau_connector {
 
struct drm_dp_aux aux;
 
+   /* The fixed DP encoder for this connector, if there is one */
+   struct nouveau_encoder *dp_encoder;
+
int dithering_mode;
int scaling_mode;
 
-- 
2.37.1



[RFC v4 09/17] drm/display/dp_mst: Don't open code modeset checks for releasing time slots

2022-08-17 Thread Lyude Paul
I'm not sure why, but at the time I originally wrote the find/release time
slot helpers I thought we should avoid keeping modeset tracking out of the
MST helpers. In retrospect though there's no actual good reason to do
this, and the logic has ended up being identical across all the drivers
using the helpers. Also, it needs to be fixed anyway so we don't break
things when going atomic-only with MST.

So, let's just move this code into drm_dp_atomic_release_time_slots() and
stop open coding it.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 29 +++
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 21 --
 drivers/gpu/drm/i915/display/intel_dp_mst.c   | 24 +--
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 21 --
 4 files changed, 23 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 655d63b20b33..7a0d6cfa77f5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -447,34 +447,13 @@ dm_dp_mst_detect(struct drm_connector *connector,
 }
 
 static int dm_dp_mst_atomic_check(struct drm_connector *connector,
-   struct drm_atomic_state *state)
+ struct drm_atomic_state *state)
 {
-   struct drm_connector_state *new_conn_state =
-   drm_atomic_get_new_connector_state(state, connector);
-   struct drm_connector_state *old_conn_state =
-   drm_atomic_get_old_connector_state(state, connector);
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
-   struct drm_crtc_state *new_crtc_state;
-   struct drm_dp_mst_topology_mgr *mst_mgr;
-   struct drm_dp_mst_port *mst_port;
+   struct drm_dp_mst_topology_mgr *mst_mgr = 
>mst_port->mst_mgr;
+   struct drm_dp_mst_port *mst_port = aconnector->port;
 
-   mst_port = aconnector->port;
-   mst_mgr = >mst_port->mst_mgr;
-
-   if (!old_conn_state->crtc)
-   return 0;
-
-   if (new_conn_state->crtc) {
-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
-   if (!new_crtc_state ||
-   !drm_atomic_crtc_needs_modeset(new_crtc_state) ||
-   new_crtc_state->enable)
-   return 0;
-   }
-
-   return drm_dp_atomic_release_time_slots(state,
-   mst_mgr,
-   mst_port);
+   return drm_dp_atomic_release_time_slots(state, mst_mgr, mst_port);
 }
 
 static const struct drm_connector_helper_funcs 
dm_dp_mst_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index d701e5b819b8..aa6dcd9ff6a5 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4473,14 +4473,29 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 {
struct drm_dp_mst_topology_state *topology_state;
struct drm_dp_mst_atomic_payload *payload;
-   struct drm_connector_state *conn_state;
+   struct drm_connector_state *old_conn_state, *new_conn_state;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, 
port->connector);
+   if (!old_conn_state->crtc)
+   return 0;
+
+   /* If the CRTC isn't disabled by this state, don't release it's payload 
*/
+   new_conn_state = drm_atomic_get_new_connector_state(state, 
port->connector);
+   if (new_conn_state->crtc) {
+   struct drm_crtc_state *crtc_state =
+   drm_atomic_get_new_crtc_state(state, 
new_conn_state->crtc);
+
+   if (!crtc_state ||
+   !drm_atomic_crtc_needs_modeset(crtc_state) ||
+   crtc_state->enable)
+   return 0;
+   }
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   conn_state = drm_atomic_get_old_connector_state(state, port->connector);
-   topology_state->pending_crtc_mask |= drm_crtc_mask(conn_state->crtc);
+   topology_state->pending_crtc_mask |= 
drm_crtc_mask(old_conn_state->crtc);
 
payload = drm_atomic_get_mst_payload_state(topology_state, port);
if (WARN_ON(!payload)) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 1cebbc51d8fa..1b067cd73261 100644
--- 

[RFC v4 07/17] drm/display/dp_mst: Add helper for finding payloads in atomic MST state

2022-08-17 Thread Lyude Paul
We already open-code this quite often, and will be iterating through
payloads even more once we've moved all of the payload tracking into the
atomic state. So, let's add a helper for doing this.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 109 --
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 8a2ddfde594a..1c054a5e2e77 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -1738,6 +1738,19 @@ drm_dp_mst_dump_port_topology_history(struct 
drm_dp_mst_port *port) {}
 #define save_port_topology_ref(port, type)
 #endif
 
+static struct drm_dp_mst_atomic_payload *
+drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
+struct drm_dp_mst_port *port)
+{
+   struct drm_dp_mst_atomic_payload *payload;
+
+   list_for_each_entry(payload, >payloads, next)
+   if (payload->port == port)
+   return payload;
+
+   return NULL;
+}
+
 static void drm_dp_destroy_mst_branch_device(struct kref *kref)
 {
struct drm_dp_mst_branch *mstb =
@@ -4370,39 +4383,31 @@ int drm_dp_atomic_find_time_slots(struct 
drm_atomic_state *state,
  int pbn_div)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
-   int prev_slots, prev_bw, req_slots;
+   struct drm_dp_mst_atomic_payload *payload = NULL;
+   int prev_slots = 0, prev_bw = 0, req_slots;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
/* Find the current allocation for this port, if any */
-   list_for_each_entry(pos, _state->payloads, next) {
-   if (pos->port == port) {
-   payload = pos;
-   prev_slots = payload->time_slots;
-   prev_bw = payload->pbn;
-
-   /*
-* This should never happen, unless the driver tries
-* releasing and allocating the same timeslot 
allocation,
-* which is an error
-*/
-   if (WARN_ON(!prev_slots)) {
-   drm_err(mgr->dev,
-   "cannot allocate and release time slots 
on [MST PORT:%p] in the same state\n",
-   port);
-   return -EINVAL;
-   }
+   payload = drm_atomic_get_mst_payload_state(topology_state, port);
+   if (payload) {
+   prev_slots = payload->time_slots;
+   prev_bw = payload->pbn;
 
-   break;
+   /*
+* This should never happen, unless the driver tries
+* releasing and allocating the same timeslot allocation,
+* which is an error
+*/
+   if (WARN_ON(!prev_slots)) {
+   drm_err(mgr->dev,
+   "cannot allocate and release time slots on [MST 
PORT:%p] in the same state\n",
+   port);
+   return -EINVAL;
}
}
-   if (!payload) {
-   prev_slots = 0;
-   prev_bw = 0;
-   }
 
if (pbn_div <= 0)
pbn_div = mgr->pbn_div;
@@ -4463,30 +4468,24 @@ int drm_dp_atomic_release_time_slots(struct 
drm_atomic_state *state,
 struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_topology_state *topology_state;
-   struct drm_dp_mst_atomic_payload *pos;
-   bool found = false;
+   struct drm_dp_mst_atomic_payload *payload;
 
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
if (IS_ERR(topology_state))
return PTR_ERR(topology_state);
 
-   list_for_each_entry(pos, _state->payloads, next) {
-   if (pos->port == port) {
-   found = true;
-   break;
-   }
-   }
-   if (WARN_ON(!found)) {
+   payload = drm_atomic_get_mst_payload_state(topology_state, port);
+   if (WARN_ON(!payload)) {
drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst 
state %p\n",
port, _state->base);
return -EINVAL;
}
 
-   drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, 
pos->

[RFC v4 05/17] drm/display/dp_mst: Fix confusing docs for drm_dp_atomic_release_time_slots()

2022-08-17 Thread Lyude Paul
For some reason we mention returning 0 if "slots have been added back to
drm_dp_mst_topology_state->avail_slots". This is totally misleading,
avail_slots is simply for figuring out the total number of slots available
in total on the topology and has no relation to the current payload
allocations.

So, let's get rid of that comment.

Signed-off-by: Lyude Paul 
Cc: Wayne Lin 
Cc: Ville Syrjälä 
Cc: Fangzhi Zuo 
Cc: Jani Nikula 
Cc: Imre Deak 
Cc: Daniel Vetter 
Cc: Sean Paul 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index fad80ab2b9db..8a2ddfde594a 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4456,8 +4456,7 @@ EXPORT_SYMBOL(drm_dp_atomic_find_time_slots);
  * drm_dp_mst_atomic_check()
  *
  * Returns:
- * 0 if all slots for this port were added back to
- * _dp_mst_topology_state.avail_slots or negative error code
+ * 0 on success, negative error code otherwise
  */
 int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
 struct drm_dp_mst_topology_mgr *mgr,
-- 
2.37.1



<    1   2   3   4   5   6   7   >