If a custom workload profile was provided, save the custom state
and reapply if the custom profile is enabled when applying the
workload profile.

Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
Cc: Kenneth Feng <kenneth.f...@amd.com>
Cc: Lijo Lazar <lijo.la...@amd.com>
---
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |   3 +
 .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 128 +++++++++-------
 .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c   | 141 ++++++++++-------
 .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c   | 144 ++++++++++--------
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 126 ++++++++-------
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  | 114 ++++++++------
 .../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c  | 132 +++++++++-------
 drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c        |  12 ++
 drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h        |   3 +
 9 files changed, 484 insertions(+), 319 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index da7558a65c09..ae57394beb84 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -562,6 +562,9 @@ struct smu_context {
        uint32_t power_profile_mode;
        uint32_t workload_refcount[PP_SMC_POWER_PROFILE_COUNT];
        struct mutex workload_lock;
+       /* backend specific custom workload settings */
+       long custom_profile_input[10];
+       bool custom_profile_size;
        bool pm_enabled;
        bool is_apu;
 
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
index 1e44cf6fec4b..72dca191263f 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
@@ -1441,72 +1441,87 @@ static int arcturus_get_power_profile_mode(struct 
smu_context *smu,
        return size;
 }
 
+static int arcturus_set_power_profile_mode_coeff(struct smu_context *smu,
+                                                long *input,
+                                                uint32_t size)
+{
+       DpmActivityMonitorCoeffInt_t activity_monitor;
+       int ret;
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
+                                  WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor),
+                                  false);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", 
__func__);
+               return ret;
+       }
+
+       switch (input[0]) {
+       case 0: /* Gfxclk */
+               activity_monitor.Gfx_FPS = input[1];
+               activity_monitor.Gfx_UseRlcBusy = 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: /* Uclk */
+               activity_monitor.Mem_FPS = input[1];
+               activity_monitor.Mem_UseRlcBusy = 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;
+       default:
+               return -EINVAL;
+       }
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
+                                  WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor),
+                                  true);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", 
__func__);
+               return ret;
+       }
+
+       return ret;
+}
+
 static int arcturus_set_power_profile_mode(struct smu_context *smu,
                                           long *input,
                                           uint32_t size,
                                           bool enable)
 {
-       DpmActivityMonitorCoeffInt_t activity_monitor;
        int workload_type = 0;
        uint32_t profile_mode = input[size];
-       int ret = 0;
+       int i, ret;
 
        if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
                dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
                return -EINVAL;
        }
 
-       if (enable &&
-           (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
+       if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
            (smu->smc_fw_version >= 0x360d00)) {
-               if (size != 10)
-                       return -EINVAL;
-
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-                                      WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor),
-                                      false);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-                       return ret;
-               }
-
-               switch (input[0]) {
-               case 0: /* Gfxclk */
-                       activity_monitor.Gfx_FPS = input[1];
-                       activity_monitor.Gfx_UseRlcBusy = 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: /* Uclk */
-                       activity_monitor.Mem_FPS = input[1];
-                       activity_monitor.Mem_UseRlcBusy = 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;
-               default:
-                       return -EINVAL;
-               }
-
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-                                      WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor),
-                                      true);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-                       return ret;
+               if (enable) {
+                       if (size != 10)
+                               return -EINVAL;
+                       for (i = 0; i < size; i++)
+                               smu->custom_profile_input[i] = input[i];
+                       smu->custom_profile_size = size;
+               } else {
+                       smu->custom_profile_size = 0;
                }
        }
 
@@ -1526,6 +1541,15 @@ static int arcturus_set_power_profile_mode(struct 
smu_context *smu,
                smu->workload_mask |= (1 << workload_type);
        else
                smu->workload_mask &= ~(1 << workload_type);
+
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_CUSTOM)) {
+               ret = arcturus_set_power_profile_mode_coeff(smu,
+                                                           
smu->custom_profile_input,
+                                                           
smu->custom_profile_size);
+               if (ret)
+                       return ret;
+       }
+
        ret = smu_cmn_send_smc_msg_with_param(smu,
                                          SMU_MSG_SetWorkloadMask,
                                          smu->workload_mask,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
index d944a9f954d0..339e64b1e95b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
@@ -2006,74 +2006,90 @@ static int navi10_get_power_profile_mode(struct 
smu_context *smu, char *buf)
        return size;
 }
 
