[PATCH 16/34] drm/amd/display: Decide zstate_support based off Z8 global support
Tom Chung <[email protected]> Wed, 5 Aug 2026 14:36:28 +0800
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Ovidiu Bunea <[email protected]> [why & how] DC incorrectly reports ZStates NOT supported for eDP panels without support for PSR or Replay. This is because the zstate_support flag is populated with supported_in_blank, which is not the correct interpretation. Z8 can be entered for a plane when its Z8 stutter enter plus exit time is covered either during vblank (reserved vblank time is greater than SREnterPlusExitZ8Time) or during vactive (active clock change latency hiding minus the Z8StutterEnterPlusExitWatermark is positive). Compute this per plane in CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(), and report Z8 as supported only when every non-phantom plane satisfies at least one of these two cases. Populate z8_stutter.global_support in mode programming and use it to populate zstate_support. Assisted-by: Claude:claude-Opus-4.8 Reviewed-by: Dillon Varone <[email protected]> Signed-off-by: Ovidiu Bunea <[email protected]> Signed-off-by: Tom Chung <[email protected]> --- .../dc/dml2_0/dml21/dml21_translation_helper.c | 2 +- .../display/dc/dml2_0/dml21/inc/dml_top_types.h | 1 + .../dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c | 4 ++++ .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 15 +++++++++++++++ .../dml21/src/dml2_core/dml2_core_dcn4_calcs.h | 1 + .../dml21/src/dml2_core/dml2_core_shared_types.h | 2 ++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c index 1b0d55e2d7b0..f4f848d73820 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c @@ -999,7 +999,7 @@ void dml21_copy_clocks_to_dc_state(struct dml2_context *in_ctx, struct dc_state context->bw_ctx.bw.dcn.clk.stutter_efficiency.low_power_efficiency = (uint8_t)in_ctx->v21.mode_programming.programming->stutter.low_power_percent_efficiency; context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_efficiency = (uint8_t)in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_efficiency; context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_period = (int)in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_period; - context->bw_ctx.bw.dcn.clk.zstate_support = in_ctx->v21.mode_programming.programming->z8_stutter.supported_in_blank; /*ignore meets_eco since it is not used*/ + context->bw_ctx.bw.dcn.clk.zstate_support = in_ctx->v21.mode_programming.programming->z8_stutter.global_support; } static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_watermark_set *watermarks, const enum dml2_dchub_watermark_reg_set_index wm_index) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h index bf71f4e1a451..c04a4af1f3ea 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h @@ -480,6 +480,7 @@ struct dml2_display_cfg_programming { struct { bool meets_eco; // Stutter cycles will meet Z8 ECO criteria bool supported_in_blank; // Changing to configurations where this is false requires Z8 to be disabled during the transition + bool global_support; // Z8 supported in vblank or vactive } z8_stutter; struct dml2_dchub_global_register_set global_regs; 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 6ea36aedcf20..a040c3f47337 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 @@ -701,6 +701,10 @@ bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out result = dml2_core_calcs_mode_programming_ex(&l->mode_programming_ex_params); if (result) { + // Populate the global Z8 stutter support (common to all packing paths) + dml2_core_calcs_get_z8_stutter_support(&core->clean_me_up.mode_lib, + &in_out->programming->z8_stutter.global_support); + // If the input display configuration contains implict SVP, we need to use a special packer if (in_out->display_cfg->display_config.overrides.enable_subvp_implicit_pmo) { pack_mode_programming_params_with_implicit_subvp(core, in_out->display_cfg, &l->svp_expanded_display_cfg, in_out->programming, &core->scratch); 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 72acf12e9251..d943cc8bf60e 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 @@ -6876,6 +6876,8 @@ static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( *p->global_fclk_change_supported = true; *p->global_dram_clock_change_supported = true; + if (p->global_z8_stutter_supported) + *p->global_z8_stutter_supported = true; for (unsigned int k = 0; k < p->NumberOfActiveSurfaces; ++k) { double h_total = (double)p->display_cfg->stream_descriptors[p->display_cfg->plane_descriptors[k].stream_index].timing.h_total; @@ -6990,6 +6992,12 @@ static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( if (p->DRAMClockChangeSupport[k] == dml2_pstate_change_unsupported) *p->global_dram_clock_change_supported = false; + if (p->global_z8_stutter_supported && + !dml_is_phantom_pipe(&p->display_cfg->plane_descriptors[k]) && + !(reserved_vblank_time_us > p->mmSOCParameters.SREnterPlusExitZ8Time) && + !((s->ActiveClockChangeLatencyHiding - p->Watermark->Z8StutterEnterPlusExitWatermark) > 0)) + *p->global_z8_stutter_supported = false; + s->dst_y_pstate = (unsigned int)(math_ceil2((p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.UrgentLatency) / (h_total / pixel_clock_mhz), 1)); s->src_y_pstate_l = (unsigned int)(math_ceil2(s->dst_y_pstate * v_ratio, p->SwathHeightY[k])); s->src_y_ahead_l = (unsigned int)(math_floor2(p->DETBufferSizeY[k] / p->BytePerPixelDETY[k] / p->SwathWidthY[k], p->SwathHeightY[k]) + s->LBLatencyHidingSourceLinesY[k]); @@ -8027,6 +8035,7 @@ static noinline_for_stack void dml_core_ms_prefetch_check(struct dml2_core_inter CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // double *MaxActiveFCLKChangeLatencySupported CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport; CalculateWatermarks_params->g6_temp_read_support = &mode_lib->ms.support.g6_temp_read_support; + CalculateWatermarks_params->global_z8_stutter_supported = NULL; // only consumed by mode programming CalculateWatermarks_params->VActiveLatencyHidingMargin = mode_lib->ms.VActiveLatencyHidingMargin; CalculateWatermarks_params->VActiveLatencyHidingUs = mode_lib->ms.VActiveLatencyHidingUs; @@ -11883,6 +11892,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &mode_lib->mp.MaxActiveFCLKChangeLatencySupported; CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->mp.USRRetrainingSupport; CalculateWatermarks_params->g6_temp_read_support = &mode_lib->mp.g6_temp_read_support; + CalculateWatermarks_params->global_z8_stutter_supported = &mode_lib->mp.global_z8_stutter_supported; CalculateWatermarks_params->VActiveLatencyHidingMargin = 0; CalculateWatermarks_params->VActiveLatencyHidingUs = 0; @@ -12909,6 +12919,11 @@ void dml2_core_calcs_get_mcif_arb_params(const struct dml2_core_internal_display out->wm_regs[0].temp_read_or_ppt = (unsigned int)(mode_lib->mp.Watermark.writeback_temp_read_or_ppt_watermark_us * 1000.0); } +void dml2_core_calcs_get_z8_stutter_support(const struct dml2_core_internal_display_mode_lib *mode_lib, bool *out) +{ + *out = mode_lib->mp.global_z8_stutter_supported; +} + void dml2_core_calcs_get_pipe_regs(const struct dml2_display_cfg *display_cfg, struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_per_pipe_register_set *out, int pipe_index) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h index 3249f6bcf7bc..e0e397b14bb4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.h @@ -20,6 +20,7 @@ unsigned int dml2_core_calcs_mode_support_ex(struct dml2_core_calcs_mode_support bool dml2_core_calcs_mode_programming_ex(struct dml2_core_calcs_mode_programming_ex *in_out_params); void dml2_core_calcs_get_watermarks(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_watermark_regs *out); void dml2_core_calcs_get_mcif_arb_params(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_mcif_global_register_set *out); +void dml2_core_calcs_get_z8_stutter_support(const struct dml2_core_internal_display_mode_lib *mode_lib, bool *out); void dml2_core_calcs_get_arb_params(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_arb_regs *out); void dml2_core_calcs_get_pipe_regs(const struct dml2_display_cfg *dml2_display_cfg, struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_dchub_per_pipe_register_set *out, int pipe_index); void dml2_core_calcs_get_stream_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_per_stream_programming *out, int pipe_index); 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 8a371bd1a7a5..0f1f58471cff 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 @@ -1039,6 +1039,7 @@ struct dml2_core_internal_mode_program { double MaxActiveFCLKChangeLatencySupported; bool USRRetrainingSupport; bool g6_temp_read_support; + bool global_z8_stutter_supported; enum dml2_pstate_change_support FCLKChangeSupport[DML2_MAX_PLANES]; enum dml2_pstate_change_support DRAMClockChangeSupport[DML2_MAX_PLANES]; enum dml2_pstate_change_support temp_read_or_ppt_support[DML2_MAX_PLANES]; @@ -1841,6 +1842,7 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_param bool *g6_temp_read_support; enum dml2_pstate_change_support *temp_read_or_ppt_support; bool *global_temp_read_or_ppt_supported; + bool *global_z8_stutter_supported; }; struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params { -- 2.43.0