[AMD Official Use Only - Internal Distribution Only] To be consistent with other ASICs, "echo r" is enough to restore to the default values. No need to followed by a "echo c". With that fixed, the series is reviewed-by: Evan Quan <evan.quan@xxxxxxx> -----Original Message----- From: Du, Xiaojian <Xiaojian.Du@xxxxxxx> Sent: Sunday, November 15, 2020 10:45 PM To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx Cc: Huang, Ray <Ray.Huang@xxxxxxx>; Quan, Evan <Evan.Quan@xxxxxxx>; Deucher, Alexander <Alexander.Deucher@xxxxxxx>; Wang, Kevin(Yang) <Kevin1.Wang@xxxxxxx>; Huang, Shimmer <Xinmei.Huang@xxxxxxx>; Liang, Prike <Prike.Liang@xxxxxxx>; Zhu, Changfeng <Changfeng.Zhu@xxxxxxx>; Du, Xiaojian <Xiaojian.Du@xxxxxxx> Subject: [PATCH 1/2] drm/amd/pm: add the fine grain tuning function for vangogh This patch is to add the fine grain tuning function for vangogh. This function uses the pp_od_clk_voltage sysfs file to configure the min and max value of gfx clock frequency or restore the default value. Command guide: echo "s level value" > pp_od_clk_voltage "s" - set the sclk frequency "level" - 0 or 1, "0" represents the min value, "1" represents the max value "value" - the target value of sclk frequency, it should be limited in the safe range. echo "r" > pp_od_clk_voltage "r" - reset the sclk frequency, restore the default value echo "c" > pp_od_clk_voltage "c" - commit the min and max value of sclk frequency to the system. only after the commit command, the target values will take effect. Example: 1)check the default sclk frequency $ cat pp_od_clk_voltage OD_SCLK: 0: 200Mhz 1: 1400Mhz OD_RANGE: SCLK: 200MHz 1400MHz 2)use "s" -- set command to configure the min or max sclk frequency $ echo "s 0 600" > pp_od_clk_voltage $ echo "s 1 1000" > pp_od_clk_voltage $ echo "c" > pp_od_clk_voltage $ cat pp_od_clk_voltage OD_SCLK: 0: 600Mhz 1: 1000Mhz OD_RANGE: SCLK: 200MHz 1400MHz 3)use "r" -- reset command to restore the min and max sclk frequency $ echo "r" > pp_od_clk_voltage & echo "c" > pp_od_clk_voltage $ cat pp_od_clk_voltage OD_SCLK: 0: 200Mhz 1: 1400Mhz OD_RANGE: SCLK: 200MHz 1400MHz Signed-off-by: Xiaojian Du <Xiaojian.Du@xxxxxxx> --- drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 6 + .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 2 + .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 135 ++++++++++++++++++ drivers/gpu/drm/amd/pm/swsmu/smu_internal.h | 1 + 4 files changed, 144 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index ae8ff7b07932..7550757cc059 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -459,6 +459,11 @@ struct smu_context unsigned fan_max_rpm; unsigned manual_fan_speed_rpm; + +uint32_t gfx_default_hard_min_freq; +uint32_t gfx_default_soft_max_freq; +uint32_t gfx_actual_hard_min_freq; +uint32_t gfx_actual_soft_max_freq; }; struct i2c_adapter; @@ -577,6 +582,7 @@ struct pptable_funcs { void (*interrupt_work)(struct smu_context *smu); int (*gpo_control)(struct smu_context *smu, bool enablement); int (*gfx_state_change_set)(struct smu_context *smu, uint32_t state); +int (*set_fine_grain_gfx_freq_parameters)(struct smu_context *smu); }; typedef enum { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index b880c72c322c..b23311096467 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -438,11 +438,13 @@ int smu_v11_0_fini_smc_tables(struct smu_context *smu) kfree(smu_table->overdrive_table); kfree(smu_table->max_sustainable_clocks); kfree(smu_table->driver_pptable); +kfree(smu_table->clocks_table); smu_table->gpu_metrics_table = NULL; smu_table->boot_overdrive_table = NULL; smu_table->overdrive_table = NULL; smu_table->max_sustainable_clocks = NULL; smu_table->driver_pptable = NULL; +smu_table->clocks_table = NULL; kfree(smu_table->hardcode_pptable); smu_table->hardcode_pptable = NULL; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index cbcbcd8514f0..299ad695f607 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -200,8 +200,14 @@ static int vangogh_tables_init(struct smu_context *smu) if (!smu_table->watermarks_table) goto err2_out; +smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); +if (!smu_table->clocks_table) +goto err3_out; + return 0; +err3_out: +kfree(smu_table->clocks_table); err2_out: kfree(smu_table->gpu_metrics_table); err1_out: @@ -477,6 +483,35 @@ static int vangogh_get_current_clk_freq_by_table(struct smu_context *smu, value); } +static int vangogh_print_fine_grain_clk(struct smu_context *smu, +enum smu_clk_type clk_type, char *buf) +{ +int size = 0; + +switch (clk_type) { +case SMU_OD_SCLK: +if (smu->od_enabled) { +size = sprintf(buf, "%s:\n", "OD_SCLK"); +size += sprintf(buf + size, "0: %10uMhz\n", +(smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); +size += sprintf(buf + size, "1: %10uMhz\n", +(smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); +} +break; +case SMU_OD_RANGE: +if (smu->od_enabled) { +size = sprintf(buf, "%s:\n", "OD_RANGE"); +size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n", +smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); +} +break; +default: +break; +} + +return size; +} + static int vangogh_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, void *data, uint32_t *size) @@ -635,6 +670,102 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, return sizeof(struct gpu_metrics_v2_0); } +static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, +long input[], uint32_t size) +{ +int ret = 0; + +if (!smu->od_enabled) { +dev_warn(smu->adev->dev, "Fine grain is not enabled!\n"); +return -EINVAL; +} + +switch (type) { +case PP_OD_EDIT_SCLK_VDDC_TABLE: +if (size != 2) { +dev_err(smu->adev->dev, "Input parameter number not correct\n"); +return -EINVAL; +} + +if (input[0] == 0) { +if (input[1] < smu->gfx_default_hard_min_freq) { +dev_warn(smu->adev->dev, "Fine grain setting minimun sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", +input[1], smu->gfx_default_hard_min_freq); +return -EINVAL; +} +smu->gfx_actual_hard_min_freq = input[1]; +} else if (input[0] == 1) { +if (input[1] > smu->gfx_default_soft_max_freq) { +dev_warn(smu->adev->dev, "Fine grain setting maximun sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", +input[1], smu->gfx_default_soft_max_freq); +return -EINVAL; +} +smu->gfx_actual_soft_max_freq = input[1]; +} else { +return -EINVAL; +} +break; +case PP_OD_RESTORE_DEFAULT_TABLE: +if (size != 0) { +dev_err(smu->adev->dev, "Input parameter number not correct\n"); +return -EINVAL; +} else { +smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; +smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; +} +break; +case PP_OD_COMMIT_DPM_TABLE: +if (size != 0) { +dev_err(smu->adev->dev, "Input parameter number not correct\n"); +return -EINVAL; +} else { +if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) { +dev_err(smu->adev->dev, "The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", +smu->gfx_actual_hard_min_freq, smu->gfx_actual_soft_max_freq); +return -EINVAL; +} + +ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, +smu->gfx_actual_hard_min_freq, NULL); +if (ret) { +dev_err(smu->adev->dev, "Set hard min sclk failed!"); +return ret; +} + +ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, +smu->gfx_actual_soft_max_freq, NULL); +if (ret) { +dev_err(smu->adev->dev, "Set soft max sclk failed!"); +return ret; +} +} +break; +default: +return -ENOSYS; +} + +return ret; +} + +int vangogh_set_default_dpm_tables(struct smu_context *smu) +{ +struct smu_table_context *smu_table = &smu->smu_table; + +return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); +} + +static int vangogh_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) +{ +DpmClocks_t *clk_table = smu->smu_table.clocks_table; + +smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; +smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; +smu->gfx_actual_hard_min_freq = 0; +smu->gfx_actual_soft_max_freq = 0; + +return 0; +} + static const struct pptable_funcs vangogh_ppt_funcs = { .check_fw_status = smu_v11_0_check_fw_status, @@ -659,6 +790,10 @@ static const struct pptable_funcs vangogh_ppt_funcs = { .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception, .interrupt_work = smu_v11_0_interrupt_work, .get_gpu_metrics = vangogh_get_gpu_metrics, +.od_edit_dpm_table = vangogh_od_edit_dpm_table, +.print_clk_levels = vangogh_print_fine_grain_clk, +.set_default_dpm_table = vangogh_set_default_dpm_tables, +.set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters, }; void vangogh_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h index f7be2d1a0ff2..68d9464ababc 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h @@ -90,6 +90,7 @@ #define smu_get_fan_parameters(smu)smu_ppt_funcs(get_fan_parameters, 0, smu) #define smu_post_init(smu)smu_ppt_funcs(post_init, 0, smu) #define smu_gpo_control(smu, enablement)smu_ppt_funcs(gpo_control, 0, smu, enablement) +#define smu_set_fine_grain_gfx_freq_parameters(smu)smu_ppt_funcs(set_fine_grain_gfx_freq_parameters, 0, smu) #endif #endif -- 2.17.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx