From: Jingwen Zhu <jingwen....@amd.com>

[Why]
This is a workaround for an dcn3.1 hang that happens if otg dispclk
is ramped while otg is on and stream enc is off.
But this w/a should not trigger when we have a dig active.

[How]
Avoid disable otg when dig FE/BE FIFO was not switched.

Acked-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
Signed-off-by: Jerry Zuo <jerry....@amd.com>
Signed-off-by: Jingwen Zhu <jingwen....@amd.com>
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c   | 18 +++++++++++++++---
 .../dc/dio/dcn35/dcn35_dio_stream_encoder.c    |  9 +++++++++
 .../drm/amd/display/dc/inc/hw/stream_encoder.h |  1 +
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 70ee0089a20d..248d22b23a6d 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -120,7 +120,6 @@ static int dcn35_get_active_display_cnt_wa(
 
        return display_count;
 }
-
 static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state 
*context,
                bool safe_to_lower, bool disable)
 {
@@ -128,14 +127,27 @@ static void dcn35_disable_otg_wa(struct clk_mgr 
*clk_mgr_base, struct dc_state *
        int i;
 
        for (i = 0; i < dc->res_pool->pipe_count; ++i) {
+               struct pipe_ctx *old_pipe = 
&dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
                struct pipe_ctx *pipe = safe_to_lower
                        ? &context->res_ctx.pipe_ctx[i]
                        : &dc->current_state->res_ctx.pipe_ctx[i];
-
+               bool stream_changed_otg_dig_on = false;
                if (pipe->top_pipe || pipe->prev_odm_pipe)
                        continue;
+               stream_changed_otg_dig_on = old_pipe->stream && 
new_pipe->stream &&
+               old_pipe->stream != new_pipe->stream &&
+               old_pipe->stream_res.tg == new_pipe->stream_res.tg &&
+               new_pipe->stream->link_enc && !new_pipe->stream->dpms_off &&
+               new_pipe->stream->link->link_enc->funcs->is_dig_enabled &&
+               new_pipe->stream->link->link_enc->funcs->is_dig_enabled(
+               new_pipe->stream->link->link_enc) &&
+               new_pipe->stream_res.stream_enc &&
+               new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled &&
+               
new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled(new_pipe->stream_res.stream_enc);
                if (pipe->stream && (pipe->stream->dpms_off || 
dc_is_virtual_signal(pipe->stream->signal) ||
-                                    !pipe->stream->link_enc)) {
+                       !pipe->stream->link_enc) && !stream_changed_otg_dig_on) 
{
+                       /* This w/a should not trigger when we have a dig 
active */
                        if (disable) {
                                if (pipe->stream_res.tg && 
pipe->stream_res.tg->funcs->disable_crtc)
                                        
pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
diff --git 
a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
index 6a179e5ab417..fcc88ef83e6a 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
@@ -392,6 +392,14 @@ static void enc35_reset_fifo(struct stream_encoder *enc, 
bool reset)
                udelay(10);
 }
 
+static bool enc35_is_fifo_enabled(struct stream_encoder *enc)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+       uint32_t reset_val;
+
+       REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &reset_val);
+       return (reset_val == 0) ? false : true;
+}
 void enc35_disable_fifo(struct stream_encoder *enc)
 {
        struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
@@ -465,6 +473,7 @@ static const struct stream_encoder_funcs 
dcn35_str_enc_funcs = {
        .set_input_mode = enc314_set_dig_input_mode,
        .enable_fifo = enc35_enable_fifo,
        .disable_fifo = enc35_disable_fifo,
+       .is_fifo_enabled = enc35_is_fifo_enabled,
        .map_stream_to_link = enc35_stream_encoder_map_to_link,
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index e5e11c84e9e2..6fe42120738d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -271,6 +271,7 @@ struct stream_encoder_funcs {
                struct stream_encoder *enc, unsigned int pix_per_container);
        void (*enable_fifo)(struct stream_encoder *enc);
        void (*disable_fifo)(struct stream_encoder *enc);
+       bool (*is_fifo_enabled)(struct stream_encoder *enc);
        void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t 
stream_enc_inst, uint32_t link_enc_inst);
 };
 
-- 
2.34.1

Reply via email to