drm/amd/display: reallocate MST payload when link loss
authorPaul Hsieh <paul.hsieh@amd.com>
Fri, 27 Dec 2019 03:35:33 +0000 (11:35 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 16 Jan 2020 19:16:54 +0000 (14:16 -0500)
[Why]
Try to allocate MST payload but receive HPD short pulse with link loss
casue driver allocate payload twice. It cause monitor can't light up
successfully.

[How]
When driver receive HPD short pulse with link loss, we need to
deallocate payload then allocate payload.
Then we will not allocate payload twice with same sink.

Signed-off-by: Paul Hsieh <paul.hsieh@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
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

index e5807be78edb0f1278772f08f179c7424a11f782..260c0b62d37dc8806b4f0da168f9b6ec9695e9be 100644 (file)
@@ -2873,6 +2873,39 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
 
        return DC_OK;
 }
+
+enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link)
+{
+       int i;
+       struct pipe_ctx *pipe_ctx;
+
+       // Clear all of MST payload then reallocate
+       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) {
+                       deallocate_mst_payload(pipe_ctx);
+               }
+       }
+
+       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) {
+                       /* enable/disable PHY will clear connection between BE and FE
+                        * need to restore it.
+                        */
+                       link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
+                                                                       pipe_ctx->stream_res.stream_enc->id, true);
+                       dc_link_allocate_mst_payload(pipe_ctx);
+               }
+       }
+
+       return DC_OK;
+}
+
 #if defined(CONFIG_DRM_AMD_DC_HDCP)
 static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 {
index 2124bc10fc53050145c25fa035890c8362bd11be..6ab298c65247258a1d31d867aabad5c9fc88847c 100644 (file)
@@ -2901,11 +2901,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
                        pipe_ctx,
                        pipe_ctx->stream->signal);
 
-               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);
-               }
+               if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
+                       dc_link_reallocate_mst_payload(link);
 
                status = false;
                if (out_link_loss)
index f9aae35aec921ae0775916e89528f703620939ac..d25603128394b2b4cc3d366a7d5e8b26a37fec37 100644 (file)
@@ -205,6 +205,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);
+enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link);
 
 /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
  * Return: