Can be called from KGD.
Signed-off-by: Alex Deucher <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 14 +++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 16 ++++++++++++-
drivers/gpu/drm/amd/amdkfd/kfd_device.c | 24 +++++++++++++++++++
.../drm/amd/amdkfd/kfd_device_queue_manager.c | 11 +++++++++
.../drm/amd/amdkfd/kfd_device_queue_manager.h | 2 ++
5 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 0017d502d1692..ffd059089c56e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -942,3 +942,17 @@ int amdgpu_amdkfd_config_sq_perfmon(struct amdgpu_device
*adev, uint32_t xcp_id,
return r;
}
+
+/* Reset an MES queue */
+int amdgpu_amdkfd_reset_mes_queue(struct amdgpu_device *adev,
+ uint32_t node_id,
+ int queue_type,
+ int pipe, int queue,
+ unsigned int db)
+{
+ if (!adev->kfd.init_complete)
+ return 0;
+
+ return kgd2kfd_reset_mes_queue(adev->kfd.dev, node_id, queue_type,
+ pipe, queue, db);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 5333e052d56db..d403af5fb5526 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -275,7 +275,11 @@ int amdgpu_amdkfd_stop_sched(struct amdgpu_device *adev,
uint32_t node_id);
int amdgpu_amdkfd_config_sq_perfmon(struct amdgpu_device *adev, uint32_t
xcp_id,
bool core_override_enable, bool reg_override_enable, bool
perfmon_override_enable);
bool amdgpu_amdkfd_compute_active(struct amdgpu_device *adev, uint32_t
node_id);
-
+int amdgpu_amdkfd_reset_mes_queue(struct amdgpu_device *adev,
+ uint32_t node_id,
+ int queue_type,
+ int pipe, int queue,
+ unsigned int db);
/* Read user wptr from a specified user address space with page fault
* disabled. The memory must be pinned and mapped to the hardware when
@@ -446,6 +450,9 @@ bool kgd2kfd_vmfault_fast_path(struct amdgpu_device *adev,
struct amdgpu_iv_entr
bool retry_fault);
void kgd2kfd_lock_kfd(void);
void kgd2kfd_teardown_processes(struct amdgpu_device *adev);
+int kgd2kfd_reset_mes_queue(struct kfd_dev *kfd, uint32_t node_id,
+ int queue_type, int pipe, int queue,
+ unsigned int db);
#else
static inline int kgd2kfd_init(void)
@@ -576,5 +583,12 @@ static inline void kgd2kfd_teardown_processes(struct
amdgpu_device *adev)
{
}
+static inline int kgd2kfd_reset_mes_queue(struct kfd_dev *kfd, uint32_t
node_id,
+ int queue_type, int pipe, int queue,
+ unsigned int db)
+{
+ return 0;
+}
+
#endif
#endif /* AMDGPU_AMDKFD_H_INCLUDED */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 9e77c4a842ef7..e87e1b78ca421 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -1793,6 +1793,30 @@ void kgd2kfd_teardown_processes(struct amdgpu_device
*adev)
cond_resched();
}
+int kgd2kfd_reset_mes_queue(struct kfd_dev *kfd, uint32_t node_id,
+ int queue_type, int pipe, int queue,
+ unsigned int db)
+{
+ struct kfd_node *node;
+ int ret;
+
+ if (!kfd->init_complete)
+ return 0;
+
+ if (node_id >= kfd->num_nodes) {
+ dev_warn(kfd->adev->dev, "Invalid node ID: %u exceeds %u\n",
+ node_id, kfd->num_nodes - 1);
+ return -EINVAL;
+ }
+ node = kfd->nodes[node_id];
+
+ ret = kfd_reset_queue_mes(node->dqm, queue_type, pipe, queue, db);
+ if (ret)
+ dev_err(kfd_device, "Error resetting queue\n");
+
+ return ret;
+}
+
#if defined(CONFIG_DEBUG_FS)
/* This function will send a package to HIQ to hang the HWS
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 0a59a79ee28be..babf53b7b1bb2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -433,6 +433,17 @@ static int reset_queue_mes(struct device_queue_manager
*dqm, struct queue *q,
return 0;
}
+int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type,
+ int pipe, int queue, unsigned int db)
+{
+ struct queue *q;
+
+ q = find_queue_by_doorbell_offset(dqm, db);
+ if (!q)
+ return 0;
+ return reset_queue_mes(dqm, q, queue_type, pipe, queue, db);
+}
+
static int reset_queues_mes(struct device_queue_manager *dqm)
{
struct amdgpu_device *adev = (struct amdgpu_device *)dqm->dev->adev;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index e0b6a47e7722b..2229f8b2f4462 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -333,6 +333,8 @@ int debug_refresh_runlist(struct device_queue_manager *dqm);
bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm,
struct qcm_process_device *qpd,
int doorbell_off, u32 *queue_format);
+int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type,
+ int pipe, int queue, unsigned int db);
static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
{
--
2.54.0