Commit 6ab8555e authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

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: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 71d0a898
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+61 −0
Original line number Diff line number Diff line
@@ -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,
+1 −0
Original line number Diff line number Diff line
@@ -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,
+5 −3
Original line number Diff line number Diff line
@@ -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!");
			}
		}
+1 −0
Original line number Diff line number Diff line
@@ -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)
Loading