+static int navi10_set_power_profile_mode_coeff(struct smu_context *smu,
+                                              long *input,
+                                              uint32_t size)
+{
+       DpmActivityMonitorCoeffInt_t activity_monitor;
+       int ret;
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor), false);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%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: /* Memclk */
+               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;
+       default:
+               return -EINVAL;
+       }
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor), true);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", 
__func__);
+               return ret;
+       }
+
+       return ret;
+}
+
 static int navi10_set_power_profile_mode(struct smu_context *smu, long *input,
                                         uint32_t size, bool enable)
 {
-       DpmActivityMonitorCoeffInt_t activity_monitor;
-       int workload_type, ret = 0;
        uint32_t profile_mode = input[size];
+       int workload_type, i, ret = 0;
 
        if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
                dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
                return -EINVAL;
        }
 
-       if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
-               if (size != 10)
-                       return -EINVAL;
-
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor), false);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%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: /* Memclk */
-                       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;
-               default:
-                       return -EINVAL;
-               }
-
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor), true);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-                       return ret;
+       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+               if (enable) {
+                       if (size != 10)
+                               return -EINVAL;
+                       for (i = 0; i < size; i++)
+                               smu->custom_profile_input[i] = input[i];
+                       smu->custom_profile_size = size;
+               } else {
+                       smu->custom_profile_size = 0;
                }
        }
 
@@ -2088,6 +2104,15 @@ static int navi10_set_power_profile_mode(struct 
smu_context *smu, long *input,
                smu->workload_mask |= (1 << workload_type);
        else
                smu->workload_mask &= ~(1 << workload_type);
+
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_CUSTOM)) {
+               ret = navi10_set_power_profile_mode_coeff(smu,
+                                                         
smu->custom_profile_input,
+                                                         
smu->custom_profile_size);
+               if (ret)
+                       return ret;
+       }
+
        ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
                                    smu->workload_mask, NULL);
        if (ret)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
index 4967e087088b..8580fef73222 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
@@ -1704,78 +1704,93 @@ static int sienna_cichlid_get_power_profile_mode(struct 
smu_context *smu, char *
        return size;
 }
 
-static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu,
-                                                long *input, uint32_t size,
-                                                bool enable)
+static int sienna_cichlid_set_power_profile_mode_coeff(struct smu_context *smu,
+                                                      long *input, uint32_t 
size)
 {
 
        DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
        DpmActivityMonitorCoeffInt_t *activity_monitor =
                &(activity_monitor_external.DpmActivityMonitorCoeffInt);
-       uint32_t profile_mode = input[size];
-       int workload_type, ret = 0;
+       int ret;
 
-       if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
-               dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external), false);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%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->Fclk_FPS = input[1];
+               activity_monitor->Fclk_MinFreqStep = input[2];
+               activity_monitor->Fclk_MinActiveFreqType = input[3];
+               activity_monitor->Fclk_MinActiveFreq = input[4];
+               activity_monitor->Fclk_BoosterFreqType = input[5];
+               activity_monitor->Fclk_BoosterFreq = input[6];
+               activity_monitor->Fclk_PD_Data_limit_c = input[7];
+               activity_monitor->Fclk_PD_Data_error_coeff = input[8];
+               activity_monitor->Fclk_PD_Data_error_rate_coeff = input[9];
+               break;
+       case 2: /* Memclk */
+               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;
+       default:
                return -EINVAL;
        }
 
-       if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
-               if (size != 10)
-                       return -EINVAL;
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external), true);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", 
__func__);
+               return ret;
+       }
 
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor_external), 
false);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-                       return ret;
-               }
+       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->Fclk_FPS = input[1];
-                       activity_monitor->Fclk_MinFreqStep = input[2];
-                       activity_monitor->Fclk_MinActiveFreqType = input[3];
-                       activity_monitor->Fclk_MinActiveFreq = input[4];
-                       activity_monitor->Fclk_BoosterFreqType = input[5];
-                       activity_monitor->Fclk_BoosterFreq = input[6];
-                       activity_monitor->Fclk_PD_Data_limit_c = input[7];
-                       activity_monitor->Fclk_PD_Data_error_coeff = input[8];
-                       activity_monitor->Fclk_PD_Data_error_rate_coeff = 
input[9];
-                       break;
-               case 2: /* Memclk */
-                       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;
-               default:
-                       return -EINVAL;
-               }
+static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu,
+                                                long *input, uint32_t size,
+                                                bool enable)
+{
+       uint32_t profile_mode = input[size];
+       int workload_type, i, ret = 0;
 
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor_external), 
true);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-                       return ret;
+       if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
+               dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
+               return -EINVAL;
+       }
+
+       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+               if (enable) {
+                       if (size != 10)
+                               return -EINVAL;
+                       for (i = 0; i < size; i++)
+                               smu->custom_profile_input[i] = input[i];
+                       smu->custom_profile_size = size;
+               } else {
+                       smu->custom_profile_size = 0;
                }
        }
 
