brintos

brintos / linux-shallow public Read only

0
0
Text · 5.2 KiB · 163c9bf Raw
200 lines · c
1/*2 * Copyright 2013 Advanced Micro Devices, Inc.3 * All Rights Reserved.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the7 * "Software"), to deal in the Software without restriction, including8 * without limitation the rights to use, copy, modify, merge, publish,9 * distribute, sub license, and/or sell copies of the Software, and to10 * permit persons to whom the Software is furnished to do so, subject to11 * the following conditions:12 *13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE19 * USE OR OTHER DEALINGS IN THE SOFTWARE.20 *21 * The above copyright notice and this permission notice (including the22 * next paragraph) shall be included in all copies or substantial portions23 * of the Software.24 *25 * Authors: Christian König <christian.koenig@amd.com>26 */27 28#include <linux/firmware.h>29 30#include "radeon.h"31#include "radeon_asic.h"32#include "cikd.h"33#include "vce.h"34 35#define VCE_V2_0_FW_SIZE	(256 * 1024)36#define VCE_V2_0_STACK_SIZE	(64 * 1024)37#define VCE_V2_0_DATA_SIZE	(23552 * RADEON_MAX_VCE_HANDLES)38 39static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated)40{41	u32 tmp;42 43	if (gated) {44		tmp = RREG32(VCE_CLOCK_GATING_B);45		tmp |= 0xe70000;46		WREG32(VCE_CLOCK_GATING_B, tmp);47 48		tmp = RREG32(VCE_UENC_CLOCK_GATING);49		tmp |= 0xff000000;50		WREG32(VCE_UENC_CLOCK_GATING, tmp);51 52		tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);53		tmp &= ~0x3fc;54		WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);55 56		WREG32(VCE_CGTT_CLK_OVERRIDE, 0);57	} else {58		tmp = RREG32(VCE_CLOCK_GATING_B);59		tmp |= 0xe7;60		tmp &= ~0xe70000;61		WREG32(VCE_CLOCK_GATING_B, tmp);62 63		tmp = RREG32(VCE_UENC_CLOCK_GATING);64		tmp |= 0x1fe000;65		tmp &= ~0xff000000;66		WREG32(VCE_UENC_CLOCK_GATING, tmp);67 68		tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);69		tmp |= 0x3fc;70		WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);71	}72}73 74static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated)75{76	u32 orig, tmp;77 78	tmp = RREG32(VCE_CLOCK_GATING_B);79	tmp &= ~0x00060006;80	if (gated) {81		tmp |= 0xe10000;82	} else {83		tmp |= 0xe1;84		tmp &= ~0xe10000;85	}86	WREG32(VCE_CLOCK_GATING_B, tmp);87 88	orig = tmp = RREG32(VCE_UENC_CLOCK_GATING);89	tmp &= ~0x1fe000;90	tmp &= ~0xff000000;91	if (tmp != orig)92		WREG32(VCE_UENC_CLOCK_GATING, tmp);93 94	orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);95	tmp &= ~0x3fc;96	if (tmp != orig)97		WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);98 99	if (gated)100		WREG32(VCE_CGTT_CLK_OVERRIDE, 0);101}102 103static void vce_v2_0_disable_cg(struct radeon_device *rdev)104{105	WREG32(VCE_CGTT_CLK_OVERRIDE, 7);106}107 108/*109 * Local variable sw_cg is used for debugging purposes, in case we110 * ran into problems with dynamic clock gating. Don't remove it.111 */112void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable)113{114	bool sw_cg = false;115 116	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) {117		if (sw_cg)118			vce_v2_0_set_sw_cg(rdev, true);119		else120			vce_v2_0_set_dyn_cg(rdev, true);121	} else {122		vce_v2_0_disable_cg(rdev);123 124		if (sw_cg)125			vce_v2_0_set_sw_cg(rdev, false);126		else127			vce_v2_0_set_dyn_cg(rdev, false);128	}129}130 131static void vce_v2_0_init_cg(struct radeon_device *rdev)132{133	u32 tmp;134 135	tmp = RREG32(VCE_CLOCK_GATING_A);136	tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK);137	tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4));138	tmp |= CGC_UENC_WAIT_AWAKE;139	WREG32(VCE_CLOCK_GATING_A, tmp);140 141	tmp = RREG32(VCE_UENC_CLOCK_GATING);142	tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK);143	tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4));144	WREG32(VCE_UENC_CLOCK_GATING, tmp);145 146	tmp = RREG32(VCE_CLOCK_GATING_B);147	tmp |= 0x10;148	tmp &= ~0x100000;149	WREG32(VCE_CLOCK_GATING_B, tmp);150}151 152unsigned vce_v2_0_bo_size(struct radeon_device *rdev)153{154	WARN_ON(rdev->vce_fw->size > VCE_V2_0_FW_SIZE);155	return VCE_V2_0_FW_SIZE + VCE_V2_0_STACK_SIZE + VCE_V2_0_DATA_SIZE;156}157 158int vce_v2_0_resume(struct radeon_device *rdev)159{160	uint64_t addr = rdev->vce.gpu_addr;161	uint32_t size;162 163	WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16));164	WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);165	WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);166	WREG32(VCE_CLOCK_GATING_B, 0xf7);167 168	WREG32(VCE_LMI_CTRL, 0x00398000);169	WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1);170	WREG32(VCE_LMI_SWAP_CNTL, 0);171	WREG32(VCE_LMI_SWAP_CNTL1, 0);172	WREG32(VCE_LMI_VM_CTRL, 0);173 174	WREG32(VCE_LMI_VCPU_CACHE_40BIT_BAR, addr >> 8);175 176	addr &= 0xff;177	size = VCE_V2_0_FW_SIZE;178	WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);179	WREG32(VCE_VCPU_CACHE_SIZE0, size);180 181	addr += size;182	size = VCE_V2_0_STACK_SIZE;183	WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);184	WREG32(VCE_VCPU_CACHE_SIZE1, size);185 186	addr += size;187	size = VCE_V2_0_DATA_SIZE;188	WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);189	WREG32(VCE_VCPU_CACHE_SIZE2, size);190 191	WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100);192 193	WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN,194		 ~VCE_SYS_INT_TRAP_INTERRUPT_EN);195 196	vce_v2_0_init_cg(rdev);197 198	return 0;199}200