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