From: Lijo Lazar <[email protected]>

Initialize the CWSR handler during device initialization and release
the associated resources during device teardown.

Add a per-file CWSR trap object for render-node user queues and map the
first-level CWSR trap handler into the GPUVM associated with the file.
Use the mapped TBA and TMA addresses when programming user queues.

Signed-off-by: Lijo Lazar <[email protected]>
Change-Id: I35b7007318a467bf391460cc42414eb808d512cf
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h   |  6 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  8 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    | 10 ++++++++
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 29 +++++++++++++++++-----
 5 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 26561a4f4db8..bdd55ac5b06e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -333,6 +333,7 @@ struct amdgpu_reset_control;
 struct amdgpu_coredump_info;
 struct amdgpu_video_codecs;
 struct amdgpu_cwsr_isa;
+struct amdgpu_cwsr_trap_obj;
 
 enum amdgpu_cp_irq {
        AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP = 0,
@@ -421,6 +422,7 @@ struct amdgpu_fpriv {
        struct xarray           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 7f922559e297..5717e1d662fc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
@@ -78,4 +78,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_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index e0014611f039..5a7f111763bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -81,6 +81,7 @@
 #include "amdgpu_reset.h"
 #include "amdgpu_virt.h"
 #include "amdgpu_dev_coredump.h"
+#include "amdgpu_cwsr.h"
 
 #include <linux/suspend.h>
 #include <drm/task_barrier.h>
@@ -2549,6 +2550,12 @@ static int amdgpu_device_ip_init(struct amdgpu_device 
*adev)
 
        r = amdgpu_cper_init(adev);
 
+       if (!r) {
+               r = amdgpu_cwsr_init(adev);
+               if (r == -EOPNOTSUPP)
+                       r = 0;
+       }
+
 init_failed:
 
        return r;
@@ -2946,6 +2953,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device 
*adev)
 {
        int i, r;
 
+       amdgpu_cwsr_fini(adev);
        amdgpu_cper_fini(adev);
 
        if (amdgpu_sriov_vf(adev) && adev->virt.ras_init_done)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index f34150d20a2f..f3945b3988d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -49,6 +49,8 @@
 #include "amdgpu_userq.h"
 #include "amdgpu_video_codecs.h"
 #include "amdgpu_ras_mgr.h"
+#include "amdgpu_vm.h"
+#include "amdgpu_cwsr.h"
 
 void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
 {
@@ -1552,6 +1554,13 @@ int amdgpu_driver_open_kms(struct drm_device *dev, 
struct drm_file *file_priv)
                         r);
 
        amdgpu_evf_mgr_init(&fpriv->evf_mgr);
+
+       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");
+       }
+
        amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
 
        file_priv->driver_priv = fpriv;
@@ -1621,6 +1630,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);
 
        if (pasid)
                amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 1b76c10d1ac2..89a35fd53cba 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -27,6 +27,7 @@
 #include "mes_userqueue.h"
 #include "amdgpu_userq_fence.h"
 #include "amdgpu_trace.h"
+#include "amdgpu_cwsr.h"
 
 #define AMDGPU_USERQ_PROC_CTX_SZ PAGE_SIZE
 #define AMDGPU_USERQ_GANG_CTX_SZ PAGE_SIZE
@@ -115,6 +116,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;
@@ -146,24 +148,37 @@ static int mes_userq_map(struct amdgpu_usermode_queue 
*queue)
        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);
+       }
+
        if (mes->use_rs64mem) {
                if (!uq_mgr->proc_ctx_allocated) {
-                       r = amdgpu_mes_alloc_proc_ctx_index(mes, 
&uq_mgr->proc_ctx_array_index);
+                       r = amdgpu_mes_alloc_proc_ctx_index(mes,
+                                                           
&uq_mgr->proc_ctx_array_index);
                        if (r) {
-                               DRM_ERROR("Failed to allocate userq process 
index err:%d\n", r);
+                               DRM_ERROR("Failed to allocate userq process 
index err:%d\n",
+                                         r);
                                return r;
                        }
                        uq_mgr->proc_ctx_allocated = true;
                }
 
-               r = amdgpu_mes_alloc_gang_ctx_index(mes, 
&queue->gang_ctx_array_index);
+               r = amdgpu_mes_alloc_gang_ctx_index(mes,
+                                                   
&queue->gang_ctx_array_index);
                if (r) {
                        DRM_ERROR("Failed to allocate userq gang index 
err:%d\n", r);
                        return r;
                }
-               queue_input.process_context_array_index = 
uq_mgr->proc_ctx_array_index;
-               queue_input.gang_context_array_index = 
queue->gang_ctx_array_index;
+
+               queue_input.process_context_array_index =
+                       uq_mgr->proc_ctx_array_index;
+               queue_input.gang_context_array_index =
+                       queue->gang_ctx_array_index;
        }
+
        amdgpu_mes_lock(&adev->mes);
        r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
        amdgpu_mes_unlock(&adev->mes);
@@ -174,7 +189,9 @@ static int mes_userq_map(struct amdgpu_usermode_queue 
*queue)
 
        amdgpu_mes_userq_queue_mapped(adev);
 
-       DRM_DEBUG_DRIVER("Queue (doorbell:%d) mapped successfully\n", 
userq_props->doorbell_index);
+       DRM_DEBUG_DRIVER("Queue (doorbell:%d) mapped successfully\n",
+                        userq_props->doorbell_index);
+
        return 0;
 }
 
-- 
2.34.1

Reply via email to