amd-drm-next-6.18-2025-10-09:

amdgpu:
 - DC DCE6 fixes
 - GPU reset fixes
 - Secure diplay messaging cleanup
 - MES fix
 - GPUVM locking fixes
 - PMFW messaging cleanup
 - PCI US/DS switch handling fix
 - VCN queue reset fix
 - DC FPU handling fix
 - DCN 3.5 fix
 - DC mirroring fix
 
 amdkfd:
 - Fix kfd process ref leak
 - mmap write lock handling fix
 - Fix comments in IOCTL
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCaOfiAgAKCRC93/aFa7yZ
 2LyaAQDYoZEPZdtkju7F61ZGrDmpcouTXGQai6kCYw0kkdFPxwEAnDHk6lbmDZBV
 1NPv9xpZsjkbbSN4QrfL07B2YmB+xwk=
 =5b3K
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-next-6.18-2025-10-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-6.18-2025-10-09:

amdgpu:
- DC DCE6 fixes
- GPU reset fixes
- Secure diplay messaging cleanup
- MES fix
- GPUVM locking fixes
- PMFW messaging cleanup
- PCI US/DS switch handling fix
- VCN queue reset fix
- DC FPU handling fix
- DCN 3.5 fix
- DC mirroring fix

amdkfd:
- Fix kfd process ref leak
- mmap write lock handling fix
- Fix comments in IOCTL

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/r/20251009162915.981503-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2025-10-10 06:57:28 +10:00
commit c4b6ddcf01
28 changed files with 276 additions and 174 deletions

View File

@ -2586,12 +2586,17 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
* from the KFD, trigger a segmentation fault in VM debug mode. * from the KFD, trigger a segmentation fault in VM debug mode.
*/ */
if (amdgpu_ttm_adev(bo->tbo.bdev)->debug_vm_userptr) { if (amdgpu_ttm_adev(bo->tbo.bdev)->debug_vm_userptr) {
struct kfd_process *p;
pr_err("Pid %d unmapped memory before destroying userptr at GPU addr 0x%llx\n", pr_err("Pid %d unmapped memory before destroying userptr at GPU addr 0x%llx\n",
pid_nr(process_info->pid), mem->va); pid_nr(process_info->pid), mem->va);
// Send GPU VM fault to user space // Send GPU VM fault to user space
kfd_signal_vm_fault_event_with_userptr(kfd_lookup_process_by_pid(process_info->pid), p = kfd_lookup_process_by_pid(process_info->pid);
mem->va); if (p) {
kfd_signal_vm_fault_event_with_userptr(p, mem->va);
kfd_unref_process(p);
}
} }
ret = 0; ret = 0;

View File

@ -6389,23 +6389,28 @@ static int amdgpu_device_sched_resume(struct list_head *device_list,
if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled)
drm_helper_resume_force_mode(adev_to_drm(tmp_adev)); drm_helper_resume_force_mode(adev_to_drm(tmp_adev));
if (tmp_adev->asic_reset_res) if (tmp_adev->asic_reset_res) {
r = tmp_adev->asic_reset_res;
tmp_adev->asic_reset_res = 0;
if (r) {
/* bad news, how to tell it to userspace ? /* bad news, how to tell it to userspace ?
* for ras error, we should report GPU bad status instead of * for ras error, we should report GPU bad status instead of
* reset failure * reset failure
*/ */
if (reset_context->src != AMDGPU_RESET_SRC_RAS || if (reset_context->src != AMDGPU_RESET_SRC_RAS ||
!amdgpu_ras_eeprom_check_err_threshold(tmp_adev)) !amdgpu_ras_eeprom_check_err_threshold(tmp_adev))
dev_info(tmp_adev->dev, "GPU reset(%d) failed\n", dev_info(
atomic_read(&tmp_adev->gpu_reset_counter)); tmp_adev->dev,
amdgpu_vf_error_put(tmp_adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); "GPU reset(%d) failed with error %d \n",
atomic_read(
&tmp_adev->gpu_reset_counter),
tmp_adev->asic_reset_res);
amdgpu_vf_error_put(tmp_adev,
AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0,
tmp_adev->asic_reset_res);
if (!r)
r = tmp_adev->asic_reset_res;
tmp_adev->asic_reset_res = 0;
} else { } else {
dev_info(tmp_adev->dev, "GPU reset(%d) succeeded!\n", atomic_read(&tmp_adev->gpu_reset_counter)); dev_info(tmp_adev->dev, "GPU reset(%d) succeeded!\n",
atomic_read(&tmp_adev->gpu_reset_counter));
if (amdgpu_acpi_smart_shift_update(tmp_adev, if (amdgpu_acpi_smart_shift_update(tmp_adev,
AMDGPU_SS_DEV_D0)) AMDGPU_SS_DEV_D0))
dev_warn(tmp_adev->dev, dev_warn(tmp_adev->dev,
@ -7157,28 +7162,35 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
static void amdgpu_device_cache_switch_state(struct amdgpu_device *adev) static void amdgpu_device_cache_switch_state(struct amdgpu_device *adev)
{ {
struct pci_dev *parent = pci_upstream_bridge(adev->pdev); struct pci_dev *swus, *swds;
int r; int r;
if (!parent || parent->vendor != PCI_VENDOR_ID_ATI) swds = pci_upstream_bridge(adev->pdev);
if (!swds || swds->vendor != PCI_VENDOR_ID_ATI ||
pci_pcie_type(swds) != PCI_EXP_TYPE_DOWNSTREAM)
return;
swus = pci_upstream_bridge(swds);
if (!swus ||
(swus->vendor != PCI_VENDOR_ID_ATI &&
swus->vendor != PCI_VENDOR_ID_AMD) ||
pci_pcie_type(swus) != PCI_EXP_TYPE_UPSTREAM)
return; return;
/* If already saved, return */ /* If already saved, return */
if (adev->pcie_reset_ctx.swus) if (adev->pcie_reset_ctx.swus)
return; return;
/* Upstream bridge is ATI, assume it's SWUS/DS architecture */ /* Upstream bridge is ATI, assume it's SWUS/DS architecture */
r = pci_save_state(parent); r = pci_save_state(swds);
if (r) if (r)
return; return;
adev->pcie_reset_ctx.swds_pcistate = pci_store_saved_state(parent); adev->pcie_reset_ctx.swds_pcistate = pci_store_saved_state(swds);
parent = pci_upstream_bridge(parent); r = pci_save_state(swus);
r = pci_save_state(parent);
if (r) if (r)
return; return;
adev->pcie_reset_ctx.swus_pcistate = pci_store_saved_state(parent); adev->pcie_reset_ctx.swus_pcistate = pci_store_saved_state(swus);
adev->pcie_reset_ctx.swus = parent; adev->pcie_reset_ctx.swus = swus;
} }
static void amdgpu_device_load_switch_state(struct amdgpu_device *adev) static void amdgpu_device_load_switch_state(struct amdgpu_device *adev)

View File

@ -1102,6 +1102,9 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_
might_sleep(); might_sleep();
while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
if (amdgpu_in_reset(adev))
goto failed_kiq_read;
msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
} }
@ -1171,6 +1174,8 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint3
might_sleep(); might_sleep();
while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
if (amdgpu_in_reset(adev))
goto failed_kiq_write;
msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);

View File

@ -1421,14 +1421,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
amdgpu_debugfs_vm_init(file_priv); amdgpu_debugfs_vm_init(file_priv);
r = amdgpu_vm_init(adev, &fpriv->vm, fpriv->xcp_id); r = amdgpu_vm_init(adev, &fpriv->vm, fpriv->xcp_id, pasid);
if (r) if (r)
goto error_pasid; goto error_pasid;
r = amdgpu_vm_set_pasid(adev, &fpriv->vm, pasid);
if (r)
goto error_vm;
fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL); fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL);
if (!fpriv->prt_va) { if (!fpriv->prt_va) {
r = -ENOMEM; r = -ENOMEM;
@ -1468,10 +1464,8 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
amdgpu_vm_fini(adev, &fpriv->vm); amdgpu_vm_fini(adev, &fpriv->vm);
error_pasid: error_pasid:
if (pasid) { if (pasid)
amdgpu_pasid_free(pasid); amdgpu_pasid_free(pasid);
amdgpu_vm_set_pasid(adev, &fpriv->vm, 0);
}
kfree(fpriv); kfree(fpriv);

View File

@ -2352,7 +2352,7 @@ static int psp_securedisplay_initialize(struct psp_context *psp)
} }
ret = psp_ta_load(psp, &psp->securedisplay_context.context); ret = psp_ta_load(psp, &psp->securedisplay_context.context);
if (!ret) { if (!ret && !psp->securedisplay_context.context.resp_status) {
psp->securedisplay_context.context.initialized = true; psp->securedisplay_context.context.initialized = true;
mutex_init(&psp->securedisplay_context.mutex); mutex_init(&psp->securedisplay_context.mutex);
} else } else

