diff options
author | Dave Airlie <airlied@redhat.com> | 2023-08-15 13:37:47 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2023-08-15 13:37:49 +1000 |
commit | a8b273a8fd9c88cee038ffdae05b7eca063b9622 (patch) | |
tree | 8ec55ab4de0dffb6ba3e5e30ba36c24a52e7f480 /drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | |
parent | 73c98bf2fad6cd87e34fca4f8cf00329e49e63e7 (diff) | |
parent | 6be2ad4f0073c541146caa66c5ae936c955a8224 (diff) |
Merge tag 'amd-drm-next-6.6-2023-08-11' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amdgpu:
- SDMA 6.1.0 support
- SMU 13.x fixes
- PSP 13.x fixes
- HDP 6.1 support
- SMUIO 14.0 support
- IH 6.1 support
- Coding style cleanups
- Misc display fixes
- Initial Freesync panel replay support
- RAS fixes
- SDMA 5.2 MGCG updates
- SR-IOV fixes
- DCN3+ gamma fix
- Revert zpos properly until IGT regression is fixed
- NBIO 7.9 fixes
- Use TTM to manage the doorbell BAR
- Async flip fix
- DPIA tracing support
- DCN 3.x TMDS HDMI fixes
- FRU fixes
amdkfd:
- Coding style cleanups
- SVM fixes
- Trap handler fixes
- Convert older APUs to use dGPU path like newer APUs
- Drop IOMMUv2 path as it is no longer used
radeon:
- Coding style cleanups
drm buddy:
- Fix debugging output
UAPI:
- A new memory pool was added to amdgpu_drm.h since we converted doorbell BAR management to use TTM,
but userspace is blocked from allocating from it at this point, so kind of not really anything new
here per se
Signed-off-by: Dave Airlie <airlied@redhat.com>
# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZNahZwAKCRC93/aFa7yZ
# 2KNjAP0UV2vJZjrze7OQI/YoI+40UlGjS81nKGlMIN3eR8nzvAD/c9McLJViL82R
# idEAK7tsr/MaCKoPAlED7CkUZiHNlQw=
# =4w7I
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 12 Aug 2023 07:00:23 AEST
# gpg: using EDDSA key 203B921D836B5735349902BDBDDFF6856BBC99D8
# gpg: Can't check signature: No public key
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230811211554.7804-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 148 |
1 files changed, 38 insertions, 110 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 37f15abf7543c..b6015157763af 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -39,120 +39,70 @@ int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev) PAGE_SIZE); } -int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev, - unsigned int *doorbell_index) -{ - int r = ida_simple_get(&adev->mes.doorbell_ida, 2, - adev->mes.max_doorbell_slices, - GFP_KERNEL); - if (r > 0) - *doorbell_index = r; - - return r; -} - -void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev, - unsigned int doorbell_index) -{ - if (doorbell_index) - ida_simple_remove(&adev->mes.doorbell_ida, doorbell_index); -} - -unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar( - struct amdgpu_device *adev, - uint32_t doorbell_index, - unsigned int doorbell_id) -{ - return ((doorbell_index * - amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32) + - doorbell_id * 2); -} - -static int amdgpu_mes_queue_doorbell_get(struct amdgpu_device *adev, +static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev, struct amdgpu_mes_process *process, int ip_type, uint64_t *doorbell_index) { unsigned int offset, found; + struct amdgpu_mes *mes = &adev->mes; - if (ip_type == AMDGPU_RING_TYPE_SDMA) { + if (ip_type == AMDGPU_RING_TYPE_SDMA) offset = adev->doorbell_index.sdma_engine[0]; - found = find_next_zero_bit(process->doorbell_bitmap, - AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS, - offset); - } else { - found = find_first_zero_bit(process->doorbell_bitmap, - AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS); - } + else + offset = 0; - if (found >= AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS) { + found = find_next_zero_bit(mes->doorbell_bitmap, mes->num_mes_dbs, offset); + if (found >= mes->num_mes_dbs) { DRM_WARN("No doorbell available\n"); return -ENOSPC; } - set_bit(found, process->doorbell_bitmap); - - *doorbell_index = amdgpu_mes_get_doorbell_dw_offset_in_bar(adev, - process->doorbell_index, found); + set_bit(found, mes->doorbell_bitmap); + /* Get the absolute doorbell index on BAR */ + *doorbell_index = mes->db_start_dw_offset + found * 2; return 0; } -static void amdgpu_mes_queue_doorbell_free(struct amdgpu_device *adev, +static void amdgpu_mes_kernel_doorbell_free(struct amdgpu_device *adev, struct amdgpu_mes_process *process, uint32_t doorbell_index) { - unsigned int old, doorbell_id; + unsigned int old, rel_index; + struct amdgpu_mes *mes = &adev->mes; - doorbell_id = doorbell_index - - (process->doorbell_index * - amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32); - doorbell_id /= 2; - - old = test_and_clear_bit(doorbell_id, process->doorbell_bitmap); + /* Find the relative index of the doorbell in this object */ + rel_index = (doorbell_index - mes->db_start_dw_offset) / 2; + old = test_and_clear_bit(rel_index, mes->doorbell_bitmap); WARN_ON(!old); } static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev) { - size_t doorbell_start_offset; - size_t doorbell_aperture_size; - size_t doorbell_process_limit; - size_t aggregated_doorbell_start; int i; + struct amdgpu_mes *mes = &adev->mes; - aggregated_doorbell_start = (adev->doorbell_index.max_assignment + 1) * sizeof(u32); - aggregated_doorbell_start = - roundup(aggregated_doorbell_start, PAGE_SIZE); - - doorbell_start_offset = aggregated_doorbell_start + PAGE_SIZE; - doorbell_start_offset = - roundup(doorbell_start_offset, - amdgpu_mes_doorbell_process_slice(adev)); - - doorbell_aperture_size = adev->doorbell.size; - doorbell_aperture_size = - rounddown(doorbell_aperture_size, - amdgpu_mes_doorbell_process_slice(adev)); - - if (doorbell_aperture_size > doorbell_start_offset) - doorbell_process_limit = - (doorbell_aperture_size - doorbell_start_offset) / - amdgpu_mes_doorbell_process_slice(adev); - else - return -ENOSPC; - - adev->mes.doorbell_id_offset = doorbell_start_offset / sizeof(u32); - adev->mes.max_doorbell_slices = doorbell_process_limit; + /* Bitmap for dynamic allocation of kernel doorbells */ + mes->doorbell_bitmap = bitmap_zalloc(PAGE_SIZE / sizeof(u32), GFP_KERNEL); + if (!mes->doorbell_bitmap) { + DRM_ERROR("Failed to allocate MES doorbell bitmap\n"); + return -ENOMEM; + } - /* allocate Qword range for aggregated doorbell */ - for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++) - adev->mes.aggregated_doorbells[i] = - aggregated_doorbell_start / sizeof(u32) + i * 2; + mes->num_mes_dbs = PAGE_SIZE / AMDGPU_ONE_DOORBELL_SIZE; + for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++) { + adev->mes.aggregated_doorbells[i] = mes->db_start_dw_offset + i * 2; + set_bit(i, mes->doorbell_bitmap); + } - DRM_INFO("max_doorbell_slices=%zu\n", doorbell_process_limit); return 0; } +static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev) +{ + bitmap_free(adev->mes.doorbell_bitmap); +} + int amdgpu_mes_init(struct amdgpu_device *adev) { int i, r; @@ -251,6 +201,7 @@ void amdgpu_mes_fini(struct amdgpu_device *adev) amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs); amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs); amdgpu_device_wb_free(adev, adev->mes.read_val_offs); + amdgpu_mes_doorbell_free(adev); idr_destroy(&adev->mes.pasid_idr); idr_destroy(&adev->mes.gang_id_idr); @@ -279,15 +230,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid, return -ENOMEM; } - process->doorbell_bitmap = - kzalloc(DIV_ROUND_UP(AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS, - BITS_PER_BYTE), GFP_KERNEL); - if (!process->doorbell_bitmap) { - DRM_ERROR("failed to allocate doorbell bitmap\n"); - kfree(process); - return -ENOMEM; - } - /* allocate the process context bo and map it */ r = amdgpu_bo_create_kernel(adev, AMDGPU_MES_PROC_CTX_SIZE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, @@ -314,15 +256,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid, goto clean_up_ctx; } - /* allocate the starting doorbell index of the process */ - r = amdgpu_mes_alloc_process_doorbells(adev, &process->doorbell_index); - if (r < 0) { - DRM_ERROR("failed to allocate doorbell for process\n"); - goto clean_up_pasid; - } - - DRM_DEBUG("process doorbell index = %d\n", process->doorbell_index); - INIT_LIST_HEAD(&process->gang_list); process->vm = vm; process->pasid = pasid; @@ -332,15 +265,12 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid, amdgpu_mes_unlock(&adev->mes); return 0; -clean_up_pasid: - idr_remove(&adev->mes.pasid_idr, pasid); - amdgpu_mes_unlock(&adev->mes); clean_up_ctx: + amdgpu_mes_unlock(&adev->mes); amdgpu_bo_free_kernel(&process->proc_ctx_bo, &process->proc_ctx_gpu_addr, &process->proc_ctx_cpu_ptr); clean_up_memory: - kfree(process->doorbell_bitmap); kfree(process); return r; } @@ -386,7 +316,6 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid) idr_remove(&adev->mes.gang_id_idr, gang->gang_id); } - amdgpu_mes_free_process_doorbells(adev, process->doorbell_index); idr_remove(&adev->mes.pasid_idr, pasid); amdgpu_mes_unlock(&adev->mes); @@ -408,7 +337,6 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid) amdgpu_bo_free_kernel(&process->proc_ctx_bo, &process->proc_ctx_gpu_addr, &process->proc_ctx_cpu_ptr); - kfree(process->doorbell_bitmap); kfree(process); } @@ -682,7 +610,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id, *queue_id = queue->queue_id = r; /* allocate a doorbell index for the queue */ - r = amdgpu_mes_queue_doorbell_get(adev, gang->process, + r = amdgpu_mes_kernel_doorbell_get(adev, gang->process, qprops->queue_type, &qprops->doorbell_off); if (r) @@ -740,7 +668,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id, return 0; clean_up_doorbell: - amdgpu_mes_queue_doorbell_free(adev, gang->process, + amdgpu_mes_kernel_doorbell_free(adev, gang->process, qprops->doorbell_off); clean_up_queue_id: spin_lock_irqsave(&adev->mes.queue_id_lock, flags); @@ -795,7 +723,7 @@ int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id) queue_id); list_del(&queue->list); - amdgpu_mes_queue_doorbell_free(adev, gang->process, + amdgpu_mes_kernel_doorbell_free(adev, gang->process, queue->doorbell_off); amdgpu_mes_unlock(&adev->mes); |