14cd92098Szrj /* 24cd92098Szrj * Copyright 2013 Advanced Micro Devices, Inc. 34cd92098Szrj * 44cd92098Szrj * Permission is hereby granted, free of charge, to any person obtaining a 54cd92098Szrj * copy of this software and associated documentation files (the "Software"), 64cd92098Szrj * to deal in the Software without restriction, including without limitation 74cd92098Szrj * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84cd92098Szrj * and/or sell copies of the Software, and to permit persons to whom the 94cd92098Szrj * Software is furnished to do so, subject to the following conditions: 104cd92098Szrj * 114cd92098Szrj * The above copyright notice and this permission notice shall be included in 124cd92098Szrj * all copies or substantial portions of the Software. 134cd92098Szrj * 144cd92098Szrj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 154cd92098Szrj * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 164cd92098Szrj * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 174cd92098Szrj * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 184cd92098Szrj * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 194cd92098Szrj * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 204cd92098Szrj * OTHER DEALINGS IN THE SOFTWARE. 214cd92098Szrj * 224cd92098Szrj * Authors: Christian König <christian.koenig@amd.com> 234cd92098Szrj */ 244cd92098Szrj 254cd92098Szrj #include <linux/firmware.h> 264cd92098Szrj #include <drm/drmP.h> 274cd92098Szrj #include "radeon.h" 284cd92098Szrj #include "radeon_asic.h" 294cd92098Szrj #include "rv770d.h" 304cd92098Szrj 314cd92098Szrj /** 324cd92098Szrj * uvd_v2_2_fence_emit - emit an fence & trap command 334cd92098Szrj * 344cd92098Szrj * @rdev: radeon_device pointer 354cd92098Szrj * @fence: fence to emit 364cd92098Szrj * 374cd92098Szrj * Write a fence and a trap command to the ring. 384cd92098Szrj */ 394cd92098Szrj void uvd_v2_2_fence_emit(struct radeon_device *rdev, 404cd92098Szrj struct radeon_fence *fence) 414cd92098Szrj { 424cd92098Szrj struct radeon_ring *ring = &rdev->ring[fence->ring]; 434cd92098Szrj uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr; 444cd92098Szrj 454cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0)); 464cd92098Szrj radeon_ring_write(ring, fence->seq); 474cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0)); 48*c6f73aabSFrançois Tigeot radeon_ring_write(ring, lower_32_bits(addr)); 494cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0)); 504cd92098Szrj radeon_ring_write(ring, upper_32_bits(addr) & 0xff); 514cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); 524cd92098Szrj radeon_ring_write(ring, 0); 534cd92098Szrj 544cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0)); 554cd92098Szrj radeon_ring_write(ring, 0); 564cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0)); 574cd92098Szrj radeon_ring_write(ring, 0); 584cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); 594cd92098Szrj radeon_ring_write(ring, 2); 604cd92098Szrj } 614cd92098Szrj 624cd92098Szrj /** 634cd92098Szrj * uvd_v2_2_resume - memory controller programming 644cd92098Szrj * 654cd92098Szrj * @rdev: radeon_device pointer 664cd92098Szrj * 674cd92098Szrj * Let the UVD memory controller know it's offsets 684cd92098Szrj */ 694cd92098Szrj int uvd_v2_2_resume(struct radeon_device *rdev) 704cd92098Szrj { 714cd92098Szrj uint64_t addr; 724cd92098Szrj uint32_t chip_id, size; 734cd92098Szrj int r; 744cd92098Szrj 754cd92098Szrj r = radeon_uvd_resume(rdev); 764cd92098Szrj if (r) 774cd92098Szrj return r; 784cd92098Szrj 794cd92098Szrj /* programm the VCPU memory controller bits 0-27 */ 804cd92098Szrj addr = rdev->uvd.gpu_addr >> 3; 814cd92098Szrj size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->datasize + 4) >> 3; 824cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET0, addr); 834cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE0, size); 844cd92098Szrj 854cd92098Szrj addr += size; 864cd92098Szrj size = RADEON_UVD_STACK_SIZE >> 3; 874cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET1, addr); 884cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE1, size); 894cd92098Szrj 904cd92098Szrj addr += size; 914cd92098Szrj size = RADEON_UVD_HEAP_SIZE >> 3; 924cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET2, addr); 934cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE2, size); 944cd92098Szrj 954cd92098Szrj /* bits 28-31 */ 964cd92098Szrj addr = (rdev->uvd.gpu_addr >> 28) & 0xF; 974cd92098Szrj WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); 984cd92098Szrj 994cd92098Szrj /* bits 32-39 */ 1004cd92098Szrj addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; 1014cd92098Szrj WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); 1024cd92098Szrj 1034cd92098Szrj /* tell firmware which hardware it is running on */ 1044cd92098Szrj switch (rdev->family) { 1054cd92098Szrj default: 1064cd92098Szrj return -EINVAL; 1074cd92098Szrj case CHIP_RV710: 1084cd92098Szrj chip_id = 0x01000005; 1094cd92098Szrj break; 1104cd92098Szrj case CHIP_RV730: 1114cd92098Szrj chip_id = 0x01000006; 1124cd92098Szrj break; 1134cd92098Szrj case CHIP_RV740: 1144cd92098Szrj chip_id = 0x01000007; 1154cd92098Szrj break; 1164cd92098Szrj case CHIP_CYPRESS: 1174cd92098Szrj case CHIP_HEMLOCK: 1184cd92098Szrj chip_id = 0x01000008; 1194cd92098Szrj break; 1204cd92098Szrj case CHIP_JUNIPER: 1214cd92098Szrj chip_id = 0x01000009; 1224cd92098Szrj break; 1234cd92098Szrj case CHIP_REDWOOD: 1244cd92098Szrj chip_id = 0x0100000a; 1254cd92098Szrj break; 1264cd92098Szrj case CHIP_CEDAR: 1274cd92098Szrj chip_id = 0x0100000b; 1284cd92098Szrj break; 1294cd92098Szrj case CHIP_SUMO: 1304cd92098Szrj case CHIP_SUMO2: 1314cd92098Szrj chip_id = 0x0100000c; 1324cd92098Szrj break; 1334cd92098Szrj case CHIP_PALM: 1344cd92098Szrj chip_id = 0x0100000e; 1354cd92098Szrj break; 1364cd92098Szrj case CHIP_CAYMAN: 1374cd92098Szrj chip_id = 0x0100000f; 1384cd92098Szrj break; 1394cd92098Szrj case CHIP_BARTS: 1404cd92098Szrj chip_id = 0x01000010; 1414cd92098Szrj break; 1424cd92098Szrj case CHIP_TURKS: 1434cd92098Szrj chip_id = 0x01000011; 1444cd92098Szrj break; 1454cd92098Szrj case CHIP_CAICOS: 1464cd92098Szrj chip_id = 0x01000012; 1474cd92098Szrj break; 1484cd92098Szrj case CHIP_TAHITI: 1494cd92098Szrj chip_id = 0x01000014; 1504cd92098Szrj break; 1514cd92098Szrj case CHIP_VERDE: 1524cd92098Szrj chip_id = 0x01000015; 1534cd92098Szrj break; 1544cd92098Szrj case CHIP_PITCAIRN: 155*c6f73aabSFrançois Tigeot case CHIP_OLAND: 1564cd92098Szrj chip_id = 0x01000016; 1574cd92098Szrj break; 1584cd92098Szrj case CHIP_ARUBA: 1594cd92098Szrj chip_id = 0x01000017; 1604cd92098Szrj break; 1614cd92098Szrj } 1624cd92098Szrj WREG32(UVD_VCPU_CHIP_ID, chip_id); 1634cd92098Szrj 1644cd92098Szrj return 0; 1654cd92098Szrj } 166