1*f28be810SChristian König /* 2*f28be810SChristian König * Copyright 2008 Advanced Micro Devices, Inc. 3*f28be810SChristian König * Copyright 2008 Red Hat Inc. 4*f28be810SChristian König * Copyright 2009 Jerome Glisse. 5*f28be810SChristian König * 6*f28be810SChristian König * Permission is hereby granted, free of charge, to any person obtaining a 7*f28be810SChristian König * copy of this software and associated documentation files (the "Software"), 8*f28be810SChristian König * to deal in the Software without restriction, including without limitation 9*f28be810SChristian König * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10*f28be810SChristian König * and/or sell copies of the Software, and to permit persons to whom the 11*f28be810SChristian König * Software is furnished to do so, subject to the following conditions: 12*f28be810SChristian König * 13*f28be810SChristian König * The above copyright notice and this permission notice shall be included in 14*f28be810SChristian König * all copies or substantial portions of the Software. 15*f28be810SChristian König * 16*f28be810SChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*f28be810SChristian König * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*f28be810SChristian König * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*f28be810SChristian König * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20*f28be810SChristian König * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21*f28be810SChristian König * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22*f28be810SChristian König * OTHER DEALINGS IN THE SOFTWARE. 23*f28be810SChristian König * 24*f28be810SChristian König * Authors: Dave Airlie 25*f28be810SChristian König * Alex Deucher 26*f28be810SChristian König * Jerome Glisse 27*f28be810SChristian König * Christian König 28*f28be810SChristian König */ 29*f28be810SChristian König #include <drm/drmP.h> 30*f28be810SChristian König #include "radeon.h" 31*f28be810SChristian König 32*f28be810SChristian König /* 33*f28be810SChristian König * IB 34*f28be810SChristian König * IBs (Indirect Buffers) and areas of GPU accessible memory where 35*f28be810SChristian König * commands are stored. You can put a pointer to the IB in the 36*f28be810SChristian König * command ring and the hw will fetch the commands from the IB 37*f28be810SChristian König * and execute them. Generally userspace acceleration drivers 38*f28be810SChristian König * produce command buffers which are send to the kernel and 39*f28be810SChristian König * put in IBs for execution by the requested ring. 40*f28be810SChristian König */ 41*f28be810SChristian König static int radeon_debugfs_sa_init(struct radeon_device *rdev); 42*f28be810SChristian König 43*f28be810SChristian König /** 44*f28be810SChristian König * radeon_ib_get - request an IB (Indirect Buffer) 45*f28be810SChristian König * 46*f28be810SChristian König * @rdev: radeon_device pointer 47*f28be810SChristian König * @ring: ring index the IB is associated with 48*f28be810SChristian König * @ib: IB object returned 49*f28be810SChristian König * @size: requested IB size 50*f28be810SChristian König * 51*f28be810SChristian König * Request an IB (all asics). IBs are allocated using the 52*f28be810SChristian König * suballocator. 53*f28be810SChristian König * Returns 0 on success, error on failure. 54*f28be810SChristian König */ 55*f28be810SChristian König int radeon_ib_get(struct radeon_device *rdev, int ring, 56*f28be810SChristian König struct radeon_ib *ib, struct radeon_vm *vm, 57*f28be810SChristian König unsigned size) 58*f28be810SChristian König { 59*f28be810SChristian König int r; 60*f28be810SChristian König 61*f28be810SChristian König r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256); 62*f28be810SChristian König if (r) { 63*f28be810SChristian König dev_err(rdev->dev, "failed to get a new IB (%d)\n", r); 64*f28be810SChristian König return r; 65*f28be810SChristian König } 66*f28be810SChristian König 67*f28be810SChristian König r = radeon_semaphore_create(rdev, &ib->semaphore); 68*f28be810SChristian König if (r) { 69*f28be810SChristian König return r; 70*f28be810SChristian König } 71*f28be810SChristian König 72*f28be810SChristian König ib->ring = ring; 73*f28be810SChristian König ib->fence = NULL; 74*f28be810SChristian König ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo); 75*f28be810SChristian König ib->vm = vm; 76*f28be810SChristian König if (vm) { 77*f28be810SChristian König /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address 78*f28be810SChristian König * space and soffset is the offset inside the pool bo 79*f28be810SChristian König */ 80*f28be810SChristian König ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET; 81*f28be810SChristian König } else { 82*f28be810SChristian König ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); 83*f28be810SChristian König } 84*f28be810SChristian König ib->is_const_ib = false; 85*f28be810SChristian König 86*f28be810SChristian König return 0; 87*f28be810SChristian König } 88*f28be810SChristian König 89*f28be810SChristian König /** 90*f28be810SChristian König * radeon_ib_free - free an IB (Indirect Buffer) 91*f28be810SChristian König * 92*f28be810SChristian König * @rdev: radeon_device pointer 93*f28be810SChristian König * @ib: IB object to free 94*f28be810SChristian König * 95*f28be810SChristian König * Free an IB (all asics). 96*f28be810SChristian König */ 97*f28be810SChristian König void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) 98*f28be810SChristian König { 99*f28be810SChristian König radeon_semaphore_free(rdev, &ib->semaphore, ib->fence); 100*f28be810SChristian König radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); 101*f28be810SChristian König radeon_fence_unref(&ib->fence); 102*f28be810SChristian König } 103*f28be810SChristian König 104*f28be810SChristian König /** 105*f28be810SChristian König * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring 106*f28be810SChristian König * 107*f28be810SChristian König * @rdev: radeon_device pointer 108*f28be810SChristian König * @ib: IB object to schedule 109*f28be810SChristian König * @const_ib: Const IB to schedule (SI only) 110*f28be810SChristian König * 111*f28be810SChristian König * Schedule an IB on the associated ring (all asics). 112*f28be810SChristian König * Returns 0 on success, error on failure. 113*f28be810SChristian König * 114*f28be810SChristian König * On SI, there are two parallel engines fed from the primary ring, 115*f28be810SChristian König * the CE (Constant Engine) and the DE (Drawing Engine). Since 116*f28be810SChristian König * resource descriptors have moved to memory, the CE allows you to 117*f28be810SChristian König * prime the caches while the DE is updating register state so that 118*f28be810SChristian König * the resource descriptors will be already in cache when the draw is 119*f28be810SChristian König * processed. To accomplish this, the userspace driver submits two 120*f28be810SChristian König * IBs, one for the CE and one for the DE. If there is a CE IB (called 121*f28be810SChristian König * a CONST_IB), it will be put on the ring prior to the DE IB. Prior 122*f28be810SChristian König * to SI there was just a DE IB. 123*f28be810SChristian König */ 124*f28be810SChristian König int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, 125*f28be810SChristian König struct radeon_ib *const_ib) 126*f28be810SChristian König { 127*f28be810SChristian König struct radeon_ring *ring = &rdev->ring[ib->ring]; 128*f28be810SChristian König int r = 0; 129*f28be810SChristian König 130*f28be810SChristian König if (!ib->length_dw || !ring->ready) { 131*f28be810SChristian König /* TODO: Nothings in the ib we should report. */ 132*f28be810SChristian König dev_err(rdev->dev, "couldn't schedule ib\n"); 133*f28be810SChristian König return -EINVAL; 134*f28be810SChristian König } 135*f28be810SChristian König 136*f28be810SChristian König /* 64 dwords should be enough for fence too */ 137*f28be810SChristian König r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8); 138*f28be810SChristian König if (r) { 139*f28be810SChristian König dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); 140*f28be810SChristian König return r; 141*f28be810SChristian König } 142*f28be810SChristian König 143*f28be810SChristian König /* grab a vm id if necessary */ 144*f28be810SChristian König if (ib->vm) { 145*f28be810SChristian König struct radeon_fence *vm_id_fence; 146*f28be810SChristian König vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); 147*f28be810SChristian König radeon_semaphore_sync_to(ib->semaphore, vm_id_fence); 148*f28be810SChristian König } 149*f28be810SChristian König 150*f28be810SChristian König /* sync with other rings */ 151*f28be810SChristian König r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); 152*f28be810SChristian König if (r) { 153*f28be810SChristian König dev_err(rdev->dev, "failed to sync rings (%d)\n", r); 154*f28be810SChristian König radeon_ring_unlock_undo(rdev, ring); 155*f28be810SChristian König return r; 156*f28be810SChristian König } 157*f28be810SChristian König 158*f28be810SChristian König if (ib->vm) 159*f28be810SChristian König radeon_vm_flush(rdev, ib->vm, ib->ring); 160*f28be810SChristian König 161*f28be810SChristian König if (const_ib) { 162*f28be810SChristian König radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); 163*f28be810SChristian König radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); 164*f28be810SChristian König } 165*f28be810SChristian König radeon_ring_ib_execute(rdev, ib->ring, ib); 166*f28be810SChristian König r = radeon_fence_emit(rdev, &ib->fence, ib->ring); 167*f28be810SChristian König if (r) { 168*f28be810SChristian König dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r); 169*f28be810SChristian König radeon_ring_unlock_undo(rdev, ring); 170*f28be810SChristian König return r; 171*f28be810SChristian König } 172*f28be810SChristian König if (const_ib) { 173*f28be810SChristian König const_ib->fence = radeon_fence_ref(ib->fence); 174*f28be810SChristian König } 175*f28be810SChristian König 176*f28be810SChristian König if (ib->vm) 177*f28be810SChristian König radeon_vm_fence(rdev, ib->vm, ib->fence); 178*f28be810SChristian König 179*f28be810SChristian König radeon_ring_unlock_commit(rdev, ring); 180*f28be810SChristian König return 0; 181*f28be810SChristian König } 182*f28be810SChristian König 183*f28be810SChristian König /** 184*f28be810SChristian König * radeon_ib_pool_init - Init the IB (Indirect Buffer) pool 185*f28be810SChristian König * 186*f28be810SChristian König * @rdev: radeon_device pointer 187*f28be810SChristian König * 188*f28be810SChristian König * Initialize the suballocator to manage a pool of memory 189*f28be810SChristian König * for use as IBs (all asics). 190*f28be810SChristian König * Returns 0 on success, error on failure. 191*f28be810SChristian König */ 192*f28be810SChristian König int radeon_ib_pool_init(struct radeon_device *rdev) 193*f28be810SChristian König { 194*f28be810SChristian König int r; 195*f28be810SChristian König 196*f28be810SChristian König if (rdev->ib_pool_ready) { 197*f28be810SChristian König return 0; 198*f28be810SChristian König } 199*f28be810SChristian König 200*f28be810SChristian König if (rdev->family >= CHIP_BONAIRE) { 201*f28be810SChristian König r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo, 202*f28be810SChristian König RADEON_IB_POOL_SIZE*64*1024, 203*f28be810SChristian König RADEON_GPU_PAGE_SIZE, 204*f28be810SChristian König RADEON_GEM_DOMAIN_GTT, 205*f28be810SChristian König RADEON_GEM_GTT_WC); 206*f28be810SChristian König } else { 207*f28be810SChristian König /* Before CIK, it's better to stick to cacheable GTT due 208*f28be810SChristian König * to the command stream checking 209*f28be810SChristian König */ 210*f28be810SChristian König r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo, 211*f28be810SChristian König RADEON_IB_POOL_SIZE*64*1024, 212*f28be810SChristian König RADEON_GPU_PAGE_SIZE, 213*f28be810SChristian König RADEON_GEM_DOMAIN_GTT, 0); 214*f28be810SChristian König } 215*f28be810SChristian König if (r) { 216*f28be810SChristian König return r; 217*f28be810SChristian König } 218*f28be810SChristian König 219*f28be810SChristian König r = radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo); 220*f28be810SChristian König if (r) { 221*f28be810SChristian König return r; 222*f28be810SChristian König } 223*f28be810SChristian König 224*f28be810SChristian König rdev->ib_pool_ready = true; 225*f28be810SChristian König if (radeon_debugfs_sa_init(rdev)) { 226*f28be810SChristian König dev_err(rdev->dev, "failed to register debugfs file for SA\n"); 227*f28be810SChristian König } 228*f28be810SChristian König return 0; 229*f28be810SChristian König } 230*f28be810SChristian König 231*f28be810SChristian König /** 232*f28be810SChristian König * radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool 233*f28be810SChristian König * 234*f28be810SChristian König * @rdev: radeon_device pointer 235*f28be810SChristian König * 236*f28be810SChristian König * Tear down the suballocator managing the pool of memory 237*f28be810SChristian König * for use as IBs (all asics). 238*f28be810SChristian König */ 239*f28be810SChristian König void radeon_ib_pool_fini(struct radeon_device *rdev) 240*f28be810SChristian König { 241*f28be810SChristian König if (rdev->ib_pool_ready) { 242*f28be810SChristian König radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo); 243*f28be810SChristian König radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo); 244*f28be810SChristian König rdev->ib_pool_ready = false; 245*f28be810SChristian König } 246*f28be810SChristian König } 247*f28be810SChristian König 248*f28be810SChristian König /** 249*f28be810SChristian König * radeon_ib_ring_tests - test IBs on the rings 250*f28be810SChristian König * 251*f28be810SChristian König * @rdev: radeon_device pointer 252*f28be810SChristian König * 253*f28be810SChristian König * Test an IB (Indirect Buffer) on each ring. 254*f28be810SChristian König * If the test fails, disable the ring. 255*f28be810SChristian König * Returns 0 on success, error if the primary GFX ring 256*f28be810SChristian König * IB test fails. 257*f28be810SChristian König */ 258*f28be810SChristian König int radeon_ib_ring_tests(struct radeon_device *rdev) 259*f28be810SChristian König { 260*f28be810SChristian König unsigned i; 261*f28be810SChristian König int r; 262*f28be810SChristian König 263*f28be810SChristian König for (i = 0; i < RADEON_NUM_RINGS; ++i) { 264*f28be810SChristian König struct radeon_ring *ring = &rdev->ring[i]; 265*f28be810SChristian König 266*f28be810SChristian König if (!ring->ready) 267*f28be810SChristian König continue; 268*f28be810SChristian König 269*f28be810SChristian König r = radeon_ib_test(rdev, i, ring); 270*f28be810SChristian König if (r) { 271*f28be810SChristian König ring->ready = false; 272*f28be810SChristian König rdev->needs_reset = false; 273*f28be810SChristian König 274*f28be810SChristian König if (i == RADEON_RING_TYPE_GFX_INDEX) { 275*f28be810SChristian König /* oh, oh, that's really bad */ 276*f28be810SChristian König DRM_ERROR("radeon: failed testing IB on GFX ring (%d).\n", r); 277*f28be810SChristian König rdev->accel_working = false; 278*f28be810SChristian König return r; 279*f28be810SChristian König 280*f28be810SChristian König } else { 281*f28be810SChristian König /* still not good, but we can live with it */ 282*f28be810SChristian König DRM_ERROR("radeon: failed testing IB on ring %d (%d).\n", i, r); 283*f28be810SChristian König } 284*f28be810SChristian König } 285*f28be810SChristian König } 286*f28be810SChristian König return 0; 287*f28be810SChristian König } 288*f28be810SChristian König 289*f28be810SChristian König /* 290*f28be810SChristian König * Debugfs info 291*f28be810SChristian König */ 292*f28be810SChristian König #if defined(CONFIG_DEBUG_FS) 293*f28be810SChristian König 294*f28be810SChristian König static int radeon_debugfs_sa_info(struct seq_file *m, void *data) 295*f28be810SChristian König { 296*f28be810SChristian König struct drm_info_node *node = (struct drm_info_node *) m->private; 297*f28be810SChristian König struct drm_device *dev = node->minor->dev; 298*f28be810SChristian König struct radeon_device *rdev = dev->dev_private; 299*f28be810SChristian König 300*f28be810SChristian König radeon_sa_bo_dump_debug_info(&rdev->ring_tmp_bo, m); 301*f28be810SChristian König 302*f28be810SChristian König return 0; 303*f28be810SChristian König 304*f28be810SChristian König } 305*f28be810SChristian König 306*f28be810SChristian König static struct drm_info_list radeon_debugfs_sa_list[] = { 307*f28be810SChristian König {"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL}, 308*f28be810SChristian König }; 309*f28be810SChristian König 310*f28be810SChristian König #endif 311*f28be810SChristian König 312*f28be810SChristian König static int radeon_debugfs_sa_init(struct radeon_device *rdev) 313*f28be810SChristian König { 314*f28be810SChristian König #if defined(CONFIG_DEBUG_FS) 315*f28be810SChristian König return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1); 316*f28be810SChristian König #else 317*f28be810SChristian König return 0; 318*f28be810SChristian König #endif 319*f28be810SChristian König } 320