View File

@ -726,12 +726,12 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
int ret; int ret;
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
while (!list_empty(&vm->invalidated)) { while (!list_empty(&vm->invalidated)) {
bo_va = list_first_entry(&vm->invalidated, bo_va = list_first_entry(&vm->invalidated,
struct amdgpu_bo_va, struct amdgpu_bo_va,
base.vm_status); base.vm_status);
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
bo = bo_va->base.bo; bo = bo_va->base.bo;
ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 2); ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 2);
@ -748,9 +748,9 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
if (ret) if (ret)
return ret; return ret;
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
} }
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
return 0; return 0;
} }

View File

@ -138,48 +138,6 @@ static void amdgpu_vm_assert_locked(struct amdgpu_vm *vm)
dma_resv_assert_held(vm->root.bo->tbo.base.resv); dma_resv_assert_held(vm->root.bo->tbo.base.resv);
} }
/**
* amdgpu_vm_set_pasid - manage pasid and vm ptr mapping
*
* @adev: amdgpu_device pointer
* @vm: amdgpu_vm pointer
* @pasid: the pasid the VM is using on this GPU
*
* Set the pasid this VM is using on this GPU, can also be used to remove the
* pasid by passing in zero.
*
*/
int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
u32 pasid)
{
int r;
amdgpu_vm_assert_locked(vm);
if (vm->pasid == pasid)
return 0;
if (vm->pasid) {
r = xa_err(xa_erase_irq(&adev->vm_manager.pasids, vm->pasid));
if (r < 0)
return r;
vm->pasid = 0;
}
if (pasid) {
r = xa_err(xa_store_irq(&adev->vm_manager.pasids, pasid, vm,
GFP_KERNEL));
if (r < 0)
return r;
vm->pasid = pasid;
}
return 0;
}
/** /**
* amdgpu_vm_bo_evicted - vm_bo is evicted * amdgpu_vm_bo_evicted - vm_bo is evicted
* *
@ -195,10 +153,12 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
vm_bo->moved = true; vm_bo->moved = true;
amdgpu_vm_assert_locked(vm); amdgpu_vm_assert_locked(vm);
spin_lock(&vm_bo->vm->status_lock);
if (bo->tbo.type == ttm_bo_type_kernel) if (bo->tbo.type == ttm_bo_type_kernel)
list_move(&vm_bo->vm_status, &vm->evicted); list_move(&vm_bo->vm_status, &vm->evicted);
else else
list_move_tail(&vm_bo->vm_status, &vm->evicted); list_move_tail(&vm_bo->vm_status, &vm->evicted);
spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
* amdgpu_vm_bo_moved - vm_bo is moved * amdgpu_vm_bo_moved - vm_bo is moved
@ -211,7 +171,9 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
{ {
amdgpu_vm_assert_locked(vm_bo->vm); amdgpu_vm_assert_locked(vm_bo->vm);
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->moved); list_move(&vm_bo->vm_status, &vm_bo->vm->moved);
spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -225,7 +187,9 @@ static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
{ {
amdgpu_vm_assert_locked(vm_bo->vm); amdgpu_vm_assert_locked(vm_bo->vm);
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->idle); list_move(&vm_bo->vm_status, &vm_bo->vm->idle);
spin_unlock(&vm_bo->vm->status_lock);
vm_bo->moved = false; vm_bo->moved = false;
} }
@ -239,9 +203,9 @@ static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
{ {
spin_lock(&vm_bo->vm->invalidated_lock); spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated); list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated);
spin_unlock(&vm_bo->vm->invalidated_lock); spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -254,9 +218,10 @@ static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)
{ {
amdgpu_vm_assert_locked(vm_bo->vm);
vm_bo->moved = true; vm_bo->moved = true;
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->evicted_user); list_move(&vm_bo->vm_status, &vm_bo->vm->evicted_user);
spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -270,10 +235,13 @@ static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
{ {
amdgpu_vm_assert_locked(vm_bo->vm); amdgpu_vm_assert_locked(vm_bo->vm);
if (vm_bo->bo->parent) if (vm_bo->bo->parent) {
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated); list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
else spin_unlock(&vm_bo->vm->status_lock);
} else {
amdgpu_vm_bo_idle(vm_bo); amdgpu_vm_bo_idle(vm_bo);
}
} }
/** /**
@ -287,7 +255,9 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
{ {
amdgpu_vm_assert_locked(vm_bo->vm); amdgpu_vm_assert_locked(vm_bo->vm);
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->done); list_move(&vm_bo->vm_status, &vm_bo->vm->done);
spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -301,13 +271,13 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
{ {
struct amdgpu_vm_bo_base *vm_bo, *tmp; struct amdgpu_vm_bo_base *vm_bo, *tmp;
spin_lock(&vm->invalidated_lock); amdgpu_vm_assert_locked(vm);
spin_lock(&vm->status_lock);
list_splice_init(&vm->done, &vm->invalidated); list_splice_init(&vm->done, &vm->invalidated);
list_for_each_entry(vm_bo, &vm->invalidated, vm_status) list_for_each_entry(vm_bo, &vm->invalidated, vm_status)
vm_bo->moved = true; vm_bo->moved = true;
spin_unlock(&vm->invalidated_lock);
amdgpu_vm_assert_locked(vm_bo->vm);
list_for_each_entry_safe(vm_bo, tmp, &vm->idle, vm_status) { list_for_each_entry_safe(vm_bo, tmp, &vm->idle, vm_status) {
struct amdgpu_bo *bo = vm_bo->bo; struct amdgpu_bo *bo = vm_bo->bo;
@ -317,13 +287,14 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
else if (bo->parent) else if (bo->parent)
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated); list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
} }
spin_unlock(&vm->status_lock);
} }
/** /**
* amdgpu_vm_update_shared - helper to update shared memory stat * amdgpu_vm_update_shared - helper to update shared memory stat
* @base: base structure for tracking BO usage in a VM * @base: base structure for tracking BO usage in a VM
* *
* Takes the vm stats_lock and updates the shared memory stat. If the basic * Takes the vm status_lock and updates the shared memory stat. If the basic
* stat changed (e.g. buffer was moved) amdgpu_vm_update_stats need to be called * stat changed (e.g. buffer was moved) amdgpu_vm_update_stats need to be called
* as well. * as well.
*/ */
@ -336,7 +307,7 @@ static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base)
bool shared; bool shared;
dma_resv_assert_held(bo->tbo.base.resv); dma_resv_assert_held(bo->tbo.base.resv);
spin_lock(&vm->stats_lock); spin_lock(&vm->status_lock);
shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base); shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base);
if (base->shared != shared) { if (base->shared != shared) {
base->shared = shared; base->shared = shared;
@ -348,7 +319,7 @@ static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base)
vm->stats[bo_memtype].drm.private += size; vm->stats[bo_memtype].drm.private += size;
} }
} }
spin_unlock(&vm->stats_lock); spin_unlock(&vm->status_lock);
} }
/** /**
@ -373,11 +344,11 @@ void amdgpu_vm_bo_update_shared(struct amdgpu_bo *bo)
* be bo->tbo.resource * be bo->tbo.resource
* @sign: if we should add (+1) or subtract (-1) from the stat * @sign: if we should add (+1) or subtract (-1) from the stat
* *
* Caller need to have the vm stats_lock held. Useful for when multiple update * Caller need to have the vm status_lock held. Useful for when multiple update
* need to happen at the same time. * need to happen at the same time.
*/ */
static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base, static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base,
struct ttm_resource *res, int sign) struct ttm_resource *res, int sign)
{ {
struct amdgpu_vm *vm = base->vm; struct amdgpu_vm *vm = base->vm;
struct amdgpu_bo *bo = base->bo; struct amdgpu_bo *bo = base->bo;
@ -401,8 +372,7 @@ static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base,
*/ */
if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE)
vm->stats[res_memtype].drm.purgeable += size; vm->stats[res_memtype].drm.purgeable += size;
if (!(bo->preferred_domains & if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(res_memtype)))
amdgpu_mem_type_to_domain(res_memtype)))
vm->stats[bo_memtype].evicted += size; vm->stats[bo_memtype].evicted += size;
} }
} }
@ -421,9 +391,9 @@ void amdgpu_vm_update_stats(struct amdgpu_vm_bo_base *base,
{ {
struct amdgpu_vm *vm = base->vm; struct amdgpu_vm *vm = base->vm;
spin_lock(&vm->stats_lock); spin_lock(&vm->status_lock);
amdgpu_vm_update_stats_locked(base, res, sign); amdgpu_vm_update_stats_locked(base, res, sign);
spin_unlock(&vm->stats_lock); spin_unlock(&vm->status_lock);
} }
/** /**
@ -449,10 +419,10 @@ void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
base->next = bo->vm_bo; base->next = bo->vm_bo;
bo->vm_bo = base; bo->vm_bo = base;
spin_lock(&vm->stats_lock); spin_lock(&vm->status_lock);
base->shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base); base->shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base);
amdgpu_vm_update_stats_locked(base, bo->tbo.resource, +1); amdgpu_vm_update_stats_locked(base, bo->tbo.resource, +1);
spin_unlock(&vm->stats_lock); spin_unlock(&vm->status_lock);
if (!amdgpu_vm_is_bo_always_valid(vm, bo)) if (!amdgpu_vm_is_bo_always_valid(vm, bo))
return; return;
@ -511,10 +481,10 @@ int amdgpu_vm_lock_done_list(struct amdgpu_vm *vm, struct drm_exec *exec,
int ret; int ret;
/* We can only trust prev->next while holding the lock */ /* We can only trust prev->next while holding the lock */
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
while (!list_is_head(prev->next, &vm->done)) { while (!list_is_head(prev->next, &vm->done)) {
bo_va = list_entry(prev->next, typeof(*bo_va), base.vm_status); bo_va = list_entry(prev->next, typeof(*bo_va), base.vm_status);
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
bo = bo_va->base.bo; bo = bo_va->base.bo;
if (bo) { if (bo) {
@ -522,10 +492,10 @@ int amdgpu_vm_lock_done_list(struct amdgpu_vm *vm, struct drm_exec *exec,
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
} }
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
prev = prev->next; prev = prev->next;
} }
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
return 0; return 0;
} }
@ -621,7 +591,7 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
void *param) void *param)
{ {
uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm); uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm);
struct amdgpu_vm_bo_base *bo_base, *tmp; struct amdgpu_vm_bo_base *bo_base;
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
int r; int r;
@ -634,7 +604,13 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
return r; return r;
} }
list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) { spin_lock(&vm->status_lock);
while (!list_empty(&vm->evicted)) {
bo_base = list_first_entry(&vm->evicted,
struct amdgpu_vm_bo_base,
vm_status);
spin_unlock(&vm->status_lock);
bo = bo_base->bo; bo = bo_base->bo;
r = validate(param, bo); r = validate(param, bo);
@ -647,21 +623,26 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
vm->update_funcs->map_table(to_amdgpu_bo_vm(bo)); vm->update_funcs->map_table(to_amdgpu_bo_vm(bo));
amdgpu_vm_bo_relocated(bo_base); amdgpu_vm_bo_relocated(bo_base);
} }
spin_lock(&vm->status_lock);
} }
while (ticket && !list_empty(&vm->evicted_user)) {
bo_base = list_first_entry(&vm->evicted_user,
struct amdgpu_vm_bo_base,
vm_status);
spin_unlock(&vm->status_lock);
if (ticket) { bo = bo_base->bo;
list_for_each_entry_safe(bo_base, tmp, &vm->evicted_user, dma_resv_assert_held(bo->tbo.base.resv);
vm_status) {
bo = bo_base->bo;
dma_resv_assert_held(bo->tbo.base.resv);
r = validate(param, bo); r = validate(param, bo);
if (r) if (r)
return r; return r;
amdgpu_vm_bo_invalidated(bo_base); amdgpu_vm_bo_invalidated(bo_base);
}
spin_lock(&vm->status_lock);
} }
spin_unlock(&vm->status_lock);
amdgpu_vm_eviction_lock(vm); amdgpu_vm_eviction_lock(vm);
vm->evicting = false; vm->evicting = false;
@ -690,7 +671,9 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
ret = !vm->evicting; ret = !vm->evicting;
amdgpu_vm_eviction_unlock(vm); amdgpu_vm_eviction_unlock(vm);
spin_lock(&vm->status_lock);
ret &= list_empty(&vm->evicted); ret &= list_empty(&vm->evicted);
spin_unlock(&vm->status_lock);
spin_lock(&vm->immediate.lock); spin_lock(&vm->immediate.lock);
ret &= !vm->immediate.stopped; ret &= !vm->immediate.stopped;
@ -981,13 +964,18 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
struct amdgpu_vm *vm, bool immediate) struct amdgpu_vm *vm, bool immediate)
{ {
struct amdgpu_vm_update_params params; struct amdgpu_vm_update_params params;
struct amdgpu_vm_bo_base *entry, *tmp; struct amdgpu_vm_bo_base *entry;
bool flush_tlb_needed = false; bool flush_tlb_needed = false;
LIST_HEAD(relocated);
int r, idx; int r, idx;
amdgpu_vm_assert_locked(vm); amdgpu_vm_assert_locked(vm);
if (list_empty(&vm->relocated)) spin_lock(&vm->status_lock);
list_splice_init(&vm->relocated, &relocated);
spin_unlock(&vm->status_lock);
if (list_empty(&relocated))
return 0; return 0;
if (!drm_dev_enter(adev_to_drm(adev), &idx)) if (!drm_dev_enter(adev_to_drm(adev), &idx))
@ -1003,7 +991,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
if (r) if (r)
goto error; goto error;
list_for_each_entry(entry, &vm->relocated, vm_status) { list_for_each_entry(entry, &relocated, vm_status) {
/* vm_flush_needed after updating moved PDEs */ /* vm_flush_needed after updating moved PDEs */
flush_tlb_needed |= entry->moved; flush_tlb_needed |= entry->moved;
@ -1019,7 +1007,9 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
if (flush_tlb_needed) if (flush_tlb_needed)
atomic64_inc(&vm->tlb_seq); atomic64_inc(&vm->tlb_seq);
list_for_each_entry_safe(entry, tmp, &vm->relocated, vm_status) { while (!list_empty(&relocated)) {
entry = list_first_entry(&relocated, struct amdgpu_vm_bo_base,
vm_status);
amdgpu_vm_bo_idle(entry); amdgpu_vm_bo_idle(entry);
} }
@ -1246,9 +1236,9 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
void amdgpu_vm_get_memory(struct amdgpu_vm *vm, void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]) struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM])
{ {
spin_lock(&vm->stats_lock); spin_lock(&vm->status_lock);
memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM); memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM);
spin_unlock(&vm->stats_lock); spin_unlock(&vm->status_lock);
} }
/** /**
@ -1615,24 +1605,29 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
struct amdgpu_vm *vm, struct amdgpu_vm *vm,
struct ww_acquire_ctx *ticket) struct ww_acquire_ctx *ticket)
{ {
struct amdgpu_bo_va *bo_va, *tmp; struct amdgpu_bo_va *bo_va;
struct dma_resv *resv; struct dma_resv *resv;
bool clear, unlock; bool clear, unlock;
int r; int r;
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) { spin_lock(&vm->status_lock);
while (!list_empty(&vm->moved)) {
bo_va = list_first_entry(&vm->moved, struct amdgpu_bo_va,
base.vm_status);
spin_unlock(&vm->status_lock);
/* Per VM BOs never need to bo cleared in the page tables */ /* Per VM BOs never need to bo cleared in the page tables */
r = amdgpu_vm_bo_update(adev, bo_va, false); r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r) if (r)
return r; return r;
spin_lock(&vm->status_lock);
} }
spin_lock(&vm->invalidated_lock);
while (!list_empty(&vm->invalidated)) { while (!list_empty(&vm->invalidated)) {
bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va, bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va,
base.vm_status); base.vm_status);
resv = bo_va->base.bo->tbo.base.resv; resv = bo_va->base.bo->tbo.base.resv;
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
/* Try to reserve the BO to avoid clearing its ptes */ /* Try to reserve the BO to avoid clearing its ptes */
if (!adev->debug_vm && dma_resv_trylock(resv)) { if (!adev->debug_vm && dma_resv_trylock(resv)) {
@ -1664,9 +1659,9 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
bo_va->base.bo->tbo.resource->mem_type == TTM_PL_SYSTEM)) bo_va->base.bo->tbo.resource->mem_type == TTM_PL_SYSTEM))
amdgpu_vm_bo_evicted_user(&bo_va->base); amdgpu_vm_bo_evicted_user(&bo_va->base);
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
} }
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
return 0; return 0;
} }
@ -2195,9 +2190,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev,
} }
} }
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
list_del(&bo_va->base.vm_status); list_del(&bo_va->base.vm_status);
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
list_del(&mapping->list); list_del(&mapping->list);
@ -2305,10 +2300,10 @@ void amdgpu_vm_bo_move(struct amdgpu_bo *bo, struct ttm_resource *new_mem,
for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) { for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) {
struct amdgpu_vm *vm = bo_base->vm; struct amdgpu_vm *vm = bo_base->vm;
spin_lock(&vm->stats_lock); spin_lock(&vm->status_lock);
amdgpu_vm_update_stats_locked(bo_base, bo->tbo.resource, -1); amdgpu_vm_update_stats_locked(bo_base, bo->tbo.resource, -1);
amdgpu_vm_update_stats_locked(bo_base, new_mem, +1); amdgpu_vm_update_stats_locked(bo_base, new_mem, +1);
spin_unlock(&vm->stats_lock); spin_unlock(&vm->status_lock);
} }
amdgpu_vm_bo_invalidate(bo, evicted); amdgpu_vm_bo_invalidate(bo, evicted);
@ -2554,6 +2549,7 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @vm: requested vm * @vm: requested vm
* @xcp_id: GPU partition selection id * @xcp_id: GPU partition selection id
* @pasid: the pasid the VM is using on this GPU
* *
* Init @vm fields. * Init @vm fields.
* *
@ -2561,7 +2557,7 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
* 0 for success, error for failure. * 0 for success, error for failure.
*/ */
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int32_t xcp_id) int32_t xcp_id, uint32_t pasid)
{ {
struct amdgpu_bo *root_bo; struct amdgpu_bo *root_bo;
struct amdgpu_bo_vm *root; struct amdgpu_bo_vm *root;
@ -2575,12 +2571,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
INIT_LIST_HEAD(&vm->relocated); INIT_LIST_HEAD(&vm->relocated);
INIT_LIST_HEAD(&vm->moved); INIT_LIST_HEAD(&vm->moved);
INIT_LIST_HEAD(&vm->idle); INIT_LIST_HEAD(&vm->idle);
spin_lock_init(&vm->invalidated_lock);
INIT_LIST_HEAD(&vm->invalidated); INIT_LIST_HEAD(&vm->invalidated);
spin_lock_init(&vm->status_lock);
INIT_LIST_HEAD(&vm->freed); INIT_LIST_HEAD(&vm->freed);
INIT_LIST_HEAD(&vm->done); INIT_LIST_HEAD(&vm->done);
INIT_KFIFO(vm->faults); INIT_KFIFO(vm->faults);
spin_lock_init(&vm->stats_lock);
r = amdgpu_vm_init_entities(adev, vm); r = amdgpu_vm_init_entities(adev, vm);
if (r) if (r)
@ -2638,12 +2633,26 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r) if (r)
dev_dbg(adev->dev, "Failed to create task info for VM\n"); dev_dbg(adev->dev, "Failed to create task info for VM\n");
/* Store new PASID in XArray (if non-zero) */
if (pasid != 0) {
r = xa_err(xa_store_irq(&adev->vm_manager.pasids, pasid, vm, GFP_KERNEL));
if (r < 0)
goto error_free_root;
vm->pasid = pasid;
}
amdgpu_bo_unreserve(vm->root.bo); amdgpu_bo_unreserve(vm->root.bo);
amdgpu_bo_unref(&root_bo); amdgpu_bo_unref(&root_bo);
return 0; return 0;
error_free_root: error_free_root:
/* If PASID was partially set, erase it from XArray before failing */
if (vm->pasid != 0) {
xa_erase_irq(&adev->vm_manager.pasids, vm->pasid);
vm->pasid = 0;
}
amdgpu_vm_pt_free_root(adev, vm); amdgpu_vm_pt_free_root(adev, vm);
amdgpu_bo_unreserve(vm->root.bo); amdgpu_bo_unreserve(vm->root.bo);
amdgpu_bo_unref(&root_bo); amdgpu_bo_unref(&root_bo);
@ -2749,7 +2758,11 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
root = amdgpu_bo_ref(vm->root.bo); root = amdgpu_bo_ref(vm->root.bo);
amdgpu_bo_reserve(root, true); amdgpu_bo_reserve(root, true);
amdgpu_vm_set_pasid(adev, vm, 0); /* Remove PASID mapping before destroying VM */
if (vm->pasid != 0) {
xa_erase_irq(&adev->vm_manager.pasids, vm->pasid);
vm->pasid = 0;
}
dma_fence_wait(vm->last_unlocked, false); dma_fence_wait(vm->last_unlocked, false);
dma_fence_put(vm->last_unlocked); dma_fence_put(vm->last_unlocked);
dma_fence_wait(vm->last_tlb_flush, false); dma_fence_wait(vm->last_tlb_flush, false);
@ -3038,6 +3051,7 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
amdgpu_vm_assert_locked(vm); amdgpu_vm_assert_locked(vm);
spin_lock(&vm->status_lock);
seq_puts(m, "\tIdle BOs:\n"); seq_puts(m, "\tIdle BOs:\n");
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
@ -3075,13 +3089,11 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
id = 0; id = 0;
seq_puts(m, "\tInvalidated BOs:\n"); seq_puts(m, "\tInvalidated BOs:\n");
spin_lock(&vm->invalidated_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m); total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
} }
spin_unlock(&vm->invalidated_lock);
total_invalidated_objs = id; total_invalidated_objs = id;
id = 0; id = 0;
@ -3091,6 +3103,7 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
continue; continue;
total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m); total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
} }
spin_unlock(&vm->status_lock);
total_done_objs = id; total_done_objs = id;
seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle, seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,

