From: George Shen <[email protected]>

[Why]
Current DSC enable sequence is intertwined with the DPMS on sequence.
The sequence has become unnecessarily confusing, and resulted in cases
where DSC is programmed unexpectedly, or in an incorrect sequence.

Current sequence enables OTG before DSC. After discussing with HW team,
there should be no issue with enabling DSC first before OTG.

[How]
Starting with DCN60, skip DSC HW programming in the DPMS sequences.

Add enable DSC function call prior to OTG enable, and similarly for the
disable case.

Reviewed-by: Dillon Varone <[email protected]>
Signed-off-by: George Shen <[email protected]>
Signed-off-by: Ivan Lipski <[email protected]>
---
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 18 ++++++++++++++++++
 .../amd/display/dc/hwss/dcn60/dcn60_hwseq.c   |  2 ++
 .../gpu/drm/amd/display/dc/link/link_dpms.c   | 19 ++++++++++++++-----
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index d237061236af..a843e216a6b0 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -818,6 +818,15 @@ enum dc_status dcn401_enable_stream_timing(
 
        hws->funcs.blank_pixel_data(dc, pipe_ctx, true);
 
+       /* Legacy code path will enable DSC during DPMS on sequence. Since DSC
+        * HW block programming is independent from link and stream encoder 
operations, it
+        * has moved to hwss and should be called when enabling/disabling OTG.
+        */
+       if (stream->timing.flags.DSC && pipe_ctx->stream_res.dsc) {
+               if (dc->hwss.configure_dsc)
+                       dc->hwss.configure_dsc(pipe_ctx, true);
+       }
+
        /* VTG is  within DCHUB command block. DCFCLK is always on */
        if (false == 
pipe_ctx->stream_res.tg->funcs->enable_crtc(pipe_ctx->stream_res.tg)) {
                BREAK_TO_DEBUGGER();
@@ -2116,6 +2125,15 @@ void dcn401_reset_back_end_for_pipe(
 
                        
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
 
+                       /* Legacy code path will enable DSC during DPMS on 
sequence. Since DSC
+                        * HW block programming is independent from backend 
operations, it
+                        * has moved to hwss and should be called when 
enabling/disabling OTG.
+                        */
+                       if (pipe_ctx->stream_res.dsc) {
+                               if (dc->hwss.configure_dsc)
+                                       dc->hwss.configure_dsc(pipe_ctx, false);
+                       }
+
                        
pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, 
false);
                }
                if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
index e2dddbc170f8..c5fab430b7f7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
@@ -125,6 +125,7 @@ bool dcn60_configure_dsc(struct pipe_ctx *pipe_ctx, bool 
enable)
                        enum optc_dsc_mode mode = 
dsc_optc_cfg.is_pixel_format_444 ?
                                        OPTC_DSC_ENABLED_444 : 
OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
 
+                       DC_LOG_DSC("Setting optc DSC config for tg instance 
%d:", pipe_ctx->stream_res.tg->inst);
                        pipe_ctx->stream_res.tg->funcs->set_dsc_config(
                                        pipe_ctx->stream_res.tg, mode,
                                        dsc_optc_cfg.bytes_per_pixel, 
dsc_optc_cfg.slice_width);
@@ -132,6 +133,7 @@ bool dcn60_configure_dsc(struct pipe_ctx *pipe_ctx, bool 
enable)
                return true;
        }
 
+       DC_LOG_DSC("Setting optc DSC config for tg instance %d:", 
pipe_ctx->stream_res.tg->inst);
        pipe_ctx->stream_res.tg->funcs->set_dsc_config(
                        pipe_ctx->stream_res.tg, OPTC_DSC_DISABLED, 0, 0);
 
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c 
b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index ef577e0e5215..42a47d12d1f3 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -914,6 +914,7 @@ static bool configure_dsc_hw_block(struct pipe_ctx 
*pipe_ctx, bool enable,
  */
 void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 {
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
        struct dsc_config dsc_cfg = {0};
        struct dsc_optc_config dsc_optc_cfg = {0};
 
@@ -922,12 +923,20 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, 
bool enable)
                return;
        }
 
-       if (enable) {
-               if (configure_dsc_hw_block(pipe_ctx, true, &dsc_cfg, 
&dsc_optc_cfg))
-                       set_encoder_dsc_config(pipe_ctx, &dsc_cfg, 
&dsc_optc_cfg, true);
-       } else {
+       if (dc->hwss.configure_dsc) {
+               /* If the hwss configure_dsc function is supported, then DSC 
will be programmed
+                * in the same sequence of OTG enable/disable. Thus, we don't 
need to configure
+                * the DSC hw block here.
+                */
                set_encoder_dsc_config(pipe_ctx, &dsc_cfg, &dsc_optc_cfg, 
false);
-               configure_dsc_hw_block(pipe_ctx, false, &dsc_cfg, 
&dsc_optc_cfg);
+       } else {
+               if (enable) {
+                       if (configure_dsc_hw_block(pipe_ctx, true, &dsc_cfg, 
&dsc_optc_cfg))
+                               set_encoder_dsc_config(pipe_ctx, &dsc_cfg, 
&dsc_optc_cfg, true);
+               } else {
+                       set_encoder_dsc_config(pipe_ctx, &dsc_cfg, 
&dsc_optc_cfg, false);
+                       configure_dsc_hw_block(pipe_ctx, false, &dsc_cfg, 
&dsc_optc_cfg);
+               }
        }
 }
 
-- 
2.43.0

Reply via email to