diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-24 11:33:23 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-24 11:33:23 -0700 |
| commit | 92c4c9fdc838d3b41a996bb700ea64b9e78fc7ea (patch) | |
| tree | e5a1763ce1295ccdeb94f4e26ee52eb4f3c3aed6 /drivers/gpu/drm/amd/amdgpu | |
| parent | 892c894b4ba4e4eb835f99de6fe7c41871e6d4f8 (diff) | |
| parent | e49712ef03dbc4e282dd0e76469642279c2811e5 (diff) | |
Merge tag 'drm-next-2026-04-24' of https://gitlab.freedesktop.org/drm/kernel
Pull drm next fixes from Dave Airlie:
"This is the first of two fixes for the merge PRs, the other is based
on 7.0 branch. This mostly AMD fixes, a couple of weeks of backlog
built up and this weeks. The main complaint I've seen is some boot
warnings around the FP code handling which this should fix. Otherwise
a single rcar-du and a single i915 fix.
amdgpu:
- SMU 14 fixes
- Partition fixes
- SMUIO 15.x fix
- SR-IOV fixes
- JPEG fix
- PSP 15.x fix
- NBIF fix
- Devcoredump fixes
- DPC fix
- RAS fixes
- Aldebaran smu fix
- IP discovery fix
- SDMA 7.1 fix
- Runtime pm fix
- MES 12.1 fix
- DML2 fixes
- DCN 4.2 fixes
- YCbCr fixes
- Freesync fixes
- ISM fixes
- Overlay cursor fix
- DC FP fixes
- UserQ locking fixes
- DC idle state manager fix
- ASPM fix
- GPUVM SVM fix
- DCE 6 fix
amdkfd:
- Fix memory clear handling
- num_of_nodes bounds check fix
i915:
- Fix uninitialized variable in the alignment loop [psr]
rcar-du:
- fix NULL-ptr crash"
* tag 'drm-next-2026-04-24' of https://gitlab.freedesktop.org/drm/kernel: (75 commits)
drm/amdkfd: Add upper bound check for num_of_nodes
drm: rcar-du: Fix crash when no CMM is available
drm/amd/display: Disable 10-bit truncation and dithering on DCE 6.x
drm/amdgpu: OR init_pte_flags into invalid leaf PTE updates
drm/amd: Adjust ASPM support quirk to cover more Intel hosts
drm/amd/display: Undo accidental fix revert in amdgpu_dm_ism.c
drm/i915/psr: Init variable to avoid early exit from et alignment loop
drm/amdgpu: drop userq fence driver refs out of fence process()
drm/amdgpu/userq: unpin and unref doorbell and wptr outside mutex
drm/amdgpu/userq: use pm_runtime_resume_and_get and fix err handling
drm/amdgpu/userq: unmap_helper dont return the queue state
drm/amdgpu/userq: unmap is to be called before freeing doorbell/wptr bo
drm/amdgpu/userq: hold root bo lock in caller of input_va_validate
drm/amdgpu/userq: caller to take reserv lock for vas_list_cleanup
drm/amdgpu/userq: create_mqd does not need userq_mutex
drm/amdgpu/userq: dont lock root bo with userq_mutex held
drm/amdgpu/userq: fix kerneldoc for amdgpu_userq_ensure_ev_fence
drm/amdgpu/userq: clean the VA mapping list for failed queue creation
drm/amdgpu/userq: avoid uneccessary locking in amdgpu_userq_create
drm/amd/display: Fix ISM teardown crash from NULL dc dereference
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
19 files changed, 301 insertions, 121 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 29b400cdd6d5..72a5a29e63f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1735,7 +1735,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( alloc_domain = AMDGPU_GEM_DOMAIN_GTT; alloc_flags = 0; } else { - alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE; + alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE | + AMDGPU_GEM_CREATE_VRAM_CLEARED; alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ? AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index b04fa9fd90b7..92c98e999efe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -866,6 +866,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) if (dret) { amdgpu_connector->detected_by_load = false; drm_edid_free(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; amdgpu_connector_get_edid(connector); if (!amdgpu_connector->edid) { @@ -882,6 +883,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) */ if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) { drm_edid_free(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; ret = connector_status_disconnected; } else { ret = connector_status_connected; @@ -977,6 +979,7 @@ static void amdgpu_connector_shared_ddc(enum drm_connector_status *status, if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) { drm_edid_free(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; *status = connector_status_disconnected; } } @@ -1046,6 +1049,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) if (dret) { amdgpu_connector->detected_by_load = false; drm_edid_free(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; amdgpu_connector_get_edid(connector); if (!amdgpu_connector->edid) { @@ -1062,6 +1066,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) */ if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) { drm_edid_free(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; ret = connector_status_disconnected; } else { ret = connector_status_connected; @@ -1412,6 +1417,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) } drm_edid_free(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c index c72c345334d0..4e6e390854e6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c @@ -32,6 +32,8 @@ static const guid_t BOOT = BOOT_TYPE; static const guid_t CRASHDUMP = AMD_CRASHDUMP; static const guid_t RUNTIME = AMD_GPU_NONSTANDARD_ERROR; +#define CPER_SIGNATURE_SZ (sizeof(((struct cper_hdr *)0)->signature)) + static void __inc_entry_length(struct cper_hdr *hdr, uint32_t size) { hdr->record_length += size; @@ -425,23 +427,40 @@ int amdgpu_cper_generate_ce_records(struct amdgpu_device *adev, static bool amdgpu_cper_is_hdr(struct amdgpu_ring *ring, u64 pos) { - struct cper_hdr *chdr; + char signature[CPER_SIGNATURE_SZ]; + + if ((pos << 2) >= ring->ring_size) + return false; - chdr = (struct cper_hdr *)&(ring->ring[pos]); - return strcmp(chdr->signature, "CPER") ? false : true; + if ((pos << 2) + CPER_SIGNATURE_SZ <= ring->ring_size) { + memcpy(signature, &ring->ring[pos], CPER_SIGNATURE_SZ); + } else { + u32 chunk = ring->ring_size - (pos << 2); + + memcpy(signature, &ring->ring[pos], chunk); + memcpy(signature + chunk, ring->ring, CPER_SIGNATURE_SZ - chunk); + } + + return !memcmp(signature, "CPER", CPER_SIGNATURE_SZ); } static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos) { - struct cper_hdr *chdr; + struct cper_hdr chdr; u64 p; u32 chunk, rec_len = 0; - chdr = (struct cper_hdr *)&(ring->ring[pos]); chunk = ring->ring_size - (pos << 2); - if (!strcmp(chdr->signature, "CPER")) { - rec_len = chdr->record_length; + if (amdgpu_cper_is_hdr(ring, pos)) { + if (chunk >= sizeof(chdr)) { + memcpy(&chdr, &ring->ring[pos], sizeof(chdr)); + } else { + memcpy(&chdr, &ring->ring[pos], chunk); + memcpy((u8 *)&chdr + chunk, ring->ring, sizeof(chdr) - chunk); + } + + rec_len = chdr.record_length; goto calc; } @@ -450,8 +469,7 @@ static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos) goto calc; for (p = pos + 1; p <= ring->buf_mask; p++) { - chdr = (struct cper_hdr *)&(ring->ring[p]); - if (!strcmp(chdr->signature, "CPER")) { + if (amdgpu_cper_is_hdr(ring, p)) { rec_len = (p - pos) << 2; goto calc; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c index 3f1cc2265645..d386bc775d03 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c @@ -464,6 +464,9 @@ static void amdgpu_devcoredump_deferred_work(struct work_struct *work) struct amdgpu_device *adev = container_of(work, typeof(*adev), coredump_work); struct amdgpu_coredump_info *coredump = adev->coredump; + if (!coredump) + goto end; + /* Do a one-time preparation of the coredump output because * repeatingly calling drm_coredump_printer is very slow. */ @@ -499,7 +502,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, int i, off, idx; /* No need to generate a new coredump if there's one in progress already. */ - if (work_pending(&adev->coredump_work)) + if (work_busy(&adev->coredump_work)) return; if (job && job->pasid) @@ -511,7 +514,6 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, coredump->skip_vram_check = skip_vram_check; coredump->reset_vram_lost = vram_lost; - coredump->pasid = job->pasid; if (job && job->pasid) { struct amdgpu_task_info *ti; @@ -521,6 +523,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, coredump->reset_task_info = *ti; amdgpu_vm_put_task_info(ti); } + coredump->pasid = job->pasid; coredump->num_ibs = job->num_ibs; for (i = 0; i < job->num_ibs; ++i) { coredump->ibs[i].gpu_addr = job->ibs[i].gpu_addr; @@ -563,7 +566,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, coredump->rings[idx].offset = off; memcpy(&coredump->rings_dw[off], ring->ring, ring->ring_size); - off += ring->ring_size; + off += ring->ring_size / 4; idx++; } coredump->num_rings = idx; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 584c9ec28bf1..737ef1ef96a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1334,18 +1334,15 @@ static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev) #if IS_ENABLED(CONFIG_X86) struct cpuinfo_x86 *c = &cpu_data(0); - if (!(amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 0, 0) || - amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 0, 1))) - return false; - - if (c->x86 == 6 && - adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN5) { + if (c->x86_vendor == X86_VENDOR_INTEL) { switch (c->x86_model) { case VFM_MODEL(INTEL_ALDERLAKE): case VFM_MODEL(INTEL_ALDERLAKE_L): case VFM_MODEL(INTEL_RAPTORLAKE): case VFM_MODEL(INTEL_RAPTORLAKE_P): case VFM_MODEL(INTEL_RAPTORLAKE_S): + case VFM_MODEL(INTEL_TIGERLAKE): + case VFM_MODEL(INTEL_TIGERLAKE_L): return true; default: return false; @@ -5518,8 +5515,6 @@ static void amdgpu_device_recovery_prepare(struct amdgpu_device *adev, list_add_tail(&tmp_adev->reset_list, device_list); if (adev->shutdown) tmp_adev->shutdown = true; - if (amdgpu_reset_in_dpc(adev)) - tmp_adev->pcie_reset_ctx.in_link_reset = true; } if (!list_is_first(&adev->reset_list, device_list)) list_rotate_to_front(&adev->reset_list, device_list); @@ -6291,6 +6286,9 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta amdgpu_reset_set_dpc_status(adev, true); mutex_lock(&hive->hive_lock); + } else { + if (amdgpu_device_bus_status_check(adev)) + amdgpu_reset_set_dpc_status(adev, true); } memset(&reset_context, 0, sizeof(reset_context)); INIT_LIST_HEAD(&device_list); @@ -6411,6 +6409,7 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev) list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) tmp_adev->pcie_reset_ctx.in_link_reset = true; } else { + adev->pcie_reset_ctx.in_link_reset = true; set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags); } @@ -6467,9 +6466,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev) tmp_adev->pcie_reset_ctx.in_link_reset = false; list_add_tail(&tmp_adev->reset_list, &device_list); } - } else + } else { + adev->pcie_reset_ctx.in_link_reset = false; list_add_tail(&adev->reset_list, &device_list); - + } amdgpu_device_sched_resume(&device_list, NULL, NULL); amdgpu_device_gpu_resume(adev, &device_list, false); amdgpu_device_recovery_put_reset_lock(adev, &device_list); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 8ec5465c3349..fcad7daaa41b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -535,10 +535,11 @@ static int amdgpu_discovery_get_table_info(struct amdgpu_device *adev, *info = &bhdrv2->table_list[table_id]; break; case 1: + case 0: *info = &bhdr->table_list[table_id]; break; default: - dev_err(adev->dev, "Invalid ip discovery table version\n"); + dev_err(adev->dev, "Invalid ip discovery table version %d\n",bhdr->version_major); return -EINVAL; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 2956e45c9254..b8ca876694ff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -2013,6 +2013,8 @@ static void amdgpu_gfx_sysfs_xcp_fini(struct amdgpu_device *adev) (xcp_mgr->funcs && xcp_mgr->funcs->switch_partition_mode); device_remove_file(adev->dev, &dev_attr_current_compute_partition); + device_remove_file(adev->dev, &dev_attr_compute_partition_mem_alloc_mode); + if (xcp_switch_supported) device_remove_file(adev->dev, &dev_attr_available_compute_partition); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index bfca5b040a32..d5abf785ca17 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -239,13 +239,12 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, u64 size; int r = 0; + /* Caller must hold vm->root.bo reservation */ + dma_resv_assert_held(queue->vm->root.bo->tbo.base.resv); + user_addr = (addr & AMDGPU_GMC_HOLE_MASK) >> AMDGPU_GPU_PAGE_SHIFT; size = expected_size >> AMDGPU_GPU_PAGE_SHIFT; - r = amdgpu_bo_reserve(vm->root.bo, false); - if (r) - return r; - va_map = amdgpu_vm_bo_lookup_mapping(vm, user_addr); if (!va_map) { r = -EINVAL; @@ -255,13 +254,11 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, if (user_addr >= va_map->start && va_map->last - user_addr + 1 >= size) { amdgpu_userq_buffer_va_list_add(queue, va_map, user_addr); - amdgpu_bo_unreserve(vm->root.bo); return 0; } r = -EINVAL; out_err: - amdgpu_bo_unreserve(vm->root.bo); return r; } @@ -270,15 +267,13 @@ static bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr) struct amdgpu_bo_va_mapping *mapping; bool r; - if (amdgpu_bo_reserve(vm->root.bo, false)) - return false; + dma_resv_assert_held(vm->root.bo->tbo.base.resv); mapping = amdgpu_vm_bo_lookup_mapping(vm, addr); if (!IS_ERR_OR_NULL(mapping) && atomic_read(&mapping->bo_va->userq_va_mapped)) r = true; else r = false; - amdgpu_bo_unreserve(vm->root.bo); return r; } @@ -314,25 +309,21 @@ static int amdgpu_userq_buffer_vas_list_cleanup(struct amdgpu_device *adev, { struct amdgpu_userq_va_cursor *va_cursor, *tmp; struct amdgpu_bo_va_mapping *mapping; - int r; - r = amdgpu_bo_reserve(queue->vm->root.bo, false); - if (r) - return r; + /* Caller must hold vm->root.bo reservation */ + dma_resv_assert_held(queue->vm->root.bo->tbo.base.resv); list_for_each_entry_safe(va_cursor, tmp, &queue->userq_va_list, list) { mapping = amdgpu_vm_bo_lookup_mapping(queue->vm, va_cursor->gpu_addr); if (!mapping) { - r = -EINVAL; - goto err; + return -EINVAL; } dev_dbg(adev->dev, "delete the userq:%p va:%llx\n", queue, va_cursor->gpu_addr); amdgpu_userq_buffer_va_list_del(mapping, va_cursor); } -err: - amdgpu_bo_unreserve(queue->vm->root.bo); - return r; + + return 0; } static int amdgpu_userq_preempt_helper(struct amdgpu_usermode_queue *queue) @@ -446,8 +437,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue) /* Wait for mode-1 reset to complete */ down_read(&adev->reset_domain->sem); - /* Drop the userq reference. */ - amdgpu_userq_buffer_vas_list_cleanup(adev, queue); uq_funcs->mqd_destroy(queue); /* Use interrupt-safe locking since IRQ handlers may access these XArrays */ xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index); @@ -455,11 +444,19 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue) queue->fence_drv = NULL; queue->userq_mgr = NULL; list_del(&queue->userq_va_list); - kfree(queue); up_read(&adev->reset_domain->sem); } +/** + * amdgpu_userq_ensure_ev_fence - ensure a valid, unsignaled eviction fence exists + * @uq_mgr: the usermode queue manager for this process + * @evf_mgr: the eviction fence manager to check and rearm + * + * Ensures that a valid and not yet signaled eviction fence is attached to the + * usermode queue before any queue operations proceed. If it is signalled, then + * rearm a new eviction fence. + */ void amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_eviction_fence_mgr *evf_mgr) @@ -619,6 +616,9 @@ static int amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) { struct amdgpu_device *adev = uq_mgr->adev; + struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); + struct amdgpu_vm *vm = &fpriv->vm; + int r = 0; cancel_delayed_work_sync(&uq_mgr->resume_work); @@ -626,38 +626,44 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_que /* Cancel any pending hang detection work and cleanup */ cancel_delayed_work_sync(&queue->hang_detect_work); + r = amdgpu_bo_reserve(vm->root.bo, false); + if (r) { + drm_file_err(uq_mgr->file, "Failed to reserve root bo during userqueue destroy\n"); + return r; + } + amdgpu_userq_buffer_vas_list_cleanup(adev, queue); + amdgpu_bo_unreserve(vm->root.bo); + mutex_lock(&uq_mgr->userq_mutex); queue->hang_detect_fence = NULL; amdgpu_userq_wait_for_last_fence(queue); - r = amdgpu_bo_reserve(queue->db_obj.obj, true); - if (!r) { - amdgpu_bo_unpin(queue->db_obj.obj); - amdgpu_bo_unreserve(queue->db_obj.obj); - } - amdgpu_bo_unref(&queue->db_obj.obj); - - r = amdgpu_bo_reserve(queue->wptr_obj.obj, true); - if (!r) { - amdgpu_bo_unpin(queue->wptr_obj.obj); - amdgpu_bo_unreserve(queue->wptr_obj.obj); - } - amdgpu_bo_unref(&queue->wptr_obj.obj); - - atomic_dec(&uq_mgr->userq_count[queue->queue_type]); #if defined(CONFIG_DEBUG_FS) debugfs_remove_recursive(queue->debugfs_queue); #endif amdgpu_userq_detect_and_reset_queues(uq_mgr); r = amdgpu_userq_unmap_helper(queue); /*TODO: It requires a reset for userq hw unmap error*/ - if (unlikely(r != AMDGPU_USERQ_STATE_UNMAPPED)) { + if (r) { drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n"); queue->state = AMDGPU_USERQ_STATE_HUNG; } + + atomic_dec(&uq_mgr->userq_count[queue->queue_type]); amdgpu_userq_cleanup(queue); mutex_unlock(&uq_mgr->userq_mutex); + amdgpu_bo_reserve(queue->db_obj.obj, true); + amdgpu_bo_unpin(queue->db_obj.obj); + amdgpu_bo_unreserve(queue->db_obj.obj); + amdgpu_bo_unref(&queue->db_obj.obj); + + amdgpu_bo_reserve(queue->wptr_obj.obj, true); + amdgpu_bo_unpin(queue->wptr_obj.obj); + amdgpu_bo_unreserve(queue->wptr_obj.obj); + amdgpu_bo_unref(&queue->wptr_obj.obj); + kfree(queue); + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); return r; @@ -730,35 +736,25 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) if (r) return r; - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); + r = pm_runtime_resume_and_get(adev_to_drm(adev)->dev); if (r < 0) { - drm_file_err(uq_mgr->file, "pm_runtime_get_sync() failed for userqueue create\n"); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + drm_file_err(uq_mgr->file, "pm_runtime_resume_and_get() failed for userqueue create\n"); return r; } - /* - * There could be a situation that we are creating a new queue while - * the other queues under this UQ_mgr are suspended. So if there is any - * resume work pending, wait for it to get done. - * - * This will also make sure we have a valid eviction fence ready to be used. - */ - amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); - uq_funcs = adev->userq_funcs[args->in.ip_type]; if (!uq_funcs) { drm_file_err(uq_mgr->file, "Usermode queue is not supported for this IP (%u)\n", args->in.ip_type); r = -EINVAL; - goto unlock; + goto err_pm_runtime; } queue = kzalloc_obj(struct amdgpu_usermode_queue); if (!queue) { drm_file_err(uq_mgr->file, "Failed to allocate memory for queue\n"); r = -ENOMEM; - goto unlock; + goto err_pm_runtime; } INIT_LIST_HEAD(&queue->userq_va_list); @@ -773,20 +769,27 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) db_info.doorbell_offset = args->in.doorbell_offset; queue->userq_mgr = uq_mgr; + /* Validate the userq virtual address.*/ + r = amdgpu_bo_reserve(fpriv->vm.root.bo, false); + if (r) + goto free_queue; + if (amdgpu_userq_input_va_validate(adev, queue, args->in.queue_va, args->in.queue_size) || amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { r = -EINVAL; - goto free_queue; + amdgpu_bo_unreserve(fpriv->vm.root.bo); + goto clean_mapping; } + amdgpu_bo_unreserve(fpriv->vm.root.bo); /* Convert relative doorbell offset into absolute doorbell index */ index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp); if (index == (uint64_t)-EINVAL) { drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n"); r = -EINVAL; - goto free_queue; + goto clean_mapping; } queue->doorbell_index = index; @@ -794,7 +797,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) r = amdgpu_userq_fence_driver_alloc(adev, &queue->fence_drv); if (r) { drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n"); - goto free_queue; + goto clean_mapping; } r = uq_funcs->mqd_create(queue, &args->in); @@ -803,6 +806,8 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) goto clean_fence_driver; } + amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); + /* don't map the queue if scheduling is halted */ if (adev->userq_halt_for_enforce_isolation && ((queue->queue_type == AMDGPU_HW_IP_GFX) || @@ -814,7 +819,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) r = amdgpu_userq_map_helper(queue); if (r) { drm_file_err(uq_mgr->file, "Failed to map Queue\n"); - down_read(&adev->reset_domain->sem); goto clean_mqd; } } @@ -830,9 +834,8 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) if (r) { if (!skip_map_queue) amdgpu_userq_unmap_helper(queue); - r = -ENOMEM; - goto clean_mqd; + goto clean_reset_domain; } r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL)); @@ -840,8 +843,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) xa_erase(&uq_mgr->userq_xa, qid); if (!skip_map_queue) amdgpu_userq_unmap_helper(queue); - - goto clean_mqd; + goto clean_reset_domain; } up_read(&adev->reset_domain->sem); @@ -853,16 +855,21 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) mutex_unlock(&uq_mgr->userq_mutex); return 0; +clean_reset_domain: + up_read(&adev->reset_domain->sem); clean_mqd: + mutex_unlock(&uq_mgr->userq_mutex); uq_funcs->mqd_destroy(queue); - up_read(&adev->reset_domain->sem); clean_fence_driver: amdgpu_userq_fence_driver_free(queue); +clean_mapping: + amdgpu_bo_reserve(fpriv->vm.root.bo, true); + amdgpu_userq_buffer_vas_list_cleanup(adev, queue); + amdgpu_bo_unreserve(fpriv->vm.root.bo); free_queue: kfree(queue); -unlock: - mutex_unlock(&uq_mgr->userq_mutex); - +err_pm_runtime: + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); return r; } @@ -992,10 +999,16 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, static int amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) { + struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr); + struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_usermode_queue *queue; unsigned long queue_id; int ret = 0, r; + + if (amdgpu_bo_reserve(vm->root.bo, false)) + return false; + mutex_lock(&uq_mgr->userq_mutex); /* Resume all the queues for this process */ xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { @@ -1013,6 +1026,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) } mutex_unlock(&uq_mgr->userq_mutex); + amdgpu_bo_unreserve(vm->root.bo); if (ret) drm_file_err(uq_mgr->file, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 5784f2b3ecae..da39ac862f37 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -145,13 +145,22 @@ amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq) amdgpu_userq_fence_driver_put(userq->fence_drv); } +static void +amdgpu_userq_fence_put_fence_drv_array(struct amdgpu_userq_fence *userq_fence) +{ + unsigned long i; + for (i = 0; i < userq_fence->fence_drv_array_count; i++) + amdgpu_userq_fence_driver_put(userq_fence->fence_drv_array[i]); + userq_fence->fence_drv_array_count = 0; +} + void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv) { struct amdgpu_userq_fence *userq_fence, *tmp; + LIST_HEAD(to_be_signaled); struct dma_fence *fence; unsigned long flags; u64 rptr; - int i; if (!fence_drv) return; @@ -159,21 +168,26 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d spin_lock_irqsave(&fence_drv->fence_list_lock, flags); rptr = amdgpu_userq_fence_read(fence_drv); - list_for_each_entry_safe(userq_fence, tmp, &fence_drv->fences, link) { - fence = &userq_fence->base; - - if (rptr < fence->seqno) + list_for_each_entry(userq_fence, &fence_drv->fences, link) { + if (rptr < userq_fence->base.seqno) break; + } - dma_fence_signal(fence); - - for (i = 0; i < userq_fence->fence_drv_array_count; i++) - amdgpu_userq_fence_driver_put(userq_fence->fence_drv_array[i]); + list_cut_before(&to_be_signaled, &fence_drv->fences, + &userq_fence->link); + spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags); - list_del(&userq_fence->link); + list_for_each_entry_safe(userq_fence, tmp, &to_be_signaled, link) { + fence = &userq_fence->base; + list_del_init(&userq_fence->link); + dma_fence_signal(fence); + /* Drop fence_drv_array outside fence_list_lock + * to avoid the recursion lock. + */ + amdgpu_userq_fence_put_fence_drv_array(userq_fence); dma_fence_put(fence); } - spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags); + } void amdgpu_userq_fence_driver_destroy(struct kref *ref) @@ -228,6 +242,7 @@ static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq, struct amdgpu_userq_fence_driver *fence_drv; struct dma_fence *fence; unsigned long flags; + bool signaled = false; fence_drv = userq->fence_drv; if (!fence_drv) @@ -274,13 +289,17 @@ static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq, /* Check if hardware has already processed the job */ spin_lock_irqsave(&fence_drv->fence_list_lock, flags); - if (!dma_fence_is_signaled(fence)) + if (!dma_fence_is_signaled(fence)) { list_add_tail(&userq_fence->link, &fence_drv->fences); - else + } else { + signaled = true; dma_fence_put(fence); - + } spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags); + if (signaled) + amdgpu_userq_fence_put_fence_drv_array(userq_fence); + *f = fence; return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 03d95dca93d7..debb82a2e031 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -34,6 +34,7 @@ #include "amdgpu.h" #include "amdgpu_pm.h" #include "amdgpu_vcn.h" +#include "amdgpu_reset.h" #include "soc15d.h" /* Firmware Names */ @@ -361,7 +362,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev, int i) /* err_event_athub and dpc recovery will corrupt VCPU buffer, so we need to * restore fw data and clear buffer in amdgpu_vcn_resume() */ - if (in_ras_intr || adev->pcie_reset_ctx.in_link_reset) + if (in_ras_intr || amdgpu_reset_in_dpc(adev)) return 0; return amdgpu_vcn_save_vcpu_bo_inst(adev, i); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c index 22e2e5b47341..f078db3fef79 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c @@ -21,6 +21,8 @@ */ #include "amdgpu_vm.h" +#include "amdgpu.h" +#include "amdgpu_reset.h" #include "amdgpu_object.h" #include "amdgpu_trace.h" @@ -108,11 +110,19 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p, static int amdgpu_vm_cpu_commit(struct amdgpu_vm_update_params *p, struct dma_fence **fence) { + struct amdgpu_device *adev = p->adev; + if (p->needs_flush) atomic64_inc(&p->vm->tlb_seq); mb(); - amdgpu_device_flush_hdp(p->adev, NULL); + /* A reset flushed the HDP anyway, so that here can be skipped when a reset is ongoing */ + if (!down_read_trylock(&adev->reset_domain->sem)) + return 0; + + amdgpu_device_flush_hdp(adev, NULL); + up_read(&adev->reset_domain->sem); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c index 31a437ce9570..a930f1522f96 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c @@ -693,8 +693,11 @@ static void amdgpu_vm_pte_update_flags(struct amdgpu_vm_update_params *params, !(flags & AMDGPU_PTE_VALID) && !(flags & AMDGPU_PTE_PRT_FLAG(params->adev))) { - /* Workaround for fault priority problem on GMC9 */ - flags |= AMDGPU_PTE_EXECUTABLE; + /* Workaround for fault priority problem on GMC9 and GFX12, + * EXECUTABLE for GMC9 fault priority and init_pte_flags + * (e.g. AMDGPU_PTE_IS_PTE on GFX12) + */ + flags |= AMDGPU_PTE_EXECUTABLE | adev->gmc.init_pte_flags; } /* diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 5097de940a19..8c82e90f871b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -64,6 +64,11 @@ #define regPC_CONFIG_CNTL_1 0x194d #define regPC_CONFIG_CNTL_1_BASE_IDX 1 +#define regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0 0x0030 +#define regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0_BASE_IDX 1 +#define regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0 0x0031 +#define regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0_BASE_IDX 1 + #define regCP_GFX_MQD_CONTROL_DEFAULT 0x00000100 #define regCP_GFX_HQD_VMID_DEFAULT 0x00000000 #define regCP_GFX_HQD_QUEUE_PRIORITY_DEFAULT 0x00000000 @@ -5234,11 +5239,27 @@ static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev) amdgpu_gfx_off_ctrl(adev, true); } else { preempt_disable(); - clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER); - clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER); - clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER); - if (clock_counter_hi_pre != clock_counter_hi_after) - clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER); + if (amdgpu_ip_version(adev, SMUIO_HWIP, 0) < IP_VERSION(15, 0, 0)) { + clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_UPPER); + clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_LOWER); + clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_UPPER); + if (clock_counter_hi_pre != clock_counter_hi_after) + clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_LOWER); + } else { + clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0); + clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0); + clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0); + if (clock_counter_hi_pre != clock_counter_hi_after) + clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, + regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0); + } preempt_enable(); } clock = clock_counter_lo | (clock_counter_hi_after << 32ULL); diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c index 4b4aa9553624..82abe181c730 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c @@ -736,15 +736,35 @@ static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring) */ void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring) { - if (!amdgpu_sriov_vf(ring->adev)) { + struct amdgpu_device *adev = ring->adev; + + if (!amdgpu_sriov_vf(adev)) { + int jpeg_inst = GET_INST(JPEG, ring->me); + uint32_t value = 0x80004000; /* default DS14 */ + amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */ + + /* PCTL0__MMHUB_DEEPSLEEP_IB could be different on different mmhub version */ + switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) { + case IP_VERSION(4, 1, 0): + amdgpu_ring_write(ring, 0x69004); + value = 0x80010000; + break; + case IP_VERSION(4, 2, 0): + amdgpu_ring_write(ring, 0x60804); + if (jpeg_inst & 1) + value = 0x80010000; + break; + default: + amdgpu_ring_write(ring, 0x62a04); + break; + } amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x80004000); + amdgpu_ring_write(ring, value); } } @@ -757,15 +777,35 @@ void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring) */ void jpeg_v4_0_3_dec_ring_insert_end(struct amdgpu_ring *ring) { - if (!amdgpu_sriov_vf(ring->adev)) { + struct amdgpu_device *adev = ring->adev; + + if (!amdgpu_sriov_vf(adev)) { + int jpeg_inst = GET_INST(JPEG, ring->me); + uint32_t value = 0x00004000; /* default DS14 */ + amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x62a04); + + /* PCTL0__MMHUB_DEEPSLEEP_IB could be different on different mmhub version */ + switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) { + case IP_VERSION(4, 1, 0): + amdgpu_ring_write(ring, 0x69004); + value = 0x00010000; + break; + case IP_VERSION(4, 2, 0): + amdgpu_ring_write(ring, 0x60804); + if (jpeg_inst & 1) + value = 0x00010000; + break; + default: + amdgpu_ring_write(ring, 0x62a04); + break; + } amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x00004000); + amdgpu_ring_write(ring, value); } } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index faac21ee5739..2fc39a6938f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -322,8 +322,14 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, goto free_mqd; } + r = amdgpu_bo_reserve(queue->vm->root.bo, false); + if (r) { + kfree(compute_mqd); + goto free_mqd; + } r = amdgpu_userq_input_va_validate(adev, queue, compute_mqd->eop_va, 2048); + amdgpu_bo_unreserve(queue->vm->root.bo); if (r) { kfree(compute_mqd); goto free_mqd; @@ -365,14 +371,22 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, userq_props->tmz_queue = mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; + r = amdgpu_bo_reserve(queue->vm->root.bo, false); + if (r) { + kfree(mqd_gfx_v11); + goto free_mqd; + } r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->shadow_va, shadow_info.shadow_size); if (r) { + amdgpu_bo_unreserve(queue->vm->root.bo); kfree(mqd_gfx_v11); goto free_mqd; } + r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->csa_va, shadow_info.csa_size); + amdgpu_bo_unreserve(queue->vm->root.bo); if (r) { kfree(mqd_gfx_v11); goto free_mqd; @@ -394,8 +408,15 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, r = -ENOMEM; goto free_mqd; } + + r = amdgpu_bo_reserve(queue->vm->root.bo, false); + if (r) { + kfree(mqd_sdma_v11); + goto free_mqd; + } r = amdgpu_userq_input_va_validate(adev, queue, mqd_sdma_v11->csa_va, 32); + amdgpu_bo_unreserve(queue->vm->root.bo); if (r) { kfree(mqd_sdma_v11); goto free_mqd; diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c index 0e9089544769..cec801278126 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c @@ -2028,7 +2028,7 @@ static int mes_v12_1_test_ring(struct amdgpu_device *adev, int xcc_id, int num_xcc = NUM_XCC(adev->gfx.xcc_mask); int sdma_ring_align = 0x10, compute_ring_align = 0x100; uint32_t tmp, xcc_offset; - int r = 0, i, wptr = 0; + int r = 0, i, j, wptr = 0; if (queue_type == AMDGPU_RING_TYPE_COMPUTE) { if (!adev->mes.enable_coop_mode) { @@ -2077,11 +2077,11 @@ static int mes_v12_1_test_ring(struct amdgpu_device *adev, int xcc_id, tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regSCRATCH_REG0); } else { - for (i = 0; i < num_xcc; i++) { - if (xcc_id != adev->mes.master_xcc_ids[i]) + for (j = 0; j < num_xcc; j++) { + if (xcc_id != adev->mes.master_xcc_ids[j]) continue; - tmp = RREG32_SOC15(GC, GET_INST(GC, i), + tmp = RREG32_SOC15(GC, GET_INST(GC, j), regSCRATCH_REG0); if (tmp != 0xDEADBEEF) break; diff --git a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c index db14a1a326d2..b6f832c53860 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c @@ -54,6 +54,8 @@ #define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10_BASE_IDX 3 #define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10 0x4f0af6 #define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10_BASE_IDX 3 +#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10 0x0021 +#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10_BASE_IDX 2 static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev) { @@ -65,7 +67,12 @@ static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev) static u32 nbif_v6_3_1_get_rev_id(struct amdgpu_device *adev) { - u32 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0); + u32 tmp; + + if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 4)) + tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10); + else + tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0); tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c index 73a709773e85..2a8582e87f2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c @@ -32,6 +32,7 @@ #include "mp/mp_15_0_0_sh_mask.h" MODULE_FIRMWARE("amdgpu/psp_15_0_0_toc.bin"); +MODULE_FIRMWARE("amdgpu/psp_15_0_0_ta.bin"); static int psp_v15_0_0_init_microcode(struct psp_context *psp) { diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c index f20e0fc3fc74..061934a2e93a 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c @@ -1268,6 +1268,18 @@ static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block) struct amdgpu_device *adev = ip_block->adev; int r; + switch (amdgpu_user_queue) { + case -1: + default: + adev->sdma.no_user_submission = true; + adev->sdma.disable_uq = true; + break; + case 0: + adev->sdma.no_user_submission = false; + adev->sdma.disable_uq = true; + break; + } + r = amdgpu_sdma_init_microcode(adev, 0, true); if (r) { DRM_ERROR("Failed to init sdma firmware!\n"); |
