diff options
author | 2020-06-08 04:47:57 +0000 | |
---|---|---|
committer | 2020-06-08 04:47:57 +0000 | |
commit | c349dbc7938c71a30e13c1be4acc1976165f4630 (patch) | |
tree | 8798187dfd7a927a15123e8dad31b782b074baa8 /sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c | |
parent | The errcheck() function treats an errno of ERANGE or EDOM as something (diff) | |
download | wireguard-openbsd-c349dbc7938c71a30e13c1be4acc1976165f4630.tar.xz wireguard-openbsd-c349dbc7938c71a30e13c1be4acc1976165f4630.zip |
update drm to linux 5.7
adds kernel support for
amdgpu: vega20, raven2, renoir, navi10, navi14
inteldrm: icelake, tigerlake
Thanks to the OpenBSD Foundation for sponsoring this work, kettenis@ for
helping, patrick@ for helping adapt rockchip drm and many developers for
testing.
Diffstat (limited to 'sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c')
-rw-r--r-- | sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c | 85 |
1 files changed, 61 insertions, 24 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c index 9234e9d8b1e..495138ff339 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c @@ -34,7 +34,10 @@ #include <linux/kref.h> #include <linux/slab.h> #include <linux/firmware.h> -#include <drm/drmP.h> +#include <linux/pm_runtime.h> + +#include <drm/drm_debugfs.h> + #include "amdgpu.h" #include "amdgpu_trace.h" @@ -165,7 +168,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, seq); amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, seq, flags | AMDGPU_FENCE_FLAG_INT); - + pm_runtime_get_noresume(adev->ddev->dev); ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask]; if (unlikely(rcu_dereference_protected(*ptr, 1))) { struct dma_fence *old; @@ -239,10 +242,13 @@ static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) * Checks the current fence value and calculates the last * signalled fence value. Wakes the fence queue if the * sequence number has increased. + * + * Returns true if fence was processed */ -void amdgpu_fence_process(struct amdgpu_ring *ring) +bool amdgpu_fence_process(struct amdgpu_ring *ring) { struct amdgpu_fence_driver *drv = &ring->fence_drv; + struct amdgpu_device *adev = ring->adev; uint32_t seq, last_seq; int r; @@ -252,11 +258,12 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq); - if (seq != ring->fence_drv.sync_seq) + if (del_timer(&ring->fence_drv.fallback_timer) && + seq != ring->fence_drv.sync_seq) amdgpu_fence_schedule_fallback(ring); if (unlikely(seq == last_seq)) - return; + return false; last_seq &= drv->num_fences_mask; seq &= drv->num_fences_mask; @@ -282,7 +289,11 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) BUG(); dma_fence_put(fence); + pm_runtime_mark_last_busy(adev->ddev->dev); + pm_runtime_put_autosuspend(adev->ddev->dev); } while (last_seq != seq); + + return true; } /** @@ -296,7 +307,8 @@ static void amdgpu_fence_fallback(void *arg) { struct amdgpu_ring *ring = arg; - amdgpu_fence_process(ring); + if (amdgpu_fence_process(ring)) + DRM_WARN("Fence fallback timer expired on ring %s\n", ring->name); } /** @@ -414,9 +426,9 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, ring->fence_drv.irq_type = irq_type; ring->fence_drv.initialized = true; - dev_dbg(adev->dev, "fence driver on ring %d use gpu addr 0x%016llx, " - "cpu addr 0x%p\n", ring->idx, - ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr); + DRM_DEV_DEBUG(adev->dev, "fence driver on ring %s use gpu addr " + "0x%016llx, cpu addr 0x%p\n", ring->name, + ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr); return 0; } @@ -433,9 +445,13 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, unsigned num_hw_submission) { + struct amdgpu_device *adev = ring->adev; long timeout; int r; + if (!adev) + return -EINVAL; + /* Check that num_hw_submission is a power of two */ if ((num_hw_submission & (num_hw_submission - 1)) != 0) return -EINVAL; @@ -462,12 +478,20 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, /* No need to setup the GPU scheduler for KIQ ring */ if (ring->funcs->type != AMDGPU_RING_TYPE_KIQ) { - /* for non-sriov case, no timeout enforce on compute ring */ - if ((ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) - && !amdgpu_sriov_vf(ring->adev)) - timeout = MAX_SCHEDULE_TIMEOUT; - else - timeout = msecs_to_jiffies(amdgpu_lockup_timeout); + switch (ring->funcs->type) { + case AMDGPU_RING_TYPE_GFX: + timeout = adev->gfx_timeout; + break; + case AMDGPU_RING_TYPE_COMPUTE: + timeout = adev->compute_timeout; + break; + case AMDGPU_RING_TYPE_SDMA: + timeout = adev->sdma_timeout; + break; + default: + timeout = adev->video_timeout; + break; + } r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, num_hw_submission, amdgpu_job_hang_limit, @@ -496,9 +520,6 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, */ int amdgpu_fence_driver_init(struct amdgpu_device *adev) { - if (amdgpu_debugfs_fence_init(adev)) - dev_err(adev->dev, "fence debugfs file creation failed\n"); - return 0; } @@ -699,22 +720,30 @@ static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data) amdgpu_fence_process(ring); seq_printf(m, "--- ring %d (%s) ---\n", i, ring->name); - seq_printf(m, "Last signaled fence 0x%08x\n", + seq_printf(m, "Last signaled fence 0x%08x\n", atomic_read(&ring->fence_drv.last_seq)); - seq_printf(m, "Last emitted 0x%08x\n", + seq_printf(m, "Last emitted 0x%08x\n", ring->fence_drv.sync_seq); + if (ring->funcs->type == AMDGPU_RING_TYPE_GFX || + ring->funcs->type == AMDGPU_RING_TYPE_SDMA) { + seq_printf(m, "Last signaled trailing fence 0x%08x\n", + le32_to_cpu(*ring->trail_fence_cpu_addr)); + seq_printf(m, "Last emitted 0x%08x\n", + ring->trail_seq); + } + if (ring->funcs->type != AMDGPU_RING_TYPE_GFX) continue; /* set in CP_VMID_PREEMPT and preemption occurred */ - seq_printf(m, "Last preempted 0x%08x\n", + seq_printf(m, "Last preempted 0x%08x\n", le32_to_cpu(*(ring->fence_drv.cpu_addr + 2))); /* set in CP_VMID_RESET and reset occurred */ - seq_printf(m, "Last reset 0x%08x\n", + seq_printf(m, "Last reset 0x%08x\n", le32_to_cpu(*(ring->fence_drv.cpu_addr + 4))); /* Both preemption and reset occurred */ - seq_printf(m, "Last both 0x%08x\n", + seq_printf(m, "Last both 0x%08x\n", le32_to_cpu(*(ring->fence_drv.cpu_addr + 6))); } return 0; @@ -730,9 +759,17 @@ static int amdgpu_debugfs_gpu_recover(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = dev->dev_private; + int r; + + r = pm_runtime_get_sync(dev->dev); + if (r < 0) + return 0; seq_printf(m, "gpu recover\n"); - amdgpu_device_gpu_recover(adev, NULL, true); + amdgpu_device_gpu_recover(adev, NULL); + + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); return 0; } |