diff options
author | Eric Huang | 2017-01-24 16:47:25 +0100 |
---|---|---|
committer | Alex Deucher | 2017-03-30 05:52:49 +0200 |
commit | ff3953d49c0acafab527ec97a665df87ab6bbc70 (patch) | |
tree | d133f3cae01ed4e635c402e76ffb034da1e9e3af /drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |
parent | drm/amd/powerplay: reapply power profile when force dpm level to auto (diff) | |
download | kernel-qcow2-linux-ff3953d49c0acafab527ec97a665df87ab6bbc70.tar.gz kernel-qcow2-linux-ff3953d49c0acafab527ec97a665df87ab6bbc70.tar.xz kernel-qcow2-linux-ff3953d49c0acafab527ec97a665df87ab6bbc70.zip |
drm/amd/powerplay: add power profile support for SMU7
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
Acked-by: Rex Zhu <Rex.Zhu@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index f75ee33ec5bb..31289a8d5cec 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -4502,6 +4502,76 @@ static int smu7_release_firmware(struct pp_hwmgr *hwmgr) return 0; } +static void smu7_find_min_clock_masks(struct pp_hwmgr *hwmgr, + uint32_t *sclk_mask, uint32_t *mclk_mask, + uint32_t min_sclk, uint32_t min_mclk) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct smu7_dpm_table *dpm_table = &(data->dpm_table); + uint32_t i; + + for (i = 0; i < dpm_table->sclk_table.count; i++) { + if (dpm_table->sclk_table.dpm_levels[i].enabled && + dpm_table->sclk_table.dpm_levels[i].value >= min_sclk) + *sclk_mask |= 1 << i; + } + + for (i = 0; i < dpm_table->mclk_table.count; i++) { + if (dpm_table->mclk_table.dpm_levels[i].enabled && + dpm_table->mclk_table.dpm_levels[i].value >= min_mclk) + *mclk_mask |= 1 << i; + } +} + +static int smu7_set_power_profile_state(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int tmp_result, result = 0; + uint32_t sclk_mask = 0, mclk_mask = 0; + + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_AUTO) + return -EINVAL; + + tmp_result = smu7_freeze_sclk_mclk_dpm(hwmgr); + PP_ASSERT_WITH_CODE(!tmp_result, + "Failed to freeze SCLK MCLK DPM!", + result = tmp_result); + + tmp_result = smum_populate_requested_graphic_levels(hwmgr, request); + PP_ASSERT_WITH_CODE(!tmp_result, + "Failed to populate requested graphic levels!", + result = tmp_result); + + tmp_result = smu7_unfreeze_sclk_mclk_dpm(hwmgr); + PP_ASSERT_WITH_CODE(!tmp_result, + "Failed to unfreeze SCLK MCLK DPM!", + result = tmp_result); + + smu7_find_min_clock_masks(hwmgr, &sclk_mask, &mclk_mask, + request->min_sclk, request->min_mclk); + + if (sclk_mask) { + if (!data->sclk_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_SCLKDPM_SetEnabledMask, + data->dpm_level_enable_mask. + sclk_dpm_enable_mask & + sclk_mask); + } + + if (mclk_mask) { + if (!data->mclk_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_MCLKDPM_SetEnabledMask, + data->dpm_level_enable_mask. + mclk_dpm_enable_mask & + mclk_mask); + } + + return result; +} + static const struct pp_hwmgr_func smu7_hwmgr_funcs = { .backend_init = &smu7_hwmgr_backend_init, .backend_fini = &smu7_hwmgr_backend_fini, @@ -4551,6 +4621,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { .dynamic_state_management_disable = smu7_disable_dpm_tasks, .request_firmware = smu7_request_firmware, .release_firmware = smu7_release_firmware, + .set_power_profile_state = smu7_set_power_profile_state, }; uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock, |