From: Alexander Chechik <[email protected]>

[Why]
mode_support reads mode_lib.ms.uclk_pstate_switch_modes to enforce the
vactive pstate margin, but nothing populates it: the memset clears it and
the PMO selection is never passed in. The check always sees na and never
runs, so a plane with negative vactive margin can still pass and blank the
display.

[How]
Add a const per-plane pstate-method pointer to mode_support_ex, point it at
stage3.pstate_switch_modes when stage 3 has run (NULL otherwise), and copy
it into mode_lib.ms after the memset. Scope the support-required check to
the vactive methods it governs (vactive, fw_vactive_drr) so SVP, DRR and
vblank planes are not rejected by the vactive support flag.

Reviewed-by: Charlene Liu <[email protected]>
Signed-off-by: Alexander Chechik <[email protected]>
Signed-off-by: Matthew Stewart <[email protected]>
Tested-by: Dan Wheeler <[email protected]>
---
 .../dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c | 10 +++-------
 .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c  | 17 +++++++++++++----
 .../src/dml2_core/dml2_core_shared_types.h      |  1 +
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
index 45f1bf5e14bf..6ea36aedcf20 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
@@ -554,13 +554,9 @@ bool core_dcn4_mode_support(struct 
dml2_core_mode_support_in_out *in_out)
        l->mode_support_ex_params.min_clk_index = in_out->min_clk_index;
        l->mode_support_ex_params.out_evaluation_info = 
&in_out->mode_support_result.cfg_support_info.clean_me_up.support_info;
 
-       for (i = 0; i < l->svp_expanded_display_cfg.num_planes; i++) {
-               if (i < in_out->display_cfg->display_config.num_planes)
-                       
core->clean_me_up.mode_lib.ms.uclk_pstate_switch_modes[i] =
-                               
in_out->display_cfg->stage3.pstate_switch_modes[i];
-               else
-                       
core->clean_me_up.mode_lib.ms.uclk_pstate_switch_modes[i] = 
dml2_pstate_method_na;
-       }
+       l->mode_support_ex_params.uclk_pstate_switch_modes =
+               in_out->display_cfg->stage3.performed ?
+                       in_out->display_cfg->stage3.pstate_switch_modes : NULL;
 
        result = dml2_core_calcs_mode_support_ex(&l->mode_support_ex_params);
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index 4ca6a4521f11..09452f3e49db 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -8057,6 +8057,16 @@ static bool dml_core_mode_support(struct 
dml2_core_calcs_mode_support_ex *in_out
        memset(&mode_lib->ms, 0, sizeof(struct 
dml2_core_internal_mode_support));
 
        mode_lib->ms.num_active_planes = display_cfg->num_planes;
+
+       for (k = 0; k < mode_lib->ms.num_active_planes; k++) {
+               if (in_out_params->uclk_pstate_switch_modes &&
+                               
!dml_is_phantom_pipe(&display_cfg->plane_descriptors[k]))
+                       mode_lib->ms.uclk_pstate_switch_modes[k] =
+                               in_out_params->uclk_pstate_switch_modes[k];
+               else
+                       mode_lib->ms.uclk_pstate_switch_modes[k] = 
dml2_pstate_method_na;
+       }
+
        get_stream_output_bpp(s->OutputBpp, display_cfg);
 
        mode_lib->ms.state_idx = in_out_params->min_clk_index;
@@ -9644,14 +9654,13 @@ static bool dml_core_mode_support(struct 
dml2_core_calcs_mode_support_ex *in_out
 
        if (!display_cfg->overrides.all_streams_blanked) {
                for (k = 0; k < mode_lib->ms.num_active_planes; k++) {
-                       if (mode_lib->ms.uclk_pstate_switch_modes[k] == 
dml2_pstate_method_na)
+                       if (mode_lib->ms.uclk_pstate_switch_modes[k] != 
dml2_pstate_method_vactive &&
+                                       
mode_lib->ms.uclk_pstate_switch_modes[k] != dml2_pstate_method_fw_vactive_drr)
                                continue;
 
                        
mode_lib->ms.support.global_dram_clock_change_support_required = true;
 
-                       if ((mode_lib->ms.uclk_pstate_switch_modes[k] == 
dml2_pstate_method_vactive ||
-                                       
mode_lib->ms.uclk_pstate_switch_modes[k] == dml2_pstate_method_fw_vactive_drr) 
&&
-                                       
mode_lib->ms.VActiveLatencyHidingMargin[k] < 0)
+                       if (mode_lib->ms.VActiveLatencyHidingMargin[k] < 0)
                                
mode_lib->ms.support.global_dram_clock_change_supported = false;
                }
        }
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
index 131cec64aa48..b8af72392176 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -2333,6 +2333,7 @@ struct dml2_core_calcs_mode_support_ex {
        int min_clk_index;
        //unsigned int in_state_index;
        struct dml2_core_internal_mode_support_info *out_evaluation_info;
+       const enum dml2_pstate_method *uclk_pstate_switch_modes;
 };
 
 struct core_display_cfg_support_info;
-- 
2.53.0

Reply via email to