support stream performance monitor.

Signed-off-by: James Zhu <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 10 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c | 72 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h |  6 +++
 3 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index eebad3378352..685ebbacf14a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -164,6 +164,15 @@ struct amdgpu_kiq {
        void                    *mqd_backup;
 };
 
+struct spm_funcs {
+       void (*start)(struct amdgpu_device *adev, int xcc_id);
+       void (*stop)(struct amdgpu_device *adev, int xcc_id);
+       void (*set_rdptr)(struct amdgpu_device *adev, int xcc_id, u32 rptr);
+       void (*set_spm_perfmon_ring_buf)(struct amdgpu_device *adev, int 
xcc_id, u64 gpu_rptr, u32 size);
+       /* Packet sizes */
+       int set_spm_config_size;
+};
+
 /*
  * GFX configurations
  */
@@ -416,6 +425,7 @@ struct amdgpu_gfx {
        struct amdgpu_mec_bitmap        mec_bitmap[AMDGPU_MAX_GC_INSTANCES];
        struct amdgpu_kiq               kiq[AMDGPU_MAX_GC_INSTANCES];
        struct amdgpu_imu               imu;
+       const struct spm_funcs          *spmfuncs;
        bool                            rs64_enable; /* firmware format */
        const struct firmware           *me_fw; /* ME firmware */
        uint32_t                        me_fw_version;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
index 5aa830a02d80..08d62183b2e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c
@@ -548,3 +548,75 @@ int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device 
*adev,
 
        return 0;
 }
+
+void amdgpu_rlc_spm_cntl(struct amdgpu_device *adev, int xcc_id, bool cntl)
+{
+       struct amdgpu_ring *kiq_ring = &adev->gfx.kiq[xcc_id].ring;
+
+       spin_lock(&adev->gfx.kiq[xcc_id].ring_lock);
+       amdgpu_ring_alloc(kiq_ring, adev->gfx.spmfuncs->set_spm_config_size);
+       if (cntl)
+               adev->gfx.spmfuncs->start(adev, xcc_id);
+       else
+               adev->gfx.spmfuncs->stop(adev, xcc_id);
+       amdgpu_ring_commit(kiq_ring);
+       spin_unlock(&adev->gfx.kiq[xcc_id].ring_lock);
+}
+
+void amdgpu_rlc_spm_set_rdptr(struct amdgpu_device *adev, int xcc_id, u32 rptr)
+{
+       struct amdgpu_ring *kiq_ring = &adev->gfx.kiq[xcc_id].ring;
+
+       spin_lock(&adev->gfx.kiq[xcc_id].ring_lock);
+       amdgpu_ring_alloc(kiq_ring, adev->gfx.spmfuncs->set_spm_config_size);
+       adev->gfx.spmfuncs->set_rdptr(adev, xcc_id, rptr);
+       amdgpu_ring_commit(kiq_ring);
+       spin_unlock(&adev->gfx.kiq[xcc_id].ring_lock);
+}
+
+int amdgpu_rlc_spm_acquire(struct amdgpu_device *adev, int xcc_id,
+                       struct amdgpu_vm *vm, u64 gpu_addr, u32 size)
+{
+       struct amdgpu_ring *kiq_ring = &adev->gfx.kiq[xcc_id].ring;
+       int r = 0;
+
+       if (!adev->gfx.rlc.funcs->update_spm_vmid)
+               return -EINVAL;
+
+       r = amdgpu_vmid_alloc_reserved(adev, vm, AMDGPU_GFXHUB(0));
+       if (r)
+               return r;
+
+       /* init spm vmid with 0x0 */
+       adev->gfx.rlc.funcs->update_spm_vmid(adev, xcc_id, NULL, 0);
+
+       /* set spm ring registers */
+       spin_lock(&adev->gfx.kiq[xcc_id].ring_lock);
+       amdgpu_ring_alloc(kiq_ring, adev->gfx.spmfuncs->set_spm_config_size);
+       adev->gfx.spmfuncs->set_spm_perfmon_ring_buf(adev, xcc_id, gpu_addr, 
size);
+       amdgpu_ring_commit(kiq_ring);
+       spin_unlock(&adev->gfx.kiq[xcc_id].ring_lock);
+       return r;
+}
+
+void amdgpu_rlc_spm_release(struct amdgpu_device *adev, int xcc_id, struct 
amdgpu_vm *vm)
+{
+       struct amdgpu_ring *kiq_ring = &adev->gfx.kiq[xcc_id].ring;
+
+       /* stop spm stream and interrupt */
+       spin_lock(&adev->gfx.kiq[xcc_id].ring_lock);
+       amdgpu_ring_alloc(kiq_ring, adev->gfx.spmfuncs->set_spm_config_size);
+       adev->gfx.spmfuncs->stop(adev, xcc_id);
+       amdgpu_ring_commit(kiq_ring);
+       spin_unlock(&adev->gfx.kiq[xcc_id].ring_lock);
+
+       /* revert spm vmid with 0xf */
+       if (adev->gfx.rlc.funcs->update_spm_vmid)
+               adev->gfx.rlc.funcs->update_spm_vmid(adev, xcc_id, NULL, 0xf);
+}
+
+void amdgpu_rlc_spm_interrupt(struct amdgpu_device *adev, int xcc_id)
+{
+       if (adev->kfd.dev)
+               return; /* TODO: */
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
index 3e2d2e333907..b526f256ad30 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
@@ -361,4 +361,10 @@ void amdgpu_gfx_rlc_fini(struct amdgpu_device *adev);
 int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,
                                  uint16_t version_major,
                                  uint16_t version_minor);
+void amdgpu_rlc_spm_cntl(struct amdgpu_device *adev, int xcc_id, bool cntl);
+int amdgpu_rlc_spm_acquire(struct amdgpu_device *adev, int xcc_id,
+               struct amdgpu_vm *vm, u64 gpu_addr, u32 size);
+void amdgpu_rlc_spm_release(struct amdgpu_device *adev, int xcc_id, struct 
amdgpu_vm *vm);
+void amdgpu_rlc_spm_set_rdptr(struct amdgpu_device *adev, int xcc_id, u32 
rptr);
+void amdgpu_rlc_spm_interrupt(struct amdgpu_device *adev, int xcc_id);
 #endif
-- 
2.34.1

Reply via email to