@@ -1790,6 +1805,15 @@ static int sienna_cichlid_set_power_profile_mode(struct 
smu_context *smu,
                smu->workload_mask |= (1 << workload_type);
        else
                smu->workload_mask &= ~(1 << workload_type);
+
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_CUSTOM)) {
+               ret = sienna_cichlid_set_power_profile_mode_coeff(smu,
+                                                                 
smu->custom_profile_input,
+                                                                 
smu->custom_profile_size);
+               if (ret)
+                       return ret;
+       }
+
        ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
                                    smu->workload_mask, NULL);
        if (ret)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 3cc734331891..e928719bf6b7 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2571,16 +2571,70 @@ static int smu_v13_0_0_get_power_profile_mode(struct 
smu_context *smu,
        return size;
 }
 
+static int smu_v13_0_0_set_power_profile_mode_coeff(struct smu_context *smu,
+                                                   long *input,
+                                                   uint32_t size)
+{
+       DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
+       DpmActivityMonitorCoeffInt_t *activity_monitor =
+               &(activity_monitor_external.DpmActivityMonitorCoeffInt);
+       int ret;
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
+                                  WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external),
+                                  false);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", 
__func__);
+               return ret;
+       }
+
+       switch (input[0]) {
+       case 0: /* Gfxclk */
+               activity_monitor->Gfx_FPS = input[1];
+               activity_monitor->Gfx_MinActiveFreqType = input[2];
+               activity_monitor->Gfx_MinActiveFreq = input[3];
+               activity_monitor->Gfx_BoosterFreqType = input[4];
+               activity_monitor->Gfx_BoosterFreq = input[5];
+               activity_monitor->Gfx_PD_Data_limit_c = input[6];
+               activity_monitor->Gfx_PD_Data_error_coeff = input[7];
+               activity_monitor->Gfx_PD_Data_error_rate_coeff = input[8];
+               break;
+       case 1: /* Fclk */
+               activity_monitor->Fclk_FPS = input[1];
+               activity_monitor->Fclk_MinActiveFreqType = input[2];
+               activity_monitor->Fclk_MinActiveFreq = input[3];
+               activity_monitor->Fclk_BoosterFreqType = input[4];
+               activity_monitor->Fclk_BoosterFreq = input[5];
+               activity_monitor->Fclk_PD_Data_limit_c = input[6];
+               activity_monitor->Fclk_PD_Data_error_coeff = input[7];
+               activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8];
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
+                                  WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external),
+                                  true);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", 
__func__);
+               return ret;
+       }
+
+       return ret;
+}
+
 static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
                                              long *input,
                                              uint32_t size,
                                              bool enable)
 {
-       DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
-       DpmActivityMonitorCoeffInt_t *activity_monitor =
-               &(activity_monitor_external.DpmActivityMonitorCoeffInt);
        uint32_t profile_mode = input[size];
-       int workload_type, ret = 0;
+       int workload_type, i, ret = 0;
        u32 workload_mask;
 
        if (profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {
@@ -2588,53 +2642,15 @@ static int smu_v13_0_0_set_power_profile_mode(struct 
smu_context *smu,
                return -EINVAL;
        }
 
-       if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
-               if (size != 9)
-                       return -EINVAL;
-
-               ret = smu_cmn_update_table(smu,
-                                          SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-                                          WORKLOAD_PPLIB_CUSTOM_BIT,
-                                          (void *)(&activity_monitor_external),
-                                          false);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-                       return ret;
-               }
-
-               switch (input[0]) {
-               case 0: /* Gfxclk */
-                       activity_monitor->Gfx_FPS = input[1];
-                       activity_monitor->Gfx_MinActiveFreqType = input[2];
-                       activity_monitor->Gfx_MinActiveFreq = input[3];
-                       activity_monitor->Gfx_BoosterFreqType = input[4];
-                       activity_monitor->Gfx_BoosterFreq = input[5];
-                       activity_monitor->Gfx_PD_Data_limit_c = input[6];
-                       activity_monitor->Gfx_PD_Data_error_coeff = input[7];
-                       activity_monitor->Gfx_PD_Data_error_rate_coeff = 
input[8];
-                       break;
-               case 1: /* Fclk */
-                       activity_monitor->Fclk_FPS = input[1];
-                       activity_monitor->Fclk_MinActiveFreqType = input[2];
-                       activity_monitor->Fclk_MinActiveFreq = input[3];
-                       activity_monitor->Fclk_BoosterFreqType = input[4];
-                       activity_monitor->Fclk_BoosterFreq = input[5];
-                       activity_monitor->Fclk_PD_Data_limit_c = input[6];
-                       activity_monitor->Fclk_PD_Data_error_coeff = input[7];
-                       activity_monitor->Fclk_PD_Data_error_rate_coeff = 
input[8];
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               ret = smu_cmn_update_table(smu,
-                                          SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-                                          WORKLOAD_PPLIB_CUSTOM_BIT,
-                                          (void *)(&activity_monitor_external),
-                                          true);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-                       return ret;
+       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+               if (enable) {
+                       if (size != 9)
+                               return -EINVAL;
+                       for (i = 0; i < size; i++)
+                               smu->custom_profile_input[i] = input[i];
+                       smu->custom_profile_size = size;
+               } else {
+                       smu->custom_profile_size = 0;
                }
        }
 
@@ -2666,6 +2682,14 @@ static int smu_v13_0_0_set_power_profile_mode(struct 
smu_context *smu,
                        smu->workload_mask |= 1 << workload_type;
        }
 
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_CUSTOM)) {
+               ret = smu_v13_0_0_set_power_profile_mode_coeff(smu,
+                                                              
smu->custom_profile_input,
+                                                              
smu->custom_profile_size);
+               if (ret)
+                       return ret;
+       }
+
        ret = smu_cmn_send_smc_msg_with_param(smu,
                                               SMU_MSG_SetWorkloadMask,
                                               smu->workload_mask,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 1aafd23857f0..e14d8d46ca2a 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -2528,63 +2528,78 @@ do {                                                    
                                                \
        return result;
 }
 
-static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu,
-                                             long *input, uint32_t size,
-                                             bool enable)
+static int smu_v13_0_7_set_power_profile_mode_coeff(struct smu_context *smu,
+                                                   long *input, uint32_t size)
 {
 
        DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
        DpmActivityMonitorCoeffInt_t *activity_monitor =
                &(activity_monitor_external.DpmActivityMonitorCoeffInt);
-       uint32_t profile_mode = input[size];
-       int workload_type, ret = 0;
+       int ret;
 
-       if (profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) {
-               dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external), false);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", 
__func__);
+               return ret;
+       }
+
+       switch (input[0]) {
+       case 0: /* Gfxclk */
+               activity_monitor->Gfx_ActiveHystLimit = input[1];
+               activity_monitor->Gfx_IdleHystLimit = input[2];
+               activity_monitor->Gfx_FPS = input[3];
+               activity_monitor->Gfx_MinActiveFreqType = input[4];
+               activity_monitor->Gfx_BoosterFreqType = input[5];
+               activity_monitor->Gfx_MinActiveFreq = input[6];
+               activity_monitor->Gfx_BoosterFreq = input[7];
+               break;
+       case 1: /* Fclk */
+               activity_monitor->Fclk_ActiveHystLimit = input[1];
+               activity_monitor->Fclk_IdleHystLimit = input[2];
+               activity_monitor->Fclk_FPS = input[3];
+               activity_monitor->Fclk_MinActiveFreqType = input[4];
+               activity_monitor->Fclk_BoosterFreqType = input[5];
+               activity_monitor->Fclk_MinActiveFreq = input[6];
+               activity_monitor->Fclk_BoosterFreq = input[7];
+               break;
+       default:
                return -EINVAL;
        }
 
