Commit 12a6727d authored by Xiaojian Du's avatar Xiaojian Du Committed by Alex Deucher
Browse files

drm/amd/powerplay: add one sysfs file to support the feature to modify gfx...


drm/amd/powerplay: add one sysfs file to support the feature to modify gfx clock on Raven/Raven2/Picasso APU.

This patch is to add one sysfs file -- "pp_od_clk_voltage" for
Raven/Raven2/Picasso APU, which is only used by dGPU like VEGA10.
This sysfs file supports the feature to modify gfx engine clock(Mhz units), it can
be used to configure the min value and the max value for gfx clock limited in the
safe range.

Command guide:
echo "s level clock" > pp_od_clk_voltage
	s - adjust teh sclk level
	level - 0 or 1, "0" represents the min value, "1" represents the max value
	clock - the clock value(Mhz units), like 400, 800 or 1200, the value must be within the
                OD_RANGE limits.
Example:
$ cat pp_od_clk_voltage
OD_SCLK:
0:        200Mhz
1:       1400Mhz
OD_RANGE:
SCLK:     200MHz       1400MHz

$ echo "s 0 600" > pp_od_clk_voltage
$ echo "s 1 1000" > pp_od_clk_voltage
$ cat pp_od_clk_voltage
OD_SCLK:
0:        600Mhz
1:       1000Mhz
OD_RANGE:
SCLK:     200MHz       1400MHz

Signed-off-by: default avatarXiaojian Du <Xiaojian.Du@amd.com>
Reviewed-by: default avatarKevin Wang <kevin1.wang@amd.com>
Reviewed-by: default avatarHuang Rui <ray.huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 72e71a82
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ struct amd_pm_funcs {
	int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit);
	int (*get_power_profile_mode)(void *handle, char *buf);
	int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
	int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size);
	int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
	int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
	int (*smu_i2c_bus_access)(void *handle, bool acquire);
+12 −0
Original line number Diff line number Diff line
@@ -827,6 +827,18 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
			return -EINVAL;
		}
	} else {

		if (adev->powerplay.pp_funcs->set_fine_grain_clk_vol) {
			ret = amdgpu_dpm_set_fine_grain_clk_vol(adev, type,
								parameter,
								parameter_size);
			if (ret) {
				pm_runtime_mark_last_busy(ddev->dev);
				pm_runtime_put_autosuspend(ddev->dev);
				return -EINVAL;
			}
		}

		if (adev->powerplay.pp_funcs->odn_edit_dpm_table) {
			ret = amdgpu_dpm_odn_edit_dpm_table(adev, type,
						parameter, parameter_size);
+4 −0
Original line number Diff line number Diff line
@@ -349,6 +349,10 @@ enum amdgpu_pcie_gen {
		((adev)->powerplay.pp_funcs->set_power_profile_mode(\
			(adev)->powerplay.pp_handle, parameter, size))

#define amdgpu_dpm_set_fine_grain_clk_vol(adev, type, parameter, size) \
		((adev)->powerplay.pp_funcs->set_fine_grain_clk_vol(\
			(adev)->powerplay.pp_handle, type, parameter, size))

#define amdgpu_dpm_odn_edit_dpm_table(adev, type, parameter, size) \
		((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\
			(adev)->powerplay.pp_handle, type, parameter, size))
+5 −0
Original line number Diff line number Diff line
@@ -340,6 +340,9 @@ 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_fine_grain_clk_vol)(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 (*powergate_mmhub)(struct pp_hwmgr *hwmgr);
	int (*smus_notify_pwe)(struct pp_hwmgr *hwmgr);
@@ -347,6 +350,8 @@ struct pp_hwmgr_func {
	int (*enable_mgpu_fan_boost)(struct pp_hwmgr *hwmgr);
	int (*set_hard_min_dcefclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
	int (*set_hard_min_fclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
	int (*set_hard_min_gfxclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
	int (*set_soft_max_gfxclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
	int (*get_asic_baco_capability)(struct pp_hwmgr *hwmgr, bool *cap);
	int (*get_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
	int (*set_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
+15 −1
Original line number Diff line number Diff line
@@ -911,6 +911,19 @@ static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
	return ret;
}

static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, uint32_t size)
{
	struct pp_hwmgr *hwmgr = handle;

	if (!hwmgr || !hwmgr->pm_en)
		return -EINVAL;

	if (hwmgr->hwmgr_func->set_fine_grain_clk_vol == NULL)
		return 0;

	return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size);
}

static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size)
{
	struct pp_hwmgr *hwmgr = handle;
@@ -920,7 +933,7 @@ static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint3

	if (hwmgr->hwmgr_func->odn_edit_dpm_table == NULL) {
		pr_info_ratelimited("%s was not implemented.\n", __func__);
		return -EINVAL;
		return 0;
	}

	return hwmgr->hwmgr_func->odn_edit_dpm_table(hwmgr, type, input, size);
@@ -1645,6 +1658,7 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
	.set_powergating_by_smu = pp_set_powergating_by_smu,
	.get_power_profile_mode = pp_get_power_profile_mode,
	.set_power_profile_mode = pp_set_power_profile_mode,
	.set_fine_grain_clk_vol = pp_set_fine_grain_clk_vol,
	.odn_edit_dpm_table = pp_odn_edit_dpm_table,
	.set_mp1_state = pp_dpm_set_mp1_state,
	.set_power_limit = pp_set_power_limit,
Loading