From: Alvin Lee <alvin.l...@amd.com>

[Why and How]
- For driver disable cases in current implementation, if P-State
  is unsupported or still supported by firmware, we force it
  supported by DCN.

- SubVP now needs to be included in this case along with FPO.

Reviewed-by: Jun Lei <jun....@amd.com>
Acked-by: Wayne Lin <wayne....@amd.com>
Signed-off-by: Alvin Lee <alvin.l...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  |  1 +
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    | 21 ++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index 9f5b47b9a83d..7e438345b1a8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -85,6 +85,7 @@ void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv 
*dmub_srv, union dmub_inbox0
 
 bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct 
dmub_diagnostic_data *dmub_oca);
 
+void dc_dmub_setup_subvp_dmub_command(struct dc *dc, struct dc_state *context, 
bool enable);
 void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv);
 
 #endif /* _DMUB_DC_SRV_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index fb59fed8f425..4a1954fe3f7e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -939,13 +939,32 @@ bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct 
dc_plane_state *plane, s
 
 void dcn30_hardware_release(struct dc *dc)
 {
+       bool subvp_in_use = false;
+       uint8_t i;
+
        dc_dmub_srv_p_state_delegate(dc, false, NULL);
+       dc_dmub_setup_subvp_dmub_command(dc, dc->current_state, false);
+
+       /* SubVP treated the same way as FPO. If driver disable and
+        * we are using a SubVP config, disable and force on DCN side
+        * to prevent P-State hang on driver enable.
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 
+               if (!pipe->stream)
+                       continue;
+
+               if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+                       subvp_in_use = true;
+                       break;
+               }
+       }
        /* If pstate unsupported, or still supported
         * by firmware, force it supported by dcn
         */
        if (dc->current_state)
-               if ((!dc->clk_mgr->clks.p_state_change_support ||
+               if ((!dc->clk_mgr->clks.p_state_change_support || subvp_in_use 
||
                                
dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) &&
                                
dc->res_pool->hubbub->funcs->force_pstate_change_control)
                        
dc->res_pool->hubbub->funcs->force_pstate_change_control(
-- 
2.37.3

Reply via email to