radeon_ring.c revision c1341e52802ab401be7addb55408e23307f9074b
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 112771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 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"); 117ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie 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; 135b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* ib are most likely to be allocated in a ring fashion 136b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse * thus rdev->ib_pool.head_id should be the id of the 137b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse * oldest ib 138b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse */ 139b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.head_id = (1 + idx); 140b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); 141b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 142b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return 0; 143b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 14491cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse } 145b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); 146b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 147b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* this should be rare event, ie all ib scheduled none signaled yet. 148b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse */ 149b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 150c1341e52802ab401be7addb55408e23307f9074bJerome Glisse if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) { 151b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false); 152b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (!r) { 153b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse goto retry; 154b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 155b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse /* an error happened */ 156b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse break; 157b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 158b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); 159771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 160ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie mutex_unlock(&rdev->ib_pool.mutex); 161b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&fence); 162b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return r; 163771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 164771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) 166771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 167771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_ib *tmp = *ib; 168771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 169771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *ib = NULL; 170771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (tmp == NULL) { 171771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return; 172771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 173771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 174b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (tmp->fence && !tmp->fence->emitted) { 175b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_free(rdev, &tmp->sa_bo); 176b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&tmp->fence); 177b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse } 178771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 179771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 180771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 181771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) 182771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 183e32eb50dbe43862606a51caa94368ec6bd019434Christian König struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; 184771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r = 0; 185771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 186e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (!ib->length_dw || !ring->ready) { 187771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* TODO: Nothings in the ib we should report. */ 18891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); 189771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return -EINVAL; 190771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 191ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie 1926cdf65855cf884712532fc72770baaef7bdf1b9aDave Airlie /* 64 dwords should be enough for fence too */ 193e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_ring_lock(rdev, ring, 64); 194771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 195ec4f2ac471e25d3e0cea05abb8da34c05a0868f9Paul Bolle DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); 196771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 197771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 1984c87bc268d764cf8846d20ea54b355d1e87507c9Christian König radeon_ring_ib_execute(rdev, ib->fence->ring, ib); 199771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_fence_emit(rdev, ib->fence); 200e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_ring_unlock_commit(rdev, ring); 201771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 202771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 203771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_pool_init(struct radeon_device *rdev) 205771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 206b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse int i, r; 207771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 208b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 209b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (rdev->ib_pool.ready) { 210b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 2119f022ddfb23793b475ff7e57ac08a766dd5d31bdJerome Glisse return 0; 212771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 213b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 214b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager, 215b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse RADEON_IB_POOL_SIZE*64*1024, 216b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse RADEON_GEM_DOMAIN_GTT); 217771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 218b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 219771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 220771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 221771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 222b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 223b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.ibs[i].fence = NULL; 224771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].idx = i; 225771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].length_dw = 0; 226b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list); 227771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 22891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse rdev->ib_pool.head_id = 0; 229771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ready = true; 230771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_INFO("radeon: ib pool ready.\n"); 231b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 232771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (radeon_debugfs_ib_init(rdev)) { 233771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_ERROR("Failed to register debugfs file for IB !\n"); 234771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 235af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König if (radeon_debugfs_ring_init(rdev)) { 236af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König DRM_ERROR("Failed to register debugfs file for rings !\n"); 237af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König } 238b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 239b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return 0; 240771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 241771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 242771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_pool_fini(struct radeon_device *rdev) 243771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 244b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse unsigned i; 2454c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse 246771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 247b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse if (rdev->ib_pool.ready) { 248b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 249b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); 250b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); 2514c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse } 252b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); 253b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse rdev->ib_pool.ready = false; 254771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 255b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 256771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 257771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 258b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_start(struct radeon_device *rdev) 259b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{ 260b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager); 261b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse} 262b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse 263b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisseint radeon_ib_pool_suspend(struct radeon_device *rdev) 264b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse{ 265b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager); 266b15ba51207e54245409d6f46e20dab36f906eed1Jerome Glisse} 267771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 268771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 269771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Ring. 270771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 271e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) 272bf85279958da96cb4b11aac89b34f0424c3c120eChristian König{ 273bf85279958da96cb4b11aac89b34f0424c3c120eChristian König /* r1xx-r5xx only has CP ring */ 274bf85279958da96cb4b11aac89b34f0424c3c120eChristian König if (rdev->family < CHIP_R600) 275bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return RADEON_RING_TYPE_GFX_INDEX; 276bf85279958da96cb4b11aac89b34f0424c3c120eChristian König 277bf85279958da96cb4b11aac89b34f0424c3c120eChristian König if (rdev->family >= CHIP_CAYMAN) { 278e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]) 279bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return CAYMAN_RING_TYPE_CP1_INDEX; 280e32eb50dbe43862606a51caa94368ec6bd019434Christian König else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]) 281bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return CAYMAN_RING_TYPE_CP2_INDEX; 282bf85279958da96cb4b11aac89b34f0424c3c120eChristian König } 283bf85279958da96cb4b11aac89b34f0424c3c120eChristian König return RADEON_RING_TYPE_GFX_INDEX; 284bf85279958da96cb4b11aac89b34f0424c3c120eChristian König} 285bf85279958da96cb4b11aac89b34f0424c3c120eChristian König 286e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) 287771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 28878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher u32 rptr; 28978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher 290724c80e1d630296d1324859e964d80d35007d83cAlex Deucher if (rdev->wb.enabled) 29178c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); 2925596a9db156107b01ceb7db4d50cc091117da627Christian König else 29378c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher rptr = RREG32(ring->rptr_reg); 29478c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; 295771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* This works because ring_size is a power of 2 */ 296e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); 297e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw -= ring->wptr; 298e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw &= ring->ptr_mask; 299e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (!ring->ring_free_dw) { 300e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw = ring->ring_size / 4; 301771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 302771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 303771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3047b1f2485db253aaa0081e1c5213533e166130732Christian König 305e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) 306771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 307771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 308771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 309771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Align requested size with padding so unlock_commit can 310771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * pad safely */ 311e32eb50dbe43862606a51caa94368ec6bd019434Christian König ndw = (ndw + ring->align_mask) & ~ring->align_mask; 312e32eb50dbe43862606a51caa94368ec6bd019434Christian König while (ndw > (ring->ring_free_dw - 1)) { 313e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_ring_free_size(rdev, ring); 314e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ndw < ring->ring_free_dw) { 315771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse break; 316771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 317e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring)); 31891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett if (r) 319771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 320771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 321e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->count_dw = ndw; 322e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr_old = ring->wptr; 323771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 324771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 325771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 326e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) 32791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{ 32891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett int r; 32991700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 330e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_lock(&ring->mutex); 331e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_ring_alloc(rdev, ring, ndw); 33291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett if (r) { 333e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 33491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett return r; 33591700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett } 33691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett return 0; 33791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett} 33891700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 339e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) 340771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 341771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned count_dw_pad; 342771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 343771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 344771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* We pad to match fetch size */ 345e32eb50dbe43862606a51caa94368ec6bd019434Christian König count_dw_pad = (ring->align_mask + 1) - 346e32eb50dbe43862606a51caa94368ec6bd019434Christian König (ring->wptr & ring->align_mask); 347771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < count_dw_pad; i++) { 34878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher radeon_ring_write(ring, ring->nop); 349771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 350771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_MEMORYBARRIER(); 35178c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask); 352e32eb50dbe43862606a51caa94368ec6bd019434Christian König (void)RREG32(ring->wptr_reg); 35391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett} 35491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 355e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) 35691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{ 357e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_ring_commit(rdev, ring); 358e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 359771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 360771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 361e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) 362771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 363e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr = ring->wptr_old; 364e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 365771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 366771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 367e32eb50dbe43862606a51caa94368ec6bd019434Christian Königint radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, 36878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, 36978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) 370771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 371771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 372771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 373e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_size = ring_size; 374e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->rptr_offs = rptr_offs; 375e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->rptr_reg = rptr_reg; 376e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->wptr_reg = wptr_reg; 37778c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->ptr_reg_shift = ptr_reg_shift; 37878c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->ptr_reg_mask = ptr_reg_mask; 37978c5560a08114d7bbbce04cee1628049a22ea104Alex Deucher ring->nop = nop; 380771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Allocate ring buffer */ 381e32eb50dbe43862606a51caa94368ec6bd019434Christian König if (ring->ring_obj == NULL) { 382e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, 3834c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse RADEON_GEM_DOMAIN_GTT, 384e32eb50dbe43862606a51caa94368ec6bd019434Christian König &ring->ring_obj); 385771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 3864c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring create failed\n", r); 387771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 388771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 389e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_reserve(ring->ring_obj, false); 3904c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (unlikely(r != 0)) 3914c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse return r; 392e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT, 393e32eb50dbe43862606a51caa94368ec6bd019434Christian König &ring->gpu_addr); 394771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 395e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_bo_unreserve(ring->ring_obj); 3964c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring pin failed\n", r); 397771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 398771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 399e32eb50dbe43862606a51caa94368ec6bd019434Christian König r = radeon_bo_kmap(ring->ring_obj, 400e32eb50dbe43862606a51caa94368ec6bd019434Christian König (void **)&ring->ring); 401e32eb50dbe43862606a51caa94368ec6bd019434Christian König radeon_bo_unreserve(ring->ring_obj); 402771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 4034c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring map failed\n", r); 404771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 405771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 406771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 407e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ptr_mask = (ring->ring_size / 4) - 1; 408e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_free_dw = ring->ring_size / 4; 409771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 410771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 411771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 412e32eb50dbe43862606a51caa94368ec6bd019434Christian Königvoid radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) 413771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 4144c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse int r; 415ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher struct radeon_bo *ring_obj; 4164c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse 417e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_lock(&ring->mutex); 418e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring_obj = ring->ring_obj; 419e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring = NULL; 420e32eb50dbe43862606a51caa94368ec6bd019434Christian König ring->ring_obj = NULL; 421e32eb50dbe43862606a51caa94368ec6bd019434Christian König mutex_unlock(&ring->mutex); 422ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher 423ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher if (ring_obj) { 424ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher r = radeon_bo_reserve(ring_obj, false); 4254c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (likely(r == 0)) { 426ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_kunmap(ring_obj); 427ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unpin(ring_obj); 428ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unreserve(ring_obj); 4294c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse } 430ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unref(&ring_obj); 431771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 432771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 433771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 434771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 435771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Debugfs info 436771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 437771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 438af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 439af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_debugfs_ring_info(struct seq_file *m, void *data) 440af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{ 441af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct drm_info_node *node = (struct drm_info_node *) m->private; 442af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct drm_device *dev = node->minor->dev; 443af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct radeon_device *rdev = dev->dev_private; 444af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König int ridx = *(int*)node->info_ent->data; 445af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König struct radeon_ring *ring = &rdev->ring[ridx]; 446af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König unsigned count, i, j; 447af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 448af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König radeon_ring_free_size(rdev, ring); 449af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König count = (ring->ring_size / 4) - ring->ring_free_dw; 450af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); 451af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); 452af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); 453af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); 454af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); 455af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "%u dwords in ring\n", count); 456af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König i = ring->rptr; 457af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König for (j = 0; j <= count; j++) { 458af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); 459af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König i = (i + 1) & ring->ptr_mask; 460af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König } 461af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König return 0; 462af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König} 463af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 464af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX; 465af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX; 466af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX; 467af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 468af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königstatic struct drm_info_list radeon_debugfs_ring_info_list[] = { 469af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index}, 470af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index}, 471af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index}, 472af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König}; 473af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 474771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_ib_info(struct seq_file *m, void *data) 475771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 476771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct drm_info_node *node = (struct drm_info_node *) m->private; 477771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_ib *ib = node->info_ent->data; 478771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 479771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 480771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (ib == NULL) { 481771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 482771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 48391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse seq_printf(m, "IB %04u\n", ib->idx); 484771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "IB fence %p\n", ib->fence); 485771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "IB size %05u dwords\n", ib->length_dw); 486771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < ib->length_dw; i++) { 487771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); 488771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 489771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 490771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 491771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 492771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; 493771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; 494771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 495771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 496af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian Königint radeon_debugfs_ring_init(struct radeon_device *rdev) 497af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König{ 498af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#if defined(CONFIG_DEBUG_FS) 499af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 500af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König ARRAY_SIZE(radeon_debugfs_ring_info_list)); 501af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#else 502af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König return 0; 503af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König#endif 504af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König} 505af9720f4907e0a4a4341a015efe08026b3d3eb2eChristian König 506771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev) 507771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 508771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 509771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 510771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 511771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 512771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); 513771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; 514771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info; 515771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].driver_features = 0; 516771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].data = &rdev->ib_pool.ibs[i]; 517771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 518771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list, 519771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse RADEON_IB_POOL_SIZE); 520771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else 521771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 522771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 523771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 524