Also cache the current and max power limits.

Change-Id: Ida2ce964736bee2e558522441d3505f84c4e00f4
Signed-off-by: Evan Quan <evan.q...@amd.com>
---
 drivers/gpu/drm/amd/powerplay/arcturus_ppt.c  | 49 ++++++++---------
 .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h    |  2 +
 drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h |  3 ++
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c    | 53 ++++++++-----------
 .../drm/amd/powerplay/sienna_cichlid_ppt.c    | 51 ++++++++----------
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c     | 23 ++++++++
 6 files changed, 94 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c 
b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
index 0704a9c1d567..2c78271123f7 100644
--- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
@@ -1413,40 +1413,33 @@ static int arcturus_get_power_limit(struct smu_context 
*smu,
                                     uint32_t *limit,
                                     bool cap)
 {
+       struct smu_11_0_powerplay_table *powerplay_table =
+               (struct smu_11_0_powerplay_table 
*)smu->smu_table.power_play_table;
        PPTable_t *pptable = smu->smu_table.driver_pptable;
-       uint32_t asic_default_power_limit = 0;
-       int ret = 0;
-       int power_src;
-
-       if (!smu->power_limit) {
-               if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
-                       power_src = smu_power_get_index(smu, 
SMU_POWER_SOURCE_AC);
-                       if (power_src < 0)
-                               return -EINVAL;
+       uint32_t power_limit, od_percent;
 
-                       ret = smu_send_smc_msg_with_param(smu, 
SMU_MSG_GetPptLimit,
-                               power_src << 16, &asic_default_power_limit);
-                       if (ret) {
-                               dev_err(smu->adev->dev, "[%s] get PPT limit 
failed!", __func__);
-                               return ret;
-                       }
-               } else {
-                       /* the last hope to figure out the ppt limit */
-                       if (!pptable) {
-                               dev_err(smu->adev->dev, "Cannot get PPT limit 
due to pptable missing!");
-                               return -EINVAL;
-                       }
-                       asic_default_power_limit =
-                               pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+       if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
+               /* the last hope to figure out the ppt limit */
+               if (!pptable) {
+                       dev_err(smu->adev->dev, "Cannot get PPT limit due to 
pptable missing!");
+                       return -EINVAL;
                }
+               power_limit =
+                       pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+       }
+       smu->current_power_limit = power_limit;
+
+       if (smu->od_enabled) {
+               od_percent = 
le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+
+               dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d 
(default: %d)\n", od_percent, power_limit);
 
-               smu->power_limit = asic_default_power_limit;
+               power_limit *= (100 + od_percent);
+               power_limit /= 100;
        }
+       smu->max_power_limit = power_limit;
 
-       if (cap)
-               *limit = smu_get_max_power_limit(smu);
-       else
-               *limit = smu->power_limit;
+       *limit = (cap ? smu->max_power_limit : smu->current_power_limit);
 
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index 9276320c09d0..574a793b5d26 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -382,6 +382,8 @@ struct smu_context
        bool od_enabled;
        uint32_t power_limit;
        uint32_t default_power_limit;
+       uint32_t current_power_limit;
+       uint32_t max_power_limit;
 
        /* soft pptable */
        uint32_t ppt_offset_bytes;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h 
b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
index 9da2f26b7267..2e9939beb128 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
@@ -196,6 +196,9 @@ int smu_v11_0_get_enabled_mask(struct smu_context *smu,
 
 int smu_v11_0_notify_display_change(struct smu_context *smu);
 
+int smu_v11_0_get_current_power_limit(struct smu_context *smu,
+                                     uint32_t *power_limit);
+
 int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n);
 
 int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c 
b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index e63498e747ac..b867f94ba559 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -1923,43 +1923,36 @@ static uint32_t navi10_get_pptable_power_limit(struct 
smu_context *smu)
 }
 
 static int navi10_get_power_limit(struct smu_context *smu,
-                                    uint32_t *limit,
-                                    bool cap)
+                                 uint32_t *limit,
+                                 bool cap)
 {
+       struct smu_11_0_powerplay_table *powerplay_table =
+               (struct smu_11_0_powerplay_table 
*)smu->smu_table.power_play_table;
        PPTable_t *pptable = smu->smu_table.driver_pptable;
-       uint32_t asic_default_power_limit = 0;
-       int ret = 0;
-       int power_src;
-
-       if (!smu->power_limit) {
-               if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
-                       power_src = smu_power_get_index(smu, 
SMU_POWER_SOURCE_AC);
-                       if (power_src < 0)
-                               return -EINVAL;
+       uint32_t power_limit, od_percent;
 
-                       ret = smu_send_smc_msg_with_param(smu, 
SMU_MSG_GetPptLimit,
-                               power_src << 16, &asic_default_power_limit);
-                       if (ret) {
-                               dev_err(smu->adev->dev, "[%s] get PPT limit 
failed!", __func__);
-                               return ret;
-                       }
-               } else {
-                       /* the last hope to figure out the ppt limit */
-                       if (!pptable) {
-                               dev_err(smu->adev->dev, "Cannot get PPT limit 
due to pptable missing!");
-                               return -EINVAL;
-                       }
-                       asic_default_power_limit =
-                               pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+       if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
+               /* the last hope to figure out the ppt limit */
+               if (!pptable) {
+                       dev_err(smu->adev->dev, "Cannot get PPT limit due to 
pptable missing!");
+                       return -EINVAL;
                }
+               power_limit =
+                       pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+       }
+       smu->current_power_limit = power_limit;
 
-               smu->power_limit = asic_default_power_limit;
+       if (smu->od_enabled) {
+               od_percent = 
le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+
+               dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d 
(default: %d)\n", od_percent, power_limit);
+
+               power_limit *= (100 + od_percent);
+               power_limit /= 100;
        }
+       smu->max_power_limit = power_limit;
 
-       if (cap)
-               *limit = smu_get_max_power_limit(smu);
-       else
-               *limit = smu->power_limit;
+       *limit = (cap ? smu->max_power_limit : smu->current_power_limit);
 
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c 
b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c
index b83675227a6f..c427e233dfad 100644
--- a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c
@@ -1747,40 +1747,33 @@ static int sienna_cichlid_get_power_limit(struct 
smu_context *smu,
                                     uint32_t *limit,
                                     bool cap)
 {
+       struct smu_11_0_7_powerplay_table *powerplay_table =
+               (struct smu_11_0_7_powerplay_table 
*)smu->smu_table.power_play_table;
        PPTable_t *pptable = smu->smu_table.driver_pptable;
-       uint32_t asic_default_power_limit = 0;
-       int ret = 0;
-       int power_src;
-
-       if (!smu->power_limit) {
-               if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
-                       power_src = smu_power_get_index(smu, 
SMU_POWER_SOURCE_AC);
-                       if (power_src < 0)
-                               return -EINVAL;
-
-                       ret = smu_send_smc_msg_with_param(smu, 
SMU_MSG_GetPptLimit,
-                                                         power_src << 16, 
&asic_default_power_limit);
-                       if (ret) {
-                               dev_err(smu->adev->dev, "[%s] get PPT limit 
failed!", __func__);
-                               return ret;
-                       }
-               } else {
-                       /* the last hope to figure out the ppt limit */
-                       if (!pptable) {
-                               dev_err(smu->adev->dev, "Cannot get PPT limit 
due to pptable missing!");
-                               return -EINVAL;
-                       }
-                       asic_default_power_limit =
-                               pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+       uint32_t power_limit, od_percent;
+
+       if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
+               /* the last hope to figure out the ppt limit */
+               if (!pptable) {
+                       dev_err(smu->adev->dev, "Cannot get PPT limit due to 
pptable missing!");
+                       return -EINVAL;
                }
+               power_limit =
+                       pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+       }
+       smu->current_power_limit = power_limit;
+
+       if (smu->od_enabled) {
+               od_percent = 
le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+
+               dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d 
(default: %d)\n", od_percent, power_limit);
 
-               smu->power_limit = asic_default_power_limit;
+               power_limit *= (100 + od_percent);
+               power_limit /= 100;
        }
+       smu->max_power_limit = power_limit;
 
-       if (cap)
-               *limit = smu_get_max_power_limit(smu);
-       else
-               *limit = smu->power_limit;
+       *limit = (cap ? smu->max_power_limit : smu->current_power_limit);
 
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c 
b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index acb9a3cec7ee..358c903c4a86 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1056,6 +1056,29 @@ int smu_v11_0_init_max_sustainable_clocks(struct 
smu_context *smu)
        return 0;
 }
 
+int smu_v11_0_get_current_power_limit(struct smu_context *smu,
+                                     uint32_t *power_limit)
+{
+       int power_src;
+       int ret = 0;
+
+       if (!smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT))
+               return -EINVAL;
+
+       power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC);
+       if (power_src < 0)
+               return -EINVAL;
+
+       ret = smu_send_smc_msg_with_param(smu,
+                                         SMU_MSG_GetPptLimit,
+                                         power_src << 16,
+                                         power_limit);
+       if (ret)
+               dev_err(smu->adev->dev, "[%s] get PPT limit failed!", __func__);
+
+       return ret;
+}
+
 int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
 {
        int ret = 0;
-- 
2.27.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to