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
