mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
drm/amd/pm: fix smu13 power limit default/cap calculation
smu_v13_0_0_get_power_limit() and smu_v13_0_7_get_power_limit() mix runtime power_limit with PP table limits when reporting default/min/max. When current power limit query succeeds, default_power_limit was set to the runtime value instead of the PP table default, and min/max could be derived from inconsistent bases (MsgLimits/runtime), leading to incorrect cap info. Use SocketPowerLimitAc/Dc as the PP default base (pp_limit), keep current_power_limit as runtime value, and derive min/max from pp_limit with OD percentages. Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5227 Signed-off-by: Yang Wang <kevinyang.wang@amd.com> Reviewed-by: Kenneth Feng <kenneth.feng@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4e8ee1afee
commit
1eaf26db95
|
|
@ -2390,28 +2390,30 @@ 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)
|
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_upper = 0, od_percent_lower = 0;
|
uint32_t pp_limit = smu->adev->pm.ac_power ?
|
||||||
uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
|
|
||||||
|
|
||||||
if (smu_v13_0_get_current_power_limit(smu, &power_limit))
|
|
||||||
power_limit = smu->adev->pm.ac_power ?
|
|
||||||
skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
|
skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
|
||||||
skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
|
skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
|
||||||
|
uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (current_power_limit) {
|
||||||
|
ret = smu_v13_0_get_current_power_limit(smu, &power_limit);
|
||||||
|
if (ret)
|
||||||
|
*current_power_limit = pp_limit;
|
||||||
|
}
|
||||||
|
|
||||||
if (current_power_limit)
|
|
||||||
*current_power_limit = power_limit;
|
|
||||||
if (default_power_limit)
|
if (default_power_limit)
|
||||||
*default_power_limit = power_limit;
|
*default_power_limit = pp_limit;
|
||||||
|
|
||||||
if (powerplay_table) {
|
if (powerplay_table) {
|
||||||
if (smu->od_enabled &&
|
if (smu->od_enabled &&
|
||||||
|
|
@ -2425,15 +2427,15 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
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);
|
od_percent_upper, od_percent_lower, pp_limit);
|
||||||
|
|
||||||
if (max_power_limit) {
|
if (max_power_limit) {
|
||||||
*max_power_limit = msg_limit * (100 + od_percent_upper);
|
*max_power_limit = pp_limit * (100 + od_percent_upper);
|
||||||
*max_power_limit /= 100;
|
*max_power_limit /= 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_power_limit) {
|
if (min_power_limit) {
|
||||||
*min_power_limit = power_limit * (100 - od_percent_lower);
|
*min_power_limit = pp_limit * (100 - od_percent_lower);
|
||||||
*min_power_limit /= 100;
|
*min_power_limit /= 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2372,28 +2372,32 @@ 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)
|
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_upper = 0, od_percent_lower = 0;
|
uint32_t pp_limit = smu->adev->pm.ac_power ?
|
||||||
uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
|
|
||||||
|
|
||||||
if (smu_v13_0_get_current_power_limit(smu, &power_limit))
|
|
||||||
power_limit = smu->adev->pm.ac_power ?
|
|
||||||
skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
|
skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
|
||||||
skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
|
skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
|
||||||
|
uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (current_power_limit) {
|
||||||
|
ret = smu_v13_0_get_current_power_limit(smu, &power_limit);
|
||||||
|
if (ret)
|
||||||
|
power_limit = pp_limit;
|
||||||
|
|
||||||
if (current_power_limit)
|
|
||||||
*current_power_limit = power_limit;
|
*current_power_limit = power_limit;
|
||||||
|
}
|
||||||
|
|
||||||
if (default_power_limit)
|
if (default_power_limit)
|
||||||
*default_power_limit = power_limit;
|
*default_power_limit = pp_limit;
|
||||||
|
|
||||||
if (powerplay_table) {
|
if (powerplay_table) {
|
||||||
if (smu->od_enabled &&
|
if (smu->od_enabled &&
|
||||||
|
|
@ -2407,15 +2411,15 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
|
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);
|
od_percent_upper, od_percent_lower, pp_limit);
|
||||||
|
|
||||||
if (max_power_limit) {
|
if (max_power_limit) {
|
||||||
*max_power_limit = msg_limit * (100 + od_percent_upper);
|
*max_power_limit = pp_limit * (100 + od_percent_upper);
|
||||||
*max_power_limit /= 100;
|
*max_power_limit /= 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_power_limit) {
|
if (min_power_limit) {
|
||||||
*min_power_limit = power_limit * (100 - od_percent_lower);
|
*min_power_limit = pp_limit * (100 - od_percent_lower);
|
||||||
*min_power_limit /= 100;
|
*min_power_limit /= 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user