Commit 19589468 authored by Ma Jun's avatar Ma Jun Committed by Alex Deucher

drm/amd/pm: Support for getting power1_cap_min value

Support for getting power1_cap_min value on smu13 and smu11.
For other Asics, we still use 0 as the default value.
Signed-off-by: default avatarMa Jun <Jun.Ma2@amd.com>
Reviewed-by: default avatarKenneth Feng <kenneth.feng@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent afcf949c
...@@ -2921,14 +2921,6 @@ static ssize_t amdgpu_hwmon_show_power_input(struct device *dev, ...@@ -2921,14 +2921,6 @@ static ssize_t amdgpu_hwmon_show_power_input(struct device *dev,
return sysfs_emit(buf, "%zd\n", val); return sysfs_emit(buf, "%zd\n", val);
} }
static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sysfs_emit(buf, "%i\n", 0);
}
static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev, static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf, char *buf,
...@@ -2965,6 +2957,12 @@ static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev, ...@@ -2965,6 +2957,12 @@ static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev,
return size; return size;
} }
static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return amdgpu_hwmon_show_power_cap_generic(dev, attr, buf, PP_PWR_LIMIT_MIN);
}
static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
......
...@@ -849,7 +849,8 @@ static int smu_late_init(void *handle) ...@@ -849,7 +849,8 @@ static int smu_late_init(void *handle)
ret = smu_get_asic_power_limits(smu, ret = smu_get_asic_power_limits(smu,
&smu->current_power_limit, &smu->current_power_limit,
&smu->default_power_limit, &smu->default_power_limit,
&smu->max_power_limit); &smu->max_power_limit,
&smu->min_power_limit);
if (ret) { if (ret) {
dev_err(adev->dev, "Failed to get asic power limits!\n"); dev_err(adev->dev, "Failed to get asic power limits!\n");
return ret; return ret;
...@@ -2447,6 +2448,8 @@ int smu_get_power_limit(void *handle, ...@@ -2447,6 +2448,8 @@ int smu_get_power_limit(void *handle,
limit_level = SMU_PPT_LIMIT_MAX; limit_level = SMU_PPT_LIMIT_MAX;
break; break;
case PP_PWR_LIMIT_MIN: case PP_PWR_LIMIT_MIN:
limit_level = SMU_PPT_LIMIT_MIN;
break;
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
break; break;
...@@ -2466,8 +2469,7 @@ int smu_get_power_limit(void *handle, ...@@ -2466,8 +2469,7 @@ int smu_get_power_limit(void *handle,
case IP_VERSION(11, 0, 13): case IP_VERSION(11, 0, 13):
ret = smu_get_asic_power_limits(smu, ret = smu_get_asic_power_limits(smu,
&smu->current_power_limit, &smu->current_power_limit,
NULL, NULL, NULL, NULL);
NULL);
break; break;
default: default:
break; break;
...@@ -2480,6 +2482,9 @@ int smu_get_power_limit(void *handle, ...@@ -2480,6 +2482,9 @@ int smu_get_power_limit(void *handle,
case SMU_PPT_LIMIT_MAX: case SMU_PPT_LIMIT_MAX:
*limit = smu->max_power_limit; *limit = smu->max_power_limit;
break; break;
case SMU_PPT_LIMIT_MIN:
*limit = smu->min_power_limit;
break;
default: default:
break; break;
} }
...@@ -2502,10 +2507,10 @@ static int smu_set_power_limit(void *handle, uint32_t limit) ...@@ -2502,10 +2507,10 @@ static int smu_set_power_limit(void *handle, uint32_t limit)
if (smu->ppt_funcs->set_power_limit) if (smu->ppt_funcs->set_power_limit)
return smu->ppt_funcs->set_power_limit(smu, limit_type, limit); return smu->ppt_funcs->set_power_limit(smu, limit_type, limit);
if (limit > smu->max_power_limit) { if ((limit > smu->max_power_limit) || (limit < smu->min_power_limit)) {
dev_err(smu->adev->dev, dev_err(smu->adev->dev,
"New power limit (%d) is over the max allowed %d\n", "New power limit (%d) is out of range [%d,%d]\n",
limit, smu->max_power_limit); limit, smu->min_power_limit, smu->max_power_limit);
return -EINVAL; return -EINVAL;
} }
......
...@@ -500,6 +500,7 @@ struct smu_context { ...@@ -500,6 +500,7 @@ struct smu_context {
uint32_t current_power_limit; uint32_t current_power_limit;
uint32_t default_power_limit; uint32_t default_power_limit;
uint32_t max_power_limit; uint32_t max_power_limit;
uint32_t min_power_limit;
/* soft pptable */ /* soft pptable */
uint32_t ppt_offset_bytes; uint32_t ppt_offset_bytes;
...@@ -821,9 +822,10 @@ struct pptable_funcs { ...@@ -821,9 +822,10 @@ struct pptable_funcs {
* @get_power_limit: Get the device's power limits. * @get_power_limit: Get the device's power limits.
*/ */
int (*get_power_limit)(struct smu_context *smu, int (*get_power_limit)(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit); uint32_t *max_power_limit,
uint32_t *min_power_limit);
/** /**
* @get_ppt_limit: Get the device's ppt limits. * @get_ppt_limit: Get the device's ppt limits.
......
...@@ -1278,14 +1278,15 @@ static int arcturus_get_fan_parameters(struct smu_context *smu) ...@@ -1278,14 +1278,15 @@ static int arcturus_get_fan_parameters(struct smu_context *smu)
} }
static int arcturus_get_power_limit(struct smu_context *smu, static int arcturus_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_11_0_powerplay_table *powerplay_table = struct smu_11_0_powerplay_table *powerplay_table =
(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
PPTable_t *pptable = smu->smu_table.driver_pptable; PPTable_t *pptable = smu->smu_table.driver_pptable;
uint32_t power_limit, od_percent; uint32_t power_limit, od_percent_upper, od_percent_lower;
if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
/* the last hope to figure out the ppt limit */ /* the last hope to figure out the ppt limit */
...@@ -1302,17 +1303,25 @@ static int arcturus_get_power_limit(struct smu_context *smu, ...@@ -1302,17 +1303,25 @@ static int arcturus_get_power_limit(struct smu_context *smu,
if (default_power_limit) if (default_power_limit)
*default_power_limit = power_limit; *default_power_limit = power_limit;
if (max_power_limit) { if (smu->od_enabled) {
if (smu->od_enabled) { od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
} else {
od_percent_upper = 0;
od_percent_lower = 100;
}
dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent_upper, od_percent_lower, power_limit);
power_limit *= (100 + od_percent); if (max_power_limit) {
power_limit /= 100; *max_power_limit = power_limit * (100 + od_percent_upper);
} *max_power_limit /= 100;
}
*max_power_limit = power_limit; if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
} }
return 0; return 0;
......
...@@ -2330,15 +2330,16 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, ...@@ -2330,15 +2330,16 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu,
} }
static int navi10_get_power_limit(struct smu_context *smu, static int navi10_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_11_0_powerplay_table *powerplay_table = struct smu_11_0_powerplay_table *powerplay_table =
(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
struct smu_11_0_overdrive_table *od_settings = smu->od_settings; struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
PPTable_t *pptable = smu->smu_table.driver_pptable; PPTable_t *pptable = smu->smu_table.driver_pptable;
uint32_t power_limit, od_percent; uint32_t power_limit, od_percent_upper, od_percent_lower;
if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
/* the last hope to figure out the ppt limit */ /* the last hope to figure out the ppt limit */
...@@ -2355,18 +2356,26 @@ static int navi10_get_power_limit(struct smu_context *smu, ...@@ -2355,18 +2356,26 @@ static int navi10_get_power_limit(struct smu_context *smu,
if (default_power_limit) if (default_power_limit)
*default_power_limit = power_limit; *default_power_limit = power_limit;
if (max_power_limit) { if (smu->od_enabled &&
if (smu->od_enabled &&
navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) { navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
} else {
od_percent_upper = 0;
od_percent_lower = 100;
}
dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent_upper, od_percent_lower, power_limit);
power_limit *= (100 + od_percent); if (max_power_limit) {
power_limit /= 100; *max_power_limit = power_limit * (100 + od_percent_upper);
} *max_power_limit /= 100;
}
*max_power_limit = power_limit; if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
} }
return 0; return 0;
......
...@@ -620,11 +620,12 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s ...@@ -620,11 +620,12 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s
static int sienna_cichlid_get_power_limit(struct smu_context *smu, static int sienna_cichlid_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_11_0_7_powerplay_table *powerplay_table = struct smu_11_0_7_powerplay_table *powerplay_table =
(struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table; (struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
uint32_t power_limit, od_percent; uint32_t power_limit, od_percent_upper, od_percent_lower;
uint16_t *table_member; uint16_t *table_member;
GET_PPTABLE_MEMBER(SocketPowerLimitAc, &table_member); GET_PPTABLE_MEMBER(SocketPowerLimitAc, &table_member);
...@@ -639,21 +640,26 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu, ...@@ -639,21 +640,26 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu,
if (default_power_limit) if (default_power_limit)
*default_power_limit = power_limit; *default_power_limit = power_limit;
if (max_power_limit) { if (smu->od_enabled) {
if (smu->od_enabled) { od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
od_percent = od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
le32_to_cpu(powerplay_table->overdrive_table.max[ } else {
SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); od_percent_upper = 0;
od_percent_lower = 100;
}
dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent, power_limit); od_percent_upper, od_percent_lower, power_limit);
power_limit *= (100 + od_percent); if (max_power_limit) {
power_limit /= 100; *max_power_limit = power_limit * (100 + od_percent_upper);
} *max_power_limit /= 100;
*max_power_limit = power_limit;
} }
if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
}
return 0; return 0;
} }
...@@ -672,7 +678,7 @@ static void sienna_cichlid_get_smartshift_power_percentage(struct smu_context *s ...@@ -672,7 +678,7 @@ static void sienna_cichlid_get_smartshift_power_percentage(struct smu_context *s
uint32_t cur_power_limit; uint32_t cur_power_limit;
if (metrics_v4->ApuSTAPMSmartShiftLimit != 0) { if (metrics_v4->ApuSTAPMSmartShiftLimit != 0) {
sienna_cichlid_get_power_limit(smu, &cur_power_limit, NULL, NULL); sienna_cichlid_get_power_limit(smu, &cur_power_limit, NULL, NULL, NULL);
apu_power_limit = metrics_v4->ApuSTAPMLimit; apu_power_limit = metrics_v4->ApuSTAPMLimit;
dgpu_power_limit = cur_power_limit; dgpu_power_limit = cur_power_limit;
powerRatio = (((apu_power_limit + powerRatio = (((apu_power_limit +
......
...@@ -2314,7 +2314,8 @@ static u32 vangogh_get_gfxoff_status(struct smu_context *smu) ...@@ -2314,7 +2314,8 @@ static u32 vangogh_get_gfxoff_status(struct smu_context *smu)
static int vangogh_get_power_limit(struct smu_context *smu, static int vangogh_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_11_5_power_context *power_context = struct smu_11_5_power_context *power_context =
smu->smu_power.power_context; smu->smu_power.power_context;
...@@ -2336,6 +2337,8 @@ static int vangogh_get_power_limit(struct smu_context *smu, ...@@ -2336,6 +2337,8 @@ static int vangogh_get_power_limit(struct smu_context *smu,
*default_power_limit = ppt_limit / 1000; *default_power_limit = ppt_limit / 1000;
if (max_power_limit) if (max_power_limit)
*max_power_limit = 29; *max_power_limit = 29;
if (min_power_limit)
*min_power_limit = 0;
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit); ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit);
if (ret) { if (ret) {
......
...@@ -1139,9 +1139,10 @@ static int aldebaran_read_sensor(struct smu_context *smu, ...@@ -1139,9 +1139,10 @@ static int aldebaran_read_sensor(struct smu_context *smu,
} }
static int aldebaran_get_power_limit(struct smu_context *smu, static int aldebaran_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
PPTable_t *pptable = smu->smu_table.driver_pptable; PPTable_t *pptable = smu->smu_table.driver_pptable;
uint32_t power_limit = 0; uint32_t power_limit = 0;
...@@ -1154,7 +1155,8 @@ static int aldebaran_get_power_limit(struct smu_context *smu, ...@@ -1154,7 +1155,8 @@ static int aldebaran_get_power_limit(struct smu_context *smu,
*default_power_limit = 0; *default_power_limit = 0;
if (max_power_limit) if (max_power_limit)
*max_power_limit = 0; *max_power_limit = 0;
if (min_power_limit)
*min_power_limit = 0;
dev_warn(smu->adev->dev, dev_warn(smu->adev->dev,
"PPT feature is not enabled, power values can't be fetched."); "PPT feature is not enabled, power values can't be fetched.");
...@@ -1189,6 +1191,9 @@ static int aldebaran_get_power_limit(struct smu_context *smu, ...@@ -1189,6 +1191,9 @@ static int aldebaran_get_power_limit(struct smu_context *smu,
*max_power_limit = pptable->PptLimit; *max_power_limit = pptable->PptLimit;
} }
if (min_power_limit)
*min_power_limit = 0;
return 0; return 0;
} }
......
...@@ -2341,16 +2341,17 @@ static int smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context *smu) ...@@ -2341,16 +2341,17 @@ static int smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context *smu)
} }
static int smu_v13_0_0_get_power_limit(struct smu_context *smu, static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_table_context *table_context = &smu->smu_table; struct smu_table_context *table_context = &smu->smu_table;
struct smu_13_0_0_powerplay_table *powerplay_table = struct smu_13_0_0_powerplay_table *powerplay_table =
(struct smu_13_0_0_powerplay_table *)table_context->power_play_table; (struct smu_13_0_0_powerplay_table *)table_context->power_play_table;
PPTable_t *pptable = table_context->driver_pptable; PPTable_t *pptable = table_context->driver_pptable;
SkuTable_t *skutable = &pptable->SkuTable; SkuTable_t *skutable = &pptable->SkuTable;
uint32_t power_limit, od_percent; uint32_t power_limit, od_percent_upper, od_percent_lower;
if (smu_v13_0_get_current_power_limit(smu, &power_limit)) if (smu_v13_0_get_current_power_limit(smu, &power_limit))
power_limit = smu->adev->pm.ac_power ? power_limit = smu->adev->pm.ac_power ?
...@@ -2362,16 +2363,25 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu, ...@@ -2362,16 +2363,25 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
if (default_power_limit) if (default_power_limit)
*default_power_limit = power_limit; *default_power_limit = power_limit;
if (max_power_limit) { if (smu->od_enabled) {
if (smu->od_enabled) { od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
} else {
od_percent_upper = 0;
od_percent_lower = 100;
}
dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent_upper, od_percent_lower, power_limit);
power_limit *= (100 + od_percent); if (max_power_limit) {
power_limit /= 100; *max_power_limit = power_limit * (100 + od_percent_upper);
} *max_power_limit /= 100;
*max_power_limit = power_limit; }
if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
} }
return 0; return 0;
......
...@@ -1309,9 +1309,10 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, ...@@ -1309,9 +1309,10 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu,
} }
static int smu_v13_0_6_get_power_limit(struct smu_context *smu, static int smu_v13_0_6_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_table_context *smu_table = &smu->smu_table; struct smu_table_context *smu_table = &smu->smu_table;
struct PPTable_t *pptable = struct PPTable_t *pptable =
...@@ -1335,6 +1336,8 @@ static int smu_v13_0_6_get_power_limit(struct smu_context *smu, ...@@ -1335,6 +1336,8 @@ static int smu_v13_0_6_get_power_limit(struct smu_context *smu,
*max_power_limit = pptable->MaxSocketPowerLimit; *max_power_limit = pptable->MaxSocketPowerLimit;
} }
if (min_power_limit)
*min_power_limit = 0;
return 0; return 0;
} }
......
...@@ -2304,16 +2304,17 @@ static int smu_v13_0_7_enable_mgpu_fan_boost(struct smu_context *smu) ...@@ -2304,16 +2304,17 @@ static int smu_v13_0_7_enable_mgpu_fan_boost(struct smu_context *smu)
} }
static int smu_v13_0_7_get_power_limit(struct smu_context *smu, static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit, uint32_t *current_power_limit,
uint32_t *default_power_limit, uint32_t *default_power_limit,
uint32_t *max_power_limit) uint32_t *max_power_limit,
uint32_t *min_power_limit)
{ {
struct smu_table_context *table_context = &smu->smu_table; struct smu_table_context *table_context = &smu->smu_table;
struct smu_13_0_7_powerplay_table *powerplay_table = struct smu_13_0_7_powerplay_table *powerplay_table =
(struct smu_13_0_7_powerplay_table *)table_context->power_play_table; (struct smu_13_0_7_powerplay_table *)table_context->power_play_table;
PPTable_t *pptable = table_context->driver_pptable; PPTable_t *pptable = table_context->driver_pptable;
SkuTable_t *skutable = &pptable->SkuTable; SkuTable_t *skutable = &pptable->SkuTable;
uint32_t power_limit, od_percent; uint32_t power_limit, od_percent_upper, od_percent_lower;
if (smu_v13_0_get_current_power_limit(smu, &power_limit)) if (smu_v13_0_get_current_power_limit(smu, &power_limit))
power_limit = smu->adev->pm.ac_power ? power_limit = smu->adev->pm.ac_power ?
...@@ -2325,16 +2326,25 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, ...@@ -2325,16 +2326,25 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
if (default_power_limit) if (default_power_limit)
*default_power_limit = power_limit; *default_power_limit = power_limit;
if (max_power_limit) { if (smu->od_enabled) {
if (smu->od_enabled) { od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
} else {
od_percent_upper = 0;
od_percent_lower = 100;
}
dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent_upper, od_percent_lower, power_limit);
power_limit *= (100 + od_percent); if (max_power_limit) {
power_limit /= 100; *max_power_limit = power_limit * (100 + od_percent_upper);
} *max_power_limit /= 100;
*max_power_limit = power_limit; }
if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
} }
return 0; return 0;
......
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
#define smu_i2c_fini(smu) smu_ppt_funcs(i2c_fini, 0, smu) #define smu_i2c_fini(smu) smu_ppt_funcs(i2c_fini, 0, smu)
#define smu_get_unique_id(smu) smu_ppt_funcs(get_unique_id, 0, smu) #define smu_get_unique_id(smu) smu_ppt_funcs(get_unique_id, 0, smu)
#define smu_log_thermal_throttling(smu) smu_ppt_funcs(log_thermal_throttling_event, 0, smu) #define smu_log_thermal_throttling(smu) smu_ppt_funcs(log_thermal_throttling_event, 0, smu)
#define smu_get_asic_power_limits(smu, current, default, max) smu_ppt_funcs(get_power_limit, 0, smu, current, default, max) #define smu_get_asic_power_limits(smu, current, default, max, min) smu_ppt_funcs(get_power_limit, 0, smu, current, default, max, min)
#define smu_get_pp_feature_mask(smu, buf) smu_ppt_funcs(get_pp_feature_mask, 0, smu, buf) #define smu_get_pp_feature_mask(smu, buf) smu_ppt_funcs(get_pp_feature_mask, 0, smu, buf)
#define smu_set_pp_feature_mask(smu, new_mask) smu_ppt_funcs(set_pp_feature_mask, 0, smu, new_mask) #define smu_set_pp_feature_mask(smu, new_mask) smu_ppt_funcs(set_pp_feature_mask, 0, smu, new_mask)
#define smu_gfx_ulv_control(smu, enablement) smu_ppt_funcs(gfx_ulv_control, 0, smu, enablement) #define smu_gfx_ulv_control(smu, enablement) smu_ppt_funcs(gfx_ulv_control, 0, smu, enablement)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment