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>
  * 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)
 {
        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(
 
 /* 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;
        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
                &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);
 #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);
 
        enum dc_status result;
 
        bool status = false;
+       struct pipe_ctx *pipe_ctx;
+       int i;
 
        if (out_link_loss)
                *out_link_loss = false;
                        &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;
 
 
 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:
 
        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]*/
 
 /*
  * 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);
 /*