static int vce_v2_0_hw_init(void *handle) { struct amdgpu_ring *ring; int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; r = vce_v2_0_start(adev); if (r) return r; ring = &adev->vce.ring[0]; ring->ready = true; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; return r; } ring = &adev->vce.ring[1]; ring->ready = true; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; return r; } DRM_INFO("VCE initialized successfully.\n"); return 0; }
static int vce_v2_0_hw_init(void *handle) { int r, i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; r = vce_v2_0_start(adev); /* this error mean vcpu not in running state, so just skip ring test, not stop driver initialize */ if (r) return 0; for (i = 0; i < adev->vce.num_rings; i++) adev->vce.ring[i].ready = false; for (i = 0; i < adev->vce.num_rings; i++) { r = amdgpu_ring_test_ring(&adev->vce.ring[i]); if (r) return r; else adev->vce.ring[i].ready = true; } DRM_INFO("VCE initialized successfully.\n"); return 0; }
/** * uvd_v5_0_hw_init - start and test UVD block * * @adev: amdgpu_device pointer * * Initialize the hardware, boot up the VCPU and do some testing */ static int uvd_v5_0_hw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_ring *ring = &adev->uvd.ring; uint32_t tmp; int r; /* raise clocks while booting up the VCPU */ amdgpu_asic_set_uvd_clocks(adev, 53300, 40000); r = uvd_v5_0_start(adev); if (r) goto done; ring->ready = true; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; goto done; } r = amdgpu_ring_alloc(ring, 10); if (r) { DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); goto done; } tmp = PACKET0(mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0); amdgpu_ring_write(ring, tmp); amdgpu_ring_write(ring, 0xFFFFF); tmp = PACKET0(mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0); amdgpu_ring_write(ring, tmp); amdgpu_ring_write(ring, 0xFFFFF); tmp = PACKET0(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0); amdgpu_ring_write(ring, tmp); amdgpu_ring_write(ring, 0xFFFFF); /* Clear timeout status bits */ amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_TIMEOUT_STATUS, 0)); amdgpu_ring_write(ring, 0x8); amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0)); amdgpu_ring_write(ring, 3); amdgpu_ring_commit(ring); done: /* lower clocks again */ amdgpu_asic_set_uvd_clocks(adev, 0, 0); if (!r) DRM_INFO("UVD initialized successfully.\n"); return r; }
/** * uvd_v5_0_hw_init - start and test UVD block * * @adev: amdgpu_device pointer * * Initialize the hardware, boot up the VCPU and do some testing */ static int uvd_v5_0_hw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_ring *ring = &adev->uvd.ring; uint32_t tmp; int r; amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); uvd_v5_0_enable_mgcg(adev, true); ring->ready = true; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; goto done; } r = amdgpu_ring_alloc(ring, 10); if (r) { DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); goto done; } tmp = PACKET0(mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0); amdgpu_ring_write(ring, tmp); amdgpu_ring_write(ring, 0xFFFFF); tmp = PACKET0(mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0); amdgpu_ring_write(ring, tmp); amdgpu_ring_write(ring, 0xFFFFF); tmp = PACKET0(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0); amdgpu_ring_write(ring, tmp); amdgpu_ring_write(ring, 0xFFFFF); /* Clear timeout status bits */ amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_TIMEOUT_STATUS, 0)); amdgpu_ring_write(ring, 0x8); amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0)); amdgpu_ring_write(ring, 3); amdgpu_ring_commit(ring); done: if (!r) DRM_INFO("UVD initialized successfully.\n"); return r; }
/** * cik_sdma_gfx_resume - setup and start the async dma engines * * @adev: amdgpu_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 amdgpu_device *adev) { struct amdgpu_ring *ring; u32 rb_cntl, ib_cntl; u32 rb_bufsz; u32 wb_offset; int i, j, r; for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; wb_offset = (ring->rptr_offs * 4); mutex_lock(&adev->srbm_mutex); for (j = 0; j < 16; j++) { cik_srbm_select(adev, 0, 0, 0, j); /* SDMA GFX */ WREG32(mmSDMA0_GFX_VIRTUAL_ADDR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_APE1_CNTL + sdma_offsets[i], 0); /* XXX SDMA RLC - todo */ } cik_srbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i], adev->gfx.config.gb_addr_config & 0x70); WREG32(mmSDMA0_SEM_INCOMPLETE_TIMER_CNTL + sdma_offsets[i], 0); WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 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 |= SDMA0_GFX_RB_CNTL__RB_SWAP_ENABLE_MASK | SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_SWAP_ENABLE_MASK; #endif WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); /* set the wb address whether it's enabled or not */ WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_LO + sdma_offsets[i], ((adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC)); rb_cntl |= SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_ENABLE_MASK; WREG32(mmSDMA0_GFX_RB_BASE + sdma_offsets[i], ring->gpu_addr >> 8); WREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i], ring->gpu_addr >> 40); ring->wptr = 0; WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], lower_32_bits(ring->wptr) << 2); /* enable DMA RB */ WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl | SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK); ib_cntl = SDMA0_GFX_IB_CNTL__IB_ENABLE_MASK; #ifdef __BIG_ENDIAN ib_cntl |= SDMA0_GFX_IB_CNTL__IB_SWAP_ENABLE_MASK; #endif /* enable DMA IBs */ WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); ring->ready = true; } cik_sdma_enable(adev, true); for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; return r; } if (adev->mman.buffer_funcs_ring == ring) amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size); } return 0; }
static int si_dma_start(struct amdgpu_device *adev) { struct amdgpu_ring *ring; u32 rb_cntl, dma_cntl, ib_cntl, rb_bufsz; int i, r; uint64_t rptr_addr; for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + sdma_offsets[i], 0); WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 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 + sdma_offsets[i], rb_cntl); /* Initialize the ring buffer's read and write pointers */ WREG32(DMA_RB_RPTR + sdma_offsets[i], 0); WREG32(DMA_RB_WPTR + sdma_offsets[i], 0); rptr_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4); WREG32(DMA_RB_RPTR_ADDR_LO + sdma_offsets[i], lower_32_bits(rptr_addr)); WREG32(DMA_RB_RPTR_ADDR_HI + sdma_offsets[i], upper_32_bits(rptr_addr) & 0xFF); rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE; WREG32(DMA_RB_BASE + sdma_offsets[i], ring->gpu_addr >> 8); /* enable DMA IBs */ ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; #ifdef __BIG_ENDIAN ib_cntl |= DMA_IB_SWAP_ENABLE; #endif WREG32(DMA_IB_CNTL + sdma_offsets[i], ib_cntl); dma_cntl = RREG32(DMA_CNTL + sdma_offsets[i]); dma_cntl &= ~CTXEMPTY_INT_ENABLE; WREG32(DMA_CNTL + sdma_offsets[i], dma_cntl); ring->wptr = 0; WREG32(DMA_RB_WPTR + sdma_offsets[i], ring->wptr << 2); WREG32(DMA_RB_CNTL + sdma_offsets[i], rb_cntl | DMA_RB_ENABLE); ring->ready = true; r = amdgpu_ring_test_ring(ring); if (r) { ring->ready = false; return r; } if (adev->mman.buffer_funcs_ring == ring) amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size); } return 0; }