mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
drm/amd/pp: Expose set/get_power_limit for DGPU
User can change power limit between [0, 1] * max power limit. Set power limit to 0, restore to max power limit. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
71d0a89812
commit
6ab8555e04
7 changed files with 77 additions and 6 deletions
|
@ -283,6 +283,8 @@ struct amd_pm_funcs {
|
|||
uint32_t mc_addr_low,
|
||||
uint32_t mc_addr_hi,
|
||||
uint32_t size);
|
||||
int (*set_power_limit)(void *handle, uint32_t n);
|
||||
int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit);
|
||||
/* export to DC */
|
||||
u32 (*get_sclk)(void *handle, bool low);
|
||||
u32 (*get_mclk)(void *handle, bool low);
|
||||
|
|
|
@ -1237,6 +1237,65 @@ static int pp_dpm_notify_smu_memory_info(void *handle,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int pp_set_power_limit(void *handle, uint32_t limit)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr;
|
||||
struct pp_instance *pp_handle = (struct pp_instance *)handle;
|
||||
int ret = 0;
|
||||
|
||||
ret = pp_check(pp_handle);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hwmgr = pp_handle->hwmgr;
|
||||
|
||||
if (hwmgr->hwmgr_func->set_power_limit == NULL) {
|
||||
pr_info("%s was not implemented.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (limit == 0)
|
||||
limit = hwmgr->default_power_limit;
|
||||
|
||||
if (limit > hwmgr->default_power_limit)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pp_handle->pp_lock);
|
||||
hwmgr->hwmgr_func->set_power_limit(hwmgr, limit);
|
||||
hwmgr->power_limit = limit;
|
||||
mutex_unlock(&pp_handle->pp_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr;
|
||||
struct pp_instance *pp_handle = (struct pp_instance *)handle;
|
||||
int ret = 0;
|
||||
|
||||
ret = pp_check(pp_handle);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (limit == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
hwmgr = pp_handle->hwmgr;
|
||||
|
||||
mutex_lock(&pp_handle->pp_lock);
|
||||
|
||||
if (default_limit)
|
||||
*limit = hwmgr->default_power_limit;
|
||||
else
|
||||
*limit = hwmgr->power_limit;
|
||||
|
||||
mutex_unlock(&pp_handle->pp_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pp_display_configuration_change(void *handle,
|
||||
const struct amd_pp_display_configuration *display_config)
|
||||
{
|
||||
|
@ -1530,6 +1589,8 @@ const struct amd_pm_funcs pp_dpm_funcs = {
|
|||
.get_power_profile_mode = pp_get_power_profile_mode,
|
||||
.set_power_profile_mode = pp_set_power_profile_mode,
|
||||
.odn_edit_dpm_table = pp_odn_edit_dpm_table,
|
||||
.set_power_limit = pp_set_power_limit,
|
||||
.get_power_limit = pp_get_power_limit,
|
||||
/* export to DC */
|
||||
.get_sclk = pp_dpm_get_sclk,
|
||||
.get_mclk = pp_dpm_get_mclk,
|
||||
|
|
|
@ -4987,6 +4987,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
|
|||
.get_max_high_clocks = smu7_get_max_high_clocks,
|
||||
.get_thermal_temperature_range = smu7_get_thermal_temperature_range,
|
||||
.odn_edit_dpm_table = smu7_odn_edit_dpm_table,
|
||||
.set_power_limit = smu7_set_power_limit,
|
||||
};
|
||||
|
||||
uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
|
||||
|
|
|
@ -857,6 +857,8 @@ int smu7_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
|
|||
{
|
||||
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||
|
||||
n = (n & 0xff) << 8;
|
||||
|
||||
if (data->power_containment_features &
|
||||
POWERCONTAINMENT_FEATURE_PkgPwrLimit)
|
||||
return smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||
|
@ -903,12 +905,12 @@ int smu7_enable_power_containment(struct pp_hwmgr *hwmgr)
|
|||
PP_ASSERT_WITH_CODE((0 == smc_result),
|
||||
"Failed to enable PkgPwrTracking in SMC.", result = -1;);
|
||||
if (0 == smc_result) {
|
||||
uint32_t default_limit =
|
||||
(uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256);
|
||||
hwmgr->default_power_limit = hwmgr->power_limit =
|
||||
cac_table->usMaximumPowerDeliveryLimit;
|
||||
data->power_containment_features |=
|
||||
POWERCONTAINMENT_FEATURE_PkgPwrLimit;
|
||||
|
||||
if (smu7_set_power_limit(hwmgr, default_limit))
|
||||
if (smu7_set_power_limit(hwmgr, hwmgr->power_limit))
|
||||
pr_err("Failed to set Default Power Limit in SMC!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5155,6 +5155,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
|
|||
.start_thermal_controller = vega10_start_thermal_controller,
|
||||
.get_power_profile_mode = vega10_get_power_profile_mode,
|
||||
.set_power_profile_mode = vega10_set_power_profile_mode,
|
||||
.set_power_limit = vega10_set_power_limit,
|
||||
};
|
||||
|
||||
int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
|
||||
|
|
|
@ -1357,10 +1357,11 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr)
|
|||
struct phm_ppt_v2_information *table_info =
|
||||
(struct phm_ppt_v2_information *)(hwmgr->pptable);
|
||||
struct phm_tdp_table *tdp_table = table_info->tdp_table;
|
||||
uint32_t default_pwr_limit =
|
||||
(uint32_t)(tdp_table->usMaximumPowerDeliveryLimit);
|
||||
int result = 0;
|
||||
|
||||
hwmgr->default_power_limit = hwmgr->power_limit =
|
||||
(uint32_t)(tdp_table->usMaximumPowerDeliveryLimit);
|
||||
|
||||
if (PP_CAP(PHM_PlatformCaps_PowerContainment)) {
|
||||
if (data->smu_features[GNLD_PPT].supported)
|
||||
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
|
||||
|
@ -1374,7 +1375,7 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr)
|
|||
"Attempt to enable PPT feature Failed!",
|
||||
data->smu_features[GNLD_TDC].supported = false);
|
||||
|
||||
result = vega10_set_power_limit(hwmgr, default_pwr_limit);
|
||||
result = vega10_set_power_limit(hwmgr, hwmgr->power_limit);
|
||||
PP_ASSERT_WITH_CODE(!result,
|
||||
"Failed to set Default Power Limit in SMC!",
|
||||
return result);
|
||||
|
|
|
@ -347,6 +347,7 @@ struct pp_hwmgr_func {
|
|||
int (*odn_edit_dpm_table)(struct pp_hwmgr *hwmgr,
|
||||
enum PP_OD_DPM_TABLE_COMMAND type,
|
||||
long *input, uint32_t size);
|
||||
int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n);
|
||||
int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr);
|
||||
};
|
||||
|
||||
|
@ -759,6 +760,8 @@ struct pp_hwmgr {
|
|||
uint32_t pstate_sclk;
|
||||
uint32_t pstate_mclk;
|
||||
bool od_enabled;
|
||||
uint32_t power_limit;
|
||||
uint32_t default_power_limit;
|
||||
};
|
||||
|
||||
struct cgs_irq_src_funcs {
|
||||
|
|
Loading…
Reference in a new issue