From d6c025d243b191e4d577fc217697adb2f0c8a14b Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Mon, 8 May 2017 15:11:41 -0400 Subject: [PATCH] drm/amd/powerplay: add power profile support for Vega10 (v2) This implements the workload specific interface of optimized compute power profile for Vega10. v2: squash in fix (Tom) Signed-off-by: Eric Huang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 2614af2f553f..1c5d0a994ad7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -2286,6 +2286,34 @@ static int vega10_avfs_enable(struct pp_hwmgr *hwmgr, bool enable) return 0; } +static int vega10_save_default_power_profile(struct pp_hwmgr *hwmgr) +{ + struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend); + struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table); + uint32_t min_level; + + hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; + hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; + + /* Optimize compute power profile: Use only highest + * 2 power levels (if more than 2 are available) + */ + if (dpm_table->count > 2) + min_level = dpm_table->count - 2; + else if (dpm_table->count == 2) + min_level = 1; + else + min_level = 0; + + hwmgr->default_compute_power_profile.min_sclk = + dpm_table->dpm_levels[min_level].value; + + hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; + + return 0; +} + /** * Initializes the SMC table and uploads it * @@ -2420,6 +2448,8 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE(!result, "Attempt to enable AVFS feature Failed!", return result); + vega10_save_default_power_profile(hwmgr); + return 0; } @@ -4483,6 +4513,67 @@ static int vega10_power_off_asic(struct pp_hwmgr *hwmgr) return result; } +static void vega10_find_min_clock_index(struct pp_hwmgr *hwmgr, + uint32_t *sclk_idx, uint32_t *mclk_idx, + uint32_t min_sclk, uint32_t min_mclk) +{ + struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend); + struct vega10_dpm_table *dpm_table = &(data->dpm_table); + uint32_t i; + + for (i = 0; i < dpm_table->gfx_table.count; i++) { + if (dpm_table->gfx_table.dpm_levels[i].enabled && + dpm_table->gfx_table.dpm_levels[i].value >= min_sclk) { + *sclk_idx = i; + break; + } + } + + for (i = 0; i < dpm_table->mem_table.count; i++) { + if (dpm_table->mem_table.dpm_levels[i].enabled && + dpm_table->mem_table.dpm_levels[i].value >= min_mclk) { + *mclk_idx = i; + break; + } + } +} + +static int vega10_set_power_profile_state(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) +{ + struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend); + uint32_t sclk_idx = 0, mclk_idx = 0; + + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_AUTO) + return -EINVAL; + + vega10_find_min_clock_index(hwmgr, &sclk_idx, &mclk_idx, + request->min_sclk, request->min_mclk); + + if (sclk_idx) { + if (!data->registry_data.sclk_dpm_key_disabled) + PP_ASSERT_WITH_CODE( + !smum_send_msg_to_smc_with_parameter( + hwmgr->smumgr, + PPSMC_MSG_SetSoftMinGfxclkByIndex, + sclk_idx), + "Failed to set soft min sclk index!", + return -EINVAL); + } + + if (mclk_idx) { + if (!data->registry_data.mclk_dpm_key_disabled) + PP_ASSERT_WITH_CODE( + !smum_send_msg_to_smc_with_parameter( + hwmgr->smumgr, + PPSMC_MSG_SetSoftMinUclkByIndex, + mclk_idx), + "Failed to set soft min mclk index!", + return -EINVAL); + } + + return 0; +} static const struct pp_hwmgr_func vega10_hwmgr_funcs = { .backend_init = vega10_hwmgr_backend_init, @@ -4531,6 +4622,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = { vega10_check_smc_update_required_for_display_configuration, .power_off_asic = vega10_power_off_asic, .disable_smc_firmware_ctf = vega10_thermal_disable_alert, + .set_power_profile_state = vega10_set_power_profile_state, }; int vega10_hwmgr_init(struct pp_hwmgr *hwmgr) -- 2.45.2