From: Dillon Varone <dillon.varone@xxxxxxx> [WHY&HOW] Improves on the SMU interface to explicitly declare P-State support. Reviewed-by: Alvin Lee <alvin.lee2@xxxxxxx> Acked-by: Zaeem Mohamed <zaeem.mohamed@xxxxxxx> Signed-off-by: Dillon Varone <dillon.varone@xxxxxxx> --- .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 133 ++++++++++++------ .../dc/clk_mgr/dcn401/dcn401_clk_mgr.h | 3 +- .../clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c | 14 +- .../clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h | 6 +- .../dc/resource/dcn32/dcn32_resource.c | 4 + 5 files changed, 106 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c index e3a3893a9cab..0975986f5989 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c @@ -467,10 +467,10 @@ static void dcn401_update_clocks_legacy(struct clk_mgr *clk_mgr_base, if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support)) { clk_mgr_base->clks.fclk_p_state_change_support = fclk_p_state_change_support; - /* To enable FCLK P-state switching, send FCLK_PSTATE_SUPPORTED message to PMFW */ + /* To enable FCLK P-state switching, send PSTATE_SUPPORTED message to PMFW */ if (clk_mgr_base->clks.fclk_p_state_change_support) { /* Handle the code for sending a message to PMFW that FCLK P-state change is supported */ - dcn401_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_SUPPORTED); + dcn401_smu_send_fclk_pstate_message(clk_mgr, true); } } @@ -506,7 +506,7 @@ static void dcn401_update_clocks_legacy(struct clk_mgr *clk_mgr_base, p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0); - if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { + if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.prev_p_state_change_support)) { clk_mgr_base->clks.p_state_change_support = p_state_change_support; clk_mgr_base->clks.fw_based_mclk_switching = p_state_change_support && new_clocks->fw_based_mclk_switching; @@ -525,7 +525,7 @@ static void dcn401_update_clocks_legacy(struct clk_mgr *clk_mgr_base, update_fclk && dcn401_is_ppclk_dpm_enabled(clk_mgr, PPCLK_FCLK)) { /* Handle code for sending a message to PMFW that FCLK P-state change is not supported */ - dcn401_smu_send_fclk_pstate_message(clk_mgr, FCLK_PSTATE_NOTSUPPORTED); + dcn401_smu_send_fclk_pstate_message(clk_mgr, false); } /* Always update saved value, even if new value not set due to P-State switching unsupported */ @@ -678,7 +678,12 @@ static void dcn401_execute_block_sequence(struct clk_mgr *clk_mgr_base, unsigned case CLK_MGR401_UPDATE_FCLK_PSTATE_SUPPORT: dcn401_smu_send_fclk_pstate_message( clk_mgr_internal, - params->update_fclk_pstate_support_params.support); + params->update_pstate_support_params.support); + break; + case CLK_MGR401_UPDATE_UCLK_PSTATE_SUPPORT: + dcn401_smu_send_uclk_pstate_message( + clk_mgr_internal, + params->update_pstate_support_params.support); break; case CLK_MGR401_UPDATE_CAB_FOR_UCLK: dcn401_smu_send_cab_for_uclk_message( @@ -773,16 +778,16 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence( /* CLK_MGR401_UPDATE_FCLK_PSTATE_SUPPORT */ clk_mgr_base->clks.fclk_prev_p_state_change_support = clk_mgr_base->clks.fclk_p_state_change_support; fclk_p_state_change_support = new_clocks->fclk_p_state_change_support || (total_plane_count == 0); - if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support)) { + if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_prev_p_state_change_support)) { clk_mgr_base->clks.fclk_p_state_change_support = fclk_p_state_change_support; update_active_fclk = true; update_idle_fclk = true; - /* To enable FCLK P-state switching, send FCLK_PSTATE_SUPPORTED message to PMFW */ + /* To enable FCLK P-state switching, send PSTATE_SUPPORTED message to PMFW */ if (clk_mgr_base->clks.fclk_p_state_change_support) { /* Handle the code for sending a message to PMFW that FCLK P-state change is supported */ if (dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_FCLK)) { - block_sequence[num_steps].params.update_fclk_pstate_support_params.support = FCLK_PSTATE_SUPPORTED; + block_sequence[num_steps].params.update_pstate_support_params.support = true; block_sequence[num_steps].func = CLK_MGR401_UPDATE_FCLK_PSTATE_SUPPORT; num_steps++; } @@ -825,12 +830,26 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence( /* We don't actually care about socclk, don't notify SMU of hard min */ clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz; + /* UCLK */ + if (new_clocks->fw_based_mclk_switching != clk_mgr_base->clks.fw_based_mclk_switching && + new_clocks->fw_based_mclk_switching) { + /* enable FAMS features */ + clk_mgr_base->clks.fw_based_mclk_switching = new_clocks->fw_based_mclk_switching; + + block_sequence[num_steps].params.update_wait_for_dmub_ack_params.enable = clk_mgr_base->clks.fw_based_mclk_switching; + block_sequence[num_steps].func = CLK_MGR401_UPDATE_WAIT_FOR_DMUB_ACK; + num_steps++; + + block_sequence[num_steps].params.indicate_drr_status_params.mod_drr_for_pstate = clk_mgr_base->clks.fw_based_mclk_switching; + block_sequence[num_steps].func = CLK_MGR401_INDICATE_DRR_STATUS; + num_steps++; + } + /* CLK_MGR401_UPDATE_CAB_FOR_UCLK */ - clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; clk_mgr_base->clks.prev_num_ways = clk_mgr_base->clks.num_ways; - if (clk_mgr_base->clks.num_ways != new_clocks->num_ways && clk_mgr_base->clks.num_ways < new_clocks->num_ways) { + /* increase num ways for subvp */ clk_mgr_base->clks.num_ways = new_clocks->num_ways; if (dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_UCLK)) { block_sequence[num_steps].params.update_cab_for_uclk_params.num_ways = clk_mgr_base->clks.num_ways; @@ -839,15 +858,22 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence( } } - /* UCLK */ + clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; uclk_p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0); - if (should_update_pstate_support(safe_to_lower, uclk_p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { + if (should_update_pstate_support(safe_to_lower, uclk_p_state_change_support, clk_mgr_base->clks.prev_p_state_change_support)) { clk_mgr_base->clks.p_state_change_support = uclk_p_state_change_support; update_active_uclk = true; update_idle_uclk = true; - /* to disable P-State switching, set UCLK min = max */ - if (!clk_mgr_base->clks.p_state_change_support) { + if (clk_mgr_base->clks.p_state_change_support) { + /* enable UCLK switching */ + if (dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_UCLK)) { + block_sequence[num_steps].params.update_pstate_support_params.support = true; + block_sequence[num_steps].func = CLK_MGR401_UPDATE_UCLK_PSTATE_SUPPORT; + num_steps++; + } + } else { + /* when disabling P-State switching, set UCLK min = max */ if (dc->clk_mgr->dc_mode_softmax_enabled) { /* will never have the functional UCLK min above the softmax * since we calculate mode support based on softmax being the max UCLK @@ -870,6 +896,7 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence( active_uclk_mhz = khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz); } } + if (should_set_clock(safe_to_lower, new_clocks->idle_dramclk_khz, clk_mgr_base->clks.idle_dramclk_khz)) { clk_mgr_base->clks.idle_dramclk_khz = new_clocks->idle_dramclk_khz; @@ -879,17 +906,6 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence( } } - /* set UCLK to requested value */ - if ((update_active_uclk || update_idle_uclk) && - dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_UCLK) && - !is_idle_dpm_enabled) { - block_sequence[num_steps].params.update_hardmin_params.ppclk = PPCLK_UCLK; - block_sequence[num_steps].params.update_hardmin_params.freq_mhz = active_uclk_mhz; - block_sequence[num_steps].params.update_hardmin_params.response = NULL; - block_sequence[num_steps].func = CLK_MGR401_UPDATE_HARDMIN_PPCLK; - num_steps++; - } - /* FCLK */ /* Always update saved value, even if new value not set due to P-State switching unsupported */ if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, clk_mgr_base->clks.fclk_khz)) { @@ -927,41 +943,66 @@ static unsigned int dcn401_build_update_bandwidth_clocks_sequence( num_steps++; } - /* CLK_MGR401_UPDATE_WAIT_FOR_DMUB_ACK, CLK_MGR401_INDICATE_DRR_STATUS*/ - if (clk_mgr_base->clks.fw_based_mclk_switching != new_clocks->fw_based_mclk_switching) { - clk_mgr_base->clks.fw_based_mclk_switching = new_clocks->fw_based_mclk_switching; - - block_sequence[num_steps].params.update_wait_for_dmub_ack_params.enable = clk_mgr_base->clks.fw_based_mclk_switching; - block_sequence[num_steps].func = CLK_MGR401_UPDATE_WAIT_FOR_DMUB_ACK; - num_steps++; + /* set UCLK to requested value if P-State switching is supported, or to re-enable P-State switching */ + if (update_active_uclk || update_idle_uclk) { + if (!is_idle_dpm_enabled) { + block_sequence[num_steps].params.update_hardmin_params.ppclk = PPCLK_UCLK; + block_sequence[num_steps].params.update_hardmin_params.freq_mhz = active_uclk_mhz; + block_sequence[num_steps].params.update_hardmin_params.response = NULL; + block_sequence[num_steps].func = CLK_MGR401_UPDATE_HARDMIN_PPCLK; + num_steps++; + } - block_sequence[num_steps].params.indicate_drr_status_params.mod_drr_for_pstate = clk_mgr_base->clks.fw_based_mclk_switching; - block_sequence[num_steps].func = CLK_MGR401_INDICATE_DRR_STATUS; - num_steps++; + /* disable UCLK P-State support if needed */ + if (!uclk_p_state_change_support && + should_update_pstate_support(safe_to_lower, uclk_p_state_change_support, clk_mgr_base->clks.prev_p_state_change_support) && + dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_UCLK)) { + block_sequence[num_steps].params.update_pstate_support_params.support = false; + block_sequence[num_steps].func = CLK_MGR401_UPDATE_UCLK_PSTATE_SUPPORT; + num_steps++; + } } /* set FCLK to requested value if P-State switching is supported, or to re-enable P-State switching */ - if ((update_active_fclk || update_idle_fclk)) { + if (update_active_fclk || update_idle_fclk) { + /* No need to send active FCLK hardmin, automatically set based on DCFCLK */ + // if (!is_idle_dpm_enabled) { + // block_sequence[*num_steps].update_hardmin_params.clk_mgr = clk_mgr; + // block_sequence[*num_steps].update_hardmin_params.ppclk = PPCLK_FCLK; + // block_sequence[*num_steps].update_hardmin_params.freq_mhz = active_fclk_mhz; + // block_sequence[*num_steps].update_hardmin_params.response = NULL; + // block_sequence[*num_steps].func = CLK_MGR401_UPDATE_HARDMIN_PPCLK; + // (*num_steps)++; + // } + /* disable FCLK P-State support if needed */ - if (clk_mgr_base->clks.fclk_p_state_change_support != clk_mgr_base->clks.fclk_prev_p_state_change_support && + if (!fclk_p_state_change_support && + should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_prev_p_state_change_support) && dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_FCLK)) { - block_sequence[num_steps].params.update_fclk_pstate_support_params.support = FCLK_PSTATE_NOTSUPPORTED; + block_sequence[num_steps].params.update_pstate_support_params.support = false; block_sequence[num_steps].func = CLK_MGR401_UPDATE_FCLK_PSTATE_SUPPORT; num_steps++; } + } - /* No need to send active FCLK hardmin, automatically set based on DCFCLK */ - // block_sequence[*num_steps].update_hardmin_params.clk_mgr = clk_mgr; - // block_sequence[*num_steps].update_hardmin_params.ppclk = PPCLK_FCLK; - // block_sequence[*num_steps].update_hardmin_params.freq_mhz = active_fclk_mhz; - // block_sequence[*num_steps].update_hardmin_params.response = NULL; - // block_sequence[*num_steps].func = CLK_MGR401_UPDATE_HARDMIN_PPCLK; - // (*num_steps)++; + if (new_clocks->fw_based_mclk_switching != clk_mgr_base->clks.fw_based_mclk_switching && + safe_to_lower && !new_clocks->fw_based_mclk_switching) { + /* disable FAMS features */ + clk_mgr_base->clks.fw_based_mclk_switching = new_clocks->fw_based_mclk_switching; + + block_sequence[num_steps].params.update_wait_for_dmub_ack_params.enable = clk_mgr_base->clks.fw_based_mclk_switching; + block_sequence[num_steps].func = CLK_MGR401_UPDATE_WAIT_FOR_DMUB_ACK; + num_steps++; + + block_sequence[num_steps].params.indicate_drr_status_params.mod_drr_for_pstate = clk_mgr_base->clks.fw_based_mclk_switching; + block_sequence[num_steps].func = CLK_MGR401_INDICATE_DRR_STATUS; + num_steps++; } /* CLK_MGR401_UPDATE_CAB_FOR_UCLK */ if (clk_mgr_base->clks.num_ways != new_clocks->num_ways && - clk_mgr_base->clks.num_ways > new_clocks->num_ways) { + safe_to_lower && clk_mgr_base->clks.num_ways > new_clocks->num_ways) { + /* decrease num ways for subvp */ clk_mgr_base->clks.num_ways = new_clocks->num_ways; if (dcn401_is_ppclk_dpm_enabled(clk_mgr_internal, PPCLK_UCLK)) { block_sequence[num_steps].params.update_cab_for_uclk_params.num_ways = clk_mgr_base->clks.num_ways; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h index 8860b35279d3..8b0461992b22 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h @@ -38,7 +38,7 @@ union dcn401_clk_mgr_block_sequence_params { struct { /* inputs */ bool support; - } update_fclk_pstate_support_params; + } update_pstate_support_params; struct { /* inputs */ unsigned int num_ways; @@ -82,6 +82,7 @@ enum dcn401_clk_mgr_block_sequence_func { CLK_MGR401_UPDATE_IDLE_HARDMINS, CLK_MGR401_UPDATE_DEEP_SLEEP_DCFCLK, CLK_MGR401_UPDATE_FCLK_PSTATE_SUPPORT, + CLK_MGR401_UPDATE_UCLK_PSTATE_SUPPORT, CLK_MGR401_UPDATE_CAB_FOR_UCLK, CLK_MGR401_UPDATE_WAIT_FOR_DMUB_ACK, CLK_MGR401_INDICATE_DRR_STATUS, diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c index 84e9203aba3b..7700477d019b 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c @@ -131,12 +131,20 @@ static bool dcn401_smu_send_msg_with_param_delay(struct clk_mgr_internal *clk_mg return false; } -void dcn401_smu_send_fclk_pstate_message(struct clk_mgr_internal *clk_mgr, bool enable) +void dcn401_smu_send_fclk_pstate_message(struct clk_mgr_internal *clk_mgr, bool support) { - smu_print("FCLK P-state support value is : %d\n", enable); + smu_print("FCLK P-state support value is : %d\n", support); dcn401_smu_send_msg_with_param(clk_mgr, - DALSMC_MSG_SetFclkSwitchAllow, enable ? FCLK_PSTATE_SUPPORTED : FCLK_PSTATE_NOTSUPPORTED, NULL); + DALSMC_MSG_SetFclkSwitchAllow, support, NULL); +} + +void dcn401_smu_send_uclk_pstate_message(struct clk_mgr_internal *clk_mgr, bool support) +{ + smu_print("UCLK P-state support value is : %d\n", support); + + dcn401_smu_send_msg_with_param(clk_mgr, + DALSMC_MSG_SetUclkPstateAllow, support, NULL); } void dcn401_smu_send_cab_for_uclk_message(struct clk_mgr_internal *clk_mgr, unsigned int num_ways) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h index 892881d11ce8..651fb8d62864 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h @@ -9,10 +9,8 @@ #include "core_types.h" #include "dcn32/dcn32_clk_mgr_smu_msg.h" -#define FCLK_PSTATE_NOTSUPPORTED 0x00 -#define FCLK_PSTATE_SUPPORTED 0x01 - -void dcn401_smu_send_fclk_pstate_message(struct clk_mgr_internal *clk_mgr, bool enable); +void dcn401_smu_send_fclk_pstate_message(struct clk_mgr_internal *clk_mgr, bool support); +void dcn401_smu_send_uclk_pstate_message(struct clk_mgr_internal *clk_mgr, bool support); void dcn401_smu_send_cab_for_uclk_message(struct clk_mgr_internal *clk_mgr, unsigned int num_ways); void dcn401_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr); void dcn401_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr); diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c index 022d320be1d5..ab9df1cc1d3c 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c @@ -1978,6 +1978,10 @@ unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned { uint32_t cache_lines_used, lines_per_way, total_cache_lines, num_ways; + if (total_size_in_mall_bytes == 0) { + return 0; + } + /* add 2 lines for worst case alignment */ cache_lines_used = total_size_in_mall_bytes / dc->caps.cache_line_size + 2; -- 2.34.1