OSDN Git Service

drm/amd/display: Don't allocate payloads if link lost
authorAlvin Lee <alvin.lee2@amd.com>
Fri, 2 Aug 2019 17:42:49 +0000 (13:42 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Sep 2019 22:55:01 +0000 (17:55 -0500)
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.lee2@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dm_helpers.h

index ee1dc75..d011840 100644 (file)
@@ -282,7 +282,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)
 {
@@ -293,19 +293,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(
index ca20b15..1ef2339 100644 (file)
@@ -2510,7 +2510,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;
@@ -2521,6 +2521,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
@@ -2568,14 +2569,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);
@@ -2786,7 +2789,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);
index f574271..7c78caf 100644 (file)
@@ -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;
index 9ea75db..45e6195 100644 (file)
@@ -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:
index b273735..82abc4f 100644 (file)
@@ -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]*/
index b6b4333..94b75e9 100644 (file)
@@ -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);
 /*