Line data Source code
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 a
6 : * copy of this software and associated documentation files (the
7 : * "Software"), to deal in the Software without restriction, including
8 : * without limitation the rights to use, copy, modify, merge, publish,
9 : * distribute, sub license, and/or sell copies of the Software, and to
10 : * permit persons to whom the Software is furnished to do so, subject to
11 : * the following conditions:
12 : *
13 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 : * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 : * 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 OR
18 : * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 : * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 : *
21 : * The above copyright notice and this permission notice (including the
22 : * next paragraph) shall be included in all copies or substantial portions
23 : * of the Software.
24 : *
25 : * Authors: Christian König <christian.koenig@amd.com>
26 : */
27 :
28 : #include <dev/pci/drm/drmP.h>
29 : #include "radeon.h"
30 : #include "radeon_asic.h"
31 : #include "cikd.h"
32 :
33 : #define VCE_V2_0_FW_SIZE (256 * 1024)
34 : #define VCE_V2_0_STACK_SIZE (64 * 1024)
35 : #define VCE_V2_0_DATA_SIZE (23552 * RADEON_MAX_VCE_HANDLES)
36 :
37 0 : static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated)
38 : {
39 : u32 tmp;
40 :
41 0 : if (gated) {
42 : tmp = RREG32(VCE_CLOCK_GATING_B);
43 0 : tmp |= 0xe70000;
44 0 : WREG32(VCE_CLOCK_GATING_B, tmp);
45 :
46 0 : tmp = RREG32(VCE_UENC_CLOCK_GATING);
47 0 : tmp |= 0xff000000;
48 0 : WREG32(VCE_UENC_CLOCK_GATING, tmp);
49 :
50 0 : tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
51 0 : tmp &= ~0x3fc;
52 0 : WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
53 :
54 0 : WREG32(VCE_CGTT_CLK_OVERRIDE, 0);
55 0 : } else {
56 : tmp = RREG32(VCE_CLOCK_GATING_B);
57 0 : tmp |= 0xe7;
58 0 : tmp &= ~0xe70000;
59 0 : WREG32(VCE_CLOCK_GATING_B, tmp);
60 :
61 0 : tmp = RREG32(VCE_UENC_CLOCK_GATING);
62 0 : tmp |= 0x1fe000;
63 0 : tmp &= ~0xff000000;
64 0 : WREG32(VCE_UENC_CLOCK_GATING, tmp);
65 :
66 0 : tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
67 0 : tmp |= 0x3fc;
68 0 : WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
69 : }
70 0 : }
71 :
72 0 : static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated)
73 : {
74 : u32 orig, tmp;
75 :
76 0 : tmp = RREG32(VCE_CLOCK_GATING_B);
77 0 : tmp &= ~0x00060006;
78 0 : if (gated) {
79 0 : tmp |= 0xe10000;
80 0 : } else {
81 0 : tmp |= 0xe1;
82 0 : tmp &= ~0xe10000;
83 : }
84 0 : WREG32(VCE_CLOCK_GATING_B, tmp);
85 :
86 0 : orig = tmp = RREG32(VCE_UENC_CLOCK_GATING);
87 0 : tmp &= ~0x1fe000;
88 0 : tmp &= ~0xff000000;
89 0 : if (tmp != orig)
90 0 : WREG32(VCE_UENC_CLOCK_GATING, tmp);
91 :
92 0 : orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
93 0 : tmp &= ~0x3fc;
94 0 : if (tmp != orig)
95 0 : WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
96 :
97 0 : if (gated)
98 0 : WREG32(VCE_CGTT_CLK_OVERRIDE, 0);
99 0 : }
100 :
101 0 : static void vce_v2_0_disable_cg(struct radeon_device *rdev)
102 : {
103 0 : WREG32(VCE_CGTT_CLK_OVERRIDE, 7);
104 0 : }
105 :
106 0 : void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable)
107 : {
108 : bool sw_cg = false;
109 :
110 0 : if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) {
111 0 : if (sw_cg)
112 0 : vce_v2_0_set_sw_cg(rdev, true);
113 : else
114 0 : vce_v2_0_set_dyn_cg(rdev, true);
115 : } else {
116 0 : vce_v2_0_disable_cg(rdev);
117 :
118 0 : if (sw_cg)
119 0 : vce_v2_0_set_sw_cg(rdev, false);
120 : else
121 0 : vce_v2_0_set_dyn_cg(rdev, false);
122 : }
123 0 : }
124 :
125 0 : static void vce_v2_0_init_cg(struct radeon_device *rdev)
126 : {
127 : u32 tmp;
128 :
129 0 : tmp = RREG32(VCE_CLOCK_GATING_A);
130 0 : tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK);
131 0 : tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4));
132 0 : tmp |= CGC_UENC_WAIT_AWAKE;
133 0 : WREG32(VCE_CLOCK_GATING_A, tmp);
134 :
135 0 : tmp = RREG32(VCE_UENC_CLOCK_GATING);
136 0 : tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK);
137 0 : tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4));
138 0 : WREG32(VCE_UENC_CLOCK_GATING, tmp);
139 :
140 0 : tmp = RREG32(VCE_CLOCK_GATING_B);
141 0 : tmp |= 0x10;
142 0 : tmp &= ~0x100000;
143 0 : WREG32(VCE_CLOCK_GATING_B, tmp);
144 0 : }
145 :
146 0 : unsigned vce_v2_0_bo_size(struct radeon_device *rdev)
147 : {
148 0 : WARN_ON(rdev->vce_fw->size > VCE_V2_0_FW_SIZE);
149 0 : return VCE_V2_0_FW_SIZE + VCE_V2_0_STACK_SIZE + VCE_V2_0_DATA_SIZE;
150 : }
151 :
152 0 : int vce_v2_0_resume(struct radeon_device *rdev)
153 : {
154 0 : uint64_t addr = rdev->vce.gpu_addr;
155 : uint32_t size;
156 :
157 0 : WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16));
158 0 : WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
159 0 : WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
160 0 : WREG32(VCE_CLOCK_GATING_B, 0xf7);
161 :
162 0 : WREG32(VCE_LMI_CTRL, 0x00398000);
163 0 : WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1);
164 0 : WREG32(VCE_LMI_SWAP_CNTL, 0);
165 0 : WREG32(VCE_LMI_SWAP_CNTL1, 0);
166 0 : WREG32(VCE_LMI_VM_CTRL, 0);
167 :
168 0 : WREG32(VCE_LMI_VCPU_CACHE_40BIT_BAR, addr >> 8);
169 :
170 0 : addr &= 0xff;
171 : size = VCE_V2_0_FW_SIZE;
172 0 : WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
173 0 : WREG32(VCE_VCPU_CACHE_SIZE0, size);
174 :
175 0 : addr += size;
176 : size = VCE_V2_0_STACK_SIZE;
177 0 : WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
178 0 : WREG32(VCE_VCPU_CACHE_SIZE1, size);
179 :
180 0 : addr += size;
181 : size = VCE_V2_0_DATA_SIZE;
182 0 : WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
183 0 : WREG32(VCE_VCPU_CACHE_SIZE2, size);
184 :
185 0 : WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100);
186 :
187 0 : WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN,
188 : ~VCE_SYS_INT_TRAP_INTERRUPT_EN);
189 :
190 0 : vce_v2_0_init_cg(rdev);
191 :
192 0 : return 0;
193 : }
|