Add cwsr_trap_obj to render file handle. It maps the first level cwsr
handler to the vm with which the file handle is associated. Use
cwsr trap object's tba/tma address for the userqueue.

Signed-off-by: Lijo Lazar <[email protected]>
Acked-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h   | 6 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    | 8 ++++++++
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 7 +++++++
 4 files changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0ace28c170bb..218d8030a07c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -329,6 +329,7 @@ struct amdgpu_hive_info;
 struct amdgpu_reset_context;
 struct amdgpu_reset_control;
 struct amdgpu_cwsr_isa;
+struct amdgpu_cwsr_trap_obj;
 
 enum amdgpu_cp_irq {
        AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP = 0,
@@ -449,6 +450,7 @@ struct amdgpu_fpriv {
        struct idr              bo_list_handles;
        struct amdgpu_ctx_mgr   ctx_mgr;
        struct amdgpu_userq_mgr userq_mgr;
+       struct amdgpu_cwsr_trap_obj *cwsr_trap;
 
        /* Eviction fence infra */
        struct amdgpu_eviction_fence_mgr evf_mgr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
index 96b03a8ed99b..b54240d40a6c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
@@ -79,4 +79,10 @@ uint32_t amdgpu_cwsr_size_needed(struct amdgpu_device *adev, 
int num_xcc);
 int amdgpu_cwsr_validate_params(struct amdgpu_device *adev,
                                struct amdgpu_cwsr_params *cwsr_params,
                                int num_xcc);
+static inline bool amdgpu_cwsr_has_dbg_wa(struct amdgpu_device *adev)
+{
+       uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
+
+       return gc_ver >= IP_VERSION(11, 0, 0) && gc_ver <= IP_VERSION(11, 0, 3);
+}
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 728033a88078..fed15a922346 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -46,6 +46,7 @@
 #include "amdgpu_reset.h"
 #include "amd_pcie.h"
 #include "amdgpu_userq.h"
+#include "amdgpu_cwsr.h"
 
 void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
 {
@@ -1512,6 +1513,12 @@ int amdgpu_driver_open_kms(struct drm_device *dev, 
struct drm_file *file_priv)
                         "Failed to init usermode queue manager (%d), use 
legacy workload submission only\n",
                         r);
 
+       if (amdgpu_cwsr_is_enabled(adev)) {
+               r = amdgpu_cwsr_alloc(adev, &fpriv->vm, &fpriv->cwsr_trap);
+               if (r)
+                       dev_dbg(adev->dev, "cwsr trap not enabled");
+       }
+
        r = amdgpu_eviction_fence_init(&fpriv->evf_mgr);
        if (r)
                goto error_vm;
@@ -1584,6 +1591,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
        }
 
        amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
+       amdgpu_cwsr_free(adev, &fpriv->vm, &fpriv->cwsr_trap);
        amdgpu_vm_fini(adev, &fpriv->vm);
 
        if (pasid)
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index f2309d72bbe6..27917614b1a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -26,6 +26,7 @@
 #include "amdgpu_gfx.h"
 #include "mes_userqueue.h"
 #include "amdgpu_userq_fence.h"
+#include "amdgpu_cwsr.h"
 
 #define AMDGPU_USERQ_PROC_CTX_SZ PAGE_SIZE
 #define AMDGPU_USERQ_GANG_CTX_SZ PAGE_SIZE
@@ -136,6 +137,7 @@ static int convert_to_mes_priority(int priority)
 static int mes_userq_map(struct amdgpu_usermode_queue *queue)
 {
        struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
+       struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr);
        struct amdgpu_device *adev = uq_mgr->adev;
        struct amdgpu_userq_obj *ctx = &queue->fw_obj;
        struct amdgpu_mqd_prop *userq_props = queue->userq_prop;
@@ -165,6 +167,11 @@ static int mes_userq_map(struct amdgpu_usermode_queue 
*queue)
        queue_input.doorbell_offset = userq_props->doorbell_index;
        queue_input.page_table_base_addr = 
amdgpu_gmc_pd_addr(queue->vm->root.bo);
        queue_input.wptr_mc_addr = queue->wptr_obj.gpu_addr;
+       if (fpriv->cwsr_trap) {
+               queue_input.tba_addr = fpriv->cwsr_trap->tba_gpu_va_addr;
+               queue_input.tma_addr = fpriv->cwsr_trap->tma_gpu_va_addr;
+               queue_input.trap_en = !amdgpu_cwsr_has_dbg_wa(adev);
+       }
 
        amdgpu_mes_lock(&adev->mes);
        r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
-- 
2.49.0

Reply via email to