On Mon, Sep 28, 2020 at 03:15:30PM +0800, Du, Xiaojian wrote: > From: Xiaojian Du <xiaojian.du@xxxxxxx> > > From: Xiaojian Du <Xiaojian.Du@xxxxxxx> > > 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: Xiaojian Du <Xiaojian.Du@xxxxxxx> Reviewed-by: Huang Rui <ray.huang@xxxxxxx> > --- > .../gpu/drm/amd/include/kgd_pp_interface.h | 1 + > drivers/gpu/drm/amd/pm/amdgpu_pm.c | 12 +++ > drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 4 + > drivers/gpu/drm/amd/pm/inc/hwmgr.h | 5 ++ > .../gpu/drm/amd/pm/powerplay/amd_powerplay.c | 17 +++- > .../drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 79 +++++++++++++++++++ > 6 files changed, 117 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h > index 0aec28fda058..94132c70d7af 100644 > --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h > +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h > @@ -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); > diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c > index b5d2f30043ad..fe0de00f56e2 100644 > --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c > +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c > @@ -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); > diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h > index dff4a5f99bb0..f6e0e7d8a007 100644 > --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h > +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h > @@ -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)) > diff --git a/drivers/gpu/drm/amd/pm/inc/hwmgr.h b/drivers/gpu/drm/amd/pm/inc/hwmgr.h > index 1b3529efc91e..3898a95ec28b 100644 > --- a/drivers/gpu/drm/amd/pm/inc/hwmgr.h > +++ b/drivers/gpu/drm/amd/pm/inc/hwmgr.h > @@ -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); > diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c > index a6321f2063c1..bb8d077d3f05 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c > @@ -911,6 +911,20 @@ 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 +934,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 +1659,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, > diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c > index 9ee8cf8267c8..791db107d51a 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c > @@ -242,6 +242,34 @@ static int smu10_set_hard_min_fclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cloc > return 0; > } > > +static int smu10_set_hard_min_gfxclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t clock) > +{ > + struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); > + > + if (clock && smu10_data->gfx_actual_soft_min_freq != clock) { > + smu10_data->gfx_actual_soft_min_freq = clock; > + smum_send_msg_to_smc_with_parameter(hwmgr, > + PPSMC_MSG_SetHardMinGfxClk, > + smu10_data->gfx_actual_soft_min_freq, > + NULL); > + } > + return 0; > +} > + > +static int smu10_set_soft_max_gfxclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t clock) > +{ > + struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); > + > + if (clock && smu10_data->gfx_max_freq_limit != (clock * 100)) { > + smu10_data->gfx_max_freq_limit = clock * 100; > + smum_send_msg_to_smc_with_parameter(hwmgr, > + PPSMC_MSG_SetSoftMaxGfxClk, > + clock, > + NULL); > + } > + return 0; > +} > + > static int smu10_set_active_display_count(struct pp_hwmgr *hwmgr, uint32_t count) > { > struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); > @@ -527,6 +555,8 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) > hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK * 100; > hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK * 100; > > + hwmgr->od_enabled = 1; /*enable the pp_od_clk_voltage sysfs file*/ > + > return result; > } > > @@ -947,6 +977,26 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, > ((mclk_table->entries[i].clk / 100) > == now) ? "*" : ""); > break; > + case OD_SCLK: > + if (hwmgr->od_enabled) { > + size = sprintf(buf, "%s:\n", "OD_SCLK"); > + > + size += sprintf(buf + size, "0: %10uMhz\n", > + (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : data->gfx_min_freq_limit/100); > + size += sprintf(buf + size, "1: %10uMhz\n", data->gfx_max_freq_limit/100); > + } > + break; > + case OD_RANGE: > + if (hwmgr->od_enabled) { > + uint32_t min_freq, max_freq = 0; > + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); > + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); > + > + size = sprintf(buf, "%s:\n", "OD_RANGE"); > + size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n", > + min_freq, max_freq); > + } > + break; > default: > break; > } > @@ -1348,6 +1398,32 @@ static int smu10_asic_reset(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mod > NULL); > } > > +static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, > + enum PP_OD_DPM_TABLE_COMMAND type, > + long *input, uint32_t size) > +{ > + if (!hwmgr->od_enabled) { > + pr_err("Fine grain not support\n"); > + return -EINVAL; > + } > + > + if (size != 2) { > + pr_err("Input parameter number not correct\n"); > + return -EINVAL; > + } > + > + if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { > + if (input[0] == 0) > + smu10_set_hard_min_gfxclk_by_freq(hwmgr, input[1]); > + else if (input[0] == 1) > + smu10_set_soft_max_gfxclk_by_freq(hwmgr, input[1]); > + else > + return -EINVAL; > + } > + > + return 0; > +} > + > static const struct pp_hwmgr_func smu10_hwmgr_funcs = { > .backend_init = smu10_hwmgr_backend_init, > .backend_fini = smu10_hwmgr_backend_fini, > @@ -1388,9 +1464,12 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = { > .powergate_sdma = smu10_powergate_sdma, > .set_hard_min_dcefclk_by_freq = smu10_set_hard_min_dcefclk_by_freq, > .set_hard_min_fclk_by_freq = smu10_set_hard_min_fclk_by_freq, > + .set_hard_min_gfxclk_by_freq = smu10_set_hard_min_gfxclk_by_freq, > + .set_soft_max_gfxclk_by_freq = smu10_set_soft_max_gfxclk_by_freq, > .get_power_profile_mode = smu10_get_power_profile_mode, > .set_power_profile_mode = smu10_set_power_profile_mode, > .asic_reset = smu10_asic_reset, > + .set_fine_grain_clk_vol = smu10_set_fine_grain_clk_vol, > }; > > int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) > -- > 2.17.1 > _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx