Implement trigger pc sampling trap for gfx v9.

Signed-off-by: James Zhu <james....@amd.com>
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 36 +++++++++++++++++++
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h |  7 ++++
 2 files changed, 43 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
index 5a35a8ca8922..7d8c0e13ac12 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -1144,6 +1144,42 @@ void kgd_gfx_v9_program_trap_handler_settings(struct 
amdgpu_device *adev,
        kgd_gfx_v9_unlock_srbm(adev, inst);
 }
 
+uint32_t kgd_gfx_v9_trigger_pc_sample_trap(struct amdgpu_device *adev,
+                                           uint32_t vmid,
+                                           uint32_t max_wave_slot,
+                                           uint32_t max_simd,
+                                           uint32_t *target_simd,
+                                           uint32_t *target_wave_slot,
+                                           enum kfd_ioctl_pc_sample_method 
method)
+{
+       if (method == KFD_IOCTL_PCS_METHOD_HOSTTRAP) {
+               uint32_t value = 0;
+
+               value = REG_SET_FIELD(value, SQ_CMD, CMD, SQ_IND_CMD_CMD_TRAP);
+               value = REG_SET_FIELD(value, SQ_CMD, MODE, 
SQ_IND_CMD_MODE_SINGLE);
+
+               /* select *target_simd */
+               value = REG_SET_FIELD(value, SQ_CMD, SIMD_ID, *target_simd);
+               /* select *target_wave_slot */
+               value = REG_SET_FIELD(value, SQ_CMD, WAVE_ID, 
(*target_wave_slot)++);
+
+               mutex_lock(&adev->grbm_idx_mutex);
+               amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 
0xFFFFFFFF, 0);
+               WREG32_SOC15(GC, 0, mmSQ_CMD, value);
+               mutex_unlock(&adev->grbm_idx_mutex);
+
+               *target_wave_slot %= max_wave_slot;
+               if (!(*target_wave_slot)) {
+                       (*target_simd)++;
+                       *target_simd %= max_simd;
+               }
+       } else {
+               pr_debug("PC Sampling method %d not supported.", method);
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
 const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
        .program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
        .set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
index ce424615f59b..b47b926891a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
@@ -101,3 +101,10 @@ void kgd_gfx_v9_build_grace_period_packet_info(struct 
amdgpu_device *adev,
                                               uint32_t grace_period,
                                               uint32_t *reg_offset,
                                               uint32_t *reg_data);
+uint32_t kgd_gfx_v9_trigger_pc_sample_trap(struct amdgpu_device *adev,
+                                           uint32_t vmid,
+                                           uint32_t max_wave_slot,
+                                           uint32_t max_simd,
+                                           uint32_t *target_simd,
+                                           uint32_t *target_wave_slot,
+                                           enum kfd_ioctl_pc_sample_method 
method);
-- 
2.25.1

Reply via email to