static void cayman_cp_enable(struct radeon_device *rdev, bool enable) { if (enable) WREG32(CP_ME_CNTL, 0); else { radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); WREG32(SCRATCH_UMSK, 0); } }
/** * r600_dma_stop - stop the async dma engine * * @rdev: radeon_device pointer * * Stop the async dma engine (r6xx-evergreen). */ void r600_dma_stop(struct radeon_device *rdev) { u32 rb_cntl = RREG32(DMA_RB_CNTL); if (rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); rb_cntl &= ~DMA_RB_ENABLE; WREG32(DMA_RB_CNTL, rb_cntl); rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false; }
/** * cik_sdma_gfx_stop - stop the gfx async dma engines * * @rdev: radeon_device pointer * * Stop the gfx async dma ring buffers (CIK). */ static void cik_sdma_gfx_stop(struct radeon_device *rdev) { u32 rb_cntl, reg_offset; int i; radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); for (i = 0; i < 2; i++) { if (i == 0) reg_offset = SDMA0_REGISTER_OFFSET; else reg_offset = SDMA1_REGISTER_OFFSET; rb_cntl = RREG32(SDMA0_GFX_RB_CNTL + reg_offset); rb_cntl &= ~SDMA_RB_ENABLE; WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); WREG32(SDMA0_GFX_IB_CNTL + reg_offset, 0); } rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false; rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false; }
/** * cik_sdma_gfx_resume - setup and start the async dma engines * * @rdev: radeon_device pointer * * Set up the gfx DMA ring buffers and enable them (CIK). * Returns 0 for success, error for failure. */ static int cik_sdma_gfx_resume(struct radeon_device *rdev) { struct radeon_ring *ring; u32 rb_cntl, ib_cntl; u32 rb_bufsz; u32 reg_offset, wb_offset; int i, r; for (i = 0; i < 2; i++) { if (i == 0) { ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; reg_offset = SDMA0_REGISTER_OFFSET; wb_offset = R600_WB_DMA_RPTR_OFFSET; } else { ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; reg_offset = SDMA1_REGISTER_OFFSET; wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET; } WREG32(SDMA0_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0); WREG32(SDMA0_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN rb_cntl |= SDMA_RB_SWAP_ENABLE | SDMA_RPTR_WRITEBACK_SWAP_ENABLE; #endif WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(SDMA0_GFX_RB_RPTR + reg_offset, 0); WREG32(SDMA0_GFX_RB_WPTR + reg_offset, 0); /* set the wb address whether it's enabled or not */ WREG32(SDMA0_GFX_RB_RPTR_ADDR_HI + reg_offset, upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); WREG32(SDMA0_GFX_RB_RPTR_ADDR_LO + reg_offset, ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC)); if (rdev->wb.enabled) rb_cntl |= SDMA_RPTR_WRITEBACK_ENABLE; WREG32(SDMA0_GFX_RB_BASE + reg_offset, ring->gpu_addr >> 8); WREG32(SDMA0_GFX_RB_BASE_HI + reg_offset, ring->gpu_addr >> 40); ring->wptr = 0; WREG32(SDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2); /* enable DMA RB */ WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl | SDMA_RB_ENABLE); ib_cntl = SDMA_IB_ENABLE; #ifdef __BIG_ENDIAN ib_cntl |= SDMA_IB_SWAP_ENABLE; #endif /* enable DMA IBs */ WREG32(SDMA0_GFX_IB_CNTL + reg_offset, ib_cntl); ring->ready = true; r = radeon_ring_test(rdev, ring->idx, ring); if (r) { ring->ready = false; return r; } } if ((rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) || (rdev->asic->copy.copy_ring_index == CAYMAN_RING_TYPE_DMA1_INDEX)) radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; }
/** * r600_dma_resume - setup and start the async dma engine * * @rdev: radeon_device pointer * * Set up the DMA ring buffer and enable it. (r6xx-evergreen). * Returns 0 for success, error for failure. */ int r600_dma_resume(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; u32 rb_cntl, dma_cntl, ib_cntl; u32 rb_bufsz; int r; /* Reset dma */ if (rdev->family >= CHIP_RV770) WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA); else WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); RREG32(SRBM_SOFT_RESET); udelay(50); WREG32(SRBM_SOFT_RESET, 0); WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL, 0); WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL, 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE; #endif WREG32(DMA_RB_CNTL, rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(DMA_RB_RPTR, 0); WREG32(DMA_RB_WPTR, 0); /* set the wb address whether it's enabled or not */ WREG32(DMA_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_DMA_RPTR_OFFSET) & 0xFF); WREG32(DMA_RB_RPTR_ADDR_LO, ((rdev->wb.gpu_addr + R600_WB_DMA_RPTR_OFFSET) & 0xFFFFFFFC)); if (rdev->wb.enabled) rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE; WREG32(DMA_RB_BASE, ring->gpu_addr >> 8); /* enable DMA IBs */ ib_cntl = DMA_IB_ENABLE; #ifdef __BIG_ENDIAN ib_cntl |= DMA_IB_SWAP_ENABLE; #endif WREG32(DMA_IB_CNTL, ib_cntl); dma_cntl = RREG32(DMA_CNTL); dma_cntl &= ~CTXEMPTY_INT_ENABLE; WREG32(DMA_CNTL, dma_cntl); if (rdev->family >= CHIP_RV770) WREG32(DMA_MODE, 1); ring->wptr = 0; WREG32(DMA_RB_WPTR, ring->wptr << 2); ring->rptr = RREG32(DMA_RB_RPTR) >> 2; WREG32(DMA_RB_CNTL, rb_cntl | DMA_RB_ENABLE); ring->ready = true; r = radeon_ring_test(rdev, R600_RING_TYPE_DMA_INDEX, ring); if (r) { ring->ready = false; return r; } if (rdev->asic->copy.copy_ring_index == R600_RING_TYPE_DMA_INDEX) radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; }
int radeon_ttm_init(struct radeon_device *rdev) { int r; r = radeon_ttm_global_init(rdev); if (r) { return r; } /* No others user of address space so set it to 0 */ r = ttm_bo_device_init(&rdev->mman.bdev, rdev->mman.bo_global_ref.ref.object, &radeon_bo_driver, DRM_FILE_PAGE_OFFSET, rdev->need_dma32); if (r) { DRM_ERROR("failed initializing buffer object driver(%d).\n", r); return r; } rdev->mman.bdev.iot = rdev->iot; rdev->mman.bdev.memt = rdev->memt; rdev->mman.bdev.dmat = rdev->dmat; rdev->mman.initialized = true; r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, rdev->mc.real_vram_size >> PAGE_SHIFT); if (r) { DRM_ERROR("Failed initializing VRAM heap.\n"); return r; } /* Change the size here instead of the init above so only lpfn is affected */ radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); #ifdef __sparc64__ r = radeon_bo_create(rdev, rdev->fb_offset, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->stollen_vga_memory); #else r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->stollen_vga_memory); #endif if (r) { return r; } r = radeon_bo_reserve(rdev->stollen_vga_memory, false); if (r) return r; r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); radeon_bo_unreserve(rdev->stollen_vga_memory); if (r) { radeon_bo_unref(&rdev->stollen_vga_memory); return r; } DRM_INFO("radeon: %uM of VRAM memory ready\n", (unsigned) (rdev->mc.real_vram_size / (1024 * 1024))); r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, rdev->mc.gtt_size >> PAGE_SHIFT); if (r) { DRM_ERROR("Failed initializing GTT heap.\n"); return r; } DRM_INFO("radeon: %uM of GTT memory ready.\n", (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); #ifdef notyet rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; #endif r = radeon_ttm_debugfs_init(rdev); if (r) { DRM_ERROR("Failed to init debugfs\n"); return r; } return 0; }