[PATCH 7/7] drm/amd/pm: implement processor fine grain feature for vangogh

Huang Rui ray.huang at amd.com
Fri Jan 8 10:59:57 UTC 2021


On Fri, Jan 08, 2021 at 06:01:08PM +0800, Quan, Evan wrote:
> [AMD Official Use Only - Internal Distribution Only]
> 
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces at lists.freedesktop.org> On Behalf Of Huang Rui
> Sent: Friday, January 8, 2021 4:55 PM
> To: amd-gfx at lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher at amd.com>; Hou, Xiaomeng (Matthew) <Xiaomeng.Hou at amd.com>; Huang, Ray <Ray.Huang at amd.com>; Liu, Aaron <Aaron.Liu at amd.com>; Du, Xiaojian <Xiaojian.Du at amd.com>
> Subject: [PATCH 7/7] drm/amd/pm: implement processor fine grain feature for vangogh
> 
> This patch is to implement the processor fine grain feature for vangogh.
> It's similar with gfx clock, the only difference is below:
> 
> echo "p core_id level value" > pp_od_clk_voltage
> 
> 1. "p" - set the cclk (processor) frequency
> 2. "core_id" - 0/1/2/3, represents which cpu core you want to select
> 2. "level" - 0 or 1, "0" represents the min value,  "1" represents the
>    max value
> 3. "value" - the target value of cclk frequency, it should be limited in
>    the safe range
> 
> Signed-off-by: Huang Rui <ray.huang at amd.com>
> ---
>  .../gpu/drm/amd/include/kgd_pp_interface.h    |  1 +
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c            |  3 +
>  drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h       |  6 ++
>  drivers/gpu/drm/amd/pm/inc/smu_types.h        |  1 +
>  .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c  | 78 ++++++++++++++++++-
>  5 files changed, 88 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 57b24c4c205b..a41875ac5dfb 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -156,6 +156,7 @@ enum {
>  enum PP_OD_DPM_TABLE_COMMAND {
>  PP_OD_EDIT_SCLK_VDDC_TABLE,
>  PP_OD_EDIT_MCLK_VDDC_TABLE,
> +PP_OD_EDIT_CCLK_VDDC_TABLE,
>  PP_OD_EDIT_VDDC_CURVE,
>  PP_OD_RESTORE_DEFAULT_TABLE,
>  PP_OD_COMMIT_DPM_TABLE,
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index a5be03aa384b..298784f73705 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -800,6 +800,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
> 
>  if (*buf == 's')
>  type = PP_OD_EDIT_SCLK_VDDC_TABLE;
> +if (*buf == 'p')
> [Quan, Evan] better to use "else if" here.
> +type = PP_OD_EDIT_CCLK_VDDC_TABLE;
>  else if (*buf == 'm')
>  type = PP_OD_EDIT_MCLK_VDDC_TABLE;
>  else if(*buf == 'r')
> @@ -916,6 +918,7 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
>  size += smu_print_clk_levels(&adev->smu, SMU_OD_VDDC_CURVE, buf+size);
>  size += smu_print_clk_levels(&adev->smu, SMU_OD_VDDGFX_OFFSET, buf+size);
>  size += smu_print_clk_levels(&adev->smu, SMU_OD_RANGE, buf+size);
> +size += smu_print_clk_levels(&adev->smu, SMU_OD_CCLK, buf+size);
>  } else if (adev->powerplay.pp_funcs->print_clock_levels) {
>  size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
>  size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK, buf+size);
> diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> index 97d788451624..5f781a27cfb7 100644
> --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
> @@ -465,6 +465,12 @@ struct smu_context
>  uint32_t gfx_default_soft_max_freq;
>  uint32_t gfx_actual_hard_min_freq;
>  uint32_t gfx_actual_soft_max_freq;
> +
> +uint32_t cpu_default_hard_min_freq;
> +uint32_t cpu_default_soft_max_freq;
> +uint32_t cpu_actual_hard_min_freq;
> +uint32_t cpu_actual_soft_max_freq;
> +uint32_t cpu_core_id_select;
>  };
> 
>  struct i2c_adapter;
> diff --git a/drivers/gpu/drm/amd/pm/inc/smu_types.h b/drivers/gpu/drm/amd/pm/inc/smu_types.h
> index 8e428c728e0e..b76270e8767c 100644
> --- a/drivers/gpu/drm/amd/pm/inc/smu_types.h
> +++ b/drivers/gpu/drm/amd/pm/inc/smu_types.h
> @@ -237,6 +237,7 @@ enum smu_clk_type {
>  SMU_SCLK,
>  SMU_MCLK,
>  SMU_PCIE,
> +SMU_OD_CCLK,
>  SMU_OD_SCLK,
>  SMU_OD_MCLK,
>  SMU_OD_VDDC_CURVE,
> 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 63be82386964..4d02177cf9b0 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
> @@ -449,6 +449,15 @@ static int vangogh_print_fine_grain_clk(struct smu_context *smu,
>  (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq);
>  }
>  break;
> +case SMU_OD_CCLK:
> +if (smu->od_enabled) {
> +size = sprintf(buf, "CCLK_RANGE in Core%d:\n",  smu->cpu_core_id_select);
> +size += sprintf(buf + size, "0: %10uMhz\n",
> +(smu->cpu_actual_hard_min_freq > 0) ? smu->cpu_actual_hard_min_freq : smu->cpu_default_hard_min_freq);
> +size += sprintf(buf + size, "1: %10uMhz\n",
> +(smu->cpu_actual_soft_max_freq > 0) ? smu->cpu_actual_soft_max_freq : smu->cpu_default_soft_max_freq);
> +}
> +break;
>  case SMU_OD_RANGE:
> [Quan, Evan] The allowed frequency range for cclk should prompt user here in SMU_OD_RANGE.

I think about it again, we should not combine the fine grain and OD feature
together on the prints. APU doesn't support OD, it will make user confused.

Alternative, we can combine the fine grain prints both cpu and gfx together
here instead.

Thanks,
Ray

>  if (smu->od_enabled) {
>  size = sprintf(buf, "%s:\n", "OD_RANGE");
> @@ -1245,7 +1254,7 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu,
>  }
> 
>  static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type,
> -long input[], uint32_t size)
> +long input[], uint32_t size)
>  {
>  int ret = 0;
> 
> @@ -1255,6 +1264,34 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
>  }
> 
>  switch (type) {
> +case PP_OD_EDIT_CCLK_VDDC_TABLE:
> +if (size != 3) {
> +dev_err(smu->adev->dev, "Input parameter number not correct (should be 4 for processor)\n");
> +return -EINVAL;
> +}
> +if (input[0] >= boot_cpu_data.x86_max_cores) {
> +dev_err(smu->adev->dev, "core index is overflow, should be less than %d\n",
> +boot_cpu_data.x86_max_cores);
> +}
> +smu->cpu_core_id_select = input[0];
> +if (input[1] == 0) {
> +if (input[2] < smu->cpu_default_hard_min_freq) {
> +dev_warn(smu->adev->dev, "Fine grain setting minimum cclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
> +input[2], smu->cpu_default_hard_min_freq);
> +return -EINVAL;
> +}
> +smu->cpu_actual_hard_min_freq = input[2];
> +} else if (input[1] == 1) {
> +if (input[2] > smu->cpu_default_soft_max_freq) {
> +dev_warn(smu->adev->dev, "Fine grain setting maximum cclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
> +input[2], smu->cpu_default_soft_max_freq);
> +return -EINVAL;
> +}
> +smu->cpu_actual_soft_max_freq = input[2];
> +} else {
> +return -EINVAL;
> +}
> +break;
>  case PP_OD_EDIT_SCLK_VDDC_TABLE:
>  if (size != 2) {
>  dev_err(smu->adev->dev, "Input parameter number not correct\n");
> @@ -1286,6 +1323,8 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
>  } 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;
> +smu->cpu_actual_hard_min_freq = smu->cpu_default_hard_min_freq;
> +smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
> 
>  ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
>  smu->gfx_actual_hard_min_freq, NULL);
> @@ -1300,6 +1339,20 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
>  dev_err(smu->adev->dev, "Restore the default soft max sclk failed!");
>  return ret;
>  }
> +
> +ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinCclk,
> +      smu->cpu_actual_hard_min_freq, NULL);
> [Quan, Evan] better to name it as "soft_min_freq" instead of "hard_min_freq".
> +if (ret) {
> +dev_err(smu->adev->dev, "Set hard min cclk failed!");
> +return ret;
> +}
> +
> +ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxCclk,
> +      smu->cpu_actual_soft_max_freq, NULL);
> +if (ret) {
> +dev_err(smu->adev->dev, "Set soft max cclk failed!");
> +return ret;
> +}
>  }
>  break;
>  case PP_OD_COMMIT_DPM_TABLE:
> @@ -1326,6 +1379,24 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
>  dev_err(smu->adev->dev, "Set soft max sclk failed!");
>  return ret;
>  }
> +
> +ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinCclk,
> +      ((smu->cpu_core_id_select << 20)
> +       | smu->cpu_actual_hard_min_freq),
> +      NULL);
> +if (ret) {
> +dev_err(smu->adev->dev, "Set hard min cclk failed!");
> +return ret;
> +}
> +
> +ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxCclk,
> +      ((smu->cpu_core_id_select << 20)
> +       | smu->cpu_actual_soft_max_freq),
> +      NULL);
> +if (ret) {
> +dev_err(smu->adev->dev, "Set soft max cclk failed!");
> +return ret;
> +}
>  }
>  break;
>  default:
> @@ -1351,6 +1422,11 @@ static int vangogh_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
>  smu->gfx_actual_hard_min_freq = 0;
>  smu->gfx_actual_soft_max_freq = 0;
> 
> +smu->cpu_default_hard_min_freq = 1400;
> +smu->cpu_default_soft_max_freq = 3500;
> +smu->cpu_actual_hard_min_freq = 0;
> +smu->cpu_actual_soft_max_freq = 0;
> +
>  return 0;
>  }
> 
> --
> 2.25.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7Cevan.quan%40amd.com%7Ca1f6eb71deeb42ff36b708d8b3b338dc%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637456929634329975%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=nrUPCKEMCJqKBeGMjWfr7%2FCbuVaovJqC6AovtuRMtFk%3D&reserved=0


More information about the amd-gfx mailing list