mirror of https://github.com/torvalds/linux.git
drm next fixes for 6.18-rc1
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 xe: - Fix build with clang 16 - Fix handling of invalid configfs syntax usage and spell out the expected syntax in the documentation - Do not try late bind firmware when running as VF since it shouldn't handle firmware loading - Fix idle assertion for local BOs - Fix uninitialized variable for late binding - Do not require perfmon_capable to expose free memory at page granularity. Handle it like other drm drivers do - Fix lock handling on suspend error path - Fix I2C controller resume after S3 v3d: - fix fence locking -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmjpaS4ACgkQDHTzWXnE hr5U7xAAgBZ6kqMGN6EKKloDlpIgpQKF3pXGMo7NfwTTJ3x6jTGx41g74ohKCFn2 Zms0RbHTjGB+u495p3dadOSwbvSW2vTYWUCMnxAWye8s7A4LA7SCTXFY84gEE8ki 8THR7AU1L78MWILas2wGmDzoy2HNGLITLbcZO1B5Cdq8SxxxKsXJXXZahLjBB67C 4a23OlANL16g5NCKEQ6owuRBf5hlyc6A+vQuBcfBbKg2VL83Iv/P6nt3Lv5uMwv6 Qss3lnUrsNBrBMxx3QP8IGG3/EwHU/YcJYIYPbce6qZrxuG8Vw1hTPdJqr8kq9mv 8wg8JC9VQtPrTuAiNCgC9QrvaDW1vMc/5abYQMJBRvexnXf4VjriSH0WM7YXFQcB JvChn5Vo8Sr+1B7oQUM5SOMXHxGfxsL3ypub4a3Die6G6ymhp6cDNwBq0vbU/LXy s1fddlNM/PrUACKcFaEGVZMDyz75QTMWae5OmcuUizdzHChUzlDhq1MbHrh0D2jP mNuORIHnrO+oZOyxpnQr5YBfZk+xFrnvSLI/hJP982m9FKJ4PVjLg+4YlRNjW4wO k4LjxyMutybAFEH0nEWrdGxry+y6EM/OrXpToXFquNq3NdI133NvDRiH+f4SI+8M Y6cZdwVSiO5fd7Zup0xKBi+jUi66cfkKS+3MXGfMDX7y1orMMqQ= =tSAX -----END PGP SIGNATURE----- Merge tag 'drm-next-2025-10-11-1' of https://gitlab.freedesktop.org/drm/kernel Pull more drm fixes from Dave Airlie: "Just the follow up fixes for rc1 from the next branch, amdgpu and xe mostly with a single v3d fix in there. 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 xe: - Fix build with clang 16 - Fix handling of invalid configfs syntax usage and spell out the expected syntax in the documentation - Do not try late bind firmware when running as VF since it shouldn't handle firmware loading - Fix idle assertion for local BOs - Fix uninitialized variable for late binding - Do not require perfmon_capable to expose free memory at page granularity. Handle it like other drm drivers do - Fix lock handling on suspend error path - Fix I2C controller resume after S3 v3d: - fix fence locking" * tag 'drm-next-2025-10-11-1' of https://gitlab.freedesktop.org/drm/kernel: (34 commits) drm/amd/display: Incorrect Mirror Cositing drm/amd/display: Enable Dynamic DTBCLK Switch drm/amdgpu: Report individual reset error drm/amdgpu: partially revert "revert to old status lock handling v3" drm/amd/display: Fix unsafe uses of kernel mode FPU drm/amd/pm: Disable VCN queue reset on SMU v13.0.6 due to regression drm/amdgpu: Fix general protection fault in amdgpu_vm_bo_reset_state_machine drm/amdgpu: Check swus/ds for switch state save drm/amdkfd: Fix two comments in kfd_ioctl.h drm/amd/pm: Avoid interface mismatch messaging drm/amdgpu: Merge amdgpu_vm_set_pasid into amdgpu_vm_init drm/amd/amdgpu: Fix the mes version that support inv_tlbs drm/amd: Check whether secure display TA loaded successfully drm/amdkfd: Fix mmap write lock not release drm/amdkfd: Fix kfd process ref leaking when userptr unmapping drm/amdgpu: Fix for GPU reset being blocked by KIQ I/O. drm/amd/display: Disable scaling on DCE6 for now drm/amd/display: Properly disable scaling on DCE6 drm/amd/display: Properly clear SCL_*_FILTER_CONTROL on DCE6 drm/amd/display: Add missing DCE6 SCL_HORZ_FILTER_INIT* SRIs ...
This commit is contained in:
commit
284fc30e66
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,7 +344,7 @@ 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,
|
||||||
|
|
@ -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,11 +623,14 @@ 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) {
|
|
||||||
list_for_each_entry_safe(bo_base, tmp, &vm->evicted_user,
|
|
||||||
vm_status) {
|
|
||||||
bo = bo_base->bo;
|
bo = bo_base->bo;
|
||||||
dma_resv_assert_held(bo->tbo.base.resv);
|
dma_resv_assert_held(bo->tbo.base.resv);
|
||||||
|
|
||||||
|
|
@ -660,8 +639,10 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||||
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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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(¶ms->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, ¶ms->tlb_flush_waitlist);
|
list_move(&entry->vm_status, ¶ms->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, ¶ms->tlb_flush_waitlist);
|
list_move(&cursor->entry->vm_status, ¶ms->tlb_flush_waitlist);
|
||||||
|
spin_unlock(¶ms->vm->status_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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++;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)); \
|
||||||
|
|
|
||||||
|
|
@ -361,7 +361,6 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
|
||||||
* @name: Name of the GPU SVM.
|
* @name: Name of the GPU SVM.
|
||||||
* @drm: Pointer to the DRM device structure.
|
* @drm: Pointer to the DRM device structure.
|
||||||
* @mm: Pointer to the mm_struct for the address space.
|
* @mm: Pointer to the mm_struct for the address space.
|
||||||
* @device_private_page_owner: Device private pages owner.
|
|
||||||
* @mm_start: Start address of GPU SVM.
|
* @mm_start: Start address of GPU SVM.
|
||||||
* @mm_range: Range of the GPU SVM.
|
* @mm_range: Range of the GPU SVM.
|
||||||
* @notifier_size: Size of individual notifiers.
|
* @notifier_size: Size of individual notifiers.
|
||||||
|
|
@ -383,7 +382,7 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
|
||||||
*/
|
*/
|
||||||
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
|
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
|
||||||
const char *name, struct drm_device *drm,
|
const char *name, struct drm_device *drm,
|
||||||
struct mm_struct *mm, void *device_private_page_owner,
|
struct mm_struct *mm,
|
||||||
unsigned long mm_start, unsigned long mm_range,
|
unsigned long mm_start, unsigned long mm_range,
|
||||||
unsigned long notifier_size,
|
unsigned long notifier_size,
|
||||||
const struct drm_gpusvm_ops *ops,
|
const struct drm_gpusvm_ops *ops,
|
||||||
|
|
@ -395,15 +394,13 @@ int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
|
||||||
mmgrab(mm);
|
mmgrab(mm);
|
||||||
} else {
|
} else {
|
||||||
/* No full SVM mode, only core drm_gpusvm_pages API. */
|
/* No full SVM mode, only core drm_gpusvm_pages API. */
|
||||||
if (ops || num_chunks || mm_range || notifier_size ||
|
if (ops || num_chunks || mm_range || notifier_size)
|
||||||
device_private_page_owner)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpusvm->name = name;
|
gpusvm->name = name;
|
||||||
gpusvm->drm = drm;
|
gpusvm->drm = drm;
|
||||||
gpusvm->mm = mm;
|
gpusvm->mm = mm;
|
||||||
gpusvm->device_private_page_owner = device_private_page_owner;
|
|
||||||
gpusvm->mm_start = mm_start;
|
gpusvm->mm_start = mm_start;
|
||||||
gpusvm->mm_range = mm_range;
|
gpusvm->mm_range = mm_range;
|
||||||
gpusvm->notifier_size = notifier_size;
|
gpusvm->notifier_size = notifier_size;
|
||||||
|
|
@ -684,6 +681,7 @@ static unsigned int drm_gpusvm_hmm_pfn_to_order(unsigned long hmm_pfn,
|
||||||
* @notifier: Pointer to the GPU SVM notifier structure
|
* @notifier: Pointer to the GPU SVM notifier structure
|
||||||
* @start: Start address
|
* @start: Start address
|
||||||
* @end: End address
|
* @end: End address
|
||||||
|
* @dev_private_owner: The device private page owner
|
||||||
*
|
*
|
||||||
* Check if pages between start and end have been faulted in on the CPU. Use to
|
* Check if pages between start and end have been faulted in on the CPU. Use to
|
||||||
* prevent migration of pages without CPU backing store.
|
* prevent migration of pages without CPU backing store.
|
||||||
|
|
@ -692,14 +690,15 @@ static unsigned int drm_gpusvm_hmm_pfn_to_order(unsigned long hmm_pfn,
|
||||||
*/
|
*/
|
||||||
static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm,
|
static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm,
|
||||||
struct drm_gpusvm_notifier *notifier,
|
struct drm_gpusvm_notifier *notifier,
|
||||||
unsigned long start, unsigned long end)
|
unsigned long start, unsigned long end,
|
||||||
|
void *dev_private_owner)
|
||||||
{
|
{
|
||||||
struct hmm_range hmm_range = {
|
struct hmm_range hmm_range = {
|
||||||
.default_flags = 0,
|
.default_flags = 0,
|
||||||
.notifier = ¬ifier->notifier,
|
.notifier = ¬ifier->notifier,
|
||||||
.start = start,
|
.start = start,
|
||||||
.end = end,
|
.end = end,
|
||||||
.dev_private_owner = gpusvm->device_private_page_owner,
|
.dev_private_owner = dev_private_owner,
|
||||||
};
|
};
|
||||||
unsigned long timeout =
|
unsigned long timeout =
|
||||||
jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
|
jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
|
||||||
|
|
@ -753,6 +752,7 @@ static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm,
|
||||||
* @gpuva_start: Start address of GPUVA which mirrors CPU
|
* @gpuva_start: Start address of GPUVA which mirrors CPU
|
||||||
* @gpuva_end: End address of GPUVA which mirrors CPU
|
* @gpuva_end: End address of GPUVA which mirrors CPU
|
||||||
* @check_pages_threshold: Check CPU pages for present threshold
|
* @check_pages_threshold: Check CPU pages for present threshold
|
||||||
|
* @dev_private_owner: The device private page owner
|
||||||
*
|
*
|
||||||
* This function determines the chunk size for the GPU SVM range based on the
|
* This function determines the chunk size for the GPU SVM range based on the
|
||||||
* fault address, GPU SVM chunk sizes, existing GPU SVM ranges, and the virtual
|
* fault address, GPU SVM chunk sizes, existing GPU SVM ranges, and the virtual
|
||||||
|
|
@ -767,7 +767,8 @@ drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm,
|
||||||
unsigned long fault_addr,
|
unsigned long fault_addr,
|
||||||
unsigned long gpuva_start,
|
unsigned long gpuva_start,
|
||||||
unsigned long gpuva_end,
|
unsigned long gpuva_end,
|
||||||
unsigned long check_pages_threshold)
|
unsigned long check_pages_threshold,
|
||||||
|
void *dev_private_owner)
|
||||||
{
|
{
|
||||||
unsigned long start, end;
|
unsigned long start, end;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
@ -814,7 +815,7 @@ drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm,
|
||||||
* process-many-malloc' mallocs at least 64k at a time.
|
* process-many-malloc' mallocs at least 64k at a time.
|
||||||
*/
|
*/
|
||||||
if (end - start <= check_pages_threshold &&
|
if (end - start <= check_pages_threshold &&
|
||||||
!drm_gpusvm_check_pages(gpusvm, notifier, start, end)) {
|
!drm_gpusvm_check_pages(gpusvm, notifier, start, end, dev_private_owner)) {
|
||||||
++i;
|
++i;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
@ -957,7 +958,8 @@ drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm,
|
||||||
chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas,
|
chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas,
|
||||||
fault_addr, gpuva_start,
|
fault_addr, gpuva_start,
|
||||||
gpuva_end,
|
gpuva_end,
|
||||||
ctx->check_pages_threshold);
|
ctx->check_pages_threshold,
|
||||||
|
ctx->device_private_page_owner);
|
||||||
if (chunk_size == LONG_MAX) {
|
if (chunk_size == LONG_MAX) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto err_notifier_remove;
|
goto err_notifier_remove;
|
||||||
|
|
@ -1268,7 +1270,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
|
||||||
.notifier = notifier,
|
.notifier = notifier,
|
||||||
.start = pages_start,
|
.start = pages_start,
|
||||||
.end = pages_end,
|
.end = pages_end,
|
||||||
.dev_private_owner = gpusvm->device_private_page_owner,
|
.dev_private_owner = ctx->device_private_page_owner,
|
||||||
};
|
};
|
||||||
void *zdd;
|
void *zdd;
|
||||||
unsigned long timeout =
|
unsigned long timeout =
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@ struct v3d_queue_state {
|
||||||
/* Currently active job for this queue */
|
/* Currently active job for this queue */
|
||||||
struct v3d_job *active_job;
|
struct v3d_job *active_job;
|
||||||
spinlock_t queue_lock;
|
spinlock_t queue_lock;
|
||||||
|
/* Protect dma fence for signalling job completion */
|
||||||
|
spinlock_t fence_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Performance monitor object. The perform lifetime is controlled by userspace
|
/* Performance monitor object. The perform lifetime is controlled by userspace
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ struct dma_fence *v3d_fence_create(struct v3d_dev *v3d, enum v3d_queue q)
|
||||||
fence->dev = &v3d->drm;
|
fence->dev = &v3d->drm;
|
||||||
fence->queue = q;
|
fence->queue = q;
|
||||||
fence->seqno = ++queue->emit_seqno;
|
fence->seqno = ++queue->emit_seqno;
|
||||||
dma_fence_init(&fence->base, &v3d_fence_ops, &queue->queue_lock,
|
dma_fence_init(&fence->base, &v3d_fence_ops, &queue->fence_lock,
|
||||||
queue->fence_context, fence->seqno);
|
queue->fence_context, fence->seqno);
|
||||||
|
|
||||||
return &fence->base;
|
return &fence->base;
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,7 @@ v3d_gem_init(struct drm_device *dev)
|
||||||
seqcount_init(&queue->stats.lock);
|
seqcount_init(&queue->stats.lock);
|
||||||
|
|
||||||
spin_lock_init(&queue->queue_lock);
|
spin_lock_init(&queue->queue_lock);
|
||||||
|
spin_lock_init(&queue->fence_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_init(&v3d->mm_lock);
|
spin_lock_init(&v3d->mm_lock);
|
||||||
|
|
|
||||||
|
|
@ -211,15 +211,15 @@ static void xe_ip_kunit_desc(const struct xe_ip *param, char *desc)
|
||||||
* param generator can be used for both
|
* param generator can be used for both
|
||||||
*/
|
*/
|
||||||
static const struct xe_ip pre_gmdid_graphics_ips[] = {
|
static const struct xe_ip pre_gmdid_graphics_ips[] = {
|
||||||
graphics_ip_xelp,
|
{ 1200, "Xe_LP", &graphics_xelp },
|
||||||
graphics_ip_xelpp,
|
{ 1210, "Xe_LP+", &graphics_xelp },
|
||||||
graphics_ip_xehpg,
|
{ 1255, "Xe_HPG", &graphics_xehpg },
|
||||||
graphics_ip_xehpc,
|
{ 1260, "Xe_HPC", &graphics_xehpc },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct xe_ip pre_gmdid_media_ips[] = {
|
static const struct xe_ip pre_gmdid_media_ips[] = {
|
||||||
media_ip_xem,
|
{ 1200, "Xe_M", &media_xem },
|
||||||
media_ip_xehpm,
|
{ 1255, "Xe_HPM", &media_xem },
|
||||||
};
|
};
|
||||||
|
|
||||||
KUNIT_ARRAY_PARAM(pre_gmdid_graphics_ip, pre_gmdid_graphics_ips, xe_ip_kunit_desc);
|
KUNIT_ARRAY_PARAM(pre_gmdid_graphics_ip, pre_gmdid_graphics_ips, xe_ip_kunit_desc);
|
||||||
|
|
|
||||||
|
|
@ -1737,6 +1737,24 @@ static bool should_migrate_to_smem(struct xe_bo *bo)
|
||||||
bo->attr.atomic_access == DRM_XE_ATOMIC_CPU;
|
bo->attr.atomic_access == DRM_XE_ATOMIC_CPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xe_bo_wait_usage_kernel(struct xe_bo *bo, struct ttm_operation_ctx *ctx)
|
||||||
|
{
|
||||||
|
long lerr;
|
||||||
|
|
||||||
|
if (ctx->no_wait_gpu)
|
||||||
|
return dma_resv_test_signaled(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL) ?
|
||||||
|
0 : -EBUSY;
|
||||||
|
|
||||||
|
lerr = dma_resv_wait_timeout(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL,
|
||||||
|
ctx->interruptible, MAX_SCHEDULE_TIMEOUT);
|
||||||
|
if (lerr < 0)
|
||||||
|
return lerr;
|
||||||
|
if (lerr == 0)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Populate the bo if swapped out, or migrate if the access mode requires that. */
|
/* Populate the bo if swapped out, or migrate if the access mode requires that. */
|
||||||
static int xe_bo_fault_migrate(struct xe_bo *bo, struct ttm_operation_ctx *ctx,
|
static int xe_bo_fault_migrate(struct xe_bo *bo, struct ttm_operation_ctx *ctx,
|
||||||
struct drm_exec *exec)
|
struct drm_exec *exec)
|
||||||
|
|
@ -1745,9 +1763,8 @@ static int xe_bo_fault_migrate(struct xe_bo *bo, struct ttm_operation_ctx *ctx,
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (ttm_manager_type(tbo->bdev, tbo->resource->mem_type)->use_tt) {
|
if (ttm_manager_type(tbo->bdev, tbo->resource->mem_type)->use_tt) {
|
||||||
xe_assert(xe_bo_device(bo),
|
err = xe_bo_wait_usage_kernel(bo, ctx);
|
||||||
dma_resv_test_signaled(tbo->base.resv, DMA_RESV_USAGE_KERNEL) ||
|
if (!err)
|
||||||
(tbo->ttm && ttm_tt_is_populated(tbo->ttm)));
|
|
||||||
err = ttm_bo_populate(&bo->ttm, ctx);
|
err = ttm_bo_populate(&bo->ttm, ctx);
|
||||||
} else if (should_migrate_to_smem(bo)) {
|
} else if (should_migrate_to_smem(bo)) {
|
||||||
xe_assert(xe_bo_device(bo), bo->flags & XE_BO_FLAG_SYSTEM);
|
xe_assert(xe_bo_device(bo), bo->flags & XE_BO_FLAG_SYSTEM);
|
||||||
|
|
@ -1922,7 +1939,6 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
|
||||||
.no_wait_gpu = false,
|
.no_wait_gpu = false,
|
||||||
.gfp_retry_mayfail = retry_after_wait,
|
.gfp_retry_mayfail = retry_after_wait,
|
||||||
};
|
};
|
||||||
long lerr;
|
|
||||||
|
|
||||||
err = drm_exec_lock_obj(&exec, &tbo->base);
|
err = drm_exec_lock_obj(&exec, &tbo->base);
|
||||||
drm_exec_retry_on_contention(&exec);
|
drm_exec_retry_on_contention(&exec);
|
||||||
|
|
@ -1942,13 +1958,9 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lerr = dma_resv_wait_timeout(tbo->base.resv,
|
err = xe_bo_wait_usage_kernel(bo, &tctx);
|
||||||
DMA_RESV_USAGE_KERNEL, true,
|
if (err)
|
||||||
MAX_SCHEDULE_TIMEOUT);
|
|
||||||
if (lerr < 0) {
|
|
||||||
err = lerr;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (!retry_after_wait)
|
if (!retry_after_wait)
|
||||||
ret = __xe_bo_cpu_fault(vmf, xe, bo);
|
ret = __xe_bo_cpu_fault(vmf, xe, bo);
|
||||||
|
|
|
||||||
|
|
@ -126,8 +126,20 @@
|
||||||
* not intended for normal execution and will taint the kernel with TAINT_TEST
|
* not intended for normal execution and will taint the kernel with TAINT_TEST
|
||||||
* when used.
|
* when used.
|
||||||
*
|
*
|
||||||
* Currently this is implemented only for post and mid context restore.
|
* The syntax allows to pass straight instructions to be executed by the engine
|
||||||
* Examples:
|
* in a batch buffer or set specific registers.
|
||||||
|
*
|
||||||
|
* #. Generic instruction::
|
||||||
|
*
|
||||||
|
* <engine-class> cmd <instr> [[dword0] [dword1] [...]]
|
||||||
|
*
|
||||||
|
* #. Simple register setting::
|
||||||
|
*
|
||||||
|
* <engine-class> reg <address> <value>
|
||||||
|
*
|
||||||
|
* Commands are saved per engine class: all instances of that class will execute
|
||||||
|
* those commands during context switch. The instruction, dword arguments,
|
||||||
|
* addresses and values are in hex format like in the examples below.
|
||||||
*
|
*
|
||||||
* #. Execute a LRI command to write 0xDEADBEEF to register 0x4f10 after the
|
* #. Execute a LRI command to write 0xDEADBEEF to register 0x4f10 after the
|
||||||
* normal context restore::
|
* normal context restore::
|
||||||
|
|
@ -154,7 +166,8 @@
|
||||||
* When using multiple lines, make sure to use a command that is
|
* When using multiple lines, make sure to use a command that is
|
||||||
* implemented with a single write syscall, like HEREDOC.
|
* implemented with a single write syscall, like HEREDOC.
|
||||||
*
|
*
|
||||||
* These attributes can only be set before binding to the device.
|
* Currently this is implemented only for post and mid context restore and
|
||||||
|
* these attributes can only be set before binding to the device.
|
||||||
*
|
*
|
||||||
* Remove devices
|
* Remove devices
|
||||||
* ==============
|
* ==============
|
||||||
|
|
@ -324,8 +337,8 @@ static const struct engine_info *lookup_engine_info(const char *pattern, u64 *ma
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pattern += strlen(engine_info[i].cls);
|
pattern += strlen(engine_info[i].cls);
|
||||||
if (!mask && !*pattern)
|
if (!mask)
|
||||||
return &engine_info[i];
|
return *pattern ? NULL : &engine_info[i];
|
||||||
|
|
||||||
if (!strcmp(pattern, "*")) {
|
if (!strcmp(pattern, "*")) {
|
||||||
*mask = engine_info[i].mask;
|
*mask = engine_info[i].mask;
|
||||||
|
|
|
||||||
|
|
@ -685,16 +685,16 @@ static int wait_for_lmem_ready(struct xe_device *xe)
|
||||||
}
|
}
|
||||||
ALLOW_ERROR_INJECTION(wait_for_lmem_ready, ERRNO); /* See xe_pci_probe() */
|
ALLOW_ERROR_INJECTION(wait_for_lmem_ready, ERRNO); /* See xe_pci_probe() */
|
||||||
|
|
||||||
static void sriov_update_device_info(struct xe_device *xe)
|
static void vf_update_device_info(struct xe_device *xe)
|
||||||
{
|
{
|
||||||
|
xe_assert(xe, IS_SRIOV_VF(xe));
|
||||||
/* disable features that are not available/applicable to VFs */
|
/* disable features that are not available/applicable to VFs */
|
||||||
if (IS_SRIOV_VF(xe)) {
|
|
||||||
xe->info.probe_display = 0;
|
xe->info.probe_display = 0;
|
||||||
xe->info.has_heci_cscfi = 0;
|
xe->info.has_heci_cscfi = 0;
|
||||||
xe->info.has_heci_gscfi = 0;
|
xe->info.has_heci_gscfi = 0;
|
||||||
|
xe->info.has_late_bind = 0;
|
||||||
xe->info.skip_guc_pc = 1;
|
xe->info.skip_guc_pc = 1;
|
||||||
xe->info.skip_pcode = 1;
|
xe->info.skip_pcode = 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xe_device_vram_alloc(struct xe_device *xe)
|
static int xe_device_vram_alloc(struct xe_device *xe)
|
||||||
|
|
@ -735,7 +735,8 @@ int xe_device_probe_early(struct xe_device *xe)
|
||||||
|
|
||||||
xe_sriov_probe_early(xe);
|
xe_sriov_probe_early(xe);
|
||||||
|
|
||||||
sriov_update_device_info(xe);
|
if (IS_SRIOV_VF(xe))
|
||||||
|
vf_update_device_info(xe);
|
||||||
|
|
||||||
err = xe_pcode_probe_early(xe);
|
err = xe_pcode_probe_early(xe);
|
||||||
if (err || xe_survivability_mode_is_requested(xe)) {
|
if (err || xe_survivability_mode_is_requested(xe)) {
|
||||||
|
|
|
||||||
|
|
@ -213,17 +213,13 @@ static int xe_hw_engine_group_suspend_faulting_lr_jobs(struct xe_hw_engine_group
|
||||||
|
|
||||||
err = q->ops->suspend_wait(q);
|
err = q->ops->suspend_wait(q);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_suspend;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_resume)
|
if (need_resume)
|
||||||
xe_hw_engine_group_resume_faulting_lr_jobs(group);
|
xe_hw_engine_group_resume_faulting_lr_jobs(group);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_suspend:
|
|
||||||
up_write(&group->mode_sem);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ static int parse_cpd_header(struct xe_late_bind_fw *lb_fw,
|
||||||
const struct gsc_manifest_header *manifest;
|
const struct gsc_manifest_header *manifest;
|
||||||
const struct gsc_cpd_entry *entry;
|
const struct gsc_cpd_entry *entry;
|
||||||
size_t min_size = sizeof(*header);
|
size_t min_size = sizeof(*header);
|
||||||
u32 offset;
|
u32 offset = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* manifest_entry is mandatory */
|
/* manifest_entry is mandatory */
|
||||||
|
|
@ -116,7 +116,7 @@ static int parse_lb_layout(struct xe_late_bind_fw *lb_fw,
|
||||||
const struct csc_fpt_header *header = data;
|
const struct csc_fpt_header *header = data;
|
||||||
const struct csc_fpt_entry *entry;
|
const struct csc_fpt_entry *entry;
|
||||||
size_t min_size = sizeof(*header);
|
size_t min_size = sizeof(*header);
|
||||||
u32 offset;
|
u32 offset = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* fpt_entry is mandatory */
|
/* fpt_entry is mandatory */
|
||||||
|
|
@ -184,17 +184,13 @@ static const char *xe_late_bind_parse_status(uint32_t status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xe_late_bind_fw_num_fans(struct xe_late_bind *late_bind)
|
static int xe_late_bind_fw_num_fans(struct xe_late_bind *late_bind, u32 *num_fans)
|
||||||
{
|
{
|
||||||
struct xe_device *xe = late_bind_to_xe(late_bind);
|
struct xe_device *xe = late_bind_to_xe(late_bind);
|
||||||
struct xe_tile *root_tile = xe_device_get_root_tile(xe);
|
struct xe_tile *root_tile = xe_device_get_root_tile(xe);
|
||||||
u32 uval;
|
|
||||||
|
|
||||||
if (!xe_pcode_read(root_tile,
|
return xe_pcode_read(root_tile,
|
||||||
PCODE_MBOX(FAN_SPEED_CONTROL, FSC_READ_NUM_FANS, 0), &uval, NULL))
|
PCODE_MBOX(FAN_SPEED_CONTROL, FSC_READ_NUM_FANS, 0), num_fans, NULL);
|
||||||
return uval;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xe_late_bind_wait_for_worker_completion(struct xe_late_bind *late_bind)
|
void xe_late_bind_wait_for_worker_completion(struct xe_late_bind *late_bind)
|
||||||
|
|
@ -314,7 +310,11 @@ static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
|
||||||
lb_fw->flags &= ~INTEL_LB_FLAG_IS_PERSISTENT;
|
lb_fw->flags &= ~INTEL_LB_FLAG_IS_PERSISTENT;
|
||||||
|
|
||||||
if (lb_fw->type == INTEL_LB_TYPE_FAN_CONTROL) {
|
if (lb_fw->type == INTEL_LB_TYPE_FAN_CONTROL) {
|
||||||
num_fans = xe_late_bind_fw_num_fans(late_bind);
|
ret = xe_late_bind_fw_num_fans(late_bind, &num_fans);
|
||||||
|
if (ret) {
|
||||||
|
drm_dbg(&xe->drm, "Failed to read number of fans: %d\n", ret);
|
||||||
|
return 0; /* Not a fatal error, continue without fan control */
|
||||||
|
}
|
||||||
drm_dbg(&xe->drm, "Number of Fans: %d\n", num_fans);
|
drm_dbg(&xe->drm, "Number of Fans: %d\n", num_fans);
|
||||||
if (!num_fans)
|
if (!num_fans)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ int xe_pm_resume(struct xe_device *xe)
|
||||||
if (err)
|
if (err)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
xe_i2c_pm_resume(xe, xe->d3cold.allowed);
|
xe_i2c_pm_resume(xe, true);
|
||||||
|
|
||||||
xe_irq_resume(xe);
|
xe_irq_resume(xe);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,6 @@ static int query_mem_regions(struct xe_device *xe,
|
||||||
mem_regions->mem_regions[0].instance = 0;
|
mem_regions->mem_regions[0].instance = 0;
|
||||||
mem_regions->mem_regions[0].min_page_size = PAGE_SIZE;
|
mem_regions->mem_regions[0].min_page_size = PAGE_SIZE;
|
||||||
mem_regions->mem_regions[0].total_size = man->size << PAGE_SHIFT;
|
mem_regions->mem_regions[0].total_size = man->size << PAGE_SHIFT;
|
||||||
if (perfmon_capable())
|
|
||||||
mem_regions->mem_regions[0].used = ttm_resource_manager_usage(man);
|
mem_regions->mem_regions[0].used = ttm_resource_manager_usage(man);
|
||||||
mem_regions->num_mem_regions = 1;
|
mem_regions->num_mem_regions = 1;
|
||||||
|
|
||||||
|
|
@ -293,13 +292,11 @@ static int query_mem_regions(struct xe_device *xe,
|
||||||
mem_regions->mem_regions[mem_regions->num_mem_regions].total_size =
|
mem_regions->mem_regions[mem_regions->num_mem_regions].total_size =
|
||||||
man->size;
|
man->size;
|
||||||
|
|
||||||
if (perfmon_capable()) {
|
|
||||||
xe_ttm_vram_get_used(man,
|
xe_ttm_vram_get_used(man,
|
||||||
&mem_regions->mem_regions
|
&mem_regions->mem_regions
|
||||||
[mem_regions->num_mem_regions].used,
|
[mem_regions->num_mem_regions].used,
|
||||||
&mem_regions->mem_regions
|
&mem_regions->mem_regions
|
||||||
[mem_regions->num_mem_regions].cpu_visible_used);
|
[mem_regions->num_mem_regions].cpu_visible_used);
|
||||||
}
|
|
||||||
|
|
||||||
mem_regions->mem_regions[mem_regions->num_mem_regions].cpu_visible_size =
|
mem_regions->mem_regions[mem_regions->num_mem_regions].cpu_visible_size =
|
||||||
xe_ttm_vram_get_cpu_visible_size(man);
|
xe_ttm_vram_get_cpu_visible_size(man);
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,6 @@ void xe_svm_range_debug(struct xe_svm_range *range, const char *operation)
|
||||||
range_debug(range, operation);
|
range_debug(range, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *xe_svm_devm_owner(struct xe_device *xe)
|
|
||||||
{
|
|
||||||
return xe;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct drm_gpusvm_range *
|
static struct drm_gpusvm_range *
|
||||||
xe_svm_range_alloc(struct drm_gpusvm *gpusvm)
|
xe_svm_range_alloc(struct drm_gpusvm *gpusvm)
|
||||||
{
|
{
|
||||||
|
|
@ -744,15 +739,14 @@ int xe_svm_init(struct xe_vm *vm)
|
||||||
xe_svm_garbage_collector_work_func);
|
xe_svm_garbage_collector_work_func);
|
||||||
|
|
||||||
err = drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM", &vm->xe->drm,
|
err = drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM", &vm->xe->drm,
|
||||||
current->mm, xe_svm_devm_owner(vm->xe), 0,
|
current->mm, 0, vm->size,
|
||||||
vm->size,
|
|
||||||
xe_modparam.svm_notifier_size * SZ_1M,
|
xe_modparam.svm_notifier_size * SZ_1M,
|
||||||
&gpusvm_ops, fault_chunk_sizes,
|
&gpusvm_ops, fault_chunk_sizes,
|
||||||
ARRAY_SIZE(fault_chunk_sizes));
|
ARRAY_SIZE(fault_chunk_sizes));
|
||||||
drm_gpusvm_driver_set_lock(&vm->svm.gpusvm, &vm->lock);
|
drm_gpusvm_driver_set_lock(&vm->svm.gpusvm, &vm->lock);
|
||||||
} else {
|
} else {
|
||||||
err = drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM (simple)",
|
err = drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM (simple)",
|
||||||
&vm->xe->drm, NULL, NULL, 0, 0, 0, NULL,
|
&vm->xe->drm, NULL, 0, 0, 0, NULL,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1017,6 +1011,7 @@ static int __xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
|
||||||
.devmem_only = need_vram && devmem_possible,
|
.devmem_only = need_vram && devmem_possible,
|
||||||
.timeslice_ms = need_vram && devmem_possible ?
|
.timeslice_ms = need_vram && devmem_possible ?
|
||||||
vm->xe->atomic_svm_timeslice_ms : 0,
|
vm->xe->atomic_svm_timeslice_ms : 0,
|
||||||
|
.device_private_page_owner = xe_svm_devm_owner(vm->xe),
|
||||||
};
|
};
|
||||||
struct xe_validation_ctx vctx;
|
struct xe_validation_ctx vctx;
|
||||||
struct drm_exec exec;
|
struct drm_exec exec;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,20 @@
|
||||||
#ifndef _XE_SVM_H_
|
#ifndef _XE_SVM_H_
|
||||||
#define _XE_SVM_H_
|
#define _XE_SVM_H_
|
||||||
|
|
||||||
|
struct xe_device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xe_svm_devm_owner() - Return the owner of device private memory
|
||||||
|
* @xe: The xe device.
|
||||||
|
*
|
||||||
|
* Return: The owner of this device's device private memory to use in
|
||||||
|
* hmm_range_fault()-
|
||||||
|
*/
|
||||||
|
static inline void *xe_svm_devm_owner(struct xe_device *xe)
|
||||||
|
{
|
||||||
|
return xe;
|
||||||
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_DRM_XE_GPUSVM)
|
#if IS_ENABLED(CONFIG_DRM_XE_GPUSVM)
|
||||||
|
|
||||||
#include <drm/drm_pagemap.h>
|
#include <drm/drm_pagemap.h>
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma)
|
||||||
struct xe_device *xe = vm->xe;
|
struct xe_device *xe = vm->xe;
|
||||||
struct drm_gpusvm_ctx ctx = {
|
struct drm_gpusvm_ctx ctx = {
|
||||||
.read_only = xe_vma_read_only(vma),
|
.read_only = xe_vma_read_only(vma),
|
||||||
|
.device_private_page_owner = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
lockdep_assert_held(&vm->lock);
|
lockdep_assert_held(&vm->lock);
|
||||||
|
|
|
||||||
|
|
@ -2881,6 +2881,7 @@ static int prefetch_ranges(struct xe_vm *vm, struct xe_vma_op *op)
|
||||||
ctx.read_only = xe_vma_read_only(vma);
|
ctx.read_only = xe_vma_read_only(vma);
|
||||||
ctx.devmem_possible = devmem_possible;
|
ctx.devmem_possible = devmem_possible;
|
||||||
ctx.check_pages_threshold = devmem_possible ? SZ_64K : 0;
|
ctx.check_pages_threshold = devmem_possible ? SZ_64K : 0;
|
||||||
|
ctx.device_private_page_owner = xe_svm_devm_owner(vm->xe);
|
||||||
|
|
||||||
/* TODO: Threading the migration */
|
/* TODO: Threading the migration */
|
||||||
xa_for_each(&op->prefetch_range.range, i, svm_range) {
|
xa_for_each(&op->prefetch_range.range, i, svm_range) {
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,6 @@ struct drm_gpusvm_range {
|
||||||
* @name: Name of the GPU SVM
|
* @name: Name of the GPU SVM
|
||||||
* @drm: Pointer to the DRM device structure
|
* @drm: Pointer to the DRM device structure
|
||||||
* @mm: Pointer to the mm_struct for the address space
|
* @mm: Pointer to the mm_struct for the address space
|
||||||
* @device_private_page_owner: Device private pages owner
|
|
||||||
* @mm_start: Start address of GPU SVM
|
* @mm_start: Start address of GPU SVM
|
||||||
* @mm_range: Range of the GPU SVM
|
* @mm_range: Range of the GPU SVM
|
||||||
* @notifier_size: Size of individual notifiers
|
* @notifier_size: Size of individual notifiers
|
||||||
|
|
@ -204,7 +203,6 @@ struct drm_gpusvm {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct drm_device *drm;
|
struct drm_device *drm;
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
void *device_private_page_owner;
|
|
||||||
unsigned long mm_start;
|
unsigned long mm_start;
|
||||||
unsigned long mm_range;
|
unsigned long mm_range;
|
||||||
unsigned long notifier_size;
|
unsigned long notifier_size;
|
||||||
|
|
@ -226,6 +224,8 @@ struct drm_gpusvm {
|
||||||
/**
|
/**
|
||||||
* struct drm_gpusvm_ctx - DRM GPU SVM context
|
* struct drm_gpusvm_ctx - DRM GPU SVM context
|
||||||
*
|
*
|
||||||
|
* @device_private_page_owner: The device-private page owner to use for
|
||||||
|
* this operation
|
||||||
* @check_pages_threshold: Check CPU pages for present if chunk is less than or
|
* @check_pages_threshold: Check CPU pages for present if chunk is less than or
|
||||||
* equal to threshold. If not present, reduce chunk
|
* equal to threshold. If not present, reduce chunk
|
||||||
* size.
|
* size.
|
||||||
|
|
@ -239,6 +239,7 @@ struct drm_gpusvm {
|
||||||
* Context that is DRM GPUSVM is operating in (i.e. user arguments).
|
* Context that is DRM GPUSVM is operating in (i.e. user arguments).
|
||||||
*/
|
*/
|
||||||
struct drm_gpusvm_ctx {
|
struct drm_gpusvm_ctx {
|
||||||
|
void *device_private_page_owner;
|
||||||
unsigned long check_pages_threshold;
|
unsigned long check_pages_threshold;
|
||||||
unsigned long timeslice_ms;
|
unsigned long timeslice_ms;
|
||||||
unsigned int in_notifier :1;
|
unsigned int in_notifier :1;
|
||||||
|
|
@ -249,7 +250,7 @@ struct drm_gpusvm_ctx {
|
||||||
|
|
||||||
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
|
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
|
||||||
const char *name, struct drm_device *drm,
|
const char *name, struct drm_device *drm,
|
||||||
struct mm_struct *mm, void *device_private_page_owner,
|
struct mm_struct *mm,
|
||||||
unsigned long mm_start, unsigned long mm_range,
|
unsigned long mm_start, unsigned long mm_range,
|
||||||
unsigned long notifier_size,
|
unsigned long notifier_size,
|
||||||
const struct drm_gpusvm_ops *ops,
|
const struct drm_gpusvm_ops *ops,
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue