From: Alvin Lee <alvin.l...@amd.com>

We should not allocate payloads if the link is lost until the link is retrained.
Some displays require this.

Signed-off-by: Alvin Lee <alvin.l...@amd.com>
Reviewed-by: Wenjing Liu <wenjing....@amd.com>
Acked-by: Bhawanpreet Lakha <bhawanpreet.la...@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c   | 10 +++++-----
 drivers/gpu/drm/amd/display/dc/core/dc_link.c   | 17 ++++++++++-------
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c    | 11 +++++++++++
 drivers/gpu/drm/amd/display/dc/dc_link.h        |  1 +
 drivers/gpu/drm/amd/display/dc/dc_types.h       |  6 ++++++
 drivers/gpu/drm/amd/display/dc/dm_helpers.h     |  2 +-
 6 files changed, 34 insertions(+), 13 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 5f2c315b18ba..6f0af054a93b 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
@@ -283,7 +283,7 @@ void dm_helpers_dp_mst_clear_payload_allocation_table(
  * Polls for ACT (allocation change trigger) handled and sends
  * ALLOCATE_PAYLOAD message.
  */
-bool dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+enum act_return_status dm_helpers_dp_mst_poll_for_allocation_change_trigger(
                struct dc_context *ctx,
                const struct dc_stream_state *stream)
 {
@@ -294,19 +294,19 @@ bool dm_helpers_dp_mst_poll_for_allocation_change_trigger(
        aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
 
        if (!aconnector || !aconnector->mst_port)
-               return false;
+               return ACT_FAILED;
 
        mst_mgr = &aconnector->mst_port->mst_mgr;
 
        if (!mst_mgr->mst_state)
-               return false;
+               return ACT_FAILED;
 
        ret = drm_dp_check_act_status(mst_mgr);
 
        if (ret)
-               return false;
+               return ACT_FAILED;
 
-       return true;
+       return ACT_SUCCESS;
 }
 
 bool dm_helpers_dp_mst_send_payload_allocation(
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 a13b497ae49c..e23d08238eba 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2508,7 +2508,7 @@ static void update_mst_stream_alloc_table(
 /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
  * because stream_encoder is not exposed to dm
  */
-static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
+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;
@@ -2519,6 +2519,7 @@ static enum dc_status allocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
        struct fixed31_32 pbn;
        struct fixed31_32 pbn_per_slot;
        uint8_t i;
+       enum act_return_status ret;
        DC_LOGGER_INIT(link->ctx->logger);
 
        /* enable_link_dp_mst already check link->enabled_stream_count
@@ -2566,14 +2567,16 @@ static enum dc_status allocate_mst_payload(struct 
pipe_ctx *pipe_ctx)
                &link->mst_stream_alloc_table);
 
        /* send down message */
-       dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+       ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
                        stream->ctx,
                        stream);
 
-       dm_helpers_dp_mst_send_payload_allocation(
-                       stream->ctx,
-                       stream,
-                       true);
+       if (ret != ACT_LINK_LOST) {
+               dm_helpers_dp_mst_send_payload_allocation(
+                               stream->ctx,
+                               stream,
+                               true);
+       }
 
        /* slot X.Y for only current stream */
        pbn_per_slot = get_pbn_per_slot(stream);
@@ -2784,7 +2787,7 @@ void core_link_enable_stream(
 #endif
 
                if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
-                       allocate_mst_payload(pipe_ctx);
+                       dc_link_allocate_mst_payload(pipe_ctx);
 
                core_dc->hwss.unblank_stream(pipe_ctx,
                        &pipe_ctx->stream->link->cur_link_settings);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index f5742719b5d9..7c78caf7a602 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2364,6 +2364,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, 
union hpd_irq_data *out_hpd
        enum dc_status result;
 
        bool status = false;
+       struct pipe_ctx *pipe_ctx;
+       int i;
 
        if (out_link_loss)
                *out_link_loss = false;
@@ -2440,6 +2442,15 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, 
union hpd_irq_data *out_hpd
                        &link->cur_link_settings,
                        true, LINK_TRAINING_ATTEMPTS);
 
+               for (i = 0; i < MAX_PIPES; i++) {
+                       pipe_ctx = 
&link->dc->current_state->res_ctx.pipe_ctx[i];
+                       if (pipe_ctx && pipe_ctx->stream && 
pipe_ctx->stream->link == link &&
+                                       pipe_ctx->stream->dpms_off == false &&
+                                       pipe_ctx->stream->signal == 
SIGNAL_TYPE_DISPLAY_PORT_MST) {
+                               dc_link_allocate_mst_payload(pipe_ctx);
+                       }
+               }
+
                status = false;
                if (out_link_loss)
                        *out_link_loss = true;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h 
b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 9ea75db3484e..45e6195c5395 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -192,6 +192,7 @@ enum dc_detect_reason {
 
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
 bool dc_link_get_hpd_state(struct dc_link *dc_link);
+enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return:
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_types.h
index b273735b6a3e..82abc4ff6c49 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -159,6 +159,12 @@ enum dc_edid_status {
        EDID_THE_SAME,
 };
 
+enum act_return_status {
+       ACT_SUCCESS,
+       ACT_LINK_LOST,
+       ACT_FAILED
+};
+
 /* audio capability from EDID*/
 struct dc_cea_audio_mode {
        uint8_t format_code; /* ucData[0] [6:3]*/
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h 
b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index b6b4333737f2..94b75e942607 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -74,7 +74,7 @@ void dm_helpers_dp_mst_clear_payload_allocation_table(
 /*
  * Polls for ACT (allocation change trigger) handled and
  */
-bool dm_helpers_dp_mst_poll_for_allocation_change_trigger(
+enum act_return_status dm_helpers_dp_mst_poll_for_allocation_change_trigger(
                struct dc_context *ctx,
                const struct dc_stream_state *stream);
 /*
-- 
2.17.1

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

Reply via email to