summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
diff options
context:
space:
mode:
authorEvan Quan <evan.quan@amd.com>2019-07-30 22:52:37 -0500
committerAlex Deucher <alexander.deucher@amd.com>2019-07-30 23:48:35 -0500
commitb4af964e75c4163fe3baf98193495f7921a4b3b7 (patch)
tree33309a9111c245cd1184d4faa69b073ca7510b22 /drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
parent1f23cadbe0775559b3152a4f1fcb566d8cf6f571 (diff)
drm/amd/powerplay: make power limit retrieval as asic specific
The power limit retrieval should be done per asic. Since we may need to lookup in the pptable and that's really asic specific. Signed-off-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Kenneth Feng <kenneth.feng@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/arcturus_ppt.c')
-rw-r--r--drivers/gpu/drm/amd/powerplay/arcturus_ppt.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
index c67a9914ce7b..9360f5a25b69 100644
--- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
@@ -1323,6 +1323,56 @@ arcturus_get_profiling_clk_mask(struct smu_context *smu,
return 0;
}
+static int arcturus_get_power_limit(struct smu_context *smu,
+ uint32_t *limit,
+ bool asic_default)
+{
+ PPTable_t *pptable = smu->smu_table.driver_pptable;
+ uint32_t asic_default_power_limit;
+ int ret = 0;
+ int power_src;
+
+ if (!smu->default_power_limit ||
+ !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);
+ if (ret) {
+ pr_err("[%s] get PPT limit failed!", __func__);
+ return ret;
+ }
+ smu_read_smc_arg(smu, &asic_default_power_limit);
+ } else {
+ /* the last hope to figure out the ppt limit */
+ if (!pptable) {
+ pr_err("Cannot get PPT limit due to pptable missing!");
+ return -EINVAL;
+ }
+ asic_default_power_limit =
+ pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
+ }
+
+ if (smu->od_enabled) {
+ asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit);
+ asic_default_power_limit /= 100;
+ }
+
+ smu->default_power_limit = asic_default_power_limit;
+ smu->power_limit = asic_default_power_limit;
+ }
+
+ if (asic_default)
+ *limit = smu->default_power_limit;
+ else
+ *limit = smu->power_limit;
+
+ return 0;
+}
+
static void arcturus_dump_pptable(struct smu_context *smu)
{
struct smu_table_context *table_context = &smu->smu_table;
@@ -1788,6 +1838,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
.get_profiling_clk_mask = arcturus_get_profiling_clk_mask,
/* debug (internal used) */
.dump_pptable = arcturus_dump_pptable,
+ .get_power_limit = arcturus_get_power_limit,
};
void arcturus_set_ppt_funcs(struct smu_context *smu)