On Thu, Feb 5, 2026 at 2:02 AM Perry Yuan <[email protected]> wrote:
>
> Separate the PTL (Peak Tops Limiter) control logic into a stable public
> API layer and an internal implementation layer.
>
> v2: revise commit info
>
> Signed-off-by: Perry Yuan <[email protected]>
> Suggested-by: Alex Deucher <[email protected]>
> Reviewed-by: Yifan Zhang <[email protected]>
Would be nice to re-generate the patches with this squashed in earlier
in the series.
Alex
> ---
> .../drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c | 2 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 77 +++++++++++--------
> drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 2 +-
> drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 2 +-
> 4 files changed, 48 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
> index f491fd2e4ed9..74eb57332e07 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
> @@ -526,7 +526,7 @@ static uint32_t kgd_v9_4_3_ptl_ctrl(struct amdgpu_device
> *adev,
> enum amdgpu_ptl_fmt *fmt1,
> enum amdgpu_ptl_fmt *fmt2)
> {
> - return psp_performance_monitor_hw(&adev->psp, cmd,
> + return amdgpu_ptl_perf_monitor_ctrl(adev, cmd,
> ptl_state, fmt1, fmt2);
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> index 982494abbf1d..f0b1157d7a21 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> @@ -1239,48 +1239,25 @@ static int psp_ptl_fmt_verify(struct psp_context
> *psp, enum amdgpu_ptl_fmt fmt,
> return 0;
> }
>
> -int psp_performance_monitor_hw(struct psp_context *psp, u32 req_code,
> - uint32_t *ptl_state, uint32_t *fmt1, uint32_t
> *fmt2)
> +static int psp_ptl_invoke(struct psp_context *psp, u32 req_code,
> + uint32_t *ptl_state, uint32_t *fmt1, uint32_t *fmt2)
> {
> struct psp_gfx_cmd_resp *cmd;
> - uint32_t ptl_fmt1, ptl_fmt2;
> int ret;
>
> - if (!psp || !ptl_state || !fmt1 || !fmt2)
> - return -EINVAL;
> -
> - if (amdgpu_sriov_vf(psp->adev))
> - return 0;
> -
> - if (amdgpu_ip_version(psp->adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4) ||
> - psp->sos.fw_version < 0x0036081a)
> - return -EOPNOTSUPP;
> -
> - if (psp_ptl_fmt_verify(psp, *fmt1, &ptl_fmt1) ||
> - psp_ptl_fmt_verify(psp, *fmt2, &ptl_fmt2))
> - return -EINVAL;
> -
> - /*
> - * Add check to skip if state and formats are identical to current
> ones
> - */
> - if (req_code == PSP_PTL_PERF_MON_SET &&
> - psp->ptl_enabled == *ptl_state &&
> - psp->ptl_fmt1 == ptl_fmt1 &&
> - psp->ptl_fmt2 == ptl_fmt2)
> - return 0;
> -
> cmd = acquire_psp_cmd_buf(psp);
>
> cmd->cmd_id = GFX_CMD_ID_PERF_HW;
> cmd->cmd.cmd_req_perf_hw.req = req_code;
> cmd->cmd.cmd_req_perf_hw.ptl_state = *ptl_state;
> - cmd->cmd.cmd_req_perf_hw.pref_format1 = ptl_fmt1;
> - cmd->cmd.cmd_req_perf_hw.pref_format2 = ptl_fmt2;
> + cmd->cmd.cmd_req_perf_hw.pref_format1 = *fmt1;
> + cmd->cmd.cmd_req_perf_hw.pref_format2 = *fmt2;
>
> ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
> if (ret)
> goto out;
>
> + /* Parse response */
> switch (req_code) {
> case PSP_PTL_PERF_MON_QUERY:
> *ptl_state = cmd->resp.uresp.perf_hw_info.ptl_state;
> @@ -1288,9 +1265,10 @@ int psp_performance_monitor_hw(struct psp_context
> *psp, u32 req_code,
> *fmt2 = cmd->resp.uresp.perf_hw_info.pref_format2;
> break;
> case PSP_PTL_PERF_MON_SET:
> + /* Update cached state only on success */
> psp->ptl_enabled = *ptl_state;
> - psp->ptl_fmt1 = ptl_fmt1;
> - psp->ptl_fmt2 = ptl_fmt2;
> + psp->ptl_fmt1 = *fmt1;
> + psp->ptl_fmt2 = *fmt2;
> break;
> }
>
> @@ -1299,6 +1277,41 @@ int psp_performance_monitor_hw(struct psp_context
> *psp, u32 req_code,
> return ret;
> }
>
> +int amdgpu_ptl_perf_monitor_ctrl(struct amdgpu_device *adev, u32 req_code,
> + uint32_t *ptl_state, uint32_t *fmt1, uint32_t *fmt2)
> +{
> + uint32_t ptl_fmt1, ptl_fmt2;
> + struct psp_context *psp;
> +
> + if (!adev || !ptl_state || !fmt1 || !fmt2)
> + return -EINVAL;
> +
> + if (amdgpu_sriov_vf(adev))
> + return 0;
> +
> + psp = &adev->psp;
> +
> + if (amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4) ||
> + psp->sos.fw_version < 0x0036081a)
> + return -EOPNOTSUPP;
> +
> + /* Verify formats */
> + if (psp_ptl_fmt_verify(psp, *fmt1, &ptl_fmt1) ||
> + psp_ptl_fmt_verify(psp, *fmt2, &ptl_fmt2))
> + return -EINVAL;
> +
> + /*
> + * Add check to skip if state and formats are identical to current
> ones
> + */
> + if (req_code == PSP_PTL_PERF_MON_SET &&
> + psp->ptl_enabled == *ptl_state &&
> + psp->ptl_fmt1 == ptl_fmt1 &&
> + psp->ptl_fmt2 == ptl_fmt2)
> + return 0;
> +
> + return psp_ptl_invoke(psp, req_code, ptl_state, &ptl_fmt1, &ptl_fmt2);
> +}
> +
> static enum amdgpu_ptl_fmt str_to_ptl_fmt(const char *str)
> {
> int i;
> @@ -1356,7 +1369,7 @@ static ssize_t ptl_enable_store(struct device *dev,
> return count;
> }
>
> - ret = psp_performance_monitor_hw(psp, PSP_PTL_PERF_MON_SET,
> &ptl_state, &fmt1, &fmt2);
> + ret = amdgpu_ptl_perf_monitor_ctrl(adev, PSP_PTL_PERF_MON_SET,
> &ptl_state, &fmt1, &fmt2);
> if (ret) {
> dev_err(adev->dev, "Failed to set PTL err = %d\n", ret);
> mutex_unlock(&psp->ptl_mutex);
> @@ -1412,7 +1425,7 @@ static ssize_t ptl_format_store(struct device *dev,
> ptl_state = psp->ptl_enabled;
> fmt1 = fmt1_enum;
> fmt2 = fmt2_enum;
> - ret = psp_performance_monitor_hw(psp, PSP_PTL_PERF_MON_SET,
> &ptl_state, &fmt1, &fmt2);
> + ret = amdgpu_ptl_perf_monitor_ctrl(adev, PSP_PTL_PERF_MON_SET,
> &ptl_state, &fmt1, &fmt2);
> if (ret) {
> dev_err(adev->dev, "Failed to update PTL err = %d\n", ret);
> mutex_unlock(&psp->ptl_mutex);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> index 1ab7255718df..711f15d21940 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> @@ -662,7 +662,7 @@ void amdgpu_psp_debugfs_init(struct amdgpu_device *adev);
> int amdgpu_psp_get_fw_type(struct amdgpu_firmware_info *ucode,
> enum psp_gfx_fw_type *type);
>
> -int psp_performance_monitor_hw(struct psp_context *psp, u32 req_code,
> +int amdgpu_ptl_perf_monitor_ctrl(struct amdgpu_device *adev, u32 req_code,
> u32 *ptl_state, u32 *fmt1, u32 *fmt2);
> int amdgpu_ptl_sysfs_init(struct amdgpu_device *adev);
> void amdgpu_ptl_sysfs_fini(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> index 472e2f41fed2..1682adb1231f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
> @@ -2388,7 +2388,7 @@ static int gfx_v9_4_3_perf_monitor_ptl_init(struct
> amdgpu_device *adev, bool sta
> }
>
> /* initialize PTL with default formats: GFX_FTYPE_I8 & GFX_FTYPE_BF16
> */
> - r = psp_performance_monitor_hw(&adev->psp, PSP_PTL_PERF_MON_SET,
> &ptl_state,
> + r = amdgpu_ptl_perf_monitor_ctrl(adev, PSP_PTL_PERF_MON_SET,
> &ptl_state,
> &fmt1, &fmt2);
> if (r)
> return r;
> --
> 2.34.1
>