-       if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
-               if (size != 8)
-                       return -EINVAL;
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external), true);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", 
__func__);
+               return ret;
+       }
 
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor_external), 
false);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-                       return ret;
-               }
+       return ret;
+}
 
-               switch (input[0]) {
-               case 0: /* Gfxclk */
-                       activity_monitor->Gfx_ActiveHystLimit = input[1];
-                       activity_monitor->Gfx_IdleHystLimit = input[2];
-                       activity_monitor->Gfx_FPS = input[3];
-                       activity_monitor->Gfx_MinActiveFreqType = input[4];
-                       activity_monitor->Gfx_BoosterFreqType = input[5];
-                       activity_monitor->Gfx_MinActiveFreq = input[6];
-                       activity_monitor->Gfx_BoosterFreq = input[7];
-                       break;
-               case 1: /* Fclk */
-                       activity_monitor->Fclk_ActiveHystLimit = input[1];
-                       activity_monitor->Fclk_IdleHystLimit = input[2];
-                       activity_monitor->Fclk_FPS = input[3];
-                       activity_monitor->Fclk_MinActiveFreqType = input[4];
-                       activity_monitor->Fclk_BoosterFreqType = input[5];
-                       activity_monitor->Fclk_MinActiveFreq = input[6];
-                       activity_monitor->Fclk_BoosterFreq = input[7];
-                       break;
-               default:
-                       return -EINVAL;
-               }
+static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu,
+                                             long *input, uint32_t size,
+                                             bool enable)
+{
+       uint32_t profile_mode = input[size];
+       int workload_type, i, ret = 0;
 
-               ret = smu_cmn_update_table(smu,
-                                      SMU_TABLE_ACTIVITY_MONITOR_COEFF, 
WORKLOAD_PPLIB_CUSTOM_BIT,
-                                      (void *)(&activity_monitor_external), 
true);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-                       return ret;
+       if (profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) {
+               dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
+               return -EINVAL;
+       }
+
+       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+               if (enable) {
+                       if (size != 8)
+                               return -EINVAL;
+                       for (i = 0; i < size; i++)
+                               smu->custom_profile_input[i] = input[i];
+                       smu->custom_profile_size = size;
+               } else {
+                       smu->custom_profile_size = 0;
                }
        }
 
