diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2362-drm-amd-powerplay-add-funciton-get-set-_power_profil.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2362-drm-amd-powerplay-add-funciton-get-set-_power_profil.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2362-drm-amd-powerplay-add-funciton-get-set-_power_profil.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2362-drm-amd-powerplay-add-funciton-get-set-_power_profil.patch new file mode 100644 index 00000000..bf628214 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2362-drm-amd-powerplay-add-funciton-get-set-_power_profil.patch @@ -0,0 +1,211 @@ +From 6898c5a88ca4f5c51235f9ea716288b64a47113c Mon Sep 17 00:00:00 2001 +From: Kevin Wang <kevin1.wang@amd.com> +Date: Thu, 25 Apr 2019 15:41:13 +0800 +Subject: [PATCH 2362/2940] drm/amd/powerplay: add funciton + get[set]_power_profile_mode for navi10 (v2) + +add callback function get[set]_power_profile_mode for navi10 asic + +v2: fix smu_update_table for rebase (Alex) + +Signed-off-by: Kevin Wang <kevin1.wang@amd.com> +Reviewed-by: Huang Rui <ray.huang@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 173 +++++++++++++++++++++ + 1 file changed, 173 insertions(+) + +diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +index 979ed6b1c8df..55d67cd922f3 100644 +--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +@@ -859,6 +859,177 @@ static int navi10_get_fan_speed_percent(struct smu_context *smu, + return ret; + } + ++static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) ++{ ++ DpmActivityMonitorCoeffInt_t activity_monitor; ++ uint32_t i, size = 0; ++ uint16_t workload_type = 0; ++ static const char *profile_name[] = { ++ "BOOTUP_DEFAULT", ++ "3D_FULL_SCREEN", ++ "POWER_SAVING", ++ "VIDEO", ++ "VR", ++ "COMPUTE", ++ "CUSTOM"}; ++ static const char *title[] = { ++ "PROFILE_INDEX(NAME)", ++ "CLOCK_TYPE(NAME)", ++ "FPS", ++ "MinFreqType", ++ "MinActiveFreqType", ++ "MinActiveFreq", ++ "BoosterFreqType", ++ "BoosterFreq", ++ "PD_Data_limit_c", ++ "PD_Data_error_coeff", ++ "PD_Data_error_rate_coeff"}; ++ int result = 0; ++ ++ if (!buf) ++ return -EINVAL; ++ ++ size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n", ++ title[0], title[1], title[2], title[3], title[4], title[5], ++ title[6], title[7], title[8], title[9], title[10]); ++ ++ for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { ++ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ ++ workload_type = smu_workload_get_type(smu, i); ++ result = smu_update_table(smu, ++ SMU_TABLE_ACTIVITY_MONITOR_COEFF | workload_type << 16, ++ (void *)(&activity_monitor), false); ++ if (result) { ++ pr_err("[%s] Failed to get activity monitor!", __func__); ++ return result; ++ } ++ ++ size += sprintf(buf + size, "%2d %14s%s:\n", ++ i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); ++ ++ size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", ++ " ", ++ 0, ++ "GFXCLK", ++ activity_monitor.Gfx_FPS, ++ activity_monitor.Gfx_MinFreqStep, ++ activity_monitor.Gfx_MinActiveFreqType, ++ activity_monitor.Gfx_MinActiveFreq, ++ activity_monitor.Gfx_BoosterFreqType, ++ activity_monitor.Gfx_BoosterFreq, ++ activity_monitor.Gfx_PD_Data_limit_c, ++ activity_monitor.Gfx_PD_Data_error_coeff, ++ activity_monitor.Gfx_PD_Data_error_rate_coeff); ++ ++ size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", ++ " ", ++ 1, ++ "SOCCLK", ++ activity_monitor.Soc_FPS, ++ activity_monitor.Soc_MinFreqStep, ++ activity_monitor.Soc_MinActiveFreqType, ++ activity_monitor.Soc_MinActiveFreq, ++ activity_monitor.Soc_BoosterFreqType, ++ activity_monitor.Soc_BoosterFreq, ++ activity_monitor.Soc_PD_Data_limit_c, ++ activity_monitor.Soc_PD_Data_error_coeff, ++ activity_monitor.Soc_PD_Data_error_rate_coeff); ++ ++ size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", ++ " ", ++ 2, ++ "MEMLK", ++ activity_monitor.Mem_FPS, ++ activity_monitor.Mem_MinFreqStep, ++ activity_monitor.Mem_MinActiveFreqType, ++ activity_monitor.Mem_MinActiveFreq, ++ activity_monitor.Mem_BoosterFreqType, ++ activity_monitor.Mem_BoosterFreq, ++ activity_monitor.Mem_PD_Data_limit_c, ++ activity_monitor.Mem_PD_Data_error_coeff, ++ activity_monitor.Mem_PD_Data_error_rate_coeff); ++ } ++ ++ return size; ++} ++ ++static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) ++{ ++ DpmActivityMonitorCoeffInt_t activity_monitor; ++ int workload_type, ret = 0; ++ ++ smu->power_profile_mode = input[size]; ++ ++ if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { ++ pr_err("Invalid power profile mode %d\n", smu->power_profile_mode); ++ return -EINVAL; ++ } ++ ++ if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { ++ if (size < 0) ++ return -EINVAL; ++ ++ ret = smu_update_table(smu, ++ SMU_TABLE_ACTIVITY_MONITOR_COEFF | WORKLOAD_PPLIB_CUSTOM_BIT << 16, ++ (void *)(&activity_monitor), false); ++ if (ret) { ++ pr_err("[%s] Failed to get activity monitor!", __func__); ++ return ret; ++ } ++ ++ switch (input[0]) { ++ case 0: /* Gfxclk */ ++ activity_monitor.Gfx_FPS = input[1]; ++ activity_monitor.Gfx_MinFreqStep = input[2]; ++ activity_monitor.Gfx_MinActiveFreqType = input[3]; ++ activity_monitor.Gfx_MinActiveFreq = input[4]; ++ activity_monitor.Gfx_BoosterFreqType = input[5]; ++ activity_monitor.Gfx_BoosterFreq = input[6]; ++ activity_monitor.Gfx_PD_Data_limit_c = input[7]; ++ activity_monitor.Gfx_PD_Data_error_coeff = input[8]; ++ activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9]; ++ break; ++ case 1: /* Socclk */ ++ activity_monitor.Soc_FPS = input[1]; ++ activity_monitor.Soc_MinFreqStep = input[2]; ++ activity_monitor.Soc_MinActiveFreqType = input[3]; ++ activity_monitor.Soc_MinActiveFreq = input[4]; ++ activity_monitor.Soc_BoosterFreqType = input[5]; ++ activity_monitor.Soc_BoosterFreq = input[6]; ++ activity_monitor.Soc_PD_Data_limit_c = input[7]; ++ activity_monitor.Soc_PD_Data_error_coeff = input[8]; ++ activity_monitor.Soc_PD_Data_error_rate_coeff = input[9]; ++ break; ++ case 2: /* Memlk */ ++ activity_monitor.Mem_FPS = input[1]; ++ activity_monitor.Mem_MinFreqStep = input[2]; ++ activity_monitor.Mem_MinActiveFreqType = input[3]; ++ activity_monitor.Mem_MinActiveFreq = input[4]; ++ activity_monitor.Mem_BoosterFreqType = input[5]; ++ activity_monitor.Mem_BoosterFreq = input[6]; ++ activity_monitor.Mem_PD_Data_limit_c = input[7]; ++ activity_monitor.Mem_PD_Data_error_coeff = input[8]; ++ activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; ++ break; ++ } ++ ++ ret = smu_update_table(smu, ++ SMU_TABLE_ACTIVITY_MONITOR_COEFF | WORKLOAD_PPLIB_CUSTOM_BIT << 16, ++ (void *)(&activity_monitor), true); ++ if (ret) { ++ pr_err("[%s] Failed to set activity monitor!", __func__); ++ return ret; ++ } ++ } ++ ++ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ ++ workload_type = smu_workload_get_type(smu, smu->power_profile_mode); ++ smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, ++ 1 << workload_type); ++ ++ return ret; ++} ++ + static const struct pptable_funcs navi10_ppt_funcs = { + .tables_init = navi10_tables_init, + .alloc_dpm_context = navi10_allocate_dpm_context, +@@ -888,6 +1059,8 @@ static const struct pptable_funcs navi10_ppt_funcs = { + .is_dpm_running = navi10_is_dpm_running, + .set_thermal_fan_table = navi10_set_thermal_fan_table, + .get_fan_speed_percent = navi10_get_fan_speed_percent, ++ .get_power_profile_mode = navi10_get_power_profile_mode, ++ .set_power_profile_mode = navi10_set_power_profile_mode, + }; + + void navi10_set_ppt_funcs(struct smu_context *smu) +-- +2.17.1 + |