1*4cd92098Szrj /* 2*4cd92098Szrj * Copyright 2013 Advanced Micro Devices, Inc. 3*4cd92098Szrj * 4*4cd92098Szrj * Permission is hereby granted, free of charge, to any person obtaining a 5*4cd92098Szrj * copy of this software and associated documentation files (the "Software"), 6*4cd92098Szrj * to deal in the Software without restriction, including without limitation 7*4cd92098Szrj * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*4cd92098Szrj * and/or sell copies of the Software, and to permit persons to whom the 9*4cd92098Szrj * Software is furnished to do so, subject to the following conditions: 10*4cd92098Szrj * 11*4cd92098Szrj * The above copyright notice and this permission notice shall be included in 12*4cd92098Szrj * all copies or substantial portions of the Software. 13*4cd92098Szrj * 14*4cd92098Szrj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*4cd92098Szrj * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*4cd92098Szrj * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*4cd92098Szrj * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*4cd92098Szrj * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*4cd92098Szrj * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*4cd92098Szrj * OTHER DEALINGS IN THE SOFTWARE. 21*4cd92098Szrj * 22*4cd92098Szrj * Authors: Christian König <christian.koenig@amd.com> 23*4cd92098Szrj */ 24*4cd92098Szrj 25*4cd92098Szrj #include <linux/firmware.h> 26*4cd92098Szrj #include <drm/drmP.h> 27*4cd92098Szrj #include "radeon.h" 28*4cd92098Szrj #include "radeon_asic.h" 29*4cd92098Szrj #include "rv770d.h" 30*4cd92098Szrj 31*4cd92098Szrj /** 32*4cd92098Szrj * uvd_v2_2_fence_emit - emit an fence & trap command 33*4cd92098Szrj * 34*4cd92098Szrj * @rdev: radeon_device pointer 35*4cd92098Szrj * @fence: fence to emit 36*4cd92098Szrj * 37*4cd92098Szrj * Write a fence and a trap command to the ring. 38*4cd92098Szrj */ 39*4cd92098Szrj void uvd_v2_2_fence_emit(struct radeon_device *rdev, 40*4cd92098Szrj struct radeon_fence *fence) 41*4cd92098Szrj { 42*4cd92098Szrj struct radeon_ring *ring = &rdev->ring[fence->ring]; 43*4cd92098Szrj uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr; 44*4cd92098Szrj 45*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0)); 46*4cd92098Szrj radeon_ring_write(ring, fence->seq); 47*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0)); 48*4cd92098Szrj radeon_ring_write(ring, addr & 0xffffffff); 49*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0)); 50*4cd92098Szrj radeon_ring_write(ring, upper_32_bits(addr) & 0xff); 51*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); 52*4cd92098Szrj radeon_ring_write(ring, 0); 53*4cd92098Szrj 54*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0)); 55*4cd92098Szrj radeon_ring_write(ring, 0); 56*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0)); 57*4cd92098Szrj radeon_ring_write(ring, 0); 58*4cd92098Szrj radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); 59*4cd92098Szrj radeon_ring_write(ring, 2); 60*4cd92098Szrj return; 61*4cd92098Szrj } 62*4cd92098Szrj 63*4cd92098Szrj /** 64*4cd92098Szrj * uvd_v2_2_resume - memory controller programming 65*4cd92098Szrj * 66*4cd92098Szrj * @rdev: radeon_device pointer 67*4cd92098Szrj * 68*4cd92098Szrj * Let the UVD memory controller know it's offsets 69*4cd92098Szrj */ 70*4cd92098Szrj int uvd_v2_2_resume(struct radeon_device *rdev) 71*4cd92098Szrj { 72*4cd92098Szrj uint64_t addr; 73*4cd92098Szrj uint32_t chip_id, size; 74*4cd92098Szrj int r; 75*4cd92098Szrj 76*4cd92098Szrj r = radeon_uvd_resume(rdev); 77*4cd92098Szrj if (r) 78*4cd92098Szrj return r; 79*4cd92098Szrj 80*4cd92098Szrj /* programm the VCPU memory controller bits 0-27 */ 81*4cd92098Szrj addr = rdev->uvd.gpu_addr >> 3; 82*4cd92098Szrj size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->datasize + 4) >> 3; 83*4cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET0, addr); 84*4cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE0, size); 85*4cd92098Szrj 86*4cd92098Szrj addr += size; 87*4cd92098Szrj size = RADEON_UVD_STACK_SIZE >> 3; 88*4cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET1, addr); 89*4cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE1, size); 90*4cd92098Szrj 91*4cd92098Szrj addr += size; 92*4cd92098Szrj size = RADEON_UVD_HEAP_SIZE >> 3; 93*4cd92098Szrj WREG32(UVD_VCPU_CACHE_OFFSET2, addr); 94*4cd92098Szrj WREG32(UVD_VCPU_CACHE_SIZE2, size); 95*4cd92098Szrj 96*4cd92098Szrj /* bits 28-31 */ 97*4cd92098Szrj addr = (rdev->uvd.gpu_addr >> 28) & 0xF; 98*4cd92098Szrj WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); 99*4cd92098Szrj 100*4cd92098Szrj /* bits 32-39 */ 101*4cd92098Szrj addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; 102*4cd92098Szrj WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); 103*4cd92098Szrj 104*4cd92098Szrj /* tell firmware which hardware it is running on */ 105*4cd92098Szrj switch (rdev->family) { 106*4cd92098Szrj default: 107*4cd92098Szrj return -EINVAL; 108*4cd92098Szrj case CHIP_RV710: 109*4cd92098Szrj chip_id = 0x01000005; 110*4cd92098Szrj break; 111*4cd92098Szrj case CHIP_RV730: 112*4cd92098Szrj chip_id = 0x01000006; 113*4cd92098Szrj break; 114*4cd92098Szrj case CHIP_RV740: 115*4cd92098Szrj chip_id = 0x01000007; 116*4cd92098Szrj break; 117*4cd92098Szrj case CHIP_CYPRESS: 118*4cd92098Szrj case CHIP_HEMLOCK: 119*4cd92098Szrj chip_id = 0x01000008; 120*4cd92098Szrj break; 121*4cd92098Szrj case CHIP_JUNIPER: 122*4cd92098Szrj chip_id = 0x01000009; 123*4cd92098Szrj break; 124*4cd92098Szrj case CHIP_REDWOOD: 125*4cd92098Szrj chip_id = 0x0100000a; 126*4cd92098Szrj break; 127*4cd92098Szrj case CHIP_CEDAR: 128*4cd92098Szrj chip_id = 0x0100000b; 129*4cd92098Szrj break; 130*4cd92098Szrj case CHIP_SUMO: 131*4cd92098Szrj case CHIP_SUMO2: 132*4cd92098Szrj chip_id = 0x0100000c; 133*4cd92098Szrj break; 134*4cd92098Szrj case CHIP_PALM: 135*4cd92098Szrj chip_id = 0x0100000e; 136*4cd92098Szrj break; 137*4cd92098Szrj case CHIP_CAYMAN: 138*4cd92098Szrj chip_id = 0x0100000f; 139*4cd92098Szrj break; 140*4cd92098Szrj case CHIP_BARTS: 141*4cd92098Szrj chip_id = 0x01000010; 142*4cd92098Szrj break; 143*4cd92098Szrj case CHIP_TURKS: 144*4cd92098Szrj chip_id = 0x01000011; 145*4cd92098Szrj break; 146*4cd92098Szrj case CHIP_CAICOS: 147*4cd92098Szrj chip_id = 0x01000012; 148*4cd92098Szrj break; 149*4cd92098Szrj case CHIP_TAHITI: 150*4cd92098Szrj chip_id = 0x01000014; 151*4cd92098Szrj break; 152*4cd92098Szrj case CHIP_VERDE: 153*4cd92098Szrj chip_id = 0x01000015; 154*4cd92098Szrj break; 155*4cd92098Szrj case CHIP_PITCAIRN: 156*4cd92098Szrj chip_id = 0x01000016; 157*4cd92098Szrj break; 158*4cd92098Szrj case CHIP_ARUBA: 159*4cd92098Szrj chip_id = 0x01000017; 160*4cd92098Szrj break; 161*4cd92098Szrj } 162*4cd92098Szrj WREG32(UVD_VCPU_CHIP_ID, chip_id); 163*4cd92098Szrj 164*4cd92098Szrj return 0; 165*4cd92098Szrj } 166