@@ -2599,6 +2614,15 @@ static int smu_v13_0_7_set_power_profile_mode(struct 
smu_context *smu,
                smu->workload_mask |= (1 << workload_type);
        else
                smu->workload_mask &= ~(1 << workload_type);
+
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_CUSTOM)) {
+               ret = smu_v13_0_7_set_power_profile_mode_coeff(smu,
+                                                              
smu->custom_profile_input,
+                                                              
smu->custom_profile_size);
+               if (ret)
+                       return ret;
+       }
+
        ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
                                    smu->workload_mask, NULL);
 
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index b64490bcfd62..ba586bbaade9 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -1717,69 +1717,85 @@ static int smu_v14_0_2_get_power_profile_mode(struct 
smu_context *smu,
        return size;
 }
 
+static int smu_v14_0_2_set_power_profile_mode_coeff(struct smu_context *smu,
+                                                   long *input,
+                                                   uint32_t size)
+{
+       DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
+       DpmActivityMonitorCoeffInt_t *activity_monitor =
+               &(activity_monitor_external.DpmActivityMonitorCoeffInt);
+       int ret;
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
+                                  WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external),
+                                  false);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", 
__func__);
+               return ret;
+       }
+
+       switch (input[0]) {
+       case 0: /* Gfxclk */
+               activity_monitor->Gfx_FPS = input[1];
+               activity_monitor->Gfx_MinActiveFreqType = input[2];
+               activity_monitor->Gfx_MinActiveFreq = input[3];
+               activity_monitor->Gfx_BoosterFreqType = input[4];
+               activity_monitor->Gfx_BoosterFreq = input[5];
+               activity_monitor->Gfx_PD_Data_limit_c = input[6];
+               activity_monitor->Gfx_PD_Data_error_coeff = input[7];
+               activity_monitor->Gfx_PD_Data_error_rate_coeff = input[8];
+               break;
+       case 1: /* Fclk */
+               activity_monitor->Fclk_FPS = input[1];
+               activity_monitor->Fclk_MinActiveFreqType = input[2];
+               activity_monitor->Fclk_MinActiveFreq = input[3];
+               activity_monitor->Fclk_BoosterFreqType = input[4];
+               activity_monitor->Fclk_BoosterFreq = input[5];
+               activity_monitor->Fclk_PD_Data_limit_c = input[6];
+               activity_monitor->Fclk_PD_Data_error_coeff = input[7];
+               activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8];
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = smu_cmn_update_table(smu,
+                                  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
+                                  WORKLOAD_PPLIB_CUSTOM_BIT,
+                                  (void *)(&activity_monitor_external),
+                                  true);
+       if (ret) {
+               dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", 
__func__);
+               return ret;
+       }
+
+       return ret;
+}
+
 static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,
                                              long *input,
                                              uint32_t size,
                                              bool enable)
 {
-       DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
-       DpmActivityMonitorCoeffInt_t *activity_monitor =
-               &(activity_monitor_external.DpmActivityMonitorCoeffInt);
        uint32_t profile_mode = input[size];
-       int workload_type, ret = 0;
+       int workload_type, i, ret = 0;
 
        if (profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {
                dev_err(smu->adev->dev, "Invalid power profile mode %d\n", 
profile_mode);
                return -EINVAL;
        }
 
-       if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
-               if (size != 9)
-                       return -EINVAL;
-
-               ret = smu_cmn_update_table(smu,
-                                          SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-                                          WORKLOAD_PPLIB_CUSTOM_BIT,
-                                          (void *)(&activity_monitor_external),
-                                          false);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-                       return ret;
-               }
-
-               switch (input[0]) {
-               case 0: /* Gfxclk */
-                       activity_monitor->Gfx_FPS = input[1];
-                       activity_monitor->Gfx_MinActiveFreqType = input[2];
-                       activity_monitor->Gfx_MinActiveFreq = input[3];
-                       activity_monitor->Gfx_BoosterFreqType = input[4];
-                       activity_monitor->Gfx_BoosterFreq = input[5];
-                       activity_monitor->Gfx_PD_Data_limit_c = input[6];
-                       activity_monitor->Gfx_PD_Data_error_coeff = input[7];
-                       activity_monitor->Gfx_PD_Data_error_rate_coeff = 
input[8];
-                       break;
-               case 1: /* Fclk */
-                       activity_monitor->Fclk_FPS = input[1];
-                       activity_monitor->Fclk_MinActiveFreqType = input[2];
-                       activity_monitor->Fclk_MinActiveFreq = input[3];
-                       activity_monitor->Fclk_BoosterFreqType = input[4];
-                       activity_monitor->Fclk_BoosterFreq = input[5];
-                       activity_monitor->Fclk_PD_Data_limit_c = input[6];
-                       activity_monitor->Fclk_PD_Data_error_coeff = input[7];
-                       activity_monitor->Fclk_PD_Data_error_rate_coeff = 
input[8];
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               ret = smu_cmn_update_table(smu,
-                                          SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-                                          WORKLOAD_PPLIB_CUSTOM_BIT,
-                                          (void *)(&activity_monitor_external),
-                                          true);
-               if (ret) {
-                       dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-                       return ret;
+       if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+               if (enable) {
+                       if (size != 9)
+                               return -EINVAL;
+                       for (i = 0; i < size; i++)
+                               smu->custom_profile_input[i] = input[i];
+                       smu->custom_profile_size = size;
+               } else {
+                       smu->custom_profile_size = 0;
                }
        }
 
@@ -1796,8 +1812,18 @@ static int smu_v14_0_2_set_power_profile_mode(struct 
smu_context *smu,
                smu->workload_mask &= ~(1 << workload_type);
 
        /* disable deep sleep if compute is enabled */
-       if (profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)
-               smu_v14_0_deep_sleep_control(smu, !enable);
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_COMPUTE))
+               smu_v14_0_deep_sleep_control(smu, false);
+       else
+               smu_v14_0_deep_sleep_control(smu, true);
+
+       if (smu_cmn_is_workload_profile_enabled(smu, 
PP_SMC_POWER_PROFILE_CUSTOM)) {
+               ret = smu_v14_0_2_set_power_profile_mode_coeff(smu,
+                                                              
smu->custom_profile_input,
+                                                              
smu->custom_profile_size);
+               if (ret)
+                       return ret;
+       }
 
        ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
                                              smu->workload_mask, NULL);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index 63c4f75fa118..5d70cebdc48a 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -1218,3 +1218,15 @@ void smu_cmn_generic_plpd_policy_desc(struct 
smu_dpm_policy *policy)
 {
        policy->desc = &xgmi_plpd_policy_desc;
 }
+
+bool smu_cmn_is_workload_profile_enabled(struct smu_context *smu,
+                                        enum PP_SMC_POWER_PROFILE profile_mode)
+{
+       bool enabled;
+
+       mutex_lock(&smu->workload_lock);
+       enabled = smu->workload_refcount[profile_mode];
+       mutex_unlock(&smu->workload_lock);
+
+       return enabled;
+}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h 
b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
index 1de685defe85..11ad33a0b5a3 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
@@ -147,5 +147,8 @@ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device 
*adev);
 void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy);
 void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy);
 
+bool smu_cmn_is_workload_profile_enabled(struct smu_context *smu,
+                                        enum PP_SMC_POWER_PROFILE 
profile_mode);
+
 #endif
 #endif
-- 
2.47.0

Reply via email to