/** * 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; }
static int uvd_v5_0_soft_reset(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; uvd_v5_0_stop(adev); WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK, ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK); mdelay(5); return uvd_v5_0_start(adev); }
static int uvd_v5_0_set_powergating_state(void *handle, enum amd_powergating_state state) { /* This doesn't actually powergate the UVD block. * That's done in the dpm code via the SMC. This * just re-inits the block as necessary. The actual * gating still happens in the dpm code. We should * revisit this when there is a cleaner line between * the smc and the hw blocks */ struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) return 0; if (state == AMD_PG_STATE_GATE) { uvd_v5_0_stop(adev); return 0; } else { return uvd_v5_0_start(adev); } }