18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2013 Advanced Micro Devices, Inc. 38c2ecf20Sopenharmony_ci * All Rights Reserved. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 68c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the 78c2ecf20Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 88c2ecf20Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 98c2ecf20Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 108c2ecf20Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 118c2ecf20Sopenharmony_ci * the following conditions: 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 148c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 158c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 168c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 178c2ecf20Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 188c2ecf20Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 198c2ecf20Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the 228c2ecf20Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 238c2ecf20Sopenharmony_ci * of the Software. 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * Authors: Christian König <christian.koenig@amd.com> 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include <linux/firmware.h> 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#include "radeon.h" 318c2ecf20Sopenharmony_ci#include "radeon_asic.h" 328c2ecf20Sopenharmony_ci#include "sid.h" 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define VCE_V1_0_FW_SIZE (256 * 1024) 358c2ecf20Sopenharmony_ci#define VCE_V1_0_STACK_SIZE (64 * 1024) 368c2ecf20Sopenharmony_ci#define VCE_V1_0_DATA_SIZE (7808 * (RADEON_MAX_VCE_HANDLES + 1)) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistruct vce_v1_0_fw_signature 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci int32_t off; 418c2ecf20Sopenharmony_ci uint32_t len; 428c2ecf20Sopenharmony_ci int32_t num; 438c2ecf20Sopenharmony_ci struct { 448c2ecf20Sopenharmony_ci uint32_t chip_id; 458c2ecf20Sopenharmony_ci uint32_t keyselect; 468c2ecf20Sopenharmony_ci uint32_t nonce[4]; 478c2ecf20Sopenharmony_ci uint32_t sigval[4]; 488c2ecf20Sopenharmony_ci } val[8]; 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/** 528c2ecf20Sopenharmony_ci * vce_v1_0_get_rptr - get read pointer 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer 558c2ecf20Sopenharmony_ci * @ring: radeon_ring pointer 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * Returns the current hardware read pointer 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_ciuint32_t vce_v1_0_get_rptr(struct radeon_device *rdev, 608c2ecf20Sopenharmony_ci struct radeon_ring *ring) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci if (ring->idx == TN_RING_TYPE_VCE1_INDEX) 638c2ecf20Sopenharmony_ci return RREG32(VCE_RB_RPTR); 648c2ecf20Sopenharmony_ci else 658c2ecf20Sopenharmony_ci return RREG32(VCE_RB_RPTR2); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/** 698c2ecf20Sopenharmony_ci * vce_v1_0_get_wptr - get write pointer 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer 728c2ecf20Sopenharmony_ci * @ring: radeon_ring pointer 738c2ecf20Sopenharmony_ci * 748c2ecf20Sopenharmony_ci * Returns the current hardware write pointer 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ciuint32_t vce_v1_0_get_wptr(struct radeon_device *rdev, 778c2ecf20Sopenharmony_ci struct radeon_ring *ring) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci if (ring->idx == TN_RING_TYPE_VCE1_INDEX) 808c2ecf20Sopenharmony_ci return RREG32(VCE_RB_WPTR); 818c2ecf20Sopenharmony_ci else 828c2ecf20Sopenharmony_ci return RREG32(VCE_RB_WPTR2); 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/** 868c2ecf20Sopenharmony_ci * vce_v1_0_set_wptr - set write pointer 878c2ecf20Sopenharmony_ci * 888c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer 898c2ecf20Sopenharmony_ci * @ring: radeon_ring pointer 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * Commits the write pointer to the hardware 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_civoid vce_v1_0_set_wptr(struct radeon_device *rdev, 948c2ecf20Sopenharmony_ci struct radeon_ring *ring) 958c2ecf20Sopenharmony_ci{ 968c2ecf20Sopenharmony_ci if (ring->idx == TN_RING_TYPE_VCE1_INDEX) 978c2ecf20Sopenharmony_ci WREG32(VCE_RB_WPTR, ring->wptr); 988c2ecf20Sopenharmony_ci else 998c2ecf20Sopenharmony_ci WREG32(VCE_RB_WPTR2, ring->wptr); 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_civoid vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci u32 tmp; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { 1078c2ecf20Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_A); 1088c2ecf20Sopenharmony_ci tmp |= CGC_DYN_CLOCK_MODE; 1098c2ecf20Sopenharmony_ci WREG32(VCE_CLOCK_GATING_A, tmp); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci tmp = RREG32(VCE_UENC_CLOCK_GATING); 1128c2ecf20Sopenharmony_ci tmp &= ~0x1ff000; 1138c2ecf20Sopenharmony_ci tmp |= 0xff800000; 1148c2ecf20Sopenharmony_ci WREG32(VCE_UENC_CLOCK_GATING, tmp); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); 1178c2ecf20Sopenharmony_ci tmp &= ~0x3ff; 1188c2ecf20Sopenharmony_ci WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); 1198c2ecf20Sopenharmony_ci } else { 1208c2ecf20Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_A); 1218c2ecf20Sopenharmony_ci tmp &= ~CGC_DYN_CLOCK_MODE; 1228c2ecf20Sopenharmony_ci WREG32(VCE_CLOCK_GATING_A, tmp); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci tmp = RREG32(VCE_UENC_CLOCK_GATING); 1258c2ecf20Sopenharmony_ci tmp |= 0x1ff000; 1268c2ecf20Sopenharmony_ci tmp &= ~0xff800000; 1278c2ecf20Sopenharmony_ci WREG32(VCE_UENC_CLOCK_GATING, tmp); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); 1308c2ecf20Sopenharmony_ci tmp |= 0x3ff; 1318c2ecf20Sopenharmony_ci WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci} 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistatic void vce_v1_0_init_cg(struct radeon_device *rdev) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci u32 tmp; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_A); 1408c2ecf20Sopenharmony_ci tmp |= CGC_DYN_CLOCK_MODE; 1418c2ecf20Sopenharmony_ci WREG32(VCE_CLOCK_GATING_A, tmp); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci tmp = RREG32(VCE_CLOCK_GATING_B); 1448c2ecf20Sopenharmony_ci tmp |= 0x1e; 1458c2ecf20Sopenharmony_ci tmp &= ~0xe100e1; 1468c2ecf20Sopenharmony_ci WREG32(VCE_CLOCK_GATING_B, tmp); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci tmp = RREG32(VCE_UENC_CLOCK_GATING); 1498c2ecf20Sopenharmony_ci tmp &= ~0xff9ff000; 1508c2ecf20Sopenharmony_ci WREG32(VCE_UENC_CLOCK_GATING, tmp); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); 1538c2ecf20Sopenharmony_ci tmp &= ~0x3ff; 1548c2ecf20Sopenharmony_ci WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ciint vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci struct vce_v1_0_fw_signature *sign = (void*)rdev->vce_fw->data; 1608c2ecf20Sopenharmony_ci uint32_t chip_id; 1618c2ecf20Sopenharmony_ci int i; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci switch (rdev->family) { 1648c2ecf20Sopenharmony_ci case CHIP_TAHITI: 1658c2ecf20Sopenharmony_ci chip_id = 0x01000014; 1668c2ecf20Sopenharmony_ci break; 1678c2ecf20Sopenharmony_ci case CHIP_VERDE: 1688c2ecf20Sopenharmony_ci chip_id = 0x01000015; 1698c2ecf20Sopenharmony_ci break; 1708c2ecf20Sopenharmony_ci case CHIP_PITCAIRN: 1718c2ecf20Sopenharmony_ci chip_id = 0x01000016; 1728c2ecf20Sopenharmony_ci break; 1738c2ecf20Sopenharmony_ci case CHIP_ARUBA: 1748c2ecf20Sopenharmony_ci chip_id = 0x01000017; 1758c2ecf20Sopenharmony_ci break; 1768c2ecf20Sopenharmony_ci default: 1778c2ecf20Sopenharmony_ci return -EINVAL; 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci for (i = 0; i < le32_to_cpu(sign->num); ++i) { 1818c2ecf20Sopenharmony_ci if (le32_to_cpu(sign->val[i].chip_id) == chip_id) 1828c2ecf20Sopenharmony_ci break; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci if (i == le32_to_cpu(sign->num)) 1868c2ecf20Sopenharmony_ci return -EINVAL; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci data += (256 - 64) / 4; 1898c2ecf20Sopenharmony_ci data[0] = sign->val[i].nonce[0]; 1908c2ecf20Sopenharmony_ci data[1] = sign->val[i].nonce[1]; 1918c2ecf20Sopenharmony_ci data[2] = sign->val[i].nonce[2]; 1928c2ecf20Sopenharmony_ci data[3] = sign->val[i].nonce[3]; 1938c2ecf20Sopenharmony_ci data[4] = cpu_to_le32(le32_to_cpu(sign->len) + 64); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci memset(&data[5], 0, 44); 1968c2ecf20Sopenharmony_ci memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign)); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci data += (le32_to_cpu(sign->len) + 64) / 4; 1998c2ecf20Sopenharmony_ci data[0] = sign->val[i].sigval[0]; 2008c2ecf20Sopenharmony_ci data[1] = sign->val[i].sigval[1]; 2018c2ecf20Sopenharmony_ci data[2] = sign->val[i].sigval[2]; 2028c2ecf20Sopenharmony_ci data[3] = sign->val[i].sigval[3]; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci rdev->vce.keyselect = le32_to_cpu(sign->val[i].keyselect); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci return 0; 2078c2ecf20Sopenharmony_ci} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ciunsigned vce_v1_0_bo_size(struct radeon_device *rdev) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci WARN_ON(VCE_V1_0_FW_SIZE < rdev->vce_fw->size); 2128c2ecf20Sopenharmony_ci return VCE_V1_0_FW_SIZE + VCE_V1_0_STACK_SIZE + VCE_V1_0_DATA_SIZE; 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ciint vce_v1_0_resume(struct radeon_device *rdev) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci uint64_t addr = rdev->vce.gpu_addr; 2188c2ecf20Sopenharmony_ci uint32_t size; 2198c2ecf20Sopenharmony_ci int i; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16)); 2228c2ecf20Sopenharmony_ci WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 2238c2ecf20Sopenharmony_ci WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 2248c2ecf20Sopenharmony_ci WREG32(VCE_CLOCK_GATING_B, 0); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci WREG32_P(VCE_LMI_FW_PERIODIC_CTRL, 0x4, ~0x4); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci WREG32(VCE_LMI_CTRL, 0x00398000); 2298c2ecf20Sopenharmony_ci WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1); 2308c2ecf20Sopenharmony_ci WREG32(VCE_LMI_SWAP_CNTL, 0); 2318c2ecf20Sopenharmony_ci WREG32(VCE_LMI_SWAP_CNTL1, 0); 2328c2ecf20Sopenharmony_ci WREG32(VCE_LMI_VM_CTRL, 0); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_SCRATCH7, RADEON_MAX_VCE_HANDLES); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci addr += 256; 2378c2ecf20Sopenharmony_ci size = VCE_V1_0_FW_SIZE; 2388c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff); 2398c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_CACHE_SIZE0, size); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci addr += size; 2428c2ecf20Sopenharmony_ci size = VCE_V1_0_STACK_SIZE; 2438c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff); 2448c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_CACHE_SIZE1, size); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci addr += size; 2478c2ecf20Sopenharmony_ci size = VCE_V1_0_DATA_SIZE; 2488c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff); 2498c2ecf20Sopenharmony_ci WREG32(VCE_VCPU_CACHE_SIZE2, size); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci WREG32(VCE_LMI_FW_START_KEYSEL, rdev->vce.keyselect); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci for (i = 0; i < 10; ++i) { 2568c2ecf20Sopenharmony_ci mdelay(10); 2578c2ecf20Sopenharmony_ci if (RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_DONE) 2588c2ecf20Sopenharmony_ci break; 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci if (i == 10) 2628c2ecf20Sopenharmony_ci return -ETIMEDOUT; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_PASS)) 2658c2ecf20Sopenharmony_ci return -EINVAL; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci for (i = 0; i < 10; ++i) { 2688c2ecf20Sopenharmony_ci mdelay(10); 2698c2ecf20Sopenharmony_ci if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_BUSY)) 2708c2ecf20Sopenharmony_ci break; 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci if (i == 10) 2748c2ecf20Sopenharmony_ci return -ETIMEDOUT; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci vce_v1_0_init_cg(rdev); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci return 0; 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci/** 2828c2ecf20Sopenharmony_ci * vce_v1_0_start - start VCE block 2838c2ecf20Sopenharmony_ci * 2848c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer 2858c2ecf20Sopenharmony_ci * 2868c2ecf20Sopenharmony_ci * Setup and start the VCE block 2878c2ecf20Sopenharmony_ci */ 2888c2ecf20Sopenharmony_ciint vce_v1_0_start(struct radeon_device *rdev) 2898c2ecf20Sopenharmony_ci{ 2908c2ecf20Sopenharmony_ci struct radeon_ring *ring; 2918c2ecf20Sopenharmony_ci int i, j, r; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci /* set BUSY flag */ 2948c2ecf20Sopenharmony_ci WREG32_P(VCE_STATUS, 1, ~1); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; 2978c2ecf20Sopenharmony_ci WREG32(VCE_RB_RPTR, ring->wptr); 2988c2ecf20Sopenharmony_ci WREG32(VCE_RB_WPTR, ring->wptr); 2998c2ecf20Sopenharmony_ci WREG32(VCE_RB_BASE_LO, ring->gpu_addr); 3008c2ecf20Sopenharmony_ci WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 3018c2ecf20Sopenharmony_ci WREG32(VCE_RB_SIZE, ring->ring_size / 4); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; 3048c2ecf20Sopenharmony_ci WREG32(VCE_RB_RPTR2, ring->wptr); 3058c2ecf20Sopenharmony_ci WREG32(VCE_RB_WPTR2, ring->wptr); 3068c2ecf20Sopenharmony_ci WREG32(VCE_RB_BASE_LO2, ring->gpu_addr); 3078c2ecf20Sopenharmony_ci WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 3088c2ecf20Sopenharmony_ci WREG32(VCE_RB_SIZE2, ring->ring_size / 4); 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN); 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, 3138c2ecf20Sopenharmony_ci VCE_ECPU_SOFT_RESET | 3148c2ecf20Sopenharmony_ci VCE_FME_SOFT_RESET, ~( 3158c2ecf20Sopenharmony_ci VCE_ECPU_SOFT_RESET | 3168c2ecf20Sopenharmony_ci VCE_FME_SOFT_RESET)); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci mdelay(100); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, 0, ~( 3218c2ecf20Sopenharmony_ci VCE_ECPU_SOFT_RESET | 3228c2ecf20Sopenharmony_ci VCE_FME_SOFT_RESET)); 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci for (i = 0; i < 10; ++i) { 3258c2ecf20Sopenharmony_ci uint32_t status; 3268c2ecf20Sopenharmony_ci for (j = 0; j < 100; ++j) { 3278c2ecf20Sopenharmony_ci status = RREG32(VCE_STATUS); 3288c2ecf20Sopenharmony_ci if (status & 2) 3298c2ecf20Sopenharmony_ci break; 3308c2ecf20Sopenharmony_ci mdelay(10); 3318c2ecf20Sopenharmony_ci } 3328c2ecf20Sopenharmony_ci r = 0; 3338c2ecf20Sopenharmony_ci if (status & 2) 3348c2ecf20Sopenharmony_ci break; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); 3378c2ecf20Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET); 3388c2ecf20Sopenharmony_ci mdelay(10); 3398c2ecf20Sopenharmony_ci WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET); 3408c2ecf20Sopenharmony_ci mdelay(10); 3418c2ecf20Sopenharmony_ci r = -1; 3428c2ecf20Sopenharmony_ci } 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci /* clear BUSY flag */ 3458c2ecf20Sopenharmony_ci WREG32_P(VCE_STATUS, 0, ~1); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci if (r) { 3488c2ecf20Sopenharmony_ci DRM_ERROR("VCE not responding, giving up!!!\n"); 3498c2ecf20Sopenharmony_ci return r; 3508c2ecf20Sopenharmony_ci } 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci return 0; 3538c2ecf20Sopenharmony_ci} 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ciint vce_v1_0_init(struct radeon_device *rdev) 3568c2ecf20Sopenharmony_ci{ 3578c2ecf20Sopenharmony_ci struct radeon_ring *ring; 3588c2ecf20Sopenharmony_ci int r; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci r = vce_v1_0_start(rdev); 3618c2ecf20Sopenharmony_ci if (r) 3628c2ecf20Sopenharmony_ci return r; 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; 3658c2ecf20Sopenharmony_ci ring->ready = true; 3668c2ecf20Sopenharmony_ci r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring); 3678c2ecf20Sopenharmony_ci if (r) { 3688c2ecf20Sopenharmony_ci ring->ready = false; 3698c2ecf20Sopenharmony_ci return r; 3708c2ecf20Sopenharmony_ci } 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; 3738c2ecf20Sopenharmony_ci ring->ready = true; 3748c2ecf20Sopenharmony_ci r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring); 3758c2ecf20Sopenharmony_ci if (r) { 3768c2ecf20Sopenharmony_ci ring->ready = false; 3778c2ecf20Sopenharmony_ci return r; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci DRM_INFO("VCE initialized successfully.\n"); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci return 0; 3838c2ecf20Sopenharmony_ci} 384