drm fixes for 6.8-rc3
dma-buf: - heaps CMA page accounting fix virtio-gpu: - fix segment size xe: - A crash fix - A fix for an assert due to missing mem_acces ref - Only allow a single user-fence per exec / bind. - Some sparse warning fixes - Two fixes for compilation failures on various odd combinations of gcc / arch pointed out on LKML. - Fix a fragile partial allocation pointed out on LKML. - A sysfs ABI documentation warning fix amdgpu: - Fix reboot issue seen on some 7000 series dGPUs - Fix client init order for KFD - Misc display fixes - USB-C fix - DCN 3.5 fixes - Fix issues with GPU scheduler and GPU reset - GPU firmware loading fix - Misc fixes - GC 11.5 fix - VCN 4.0.5 fix - IH overflow fix amdkfd: - SVM fixes - Trap handler fix - Fix device permission lookup - Properly reserve BO before validating it nouveau: - fence/irq lock deadlock fix (second attempt) - gsp command size fix -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmW9RgIACgkQDHTzWXnE hr4LnQ/9FFwGKMf8a0QIAWQFQVHLa4IMfjR8l3ppqXIZWlxG1LE/TddLRsS1xqA7 QmliCFDuXHXoOBPTx5/vUBt7QuomJ2QnVOmcDbyym6Oae2XLQK8H8VRuGB33lGJo Qj7YWX5pml6jmWjG1j1b3M+Si0subiOhUCaB4AsIfUahUs8XeKbVXs3e11aaZyLK YgqFBKsPaT8x9foh0RC5X/i1QspVGUSUNtvEEi88t5ZrTfyWuL0HBWbtZYub4b9i URoTEdTWxx2zJs5Xe/1KZeyUnxtGukTeSuSyE53XFRPDIpkRCikafXvX7/PGuqbV x69K/iCHn6RssqYAOMXdDJtcVilJqPlfyH5KnoNz0XDmv2A8vRTmeZ7ULYy3yq6e kxGGeXyGHICp605P3FFsLgSiACkDAAW1lO2iLy0MOEMZ9U13rGG19ZCpOF8NC55Y Eok5AmrghD3mJqwzbrTBA8JsycC724auTwZ1J07dxS0DE1giB4BMXGe+5+yEZxp2 pGMmzJQmegyKK9YOIOVTyj6wAXns+fMsFOVylVgl8mSPAecZiRA7kkORafsQV5ts I9jHd+wdXpVOh14GUf8fOayuf+YeJYj82qKCLgpy8d/WlvVUPTho8IXTSXjRU/5H rLA6rSLGu0LVW1AlsTh94X/H1mpX0IeYIjtE8+eWh0+Ugn5c/Wg= =9BzV -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2024-02-03' of git://anongit.freedesktop.org/drm/drm Pul drm fixes from Dave Airlie: "Regular weekly fixes, mostly amdgpu and xe. One nouveau fix is a better fix for the deadlock and also helps with a sync race we were seeing. dma-buf: - heaps CMA page accounting fix virtio-gpu: - fix segment size xe: - A crash fix - A fix for an assert due to missing mem_acces ref - Only allow a single user-fence per exec / bind. - Some sparse warning fixes - Two fixes for compilation failures on various odd combinations of gcc / arch pointed out on LKML. - Fix a fragile partial allocation pointed out on LKML. - A sysfs ABI documentation warning fix amdgpu: - Fix reboot issue seen on some 7000 series dGPUs - Fix client init order for KFD - Misc display fixes - USB-C fix - DCN 3.5 fixes - Fix issues with GPU scheduler and GPU reset - GPU firmware loading fix - Misc fixes - GC 11.5 fix - VCN 4.0.5 fix - IH overflow fix amdkfd: - SVM fixes - Trap handler fix - Fix device permission lookup - Properly reserve BO before validating it nouveau: - fence/irq lock deadlock fix (second attempt) - gsp command size fix * tag 'drm-fixes-2024-02-03' of git://anongit.freedesktop.org/drm/drm: (35 commits) nouveau: offload fence uevents work to workqueue nouveau/gsp: use correct size for registry rpc. drm/amdgpu/pm: Use inline function for IP version check drm/hwmon: Fix abi doc warnings drm/xe: Make all GuC ABI shift values unsigned drm/xe/vm: Subclass userptr vmas drm/xe: Use LRC prefix rather than CTX prefix in lrc desc defines drm/xe: Don't use __user error pointers drm/xe: Annotate mcr_[un]lock() drm/xe: Only allow 1 ufence per exec / bind IOCTL drm/xe: Grab mem_access when disabling C6 on skip_guc_pc platforms drm/xe: Fix crash in trace_dma_fence_init() drm/amdgpu: Reset IH OVERFLOW_CLEAR bit drm/amdgpu: remove asymmetrical irq disabling in vcn 4.0.5 suspend drm/amdgpu: drm/amdgpu: remove golden setting for gfx 11.5.0 drm/amdkfd: reserve the BO before validating it drm/amdgpu: Fix missing error code in 'gmc_v6/7/8/9_0_hw_init()' drm/amd/display: Fix buffer overflow in 'get_host_router_total_dp_tunnel_bw()' drm/amd/display: Add NULL check for kzalloc in 'amdgpu_dm_atomic_commit_tail()' drm/amd: Don't init MEC2 firmware when it fails to load ...
This commit is contained in:
commit
9c2f0338bb
@ -1,4 +1,4 @@
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/in0_input
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/in0_input
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
@ -6,7 +6,7 @@ Description: RO. Current Voltage in millivolt.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_max
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_max
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
@ -20,7 +20,7 @@ Description: RW. Card reactive sustained (PL1/Tau) power limit in microwatts.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_rated_max
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_rated_max
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
@ -28,7 +28,7 @@ Description: RO. Card default power limit (default TDP setting).
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_max_interval
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_max_interval
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
@ -37,7 +37,7 @@ Description: RW. Sustained power limit interval (Tau in PL1/Tau) in
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_crit
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/power1_crit
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
@ -50,7 +50,7 @@ Description: RW. Card reactive critical (I1) power limit in microwatts.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/curr1_crit
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/curr1_crit
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
@ -63,7 +63,7 @@ Description: RW. Card reactive critical (I1) power limit in milliamperes.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/energy1_input
|
||||
What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/energy1_input
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
|
@ -1,4 +1,4 @@
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_max
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_max
|
||||
Date: September 2023
|
||||
KernelVersion: 6.5
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
@ -12,7 +12,7 @@ Description: RW. Card reactive sustained (PL1) power limit in microwatts.
|
||||
|
||||
Only supported for particular Intel xe graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_rated_max
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_rated_max
|
||||
Date: September 2023
|
||||
KernelVersion: 6.5
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
@ -20,7 +20,7 @@ Description: RO. Card default power limit (default TDP setting).
|
||||
|
||||
Only supported for particular Intel xe graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_crit
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_crit
|
||||
Date: September 2023
|
||||
KernelVersion: 6.5
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
@ -33,7 +33,7 @@ Description: RW. Card reactive critical (I1) power limit in microwatts.
|
||||
|
||||
Only supported for particular Intel xe graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/curr1_crit
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/curr1_crit
|
||||
Date: September 2023
|
||||
KernelVersion: 6.5
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
@ -44,7 +44,7 @@ Description: RW. Card reactive critical (I1) power limit in milliamperes.
|
||||
the operating frequency if the power averaged over a window
|
||||
exceeds this limit.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/in0_input
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/in0_input
|
||||
Date: September 2023
|
||||
KernelVersion: 6.5
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
@ -52,7 +52,7 @@ Description: RO. Current Voltage in millivolt.
|
||||
|
||||
Only supported for particular Intel xe graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/energy1_input
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/energy1_input
|
||||
Date: September 2023
|
||||
KernelVersion: 6.5
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
@ -60,7 +60,7 @@ Description: RO. Energy input of device in microjoules.
|
||||
|
||||
Only supported for particular Intel xe graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_max_interval
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_max_interval
|
||||
Date: October 2023
|
||||
KernelVersion: 6.6
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
|
@ -168,10 +168,7 @@ static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf)
|
||||
if (vmf->pgoff > buffer->pagecount)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
vmf->page = buffer->pages[vmf->pgoff];
|
||||
get_page(vmf->page);
|
||||
|
||||
return 0;
|
||||
return vmf_insert_pfn(vma, vmf->address, page_to_pfn(buffer->pages[vmf->pgoff]));
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct dma_heap_vm_ops = {
|
||||
@ -185,6 +182,8 @@ static int cma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
|
||||
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
|
||||
|
||||
vma->vm_ops = &dma_heap_vm_ops;
|
||||
vma->vm_private_data = buffer;
|
||||
|
||||
|
@ -141,11 +141,31 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
|
||||
static const struct drm_client_funcs kfd_client_funcs = {
|
||||
.unregister = drm_client_release,
|
||||
};
|
||||
|
||||
int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!adev->kfd.init_complete)
|
||||
return 0;
|
||||
|
||||
ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd",
|
||||
&kfd_client_funcs);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to init DRM client: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_client_register(&adev->kfd.client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
int last_valid_bit;
|
||||
int ret;
|
||||
|
||||
amdgpu_amdkfd_gpuvm_init_mem_limits();
|
||||
|
||||
@ -164,12 +184,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
.enable_mes = adev->enable_mes,
|
||||
};
|
||||
|
||||
ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", &kfd_client_funcs);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to init DRM client: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is going to have a few of the MSBs set that we need to
|
||||
* clear
|
||||
*/
|
||||
@ -208,10 +222,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
|
||||
adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev,
|
||||
&gpu_resources);
|
||||
if (adev->kfd.init_complete)
|
||||
drm_client_register(&adev->kfd.client);
|
||||
else
|
||||
drm_client_release(&adev->kfd.client);
|
||||
|
||||
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
||||
|
||||
|
@ -182,6 +182,8 @@ int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,
|
||||
struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
|
||||
struct mm_struct *mm,
|
||||
struct svm_range_bo *svm_bo);
|
||||
|
||||
int amdgpu_amdkfd_drm_client_create(struct amdgpu_device *adev);
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data);
|
||||
#endif
|
||||
@ -301,7 +303,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv);
|
||||
void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
|
||||
|
@ -290,7 +290,7 @@ static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool sus
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
|
||||
|
||||
if (!(ring && drm_sched_wqueue_ready(&ring->sched)))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
/* stop secheduler and drain ring. */
|
||||
|
@ -2085,21 +2085,35 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv)
|
||||
int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv)
|
||||
{
|
||||
struct kfd_mem_attachment *entry;
|
||||
struct amdgpu_vm *vm;
|
||||
int ret;
|
||||
|
||||
vm = drm_priv_to_vm(drm_priv);
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
|
||||
ret = amdgpu_bo_reserve(mem->bo, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
list_for_each_entry(entry, &mem->attachments, list) {
|
||||
if (entry->bo_va->base.vm == vm)
|
||||
kfd_mem_dmaunmap_attachment(mem, entry);
|
||||
if (entry->bo_va->base.vm != vm)
|
||||
continue;
|
||||
if (entry->bo_va->base.bo->tbo.ttm &&
|
||||
!entry->bo_va->base.bo->tbo.ttm->sg)
|
||||
continue;
|
||||
|
||||
kfd_mem_dmaunmap_attachment(mem, entry);
|
||||
}
|
||||
|
||||
amdgpu_bo_unreserve(mem->bo);
|
||||
out:
|
||||
mutex_unlock(&mem->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
|
@ -1678,7 +1678,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
drm_sched_wqueue_stop(&ring->sched);
|
||||
}
|
||||
@ -1694,7 +1694,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
drm_sched_wqueue_start(&ring->sched);
|
||||
}
|
||||
@ -1916,8 +1916,8 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)
|
||||
|
||||
ring = adev->rings[val];
|
||||
|
||||
if (!ring || !ring->funcs->preempt_ib ||
|
||||
!drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring) ||
|
||||
!ring->funcs->preempt_ib)
|
||||
return -EINVAL;
|
||||
|
||||
/* the last preemption failed */
|
||||
|
@ -4121,23 +4121,13 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
r = psp_gpu_reset(adev);
|
||||
break;
|
||||
default:
|
||||
tmp = amdgpu_reset_method;
|
||||
/* It should do a default reset when loading or reloading the driver,
|
||||
* regardless of the module parameter reset_method.
|
||||
*/
|
||||
amdgpu_reset_method = AMD_RESET_METHOD_NONE;
|
||||
r = amdgpu_asic_reset(adev);
|
||||
amdgpu_reset_method = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = amdgpu_reset_method;
|
||||
/* It should do a default reset when loading or reloading the driver,
|
||||
* regardless of the module parameter reset_method.
|
||||
*/
|
||||
amdgpu_reset_method = AMD_RESET_METHOD_NONE;
|
||||
r = amdgpu_asic_reset(adev);
|
||||
amdgpu_reset_method = tmp;
|
||||
if (r) {
|
||||
dev_err(adev->dev, "asic reset on init failed\n");
|
||||
goto failed;
|
||||
@ -5031,7 +5021,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
spin_lock(&ring->sched.job_list_lock);
|
||||
@ -5170,7 +5160,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
/* Clear job fence from fence drv to avoid force_completion
|
||||
@ -5637,7 +5627,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
drm_sched_stop(&ring->sched, job ? &job->base : NULL);
|
||||
@ -5706,7 +5696,7 @@ skip_hw_reset:
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
drm_sched_start(&ring->sched, true);
|
||||
@ -6061,7 +6051,7 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
drm_sched_stop(&ring->sched, NULL);
|
||||
@ -6189,7 +6179,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !drm_sched_wqueue_ready(&ring->sched))
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
drm_sched_start(&ring->sched, true);
|
||||
|
@ -2255,6 +2255,10 @@ retry_init:
|
||||
if (ret)
|
||||
goto err_pci;
|
||||
|
||||
ret = amdgpu_amdkfd_drm_client_create(adev);
|
||||
if (ret)
|
||||
goto err_pci;
|
||||
|
||||
/*
|
||||
* 1. don't init fbdev on hw without DCE
|
||||
* 2. don't init fbdev if there are no connectors
|
||||
|
@ -635,6 +635,7 @@ int amdgpu_ring_test_helper(struct amdgpu_ring *ring)
|
||||
ring->name);
|
||||
|
||||
ring->sched.ready = !r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -717,3 +718,14 @@ void amdgpu_ring_ib_on_emit_de(struct amdgpu_ring *ring)
|
||||
if (ring->is_sw_ring)
|
||||
amdgpu_sw_ring_ib_mark_offset(ring, AMDGPU_MUX_OFFSET_TYPE_DE);
|
||||
}
|
||||
|
||||
bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring)
|
||||
{
|
||||
if (!ring)
|
||||
return false;
|
||||
|
||||
if (ring->no_scheduler || !drm_sched_wqueue_ready(&ring->sched))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -450,5 +450,5 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
||||
int amdgpu_ib_pool_init(struct amdgpu_device *adev);
|
||||
void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring);
|
||||
#endif
|
||||
|
@ -204,6 +204,12 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = RREG32(mmIH_RB_CNTL);
|
||||
tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
}
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -216,6 +216,11 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
|
@ -4027,8 +4027,6 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
err = 0;
|
||||
adev->gfx.mec2_fw = NULL;
|
||||
}
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
|
||||
|
||||
gfx_v10_0_check_fw_write_wait(adev);
|
||||
out:
|
||||
|
@ -107,23 +107,6 @@ static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xfcffffff, 0x0000000a)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_11_5_0[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regDB_DEBUG5, 0xffffffff, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x0c1807ff, 0x00000242),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL, 0xffffffff, 0xf37fff3f),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL3, 0xfffffffb, 0x00f40188),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x80009007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_CL_ENHANCE, 0xf1ffffff, 0x00880007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regPC_CONFIG_CNTL_1, 0xffffffff, 0x00010000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL_AUX, 0xf7f7ffff, 0x01030000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL2, 0x007f0000, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xffcfffff, 0x0000200a),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regUTCL1_CTRL_2, 0xffffffff, 0x0000048f)
|
||||
};
|
||||
|
||||
#define DEFAULT_SH_MEM_CONFIG \
|
||||
((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \
|
||||
(SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
|
||||
@ -304,11 +287,6 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
golden_settings_gc_11_0_1,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));
|
||||
break;
|
||||
case IP_VERSION(11, 5, 0):
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_11_5_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_11_5_0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -915,8 +915,8 @@ static int gmc_v6_0_hw_init(void *handle)
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
return amdgpu_gmc_vram_checking(adev);
|
||||
else
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gmc_v6_0_hw_fini(void *handle)
|
||||
|
@ -1099,8 +1099,8 @@ static int gmc_v7_0_hw_init(void *handle)
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
return amdgpu_gmc_vram_checking(adev);
|
||||
else
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gmc_v7_0_hw_fini(void *handle)
|
||||
|
@ -1219,8 +1219,8 @@ static int gmc_v8_0_hw_init(void *handle)
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
return amdgpu_gmc_vram_checking(adev);
|
||||
else
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gmc_v8_0_hw_fini(void *handle)
|
||||
|
@ -2341,8 +2341,8 @@ static int gmc_v9_0_hw_init(void *handle)
|
||||
|
||||
if (amdgpu_emu_mode == 1)
|
||||
return amdgpu_gmc_vram_checking(adev);
|
||||
else
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,6 +215,11 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
|
@ -418,6 +418,12 @@ static u32 ih_v6_0_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -418,6 +418,13 @@ static u32 ih_v6_1_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -442,6 +442,12 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -119,6 +119,12 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = RREG32(IH_RB_CNTL);
|
||||
tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
}
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -219,6 +219,12 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32(mmIH_RB_CNTL, tmp);
|
||||
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -2017,22 +2017,6 @@ static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_sta
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v4_0_set_interrupt_state - set VCN block interrupt state
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @source: interrupt sources
|
||||
* @type: interrupt types
|
||||
* @state: interrupt states
|
||||
*
|
||||
* Set VCN block interrupt state
|
||||
*/
|
||||
static int vcn_v4_0_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
|
||||
unsigned type, enum amdgpu_interrupt_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v4_0_set_ras_interrupt_state - set VCN block RAS interrupt state
|
||||
*
|
||||
@ -2097,7 +2081,6 @@ static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = {
|
||||
.set = vcn_v4_0_set_interrupt_state,
|
||||
.process = vcn_v4_0_process_interrupt,
|
||||
};
|
||||
|
||||
|
@ -269,8 +269,6 @@ static int vcn_v4_0_5_hw_fini(void *handle)
|
||||
vcn_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_irq_put(adev, &adev->vcn.inst[i].irq, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1668,22 +1666,6 @@ static int vcn_v4_0_5_set_powergating_state(void *handle, enum amd_powergating_s
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v4_0_5_set_interrupt_state - set VCN block interrupt state
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @source: interrupt sources
|
||||
* @type: interrupt types
|
||||
* @state: interrupt states
|
||||
*
|
||||
* Set VCN block interrupt state
|
||||
*/
|
||||
static int vcn_v4_0_5_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
|
||||
unsigned type, enum amdgpu_interrupt_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v4_0_5_process_interrupt - process VCN block interrupt
|
||||
*
|
||||
@ -1726,7 +1708,6 @@ static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgp
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = {
|
||||
.set = vcn_v4_0_5_set_interrupt_state,
|
||||
.process = vcn_v4_0_5_process_interrupt,
|
||||
};
|
||||
|
||||
|
@ -373,6 +373,12 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -421,6 +421,12 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
|
||||
* can be detected.
|
||||
*/
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
|
||||
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
out:
|
||||
return (wptr & ih->ptr_mask);
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ static const uint32_t cwsr_trap_gfx9_hex[] = {
|
||||
0x86ea6a6a, 0x8f6e837a,
|
||||
0xb96ee0c2, 0xbf800002,
|
||||
0xb97a0002, 0xbf8a0000,
|
||||
0xbe801f6c, 0xbf810000,
|
||||
0xbe801f6c, 0xbf9b0000,
|
||||
};
|
||||
|
||||
static const uint32_t cwsr_trap_nv1x_hex[] = {
|
||||
@ -1091,7 +1091,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
|
||||
0xb9eef807, 0x876dff6d,
|
||||
0x0000ffff, 0x87fe7e7e,
|
||||
0x87ea6a6a, 0xb9faf802,
|
||||
0xbe80226c, 0xbf810000,
|
||||
0xbe80226c, 0xbf9b0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0x00000000,
|
||||
@ -1574,7 +1574,7 @@ static const uint32_t cwsr_trap_arcturus_hex[] = {
|
||||
0x86ea6a6a, 0x8f6e837a,
|
||||
0xb96ee0c2, 0xbf800002,
|
||||
0xb97a0002, 0xbf8a0000,
|
||||
0xbe801f6c, 0xbf810000,
|
||||
0xbe801f6c, 0xbf9b0000,
|
||||
};
|
||||
|
||||
static const uint32_t cwsr_trap_aldebaran_hex[] = {
|
||||
@ -2065,7 +2065,7 @@ static const uint32_t cwsr_trap_aldebaran_hex[] = {
|
||||
0x86ea6a6a, 0x8f6e837a,
|
||||
0xb96ee0c2, 0xbf800002,
|
||||
0xb97a0002, 0xbf8a0000,
|
||||
0xbe801f6c, 0xbf810000,
|
||||
0xbe801f6c, 0xbf9b0000,
|
||||
};
|
||||
|
||||
static const uint32_t cwsr_trap_gfx10_hex[] = {
|
||||
@ -2500,7 +2500,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
|
||||
0x876dff6d, 0x0000ffff,
|
||||
0x87fe7e7e, 0x87ea6a6a,
|
||||
0xb9faf802, 0xbe80226c,
|
||||
0xbf810000, 0xbf9f0000,
|
||||
0xbf9b0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
};
|
||||
@ -2944,7 +2944,7 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
|
||||
0xb8eef802, 0xbf0d866e,
|
||||
0xbfa20002, 0xb97af802,
|
||||
0xbe80486c, 0xb97af802,
|
||||
0xbe804a6c, 0xbfb00000,
|
||||
0xbe804a6c, 0xbfb10000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0x00000000,
|
||||
@ -3436,5 +3436,5 @@ static const uint32_t cwsr_trap_gfx9_4_3_hex[] = {
|
||||
0x86ea6a6a, 0x8f6e837a,
|
||||
0xb96ee0c2, 0xbf800002,
|
||||
0xb97a0002, 0xbf8a0000,
|
||||
0xbe801f6c, 0xbf810000,
|
||||
0xbe801f6c, 0xbf9b0000,
|
||||
};
|
||||
|
@ -1104,7 +1104,7 @@ L_RETURN_WITHOUT_PRIV:
|
||||
s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution
|
||||
|
||||
L_END_PGM:
|
||||
s_endpgm
|
||||
s_endpgm_saved
|
||||
end
|
||||
|
||||
function write_hwreg_to_mem(s, s_rsrc, s_mem_offset)
|
||||
|
@ -921,7 +921,7 @@ L_RESTORE:
|
||||
/* the END */
|
||||
/**************************************************************************/
|
||||
L_END_PGM:
|
||||
s_endpgm
|
||||
s_endpgm_saved
|
||||
|
||||
end
|
||||
|
||||
|
@ -1442,7 +1442,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
||||
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
|
||||
|
||||
/* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */
|
||||
amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);
|
||||
err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);
|
||||
if (err)
|
||||
goto sync_memory_failed;
|
||||
}
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
@ -574,7 +574,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms, prange->start,
|
||||
prange->last);
|
||||
|
||||
addr = prange->start << PAGE_SHIFT;
|
||||
addr = migrate->start;
|
||||
|
||||
src = (uint64_t *)(scratch + npages);
|
||||
dst = scratch;
|
||||
|
@ -1488,10 +1488,15 @@ void kfd_dec_compute_active(struct kfd_node *dev);
|
||||
|
||||
/* Cgroup Support */
|
||||
/* Check with device cgroup if @kfd device is accessible */
|
||||
static inline int kfd_devcgroup_check_permission(struct kfd_node *kfd)
|
||||
static inline int kfd_devcgroup_check_permission(struct kfd_node *node)
|
||||
{
|
||||
#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
|
||||
struct drm_device *ddev = adev_to_drm(kfd->adev);
|
||||
struct drm_device *ddev;
|
||||
|
||||
if (node->xcp)
|
||||
ddev = node->xcp->ddev;
|
||||
else
|
||||
ddev = adev_to_drm(node->adev);
|
||||
|
||||
return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR,
|
||||
ddev->render->index,
|
||||
|
@ -9187,6 +9187,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
* To fix this, DC should permit updating only stream properties.
|
||||
*/
|
||||
dummy_updates = kzalloc(sizeof(struct dc_surface_update) * MAX_SURFACES, GFP_ATOMIC);
|
||||
if (!dummy_updates) {
|
||||
DRM_ERROR("Failed to allocate memory for dummy_updates.\n");
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < status->plane_count; j++)
|
||||
dummy_updates[j].surface = status->plane_states[0];
|
||||
|
||||
|
@ -437,32 +437,32 @@ static struct wm_table ddr5_wm_table = {
|
||||
.wm_inst = WM_A,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.72,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_B,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.72,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_C,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.72,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_D,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.72,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
}
|
||||
@ -474,32 +474,32 @@ static struct wm_table lpddr5_wm_table = {
|
||||
.wm_inst = WM_A,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_B,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_C,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_D,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.valid = true,
|
||||
},
|
||||
}
|
||||
|
@ -203,12 +203,12 @@ void dcn32_link_encoder_construct(
|
||||
enc10->base.hpd_source = init_data->hpd_source;
|
||||
enc10->base.connector = init_data->connector;
|
||||
|
||||
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
|
||||
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
|
||||
|
||||
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
|
||||
|
||||
enc10->base.features = *enc_features;
|
||||
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
|
||||
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
|
||||
|
||||
enc10->base.transmitter = init_data->transmitter;
|
||||
|
||||
|
@ -184,8 +184,6 @@ void dcn35_link_encoder_construct(
|
||||
enc10->base.hpd_source = init_data->hpd_source;
|
||||
enc10->base.connector = init_data->connector;
|
||||
|
||||
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
|
||||
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
|
||||
|
||||
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
|
||||
|
||||
@ -240,6 +238,8 @@ void dcn35_link_encoder_construct(
|
||||
}
|
||||
|
||||
enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
|
||||
if (enc10->base.connector.id == CONNECTOR_ID_USBC)
|
||||
enc10->base.features.flags.bits.DP_IS_USB_C = 1;
|
||||
|
||||
if (bp_funcs->get_connector_speed_cap_info)
|
||||
result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios,
|
||||
|
@ -1112,7 +1112,7 @@ struct pipe_slice_table {
|
||||
struct pipe_ctx *pri_pipe;
|
||||
struct dc_plane_state *plane;
|
||||
int slice_count;
|
||||
} mpc_combines[MAX_SURFACES];
|
||||
} mpc_combines[MAX_PLANES];
|
||||
int mpc_combine_count;
|
||||
};
|
||||
|
||||
@ -2753,7 +2753,7 @@ static int build_synthetic_soc_states(bool disable_dc_mode_overwrite, struct clk
|
||||
struct _vcs_dpi_voltage_scaling_st entry = {0};
|
||||
struct clk_limit_table_entry max_clk_data = {0};
|
||||
|
||||
unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
|
||||
unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599;
|
||||
|
||||
static const unsigned int num_dcfclk_stas = 5;
|
||||
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564};
|
||||
|
@ -164,8 +164,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
|
||||
},
|
||||
},
|
||||
.num_states = 5,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_time_us = 28.0,
|
||||
.sr_enter_plus_exit_time_us = 30.0,
|
||||
.sr_exit_z8_time_us = 210.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 320.0,
|
||||
.fclk_change_latency_us = 24.0,
|
||||
|
@ -341,9 +341,6 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc,
|
||||
break;
|
||||
}
|
||||
|
||||
if (dml2->config.bbox_overrides.clks_table.num_states)
|
||||
p->in_states->num_states = dml2->config.bbox_overrides.clks_table.num_states;
|
||||
|
||||
/* Override from passed values, if available */
|
||||
for (i = 0; i < p->in_states->num_states; i++) {
|
||||
if (dml2->config.bbox_overrides.sr_exit_latency_us) {
|
||||
@ -400,6 +397,7 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc,
|
||||
}
|
||||
/* Copy clocks tables entries, if available */
|
||||
if (dml2->config.bbox_overrides.clks_table.num_states) {
|
||||
p->in_states->num_states = dml2->config.bbox_overrides.clks_table.num_states;
|
||||
|
||||
for (i = 0; i < dml2->config.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels; i++) {
|
||||
p->in_states->state_array[i].dcfclk_mhz = dml2->config.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz;
|
||||
@ -793,35 +791,28 @@ static void populate_dml_surface_cfg_from_plane_state(enum dml_project_id dml2_p
|
||||
}
|
||||
}
|
||||
|
||||
/*TODO no support for mpc combine, need rework - should calculate scaling params based on plane+stream*/
|
||||
static struct scaler_data get_scaler_data_for_plane(const struct dc_plane_state *in, const struct dc_state *context)
|
||||
static struct scaler_data get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
struct scaler_data data = { 0 };
|
||||
struct pipe_ctx *temp_pipe = &context->res_ctx.temp_pipe;
|
||||
|
||||
memset(temp_pipe, 0, sizeof(struct pipe_ctx));
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->plane_state == in && !pipe->prev_odm_pipe) {
|
||||
const struct pipe_ctx *next_pipe = pipe->next_odm_pipe;
|
||||
temp_pipe->stream = pipe->stream;
|
||||
temp_pipe->plane_state = pipe->plane_state;
|
||||
temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;
|
||||
|
||||
data = context->res_ctx.pipe_ctx[i].plane_res.scl_data;
|
||||
while (next_pipe) {
|
||||
data.h_active += next_pipe->plane_res.scl_data.h_active;
|
||||
data.recout.width += next_pipe->plane_res.scl_data.recout.width;
|
||||
if (in->rotation == ROTATION_ANGLE_0 || in->rotation == ROTATION_ANGLE_180) {
|
||||
data.viewport.width += next_pipe->plane_res.scl_data.viewport.width;
|
||||
} else {
|
||||
data.viewport.height += next_pipe->plane_res.scl_data.viewport.height;
|
||||
}
|
||||
next_pipe = next_pipe->next_odm_pipe;
|
||||
}
|
||||
resource_build_scaling_params(temp_pipe);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(i < MAX_PIPES);
|
||||
return data;
|
||||
return temp_pipe->plane_res.scl_data;
|
||||
}
|
||||
|
||||
static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_stream_state *in)
|
||||
@ -866,7 +857,7 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned
|
||||
out->ScalerEnabled[location] = false;
|
||||
}
|
||||
|
||||
static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_plane_state *in, const struct dc_state *context)
|
||||
static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_plane_state *in, struct dc_state *context)
|
||||
{
|
||||
const struct scaler_data scaler_data = get_scaler_data_for_plane(in, context);
|
||||
|
||||
|
@ -1183,9 +1183,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
|
||||
dto_params.timing = &pipe_ctx->stream->timing;
|
||||
dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
|
||||
if (dccg) {
|
||||
dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
|
||||
dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
|
||||
dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
|
||||
dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
|
||||
}
|
||||
} else if (dccg && dccg->funcs->disable_symclk_se) {
|
||||
dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
|
||||
|
@ -2790,18 +2790,17 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
||||
}
|
||||
|
||||
if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
|
||||
dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
|
||||
dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
|
||||
|
||||
phyd32clk = get_phyd32clk_src(link);
|
||||
dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
|
||||
|
||||
dto_params.otg_inst = tg->inst;
|
||||
dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
|
||||
dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
|
||||
dto_params.timing = &pipe_ctx->stream->timing;
|
||||
dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
|
||||
dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
|
||||
dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
|
||||
dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
|
||||
|
||||
phyd32clk = get_phyd32clk_src(link);
|
||||
dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
|
||||
} else {
|
||||
if (dccg->funcs->enable_symclk_se)
|
||||
dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst,
|
||||
|
@ -469,6 +469,8 @@ struct resource_context {
|
||||
unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
|
||||
int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
|
||||
bool is_mpc_3dlut_acquired[MAX_PIPES];
|
||||
/* solely used for build scalar data in dml2 */
|
||||
struct pipe_ctx temp_pipe;
|
||||
};
|
||||
|
||||
struct dce_bw_output {
|
||||
|
@ -196,7 +196,7 @@ static int get_host_router_total_dp_tunnel_bw(const struct dc *dc, uint8_t hr_in
|
||||
struct dc_link *link_dpia_primary, *link_dpia_secondary;
|
||||
int total_bw = 0;
|
||||
|
||||
for (uint8_t i = 0; i < MAX_PIPES * 2; ++i) {
|
||||
for (uint8_t i = 0; i < (MAX_PIPES * 2) - 1; ++i) {
|
||||
|
||||
if (!dc->links[i] || dc->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA)
|
||||
continue;
|
||||
|
@ -734,7 +734,7 @@ static int smu_early_init(void *handle)
|
||||
smu->adev = adev;
|
||||
smu->pm_enabled = !!amdgpu_dpm;
|
||||
smu->is_apu = false;
|
||||
smu->smu_baco.state = SMU_BACO_STATE_NONE;
|
||||
smu->smu_baco.state = SMU_BACO_STATE_EXIT;
|
||||
smu->smu_baco.platform_support = false;
|
||||
smu->user_dpm_profile.fan_mode = -1;
|
||||
|
||||
@ -1954,31 +1954,10 @@ static int smu_smc_hw_cleanup(struct smu_context *smu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smu_reset_mp1_state(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
|
||||
if ((!adev->in_runpm) && (!adev->in_suspend) &&
|
||||
(!amdgpu_in_reset(adev)))
|
||||
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smu_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct smu_context *smu = adev->powerplay.pp_handle;
|
||||
int ret;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
|
||||
return 0;
|
||||
@ -1996,15 +1975,7 @@ static int smu_hw_fini(void *handle)
|
||||
|
||||
adev->pm.dpm_enabled = false;
|
||||
|
||||
ret = smu_smc_hw_cleanup(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_reset_mp1_state(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return smu_smc_hw_cleanup(smu);
|
||||
}
|
||||
|
||||
static void smu_late_fini(void *handle)
|
||||
|
@ -424,7 +424,6 @@ enum smu_reset_mode {
|
||||
enum smu_baco_state {
|
||||
SMU_BACO_STATE_ENTER = 0,
|
||||
SMU_BACO_STATE_EXIT,
|
||||
SMU_BACO_STATE_NONE,
|
||||
};
|
||||
|
||||
struct smu_baco_context {
|
||||
|
@ -2748,13 +2748,7 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
|
||||
|
||||
switch (mp1_state) {
|
||||
case PP_MP1_STATE_UNLOAD:
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_PrepareMp1ForUnload,
|
||||
0x55, NULL);
|
||||
|
||||
if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT)
|
||||
ret = smu_v13_0_disable_pmfw_state(smu);
|
||||
|
||||
ret = smu_cmn_set_mp1_state(smu, mp1_state);
|
||||
break;
|
||||
default:
|
||||
/* Ignore others */
|
||||
@ -2950,7 +2944,7 @@ static bool smu_v13_0_0_wbrf_support_check(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
return smu->smc_fw_version >= 0x004e6300;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
|
@ -2505,13 +2505,7 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu,
|
||||
|
||||
switch (mp1_state) {
|
||||
case PP_MP1_STATE_UNLOAD:
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_PrepareMp1ForUnload,
|
||||
0x55, NULL);
|
||||
|
||||
if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT)
|
||||
ret = smu_v13_0_disable_pmfw_state(smu);
|
||||
|
||||
ret = smu_cmn_set_mp1_state(smu, mp1_state);
|
||||
break;
|
||||
default:
|
||||
/* Ignore others */
|
||||
|
@ -103,6 +103,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
|
||||
void
|
||||
nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
|
||||
{
|
||||
cancel_work_sync(&fctx->uevent_work);
|
||||
nouveau_fence_context_kill(fctx, 0);
|
||||
nvif_event_dtor(&fctx->event);
|
||||
fctx->dead = 1;
|
||||
@ -145,12 +146,13 @@ nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fc
|
||||
return drop;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc)
|
||||
static void
|
||||
nouveau_fence_uevent_work(struct work_struct *work)
|
||||
{
|
||||
struct nouveau_fence_chan *fctx = container_of(event, typeof(*fctx), event);
|
||||
struct nouveau_fence_chan *fctx = container_of(work, struct nouveau_fence_chan,
|
||||
uevent_work);
|
||||
unsigned long flags;
|
||||
int ret = NVIF_EVENT_KEEP;
|
||||
int drop = 0;
|
||||
|
||||
spin_lock_irqsave(&fctx->lock, flags);
|
||||
if (!list_empty(&fctx->pending)) {
|
||||
@ -160,11 +162,20 @@ nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc
|
||||
fence = list_entry(fctx->pending.next, typeof(*fence), head);
|
||||
chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock));
|
||||
if (nouveau_fence_update(chan, fctx))
|
||||
ret = NVIF_EVENT_DROP;
|
||||
drop = 1;
|
||||
}
|
||||
spin_unlock_irqrestore(&fctx->lock, flags);
|
||||
if (drop)
|
||||
nvif_event_block(&fctx->event);
|
||||
|
||||
return ret;
|
||||
spin_unlock_irqrestore(&fctx->lock, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc)
|
||||
{
|
||||
struct nouveau_fence_chan *fctx = container_of(event, typeof(*fctx), event);
|
||||
schedule_work(&fctx->uevent_work);
|
||||
return NVIF_EVENT_KEEP;
|
||||
}
|
||||
|
||||
void
|
||||
@ -178,6 +189,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
|
||||
} args;
|
||||
int ret;
|
||||
|
||||
INIT_WORK(&fctx->uevent_work, nouveau_fence_uevent_work);
|
||||
INIT_LIST_HEAD(&fctx->flip);
|
||||
INIT_LIST_HEAD(&fctx->pending);
|
||||
spin_lock_init(&fctx->lock);
|
||||
|
@ -44,6 +44,7 @@ struct nouveau_fence_chan {
|
||||
u32 context;
|
||||
char name[32];
|
||||
|
||||
struct work_struct uevent_work;
|
||||
struct nvif_event event;
|
||||
int notify_ref, dead, killed;
|
||||
};
|
||||
|
@ -1078,7 +1078,6 @@ r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp)
|
||||
if (IS_ERR(rpc))
|
||||
return PTR_ERR(rpc);
|
||||
|
||||
rpc->size = sizeof(*rpc);
|
||||
rpc->numEntries = NV_GSP_REG_NUM_ENTRIES;
|
||||
|
||||
str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]);
|
||||
@ -1094,6 +1093,7 @@ r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp)
|
||||
strings += name_len;
|
||||
str_offset += name_len;
|
||||
}
|
||||
rpc->size = str_offset;
|
||||
|
||||
return nvkm_gsp_rpc_wr(gsp, rpc, false);
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
dma_set_max_seg_size(dev->dev, dma_max_mapping_size(dev->dev) ?: UINT_MAX);
|
||||
ret = virtio_gpu_init(vdev, dev);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
@ -50,8 +50,8 @@
|
||||
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN (GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ GUC_HXG_REQUEST_MSG_0_DATA0
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY (0xffff << 16)
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN (0xffff << 0)
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY (0xffffu << 16)
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN (0xffffu << 0)
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32 GUC_HXG_REQUEST_MSG_n_DATAn
|
||||
#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64 GUC_HXG_REQUEST_MSG_n_DATAn
|
||||
|
||||
|
@ -242,8 +242,8 @@ struct slpc_shared_data {
|
||||
(HOST2GUC_PC_SLPC_REQUEST_REQUEST_MSG_MIN_LEN + \
|
||||
HOST2GUC_PC_SLPC_EVENT_MAX_INPUT_ARGS)
|
||||
#define HOST2GUC_PC_SLPC_REQUEST_MSG_0_MBZ GUC_HXG_REQUEST_MSG_0_DATA0
|
||||
#define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ID (0xff << 8)
|
||||
#define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ARGC (0xff << 0)
|
||||
#define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ID (0xffu << 8)
|
||||
#define HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ARGC (0xffu << 0)
|
||||
#define HOST2GUC_PC_SLPC_REQUEST_MSG_N_EVENT_DATA_N GUC_HXG_REQUEST_MSG_n_DATAn
|
||||
|
||||
#endif
|
||||
|
@ -82,11 +82,11 @@ static_assert(sizeof(struct guc_ct_buffer_desc) == 64);
|
||||
#define GUC_CTB_HDR_LEN 1u
|
||||
#define GUC_CTB_MSG_MIN_LEN GUC_CTB_HDR_LEN
|
||||
#define GUC_CTB_MSG_MAX_LEN 256u
|
||||
#define GUC_CTB_MSG_0_FENCE (0xffff << 16)
|
||||
#define GUC_CTB_MSG_0_FORMAT (0xf << 12)
|
||||
#define GUC_CTB_MSG_0_FENCE (0xffffu << 16)
|
||||
#define GUC_CTB_MSG_0_FORMAT (0xfu << 12)
|
||||
#define GUC_CTB_FORMAT_HXG 0u
|
||||
#define GUC_CTB_MSG_0_RESERVED (0xf << 8)
|
||||
#define GUC_CTB_MSG_0_NUM_DWORDS (0xff << 0)
|
||||
#define GUC_CTB_MSG_0_RESERVED (0xfu << 8)
|
||||
#define GUC_CTB_MSG_0_NUM_DWORDS (0xffu << 0)
|
||||
|
||||
/**
|
||||
* DOC: CTB HXG Message
|
||||
|
@ -31,9 +31,9 @@
|
||||
*/
|
||||
|
||||
#define GUC_KLV_LEN_MIN 1u
|
||||
#define GUC_KLV_0_KEY (0xffff << 16)
|
||||
#define GUC_KLV_0_LEN (0xffff << 0)
|
||||
#define GUC_KLV_n_VALUE (0xffffffff << 0)
|
||||
#define GUC_KLV_0_KEY (0xffffu << 16)
|
||||
#define GUC_KLV_0_LEN (0xffffu << 0)
|
||||
#define GUC_KLV_n_VALUE (0xffffffffu << 0)
|
||||
|
||||
/**
|
||||
* DOC: GuC Self Config KLVs
|
||||
|
@ -40,18 +40,18 @@
|
||||
*/
|
||||
|
||||
#define GUC_HXG_MSG_MIN_LEN 1u
|
||||
#define GUC_HXG_MSG_0_ORIGIN (0x1 << 31)
|
||||
#define GUC_HXG_MSG_0_ORIGIN (0x1u << 31)
|
||||
#define GUC_HXG_ORIGIN_HOST 0u
|
||||
#define GUC_HXG_ORIGIN_GUC 1u
|
||||
#define GUC_HXG_MSG_0_TYPE (0x7 << 28)
|
||||
#define GUC_HXG_MSG_0_TYPE (0x7u << 28)
|
||||
#define GUC_HXG_TYPE_REQUEST 0u
|
||||
#define GUC_HXG_TYPE_EVENT 1u
|
||||
#define GUC_HXG_TYPE_NO_RESPONSE_BUSY 3u
|
||||
#define GUC_HXG_TYPE_NO_RESPONSE_RETRY 5u
|
||||
#define GUC_HXG_TYPE_RESPONSE_FAILURE 6u
|
||||
#define GUC_HXG_TYPE_RESPONSE_SUCCESS 7u
|
||||
#define GUC_HXG_MSG_0_AUX (0xfffffff << 0)
|
||||
#define GUC_HXG_MSG_n_PAYLOAD (0xffffffff << 0)
|
||||
#define GUC_HXG_MSG_0_AUX (0xfffffffu << 0)
|
||||
#define GUC_HXG_MSG_n_PAYLOAD (0xffffffffu << 0)
|
||||
|
||||
/**
|
||||
* DOC: HXG Request
|
||||
@ -85,8 +85,8 @@
|
||||
*/
|
||||
|
||||
#define GUC_HXG_REQUEST_MSG_MIN_LEN GUC_HXG_MSG_MIN_LEN
|
||||
#define GUC_HXG_REQUEST_MSG_0_DATA0 (0xfff << 16)
|
||||
#define GUC_HXG_REQUEST_MSG_0_ACTION (0xffff << 0)
|
||||
#define GUC_HXG_REQUEST_MSG_0_DATA0 (0xfffu << 16)
|
||||
#define GUC_HXG_REQUEST_MSG_0_ACTION (0xffffu << 0)
|
||||
#define GUC_HXG_REQUEST_MSG_n_DATAn GUC_HXG_MSG_n_PAYLOAD
|
||||
|
||||
/**
|
||||
@ -117,8 +117,8 @@
|
||||
*/
|
||||
|
||||
#define GUC_HXG_EVENT_MSG_MIN_LEN GUC_HXG_MSG_MIN_LEN
|
||||
#define GUC_HXG_EVENT_MSG_0_DATA0 (0xfff << 16)
|
||||
#define GUC_HXG_EVENT_MSG_0_ACTION (0xffff << 0)
|
||||
#define GUC_HXG_EVENT_MSG_0_DATA0 (0xfffu << 16)
|
||||
#define GUC_HXG_EVENT_MSG_0_ACTION (0xffffu << 0)
|
||||
#define GUC_HXG_EVENT_MSG_n_DATAn GUC_HXG_MSG_n_PAYLOAD
|
||||
|
||||
/**
|
||||
@ -188,8 +188,8 @@
|
||||
*/
|
||||
|
||||
#define GUC_HXG_FAILURE_MSG_LEN GUC_HXG_MSG_MIN_LEN
|
||||
#define GUC_HXG_FAILURE_MSG_0_HINT (0xfff << 16)
|
||||
#define GUC_HXG_FAILURE_MSG_0_ERROR (0xffff << 0)
|
||||
#define GUC_HXG_FAILURE_MSG_0_HINT (0xfffu << 16)
|
||||
#define GUC_HXG_FAILURE_MSG_0_ERROR (0xffffu << 0)
|
||||
|
||||
/**
|
||||
* DOC: HXG Response
|
||||
|
@ -111,7 +111,7 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
||||
u64 addresses[XE_HW_ENGINE_MAX_INSTANCE];
|
||||
struct drm_gpuvm_exec vm_exec = {.extra.fn = xe_exec_fn};
|
||||
struct drm_exec *exec = &vm_exec.exec;
|
||||
u32 i, num_syncs = 0;
|
||||
u32 i, num_syncs = 0, num_ufence = 0;
|
||||
struct xe_sched_job *job;
|
||||
struct dma_fence *rebind_fence;
|
||||
struct xe_vm *vm;
|
||||
@ -157,6 +157,14 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
||||
SYNC_PARSE_FLAG_LR_MODE : 0));
|
||||
if (err)
|
||||
goto err_syncs;
|
||||
|
||||
if (xe_sync_is_ufence(&syncs[i]))
|
||||
num_ufence++;
|
||||
}
|
||||
|
||||
if (XE_IOCTL_DBG(xe, num_ufence > 1)) {
|
||||
err = -EINVAL;
|
||||
goto err_syncs;
|
||||
}
|
||||
|
||||
if (xe_exec_queue_is_parallel(q)) {
|
||||
|
@ -480,7 +480,7 @@ static bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt,
|
||||
* to synchronize with external clients (e.g., firmware), so a semaphore
|
||||
* register will also need to be taken.
|
||||
*/
|
||||
static void mcr_lock(struct xe_gt *gt)
|
||||
static void mcr_lock(struct xe_gt *gt) __acquires(>->mcr_lock)
|
||||
{
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
int ret = 0;
|
||||
@ -500,7 +500,7 @@ static void mcr_lock(struct xe_gt *gt)
|
||||
drm_WARN_ON_ONCE(&xe->drm, ret == -ETIMEDOUT);
|
||||
}
|
||||
|
||||
static void mcr_unlock(struct xe_gt *gt)
|
||||
static void mcr_unlock(struct xe_gt *gt) __releases(>->mcr_lock)
|
||||
{
|
||||
/* Release hardware semaphore - this is done by writing 1 to the register */
|
||||
if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270)
|
||||
|
@ -165,7 +165,8 @@ retry_userptr:
|
||||
goto unlock_vm;
|
||||
}
|
||||
|
||||
if (!xe_vma_is_userptr(vma) || !xe_vma_userptr_check_repin(vma)) {
|
||||
if (!xe_vma_is_userptr(vma) ||
|
||||
!xe_vma_userptr_check_repin(to_userptr_vma(vma))) {
|
||||
downgrade_write(&vm->lock);
|
||||
write_locked = false;
|
||||
}
|
||||
@ -181,11 +182,13 @@ retry_userptr:
|
||||
/* TODO: Validate fault */
|
||||
|
||||
if (xe_vma_is_userptr(vma) && write_locked) {
|
||||
struct xe_userptr_vma *uvma = to_userptr_vma(vma);
|
||||
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_del_init(&vma->userptr.invalidate_link);
|
||||
list_del_init(&uvma->userptr.invalidate_link);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
|
||||
ret = xe_vma_userptr_pin_pages(vma);
|
||||
ret = xe_vma_userptr_pin_pages(uvma);
|
||||
if (ret)
|
||||
goto unlock_vm;
|
||||
|
||||
@ -220,7 +223,7 @@ retry_userptr:
|
||||
dma_fence_put(fence);
|
||||
|
||||
if (xe_vma_is_userptr(vma))
|
||||
ret = xe_vma_userptr_check_repin(vma);
|
||||
ret = xe_vma_userptr_check_repin(to_userptr_vma(vma));
|
||||
vma->usm.tile_invalidated &= ~BIT(tile->id);
|
||||
|
||||
unlock_dma_resv:
|
||||
|
@ -963,7 +963,9 @@ void xe_guc_pc_fini(struct xe_guc_pc *pc)
|
||||
struct xe_device *xe = pc_to_xe(pc);
|
||||
|
||||
if (xe->info.skip_guc_pc) {
|
||||
xe_device_mem_access_get(xe);
|
||||
xe_gt_idle_disable_c6(pc_to_gt(pc));
|
||||
xe_device_mem_access_put(xe);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -217,13 +217,13 @@ struct xe_hw_fence *xe_hw_fence_create(struct xe_hw_fence_ctx *ctx,
|
||||
if (!fence)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dma_fence_init(&fence->dma, &xe_hw_fence_ops, &ctx->irq->lock,
|
||||
ctx->dma_fence_ctx, ctx->next_seqno++);
|
||||
|
||||
fence->ctx = ctx;
|
||||
fence->seqno_map = seqno_map;
|
||||
INIT_LIST_HEAD(&fence->irq_link);
|
||||
|
||||
dma_fence_init(&fence->dma, &xe_hw_fence_ops, &ctx->irq->lock,
|
||||
ctx->dma_fence_ctx, ctx->next_seqno++);
|
||||
|
||||
trace_xe_hw_fence_create(fence);
|
||||
|
||||
return fence;
|
||||
|
@ -21,10 +21,10 @@
|
||||
#include "xe_map.h"
|
||||
#include "xe_vm.h"
|
||||
|
||||
#define CTX_VALID (1 << 0)
|
||||
#define CTX_PRIVILEGE (1 << 8)
|
||||
#define CTX_ADDRESSING_MODE_SHIFT 3
|
||||
#define LEGACY_64B_CONTEXT 3
|
||||
#define LRC_VALID (1 << 0)
|
||||
#define LRC_PRIVILEGE (1 << 8)
|
||||
#define LRC_ADDRESSING_MODE_SHIFT 3
|
||||
#define LRC_LEGACY_64B_CONTEXT 3
|
||||
|
||||
#define ENGINE_CLASS_SHIFT 61
|
||||
#define ENGINE_INSTANCE_SHIFT 48
|
||||
@ -762,15 +762,15 @@ int xe_lrc_init(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
|
||||
(q->usm.acc_notify << ACC_NOTIFY_S) |
|
||||
q->usm.acc_trigger);
|
||||
|
||||
lrc->desc = CTX_VALID;
|
||||
lrc->desc |= LEGACY_64B_CONTEXT << CTX_ADDRESSING_MODE_SHIFT;
|
||||
lrc->desc = LRC_VALID;
|
||||
lrc->desc |= LRC_LEGACY_64B_CONTEXT << LRC_ADDRESSING_MODE_SHIFT;
|
||||
/* TODO: Priority */
|
||||
|
||||
/* While this appears to have something about privileged batches or
|
||||
* some such, it really just means PPGTT mode.
|
||||
*/
|
||||
if (vm)
|
||||
lrc->desc |= CTX_PRIVILEGE;
|
||||
lrc->desc |= LRC_PRIVILEGE;
|
||||
|
||||
if (GRAPHICS_VERx100(xe) < 1250) {
|
||||
lrc->desc |= (u64)hwe->instance << ENGINE_INSTANCE_SHIFT;
|
||||
|
@ -618,8 +618,8 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
|
||||
|
||||
if (!xe_vma_is_null(vma)) {
|
||||
if (xe_vma_is_userptr(vma))
|
||||
xe_res_first_sg(vma->userptr.sg, 0, xe_vma_size(vma),
|
||||
&curs);
|
||||
xe_res_first_sg(to_userptr_vma(vma)->userptr.sg, 0,
|
||||
xe_vma_size(vma), &curs);
|
||||
else if (xe_bo_is_vram(bo) || xe_bo_is_stolen(bo))
|
||||
xe_res_first(bo->ttm.resource, xe_vma_bo_offset(vma),
|
||||
xe_vma_size(vma), &curs);
|
||||
@ -906,17 +906,17 @@ static void xe_vm_dbg_print_entries(struct xe_device *xe,
|
||||
|
||||
#ifdef CONFIG_DRM_XE_USERPTR_INVAL_INJECT
|
||||
|
||||
static int xe_pt_userptr_inject_eagain(struct xe_vma *vma)
|
||||
static int xe_pt_userptr_inject_eagain(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
u32 divisor = vma->userptr.divisor ? vma->userptr.divisor : 2;
|
||||
u32 divisor = uvma->userptr.divisor ? uvma->userptr.divisor : 2;
|
||||
static u32 count;
|
||||
|
||||
if (count++ % divisor == divisor - 1) {
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct xe_vm *vm = xe_vma_vm(&uvma->vma);
|
||||
|
||||
vma->userptr.divisor = divisor << 1;
|
||||
uvma->userptr.divisor = divisor << 1;
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_move_tail(&vma->userptr.invalidate_link,
|
||||
list_move_tail(&uvma->userptr.invalidate_link,
|
||||
&vm->userptr.invalidated);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
return true;
|
||||
@ -927,7 +927,7 @@ static int xe_pt_userptr_inject_eagain(struct xe_vma *vma)
|
||||
|
||||
#else
|
||||
|
||||
static bool xe_pt_userptr_inject_eagain(struct xe_vma *vma)
|
||||
static bool xe_pt_userptr_inject_eagain(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -1000,9 +1000,9 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update)
|
||||
{
|
||||
struct xe_pt_migrate_pt_update *userptr_update =
|
||||
container_of(pt_update, typeof(*userptr_update), base);
|
||||
struct xe_vma *vma = pt_update->vma;
|
||||
unsigned long notifier_seq = vma->userptr.notifier_seq;
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct xe_userptr_vma *uvma = to_userptr_vma(pt_update->vma);
|
||||
unsigned long notifier_seq = uvma->userptr.notifier_seq;
|
||||
struct xe_vm *vm = xe_vma_vm(&uvma->vma);
|
||||
int err = xe_pt_vm_dependencies(pt_update->job,
|
||||
&vm->rftree[pt_update->tile_id],
|
||||
pt_update->start,
|
||||
@ -1023,7 +1023,7 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update)
|
||||
*/
|
||||
do {
|
||||
down_read(&vm->userptr.notifier_lock);
|
||||
if (!mmu_interval_read_retry(&vma->userptr.notifier,
|
||||
if (!mmu_interval_read_retry(&uvma->userptr.notifier,
|
||||
notifier_seq))
|
||||
break;
|
||||
|
||||
@ -1032,11 +1032,11 @@ static int xe_pt_userptr_pre_commit(struct xe_migrate_pt_update *pt_update)
|
||||
if (userptr_update->bind)
|
||||
return -EAGAIN;
|
||||
|
||||
notifier_seq = mmu_interval_read_begin(&vma->userptr.notifier);
|
||||
notifier_seq = mmu_interval_read_begin(&uvma->userptr.notifier);
|
||||
} while (true);
|
||||
|
||||
/* Inject errors to test_whether they are handled correctly */
|
||||
if (userptr_update->bind && xe_pt_userptr_inject_eagain(vma)) {
|
||||
if (userptr_update->bind && xe_pt_userptr_inject_eagain(uvma)) {
|
||||
up_read(&vm->userptr.notifier_lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
@ -1297,7 +1297,7 @@ __xe_pt_bind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queue
|
||||
vma->tile_present |= BIT(tile->id);
|
||||
|
||||
if (bind_pt_update.locked) {
|
||||
vma->userptr.initial_bind = true;
|
||||
to_userptr_vma(vma)->userptr.initial_bind = true;
|
||||
up_read(&vm->userptr.notifier_lock);
|
||||
xe_bo_put_commit(&deferred);
|
||||
}
|
||||
@ -1642,7 +1642,7 @@ __xe_pt_unbind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queu
|
||||
|
||||
if (!vma->tile_present) {
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_del_init(&vma->userptr.invalidate_link);
|
||||
list_del_init(&to_userptr_vma(vma)->userptr.invalidate_link);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
}
|
||||
up_read(&vm->userptr.notifier_lock);
|
||||
|
@ -459,21 +459,21 @@ static size_t calc_topo_query_size(struct xe_device *xe)
|
||||
sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss));
|
||||
}
|
||||
|
||||
static void __user *copy_mask(void __user *ptr,
|
||||
struct drm_xe_query_topology_mask *topo,
|
||||
void *mask, size_t mask_size)
|
||||
static int copy_mask(void __user **ptr,
|
||||
struct drm_xe_query_topology_mask *topo,
|
||||
void *mask, size_t mask_size)
|
||||
{
|
||||
topo->num_bytes = mask_size;
|
||||
|
||||
if (copy_to_user(ptr, topo, sizeof(*topo)))
|
||||
return ERR_PTR(-EFAULT);
|
||||
ptr += sizeof(topo);
|
||||
if (copy_to_user(*ptr, topo, sizeof(*topo)))
|
||||
return -EFAULT;
|
||||
*ptr += sizeof(topo);
|
||||
|
||||
if (copy_to_user(ptr, mask, mask_size))
|
||||
return ERR_PTR(-EFAULT);
|
||||
ptr += mask_size;
|
||||
if (copy_to_user(*ptr, mask, mask_size))
|
||||
return -EFAULT;
|
||||
*ptr += mask_size;
|
||||
|
||||
return ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int query_gt_topology(struct xe_device *xe,
|
||||
@ -493,28 +493,28 @@ static int query_gt_topology(struct xe_device *xe,
|
||||
}
|
||||
|
||||
for_each_gt(gt, xe, id) {
|
||||
int err;
|
||||
|
||||
topo.gt_id = id;
|
||||
|
||||
topo.type = DRM_XE_TOPO_DSS_GEOMETRY;
|
||||
query_ptr = copy_mask(query_ptr, &topo,
|
||||
gt->fuse_topo.g_dss_mask,
|
||||
sizeof(gt->fuse_topo.g_dss_mask));
|
||||
if (IS_ERR(query_ptr))
|
||||
return PTR_ERR(query_ptr);
|
||||
err = copy_mask(&query_ptr, &topo, gt->fuse_topo.g_dss_mask,
|
||||
sizeof(gt->fuse_topo.g_dss_mask));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
topo.type = DRM_XE_TOPO_DSS_COMPUTE;
|
||||
query_ptr = copy_mask(query_ptr, &topo,
|
||||
gt->fuse_topo.c_dss_mask,
|
||||
sizeof(gt->fuse_topo.c_dss_mask));
|
||||
if (IS_ERR(query_ptr))
|
||||
return PTR_ERR(query_ptr);
|
||||
err = copy_mask(&query_ptr, &topo, gt->fuse_topo.c_dss_mask,
|
||||
sizeof(gt->fuse_topo.c_dss_mask));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
topo.type = DRM_XE_TOPO_EU_PER_DSS;
|
||||
query_ptr = copy_mask(query_ptr, &topo,
|
||||
gt->fuse_topo.eu_mask_per_dss,
|
||||
sizeof(gt->fuse_topo.eu_mask_per_dss));
|
||||
if (IS_ERR(query_ptr))
|
||||
return PTR_ERR(query_ptr);
|
||||
err = copy_mask(&query_ptr, &topo,
|
||||
gt->fuse_topo.eu_mask_per_dss,
|
||||
sizeof(gt->fuse_topo.eu_mask_per_dss));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -33,4 +33,9 @@ struct dma_fence *
|
||||
xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync,
|
||||
struct xe_exec_queue *q, struct xe_vm *vm);
|
||||
|
||||
static inline bool xe_sync_is_ufence(struct xe_sync_entry *sync)
|
||||
{
|
||||
return !!sync->ufence;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -46,7 +46,7 @@ static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm)
|
||||
|
||||
/**
|
||||
* xe_vma_userptr_check_repin() - Advisory check for repin needed
|
||||
* @vma: The userptr vma
|
||||
* @uvma: The userptr vma
|
||||
*
|
||||
* Check if the userptr vma has been invalidated since last successful
|
||||
* repin. The check is advisory only and can the function can be called
|
||||
@ -56,15 +56,17 @@ static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm)
|
||||
*
|
||||
* Return: 0 if userptr vma is valid, -EAGAIN otherwise; repin recommended.
|
||||
*/
|
||||
int xe_vma_userptr_check_repin(struct xe_vma *vma)
|
||||
int xe_vma_userptr_check_repin(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
return mmu_interval_check_retry(&vma->userptr.notifier,
|
||||
vma->userptr.notifier_seq) ?
|
||||
return mmu_interval_check_retry(&uvma->userptr.notifier,
|
||||
uvma->userptr.notifier_seq) ?
|
||||
-EAGAIN : 0;
|
||||
}
|
||||
|
||||
int xe_vma_userptr_pin_pages(struct xe_vma *vma)
|
||||
int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
struct xe_userptr *userptr = &uvma->userptr;
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct xe_device *xe = vm->xe;
|
||||
const unsigned long num_pages = xe_vma_size(vma) >> PAGE_SHIFT;
|
||||
@ -80,30 +82,30 @@ retry:
|
||||
if (vma->gpuva.flags & XE_VMA_DESTROYED)
|
||||
return 0;
|
||||
|
||||
notifier_seq = mmu_interval_read_begin(&vma->userptr.notifier);
|
||||
if (notifier_seq == vma->userptr.notifier_seq)
|
||||
notifier_seq = mmu_interval_read_begin(&userptr->notifier);
|
||||
if (notifier_seq == userptr->notifier_seq)
|
||||
return 0;
|
||||
|
||||
pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
|
||||
if (vma->userptr.sg) {
|
||||
if (userptr->sg) {
|
||||
dma_unmap_sgtable(xe->drm.dev,
|
||||
vma->userptr.sg,
|
||||
userptr->sg,
|
||||
read_only ? DMA_TO_DEVICE :
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
sg_free_table(vma->userptr.sg);
|
||||
vma->userptr.sg = NULL;
|
||||
sg_free_table(userptr->sg);
|
||||
userptr->sg = NULL;
|
||||
}
|
||||
|
||||
pinned = ret = 0;
|
||||
if (in_kthread) {
|
||||
if (!mmget_not_zero(vma->userptr.notifier.mm)) {
|
||||
if (!mmget_not_zero(userptr->notifier.mm)) {
|
||||
ret = -EFAULT;
|
||||
goto mm_closed;
|
||||
}
|
||||
kthread_use_mm(vma->userptr.notifier.mm);
|
||||
kthread_use_mm(userptr->notifier.mm);
|
||||
}
|
||||
|
||||
while (pinned < num_pages) {
|
||||
@ -123,32 +125,32 @@ retry:
|
||||
}
|
||||
|
||||
if (in_kthread) {
|
||||
kthread_unuse_mm(vma->userptr.notifier.mm);
|
||||
mmput(vma->userptr.notifier.mm);
|
||||
kthread_unuse_mm(userptr->notifier.mm);
|
||||
mmput(userptr->notifier.mm);
|
||||
}
|
||||
mm_closed:
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = sg_alloc_table_from_pages_segment(&vma->userptr.sgt, pages,
|
||||
ret = sg_alloc_table_from_pages_segment(&userptr->sgt, pages,
|
||||
pinned, 0,
|
||||
(u64)pinned << PAGE_SHIFT,
|
||||
xe_sg_segment_size(xe->drm.dev),
|
||||
GFP_KERNEL);
|
||||
if (ret) {
|
||||
vma->userptr.sg = NULL;
|
||||
userptr->sg = NULL;
|
||||
goto out;
|
||||
}
|
||||
vma->userptr.sg = &vma->userptr.sgt;
|
||||
userptr->sg = &userptr->sgt;
|
||||
|
||||
ret = dma_map_sgtable(xe->drm.dev, vma->userptr.sg,
|
||||
ret = dma_map_sgtable(xe->drm.dev, userptr->sg,
|
||||
read_only ? DMA_TO_DEVICE :
|
||||
DMA_BIDIRECTIONAL,
|
||||
DMA_ATTR_SKIP_CPU_SYNC |
|
||||
DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
if (ret) {
|
||||
sg_free_table(vma->userptr.sg);
|
||||
vma->userptr.sg = NULL;
|
||||
sg_free_table(userptr->sg);
|
||||
userptr->sg = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -167,8 +169,8 @@ out:
|
||||
kvfree(pages);
|
||||
|
||||
if (!(ret < 0)) {
|
||||
vma->userptr.notifier_seq = notifier_seq;
|
||||
if (xe_vma_userptr_check_repin(vma) == -EAGAIN)
|
||||
userptr->notifier_seq = notifier_seq;
|
||||
if (xe_vma_userptr_check_repin(uvma) == -EAGAIN)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@ -635,7 +637,9 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
{
|
||||
struct xe_vma *vma = container_of(mni, struct xe_vma, userptr.notifier);
|
||||
struct xe_userptr *userptr = container_of(mni, typeof(*userptr), notifier);
|
||||
struct xe_userptr_vma *uvma = container_of(userptr, typeof(*uvma), userptr);
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
@ -651,7 +655,7 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
|
||||
mmu_interval_set_seq(mni, cur_seq);
|
||||
|
||||
/* No need to stop gpu access if the userptr is not yet bound. */
|
||||
if (!vma->userptr.initial_bind) {
|
||||
if (!userptr->initial_bind) {
|
||||
up_write(&vm->userptr.notifier_lock);
|
||||
return true;
|
||||
}
|
||||
@ -663,7 +667,7 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
|
||||
if (!xe_vm_in_fault_mode(vm) &&
|
||||
!(vma->gpuva.flags & XE_VMA_DESTROYED) && vma->tile_present) {
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_move_tail(&vma->userptr.invalidate_link,
|
||||
list_move_tail(&userptr->invalidate_link,
|
||||
&vm->userptr.invalidated);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
}
|
||||
@ -703,7 +707,7 @@ static const struct mmu_interval_notifier_ops vma_userptr_notifier_ops = {
|
||||
|
||||
int xe_vm_userptr_pin(struct xe_vm *vm)
|
||||
{
|
||||
struct xe_vma *vma, *next;
|
||||
struct xe_userptr_vma *uvma, *next;
|
||||
int err = 0;
|
||||
LIST_HEAD(tmp_evict);
|
||||
|
||||
@ -711,22 +715,23 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
|
||||
|
||||
/* Collect invalidated userptrs */
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_for_each_entry_safe(vma, next, &vm->userptr.invalidated,
|
||||
list_for_each_entry_safe(uvma, next, &vm->userptr.invalidated,
|
||||
userptr.invalidate_link) {
|
||||
list_del_init(&vma->userptr.invalidate_link);
|
||||
list_move_tail(&vma->combined_links.userptr,
|
||||
list_del_init(&uvma->userptr.invalidate_link);
|
||||
list_move_tail(&uvma->userptr.repin_link,
|
||||
&vm->userptr.repin_list);
|
||||
}
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
|
||||
/* Pin and move to temporary list */
|
||||
list_for_each_entry_safe(vma, next, &vm->userptr.repin_list,
|
||||
combined_links.userptr) {
|
||||
err = xe_vma_userptr_pin_pages(vma);
|
||||
list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
|
||||
userptr.repin_link) {
|
||||
err = xe_vma_userptr_pin_pages(uvma);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
list_move_tail(&vma->combined_links.userptr, &vm->rebind_list);
|
||||
list_del_init(&uvma->userptr.repin_link);
|
||||
list_move_tail(&uvma->vma.combined_links.rebind, &vm->rebind_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -782,6 +787,14 @@ struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
|
||||
return fence;
|
||||
}
|
||||
|
||||
static void xe_vma_free(struct xe_vma *vma)
|
||||
{
|
||||
if (xe_vma_is_userptr(vma))
|
||||
kfree(to_userptr_vma(vma));
|
||||
else
|
||||
kfree(vma);
|
||||
}
|
||||
|
||||
#define VMA_CREATE_FLAG_READ_ONLY BIT(0)
|
||||
#define VMA_CREATE_FLAG_IS_NULL BIT(1)
|
||||
|
||||
@ -800,14 +813,26 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||
xe_assert(vm->xe, start < end);
|
||||
xe_assert(vm->xe, end < vm->size);
|
||||
|
||||
if (!bo && !is_null) /* userptr */
|
||||
/*
|
||||
* Allocate and ensure that the xe_vma_is_userptr() return
|
||||
* matches what was allocated.
|
||||
*/
|
||||
if (!bo && !is_null) {
|
||||
struct xe_userptr_vma *uvma = kzalloc(sizeof(*uvma), GFP_KERNEL);
|
||||
|
||||
if (!uvma)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
vma = &uvma->vma;
|
||||
} else {
|
||||
vma = kzalloc(sizeof(*vma), GFP_KERNEL);
|
||||
else
|
||||
vma = kzalloc(sizeof(*vma) - sizeof(struct xe_userptr),
|
||||
GFP_KERNEL);
|
||||
if (!vma) {
|
||||
vma = ERR_PTR(-ENOMEM);
|
||||
return vma;
|
||||
if (!vma)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (is_null)
|
||||
vma->gpuva.flags |= DRM_GPUVA_SPARSE;
|
||||
if (bo)
|
||||
vma->gpuva.gem.obj = &bo->ttm.base;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&vma->combined_links.rebind);
|
||||
@ -818,8 +843,6 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||
vma->gpuva.va.range = end - start + 1;
|
||||
if (read_only)
|
||||
vma->gpuva.flags |= XE_VMA_READ_ONLY;
|
||||
if (is_null)
|
||||
vma->gpuva.flags |= DRM_GPUVA_SPARSE;
|
||||
|
||||
for_each_tile(tile, vm->xe, id)
|
||||
vma->tile_mask |= 0x1 << id;
|
||||
@ -836,35 +859,35 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||
|
||||
vm_bo = drm_gpuvm_bo_obtain(vma->gpuva.vm, &bo->ttm.base);
|
||||
if (IS_ERR(vm_bo)) {
|
||||
kfree(vma);
|
||||
xe_vma_free(vma);
|
||||
return ERR_CAST(vm_bo);
|
||||
}
|
||||
|
||||
drm_gpuvm_bo_extobj_add(vm_bo);
|
||||
drm_gem_object_get(&bo->ttm.base);
|
||||
vma->gpuva.gem.obj = &bo->ttm.base;
|
||||
vma->gpuva.gem.offset = bo_offset_or_userptr;
|
||||
drm_gpuva_link(&vma->gpuva, vm_bo);
|
||||
drm_gpuvm_bo_put(vm_bo);
|
||||
} else /* userptr or null */ {
|
||||
if (!is_null) {
|
||||
struct xe_userptr *userptr = &to_userptr_vma(vma)->userptr;
|
||||
u64 size = end - start + 1;
|
||||
int err;
|
||||
|
||||
INIT_LIST_HEAD(&vma->userptr.invalidate_link);
|
||||
INIT_LIST_HEAD(&userptr->invalidate_link);
|
||||
INIT_LIST_HEAD(&userptr->repin_link);
|
||||
vma->gpuva.gem.offset = bo_offset_or_userptr;
|
||||
|
||||
err = mmu_interval_notifier_insert(&vma->userptr.notifier,
|
||||
err = mmu_interval_notifier_insert(&userptr->notifier,
|
||||
current->mm,
|
||||
xe_vma_userptr(vma), size,
|
||||
&vma_userptr_notifier_ops);
|
||||
if (err) {
|
||||
kfree(vma);
|
||||
vma = ERR_PTR(err);
|
||||
return vma;
|
||||
xe_vma_free(vma);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
vma->userptr.notifier_seq = LONG_MAX;
|
||||
userptr->notifier_seq = LONG_MAX;
|
||||
}
|
||||
|
||||
xe_vm_get(vm);
|
||||
@ -880,13 +903,15 @@ static void xe_vma_destroy_late(struct xe_vma *vma)
|
||||
bool read_only = xe_vma_read_only(vma);
|
||||
|
||||
if (xe_vma_is_userptr(vma)) {
|
||||
if (vma->userptr.sg) {
|
||||
struct xe_userptr *userptr = &to_userptr_vma(vma)->userptr;
|
||||
|
||||
if (userptr->sg) {
|
||||
dma_unmap_sgtable(xe->drm.dev,
|
||||
vma->userptr.sg,
|
||||
userptr->sg,
|
||||
read_only ? DMA_TO_DEVICE :
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
sg_free_table(vma->userptr.sg);
|
||||
vma->userptr.sg = NULL;
|
||||
sg_free_table(userptr->sg);
|
||||
userptr->sg = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -894,7 +919,7 @@ static void xe_vma_destroy_late(struct xe_vma *vma)
|
||||
* the notifer until we're sure the GPU is not accessing
|
||||
* them anymore
|
||||
*/
|
||||
mmu_interval_notifier_remove(&vma->userptr.notifier);
|
||||
mmu_interval_notifier_remove(&userptr->notifier);
|
||||
xe_vm_put(vm);
|
||||
} else if (xe_vma_is_null(vma)) {
|
||||
xe_vm_put(vm);
|
||||
@ -902,7 +927,7 @@ static void xe_vma_destroy_late(struct xe_vma *vma)
|
||||
xe_bo_put(xe_vma_bo(vma));
|
||||
}
|
||||
|
||||
kfree(vma);
|
||||
xe_vma_free(vma);
|
||||
}
|
||||
|
||||
static void vma_destroy_work_func(struct work_struct *w)
|
||||
@ -933,7 +958,7 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
|
||||
xe_assert(vm->xe, vma->gpuva.flags & XE_VMA_DESTROYED);
|
||||
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_del(&vma->userptr.invalidate_link);
|
||||
list_del(&to_userptr_vma(vma)->userptr.invalidate_link);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
} else if (!xe_vma_is_null(vma)) {
|
||||
xe_bo_assert_held(xe_vma_bo(vma));
|
||||
@ -2150,7 +2175,7 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
|
||||
drm_exec_fini(&exec);
|
||||
|
||||
if (xe_vma_is_userptr(vma)) {
|
||||
err = xe_vma_userptr_pin_pages(vma);
|
||||
err = xe_vma_userptr_pin_pages(to_userptr_vma(vma));
|
||||
if (err) {
|
||||
prep_vma_destroy(vm, vma, false);
|
||||
xe_vma_destroy_unlocked(vma);
|
||||
@ -2507,7 +2532,7 @@ retry_userptr:
|
||||
|
||||
if (err == -EAGAIN && xe_vma_is_userptr(vma)) {
|
||||
lockdep_assert_held_write(&vm->lock);
|
||||
err = xe_vma_userptr_pin_pages(vma);
|
||||
err = xe_vma_userptr_pin_pages(to_userptr_vma(vma));
|
||||
if (!err)
|
||||
goto retry_userptr;
|
||||
|
||||
@ -2851,7 +2876,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
||||
struct drm_gpuva_ops **ops = NULL;
|
||||
struct xe_vm *vm;
|
||||
struct xe_exec_queue *q = NULL;
|
||||
u32 num_syncs;
|
||||
u32 num_syncs, num_ufence = 0;
|
||||
struct xe_sync_entry *syncs = NULL;
|
||||
struct drm_xe_vm_bind_op *bind_ops;
|
||||
LIST_HEAD(ops_list);
|
||||
@ -2988,6 +3013,14 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
||||
SYNC_PARSE_FLAG_DISALLOW_USER_FENCE : 0));
|
||||
if (err)
|
||||
goto free_syncs;
|
||||
|
||||
if (xe_sync_is_ufence(&syncs[num_syncs]))
|
||||
num_ufence++;
|
||||
}
|
||||
|
||||
if (XE_IOCTL_DBG(xe, num_ufence > 1)) {
|
||||
err = -EINVAL;
|
||||
goto free_syncs;
|
||||
}
|
||||
|
||||
if (!args->num_binds) {
|
||||
@ -3130,8 +3163,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
|
||||
if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
|
||||
if (xe_vma_is_userptr(vma)) {
|
||||
WARN_ON_ONCE(!mmu_interval_check_retry
|
||||
(&vma->userptr.notifier,
|
||||
vma->userptr.notifier_seq));
|
||||
(&to_userptr_vma(vma)->userptr.notifier,
|
||||
to_userptr_vma(vma)->userptr.notifier_seq));
|
||||
WARN_ON_ONCE(!dma_resv_test_signaled(xe_vm_resv(xe_vma_vm(vma)),
|
||||
DMA_RESV_USAGE_BOOKKEEP));
|
||||
|
||||
@ -3192,11 +3225,11 @@ int xe_analyze_vm(struct drm_printer *p, struct xe_vm *vm, int gt_id)
|
||||
if (is_null) {
|
||||
addr = 0;
|
||||
} else if (is_userptr) {
|
||||
struct sg_table *sg = to_userptr_vma(vma)->userptr.sg;
|
||||
struct xe_res_cursor cur;
|
||||
|
||||
if (vma->userptr.sg) {
|
||||
xe_res_first_sg(vma->userptr.sg, 0, XE_PAGE_SIZE,
|
||||
&cur);
|
||||
if (sg) {
|
||||
xe_res_first_sg(sg, 0, XE_PAGE_SIZE, &cur);
|
||||
addr = xe_res_dma(&cur);
|
||||
} else {
|
||||
addr = 0;
|
||||
|
@ -160,6 +160,18 @@ static inline bool xe_vma_is_userptr(struct xe_vma *vma)
|
||||
return xe_vma_has_no_bo(vma) && !xe_vma_is_null(vma);
|
||||
}
|
||||
|
||||
/**
|
||||
* to_userptr_vma() - Return a pointer to an embedding userptr vma
|
||||
* @vma: Pointer to the embedded struct xe_vma
|
||||
*
|
||||
* Return: Pointer to the embedding userptr vma
|
||||
*/
|
||||
static inline struct xe_userptr_vma *to_userptr_vma(struct xe_vma *vma)
|
||||
{
|
||||
xe_assert(xe_vma_vm(vma)->xe, xe_vma_is_userptr(vma));
|
||||
return container_of(vma, struct xe_userptr_vma, vma);
|
||||
}
|
||||
|
||||
u64 xe_vm_pdp4_descriptor(struct xe_vm *vm, struct xe_tile *tile);
|
||||
|
||||
int xe_vm_create_ioctl(struct drm_device *dev, void *data,
|
||||
@ -224,9 +236,9 @@ static inline void xe_vm_reactivate_rebind(struct xe_vm *vm)
|
||||
}
|
||||
}
|
||||
|
||||
int xe_vma_userptr_pin_pages(struct xe_vma *vma);
|
||||
int xe_vma_userptr_pin_pages(struct xe_userptr_vma *uvma);
|
||||
|
||||
int xe_vma_userptr_check_repin(struct xe_vma *vma);
|
||||
int xe_vma_userptr_check_repin(struct xe_userptr_vma *uvma);
|
||||
|
||||
bool xe_vm_validate_should_retry(struct drm_exec *exec, int err, ktime_t *end);
|
||||
|
||||
|
@ -37,6 +37,8 @@ struct xe_vm;
|
||||
struct xe_userptr {
|
||||
/** @invalidate_link: Link for the vm::userptr.invalidated list */
|
||||
struct list_head invalidate_link;
|
||||
/** @userptr: link into VM repin list if userptr. */
|
||||
struct list_head repin_link;
|
||||
/**
|
||||
* @notifier: MMU notifier for user pointer (invalidation call back)
|
||||
*/
|
||||
@ -68,8 +70,6 @@ struct xe_vma {
|
||||
* resv.
|
||||
*/
|
||||
union {
|
||||
/** @userptr: link into VM repin list if userptr. */
|
||||
struct list_head userptr;
|
||||
/** @rebind: link into VM if this VMA needs rebinding. */
|
||||
struct list_head rebind;
|
||||
/** @destroy: link to contested list when VM is being closed. */
|
||||
@ -105,11 +105,15 @@ struct xe_vma {
|
||||
* @pat_index: The pat index to use when encoding the PTEs for this vma.
|
||||
*/
|
||||
u16 pat_index;
|
||||
};
|
||||
|
||||
/**
|
||||
* @userptr: user pointer state, only allocated for VMAs that are
|
||||
* user pointers
|
||||
*/
|
||||
/**
|
||||
* struct xe_userptr_vma - A userptr vma subclass
|
||||
* @vma: The vma.
|
||||
* @userptr: Additional userptr information.
|
||||
*/
|
||||
struct xe_userptr_vma {
|
||||
struct xe_vma vma;
|
||||
struct xe_userptr userptr;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user