View File

@ -203,11 +203,11 @@ struct amdgpu_vm_bo_base {
/* protected by bo being reserved */ /* protected by bo being reserved */
struct amdgpu_vm_bo_base *next; struct amdgpu_vm_bo_base *next;
/* protected by vm reservation and invalidated_lock */ /* protected by vm status_lock */
struct list_head vm_status; struct list_head vm_status;
/* if the bo is counted as shared in mem stats /* if the bo is counted as shared in mem stats
* protected by vm BO being reserved */ * protected by vm status_lock */
bool shared; bool shared;
/* protected by the BO being reserved */ /* protected by the BO being reserved */
@ -343,8 +343,10 @@ struct amdgpu_vm {
bool evicting; bool evicting;
unsigned int saved_flags; unsigned int saved_flags;
/* Memory statistics for this vm, protected by stats_lock */ /* Lock to protect vm_bo add/del/move on all lists of vm */
spinlock_t stats_lock; spinlock_t status_lock;
/* Memory statistics for this vm, protected by status_lock */
struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]; struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM];
/* /*
@ -352,8 +354,6 @@ struct amdgpu_vm {
* PDs, PTs or per VM BOs. The state transits are: * PDs, PTs or per VM BOs. The state transits are:
* *
* evicted -> relocated (PDs, PTs) or moved (per VM BOs) -> idle * evicted -> relocated (PDs, PTs) or moved (per VM BOs) -> idle
*
* Lists are protected by the root PD dma_resv lock.
*/ */
/* Per-VM and PT BOs who needs a validation */ /* Per-VM and PT BOs who needs a validation */
@ -374,10 +374,7 @@ struct amdgpu_vm {
* state transits are: * state transits are:
* *
* evicted_user or invalidated -> done * evicted_user or invalidated -> done
*
* Lists are protected by the invalidated_lock.
*/ */
spinlock_t invalidated_lock;
/* BOs for user mode queues that need a validation */ /* BOs for user mode queues that need a validation */
struct list_head evicted_user; struct list_head evicted_user;
@ -503,11 +500,8 @@ extern const struct amdgpu_vm_update_funcs amdgpu_vm_sdma_funcs;
void amdgpu_vm_manager_init(struct amdgpu_device *adev); void amdgpu_vm_manager_init(struct amdgpu_device *adev);
void amdgpu_vm_manager_fini(struct amdgpu_device *adev); void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
u32 pasid);
long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout); long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout);
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id); int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id, uint32_t pasid);
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm); int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec, int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec,

