1771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 2771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2008 Advanced Micro Devices, Inc. 3771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2008 Red Hat Inc. 4771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Copyright 2009 Jerome Glisse. 5771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 6771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a 7771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * copy of this software and associated documentation files (the "Software"), 8771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * to deal in the Software without restriction, including without limitation 9771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * and/or sell copies of the Software, and to permit persons to whom the 11771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Software is furnished to do so, subject to the following conditions: 12771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 13771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * The above copyright notice and this permission notice shall be included in 14771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * all copies or substantial portions of the Software. 15771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 16771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * OTHER DEALINGS IN THE SOFTWARE. 23771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * 24771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Authors: Dave Airlie 25771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Alex Deucher 26771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Jerome Glisse 27771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 28771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include <linux/seq_file.h> 295a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 30771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "drmP.h" 31771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon_drm.h" 32771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon_reg.h" 33771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "radeon.h" 34771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#include "atom.h" 35771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 36771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev); 37af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königint radeon_debugfs_ring_init(struct radeon_device *rdev); 38771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 39ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleenu32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) 40ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen{ 41ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; 42ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen u32 pg_idx, pg_offset; 43ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen u32 idx_value = 0; 44ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen int new_page; 45ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 46ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen pg_idx = (idx * 4) / PAGE_SIZE; 47ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen pg_offset = (idx * 4) % PAGE_SIZE; 48ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 49ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen if (ibc->kpage_idx[0] == pg_idx) 50ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return ibc->kpage[0][pg_offset/4]; 51ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen if (ibc->kpage_idx[1] == pg_idx) 52ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return ibc->kpage[1][pg_offset/4]; 53ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 54ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen new_page = radeon_cs_update_pages(p, pg_idx); 55ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen if (new_page < 0) { 56ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen p->parser_error = new_page; 57ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return 0; 58ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen } 59ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 60ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen idx_value = ibc->kpage[new_page][pg_offset/4]; 61ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return idx_value; 62ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen} 63ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 64e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_write(struct radeon_ring *ring, uint32_t v) 65ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen{ 66ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen#if DRM_DEBUG_CODE 67e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ring->count_dw <= 0) { 68ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen DRM_ERROR("radeon: writting more dword to ring than expected !\n"); 69ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen } 70ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen#endif 71e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring[ring->wptr++] = v; 72e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr &= ring->ptr_mask; 73e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->count_dw--; 74e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw--; 75ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen} 76ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 77b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse/* 78b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse * IB. 79b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse */ 80c1341e52802ab401be7addb55408e23307f9074bJerome Glissebool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib) 819f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse{ 82b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse bool done = false; 83b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 84b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* only free ib which have been emited */ 85b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (ib->fence && ib->fence->emitted) { 86b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (radeon_fence_signaled(ib->fence)) { 87b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&ib->fence); 88b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_free(rdev, &ib->sa_bo); 89b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse done = true; 90b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 919f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse } 92b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return done; 939f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse} 949f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 9569e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisseint radeon_ib_get(struct radeon_device *rdev, int ring, 9669e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse struct radeon_ib **ib, unsigned size) 97771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 98771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_fence *fence; 99b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse unsigned cretry = 0; 100b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse int r = 0, i, idx; 101771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 102771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *ib = NULL; 10369e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse /* align size on 256 bytes */ 10469e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse size = ALIGN(size, 256); 105b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 1067b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_fence_create(rdev, &fence, ring); 107771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 10891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse dev_err(rdev->dev, "failed to create fence for new IB\n"); 109771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 110771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 111b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 1129fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_lock(&rdev->ib_pool.mutex); 113b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse idx = rdev->ib_pool.head_id; 114b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseretry: 115b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (cretry > 5) { 116b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); 1179fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 11891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse radeon_fence_unref(&fence); 119b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return -ENOMEM; 120771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 121b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse cretry++; 122b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 123b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_ib_try_free(rdev, &rdev->ib_pool.ibs[idx]); 124b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (rdev->ib_pool.ibs[idx].fence == NULL) { 125b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager, 126b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse &rdev->ib_pool.ibs[idx].sa_bo, 12769e130a6a42270f94e6ee0bce34c3480a6b9da61Jerome Glisse size, 256); 128b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (!r) { 129b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse *ib = &rdev->ib_pool.ibs[idx]; 130b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse (*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr; 131b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse (*ib)->ptr += ((*ib)->sa_bo.offset >> 2); 132b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse (*ib)->gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; 133b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse (*ib)->gpu_addr += (*ib)->sa_bo.offset; 134b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse (*ib)->fence = fence; 135721604a15b934f0a8d1909acb8017f029128be2fJerome Glisse (*ib)->vm_id = 0; 136dfcf5f36529d69eb35f4fdedfa6f244c5249698cAlex Deucher (*ib)->is_const_ib = false; 137b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* ib are most likely to be allocated in a ring fashion 138b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse * thus rdev->ib_pool.head_id should be the id of the 139b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse * oldest ib 140b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse */ 141b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.head_id = (1 + idx); 142b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); 1439fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 144b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return 0; 145b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 14691cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse } 147b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); 148b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 149b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* this should be rare event, ie all ib scheduled none signaled yet. 150b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse */ 151b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 152c1341e52802ab401be7addb55408e23307f9074bJerome Glisse if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) { 153b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false); 154b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (!r) { 155b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse goto retry; 156b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 157b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* an error happened */ 158b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse break; 159b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 160b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); 161771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 1629fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 163b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&fence); 164b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return r; 165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 166771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 167771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) 168771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 169771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_ib *tmp = *ib; 170771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 171771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *ib = NULL; 172771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (tmp == NULL) { 173771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return; 174771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 1759fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_lock(&rdev->ib_pool.mutex); 176b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (tmp->fence && !tmp->fence->emitted) { 177b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_free(rdev, &tmp->sa_bo); 178b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&tmp->fence); 179b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 1809fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 181771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 182771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 183771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) 184771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 185e32eb50dbe43862606a51caa94368ec6bd019434Christian König struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; 186771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r = 0; 187771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 188e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (!ib->length_dw || !ring->ready) { 189771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* TODO: Nothings in the ib we should report. */ 19091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); 191771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return -EINVAL; 192771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 193ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie 1946cdf65855cf884712532fc72770baaef7bdf1b9aDave Airlie /* 64 dwords should be enough for fence too */ 195e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_ring_lock(rdev, ring, 64); 196771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 197ec4f2ac471e25d3e0cea05abb8da34c05a0868f9Paul Bolle DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); 198771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 199771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 2004c87bc268d764cf8846d20ea54b355d1e87507c9Christian König radeon_ring_ib_execute(rdev, ib->fence->ring, ib); 201771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_fence_emit(rdev, ib->fence); 202e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_ring_unlock_commit(rdev, ring); 203771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 205771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 206771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_pool_init(struct radeon_device *rdev) 207771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 208d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse struct radeon_sa_manager tmp; 209b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse int i, r; 210771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 211d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse r = radeon_sa_bo_manager_init(rdev, &tmp, 212b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse RADEON_IB_POOL_SIZE*64*1024, 213b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse RADEON_GEM_DOMAIN_GTT); 214771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 215771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 216771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 217771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 2189fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_lock(&rdev->ib_pool.mutex); 219d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse if (rdev->ib_pool.ready) { 2209fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 221d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse radeon_sa_bo_manager_fini(rdev, &tmp); 222d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse return 0; 223d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse } 224d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse 225d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse rdev->ib_pool.sa_manager = tmp; 226d54fbd49efe5c75bc7cf963bf065aef3fd22417aJerome Glisse INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo); 227b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 228b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.ibs[i].fence = NULL; 229771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].idx = i; 230771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].length_dw = 0; 231b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list); 232771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 23391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse rdev->ib_pool.head_id = 0; 234771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ready = true; 235771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_INFO("radeon: ib pool ready.\n"); 236b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 237771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (radeon_debugfs_ib_init(rdev)) { 238771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_ERROR("Failed to register debugfs file for IB !\n"); 239771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 240af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König if (radeon_debugfs_ring_init(rdev)) { 241af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König DRM_ERROR("Failed to register debugfs file for rings !\n"); 242af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König } 2439fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 244b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return 0; 245771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 246771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 247771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_pool_fini(struct radeon_device *rdev) 248771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 249b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse unsigned i; 2504c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse 2519fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_lock(&rdev->ib_pool.mutex); 252b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (rdev->ib_pool.ready) { 253b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 254b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); 255b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); 2564c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse } 257b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); 258b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.ready = false; 259771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 2609fc04b503df9a34ec1a691225445c5b7dfd022e7Jerome Glisse radeon_mutex_unlock(&rdev->ib_pool.mutex); 261771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 262771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 263b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_start(struct radeon_device *rdev) 264b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{ 265b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager); 266b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse} 267b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 268b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_suspend(struct radeon_device *rdev) 269b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{ 270b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager); 271b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse} 272771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 273771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 274771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Ring. 275771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 276e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) 277bf85279958da96cb4b11aac89b34f0424c3c120eChristian König{ 278bf85279958da96cb4b11aac89b34f0424c3c120eChristian König /* r1xx-r5xx only has CP ring */ 279bf85279958da96cb4b11aac89b34f0424c3c120eChristian König if (rdev->family < CHIP_R600) 280bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return RADEON_RING_TYPE_GFX_INDEX; 281bf85279958da96cb4b11aac89b34f0424c3c120eChristian König 282bf85279958da96cb4b11aac89b34f0424c3c120eChristian König if (rdev->family >= CHIP_CAYMAN) { 283e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]) 284bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return CAYMAN_RING_TYPE_CP1_INDEX; 285e32eb50dbe43862606a51caa94368ec6bd019434Christian König else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]) 286bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return CAYMAN_RING_TYPE_CP2_INDEX; 287bf85279958da96cb4b11aac89b34f0424c3c120eChristian König } 288bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return RADEON_RING_TYPE_GFX_INDEX; 289bf85279958da96cb4b11aac89b34f0424c3c120eChristian König} 290bf85279958da96cb4b11aac89b34f0424c3c120eChristian König 291e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) 292771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 29378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher u32 rptr; 29478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher 295724c80e1d630296d1324859e964d80d35007d83cAlex Deucher if (rdev->wb.enabled) 29678c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); 2975596a9db156107b01ceb7db4d50cc091117da627Christian König else 29878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher rptr = RREG32(ring->rptr_reg); 29978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; 300771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* This works because ring_size is a power of 2 */ 301e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); 302e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw -= ring->wptr; 303e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw &= ring->ptr_mask; 304e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (!ring->ring_free_dw) { 305e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw = ring->ring_size / 4; 306771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 307771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 308771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3097b1f2485db253aaa0081e1c5213533e166130732Christian König 310e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) 311771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 312771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 313771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 314771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Align requested size with padding so unlock_commit can 315771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * pad safely */ 316e32eb50dbe43862606a51caa94368ec6bd019434Christian König ndw = (ndw + ring->align_mask) & ~ring->align_mask; 317e32eb50dbe43862606a51caa94368ec6bd019434Christian König while (ndw > (ring->ring_free_dw - 1)) { 318e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_ring_free_size(rdev, ring); 319e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ndw < ring->ring_free_dw) { 320771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse break; 321771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 322e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring)); 32391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett if (r) 324771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 325771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 326e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->count_dw = ndw; 327e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr_old = ring->wptr; 328771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 329771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 330771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 331e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) 33291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{ 33391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett int r; 33491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 335e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_lock(&ring->mutex); 336e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_ring_alloc(rdev, ring, ndw); 33791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett if (r) { 338e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 33991700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett return r; 34091700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett } 34191700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett return 0; 34291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett} 34391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 344e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) 345771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 346771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned count_dw_pad; 347771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 348771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 349771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* We pad to match fetch size */ 350e32eb50dbe43862606a51caa94368ec6bd019434Christian König count_dw_pad = (ring->align_mask + 1) - 351e32eb50dbe43862606a51caa94368ec6bd019434Christian König (ring->wptr & ring->align_mask); 352771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < count_dw_pad; i++) { 35378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher radeon_ring_write(ring, ring->nop); 354771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 355771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_MEMORYBARRIER(); 35678c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask); 357e32eb50dbe43862606a51caa94368ec6bd019434Christian König (void)RREG32(ring->wptr_reg); 35891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett} 35991700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 360e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) 36191700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{ 362e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_ring_commit(rdev, ring); 363e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 364771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 365771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 366e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) 367771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 368e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr = ring->wptr_old; 369e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 370771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 371771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 372e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, 37378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, 37478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) 375771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 376771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 377771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 378e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_size = ring_size; 379e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->rptr_offs = rptr_offs; 380e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->rptr_reg = rptr_reg; 381e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr_reg = wptr_reg; 38278c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->ptr_reg_shift = ptr_reg_shift; 38378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->ptr_reg_mask = ptr_reg_mask; 38478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->nop = nop; 385771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Allocate ring buffer */ 386e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ring->ring_obj == NULL) { 387e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, 3884c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse RADEON_GEM_DOMAIN_GTT, 389e32eb50dbe43862606a51caa94368ec6bd019434Christian König &ring->ring_obj); 390771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 3914c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring create failed\n", r); 392771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 393771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 394e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_reserve(ring->ring_obj, false); 3954c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (unlikely(r != 0)) 3964c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse return r; 397e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT, 398e32eb50dbe43862606a51caa94368ec6bd019434Christian König &ring->gpu_addr); 399771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 400e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_bo_unreserve(ring->ring_obj); 4014c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring pin failed\n", r); 402771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 403771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 404e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_kmap(ring->ring_obj, 405e32eb50dbe43862606a51caa94368ec6bd019434Christian König (void **)&ring->ring); 406e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_bo_unreserve(ring->ring_obj); 407771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 4084c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring map failed\n", r); 409771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 410771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 411771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 412e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ptr_mask = (ring->ring_size / 4) - 1; 413e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw = ring->ring_size / 4; 414771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 415771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 416771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 417e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) 418771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 4194c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse int r; 420ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher struct radeon_bo *ring_obj; 4214c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse 422e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_lock(&ring->mutex); 423e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring_obj = ring->ring_obj; 424e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring = NULL; 425e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_obj = NULL; 426e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 427ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher 428ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher if (ring_obj) { 429ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher r = radeon_bo_reserve(ring_obj, false); 4304c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (likely(r == 0)) { 431ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_kunmap(ring_obj); 432ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unpin(ring_obj); 433ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unreserve(ring_obj); 4344c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse } 435ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unref(&ring_obj); 436771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 437771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 438771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 439771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 440771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Debugfs info 441771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 442771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 443af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 444af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_debugfs_ring_info(struct seq_file *m, void *data) 445af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{ 446af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct drm_info_node *node = (struct drm_info_node *) m->private; 447af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct drm_device *dev = node->minor->dev; 448af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct radeon_device *rdev = dev->dev_private; 449af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König int ridx = *(int*)node->info_ent->data; 450af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct radeon_ring *ring = &rdev->ring[ridx]; 451af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König unsigned count, i, j; 452af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 453af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König radeon_ring_free_size(rdev, ring); 454af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König count = (ring->ring_size / 4) - ring->ring_free_dw; 455af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); 456af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); 457af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); 458af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); 459af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); 460af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "%u dwords in ring\n", count); 461af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König i = ring->rptr; 462af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König for (j = 0; j <= count; j++) { 463af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); 464af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König i = (i + 1) & ring->ptr_mask; 465af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König } 466af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König return 0; 467af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König} 468af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 469af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX; 470af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX; 471af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX; 472af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 473af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic struct drm_info_list radeon_debugfs_ring_info_list[] = { 474af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index}, 475af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index}, 476af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index}, 477af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König}; 478af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 479771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_ib_info(struct seq_file *m, void *data) 480771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 481771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct drm_info_node *node = (struct drm_info_node *) m->private; 482293f9fd53aa1529500ba16d89850100a058b11c1Christian König struct drm_device *dev = node->minor->dev; 483293f9fd53aa1529500ba16d89850100a058b11c1Christian König struct radeon_device *rdev = dev->dev_private; 484293f9fd53aa1529500ba16d89850100a058b11c1Christian König struct radeon_ib *ib = &rdev->ib_pool.ibs[*((unsigned*)node->info_ent->data)]; 485771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 486771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 487771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (ib == NULL) { 488771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 489771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 49091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse seq_printf(m, "IB %04u\n", ib->idx); 491771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "IB fence %p\n", ib->fence); 492771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "IB size %05u dwords\n", ib->length_dw); 493771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < ib->length_dw; i++) { 494771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); 495771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 496771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 497771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 498771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 499771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; 500771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; 501293f9fd53aa1529500ba16d89850100a058b11c1Christian Königstatic unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE]; 502771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 503771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 504af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königint radeon_debugfs_ring_init(struct radeon_device *rdev) 505af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{ 506af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#if defined(CONFIG_DEBUG_FS) 507f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer if (rdev->family >= CHIP_CAYMAN) 508f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 509f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer ARRAY_SIZE(radeon_debugfs_ring_info_list)); 510f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer else 511f0d14daa6906070ca044b86f483fdde7d81f5294Michel Dänzer return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1); 512af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#else 513af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König return 0; 514af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#endif 515af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König} 516af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 517771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev) 518771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 519771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 520771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 521771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 522771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 523771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); 524293f9fd53aa1529500ba16d89850100a058b11c1Christian König radeon_debugfs_ib_idx[i] = i; 525771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; 526771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info; 527771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].driver_features = 0; 528293f9fd53aa1529500ba16d89850100a058b11c1Christian König radeon_debugfs_ib_list[i].data = &radeon_debugfs_ib_idx[i]; 529771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 530771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list, 531771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse RADEON_IB_POOL_SIZE); 532771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else 533771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 534771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 535771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 536