radeon_fence.c revision 3b7a2b24ea2b703b3af595d0d4ee233ab0b36377
1771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 2771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2009 Jerome Glisse. 3771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * All Rights Reserved. 4771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 5771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a 6771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * copy of this software and associated documentation files (the 7771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * "Software"), to deal in the Software without restriction, including 8771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * without limitation the rights to use, copy, modify, merge, publish, 9771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * distribute, sub license, and/or sell copies of the Software, and to 10771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * permit persons to whom the Software is furnished to do so, subject to 11771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * the following conditions: 12771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 13771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 17771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE. 20771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 21771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * The above copyright notice and this permission notice (including the 22771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * next paragraph) shall be included in all copies or substantial portions 23771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * of the Software. 24771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 25771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 26771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 27771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Authors: 28771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Jerome Glisse <glisse@freedesktop.org> 29771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Dave Airlie 30771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 31771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/seq_file.h> 3260063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 33771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/wait.h> 34771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/list.h> 35771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/kref.h> 365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 37771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "drmP.h" 38771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "drm.h" 39771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon_reg.h" 40771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon.h" 4199ee7fac189893c90145a22b86bbcfdc98f69a9cDave Airlie#include "radeon_trace.h" 42771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 437465280c076d6440e5908c158c83b542dc063a30Alex Deucherstatic void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) 44b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher{ 45b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher if (rdev->wb.enabled) { 4630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq); 4730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse } else { 487465280c076d6440e5908c158c83b542dc063a30Alex Deucher WREG32(rdev->fence_drv[ring].scratch_reg, seq); 4930eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse } 50b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher} 51b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher 527465280c076d6440e5908c158c83b542dc063a30Alex Deucherstatic u32 radeon_fence_read(struct radeon_device *rdev, int ring) 53b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher{ 547465280c076d6440e5908c158c83b542dc063a30Alex Deucher u32 seq = 0; 55b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher 56b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher if (rdev->wb.enabled) { 5730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr); 5830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse } else { 597465280c076d6440e5908c158c83b542dc063a30Alex Deucher seq = RREG32(rdev->fence_drv[ring].scratch_reg); 6030eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse } 61b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher return seq; 62b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher} 63b81157d016a48b8025ccfcb286827679b35f16aaAlex Deucher 64771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) 65771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 663b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* we are protected by the ring emission mutex */ 67bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse if (fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { 68771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 69771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 70bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse fence->seq = ++rdev->fence_drv[fence->ring].seq; 7125a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König radeon_fence_ring_emit(rdev, fence->ring, fence); 7299ee7fac189893c90145a22b86bbcfdc98f69a9cDave Airlie trace_radeon_fence_emit(rdev->ddev, fence->seq); 73771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 74771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 75771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 763b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissevoid radeon_fence_process(struct radeon_device *rdev, int ring) 77771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 78bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse uint64_t seq, last_seq; 79bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse unsigned count_loop = 0; 80771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse bool wake = false; 81771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 82bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse /* Note there is a scenario here for an infinite loop but it's 83bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * very unlikely to happen. For it to happen, the current polling 84bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * process need to be interrupted by another process and another 85bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * process needs to update the last_seq btw the atomic read and 86bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * xchg of the current process. 87bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * 88bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * More over for this to go in infinite loop there need to be 89bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * continuously new fence signaled ie radeon_fence_read needs 90bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * to return a different value each time for both the currently 91bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * polling process and the other process that xchg the last_seq 92bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * btw atomic read and xchg of the current process. And the 93bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * value the other process set as last seq must be higher than 94bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * the seq value we just read. Which means that current process 95bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * need to be interrupted after radeon_fence_read and before 96bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * atomic xchg. 97bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * 98bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * To be even more safe we count the number of time we loop and 99bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * we bail after 10 loop just accepting the fact that we might 100bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * have temporarly set the last_seq not to the true real last 101bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * seq but to an older one. 102bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse */ 103bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); 104bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse do { 105bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse seq = radeon_fence_read(rdev, ring); 106bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse seq |= last_seq & 0xffffffff00000000LL; 107bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse if (seq < last_seq) { 108bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse seq += 0x100000000LL; 109bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse } 11036abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König 1113b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (seq == last_seq) { 1123b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse break; 113bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse } 114bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse /* If we loop over we don't want to return without 115bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * checking if a fence is signaled as it means that the 116bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * seq we just read is different from the previous on. 117bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse */ 118bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse wake = true; 1193b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse last_seq = seq; 120bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse if ((count_loop++) > 10) { 121bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse /* We looped over too many time leave with the 122bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * fact that we might have set an older fence 123bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * seq then the current real last seq as signaled 124bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse * by the hw. 125bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse */ 126bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse break; 127bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse } 128bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq); 129bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse 1303b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (wake) { 1313b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse rdev->fence_drv[ring].last_activity = jiffies; 1323b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse wake_up_all(&rdev->fence_drv[ring].queue); 133771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 134771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 135771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 136771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic void radeon_fence_destroy(struct kref *kref) 137771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 1383b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse struct radeon_fence *fence; 139771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 140771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse fence = container_of(kref, struct radeon_fence, kref); 141bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse fence->seq = RADEON_FENCE_NOTEMITED_SEQ; 14293504fce28b1a387ec01f81b26637d237dca2b36Christian König if (fence->semaphore) 14393504fce28b1a387ec01f81b26637d237dca2b36Christian König radeon_semaphore_free(fence->rdev, fence->semaphore); 144771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse kfree(fence); 145771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 146771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 1477465280c076d6440e5908c158c83b542dc063a30Alex Deucherint radeon_fence_create(struct radeon_device *rdev, 1487465280c076d6440e5908c158c83b542dc063a30Alex Deucher struct radeon_fence **fence, 1497465280c076d6440e5908c158c83b542dc063a30Alex Deucher int ring) 150771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 151771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); 152771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if ((*fence) == NULL) { 153771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return -ENOMEM; 154771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 155771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse kref_init(&((*fence)->kref)); 156771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse (*fence)->rdev = rdev; 157bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse (*fence)->seq = RADEON_FENCE_NOTEMITED_SEQ; 1587465280c076d6440e5908c158c83b542dc063a30Alex Deucher (*fence)->ring = ring; 15993504fce28b1a387ec01f81b26637d237dca2b36Christian König (*fence)->semaphore = NULL; 160771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 161771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 162771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 1633b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissestatic bool radeon_fence_seq_signaled(struct radeon_device *rdev, 1643b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse u64 seq, unsigned ring) 165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 1663b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) { 1673b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return true; 1683b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } 1693b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* poll new last sequence at least once */ 1703b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse radeon_fence_process(rdev, ring); 1713b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) { 172771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return true; 1733b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } 1743b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return false; 1753b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse} 1763655d54af8dd85788c3e5088387469703a0f8f12Darren Jenkins 1773b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissebool radeon_fence_signaled(struct radeon_fence *fence) 1783b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse{ 1793b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (!fence) { 1803b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return true; 181771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 182bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse if (fence->seq == RADEON_FENCE_NOTEMITED_SEQ) { 183851a6bd99edda0094def3b0b81bb1c7c0e886e65Christian König WARN(1, "Querying an unemitted fence : %p !\n", fence); 1843b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return true; 185771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 1863b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (fence->seq == RADEON_FENCE_SIGNALED_SEQ) { 1873b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return true; 188771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 1893b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) { 1903b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse fence->seq = RADEON_FENCE_SIGNALED_SEQ; 1913b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return true; 1923b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } 1933b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return false; 194771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 195771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 1963b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glissestatic int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, 1973b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse unsigned ring, bool intr) 198771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 1993b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse unsigned long timeout, last_activity; 200bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse uint64_t seq; 2013b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse unsigned i; 20236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König bool signaled; 2033b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse int r; 204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 2053b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse while (target_seq > atomic64_read(&rdev->fence_drv[ring].last_seq)) { 2063b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (!rdev->ring[ring].ready) { 2073b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return -EBUSY; 2083b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } 20936abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König 21036abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT; 2113b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (time_after(rdev->fence_drv[ring].last_activity, timeout)) { 21236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König /* the normal case, timeout is somewhere before last_activity */ 2133b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse timeout = rdev->fence_drv[ring].last_activity - timeout; 21436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König } else { 21536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König /* either jiffies wrapped around, or no fence was signaled in the last 500ms 2163b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * anyway we will just wait for the minimum amount and then check for a lockup 2173b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse */ 21836abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König timeout = 1; 21936abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König } 2203b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse seq = atomic64_read(&rdev->fence_drv[ring].last_seq); 221bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse /* Save current last activity valuee, used to check for GPU lockups */ 2223b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse last_activity = rdev->fence_drv[ring].last_activity; 22336abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König 22436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König trace_radeon_fence_wait_begin(rdev->ddev, seq); 2253b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse radeon_irq_kms_sw_irq_get(rdev, ring); 22636abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König if (intr) { 2273b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse r = wait_event_interruptible_timeout(rdev->fence_drv[ring].queue, 2283b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)), 2293b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse timeout); 2303b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } else { 2313b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse r = wait_event_timeout(rdev->fence_drv[ring].queue, 2323b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)), 2333b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse timeout); 23436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König } 2353b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse radeon_irq_kms_sw_irq_put(rdev, ring); 23690aca4d2740255bd130ea71a91530b9920c70abeJerome Glisse if (unlikely(r < 0)) { 2375cc6fbab9da5680e7e5d2507d0f0c2c52ff18031Thomas Hellstrom return r; 23890aca4d2740255bd130ea71a91530b9920c70abeJerome Glisse } 23936abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König trace_radeon_fence_wait_end(rdev->ddev, seq); 24025a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König 24136abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König if (unlikely(!signaled)) { 24236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König /* we were interrupted for some reason and fence 24336abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König * isn't signaled yet, resume waiting */ 24436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König if (r) { 24536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König continue; 24636abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König } 24725a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König 2483b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* check if sequence value has changed since last_activity */ 2493b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (seq != atomic64_read(&rdev->fence_drv[ring].last_seq)) { 2503b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse continue; 2513b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } 252bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse /* test if somebody else has already decided that this is a lockup */ 2533b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (last_activity != rdev->fence_drv[ring].last_activity) { 25436abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König continue; 25536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König } 25636abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König 2573b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) { 25836abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König /* good news we believe it's a lockup */ 259bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n", 2603b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse target_seq, seq); 2613b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse 2623b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* change last activity so nobody else think there is a lockup */ 2633b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse for (i = 0; i < RADEON_NUM_RINGS; ++i) { 2643b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse rdev->fence_drv[i].last_activity = jiffies; 2653b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse } 266bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse 267bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse /* change last activity so nobody else think there is a lockup */ 268bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse for (i = 0; i < RADEON_NUM_RINGS; ++i) { 269bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse rdev->fence_drv[i].last_activity = jiffies; 270bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse } 27136abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König 27236abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König /* mark the ring as not ready any more */ 2733b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse rdev->ring[ring].ready = false; 2746c6f478370eccfbfafbdc6fc55c0def03e58f124Christian König return -EDEADLK; 27536abacaed34bc1f5bcb11ca611dd3a06c5c0ef39Christian König } 276771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 277771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 278771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 279771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 280771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 2813b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseint radeon_fence_wait(struct radeon_fence *fence, bool intr) 282771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 283771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 284771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 2853b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (fence == NULL) { 2863b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse WARN(1, "Querying an invalid fence : %p !\n", fence); 2873b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return -EINVAL; 28825a9e35218c66e7a3a5344cfe94a31a3c10ff810Christian König } 2893b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse 2903b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse r = radeon_fence_wait_seq(fence->rdev, fence->seq, fence->ring, intr); 2913b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (r) { 2923b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return r; 293771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 2943b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse fence->seq = RADEON_FENCE_SIGNALED_SEQ; 2953b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return 0; 296771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 297771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 2983b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseint radeon_fence_wait_next(struct radeon_device *rdev, int ring) 299771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 3003b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse uint64_t seq; 301771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3023b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* We are not protected by ring lock when reading current seq but 3033b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * it's ok as worst case is we return to early while we could have 3043b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * wait. 3053b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse */ 3063b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL; 3073b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (seq >= rdev->fence_drv[ring].seq) { 3083b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* nothing to wait for, last_seq is already the last emited fence */ 309771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 310771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 3113b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return radeon_fence_wait_seq(rdev, seq, ring, false); 3123b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse} 3133b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse 3143b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseint radeon_fence_wait_empty(struct radeon_device *rdev, int ring) 3153b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse{ 3163b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* We are not protected by ring lock when reading current seq 3173b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * but it's ok as wait empty is call from place where no more 3183b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * activity can be scheduled so there won't be concurrent access 3193b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * to seq value. 3203b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse */ 3213b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].seq, ring, false); 322771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 323771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 324771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestruct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) 325771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 326771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse kref_get(&fence->kref); 327771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return fence; 328771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 329771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 330771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_fence_unref(struct radeon_fence **fence) 331771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 332771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_fence *tmp = *fence; 333771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 334771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *fence = NULL; 335771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (tmp) { 336cdb650a4b5eaf1c0aedbfd7dd6afd6d465c3b0a0Paul Bolle kref_put(&tmp->kref, radeon_fence_destroy); 337771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 338771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 339771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3403b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisseunsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring) 341771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 3423b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse uint64_t emitted; 343771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3443b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse radeon_fence_process(rdev, ring); 3453b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* We are not protected by ring lock when reading the last sequence 3463b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse * but it's ok to report slightly wrong fence count here. 3473b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse */ 3483b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse emitted = rdev->fence_drv[ring].seq - atomic64_read(&rdev->fence_drv[ring].last_seq); 3493b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse /* to avoid 32bits warp around */ 3503b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse if (emitted > 0x10000000) { 3513b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse emitted = 0x10000000; 35247492a23a128e953bd5087b1cac909cd8124ca5eChristian König } 3533b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse return (unsigned)emitted; 35447492a23a128e953bd5087b1cac909cd8124ca5eChristian König} 35547492a23a128e953bd5087b1cac909cd8124ca5eChristian König 35630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisseint radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) 357771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 35830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse uint64_t index; 35930eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse int r; 360771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 36130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); 36230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse if (rdev->wb.use_event) { 36330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].scratch_reg = 0; 36430eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse index = R600_WB_EVENT_OFFSET + ring * 4; 36530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse } else { 3667465280c076d6440e5908c158c83b542dc063a30Alex Deucher r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg); 3677465280c076d6440e5908c158c83b542dc063a30Alex Deucher if (r) { 3687465280c076d6440e5908c158c83b542dc063a30Alex Deucher dev_err(rdev->dev, "fence failed to get scratch register\n"); 3697465280c076d6440e5908c158c83b542dc063a30Alex Deucher return r; 3707465280c076d6440e5908c158c83b542dc063a30Alex Deucher } 37130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse index = RADEON_WB_SCRATCH_OFFSET + 37230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].scratch_reg - 37330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->scratch.reg_base; 3747465280c076d6440e5908c158c83b542dc063a30Alex Deucher } 37530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; 37630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; 377bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse radeon_fence_write(rdev, rdev->fence_drv[ring].seq, ring); 37830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].initialized = true; 3793b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n", 38030eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); 38130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse return 0; 38230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse} 38330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse 38430eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glissestatic void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) 38530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse{ 38630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].scratch_reg = -1; 38730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].cpu_addr = NULL; 38830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].gpu_addr = 0; 389bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse rdev->fence_drv[ring].seq = 0; 390bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse atomic64_set(&rdev->fence_drv[ring].last_seq, 0); 3913b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse rdev->fence_drv[ring].last_activity = jiffies; 39230eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse init_waitqueue_head(&rdev->fence_drv[ring].queue); 39330eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse rdev->fence_drv[ring].initialized = false; 39430eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse} 39530eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse 39630eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisseint radeon_fence_driver_init(struct radeon_device *rdev) 39730eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse{ 39830eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse int ring; 39930eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse 40030eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { 40130eb77f4e6ba20f797af4ff79807fae7cb67429eJerome Glisse radeon_fence_driver_init_ring(rdev, ring); 402771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 403771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (radeon_debugfs_fence_init(rdev)) { 4040a0c7596c643239e8d4c3eaaba43b74a96f2411eJerome Glisse dev_err(rdev->dev, "fence debugfs file creation failed\n"); 405771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 406771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 407771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 408771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 409771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_fence_driver_fini(struct radeon_device *rdev) 410771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 4117465280c076d6440e5908c158c83b542dc063a30Alex Deucher int ring; 4127465280c076d6440e5908c158c83b542dc063a30Alex Deucher 4137465280c076d6440e5908c158c83b542dc063a30Alex Deucher for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { 4147465280c076d6440e5908c158c83b542dc063a30Alex Deucher if (!rdev->fence_drv[ring].initialized) 4157465280c076d6440e5908c158c83b542dc063a30Alex Deucher continue; 416adea5c27694d2f6a783abb250b8e6def250928baChristian König radeon_fence_wait_empty(rdev, ring); 4177465280c076d6440e5908c158c83b542dc063a30Alex Deucher wake_up_all(&rdev->fence_drv[ring].queue); 4187465280c076d6440e5908c158c83b542dc063a30Alex Deucher radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); 4197465280c076d6440e5908c158c83b542dc063a30Alex Deucher rdev->fence_drv[ring].initialized = false; 4207465280c076d6440e5908c158c83b542dc063a30Alex Deucher } 421771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 422771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 423771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 424771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 425771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Fence debugfs 426771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 427771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 428771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_fence_info(struct seq_file *m, void *data) 429771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 430771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct drm_info_node *node = (struct drm_info_node *)m->private; 431771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct drm_device *dev = node->minor->dev; 432771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_device *rdev = dev->dev_private; 4337465280c076d6440e5908c158c83b542dc063a30Alex Deucher int i; 4347465280c076d6440e5908c158c83b542dc063a30Alex Deucher 4357465280c076d6440e5908c158c83b542dc063a30Alex Deucher for (i = 0; i < RADEON_NUM_RINGS; ++i) { 4367465280c076d6440e5908c158c83b542dc063a30Alex Deucher if (!rdev->fence_drv[i].initialized) 4377465280c076d6440e5908c158c83b542dc063a30Alex Deucher continue; 4387465280c076d6440e5908c158c83b542dc063a30Alex Deucher 4397465280c076d6440e5908c158c83b542dc063a30Alex Deucher seq_printf(m, "--- ring %d ---\n", i); 440bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse seq_printf(m, "Last signaled fence 0x%016lx\n", 441bb635567291482a87e4cc46e6683419c1f365ddfJerome Glisse atomic64_read(&rdev->fence_drv[i].last_seq)); 4423b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse seq_printf(m, "Last emitted 0x%016llx\n", 4433b7a2b24ea2b703b3af595d0d4ee233ab0b36377Jerome Glisse rdev->fence_drv[i].seq); 444771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 445771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 446771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 447771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 448771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_fence_list[] = { 449771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse {"radeon_fence_info", &radeon_debugfs_fence_info, 0, NULL}, 450771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse}; 451771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 452771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 453771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_fence_init(struct radeon_device *rdev) 454771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 455771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 456771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return radeon_debugfs_add_files(rdev, radeon_debugfs_fence_list, 1); 457771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else 458771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 459771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 460771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 461