162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2013 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * All Rights Reserved. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 662306a36Sopenharmony_ci * copy of this software and associated documentation files (the 762306a36Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 862306a36Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 962306a36Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 1062306a36Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 1162306a36Sopenharmony_ci * the following conditions: 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1462306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1562306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1662306a36Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 1762306a36Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 1862306a36Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 1962306a36Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * The above copyright notice and this permission notice (including the 2262306a36Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 2362306a36Sopenharmony_ci * of the Software. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * Authors: Christian König <christian.koenig@amd.com> 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <linux/firmware.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include "radeon.h" 3162306a36Sopenharmony_ci#include "radeon_asic.h" 3262306a36Sopenharmony_ci#include "sid.h" 3362306a36Sopenharmony_ci#include "vce.h" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define VCE_V1_0_FW_SIZE (256 * 1024) 3662306a36Sopenharmony_ci#define VCE_V1_0_STACK_SIZE (64 * 1024) 3762306a36Sopenharmony_ci#define VCE_V1_0_DATA_SIZE (7808 * (RADEON_MAX_VCE_HANDLES + 1)) 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistruct vce_v1_0_fw_signature 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci int32_t off; 4262306a36Sopenharmony_ci uint32_t len; 4362306a36Sopenharmony_ci int32_t num; 4462306a36Sopenharmony_ci struct { 4562306a36Sopenharmony_ci uint32_t chip_id; 4662306a36Sopenharmony_ci uint32_t keyselect; 4762306a36Sopenharmony_ci uint32_t nonce[4]; 4862306a36Sopenharmony_ci uint32_t sigval[4]; 4962306a36Sopenharmony_ci } val[8]; 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/** 5362306a36Sopenharmony_ci * vce_v1_0_get_rptr - get read pointer 5462306a36Sopenharmony_ci * 5562306a36Sopenharmony_ci * @rdev: radeon_device pointer 5662306a36Sopenharmony_ci * @ring: radeon_ring pointer 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * Returns the current hardware read pointer 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ciuint32_t vce_v1_0_get_rptr(struct radeon_device *rdev, 6162306a36Sopenharmony_ci struct radeon_ring *ring) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci if (ring->idx == TN_RING_TYPE_VCE1_INDEX) 6462306a36Sopenharmony_ci return RREG32(VCE_RB_RPTR); 6562306a36Sopenharmony_ci else 6662306a36Sopenharmony_ci return RREG32(VCE_RB_RPTR2); 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/** 7062306a36Sopenharmony_ci * vce_v1_0_get_wptr - get write pointer 7162306a36Sopenharmony_ci * 7262306a36Sopenharmony_ci * @rdev: radeon_device pointer 7362306a36Sopenharmony_ci * @ring: radeon_ring pointer 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * Returns the current hardware write pointer 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ciuint32_t vce_v1_0_get_wptr(struct radeon_device *rdev, 7862306a36Sopenharmony_ci struct radeon_ring *ring) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci if (ring->idx == TN_RING_TYPE_VCE1_INDEX) 8162306a36Sopenharmony_ci return RREG32(VCE_RB_WPTR); 8262306a36Sopenharmony_ci else 8362306a36Sopenharmony_ci return RREG32(VCE_RB_WPTR2); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/** 8762306a36Sopenharmony_ci * vce_v1_0_set_wptr - set write pointer 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * @rdev: radeon_device pointer 9062306a36Sopenharmony_ci * @ring: radeon_ring pointer 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * Commits the write pointer to the hardware 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_civoid vce_v1_0_set_wptr(struct radeon_device *rdev, 9562306a36Sopenharmony_ci struct radeon_ring *ring) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci if (ring->idx == TN_RING_TYPE_VCE1_INDEX) 9862306a36Sopenharmony_ci WREG32(VCE_RB_WPTR, ring->wptr); 9962306a36Sopenharmony_ci else 10062306a36Sopenharmony_ci WREG32(VCE_RB_WPTR2, ring->wptr); 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_civoid vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci u32 tmp; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { 10862306a36Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_A); 10962306a36Sopenharmony_ci tmp |= CGC_DYN_CLOCK_MODE; 11062306a36Sopenharmony_ci WREG32(VCE_CLOCK_GATING_A, tmp); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci tmp = RREG32(VCE_UENC_CLOCK_GATING); 11362306a36Sopenharmony_ci tmp &= ~0x1ff000; 11462306a36Sopenharmony_ci tmp |= 0xff800000; 11562306a36Sopenharmony_ci WREG32(VCE_UENC_CLOCK_GATING, tmp); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); 11862306a36Sopenharmony_ci tmp &= ~0x3ff; 11962306a36Sopenharmony_ci WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); 12062306a36Sopenharmony_ci } else { 12162306a36Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_A); 12262306a36Sopenharmony_ci tmp &= ~CGC_DYN_CLOCK_MODE; 12362306a36Sopenharmony_ci WREG32(VCE_CLOCK_GATING_A, tmp); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci tmp = RREG32(VCE_UENC_CLOCK_GATING); 12662306a36Sopenharmony_ci tmp |= 0x1ff000; 12762306a36Sopenharmony_ci tmp &= ~0xff800000; 12862306a36Sopenharmony_ci WREG32(VCE_UENC_CLOCK_GATING, tmp); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); 13162306a36Sopenharmony_ci tmp |= 0x3ff; 13262306a36Sopenharmony_ci WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic void vce_v1_0_init_cg(struct radeon_device *rdev) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci u32 tmp; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_A); 14162306a36Sopenharmony_ci tmp |= CGC_DYN_CLOCK_MODE; 14262306a36Sopenharmony_ci WREG32(VCE_CLOCK_GATING_A, tmp); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_B); 14562306a36Sopenharmony_ci tmp |= 0x1e; 14662306a36Sopenharmony_ci tmp &= ~0xe100e1; 14762306a36Sopenharmony_ci WREG32(VCE_CLOCK_GATING_B, tmp); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci tmp = RREG32(VCE_UENC_CLOCK_GATING); 15062306a36Sopenharmony_ci tmp &= ~0xff9ff000; 15162306a36Sopenharmony_ci WREG32(VCE_UENC_CLOCK_GATING, tmp); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); 15462306a36Sopenharmony_ci tmp &= ~0x3ff; 15562306a36Sopenharmony_ci WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ciint vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci struct vce_v1_0_fw_signature *sign = (void*)rdev->vce_fw->data; 16162306a36Sopenharmony_ci uint32_t chip_id; 16262306a36Sopenharmony_ci int i; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci switch (rdev->family) { 16562306a36Sopenharmony_ci case CHIP_TAHITI: 16662306a36Sopenharmony_ci chip_id = 0x01000014; 16762306a36Sopenharmony_ci break; 16862306a36Sopenharmony_ci case CHIP_VERDE: 16962306a36Sopenharmony_ci chip_id = 0x01000015; 17062306a36Sopenharmony_ci break; 17162306a36Sopenharmony_ci case CHIP_PITCAIRN: 17262306a36Sopenharmony_ci chip_id = 0x01000016; 17362306a36Sopenharmony_ci break; 17462306a36Sopenharmony_ci case CHIP_ARUBA: 17562306a36Sopenharmony_ci chip_id = 0x01000017; 17662306a36Sopenharmony_ci break; 17762306a36Sopenharmony_ci default: 17862306a36Sopenharmony_ci return -EINVAL; 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci for (i = 0; i < le32_to_cpu(sign->num); ++i) { 18262306a36Sopenharmony_ci if (le32_to_cpu(sign->val[i].chip_id) == chip_id) 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci if (i == le32_to_cpu(sign->num)) 18762306a36Sopenharmony_ci return -EINVAL; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci data += (256 - 64) / 4; 19062306a36Sopenharmony_ci data[0] = sign->val[i].nonce[0]; 19162306a36Sopenharmony_ci data[1] = sign->val[i].nonce[1]; 19262306a36Sopenharmony_ci data[2] = sign->val[i].nonce[2]; 19362306a36Sopenharmony_ci data[3] = sign->val[i].nonce[3]; 19462306a36Sopenharmony_ci data[4] = cpu_to_le32(le32_to_cpu(sign->len) + 64); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci memset(&data[5], 0, 44); 19762306a36Sopenharmony_ci memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign)); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci data += (le32_to_cpu(sign->len) + 64) / 4; 20062306a36Sopenharmony_ci data[0] = sign->val[i].sigval[0]; 20162306a36Sopenharmony_ci data[1] = sign->val[i].sigval[1]; 20262306a36Sopenharmony_ci data[2] = sign->val[i].sigval[2]; 20362306a36Sopenharmony_ci data[3] = sign->val[i].sigval[3]; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci rdev->vce.keyselect = le32_to_cpu(sign->val[i].keyselect); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci return 0; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciunsigned vce_v1_0_bo_size(struct radeon_device *rdev) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci WARN_ON(VCE_V1_0_FW_SIZE < rdev->vce_fw->size); 21362306a36Sopenharmony_ci return VCE_V1_0_FW_SIZE + VCE_V1_0_STACK_SIZE + VCE_V1_0_DATA_SIZE; 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ciint vce_v1_0_resume(struct radeon_device *rdev) 21762306a36Sopenharmony_ci{ 21862306a36Sopenharmony_ci uint64_t addr = rdev->vce.gpu_addr; 21962306a36Sopenharmony_ci uint32_t size; 22062306a36Sopenharmony_ci int i; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16)); 22362306a36Sopenharmony_ci WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 22462306a36Sopenharmony_ci WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 22562306a36Sopenharmony_ci WREG32(VCE_CLOCK_GATING_B, 0); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci WREG32_P(VCE_LMI_FW_PERIODIC_CTRL, 0x4, ~0x4); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci WREG32(VCE_LMI_CTRL, 0x00398000); 23062306a36Sopenharmony_ci WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1); 23162306a36Sopenharmony_ci WREG32(VCE_LMI_SWAP_CNTL, 0); 23262306a36Sopenharmony_ci WREG32(VCE_LMI_SWAP_CNTL1, 0); 23362306a36Sopenharmony_ci WREG32(VCE_LMI_VM_CTRL, 0); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci WREG32(VCE_VCPU_SCRATCH7, RADEON_MAX_VCE_HANDLES); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci addr += 256; 23862306a36Sopenharmony_ci size = VCE_V1_0_FW_SIZE; 23962306a36Sopenharmony_ci WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff); 24062306a36Sopenharmony_ci WREG32(VCE_VCPU_CACHE_SIZE0, size); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci addr += size; 24362306a36Sopenharmony_ci size = VCE_V1_0_STACK_SIZE; 24462306a36Sopenharmony_ci WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff); 24562306a36Sopenharmony_ci WREG32(VCE_VCPU_CACHE_SIZE1, size); 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci addr += size; 24862306a36Sopenharmony_ci size = VCE_V1_0_DATA_SIZE; 24962306a36Sopenharmony_ci WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff); 25062306a36Sopenharmony_ci WREG32(VCE_VCPU_CACHE_SIZE2, size); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci WREG32(VCE_LMI_FW_START_KEYSEL, rdev->vce.keyselect); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci for (i = 0; i < 10; ++i) { 25762306a36Sopenharmony_ci mdelay(10); 25862306a36Sopenharmony_ci if (RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_DONE) 25962306a36Sopenharmony_ci break; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci if (i == 10) 26362306a36Sopenharmony_ci return -ETIMEDOUT; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_PASS)) 26662306a36Sopenharmony_ci return -EINVAL; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci for (i = 0; i < 10; ++i) { 26962306a36Sopenharmony_ci mdelay(10); 27062306a36Sopenharmony_ci if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_BUSY)) 27162306a36Sopenharmony_ci break; 27262306a36Sopenharmony_ci } 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci if (i == 10) 27562306a36Sopenharmony_ci return -ETIMEDOUT; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci vce_v1_0_init_cg(rdev); 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci return 0; 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci/** 28362306a36Sopenharmony_ci * vce_v1_0_start - start VCE block 28462306a36Sopenharmony_ci * 28562306a36Sopenharmony_ci * @rdev: radeon_device pointer 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * Setup and start the VCE block 28862306a36Sopenharmony_ci */ 28962306a36Sopenharmony_ciint vce_v1_0_start(struct radeon_device *rdev) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci struct radeon_ring *ring; 29262306a36Sopenharmony_ci int i, j, r; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* set BUSY flag */ 29562306a36Sopenharmony_ci WREG32_P(VCE_STATUS, 1, ~1); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; 29862306a36Sopenharmony_ci WREG32(VCE_RB_RPTR, ring->wptr); 29962306a36Sopenharmony_ci WREG32(VCE_RB_WPTR, ring->wptr); 30062306a36Sopenharmony_ci WREG32(VCE_RB_BASE_LO, ring->gpu_addr); 30162306a36Sopenharmony_ci WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 30262306a36Sopenharmony_ci WREG32(VCE_RB_SIZE, ring->ring_size / 4); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; 30562306a36Sopenharmony_ci WREG32(VCE_RB_RPTR2, ring->wptr); 30662306a36Sopenharmony_ci WREG32(VCE_RB_WPTR2, ring->wptr); 30762306a36Sopenharmony_ci WREG32(VCE_RB_BASE_LO2, ring->gpu_addr); 30862306a36Sopenharmony_ci WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 30962306a36Sopenharmony_ci WREG32(VCE_RB_SIZE2, ring->ring_size / 4); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN); 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, 31462306a36Sopenharmony_ci VCE_ECPU_SOFT_RESET | 31562306a36Sopenharmony_ci VCE_FME_SOFT_RESET, ~( 31662306a36Sopenharmony_ci VCE_ECPU_SOFT_RESET | 31762306a36Sopenharmony_ci VCE_FME_SOFT_RESET)); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci mdelay(100); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, 0, ~( 32262306a36Sopenharmony_ci VCE_ECPU_SOFT_RESET | 32362306a36Sopenharmony_ci VCE_FME_SOFT_RESET)); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci for (i = 0; i < 10; ++i) { 32662306a36Sopenharmony_ci uint32_t status; 32762306a36Sopenharmony_ci for (j = 0; j < 100; ++j) { 32862306a36Sopenharmony_ci status = RREG32(VCE_STATUS); 32962306a36Sopenharmony_ci if (status & 2) 33062306a36Sopenharmony_ci break; 33162306a36Sopenharmony_ci mdelay(10); 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci r = 0; 33462306a36Sopenharmony_ci if (status & 2) 33562306a36Sopenharmony_ci break; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); 33862306a36Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET); 33962306a36Sopenharmony_ci mdelay(10); 34062306a36Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET); 34162306a36Sopenharmony_ci mdelay(10); 34262306a36Sopenharmony_ci r = -1; 34362306a36Sopenharmony_ci } 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci /* clear BUSY flag */ 34662306a36Sopenharmony_ci WREG32_P(VCE_STATUS, 0, ~1); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (r) { 34962306a36Sopenharmony_ci DRM_ERROR("VCE not responding, giving up!!!\n"); 35062306a36Sopenharmony_ci return r; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci return 0; 35462306a36Sopenharmony_ci} 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ciint vce_v1_0_init(struct radeon_device *rdev) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci struct radeon_ring *ring; 35962306a36Sopenharmony_ci int r; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci r = vce_v1_0_start(rdev); 36262306a36Sopenharmony_ci if (r) 36362306a36Sopenharmony_ci return r; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; 36662306a36Sopenharmony_ci ring->ready = true; 36762306a36Sopenharmony_ci r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring); 36862306a36Sopenharmony_ci if (r) { 36962306a36Sopenharmony_ci ring->ready = false; 37062306a36Sopenharmony_ci return r; 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; 37462306a36Sopenharmony_ci ring->ready = true; 37562306a36Sopenharmony_ci r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring); 37662306a36Sopenharmony_ci if (r) { 37762306a36Sopenharmony_ci ring->ready = false; 37862306a36Sopenharmony_ci return r; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci DRM_INFO("VCE initialized successfully.\n"); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci return 0; 38462306a36Sopenharmony_ci} 385