RE: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that accepts buffer base and write offset

2022-01-23 Thread Quan, Evan
[AMD Official Use Only]



> -Original Message-
> From: Powell, Darren 
> Sent: Saturday, January 22, 2022 11:47 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Powell, Darren 
> Subject: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that
> accepts buffer base and write offset
> 
>(v1)
>  - new power management function emit_clk_levels implemented by
> navi10_emit_clk_levels()
>This function currently duplicates the functionality of
> navi10_print_clk_levels, where
>snprintf is used write to the sysfs buffer. The first implementation 
> to use
> sysfs_emit
>was unsuccessful due to requirement that buf must be aligned to a
> specific memory
>boundary. This solution passes the buffer base and write offset down 
> the
> stack.
>  - new power management function emit_clock_levels implemented by
> smu_emit_ppclk_levels()
>This function combines implementation of smu_print_ppclk_levels and
>smu_print_smuclk_levels and calls emit_clk_levels
>  - new helper function smu_convert_to_smuclk called by
> smu_print_ppclk_levels and
>smu_emit_ppclk_levels
>  - emit_clock_levels currently returns the length of the string written to the
> buffer,
>maintaining the behaviour of print_clock_levels, but will be upgraded 
> to
> return
>error values in a subsequent patch
>  - failure of the emit_clock_levels at the top level
> (amdgpu_get_pp_dpm_clock) triggers a
>fallback to the print_clock_levels, which can be removed after
> emit_clock_levels is
>implemented across all platforms.
> 
>(v2)
>   Update to apply on commit 801771de03
>   adjust printing of empty carriage return only if size == 0
> 
>  == Test ==
>  LOGFILE=pp_clk.test.log
>  AMDGPU_PCI_ADDR=`lspci -nn | grep "VGA\|Display" | cut -d " " -f 1`
>  AMDGPU_HWMON=`ls -la /sys/class/hwmon | grep $AMDGPU_PCI_ADDR |
> awk '{print $9}'`
>  HWMON_DIR=/sys/class/hwmon/${AMDGPU_HWMON}
> 
>  lspci -nn | grep "VGA\|Display"  > $LOGFILE
>  FILES="pp_od_clk_voltage
>  pp_dpm_sclk
>  pp_dpm_mclk
>  pp_dpm_pcie
>  pp_dpm_socclk
>  pp_dpm_fclk
>  pp_dpm_dcefclk
>  pp_dpm_vclk
>  pp_dpm_dclk "
> 
>  for f in $FILES
>  do
>echo === $f === >> $LOGFILE
>cat $HWMON_DIR/device/$f >> $LOGFILE
>  done
>  cat $LOGFILE
> 
> Signed-off-by: Darren Powell 
> ---
>  .../gpu/drm/amd/include/kgd_pp_interface.h|   1 +
>  drivers/gpu/drm/amd/pm/amdgpu_dpm.c   |  21 ++
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c|  11 +-
>  drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h   |   4 +
>  drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c |  46 -
>  drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  10 +
>  .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c   | 189
> ++
>  7 files changed, 273 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index a8eec91c0995..8a8eb9411cdf 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -321,6 +321,7 @@ struct amd_pm_funcs {
>   int (*get_fan_speed_pwm)(void *handle, u32 *speed);
>   int (*force_clock_level)(void *handle, enum pp_clock_type type,
> uint32_t mask);
>   int (*print_clock_levels)(void *handle, enum pp_clock_type type,
> char *buf);
> + int (*emit_clock_levels)(void *handle, enum pp_clock_type type,
> char *buf, int *offset);
>   int (*force_performance_level)(void *handle, enum
> amd_dpm_forced_level level);
>   int (*get_sclk_od)(void *handle);
>   int (*set_sclk_od)(void *handle, uint32_t value);
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> index 728b6e10f302..e45578124928 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
> @@ -906,6 +906,27 @@ int amdgpu_dpm_print_clock_levels(struct
> amdgpu_device *adev,
>   return ret;
>  }
> 
> +int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev,
> +   enum pp_clock_type type,
> +   char *buf,
> +   int *offset)
> +{
> + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
> + int ret = 0;
> +
> + if (!pp_funcs->emit_clock_levels)
> + return 0;
> +
> + mutex_lock(>pm.mutex);
> + ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
> +type,
> +buf,
> +offset);
> + mutex_unlock(>pm.mutex);
> +
> + return ret;
> +}
> +
>  int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
>   uint64_t ppfeature_masks)
>  {
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index d2823aaeca09..ec2729b3930e 100644
> --- 

RE: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that accepts buffer base and write offset

2021-12-09 Thread Quan, Evan
[AMD Official Use Only]



> -Original Message-
> From: amd-gfx  On Behalf Of
> Darren Powell
> Sent: Wednesday, December 8, 2021 2:36 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Powell, Darren 
> Subject: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that
> accepts buffer base and write offset
> 
>  - new power management function emit_clk_levels implemented by
> navi10_emit_clk_levels()
>This function currently duplicates the functionality of
> navi10_print_clk_levels, where
>snprintf is used write to the sysfs buffer. The first implementation 
> to use
> sysfs_emit
>was unsuccessful due to requirement that buf must be aligned to a
> specific memory
>boundary. This solution passes the buffer base and write offset down 
> the
> stack.
>  - new power management function emit_clock_levels implemented by
> smu_emit_ppclk_levels()
>This function combines implementation of smu_print_ppclk_levels and
>smu_print_smuclk_levels and calls emit_clk_levels
>  - new helper function smu_convert_to_smuclk called by
> smu_print_ppclk_levels and
>smu_emit_ppclk_levels
>  - emit_clock_levels currently returns the length of the string written to the
> buffer,
>maintaining the behaviour of print_clock_levels, but will be upgraded 
> to
> return
>error values in a subsequent patch
>  - failure of the emit_clock_levels at the top level
> (amdgpu_get_pp_dpm_clock) triggers a
>fallback to the print_clock_levels, which can be removed after
> emit_clock_levels is
>implemented across all platforms.
> 
>  == Test ==
>  LOGFILE=pp_clk.test.log
>  AMDGPU_PCI_ADDR=`lspci -nn | grep "VGA\|Display" | cut -d " " -f 1`
>  AMDGPU_HWMON=`ls -la /sys/class/hwmon | grep $AMDGPU_PCI_ADDR |
> awk '{print $9}'`
>  HWMON_DIR=/sys/class/hwmon/${AMDGPU_HWMON}
> 
>  lspci -nn | grep "VGA\|Display"  > $LOGFILE
>  FILES="pp_od_clk_voltage
>  pp_dpm_sclk
>  pp_dpm_mclk
>  pp_dpm_pcie
>  pp_dpm_socclk
>  pp_dpm_fclk
>  pp_dpm_dcefclk
>  pp_dpm_vclk
>  pp_dpm_dclk "
> 
>  for f in $FILES
>  do
>echo === $f === >> $LOGFILE
>cat $HWMON_DIR/device/$f >> $LOGFILE
>  done
>  cat $LOGFILE
> 
> Signed-off-by: Darren Powell 
> ---
>  .../gpu/drm/amd/include/kgd_pp_interface.h|   1 +
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c|  20 +-
>  drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h   |   3 +
>  drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h   |  10 +
>  drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c |  50 -
>  .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c   | 189
> ++
>  6 files changed, 262 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index bac15c466733..43f43a4f321b 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -310,6 +310,7 @@ struct amd_pm_funcs {
>   int (*get_fan_speed_pwm)(void *handle, u32 *speed);
>   int (*force_clock_level)(void *handle, enum pp_clock_type type,
> uint32_t mask);
>   int (*print_clock_levels)(void *handle, enum pp_clock_type type,
> char *buf);
> + int (*emit_clock_levels)(void *handle, enum pp_clock_type type,
> char *buf, int *offset);
>   int (*force_performance_level)(void *handle, enum
> amd_dpm_forced_level level);
>   int (*get_sclk_od)(void *handle);
>   int (*set_sclk_od)(void *handle, uint32_t value);
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index 49df4c20f09e..a1169a2397ca 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -1056,8 +1056,8 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct
> device *dev,
>  {
>   struct drm_device *ddev = dev_get_drvdata(dev);
>   struct amdgpu_device *adev = drm_to_adev(ddev);
> - ssize_t size;
> - int ret;
> + int size = 0;
> + int ret = 0;
> 
>   if (amdgpu_in_reset(adev))
>   return -EPERM;
> @@ -1070,10 +1070,18 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct
> device *dev,
>   return ret;
>   }
> 
> - if (adev->powerplay.pp_funcs->print_clock_levels)
> - size = amdgpu_dpm_print_clock_levels(adev, type, buf);
> - else
> - size = sysfs_emit(buf, "\n");
> + ret = -EOPNOTSUPP;
> + if (adev->powerplay.pp_funcs->emit_clock_levels) {
> + ret = amdgpu_dpm_emit_clock_levels(adev, type, buf,
> );
> + }
The whole idea seems fine to me. However, we are trying to do some cleanups to 
avoid spiking into power internals(as above via 
adev->powerplay.pp_funcs->emit_clock_levels).
Check the patch series below:
https://lists.freedesktop.org/archives/amd-gfx/2021-December/072096.html
So, it would be better if you can rebase the patches here based on that. Or you 
can wait a while to let me land them first.

BR
Evan
> +
> + if (ret < 0) {
> + if 

Re: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that accepts buffer base and write offset

2021-12-09 Thread Powell, Darren
[AMD Official Use Only]

> The whole idea seems fine to me. However, we are trying to do some cleanups 
> to avoid spiking into power internals(as above via 
> adev->powerplay.pp_funcs->emit_clock_levels).
> Check the patch series below:
> https://lists.freedesktop.org/archives/amd-gfx/2021-December/072096.html
> So, it would be better if you can rebase the patches here based on that. Or 
> you can wait a while to let me land them first.

> BR
> Evan

I can wait for it to land and rebase then, will send v2 of series once this 
happens
Darren


From: Quan, Evan 
Sent: Wednesday, December 8, 2021 8:48 PM
To: Powell, Darren ; amd-gfx@lists.freedesktop.org 

Cc: Powell, Darren 
Subject: RE: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that 
accepts buffer base and write offset

[AMD Official Use Only]



> -Original Message-
> From: amd-gfx  On Behalf Of
> Darren Powell
> Sent: Wednesday, December 8, 2021 2:36 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Powell, Darren 
> Subject: [PATCH 1/3] amdgpu/pm: Implement new API function "emit" that
> accepts buffer base and write offset
>
>  - new power management function emit_clk_levels implemented by
> navi10_emit_clk_levels()
>This function currently duplicates the functionality of
> navi10_print_clk_levels, where
>snprintf is used write to the sysfs buffer. The first implementation 
> to use
> sysfs_emit
>was unsuccessful due to requirement that buf must be aligned to a
> specific memory
>boundary. This solution passes the buffer base and write offset down 
> the
> stack.
>  - new power management function emit_clock_levels implemented by
> smu_emit_ppclk_levels()
>This function combines implementation of smu_print_ppclk_levels and
>smu_print_smuclk_levels and calls emit_clk_levels
>  - new helper function smu_convert_to_smuclk called by
> smu_print_ppclk_levels and
>smu_emit_ppclk_levels
>  - emit_clock_levels currently returns the length of the string written to the
> buffer,
>maintaining the behaviour of print_clock_levels, but will be upgraded 
> to
> return
>error values in a subsequent patch
>  - failure of the emit_clock_levels at the top level
> (amdgpu_get_pp_dpm_clock) triggers a
>fallback to the print_clock_levels, which can be removed after
> emit_clock_levels is
>implemented across all platforms.
>
>  == Test ==
>  LOGFILE=pp_clk.test.log
>  AMDGPU_PCI_ADDR=`lspci -nn | grep "VGA\|Display" | cut -d " " -f 1`
>  AMDGPU_HWMON=`ls -la /sys/class/hwmon | grep $AMDGPU_PCI_ADDR |
> awk '{print $9}'`
>  HWMON_DIR=/sys/class/hwmon/${AMDGPU_HWMON}
>
>  lspci -nn | grep "VGA\|Display"  > $LOGFILE
>  FILES="pp_od_clk_voltage
>  pp_dpm_sclk
>  pp_dpm_mclk
>  pp_dpm_pcie
>  pp_dpm_socclk
>  pp_dpm_fclk
>  pp_dpm_dcefclk
>  pp_dpm_vclk
>  pp_dpm_dclk "
>
>  for f in $FILES
>  do
>echo === $f === >> $LOGFILE
>cat $HWMON_DIR/device/$f >> $LOGFILE
>  done
>  cat $LOGFILE
>
> Signed-off-by: Darren Powell 
> ---
>  .../gpu/drm/amd/include/kgd_pp_interface.h|   1 +
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c|  20 +-
>  drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h   |   3 +
>  drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h   |  10 +
>  drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c |  50 -
>  .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c   | 189
> ++
>  6 files changed, 262 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> index bac15c466733..43f43a4f321b 100644
> --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
> @@ -310,6 +310,7 @@ struct amd_pm_funcs {
>int (*get_fan_speed_pwm)(void *handle, u32 *speed);
>int (*force_clock_level)(void *handle, enum pp_clock_type type,
> uint32_t mask);
>int (*print_clock_levels)(void *handle, enum pp_clock_type type,
> char *buf);
> + int (*emit_clock_levels)(void *handle, enum pp_clock_type type,
> char *buf, int *offset);
>int (*force_performance_level)(void *handle, enum
> amd_dpm_forced_level level);
>int (*get_sclk_od)(void *handle);
>int (*set_sclk_od)(void *handle, uint32_t value);
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index 49df4c20f09e..a1169a2397ca 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -1056,8 +1056,8 @@ static ssize_t amdgpu_get_pp_dpm_cloc