33 #include <linux/wait.h>
34 #include <linux/list.h>
36 #include <linux/slab.h>
110 if ((*fence) ==
NULL) {
113 kref_init(&((*fence)->kref));
114 (*fence)->rdev =
rdev;
115 (*fence)->seq = ++rdev->
fence_drv[ring].sync_seq[ring];
116 (*fence)->ring = ring;
118 trace_radeon_fence_emit(rdev->
ddev, (*fence)->seq);
134 unsigned count_loop = 0;
160 last_emitted = rdev->
fence_drv[ring].sync_seq[ring];
161 seq = radeon_fence_read(rdev, ring);
162 seq |= last_seq & 0xffffffff00000000
LL;
163 if (seq < last_seq) {
165 seq |= last_emitted & 0xffffffff00000000
LL;
168 if (seq <= last_seq || seq > last_emitted) {
177 if ((count_loop++) > 10) {
200 static void radeon_fence_destroy(
struct kref *
kref)
222 static bool radeon_fence_seq_signaled(
struct radeon_device *rdev,
223 u64 seq,
unsigned ring)
252 if (radeon_fence_seq_signaled(fence->
rdev, fence->
seq, fence->
ring)) {
277 static int radeon_fence_wait_seq(
struct radeon_device *rdev,
u64 target_seq,
278 unsigned ring,
bool intr,
bool lock_ring)
280 unsigned long timeout, last_activity;
287 if (!rdev->
ring[ring].ready) {
305 trace_radeon_fence_wait_begin(rdev->
ddev, seq);
309 (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)),
313 (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)),
320 trace_radeon_fence_wait_end(rdev->
ddev, seq);
339 if (last_activity != rdev->
fence_drv[ring].last_activity) {
348 dev_warn(rdev->
dev,
"GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n",
388 WARN(1,
"Querying an invalid fence : %p !\n", fence);
392 r = radeon_fence_wait_seq(fence->
rdev, fence->
seq,
393 fence->
ring, intr,
true);
401 static bool radeon_fence_any_seq_signaled(
struct radeon_device *rdev,
u64 *seq)
406 if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i)) {
427 static int radeon_fence_wait_any_seq(
struct radeon_device *rdev,
428 u64 *target_seq,
bool intr)
430 unsigned long timeout, last_activity,
tmp;
436 if (!target_seq[i]) {
442 last_activity = rdev->
fence_drv[
i].last_activity;
454 if (ring == RADEON_NUM_RINGS) {
458 while (!radeon_fence_any_seq_signaled(rdev, target_seq)) {
462 timeout = last_activity - timeout;
470 trace_radeon_fence_wait_begin(rdev->
ddev, target_seq[ring]);
478 (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)),
482 (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)),
493 trace_radeon_fence_wait_end(rdev->
ddev, target_seq[ring]);
509 if (last_activity != tmp) {
517 dev_warn(rdev->
dev,
"GPU lockup (waiting for 0x%016llx)\n",
569 seq[
i] = fences[
i]->
seq;
572 r = radeon_fence_wait_any_seq(rdev, seq, intr);
594 if (seq >= rdev->
fence_drv[ring].sync_seq[ring]) {
599 return radeon_fence_wait_seq(rdev, seq, ring,
false,
false);
618 r = radeon_fence_wait_seq(rdev, seq, ring,
false,
false);
627 dev_err(rdev->
dev,
"error waiting for ring to become"
644 kref_get(&fence->
kref);
661 kref_put(&tmp->
kref, radeon_fence_destroy);
686 if (emitted > 0x10000000) {
687 emitted = 0x10000000;
689 return (
unsigned)emitted;
711 if (fence->
ring == dst_ring) {
716 fdrv = &fence->
rdev->fence_drv[dst_ring];
742 if (fence->
ring == dst_ring) {
747 src = &fence->
rdev->fence_drv[fence->
ring];
748 dst = &fence->
rdev->fence_drv[dst_ring];
775 if (rdev->
wb.use_event) {
781 dev_err(rdev->
dev,
"fence failed to get scratch register\n");
788 rdev->
fence_drv[ring].cpu_addr = &rdev->
wb.wb[index/4];
791 rdev->
fence_drv[ring].initialized =
true;
792 dev_info(rdev->
dev,
"fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n",
807 static void radeon_fence_driver_init_ring(
struct radeon_device *rdev,
int ring)
818 rdev->
fence_drv[ring].initialized =
false;
839 radeon_fence_driver_init_ring(rdev, ring);
842 dev_err(rdev->
dev,
"fence debugfs file creation failed\n");
866 rdev->
fence_drv[ring].initialized =
false;
875 #if defined(CONFIG_DEBUG_FS)
876 static int radeon_debugfs_fence_info(
struct seq_file *
m,
void *
data)
878 struct drm_info_node *
node = (
struct drm_info_node *)m->
private;
888 seq_printf(m,
"Last signaled fence 0x%016llx\n",
895 seq_printf(m,
"Last sync to ring %d 0x%016llx\n",
902 static struct drm_info_list radeon_debugfs_fence_list[] = {
903 {
"radeon_fence_info", &radeon_debugfs_fence_info, 0,
NULL},
909 #if defined(CONFIG_DEBUG_FS)