/** * radeon_fence_driver_fini - tear down the fence driver * for all possible rings. * * @rdev: radeon device pointer * * Tear down the fence driver for all possible rings (all asics). */ void radeon_fence_driver_fini(struct radeon_device *rdev) { int ring, r; mutex_lock(&rdev->ring_lock); for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { if (!rdev->fence_drv[ring].initialized) continue; r = radeon_fence_wait_empty(rdev, ring); if (r) { /* no need to trigger GPU reset as we are unloading */ radeon_fence_driver_force_completion(rdev); } #ifdef __NetBSD__ spin_lock(&rdev->fence_lock); DRM_SPIN_WAKEUP_ALL(&rdev->fence_queue, &rdev->fence_lock); spin_unlock(&rdev->fence_lock); #else wake_up_all(&rdev->fence_queue); #endif radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); rdev->fence_drv[ring].initialized = false; } mutex_unlock(&rdev->ring_lock); #ifdef __NetBSD__ DRM_DESTROY_WAITQUEUE(&rdev->fence_queue); spin_lock_destroy(&rdev->fence_lock); #endif }
/** * radeon_fence_driver_start_ring - make the fence driver * ready for use on the requested ring. * * @rdev: radeon device pointer * @ring: ring index to start the fence driver on * * Make the fence driver ready for processing (all asics). * Not all asics have all rings, so each asic will only * start the fence driver on the rings it has. * Returns 0 for success, errors for failure. */ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) { uint64_t index; int r; radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) { rdev->fence_drv[ring].scratch_reg = 0; index = R600_WB_EVENT_OFFSET + ring * 4; } else { r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg); if (r) { dev_err(rdev->dev, "fence failed to get scratch register\n"); return r; } index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base; } rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; radeon_fence_write(rdev, atomic_load_acq_64(&rdev->fence_drv[ring].last_seq), ring); rdev->fence_drv[ring].initialized = true; dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016jx and cpu addr 0x%p\n", ring, (uintmax_t)rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); return 0; }
/** * radeon_fence_driver_fini - tear down the fence driver * for all possible rings. * * @rdev: radeon device pointer * * Tear down the fence driver for all possible rings (all asics). */ void radeon_fence_driver_fini(struct radeon_device *rdev) { int ring; mutex_lock(&rdev->ring_lock); for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { if (!rdev->fence_drv[ring].initialized) continue; radeon_fence_wait_empty_locked(rdev, ring); wake_up_all(&rdev->fence_queue); radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); rdev->fence_drv[ring].initialized = false; } mutex_unlock(&rdev->ring_lock); }
/** * radeon_fence_driver_start_ring - make the fence driver * ready for use on the requested ring. * * @rdev: radeon device pointer * @ring: ring index to start the fence driver on * * Make the fence driver ready for processing (all asics). * Not all asics have all rings, so each asic will only * start the fence driver on the rings it has. * Returns 0 for success, errors for failure. */ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) { uint64_t index; int r; radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) { rdev->fence_drv[ring].scratch_reg = 0; if (ring != R600_RING_TYPE_UVD_INDEX) { index = R600_WB_EVENT_OFFSET + ring * 4; rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; } else { /* put fence directly behind firmware */ #ifdef __NetBSD__ /* XXX ALIGN means something else. */ index = round_up(rdev->uvd_fw->size, 8); #else index = ALIGN(rdev->uvd_fw->size, 8); #endif rdev->fence_drv[ring].cpu_addr = (uint32_t *)((uint8_t *)rdev->uvd.cpu_addr + index); rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; } } else { r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg); if (r) { dev_err(rdev->dev, "fence failed to get scratch register\n"); return r; } index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base; rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; } radeon_fence_write(rdev, atomic64_read(&rdev->fence_drv[ring].last_seq), ring); rdev->fence_drv[ring].initialized = true; dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016"PRIx64" and cpu addr 0x%p\n", ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); return 0; }
/** * radeon_fence_driver_fini - tear down the fence driver * for all possible rings. * * @rdev: radeon device pointer * * Tear down the fence driver for all possible rings (all asics). */ void radeon_fence_driver_fini(struct radeon_device *rdev) { int ring, r; mutex_lock(&rdev->ring_lock); for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { if (!rdev->fence_drv[ring].initialized) continue; r = radeon_fence_wait_empty(rdev, ring); if (r) { /* no need to trigger GPU reset as we are unloading */ radeon_fence_driver_force_completion(rdev, ring); } wake_up_all(&rdev->fence_queue); radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); rdev->fence_drv[ring].initialized = false; } mutex_unlock(&rdev->ring_lock); }
/** * radeon_fence_driver_fini - tear down the fence driver * for all possible rings. * * @rdev: radeon device pointer * * Tear down the fence driver for all possible rings (all asics). */ void radeon_fence_driver_fini(struct radeon_device *rdev) { int ring, r; sx_xlock(&rdev->ring_lock); for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { if (!rdev->fence_drv[ring].initialized) continue; r = radeon_fence_wait_empty_locked(rdev, ring); if (r) { /* no need to trigger GPU reset as we are unloading */ radeon_fence_driver_force_completion(rdev); } cv_broadcast(&rdev->fence_queue); radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); rdev->fence_drv[ring].initialized = false; cv_destroy(&rdev->fence_queue); } sx_xunlock(&rdev->ring_lock); }