View File

@ -543,7 +543,9 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
entry->bo->vm_bo = NULL; entry->bo->vm_bo = NULL;
ttm_bo_set_bulk_move(&entry->bo->tbo, NULL); ttm_bo_set_bulk_move(&entry->bo->tbo, NULL);
spin_lock(&entry->vm->status_lock);
list_del(&entry->vm_status); list_del(&entry->vm_status);
spin_unlock(&entry->vm->status_lock);
amdgpu_bo_unref(&entry->bo); amdgpu_bo_unref(&entry->bo);
} }
@ -587,6 +589,7 @@ static void amdgpu_vm_pt_add_list(struct amdgpu_vm_update_params *params,
struct amdgpu_vm_pt_cursor seek; struct amdgpu_vm_pt_cursor seek;
struct amdgpu_vm_bo_base *entry; struct amdgpu_vm_bo_base *entry;
spin_lock(&params->vm->status_lock);
for_each_amdgpu_vm_pt_dfs_safe(params->adev, params->vm, cursor, seek, entry) { for_each_amdgpu_vm_pt_dfs_safe(params->adev, params->vm, cursor, seek, entry) {
if (entry && entry->bo) if (entry && entry->bo)
list_move(&entry->vm_status, &params->tlb_flush_waitlist); list_move(&entry->vm_status, &params->tlb_flush_waitlist);
@ -594,6 +597,7 @@ static void amdgpu_vm_pt_add_list(struct amdgpu_vm_update_params *params,
/* enter start node now */ /* enter start node now */
list_move(&cursor->entry->vm_status, &params->tlb_flush_waitlist); list_move(&cursor->entry->vm_status, &params->tlb_flush_waitlist);
spin_unlock(&params->vm->status_lock);
} }
/** /**

View File

@ -337,7 +337,7 @@ static void gmc_v12_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
int vmid, i; int vmid, i;
if (adev->enable_uni_mes && adev->mes.ring[AMDGPU_MES_SCHED_PIPE].sched.ready && if (adev->enable_uni_mes && adev->mes.ring[AMDGPU_MES_SCHED_PIPE].sched.ready &&
(adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x83) { (adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x84) {
struct mes_inv_tlbs_pasid_input input = {0}; struct mes_inv_tlbs_pasid_input input = {0};
input.pasid = pasid; input.pasid = pasid;
input.flush_type = flush_type; input.flush_type = flush_type;

View File

@ -3045,6 +3045,8 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
if (svms->checkpoint_ts[gpuidx] != 0) { if (svms->checkpoint_ts[gpuidx] != 0) {
if (amdgpu_ih_ts_after_or_equal(ts, svms->checkpoint_ts[gpuidx])) { if (amdgpu_ih_ts_after_or_equal(ts, svms->checkpoint_ts[gpuidx])) {
pr_debug("draining retry fault, drop fault 0x%llx\n", addr); pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
if (write_locked)
mmap_write_downgrade(mm);
r = -EAGAIN; r = -EAGAIN;
goto out_unlock_svms; goto out_unlock_svms;
} else { } else {

View File

@ -2000,6 +2000,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.flags.disable_ips_in_vpb = 0; init_data.flags.disable_ips_in_vpb = 0;
/* DCN35 and above supports dynamic DTBCLK switch */
if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 5, 0))
init_data.flags.allow_0_dtb_clk = true;
/* Enable DWB for tested platforms only */ /* Enable DWB for tested platforms only */
if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0)) if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0))
init_data.num_virtual_links = 1; init_data.num_virtual_links = 1;

View File

@ -154,10 +154,13 @@ static bool dce60_setup_scaling_configuration(
REG_SET(SCL_BYPASS_CONTROL, 0, SCL_BYPASS_MODE, 0); REG_SET(SCL_BYPASS_CONTROL, 0, SCL_BYPASS_MODE, 0);
if (data->taps.h_taps + data->taps.v_taps <= 2) { if (data->taps.h_taps + data->taps.v_taps <= 2) {
/* Set bypass */ /* Disable scaler functionality */
REG_WRITE(SCL_SCALER_ENABLE, 0);
/* DCE6 has no SCL_MODE register, skip scale mode programming */
/* Clear registers that can cause glitches even when the scaler is off */
REG_WRITE(SCL_TAP_CONTROL, 0);
REG_WRITE(SCL_AUTOMATIC_MODE_CONTROL, 0);
REG_WRITE(SCL_F_SHARP_CONTROL, 0);
return false; return false;
} }
@ -165,7 +168,7 @@ static bool dce60_setup_scaling_configuration(
SCL_H_NUM_OF_TAPS, data->taps.h_taps - 1, SCL_H_NUM_OF_TAPS, data->taps.h_taps - 1,
SCL_V_NUM_OF_TAPS, data->taps.v_taps - 1); SCL_V_NUM_OF_TAPS, data->taps.v_taps - 1);
/* DCE6 has no SCL_MODE register, skip scale mode programming */ REG_WRITE(SCL_SCALER_ENABLE, 1);
/* DCE6 has no SCL_BOUNDARY_MODE bit, skip replace out of bound pixels */ /* DCE6 has no SCL_BOUNDARY_MODE bit, skip replace out of bound pixels */
@ -502,6 +505,8 @@ static void dce60_transform_set_scaler(
REG_SET(DC_LB_MEM_SIZE, 0, REG_SET(DC_LB_MEM_SIZE, 0,
DC_LB_MEM_SIZE, xfm_dce->lb_memory_size); DC_LB_MEM_SIZE, xfm_dce->lb_memory_size);
REG_WRITE(SCL_UPDATE, 0x00010000);
/* Clear SCL_F_SHARP_CONTROL value to 0 */ /* Clear SCL_F_SHARP_CONTROL value to 0 */
REG_WRITE(SCL_F_SHARP_CONTROL, 0); REG_WRITE(SCL_F_SHARP_CONTROL, 0);
@ -527,8 +532,7 @@ static void dce60_transform_set_scaler(
if (coeffs_v != xfm_dce->filter_v || coeffs_h != xfm_dce->filter_h) { if (coeffs_v != xfm_dce->filter_v || coeffs_h != xfm_dce->filter_h) {
/* 4. Program vertical filters */ /* 4. Program vertical filters */
if (xfm_dce->filter_v == NULL) if (xfm_dce->filter_v == NULL)
REG_SET(SCL_VERT_FILTER_CONTROL, 0, REG_WRITE(SCL_VERT_FILTER_CONTROL, 0);
SCL_V_2TAP_HARDCODE_COEF_EN, 0);
program_multi_taps_filter( program_multi_taps_filter(
xfm_dce, xfm_dce,
data->taps.v_taps, data->taps.v_taps,
@ -542,8 +546,7 @@ static void dce60_transform_set_scaler(
/* 5. Program horizontal filters */ /* 5. Program horizontal filters */
if (xfm_dce->filter_h == NULL) if (xfm_dce->filter_h == NULL)
REG_SET(SCL_HORZ_FILTER_CONTROL, 0, REG_WRITE(SCL_HORZ_FILTER_CONTROL, 0);
SCL_H_2TAP_HARDCODE_COEF_EN, 0);
program_multi_taps_filter( program_multi_taps_filter(
xfm_dce, xfm_dce,
data->taps.h_taps, data->taps.h_taps,
@ -566,6 +569,8 @@ static void dce60_transform_set_scaler(
/* DCE6 has no SCL_COEF_UPDATE_COMPLETE bit to flip to new coefficient memory */ /* DCE6 has no SCL_COEF_UPDATE_COMPLETE bit to flip to new coefficient memory */
/* DCE6 DATA_FORMAT register does not support ALPHA_EN */ /* DCE6 DATA_FORMAT register does not support ALPHA_EN */
REG_WRITE(SCL_UPDATE, 0);
} }
#endif #endif

View File

@ -155,6 +155,9 @@
SRI(SCL_COEF_RAM_TAP_DATA, SCL, id), \ SRI(SCL_COEF_RAM_TAP_DATA, SCL, id), \
SRI(VIEWPORT_START, SCL, id), \ SRI(VIEWPORT_START, SCL, id), \
SRI(VIEWPORT_SIZE, SCL, id), \ SRI(VIEWPORT_SIZE, SCL, id), \
SRI(SCL_SCALER_ENABLE, SCL, id), \
SRI(SCL_HORZ_FILTER_INIT_RGB_LUMA, SCL, id), \
SRI(SCL_HORZ_FILTER_INIT_CHROMA, SCL, id), \
SRI(SCL_HORZ_FILTER_SCALE_RATIO, SCL, id), \ SRI(SCL_HORZ_FILTER_SCALE_RATIO, SCL, id), \
SRI(SCL_VERT_FILTER_SCALE_RATIO, SCL, id), \ SRI(SCL_VERT_FILTER_SCALE_RATIO, SCL, id), \
SRI(SCL_VERT_FILTER_INIT, SCL, id), \ SRI(SCL_VERT_FILTER_INIT, SCL, id), \
@ -590,6 +593,7 @@ struct dce_transform_registers {
uint32_t SCL_VERT_FILTER_SCALE_RATIO; uint32_t SCL_VERT_FILTER_SCALE_RATIO;
uint32_t SCL_HORZ_FILTER_INIT; uint32_t SCL_HORZ_FILTER_INIT;
#if defined(CONFIG_DRM_AMD_DC_SI) #if defined(CONFIG_DRM_AMD_DC_SI)
uint32_t SCL_SCALER_ENABLE;
uint32_t SCL_HORZ_FILTER_INIT_RGB_LUMA; uint32_t SCL_HORZ_FILTER_INIT_RGB_LUMA;
uint32_t SCL_HORZ_FILTER_INIT_CHROMA; uint32_t SCL_HORZ_FILTER_INIT_CHROMA;
#endif #endif

View File

@ -808,6 +808,8 @@ void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc) int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc)
{ {
dc_assert_fp_enabled();
return soc->clock_limits[0].dispclk_mhz * 10000.0 / (1.0 + soc->dcn_downspread_percent / 100.0); return soc->clock_limits[0].dispclk_mhz * 10000.0 / (1.0 + soc->dcn_downspread_percent / 100.0);
} }
@ -815,6 +817,8 @@ int dcn_get_approx_det_segs_required_for_pstate(
struct _vcs_dpi_soc_bounding_box_st *soc, struct _vcs_dpi_soc_bounding_box_st *soc,
int pix_clk_100hz, int bpp, int seg_size_kb) int pix_clk_100hz, int bpp, int seg_size_kb)
{ {
dc_assert_fp_enabled();
/* Roughly calculate required crb to hide latency. In practice there is slightly /* Roughly calculate required crb to hide latency. In practice there is slightly
* more buffer available for latency hiding * more buffer available for latency hiding
*/ */

View File

@ -445,6 +445,8 @@ int dcn35_populate_dml_pipes_from_context_fpu(struct dc *dc,
bool upscaled = false; bool upscaled = false;
const unsigned int max_allowed_vblank_nom = 1023; const unsigned int max_allowed_vblank_nom = 1023;
dc_assert_fp_enabled();
dcn31_populate_dml_pipes_from_context(dc, context, pipes, dcn31_populate_dml_pipes_from_context(dc, context, pipes,
validate_mode); validate_mode);
@ -498,9 +500,7 @@ int dcn35_populate_dml_pipes_from_context_fpu(struct dc *dc,
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
DC_FP_START();
dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt); dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
DC_FP_END();
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3; pipes[pipe_cnt].pipe.src.dcc_rate = 3;
@ -581,6 +581,8 @@ void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context)
unsigned int i, plane_count = 0; unsigned int i, plane_count = 0;
DC_LOGGER_INIT(dc->ctx->logger); DC_LOGGER_INIT(dc->ctx->logger);
dc_assert_fp_enabled();
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (context->res_ctx.pipe_ctx[i].plane_state) if (context->res_ctx.pipe_ctx[i].plane_state)
plane_count++; plane_count++;

View File

@ -478,6 +478,8 @@ int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc,
bool upscaled = false; bool upscaled = false;
const unsigned int max_allowed_vblank_nom = 1023; const unsigned int max_allowed_vblank_nom = 1023;
dc_assert_fp_enabled();
dcn31_populate_dml_pipes_from_context(dc, context, pipes, dcn31_populate_dml_pipes_from_context(dc, context, pipes,
validate_mode); validate_mode);
@ -531,9 +533,7 @@ int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc,
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
DC_FP_START();
dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt); dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
DC_FP_END();
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3; pipes[pipe_cnt].pipe.src.dcc_rate = 3;

View File

@ -404,13 +404,13 @@ static const struct dc_plane_cap plane_cap = {
}, },
.max_upscale_factor = { .max_upscale_factor = {
.argb8888 = 16000, .argb8888 = 1,
.nv12 = 1, .nv12 = 1,
.fp16 = 1 .fp16 = 1
}, },
.max_downscale_factor = { .max_downscale_factor = {
.argb8888 = 250, .argb8888 = 1,
.nv12 = 1, .nv12 = 1,
.fp16 = 1 .fp16 = 1
} }

View File

@ -1760,6 +1760,20 @@ enum dc_status dcn35_patch_unknown_plane_state(struct dc_plane_state *plane_stat
} }
static int populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode)
{
int ret;
DC_FP_START();
ret = dcn35_populate_dml_pipes_from_context_fpu(dc, context, pipes, validate_mode);
DC_FP_END();
return ret;
}
static struct resource_funcs dcn35_res_pool_funcs = { static struct resource_funcs dcn35_res_pool_funcs = {
.destroy = dcn35_destroy_resource_pool, .destroy = dcn35_destroy_resource_pool,
.link_enc_create = dcn35_link_encoder_create, .link_enc_create = dcn35_link_encoder_create,
@ -1770,7 +1784,7 @@ static struct resource_funcs dcn35_res_pool_funcs = {
.validate_bandwidth = dcn35_validate_bandwidth, .validate_bandwidth = dcn35_validate_bandwidth,
.calculate_wm_and_dlg = NULL, .calculate_wm_and_dlg = NULL,
.update_soc_for_wm_a = dcn31_update_soc_for_wm_a, .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
.populate_dml_pipes = dcn35_populate_dml_pipes_from_context_fpu, .populate_dml_pipes = populate_dml_pipes_from_context_fpu,
.acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer, .acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer,
.release_pipe = dcn20_release_pipe, .release_pipe = dcn20_release_pipe,
.add_stream_to_ctx = dcn30_add_stream_to_ctx, .add_stream_to_ctx = dcn30_add_stream_to_ctx,

View File

@ -1732,6 +1732,21 @@ static enum dc_status dcn351_validate_bandwidth(struct dc *dc,
return out ? DC_OK : DC_FAIL_BANDWIDTH_VALIDATE; return out ? DC_OK : DC_FAIL_BANDWIDTH_VALIDATE;
} }
static int populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode)
{
int ret;
DC_FP_START();
ret = dcn351_populate_dml_pipes_from_context_fpu(dc, context, pipes, validate_mode);
DC_FP_END();
return ret;
}
static struct resource_funcs dcn351_res_pool_funcs = { static struct resource_funcs dcn351_res_pool_funcs = {
.destroy = dcn351_destroy_resource_pool, .destroy = dcn351_destroy_resource_pool,
.link_enc_create = dcn35_link_encoder_create, .link_enc_create = dcn35_link_encoder_create,
@ -1742,7 +1757,7 @@ static struct resource_funcs dcn351_res_pool_funcs = {
.validate_bandwidth = dcn351_validate_bandwidth, .validate_bandwidth = dcn351_validate_bandwidth,
.calculate_wm_and_dlg = NULL, .calculate_wm_and_dlg = NULL,
.update_soc_for_wm_a = dcn31_update_soc_for_wm_a, .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
.populate_dml_pipes = dcn351_populate_dml_pipes_from_context_fpu, .populate_dml_pipes = populate_dml_pipes_from_context_fpu,
.acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer, .acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer,
.release_pipe = dcn20_release_pipe, .release_pipe = dcn20_release_pipe,
.add_stream_to_ctx = dcn30_add_stream_to_ctx, .add_stream_to_ctx = dcn30_add_stream_to_ctx,

View File

@ -1734,6 +1734,20 @@ static enum dc_status dcn35_validate_bandwidth(struct dc *dc,
} }
static int populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
enum dc_validate_mode validate_mode)
{
int ret;
DC_FP_START();
ret = dcn35_populate_dml_pipes_from_context_fpu(dc, context, pipes, validate_mode);
DC_FP_END();
return ret;
}
static struct resource_funcs dcn36_res_pool_funcs = { static struct resource_funcs dcn36_res_pool_funcs = {
.destroy = dcn36_destroy_resource_pool, .destroy = dcn36_destroy_resource_pool,
.link_enc_create = dcn35_link_encoder_create, .link_enc_create = dcn35_link_encoder_create,
@ -1744,7 +1758,7 @@ static struct resource_funcs dcn36_res_pool_funcs = {
.validate_bandwidth = dcn35_validate_bandwidth, .validate_bandwidth = dcn35_validate_bandwidth,
.calculate_wm_and_dlg = NULL, .calculate_wm_and_dlg = NULL,
.update_soc_for_wm_a = dcn31_update_soc_for_wm_a, .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
.populate_dml_pipes = dcn35_populate_dml_pipes_from_context_fpu, .populate_dml_pipes = populate_dml_pipes_from_context_fpu,
.acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer, .acquire_free_pipe_as_secondary_dpp_pipe = dcn20_acquire_free_pipe_for_layer,
.release_pipe = dcn20_release_pipe, .release_pipe = dcn20_release_pipe,
.add_stream_to_ctx = dcn30_add_stream_to_ctx, .add_stream_to_ctx = dcn30_add_stream_to_ctx,

View File

@ -641,16 +641,16 @@ static void spl_calculate_inits_and_viewports(struct spl_in *spl_in,
/* this gives the direction of the cositing (negative will move /* this gives the direction of the cositing (negative will move
* left, right otherwise) * left, right otherwise)
*/ */
int sign = 1; int h_sign = flip_horz_scan_dir ? -1 : 1;
int v_sign = flip_vert_scan_dir ? -1 : 1;
switch (spl_in->basic_in.cositing) { switch (spl_in->basic_in.cositing) {
case CHROMA_COSITING_TOPLEFT: case CHROMA_COSITING_TOPLEFT:
init_adj_h = spl_fixpt_from_fraction(sign, 4); init_adj_h = spl_fixpt_from_fraction(h_sign, 4);
init_adj_v = spl_fixpt_from_fraction(sign, 4); init_adj_v = spl_fixpt_from_fraction(v_sign, 4);
break; break;
case CHROMA_COSITING_LEFT: case CHROMA_COSITING_LEFT:
init_adj_h = spl_fixpt_from_fraction(sign, 4); init_adj_h = spl_fixpt_from_fraction(h_sign, 4);
init_adj_v = spl_fixpt_zero; init_adj_v = spl_fixpt_zero;
break; break;
case CHROMA_COSITING_NONE: case CHROMA_COSITING_NONE:

View File

@ -4115,6 +4115,7 @@
#define mmSCL0_SCL_COEF_RAM_CONFLICT_STATUS 0x1B55 #define mmSCL0_SCL_COEF_RAM_CONFLICT_STATUS 0x1B55
#define mmSCL0_SCL_COEF_RAM_SELECT 0x1B40 #define mmSCL0_SCL_COEF_RAM_SELECT 0x1B40
#define mmSCL0_SCL_COEF_RAM_TAP_DATA 0x1B41 #define mmSCL0_SCL_COEF_RAM_TAP_DATA 0x1B41
#define mmSCL0_SCL_SCALER_ENABLE 0x1B42
#define mmSCL0_SCL_CONTROL 0x1B44 #define mmSCL0_SCL_CONTROL 0x1B44
#define mmSCL0_SCL_DEBUG 0x1B6A #define mmSCL0_SCL_DEBUG 0x1B6A
#define mmSCL0_SCL_DEBUG2 0x1B69 #define mmSCL0_SCL_DEBUG2 0x1B69
@ -4144,6 +4145,7 @@
#define mmSCL1_SCL_COEF_RAM_CONFLICT_STATUS 0x1E55 #define mmSCL1_SCL_COEF_RAM_CONFLICT_STATUS 0x1E55
#define mmSCL1_SCL_COEF_RAM_SELECT 0x1E40 #define mmSCL1_SCL_COEF_RAM_SELECT 0x1E40
#define mmSCL1_SCL_COEF_RAM_TAP_DATA 0x1E41 #define mmSCL1_SCL_COEF_RAM_TAP_DATA 0x1E41
#define mmSCL1_SCL_SCALER_ENABLE 0x1E42
#define mmSCL1_SCL_CONTROL 0x1E44 #define mmSCL1_SCL_CONTROL 0x1E44
#define mmSCL1_SCL_DEBUG 0x1E6A #define mmSCL1_SCL_DEBUG 0x1E6A
#define mmSCL1_SCL_DEBUG2 0x1E69 #define mmSCL1_SCL_DEBUG2 0x1E69
@ -4173,6 +4175,7 @@
#define mmSCL2_SCL_COEF_RAM_CONFLICT_STATUS 0x4155 #define mmSCL2_SCL_COEF_RAM_CONFLICT_STATUS 0x4155
#define mmSCL2_SCL_COEF_RAM_SELECT 0x4140 #define mmSCL2_SCL_COEF_RAM_SELECT 0x4140
#define mmSCL2_SCL_COEF_RAM_TAP_DATA 0x4141 #define mmSCL2_SCL_COEF_RAM_TAP_DATA 0x4141
#define mmSCL2_SCL_SCALER_ENABLE 0x4142
#define mmSCL2_SCL_CONTROL 0x4144 #define mmSCL2_SCL_CONTROL 0x4144
#define mmSCL2_SCL_DEBUG 0x416A #define mmSCL2_SCL_DEBUG 0x416A
#define mmSCL2_SCL_DEBUG2 0x4169 #define mmSCL2_SCL_DEBUG2 0x4169
@ -4202,6 +4205,7 @@
#define mmSCL3_SCL_COEF_RAM_CONFLICT_STATUS 0x4455 #define mmSCL3_SCL_COEF_RAM_CONFLICT_STATUS 0x4455
#define mmSCL3_SCL_COEF_RAM_SELECT 0x4440 #define mmSCL3_SCL_COEF_RAM_SELECT 0x4440
#define mmSCL3_SCL_COEF_RAM_TAP_DATA 0x4441 #define mmSCL3_SCL_COEF_RAM_TAP_DATA 0x4441
#define mmSCL3_SCL_SCALER_ENABLE 0x4442
#define mmSCL3_SCL_CONTROL 0x4444 #define mmSCL3_SCL_CONTROL 0x4444
#define mmSCL3_SCL_DEBUG 0x446A #define mmSCL3_SCL_DEBUG 0x446A
#define mmSCL3_SCL_DEBUG2 0x4469 #define mmSCL3_SCL_DEBUG2 0x4469
@ -4231,6 +4235,7 @@
#define mmSCL4_SCL_COEF_RAM_CONFLICT_STATUS 0x4755 #define mmSCL4_SCL_COEF_RAM_CONFLICT_STATUS 0x4755
#define mmSCL4_SCL_COEF_RAM_SELECT 0x4740 #define mmSCL4_SCL_COEF_RAM_SELECT 0x4740
#define mmSCL4_SCL_COEF_RAM_TAP_DATA 0x4741 #define mmSCL4_SCL_COEF_RAM_TAP_DATA 0x4741
#define mmSCL4_SCL_SCALER_ENABLE 0x4742
#define mmSCL4_SCL_CONTROL 0x4744 #define mmSCL4_SCL_CONTROL 0x4744
#define mmSCL4_SCL_DEBUG 0x476A #define mmSCL4_SCL_DEBUG 0x476A
#define mmSCL4_SCL_DEBUG2 0x4769 #define mmSCL4_SCL_DEBUG2 0x4769
@ -4260,6 +4265,7 @@
#define mmSCL5_SCL_COEF_RAM_CONFLICT_STATUS 0x4A55 #define mmSCL5_SCL_COEF_RAM_CONFLICT_STATUS 0x4A55
#define mmSCL5_SCL_COEF_RAM_SELECT 0x4A40 #define mmSCL5_SCL_COEF_RAM_SELECT 0x4A40
#define mmSCL5_SCL_COEF_RAM_TAP_DATA 0x4A41 #define mmSCL5_SCL_COEF_RAM_TAP_DATA 0x4A41
#define mmSCL5_SCL_SCALER_ENABLE 0x4A42
#define mmSCL5_SCL_CONTROL 0x4A44 #define mmSCL5_SCL_CONTROL 0x4A44
#define mmSCL5_SCL_DEBUG 0x4A6A #define mmSCL5_SCL_DEBUG 0x4A6A
#define mmSCL5_SCL_DEBUG2 0x4A69 #define mmSCL5_SCL_DEBUG2 0x4A69
@ -4287,6 +4293,7 @@
#define mmSCL_COEF_RAM_CONFLICT_STATUS 0x1B55 #define mmSCL_COEF_RAM_CONFLICT_STATUS 0x1B55
#define mmSCL_COEF_RAM_SELECT 0x1B40 #define mmSCL_COEF_RAM_SELECT 0x1B40
#define mmSCL_COEF_RAM_TAP_DATA 0x1B41 #define mmSCL_COEF_RAM_TAP_DATA 0x1B41
#define mmSCL_SCALER_ENABLE 0x1B42
#define mmSCL_CONTROL 0x1B44 #define mmSCL_CONTROL 0x1B44
#define mmSCL_DEBUG 0x1B6A #define mmSCL_DEBUG 0x1B6A
#define mmSCL_DEBUG2 0x1B69 #define mmSCL_DEBUG2 0x1B69

View File

@ -8650,6 +8650,8 @@
#define REGAMMA_LUT_INDEX__REGAMMA_LUT_INDEX__SHIFT 0x00000000 #define REGAMMA_LUT_INDEX__REGAMMA_LUT_INDEX__SHIFT 0x00000000
#define REGAMMA_LUT_WRITE_EN_MASK__REGAMMA_LUT_WRITE_EN_MASK_MASK 0x00000007L #define REGAMMA_LUT_WRITE_EN_MASK__REGAMMA_LUT_WRITE_EN_MASK_MASK 0x00000007L
#define REGAMMA_LUT_WRITE_EN_MASK__REGAMMA_LUT_WRITE_EN_MASK__SHIFT 0x00000000 #define REGAMMA_LUT_WRITE_EN_MASK__REGAMMA_LUT_WRITE_EN_MASK__SHIFT 0x00000000
#define SCL_SCALER_ENABLE__SCL_SCALE_EN_MASK 0x00000001L
#define SCL_SCALER_ENABLE__SCL_SCALE_EN__SHIFT 0x00000000
#define SCL_ALU_CONTROL__SCL_ALU_DISABLE_MASK 0x00000001L #define SCL_ALU_CONTROL__SCL_ALU_DISABLE_MASK 0x00000001L
#define SCL_ALU_CONTROL__SCL_ALU_DISABLE__SHIFT 0x00000000 #define SCL_ALU_CONTROL__SCL_ALU_DISABLE__SHIFT 0x00000000
#define SCL_BYPASS_CONTROL__SCL_BYPASS_MODE_MASK 0x00000003L #define SCL_BYPASS_CONTROL__SCL_BYPASS_MODE_MASK 0x00000003L

View File

@ -288,7 +288,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
* Considering above, we just leave user a verbal message instead * Considering above, we just leave user a verbal message instead
* of halt driver loading. * of halt driver loading.
*/ */
if (if_version != smu->smc_driver_if_version) { if (smu->smc_driver_if_version != SMU_IGNORE_IF_VERSION &&
if_version != smu->smc_driver_if_version) {
dev_info(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, " dev_info(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
"smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n",
smu->smc_driver_if_version, if_version, smu->smc_driver_if_version, if_version,

View File

@ -450,8 +450,7 @@ static void smu_v13_0_6_init_caps(struct smu_context *smu)
((pgm == 4) && (fw_ver >= 0x4557000))) ((pgm == 4) && (fw_ver >= 0x4557000)))
smu_v13_0_6_cap_set(smu, SMU_CAP(SDMA_RESET)); smu_v13_0_6_cap_set(smu, SMU_CAP(SDMA_RESET));
if (((pgm == 0) && (fw_ver >= 0x00558200)) || if ((pgm == 0) && (fw_ver >= 0x00558200))
((pgm == 4) && (fw_ver >= 0x04557100)))
smu_v13_0_6_cap_set(smu, SMU_CAP(VCN_RESET)); smu_v13_0_6_cap_set(smu, SMU_CAP(VCN_RESET));
} }
@ -3933,7 +3932,7 @@ void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu)
smu->feature_map = (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 12)) ? smu->feature_map = (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 12)) ?
smu_v13_0_12_feature_mask_map : smu_v13_0_6_feature_mask_map; smu_v13_0_12_feature_mask_map : smu_v13_0_6_feature_mask_map;
smu->table_map = smu_v13_0_6_table_map; smu->table_map = smu_v13_0_6_table_map;
smu->smc_driver_if_version = SMU13_0_6_DRIVER_IF_VERSION; smu->smc_driver_if_version = SMU_IGNORE_IF_VERSION;
smu->smc_fw_caps |= SMU_FW_CAP_RAS_PRI; smu->smc_fw_caps |= SMU_FW_CAP_RAS_PRI;
smu_v13_0_set_smu_mailbox_registers(smu); smu_v13_0_set_smu_mailbox_registers(smu);
smu_v13_0_6_set_temp_funcs(smu); smu_v13_0_6_set_temp_funcs(smu);

View File

@ -40,6 +40,8 @@
#define SMU_IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8 #define SMU_IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
#define SMU_IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9 #define SMU_IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
#define SMU_IGNORE_IF_VERSION 0xFFFFFFFF
#define smu_cmn_init_soft_gpu_metrics(ptr, frev, crev) \ #define smu_cmn_init_soft_gpu_metrics(ptr, frev, crev) \
do { \ do { \
typecheck(struct gpu_metrics_v##frev##_##crev *, (ptr)); \ typecheck(struct gpu_metrics_v##frev##_##crev *, (ptr)); \

View File

@ -67,8 +67,8 @@ struct kfd_ioctl_get_version_args {
struct kfd_ioctl_create_queue_args { struct kfd_ioctl_create_queue_args {
__u64 ring_base_address; /* to KFD */ __u64 ring_base_address; /* to KFD */
__u64 write_pointer_address; /* from KFD */ __u64 write_pointer_address; /* to KFD */
__u64 read_pointer_address; /* from KFD */ __u64 read_pointer_address; /* to KFD */
__u64 doorbell_offset; /* from KFD */ __u64 doorbell_offset; /* from KFD */
__u32 ring_size; /* to KFD */ __u32 ring_size; /* to KFD */