radeon_ring.c revision 5596a9db156107b01ceb7db4d50cc091117da627
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); 37771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 38ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleenu32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) 39ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen{ 40ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; 41ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen u32 pg_idx, pg_offset; 42ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen u32 idx_value = 0; 43ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen int new_page; 44ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 45ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen pg_idx = (idx * 4) / PAGE_SIZE; 46ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen pg_offset = (idx * 4) % PAGE_SIZE; 47ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 48ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen if (ibc->kpage_idx[0] == pg_idx) 49ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return ibc->kpage[0][pg_offset/4]; 50ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen if (ibc->kpage_idx[1] == pg_idx) 51ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return ibc->kpage[1][pg_offset/4]; 52ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 53ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen new_page = radeon_cs_update_pages(p, pg_idx); 54ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen if (new_page < 0) { 55ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen p->parser_error = new_page; 56ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return 0; 57ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen } 58ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 59ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen idx_value = ibc->kpage[new_page][pg_offset/4]; 60ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen return idx_value; 61ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen} 62ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 637b1f2485db253aaa0081e1c5213533e166130732Christian Königvoid radeon_ring_write(struct radeon_cp *cp, uint32_t v) 64ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen{ 65ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen#if DRM_DEBUG_CODE 667b1f2485db253aaa0081e1c5213533e166130732Christian König if (cp->count_dw <= 0) { 67ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen DRM_ERROR("radeon: writting more dword to ring than expected !\n"); 68ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen } 69ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen#endif 707b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring[cp->wptr++] = v; 717b1f2485db253aaa0081e1c5213533e166130732Christian König cp->wptr &= cp->ptr_mask; 727b1f2485db253aaa0081e1c5213533e166130732Christian König cp->count_dw--; 737b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_free_dw--; 74ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen} 75ce580fab739c815e25d13bae62f96ba7251f6e2eAndi Kleen 769f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glissevoid radeon_ib_bogus_cleanup(struct radeon_device *rdev) 779f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse{ 789f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse struct radeon_ib *ib, *n; 799f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 809f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse list_for_each_entry_safe(ib, n, &rdev->ib_pool.bogus_ib, list) { 819f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse list_del(&ib->list); 829f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse vfree(ib->ptr); 839f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse kfree(ib); 849f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse } 859f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse} 869f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 879f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glissevoid radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib) 889f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse{ 899f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse struct radeon_ib *bib; 909f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 919f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse bib = kmalloc(sizeof(*bib), GFP_KERNEL); 929f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse if (bib == NULL) 939f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse return; 949f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse bib->ptr = vmalloc(ib->length_dw * 4); 959f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse if (bib->ptr == NULL) { 969f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse kfree(bib); 979f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse return; 989f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse } 999f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse memcpy(bib->ptr, ib->ptr, ib->length_dw * 4); 1009f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse bib->length_dw = ib->length_dw; 1019f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 1029f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse list_add_tail(&bib->list, &rdev->ib_pool.bogus_ib); 1039f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 1049f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse} 1059f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 106771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 107771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * IB. 108771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 1097b1f2485db253aaa0081e1c5213533e166130732Christian Königint radeon_ib_get(struct radeon_device *rdev, int ring, struct radeon_ib **ib) 110771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 111771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_fence *fence; 112771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_ib *nib; 11391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse int r = 0, i, c; 114771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 115771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *ib = NULL; 1167b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_fence_create(rdev, &fence, ring); 117771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 11891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse dev_err(rdev->dev, "failed to create fence for new IB\n"); 119771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 120771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 121771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 12291cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) { 12391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse i &= (RADEON_IB_POOL_SIZE - 1); 12491cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse if (rdev->ib_pool.ibs[i].free) { 12591cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse nib = &rdev->ib_pool.ibs[i]; 12691cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse break; 12791cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse } 128771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 12991cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse if (nib == NULL) { 13091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse /* This should never happen, it means we allocated all 13191cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse * IB and haven't scheduled one yet, return EBUSY to 13291cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse * userspace hoping that on ioctl recall we get better 13391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse * luck 13491cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse */ 13591cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse dev_err(rdev->dev, "no free indirect buffer !\n"); 136ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie mutex_unlock(&rdev->ib_pool.mutex); 13791cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse radeon_fence_unref(&fence); 13891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse return -EBUSY; 139771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 14091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1); 14191cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse nib->free = false; 14291cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse if (nib->fence) { 143ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie mutex_unlock(&rdev->ib_pool.mutex); 14491cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse r = radeon_fence_wait(nib->fence, false); 14591cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse if (r) { 14691cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n", 14791cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw); 14891cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse mutex_lock(&rdev->ib_pool.mutex); 14991cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse nib->free = true; 15091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 15191cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse radeon_fence_unref(&fence); 15291cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse return r; 15391cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse } 15491cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse mutex_lock(&rdev->ib_pool.mutex); 155771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 156771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_fence_unref(&nib->fence); 15791cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse nib->fence = fence; 158771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse nib->length_dw = 0; 159ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie mutex_unlock(&rdev->ib_pool.mutex); 160771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *ib = nib; 16191cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse return 0; 162771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 163771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 164771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) 165771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 166771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_ib *tmp = *ib; 167771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 168771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse *ib = NULL; 169771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (tmp == NULL) { 170771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return; 171771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 172851a6bd99edda0094def3b0b81bb1c7c0e886e65Christian König if (!tmp->fence->emitted) 1737d404c7b5f4c004712bc15ed6e6edd6779842126Jerome Glisse radeon_fence_unref(&tmp->fence); 174771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 17591cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse tmp->free = true; 176771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 177771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 178771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 179771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) 180771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 1817b1f2485db253aaa0081e1c5213533e166130732Christian König struct radeon_cp *cp = &rdev->cp; 182771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r = 0; 183771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 1847b1f2485db253aaa0081e1c5213533e166130732Christian König if (!ib->length_dw || !cp->ready) { 185771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* TODO: Nothings in the ib we should report. */ 18691cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); 187771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return -EINVAL; 188771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 189ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie 1906cdf65855cf884712532fc72770baaef7bdf1b9aDave Airlie /* 64 dwords should be enough for fence too */ 1917b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_ring_lock(rdev, cp, 64); 192771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 193ec4f2ac471e25d3e0cea05abb8da34c05a0868f9Paul Bolle DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); 194771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 195771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 1963ce0a23d2d253185df24e22e3d5f89800bb3dd1cJerome Glisse radeon_ring_ib_execute(rdev, ib); 197771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_fence_emit(rdev, ib->fence); 198ecb114a128d150422d22eda238cb812f6b20bf39Dave Airlie mutex_lock(&rdev->ib_pool.mutex); 19991cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse /* once scheduled IB is considered free and protected by the fence */ 20091cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse ib->free = true; 201771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 2027b1f2485db253aaa0081e1c5213533e166130732Christian König radeon_ring_unlock_commit(rdev, cp); 203771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 204771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 205771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 206771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_ib_pool_init(struct radeon_device *rdev) 207771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 208771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse void *ptr; 209771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse uint64_t gpu_addr; 210771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int i; 211771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r = 0; 212771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 2139f022ddfb23793b475ff7e57ac08a766dd5d31bdJerome Glisse if (rdev->ib_pool.robj) 2149f022ddfb23793b475ff7e57ac08a766dd5d31bdJerome Glisse return 0; 2159f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); 216771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Allocate 1M object buffer */ 217441921d5309cfe098747d9840fd71bdc6ca2a93bDaniel Vetter r = radeon_bo_create(rdev, RADEON_IB_POOL_SIZE*64*1024, 218268b2510de14f62134d87ba9b4981816192db386Alex Deucher PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, 219268b2510de14f62134d87ba9b4981816192db386Alex Deucher &rdev->ib_pool.robj); 220771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 221771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_ERROR("radeon: failed to ib pool (%d).\n", r); 222771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 223771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 2244c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse r = radeon_bo_reserve(rdev->ib_pool.robj, false); 2254c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (unlikely(r != 0)) 2264c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse return r; 2274c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr); 228771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 2294c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse radeon_bo_unreserve(rdev->ib_pool.robj); 230771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r); 231771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 232771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 2334c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr); 2344c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse radeon_bo_unreserve(rdev->ib_pool.robj); 235771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 236205a44a436e2af83ce9b88144f0eacbb16f8e915Paul Bolle DRM_ERROR("radeon: failed to map ib pool (%d).\n", r); 237771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 238771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 239771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 240771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned offset; 241771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 242771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse offset = i * 64 * 1024; 243771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset; 244771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].ptr = ptr + offset; 245771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].idx = i; 246771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ibs[i].length_dw = 0; 24791cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse rdev->ib_pool.ibs[i].free = true; 248771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 24991cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse rdev->ib_pool.head_id = 0; 250771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse rdev->ib_pool.ready = true; 251771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_INFO("radeon: ib pool ready.\n"); 252771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (radeon_debugfs_ib_init(rdev)) { 253771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_ERROR("Failed to register debugfs file for IB !\n"); 254771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 255771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 256771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 257771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 258771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissevoid radeon_ib_pool_fini(struct radeon_device *rdev) 259771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 2604c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse int r; 261ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher struct radeon_bo *robj; 2624c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse 263771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (!rdev->ib_pool.ready) { 264771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return; 265771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 266771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 2679f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse radeon_ib_bogus_cleanup(rdev); 268ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher robj = rdev->ib_pool.robj; 269ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher rdev->ib_pool.robj = NULL; 270ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher mutex_unlock(&rdev->ib_pool.mutex); 271eb6b6d7cdd5548fa03a919d14615195600013be2Dave Airlie 272ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher if (robj) { 273ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher r = radeon_bo_reserve(robj, false); 2744c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (likely(r == 0)) { 275ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_kunmap(robj); 276ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unpin(robj); 277ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unreserve(robj); 2784c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse } 279ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unref(&robj); 280771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 281771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 282771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 283771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 284771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 285771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Ring. 286771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 2877b1f2485db253aaa0081e1c5213533e166130732Christian Königvoid radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp) 288771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 289724c80e1d630296d1324859e964d80d35007d83cAlex Deucher if (rdev->wb.enabled) 2905596a9db156107b01ceb7db4d50cc091117da627Christian König cp->rptr = le32_to_cpu(rdev->wb.wb[cp->rptr_offs/4]); 2915596a9db156107b01ceb7db4d50cc091117da627Christian König else 2925596a9db156107b01ceb7db4d50cc091117da627Christian König cp->rptr = RREG32(cp->rptr_reg); 293771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* This works because ring_size is a power of 2 */ 2947b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_free_dw = (cp->rptr + (cp->ring_size / 4)); 2957b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_free_dw -= cp->wptr; 2967b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_free_dw &= cp->ptr_mask; 2977b1f2485db253aaa0081e1c5213533e166130732Christian König if (!cp->ring_free_dw) { 2987b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_free_dw = cp->ring_size / 4; 299771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 300771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 301771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3027b1f2485db253aaa0081e1c5213533e166130732Christian König 3037b1f2485db253aaa0081e1c5213533e166130732Christian Königint radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw) 304771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 305771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 306771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 307771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Align requested size with padding so unlock_commit can 308771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * pad safely */ 3097b1f2485db253aaa0081e1c5213533e166130732Christian König ndw = (ndw + cp->align_mask) & ~cp->align_mask; 3107b1f2485db253aaa0081e1c5213533e166130732Christian König while (ndw > (cp->ring_free_dw - 1)) { 3117b1f2485db253aaa0081e1c5213533e166130732Christian König radeon_ring_free_size(rdev, cp); 3127b1f2485db253aaa0081e1c5213533e166130732Christian König if (ndw < cp->ring_free_dw) { 313771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse break; 314771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 3157465280c076d6440e5908c158c83b542dc063a30Alex Deucher r = radeon_fence_wait_next(rdev, RADEON_RING_TYPE_GFX_INDEX); 31691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett if (r) 317771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 318771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 3197b1f2485db253aaa0081e1c5213533e166130732Christian König cp->count_dw = ndw; 3207b1f2485db253aaa0081e1c5213533e166130732Christian König cp->wptr_old = cp->wptr; 321771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 322771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 323771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3247b1f2485db253aaa0081e1c5213533e166130732Christian Königint radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw) 32591700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{ 32691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett int r; 32791700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 3287b1f2485db253aaa0081e1c5213533e166130732Christian König mutex_lock(&cp->mutex); 3297b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_ring_alloc(rdev, cp, ndw); 33091700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett if (r) { 3317b1f2485db253aaa0081e1c5213533e166130732Christian König mutex_unlock(&cp->mutex); 33291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett return r; 33391700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett } 33491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett return 0; 33591700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett} 33691700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 3377b1f2485db253aaa0081e1c5213533e166130732Christian Königvoid radeon_ring_commit(struct radeon_device *rdev, struct radeon_cp *cp) 338771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 339771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned count_dw_pad; 340771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 341771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 342771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* We pad to match fetch size */ 3437b1f2485db253aaa0081e1c5213533e166130732Christian König count_dw_pad = (cp->align_mask + 1) - 3447b1f2485db253aaa0081e1c5213533e166130732Christian König (cp->wptr & cp->align_mask); 345771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < count_dw_pad; i++) { 3467b1f2485db253aaa0081e1c5213533e166130732Christian König radeon_ring_write(cp, 2 << 30); 347771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 348771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse DRM_MEMORYBARRIER(); 3495596a9db156107b01ceb7db4d50cc091117da627Christian König WREG32(cp->wptr_reg, cp->wptr); 3505596a9db156107b01ceb7db4d50cc091117da627Christian König (void)RREG32(cp->wptr_reg); 35191700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett} 35291700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett 3537b1f2485db253aaa0081e1c5213533e166130732Christian Königvoid radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_cp *cp) 35491700f3cac56a1998a56d41e4459a5cebdb4f752Matthew Garrett{ 3557b1f2485db253aaa0081e1c5213533e166130732Christian König radeon_ring_commit(rdev, cp); 3567b1f2485db253aaa0081e1c5213533e166130732Christian König mutex_unlock(&cp->mutex); 357771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 358771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3597b1f2485db253aaa0081e1c5213533e166130732Christian Königvoid radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_cp *cp) 360771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 3617b1f2485db253aaa0081e1c5213533e166130732Christian König cp->wptr = cp->wptr_old; 3627b1f2485db253aaa0081e1c5213533e166130732Christian König mutex_unlock(&cp->mutex); 363771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 364771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3655596a9db156107b01ceb7db4d50cc091117da627Christian Königint radeon_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size, 3665596a9db156107b01ceb7db4d50cc091117da627Christian König unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg) 367771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 368771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse int r; 369771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 3707b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_size = ring_size; 3715596a9db156107b01ceb7db4d50cc091117da627Christian König cp->rptr_offs = rptr_offs; 3725596a9db156107b01ceb7db4d50cc091117da627Christian König cp->rptr_reg = rptr_reg; 3735596a9db156107b01ceb7db4d50cc091117da627Christian König cp->wptr_reg = wptr_reg; 374771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse /* Allocate ring buffer */ 3757b1f2485db253aaa0081e1c5213533e166130732Christian König if (cp->ring_obj == NULL) { 3767b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_bo_create(rdev, cp->ring_size, PAGE_SIZE, true, 3774c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse RADEON_GEM_DOMAIN_GTT, 3787b1f2485db253aaa0081e1c5213533e166130732Christian König &cp->ring_obj); 379771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 3804c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring create failed\n", r); 381771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 382771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 3837b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_bo_reserve(cp->ring_obj, false); 3844c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (unlikely(r != 0)) 3854c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse return r; 3867b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_bo_pin(cp->ring_obj, RADEON_GEM_DOMAIN_GTT, 3877b1f2485db253aaa0081e1c5213533e166130732Christian König &cp->gpu_addr); 388771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 3897b1f2485db253aaa0081e1c5213533e166130732Christian König radeon_bo_unreserve(cp->ring_obj); 3904c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring pin failed\n", r); 391771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 392771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 3937b1f2485db253aaa0081e1c5213533e166130732Christian König r = radeon_bo_kmap(cp->ring_obj, 3947b1f2485db253aaa0081e1c5213533e166130732Christian König (void **)&cp->ring); 3957b1f2485db253aaa0081e1c5213533e166130732Christian König radeon_bo_unreserve(cp->ring_obj); 396771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (r) { 3974c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse dev_err(rdev->dev, "(%d) ring map failed\n", r); 398771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return r; 399771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 400771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 4017b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ptr_mask = (cp->ring_size / 4) - 1; 4027b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_free_dw = cp->ring_size / 4; 403771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 404771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 405771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 4067b1f2485db253aaa0081e1c5213533e166130732Christian Königvoid radeon_ring_fini(struct radeon_device *rdev, struct radeon_cp *cp) 407771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 4084c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse int r; 409ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher struct radeon_bo *ring_obj; 4104c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse 4117b1f2485db253aaa0081e1c5213533e166130732Christian König mutex_lock(&cp->mutex); 4127b1f2485db253aaa0081e1c5213533e166130732Christian König ring_obj = cp->ring_obj; 4137b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring = NULL; 4147b1f2485db253aaa0081e1c5213533e166130732Christian König cp->ring_obj = NULL; 4157b1f2485db253aaa0081e1c5213533e166130732Christian König mutex_unlock(&cp->mutex); 416ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher 417ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher if (ring_obj) { 418ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher r = radeon_bo_reserve(ring_obj, false); 4194c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse if (likely(r == 0)) { 420ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_kunmap(ring_obj); 421ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unpin(ring_obj); 422ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unreserve(ring_obj); 4234c7886791264f03428d5424befb1b96f08fc90f4Jerome Glisse } 424ca2af92311eee95820f3b48c35045e5f56bc1477Alex Deucher radeon_bo_unref(&ring_obj); 425771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 426771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 427771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 428771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse/* 429771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse * Debugfs info 430771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse */ 431771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 432771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic int radeon_debugfs_ib_info(struct seq_file *m, void *data) 433771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 434771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct drm_info_node *node = (struct drm_info_node *) m->private; 435771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse struct radeon_ib *ib = node->info_ent->data; 436771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 437771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 438771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse if (ib == NULL) { 439771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 440771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 44191cb91becf372b5308cdd7d2e15b2e3ef66bae7eJerome Glisse seq_printf(m, "IB %04u\n", ib->idx); 442771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "IB fence %p\n", ib->fence); 443771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "IB size %05u dwords\n", ib->length_dw); 444771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < ib->length_dw; i++) { 445771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); 446771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 447771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 448771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 449771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 4509f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glissestatic int radeon_debugfs_ib_bogus_info(struct seq_file *m, void *data) 4519f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse{ 4529f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse struct drm_info_node *node = (struct drm_info_node *) m->private; 4539f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse struct radeon_device *rdev = node->info_ent->data; 4549f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse struct radeon_ib *ib; 4559f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse unsigned i; 4569f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 4579f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse mutex_lock(&rdev->ib_pool.mutex); 4589f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse if (list_empty(&rdev->ib_pool.bogus_ib)) { 4599f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 4609f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse seq_printf(m, "no bogus IB recorded\n"); 4619f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse return 0; 4629f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse } 4639f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse ib = list_first_entry(&rdev->ib_pool.bogus_ib, struct radeon_ib, list); 4649f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse list_del_init(&ib->list); 4659f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse mutex_unlock(&rdev->ib_pool.mutex); 4669f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse seq_printf(m, "IB size %05u dwords\n", ib->length_dw); 4679f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse for (i = 0; i < ib->length_dw; i++) { 4689f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); 4699f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse } 4709f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse vfree(ib->ptr); 4719f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse kfree(ib); 4729f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse return 0; 4739f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse} 4749f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 475771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; 476771fe6b912fca54f03e8a72eb63058b582775362Jerome Glissestatic char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; 4779f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse 4789f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glissestatic struct drm_info_list radeon_debugfs_ib_bogus_info_list[] = { 4799f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse {"radeon_ib_bogus", radeon_debugfs_ib_bogus_info, 0, NULL}, 4809f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse}; 481771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 482771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 483771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisseint radeon_debugfs_ib_init(struct radeon_device *rdev) 484771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse{ 485771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#if defined(CONFIG_DEBUG_FS) 486771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse unsigned i; 4879f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse int r; 488771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse 4899f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse radeon_debugfs_ib_bogus_info_list[0].data = rdev; 4909f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse r = radeon_debugfs_add_files(rdev, radeon_debugfs_ib_bogus_info_list, 1); 4919f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse if (r) 4929f93ed39804a9cfe10577cfae66059fe6bc6e3a5Jerome Glisse return r; 493771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { 494771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); 495771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; 496771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info; 497771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].driver_features = 0; 498771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse radeon_debugfs_ib_list[i].data = &rdev->ib_pool.ibs[i]; 499771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse } 500771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list, 501771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse RADEON_IB_POOL_SIZE); 502771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#else 503771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse return 0; 504771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse#endif 505771fe6b912fca54f03e8a72eb63058b582775362Jerome Glisse} 506