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)); 48c6f73aabSFranç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 /** 63*c59a5c48SFrançois Tigeot * uvd_v2_2_semaphore_emit - emit semaphore command 64*c59a5c48SFrançois Tigeot * 65*c59a5c48SFrançois Tigeot * @rdev: radeon_device pointer 66*c59a5c48SFrançois Tigeot * @ring: radeon_ring pointer 67*c59a5c48SFrançois Tigeot * @semaphore: semaphore to emit commands for 68*c59a5c48SFrançois Tigeot * @emit_wait: true if we should emit a wait command 69*c59a5c48SFrançois Tigeot * 70*c59a5c48SFrançois Tigeot * Emit a semaphore command (either wait or signal) to the UVD ring. 71*c59a5c48SFrançois Tigeot */ 72*c59a5c48SFrançois Tigeot bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev, 73*c59a5c48SFrançois Tigeot struct radeon_ring *ring, 74*c59a5c48SFrançois Tigeot struct radeon_semaphore *semaphore, 75*c59a5c48SFrançois Tigeot bool emit_wait) 76*c59a5c48SFrançois Tigeot { 77*c59a5c48SFrançois Tigeot uint64_t addr = semaphore->gpu_addr; 78*c59a5c48SFrançois Tigeot 79*c59a5c48SFrançois Tigeot radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); 80*c59a5c48SFrançois Tigeot radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); 81*c59a5c48SFrançois Tigeot 82*c59a5c48SFrançois Tigeot radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); 83*c59a5c48SFrançois Tigeot radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); 84*c59a5c48SFrançois Tigeot 85*c59a5c48SFrançois Tigeot radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); 86*c59a5c48SFrançois Tigeot radeon_ring_write(ring, emit_wait ? 1 : 0); 87*c59a5c48SFrançois Tigeot 88*c59a5c48SFrançois Tigeot return true; 89*c59a5c48SFrançois Tigeot } 90*c59a5c48SFrançois Tigeot 91*c59a5c48SFrançois Tigeot /** 924cd92098Szrj * uvd_v2_2_resume - memory controller programming 934cd92098Szrj * 944cd92098Szrj * @rdev: radeon_device pointer 954cd92098Szrj * 964cd92098Szrj * Let the UVD memory controller know it's offsets 974cd92098Szrj */ 984cd92098Szrj int uvd_v2_2_resume(struct radeon_device *rdev) 994cd92098Szrj { 1004cd92098Szrj uint64_t addr; 1014cd92098Szrj uint32_t chip_id, size; 1024cd92098Szrj int r; 1034cd92098Szrj 104591d5043SFrançois Tigeot /* RV770 uses V1.0 MC */ 105591d5043SFrançois Tigeot if (rdev->family == CHIP_RV770) 106591d5043SFrançois Tigeot return uvd_v1_0_resume(rdev); 107591d5043SFrançois Tigeot 1084cd92098Szrj r = radeon_uvd_resume(rdev); 1094cd92098Szrj if (r) 1104cd92098Szrj return r; 1114cd92098Szrj 1124cd92098Szrj /* programm the VCPU memory controller bits 0-27 */ 1134cd92098Szrj addr = rdev->uvd.gpu_addr >> 3; 1144cd92098Szrj size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->datasize + 4) >> 3; 1154cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET0, addr); 1164cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE0, size); 1174cd92098Szrj 1184cd92098Szrj addr += size; 119ee479021SImre Vadász size = RADEON_UVD_STACK_SIZE >> 3; 1204cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET1, addr); 1214cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE1, size); 1224cd92098Szrj 1234cd92098Szrj addr += size; 124ee479021SImre Vadász size = RADEON_UVD_HEAP_SIZE >> 3; 1254cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET2, addr); 1264cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE2, size); 1274cd92098Szrj 1284cd92098Szrj /* bits 28-31 */ 1294cd92098Szrj addr = (rdev->uvd.gpu_addr >> 28) & 0xF; 1304cd92098Szrj WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); 1314cd92098Szrj 1324cd92098Szrj /* bits 32-39 */ 1334cd92098Szrj addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; 1344cd92098Szrj WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); 1354cd92098Szrj 1364cd92098Szrj /* tell firmware which hardware it is running on */ 1374cd92098Szrj switch (rdev->family) { 1384cd92098Szrj default: 1394cd92098Szrj return -EINVAL; 1404cd92098Szrj case CHIP_RV710: 1414cd92098Szrj chip_id = 0x01000005; 1424cd92098Szrj break; 1434cd92098Szrj case CHIP_RV730: 1444cd92098Szrj chip_id = 0x01000006; 1454cd92098Szrj break; 1464cd92098Szrj case CHIP_RV740: 1474cd92098Szrj chip_id = 0x01000007; 1484cd92098Szrj break; 1494cd92098Szrj case CHIP_CYPRESS: 1504cd92098Szrj case CHIP_HEMLOCK: 1514cd92098Szrj chip_id = 0x01000008; 1524cd92098Szrj break; 1534cd92098Szrj case CHIP_JUNIPER: 1544cd92098Szrj chip_id = 0x01000009; 1554cd92098Szrj break; 1564cd92098Szrj case CHIP_REDWOOD: 1574cd92098Szrj chip_id = 0x0100000a; 1584cd92098Szrj break; 1594cd92098Szrj case CHIP_CEDAR: 1604cd92098Szrj chip_id = 0x0100000b; 1614cd92098Szrj break; 1624cd92098Szrj case CHIP_SUMO: 1634cd92098Szrj case CHIP_SUMO2: 1644cd92098Szrj chip_id = 0x0100000c; 1654cd92098Szrj break; 1664cd92098Szrj case CHIP_PALM: 1674cd92098Szrj chip_id = 0x0100000e; 1684cd92098Szrj break; 1694cd92098Szrj case CHIP_CAYMAN: 1704cd92098Szrj chip_id = 0x0100000f; 1714cd92098Szrj break; 1724cd92098Szrj case CHIP_BARTS: 1734cd92098Szrj chip_id = 0x01000010; 1744cd92098Szrj break; 1754cd92098Szrj case CHIP_TURKS: 1764cd92098Szrj chip_id = 0x01000011; 1774cd92098Szrj break; 1784cd92098Szrj case CHIP_CAICOS: 1794cd92098Szrj chip_id = 0x01000012; 1804cd92098Szrj break; 1814cd92098Szrj case CHIP_TAHITI: 1824cd92098Szrj chip_id = 0x01000014; 1834cd92098Szrj break; 1844cd92098Szrj case CHIP_VERDE: 1854cd92098Szrj chip_id = 0x01000015; 1864cd92098Szrj break; 1874cd92098Szrj case CHIP_PITCAIRN: 188c6f73aabSFrançois Tigeot case CHIP_OLAND: 1894cd92098Szrj chip_id = 0x01000016; 1904cd92098Szrj break; 1914cd92098Szrj case CHIP_ARUBA: 1924cd92098Szrj chip_id = 0x01000017; 1934cd92098Szrj break; 1944cd92098Szrj } 1954cd92098Szrj WREG32(UVD_VCPU_CHIP_ID, chip_id); 1964cd92098Szrj 1974cd92098Szrj return 0; 1984cd92098Szrj } 199