1 /*
2 * Copyright 2019 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24 #include <linux/firmware.h>
25 #include <drm/drm_drv.h>
26
27 #include "amdgpu.h"
28 #include "amdgpu_vcn.h"
29 #include "amdgpu_pm.h"
30 #include "soc15.h"
31 #include "soc15d.h"
32 #include "vcn_v2_0.h"
33 #include "mmsch_v1_0.h"
34 #include "vcn_v2_5.h"
35
36 #include "vcn/vcn_2_5_offset.h"
37 #include "vcn/vcn_2_5_sh_mask.h"
38 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
39
40 #define VCN_VID_SOC_ADDRESS_2_0 0x1fa00
41 #define VCN1_VID_SOC_ADDRESS_3_0 0x48200
42 #define VCN1_AON_SOC_ADDRESS_3_0 0x48000
43
44 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
45 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
46 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10
47 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET 0x11
48 #define mmUVD_NO_OP_INTERNAL_OFFSET 0x29
49 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET 0x66
50 #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d
51
52 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431
53 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4
54 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5
55 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c
56
57 #define VCN25_MAX_HW_INSTANCES_ARCTURUS 2
58
59 static const struct amdgpu_hwip_reg_entry vcn_reg_list_2_5[] = {
60 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS),
61 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS),
62 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_STATUS),
63 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID),
64 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID2),
65 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA0),
66 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA1),
67 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_CMD),
68 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI),
69 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO),
70 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI2),
71 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO2),
72 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI3),
73 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO3),
74 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI4),
75 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO4),
76 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR),
77 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR),
78 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR2),
79 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR2),
80 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR3),
81 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR3),
82 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR4),
83 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR4),
84 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE),
85 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE2),
86 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE3),
87 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE4),
88 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_CONFIG),
89 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_STATUS),
90 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_CTL),
91 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_DATA),
92 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_MASK),
93 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_PAUSE)
94 };
95
96 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
97 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
98 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
99 static int vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst *vinst,
100 enum amd_powergating_state state);
101 static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
102 struct dpg_pause_state *new_state);
103 static int vcn_v2_5_sriov_start(struct amdgpu_device *adev);
104 static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev);
105
106 static int amdgpu_ih_clientid_vcns[] = {
107 SOC15_IH_CLIENTID_VCN,
108 SOC15_IH_CLIENTID_VCN1
109 };
110
vcn_v2_5_idle_work_handler(struct work_struct * work)111 static void vcn_v2_5_idle_work_handler(struct work_struct *work)
112 {
113 struct amdgpu_vcn_inst *vcn_inst =
114 container_of(work, struct amdgpu_vcn_inst, idle_work.work);
115 struct amdgpu_device *adev = vcn_inst->adev;
116 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
117 unsigned int i, j;
118 int r = 0;
119
120 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
121 struct amdgpu_vcn_inst *v = &adev->vcn.inst[i];
122
123 if (adev->vcn.harvest_config & (1 << i))
124 continue;
125
126 for (j = 0; j < v->num_enc_rings; ++j)
127 fence[i] += amdgpu_fence_count_emitted(&v->ring_enc[j]);
128
129 /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
130 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
131 !v->using_unified_queue) {
132 struct dpg_pause_state new_state;
133
134 if (fence[i] ||
135 unlikely(atomic_read(&v->dpg_enc_submission_cnt)))
136 new_state.fw_based = VCN_DPG_STATE__PAUSE;
137 else
138 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
139
140 v->pause_dpg_mode(v, &new_state);
141 }
142
143 fence[i] += amdgpu_fence_count_emitted(&v->ring_dec);
144 fences += fence[i];
145
146 }
147
148 if (!fences && !atomic_read(&adev->vcn.inst[0].total_submission_cnt)) {
149 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
150 AMD_PG_STATE_GATE);
151 mutex_lock(&adev->vcn.workload_profile_mutex);
152 if (adev->vcn.workload_profile_active) {
153 r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO,
154 false);
155 if (r)
156 dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r);
157 adev->vcn.workload_profile_active = false;
158 }
159 mutex_unlock(&adev->vcn.workload_profile_mutex);
160 } else {
161 schedule_delayed_work(&adev->vcn.inst[0].idle_work, VCN_IDLE_TIMEOUT);
162 }
163 }
164
vcn_v2_5_ring_begin_use(struct amdgpu_ring * ring)165 static void vcn_v2_5_ring_begin_use(struct amdgpu_ring *ring)
166 {
167 struct amdgpu_device *adev = ring->adev;
168 struct amdgpu_vcn_inst *v = &adev->vcn.inst[ring->me];
169 int r = 0;
170
171 atomic_inc(&adev->vcn.inst[0].total_submission_cnt);
172
173 cancel_delayed_work_sync(&adev->vcn.inst[0].idle_work);
174
175 /* We can safely return early here because we've cancelled the
176 * the delayed work so there is no one else to set it to false
177 * and we don't care if someone else sets it to true.
178 */
179 if (adev->vcn.workload_profile_active)
180 goto pg_lock;
181
182 mutex_lock(&adev->vcn.workload_profile_mutex);
183 if (!adev->vcn.workload_profile_active) {
184 r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO,
185 true);
186 if (r)
187 dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r);
188 adev->vcn.workload_profile_active = true;
189 }
190 mutex_unlock(&adev->vcn.workload_profile_mutex);
191
192 pg_lock:
193 mutex_lock(&adev->vcn.inst[0].vcn_pg_lock);
194 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
195 AMD_PG_STATE_UNGATE);
196
197 /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
198 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
199 !v->using_unified_queue) {
200 struct dpg_pause_state new_state;
201
202 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
203 atomic_inc(&v->dpg_enc_submission_cnt);
204 new_state.fw_based = VCN_DPG_STATE__PAUSE;
205 } else {
206 unsigned int fences = 0;
207 unsigned int i;
208
209 for (i = 0; i < v->num_enc_rings; ++i)
210 fences += amdgpu_fence_count_emitted(&v->ring_enc[i]);
211
212 if (fences || atomic_read(&v->dpg_enc_submission_cnt))
213 new_state.fw_based = VCN_DPG_STATE__PAUSE;
214 else
215 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
216 }
217 v->pause_dpg_mode(v, &new_state);
218 }
219 mutex_unlock(&adev->vcn.inst[0].vcn_pg_lock);
220 }
221
vcn_v2_5_ring_end_use(struct amdgpu_ring * ring)222 static void vcn_v2_5_ring_end_use(struct amdgpu_ring *ring)
223 {
224 struct amdgpu_device *adev = ring->adev;
225
226 /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
227 if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
228 ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
229 !adev->vcn.inst[ring->me].using_unified_queue)
230 atomic_dec(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
231
232 atomic_dec(&adev->vcn.inst[0].total_submission_cnt);
233
234 schedule_delayed_work(&adev->vcn.inst[0].idle_work,
235 VCN_IDLE_TIMEOUT);
236 }
237
238 /**
239 * vcn_v2_5_early_init - set function pointers and load microcode
240 *
241 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
242 *
243 * Set ring and irq function pointers
244 * Load microcode from filesystem
245 */
vcn_v2_5_early_init(struct amdgpu_ip_block * ip_block)246 static int vcn_v2_5_early_init(struct amdgpu_ip_block *ip_block)
247 {
248 struct amdgpu_device *adev = ip_block->adev;
249 int i, r;
250
251 if (amdgpu_sriov_vf(adev)) {
252 adev->vcn.num_vcn_inst = 2;
253 adev->vcn.harvest_config = 0;
254 for (i = 0; i < adev->vcn.num_vcn_inst; i++)
255 adev->vcn.inst[i].num_enc_rings = 1;
256 } else {
257 u32 harvest;
258 int i;
259
260 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
261 harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING);
262 if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
263 adev->vcn.harvest_config |= 1 << i;
264 adev->vcn.inst[i].num_enc_rings = 2;
265 }
266 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
267 AMDGPU_VCN_HARVEST_VCN1))
268 /* both instances are harvested, disable the block */
269 return -ENOENT;
270 }
271
272 vcn_v2_5_set_dec_ring_funcs(adev);
273 vcn_v2_5_set_enc_ring_funcs(adev);
274 vcn_v2_5_set_irq_funcs(adev);
275 vcn_v2_5_set_ras_funcs(adev);
276
277 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
278 adev->vcn.inst[i].set_pg_state = vcn_v2_5_set_pg_state;
279
280 r = amdgpu_vcn_early_init(adev, i);
281 if (r)
282 return r;
283 }
284
285 return 0;
286 }
287
288 /**
289 * vcn_v2_5_sw_init - sw init for VCN block
290 *
291 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
292 *
293 * Load firmware and sw initialization
294 */
vcn_v2_5_sw_init(struct amdgpu_ip_block * ip_block)295 static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
296 {
297 struct amdgpu_ring *ring;
298 int i, j, r;
299 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5);
300 uint32_t *ptr;
301 struct amdgpu_device *adev = ip_block->adev;
302
303 for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
304 volatile struct amdgpu_fw_shared *fw_shared;
305
306 if (adev->vcn.harvest_config & (1 << j))
307 continue;
308 /* VCN DEC TRAP */
309 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
310 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
311 if (r)
312 return r;
313
314 /* VCN ENC TRAP */
315 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
316 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
317 i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
318 if (r)
319 return r;
320 }
321
322 /* VCN POISON TRAP */
323 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
324 VCN_2_6__SRCID_UVD_POISON, &adev->vcn.inst[j].ras_poison_irq);
325 if (r)
326 return r;
327
328 r = amdgpu_vcn_sw_init(adev, j);
329 if (r)
330 return r;
331
332 /* Override the work func */
333 adev->vcn.inst[j].idle_work.work.func = vcn_v2_5_idle_work_handler;
334
335 amdgpu_vcn_setup_ucode(adev, j);
336
337 r = amdgpu_vcn_resume(adev, j);
338 if (r)
339 return r;
340
341 adev->vcn.inst[j].internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
342 adev->vcn.inst[j].internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
343 adev->vcn.inst[j].internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
344 adev->vcn.inst[j].internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
345 adev->vcn.inst[j].internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
346 adev->vcn.inst[j].internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
347
348 adev->vcn.inst[j].internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
349 adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(VCN, j, mmUVD_SCRATCH9);
350 adev->vcn.inst[j].internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
351 adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA0);
352 adev->vcn.inst[j].internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
353 adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA1);
354 adev->vcn.inst[j].internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
355 adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_CMD);
356 adev->vcn.inst[j].internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
357 adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(VCN, j, mmUVD_NO_OP);
358
359 ring = &adev->vcn.inst[j].ring_dec;
360 ring->use_doorbell = true;
361
362 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
363 (amdgpu_sriov_vf(adev) ? 2*j : 8*j);
364
365 if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(2, 5, 0))
366 ring->vm_hub = AMDGPU_MMHUB1(0);
367 else
368 ring->vm_hub = AMDGPU_MMHUB0(0);
369
370 sprintf(ring->name, "vcn_dec_%d", j);
371 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq,
372 0, AMDGPU_RING_PRIO_DEFAULT, NULL);
373 if (r)
374 return r;
375
376 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
377 enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i);
378
379 ring = &adev->vcn.inst[j].ring_enc[i];
380 ring->use_doorbell = true;
381
382 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
383 (amdgpu_sriov_vf(adev) ? (1 + i + 2*j) : (2 + i + 8*j));
384
385 if (amdgpu_ip_version(adev, UVD_HWIP, 0) ==
386 IP_VERSION(2, 5, 0))
387 ring->vm_hub = AMDGPU_MMHUB1(0);
388 else
389 ring->vm_hub = AMDGPU_MMHUB0(0);
390
391 sprintf(ring->name, "vcn_enc_%d.%d", j, i);
392 r = amdgpu_ring_init(adev, ring, 512,
393 &adev->vcn.inst[j].irq, 0,
394 hw_prio, NULL);
395 if (r)
396 return r;
397 }
398
399 fw_shared = adev->vcn.inst[j].fw_shared.cpu_addr;
400 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
401
402 if (amdgpu_vcnfw_log)
403 amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
404
405 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
406 adev->vcn.inst[j].pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
407 }
408
409 if (amdgpu_sriov_vf(adev)) {
410 r = amdgpu_virt_alloc_mm_table(adev);
411 if (r)
412 return r;
413 }
414
415 r = amdgpu_vcn_ras_sw_init(adev);
416 if (r)
417 return r;
418
419 /* Allocate memory for VCN IP Dump buffer */
420 ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL);
421 if (!ptr) {
422 DRM_ERROR("Failed to allocate memory for VCN IP Dump\n");
423 adev->vcn.ip_dump = NULL;
424 } else {
425 adev->vcn.ip_dump = ptr;
426 }
427
428 return 0;
429 }
430
431 /**
432 * vcn_v2_5_sw_fini - sw fini for VCN block
433 *
434 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
435 *
436 * VCN suspend and free up sw allocation
437 */
vcn_v2_5_sw_fini(struct amdgpu_ip_block * ip_block)438 static int vcn_v2_5_sw_fini(struct amdgpu_ip_block *ip_block)
439 {
440 int i, r, idx;
441 struct amdgpu_device *adev = ip_block->adev;
442 volatile struct amdgpu_fw_shared *fw_shared;
443
444 if (drm_dev_enter(adev_to_drm(adev), &idx)) {
445 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
446 if (adev->vcn.harvest_config & (1 << i))
447 continue;
448 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
449 fw_shared->present_flag_0 = 0;
450 }
451 drm_dev_exit(idx);
452 }
453
454
455 if (amdgpu_sriov_vf(adev))
456 amdgpu_virt_free_mm_table(adev);
457
458 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
459 r = amdgpu_vcn_suspend(adev, i);
460 if (r)
461 return r;
462 r = amdgpu_vcn_sw_fini(adev, i);
463 if (r)
464 return r;
465 }
466
467 kfree(adev->vcn.ip_dump);
468
469 return 0;
470 }
471
472 /**
473 * vcn_v2_5_hw_init - start and test VCN block
474 *
475 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
476 *
477 * Initialize the hardware, boot up the VCPU and do some testing
478 */
vcn_v2_5_hw_init(struct amdgpu_ip_block * ip_block)479 static int vcn_v2_5_hw_init(struct amdgpu_ip_block *ip_block)
480 {
481 struct amdgpu_device *adev = ip_block->adev;
482 struct amdgpu_ring *ring;
483 int i, j, r = 0;
484
485 if (amdgpu_sriov_vf(adev))
486 r = vcn_v2_5_sriov_start(adev);
487
488 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
489 if (adev->vcn.harvest_config & (1 << j))
490 continue;
491
492 if (amdgpu_sriov_vf(adev)) {
493 adev->vcn.inst[j].ring_enc[0].sched.ready = true;
494 adev->vcn.inst[j].ring_enc[1].sched.ready = false;
495 adev->vcn.inst[j].ring_enc[2].sched.ready = false;
496 adev->vcn.inst[j].ring_dec.sched.ready = true;
497 } else {
498
499 ring = &adev->vcn.inst[j].ring_dec;
500
501 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
502 ring->doorbell_index, j);
503
504 r = amdgpu_ring_test_helper(ring);
505 if (r)
506 return r;
507
508 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
509 ring = &adev->vcn.inst[j].ring_enc[i];
510 r = amdgpu_ring_test_helper(ring);
511 if (r)
512 return r;
513 }
514 }
515 }
516
517 return r;
518 }
519
520 /**
521 * vcn_v2_5_hw_fini - stop the hardware block
522 *
523 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
524 *
525 * Stop the VCN block, mark ring as not ready any more
526 */
vcn_v2_5_hw_fini(struct amdgpu_ip_block * ip_block)527 static int vcn_v2_5_hw_fini(struct amdgpu_ip_block *ip_block)
528 {
529 struct amdgpu_device *adev = ip_block->adev;
530 int i;
531
532 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
533 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
534
535 if (adev->vcn.harvest_config & (1 << i))
536 continue;
537
538 cancel_delayed_work_sync(&vinst->idle_work);
539
540 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
541 (vinst->cur_state != AMD_PG_STATE_GATE &&
542 RREG32_SOC15(VCN, i, mmUVD_STATUS)))
543 vinst->set_pg_state(vinst, AMD_PG_STATE_GATE);
544
545 if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN))
546 amdgpu_irq_put(adev, &vinst->ras_poison_irq, 0);
547 }
548
549 return 0;
550 }
551
552 /**
553 * vcn_v2_5_suspend - suspend VCN block
554 *
555 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
556 *
557 * HW fini and suspend VCN block
558 */
vcn_v2_5_suspend(struct amdgpu_ip_block * ip_block)559 static int vcn_v2_5_suspend(struct amdgpu_ip_block *ip_block)
560 {
561 struct amdgpu_device *adev = ip_block->adev;
562 int r, i;
563
564 r = vcn_v2_5_hw_fini(ip_block);
565 if (r)
566 return r;
567
568 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
569 r = amdgpu_vcn_suspend(ip_block->adev, i);
570 if (r)
571 return r;
572 }
573
574 return 0;
575 }
576
577 /**
578 * vcn_v2_5_resume - resume VCN block
579 *
580 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
581 *
582 * Resume firmware and hw init VCN block
583 */
vcn_v2_5_resume(struct amdgpu_ip_block * ip_block)584 static int vcn_v2_5_resume(struct amdgpu_ip_block *ip_block)
585 {
586 struct amdgpu_device *adev = ip_block->adev;
587 int r, i;
588
589 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
590 r = amdgpu_vcn_resume(ip_block->adev, i);
591 if (r)
592 return r;
593 }
594
595 r = vcn_v2_5_hw_init(ip_block);
596
597 return r;
598 }
599
600 /**
601 * vcn_v2_5_mc_resume - memory controller programming
602 *
603 * @vinst: VCN instance
604 *
605 * Let the VCN memory controller know it's offsets
606 */
vcn_v2_5_mc_resume(struct amdgpu_vcn_inst * vinst)607 static void vcn_v2_5_mc_resume(struct amdgpu_vcn_inst *vinst)
608 {
609 struct amdgpu_device *adev = vinst->adev;
610 int i = vinst->inst;
611 uint32_t size;
612 uint32_t offset;
613
614 if (adev->vcn.harvest_config & (1 << i))
615 return;
616
617 size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4);
618 /* cache window 0: fw */
619 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
620 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
621 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo));
622 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
623 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi));
624 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
625 offset = 0;
626 } else {
627 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
628 lower_32_bits(adev->vcn.inst[i].gpu_addr));
629 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
630 upper_32_bits(adev->vcn.inst[i].gpu_addr));
631 offset = size;
632 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0,
633 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
634 }
635 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE0, size);
636
637 /* cache window 1: stack */
638 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
639 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
640 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
641 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
642 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET1, 0);
643 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
644
645 /* cache window 2: context */
646 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
647 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
648 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
649 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
650 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
651 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
652
653 /* non-cache window */
654 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
655 lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
656 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
657 upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
658 WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
659 WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_SIZE0,
660 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
661 }
662
vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_vcn_inst * vinst,bool indirect)663 static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_vcn_inst *vinst,
664 bool indirect)
665 {
666 struct amdgpu_device *adev = vinst->adev;
667 int inst_idx = vinst->inst;
668 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[inst_idx].fw->size + 4);
669 uint32_t offset;
670
671 /* cache window 0: fw */
672 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
673 if (!indirect) {
674 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
675 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
676 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
677 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
678 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
679 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
680 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
681 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
682 } else {
683 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
684 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
685 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
686 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
687 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
688 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
689 }
690 offset = 0;
691 } else {
692 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
693 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
694 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
695 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
696 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
697 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
698 offset = size;
699 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
700 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0),
701 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
702 }
703
704 if (!indirect)
705 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
706 VCN, 0, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
707 else
708 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
709 VCN, 0, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
710
711 /* cache window 1: stack */
712 if (!indirect) {
713 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
714 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
715 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
716 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
717 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
718 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
719 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
720 VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
721 } else {
722 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
723 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
724 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
725 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
726 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
727 VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
728 }
729 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
730 VCN, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
731
732 /* cache window 2: context */
733 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
734 VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
735 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
736 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
737 VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
738 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
739 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
740 VCN, 0, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
741 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
742 VCN, 0, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
743
744 /* non-cache window */
745 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
746 VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
747 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
748 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
749 VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
750 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
751 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
752 VCN, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
753 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
754 VCN, 0, mmUVD_VCPU_NONCACHE_SIZE0),
755 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
756
757 /* VCN global tiling registers */
758 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
759 VCN, 0, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
760 }
761
762 /**
763 * vcn_v2_5_disable_clock_gating - disable VCN clock gating
764 *
765 * @vinst: VCN instance
766 *
767 * Disable clock gating for VCN block
768 */
vcn_v2_5_disable_clock_gating(struct amdgpu_vcn_inst * vinst)769 static void vcn_v2_5_disable_clock_gating(struct amdgpu_vcn_inst *vinst)
770 {
771 struct amdgpu_device *adev = vinst->adev;
772 int i = vinst->inst;
773 uint32_t data;
774
775 if (adev->vcn.harvest_config & (1 << i))
776 return;
777 /* UVD disable CGC */
778 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
779 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
780 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
781 else
782 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
783 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
784 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
785 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
786
787 data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE);
788 data &= ~(UVD_CGC_GATE__SYS_MASK
789 | UVD_CGC_GATE__UDEC_MASK
790 | UVD_CGC_GATE__MPEG2_MASK
791 | UVD_CGC_GATE__REGS_MASK
792 | UVD_CGC_GATE__RBC_MASK
793 | UVD_CGC_GATE__LMI_MC_MASK
794 | UVD_CGC_GATE__LMI_UMC_MASK
795 | UVD_CGC_GATE__IDCT_MASK
796 | UVD_CGC_GATE__MPRD_MASK
797 | UVD_CGC_GATE__MPC_MASK
798 | UVD_CGC_GATE__LBSI_MASK
799 | UVD_CGC_GATE__LRBBM_MASK
800 | UVD_CGC_GATE__UDEC_RE_MASK
801 | UVD_CGC_GATE__UDEC_CM_MASK
802 | UVD_CGC_GATE__UDEC_IT_MASK
803 | UVD_CGC_GATE__UDEC_DB_MASK
804 | UVD_CGC_GATE__UDEC_MP_MASK
805 | UVD_CGC_GATE__WCB_MASK
806 | UVD_CGC_GATE__VCPU_MASK
807 | UVD_CGC_GATE__MMSCH_MASK);
808
809 WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data);
810
811 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0, 0xFFFFFFFF);
812
813 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
814 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
815 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
816 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
817 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
818 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
819 | UVD_CGC_CTRL__SYS_MODE_MASK
820 | UVD_CGC_CTRL__UDEC_MODE_MASK
821 | UVD_CGC_CTRL__MPEG2_MODE_MASK
822 | UVD_CGC_CTRL__REGS_MODE_MASK
823 | UVD_CGC_CTRL__RBC_MODE_MASK
824 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
825 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
826 | UVD_CGC_CTRL__IDCT_MODE_MASK
827 | UVD_CGC_CTRL__MPRD_MODE_MASK
828 | UVD_CGC_CTRL__MPC_MODE_MASK
829 | UVD_CGC_CTRL__LBSI_MODE_MASK
830 | UVD_CGC_CTRL__LRBBM_MODE_MASK
831 | UVD_CGC_CTRL__WCB_MODE_MASK
832 | UVD_CGC_CTRL__VCPU_MODE_MASK
833 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
834 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
835
836 /* turn on */
837 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE);
838 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
839 | UVD_SUVD_CGC_GATE__SIT_MASK
840 | UVD_SUVD_CGC_GATE__SMP_MASK
841 | UVD_SUVD_CGC_GATE__SCM_MASK
842 | UVD_SUVD_CGC_GATE__SDB_MASK
843 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
844 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
845 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
846 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
847 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
848 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
849 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
850 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
851 | UVD_SUVD_CGC_GATE__SCLR_MASK
852 | UVD_SUVD_CGC_GATE__UVD_SC_MASK
853 | UVD_SUVD_CGC_GATE__ENT_MASK
854 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
855 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
856 | UVD_SUVD_CGC_GATE__SITE_MASK
857 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
858 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
859 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
860 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
861 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
862 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data);
863
864 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
865 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
866 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
867 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
868 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
869 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
870 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
871 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
872 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
873 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
874 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
875 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
876 }
877
vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_vcn_inst * vinst,uint8_t sram_sel,uint8_t indirect)878 static void vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_vcn_inst *vinst,
879 uint8_t sram_sel, uint8_t indirect)
880 {
881 struct amdgpu_device *adev = vinst->adev;
882 int inst_idx = vinst->inst;
883 uint32_t reg_data = 0;
884
885 /* enable sw clock gating control */
886 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
887 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
888 else
889 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
890 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
891 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
892 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
893 UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
894 UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
895 UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
896 UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
897 UVD_CGC_CTRL__SYS_MODE_MASK |
898 UVD_CGC_CTRL__UDEC_MODE_MASK |
899 UVD_CGC_CTRL__MPEG2_MODE_MASK |
900 UVD_CGC_CTRL__REGS_MODE_MASK |
901 UVD_CGC_CTRL__RBC_MODE_MASK |
902 UVD_CGC_CTRL__LMI_MC_MODE_MASK |
903 UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
904 UVD_CGC_CTRL__IDCT_MODE_MASK |
905 UVD_CGC_CTRL__MPRD_MODE_MASK |
906 UVD_CGC_CTRL__MPC_MODE_MASK |
907 UVD_CGC_CTRL__LBSI_MODE_MASK |
908 UVD_CGC_CTRL__LRBBM_MODE_MASK |
909 UVD_CGC_CTRL__WCB_MODE_MASK |
910 UVD_CGC_CTRL__VCPU_MODE_MASK |
911 UVD_CGC_CTRL__MMSCH_MODE_MASK);
912 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
913 VCN, 0, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
914
915 /* turn off clock gating */
916 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
917 VCN, 0, mmUVD_CGC_GATE), 0, sram_sel, indirect);
918
919 /* turn on SUVD clock gating */
920 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
921 VCN, 0, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
922
923 /* turn on sw mode in UVD_SUVD_CGC_CTRL */
924 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
925 VCN, 0, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
926 }
927
928 /**
929 * vcn_v2_5_enable_clock_gating - enable VCN clock gating
930 *
931 * @vinst: VCN instance
932 *
933 * Enable clock gating for VCN block
934 */
vcn_v2_5_enable_clock_gating(struct amdgpu_vcn_inst * vinst)935 static void vcn_v2_5_enable_clock_gating(struct amdgpu_vcn_inst *vinst)
936 {
937 struct amdgpu_device *adev = vinst->adev;
938 int i = vinst->inst;
939 uint32_t data = 0;
940
941 if (adev->vcn.harvest_config & (1 << i))
942 return;
943 /* enable UVD CGC */
944 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
945 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
946 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
947 else
948 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
949 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
950 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
951 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
952
953 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
954 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
955 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
956 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
957 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
958 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
959 | UVD_CGC_CTRL__SYS_MODE_MASK
960 | UVD_CGC_CTRL__UDEC_MODE_MASK
961 | UVD_CGC_CTRL__MPEG2_MODE_MASK
962 | UVD_CGC_CTRL__REGS_MODE_MASK
963 | UVD_CGC_CTRL__RBC_MODE_MASK
964 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
965 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
966 | UVD_CGC_CTRL__IDCT_MODE_MASK
967 | UVD_CGC_CTRL__MPRD_MODE_MASK
968 | UVD_CGC_CTRL__MPC_MODE_MASK
969 | UVD_CGC_CTRL__LBSI_MODE_MASK
970 | UVD_CGC_CTRL__LRBBM_MODE_MASK
971 | UVD_CGC_CTRL__WCB_MODE_MASK
972 | UVD_CGC_CTRL__VCPU_MODE_MASK);
973 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
974
975 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
976 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
977 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
978 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
979 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
980 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
981 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
982 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
983 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
984 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
985 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
986 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
987 }
988
vcn_v2_6_enable_ras(struct amdgpu_vcn_inst * vinst,bool indirect)989 static void vcn_v2_6_enable_ras(struct amdgpu_vcn_inst *vinst,
990 bool indirect)
991 {
992 struct amdgpu_device *adev = vinst->adev;
993 int inst_idx = vinst->inst;
994 uint32_t tmp;
995
996 if (amdgpu_ip_version(adev, UVD_HWIP, 0) != IP_VERSION(2, 6, 0))
997 return;
998
999 tmp = VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK |
1000 VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK |
1001 VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK |
1002 VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK;
1003 WREG32_SOC15_DPG_MODE(inst_idx,
1004 SOC15_DPG_MODE_OFFSET(VCN, 0, mmVCN_RAS_CNTL),
1005 tmp, 0, indirect);
1006
1007 tmp = UVD_VCPU_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK;
1008 WREG32_SOC15_DPG_MODE(inst_idx,
1009 SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_VCPU_INT_EN),
1010 tmp, 0, indirect);
1011
1012 tmp = UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK;
1013 WREG32_SOC15_DPG_MODE(inst_idx,
1014 SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_SYS_INT_EN),
1015 tmp, 0, indirect);
1016 }
1017
vcn_v2_5_start_dpg_mode(struct amdgpu_vcn_inst * vinst,bool indirect)1018 static int vcn_v2_5_start_dpg_mode(struct amdgpu_vcn_inst *vinst, bool indirect)
1019 {
1020 struct amdgpu_device *adev = vinst->adev;
1021 int inst_idx = vinst->inst;
1022 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
1023 struct amdgpu_ring *ring;
1024 uint32_t rb_bufsz, tmp;
1025
1026 /* disable register anti-hang mechanism */
1027 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1,
1028 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1029 /* enable dynamic power gating mode */
1030 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS);
1031 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
1032 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
1033 WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp);
1034
1035 if (indirect)
1036 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
1037
1038 /* enable clock gating */
1039 vcn_v2_5_clock_gating_dpg_mode(vinst, 0, indirect);
1040
1041 /* enable VCPU clock */
1042 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
1043 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
1044 tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
1045 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1046 VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1047
1048 /* disable master interupt */
1049 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1050 VCN, 0, mmUVD_MASTINT_EN), 0, 0, indirect);
1051
1052 /* setup mmUVD_LMI_CTRL */
1053 tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1054 UVD_LMI_CTRL__REQ_MODE_MASK |
1055 UVD_LMI_CTRL__CRC_RESET_MASK |
1056 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1057 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1058 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
1059 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
1060 0x00100000L);
1061 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1062 VCN, 0, mmUVD_LMI_CTRL), tmp, 0, indirect);
1063
1064 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1065 VCN, 0, mmUVD_MPC_CNTL),
1066 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
1067
1068 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1069 VCN, 0, mmUVD_MPC_SET_MUXA0),
1070 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1071 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1072 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1073 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
1074
1075 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1076 VCN, 0, mmUVD_MPC_SET_MUXB0),
1077 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1078 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1079 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1080 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
1081
1082 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1083 VCN, 0, mmUVD_MPC_SET_MUX),
1084 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1085 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1086 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
1087
1088 vcn_v2_5_mc_resume_dpg_mode(vinst, indirect);
1089
1090 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1091 VCN, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
1092 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1093 VCN, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
1094
1095 /* enable LMI MC and UMC channels */
1096 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1097 VCN, 0, mmUVD_LMI_CTRL2), 0, 0, indirect);
1098
1099 vcn_v2_6_enable_ras(vinst, indirect);
1100
1101 /* unblock VCPU register access */
1102 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1103 VCN, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
1104
1105 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
1106 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
1107 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1108 VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1109
1110 /* enable master interrupt */
1111 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1112 VCN, 0, mmUVD_MASTINT_EN),
1113 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
1114
1115 if (indirect)
1116 amdgpu_vcn_psp_update_sram(adev, inst_idx, 0);
1117
1118 ring = &adev->vcn.inst[inst_idx].ring_dec;
1119 /* force RBC into idle state */
1120 rb_bufsz = order_base_2(ring->ring_size);
1121 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1122 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1123 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1124 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1125 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1126 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
1127
1128 /* Stall DPG before WPTR/RPTR reset */
1129 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1130 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1131 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1132 fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
1133
1134 /* set the write pointer delay */
1135 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
1136
1137 /* set the wb address */
1138 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
1139 (upper_32_bits(ring->gpu_addr) >> 2));
1140
1141 /* program the RB_BASE for ring buffer */
1142 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1143 lower_32_bits(ring->gpu_addr));
1144 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1145 upper_32_bits(ring->gpu_addr));
1146
1147 /* Initialize the ring buffer's read and write pointers */
1148 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0);
1149
1150 WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0);
1151
1152 ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR);
1153 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
1154 lower_32_bits(ring->wptr));
1155
1156 fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
1157 /* Unstall DPG */
1158 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1159 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1160
1161 return 0;
1162 }
1163
vcn_v2_5_start(struct amdgpu_vcn_inst * vinst)1164 static int vcn_v2_5_start(struct amdgpu_vcn_inst *vinst)
1165 {
1166 struct amdgpu_device *adev = vinst->adev;
1167 int i = vinst->inst;
1168 volatile struct amdgpu_fw_shared *fw_shared =
1169 adev->vcn.inst[i].fw_shared.cpu_addr;
1170 struct amdgpu_ring *ring;
1171 uint32_t rb_bufsz, tmp;
1172 int j, k, r;
1173
1174 if (adev->vcn.harvest_config & (1 << i))
1175 return 0;
1176
1177 if (adev->pm.dpm_enabled)
1178 amdgpu_dpm_enable_vcn(adev, true, i);
1179
1180 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
1181 return vcn_v2_5_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram);
1182
1183 /* disable register anti-hang mechanism */
1184 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS), 0,
1185 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1186
1187 /* set uvd status busy */
1188 tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
1189 WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp);
1190
1191 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
1192 return 0;
1193
1194 /* SW clock gating */
1195 vcn_v2_5_disable_clock_gating(vinst);
1196
1197 /* enable VCPU clock */
1198 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1199 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
1200
1201 /* disable master interrupt */
1202 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0,
1203 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1204
1205 /* setup mmUVD_LMI_CTRL */
1206 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL);
1207 tmp &= ~0xff;
1208 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp | 0x8|
1209 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1210 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1211 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1212 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1213
1214 /* setup mmUVD_MPC_CNTL */
1215 tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL);
1216 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
1217 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
1218 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
1219
1220 /* setup UVD_MPC_SET_MUXA0 */
1221 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0,
1222 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1223 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1224 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1225 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
1226
1227 /* setup UVD_MPC_SET_MUXB0 */
1228 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0,
1229 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1230 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1231 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1232 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
1233
1234 /* setup mmUVD_MPC_SET_MUX */
1235 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX,
1236 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1237 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1238 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
1239
1240 vcn_v2_5_mc_resume(vinst);
1241
1242 /* VCN global tiling registers */
1243 WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
1244 adev->gfx.config.gb_addr_config);
1245 WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
1246 adev->gfx.config.gb_addr_config);
1247
1248 /* enable LMI MC and UMC channels */
1249 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0,
1250 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1251
1252 /* unblock VCPU register access */
1253 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0,
1254 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1255
1256 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1257 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1258
1259 for (k = 0; k < 10; ++k) {
1260 uint32_t status;
1261
1262 for (j = 0; j < 100; ++j) {
1263 status = RREG32_SOC15(VCN, i, mmUVD_STATUS);
1264 if (status & 2)
1265 break;
1266 if (amdgpu_emu_mode == 1)
1267 msleep(500);
1268 else
1269 mdelay(10);
1270 }
1271 r = 0;
1272 if (status & 2)
1273 break;
1274
1275 DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
1276 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1277 UVD_VCPU_CNTL__BLK_RST_MASK,
1278 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1279 mdelay(10);
1280 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1281 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1282
1283 mdelay(10);
1284 r = -1;
1285 }
1286
1287 if (r) {
1288 DRM_ERROR("VCN decode not responding, giving up!!!\n");
1289 return r;
1290 }
1291
1292 /* enable master interrupt */
1293 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN),
1294 UVD_MASTINT_EN__VCPU_EN_MASK,
1295 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1296
1297 /* clear the busy bit of VCN_STATUS */
1298 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0,
1299 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1300
1301 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0);
1302
1303 ring = &adev->vcn.inst[i].ring_dec;
1304 /* force RBC into idle state */
1305 rb_bufsz = order_base_2(ring->ring_size);
1306 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1307 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1308 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1309 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1310 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1311 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
1312
1313 fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
1314 /* program the RB_BASE for ring buffer */
1315 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1316 lower_32_bits(ring->gpu_addr));
1317 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1318 upper_32_bits(ring->gpu_addr));
1319
1320 /* Initialize the ring buffer's read and write pointers */
1321 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
1322
1323 ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
1324 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
1325 lower_32_bits(ring->wptr));
1326 fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
1327
1328 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
1329 ring = &adev->vcn.inst[i].ring_enc[0];
1330 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1331 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1332 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
1333 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1334 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4);
1335 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
1336
1337 fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
1338 ring = &adev->vcn.inst[i].ring_enc[1];
1339 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1340 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1341 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1342 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1343 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
1344 fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
1345
1346 return 0;
1347 }
1348
vcn_v2_5_mmsch_start(struct amdgpu_device * adev,struct amdgpu_mm_table * table)1349 static int vcn_v2_5_mmsch_start(struct amdgpu_device *adev,
1350 struct amdgpu_mm_table *table)
1351 {
1352 uint32_t data = 0, loop = 0, size = 0;
1353 uint64_t addr = table->gpu_addr;
1354 struct mmsch_v1_1_init_header *header = NULL;
1355
1356 header = (struct mmsch_v1_1_init_header *)table->cpu_addr;
1357 size = header->total_size;
1358
1359 /*
1360 * 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of
1361 * memory descriptor location
1362 */
1363 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
1364 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
1365
1366 /* 2, update vmid of descriptor */
1367 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID);
1368 data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
1369 /* use domain0 for MM scheduler */
1370 data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
1371 WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, data);
1372
1373 /* 3, notify mmsch about the size of this descriptor */
1374 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size);
1375
1376 /* 4, set resp to zero */
1377 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
1378
1379 /*
1380 * 5, kick off the initialization and wait until
1381 * VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero
1382 */
1383 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, 0x10000001);
1384
1385 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1386 loop = 10;
1387 while ((data & 0x10000002) != 0x10000002) {
1388 udelay(100);
1389 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1390 loop--;
1391 if (!loop)
1392 break;
1393 }
1394
1395 if (!loop) {
1396 dev_err(adev->dev,
1397 "failed to init MMSCH, mmMMSCH_VF_MAILBOX_RESP = %x\n",
1398 data);
1399 return -EBUSY;
1400 }
1401
1402 return 0;
1403 }
1404
vcn_v2_5_sriov_start(struct amdgpu_device * adev)1405 static int vcn_v2_5_sriov_start(struct amdgpu_device *adev)
1406 {
1407 struct amdgpu_ring *ring;
1408 uint32_t offset, size, tmp, i, rb_bufsz;
1409 uint32_t table_size = 0;
1410 struct mmsch_v1_0_cmd_direct_write direct_wt = { { 0 } };
1411 struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt = { { 0 } };
1412 struct mmsch_v1_0_cmd_end end = { { 0 } };
1413 uint32_t *init_table = adev->virt.mm_table.cpu_addr;
1414 struct mmsch_v1_1_init_header *header = (struct mmsch_v1_1_init_header *)init_table;
1415
1416 direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE;
1417 direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
1418 end.cmd_header.command_type = MMSCH_COMMAND__END;
1419
1420 header->version = MMSCH_VERSION;
1421 header->total_size = sizeof(struct mmsch_v1_1_init_header) >> 2;
1422 init_table += header->total_size;
1423
1424 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1425 header->eng[i].table_offset = header->total_size;
1426 header->eng[i].init_status = 0;
1427 header->eng[i].table_size = 0;
1428
1429 table_size = 0;
1430
1431 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(
1432 SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS),
1433 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
1434
1435 size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4);
1436 /* mc resume*/
1437 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1438 MMSCH_V1_0_INSERT_DIRECT_WT(
1439 SOC15_REG_OFFSET(VCN, i,
1440 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1441 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
1442 MMSCH_V1_0_INSERT_DIRECT_WT(
1443 SOC15_REG_OFFSET(VCN, i,
1444 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1445 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
1446 offset = 0;
1447 MMSCH_V1_0_INSERT_DIRECT_WT(
1448 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), 0);
1449 } else {
1450 MMSCH_V1_0_INSERT_DIRECT_WT(
1451 SOC15_REG_OFFSET(VCN, i,
1452 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1453 lower_32_bits(adev->vcn.inst[i].gpu_addr));
1454 MMSCH_V1_0_INSERT_DIRECT_WT(
1455 SOC15_REG_OFFSET(VCN, i,
1456 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1457 upper_32_bits(adev->vcn.inst[i].gpu_addr));
1458 offset = size;
1459 MMSCH_V1_0_INSERT_DIRECT_WT(
1460 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0),
1461 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
1462 }
1463
1464 MMSCH_V1_0_INSERT_DIRECT_WT(
1465 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE0),
1466 size);
1467 MMSCH_V1_0_INSERT_DIRECT_WT(
1468 SOC15_REG_OFFSET(VCN, i,
1469 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
1470 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
1471 MMSCH_V1_0_INSERT_DIRECT_WT(
1472 SOC15_REG_OFFSET(VCN, i,
1473 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
1474 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
1475 MMSCH_V1_0_INSERT_DIRECT_WT(
1476 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET1),
1477 0);
1478 MMSCH_V1_0_INSERT_DIRECT_WT(
1479 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE1),
1480 AMDGPU_VCN_STACK_SIZE);
1481 MMSCH_V1_0_INSERT_DIRECT_WT(
1482 SOC15_REG_OFFSET(VCN, i,
1483 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
1484 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset +
1485 AMDGPU_VCN_STACK_SIZE));
1486 MMSCH_V1_0_INSERT_DIRECT_WT(
1487 SOC15_REG_OFFSET(VCN, i,
1488 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
1489 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset +
1490 AMDGPU_VCN_STACK_SIZE));
1491 MMSCH_V1_0_INSERT_DIRECT_WT(
1492 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET2),
1493 0);
1494 MMSCH_V1_0_INSERT_DIRECT_WT(
1495 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE2),
1496 AMDGPU_VCN_CONTEXT_SIZE);
1497
1498 ring = &adev->vcn.inst[i].ring_enc[0];
1499 ring->wptr = 0;
1500
1501 MMSCH_V1_0_INSERT_DIRECT_WT(
1502 SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_LO),
1503 lower_32_bits(ring->gpu_addr));
1504 MMSCH_V1_0_INSERT_DIRECT_WT(
1505 SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_HI),
1506 upper_32_bits(ring->gpu_addr));
1507 MMSCH_V1_0_INSERT_DIRECT_WT(
1508 SOC15_REG_OFFSET(VCN, i, mmUVD_RB_SIZE),
1509 ring->ring_size / 4);
1510
1511 ring = &adev->vcn.inst[i].ring_dec;
1512 ring->wptr = 0;
1513 MMSCH_V1_0_INSERT_DIRECT_WT(
1514 SOC15_REG_OFFSET(VCN, i,
1515 mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
1516 lower_32_bits(ring->gpu_addr));
1517 MMSCH_V1_0_INSERT_DIRECT_WT(
1518 SOC15_REG_OFFSET(VCN, i,
1519 mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
1520 upper_32_bits(ring->gpu_addr));
1521
1522 /* force RBC into idle state */
1523 rb_bufsz = order_base_2(ring->ring_size);
1524 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1525 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1526 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1527 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1528 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1529 MMSCH_V1_0_INSERT_DIRECT_WT(
1530 SOC15_REG_OFFSET(VCN, i, mmUVD_RBC_RB_CNTL), tmp);
1531
1532 /* add end packet */
1533 memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
1534 table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
1535 init_table += sizeof(struct mmsch_v1_0_cmd_end) / 4;
1536
1537 /* refine header */
1538 header->eng[i].table_size = table_size;
1539 header->total_size += table_size;
1540 }
1541
1542 return vcn_v2_5_mmsch_start(adev, &adev->virt.mm_table);
1543 }
1544
vcn_v2_5_stop_dpg_mode(struct amdgpu_vcn_inst * vinst)1545 static int vcn_v2_5_stop_dpg_mode(struct amdgpu_vcn_inst *vinst)
1546 {
1547 struct amdgpu_device *adev = vinst->adev;
1548 int inst_idx = vinst->inst;
1549 uint32_t tmp;
1550
1551 /* Wait for power status to be 1 */
1552 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1553 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1554
1555 /* wait for read ptr to be equal to write ptr */
1556 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR);
1557 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1558
1559 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2);
1560 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
1561
1562 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
1563 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
1564
1565 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1566 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1567
1568 /* disable dynamic power gating mode */
1569 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0,
1570 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1571
1572 return 0;
1573 }
1574
vcn_v2_5_stop(struct amdgpu_vcn_inst * vinst)1575 static int vcn_v2_5_stop(struct amdgpu_vcn_inst *vinst)
1576 {
1577 struct amdgpu_device *adev = vinst->adev;
1578 int i = vinst->inst;
1579 uint32_t tmp;
1580 int r;
1581
1582 if (adev->vcn.harvest_config & (1 << i))
1583 return 0;
1584
1585 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1586 r = vcn_v2_5_stop_dpg_mode(vinst);
1587 goto done;
1588 }
1589
1590 /* wait for vcn idle */
1591 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1592 if (r)
1593 goto done;
1594
1595 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1596 UVD_LMI_STATUS__READ_CLEAN_MASK |
1597 UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1598 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1599 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1600 if (r)
1601 goto done;
1602
1603 /* block LMI UMC channel */
1604 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
1605 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1606 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
1607
1608 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
1609 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1610 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1611 if (r)
1612 goto done;
1613
1614 /* block VCPU register access */
1615 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL),
1616 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1617 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1618
1619 /* reset VCPU */
1620 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1621 UVD_VCPU_CNTL__BLK_RST_MASK,
1622 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1623
1624 /* disable VCPU clock */
1625 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1626 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
1627
1628 /* clear status */
1629 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
1630
1631 vcn_v2_5_enable_clock_gating(vinst);
1632
1633 /* enable register anti-hang mechanism */
1634 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS),
1635 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
1636 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1637
1638 done:
1639 if (adev->pm.dpm_enabled)
1640 amdgpu_dpm_enable_vcn(adev, false, i);
1641
1642 return r;
1643 }
1644
vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst * vinst,struct dpg_pause_state * new_state)1645 static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
1646 struct dpg_pause_state *new_state)
1647 {
1648 struct amdgpu_device *adev = vinst->adev;
1649 int inst_idx = vinst->inst;
1650 struct amdgpu_ring *ring;
1651 uint32_t reg_data = 0;
1652 int ret_code = 0;
1653
1654 /* pause/unpause if state is changed */
1655 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
1656 DRM_DEBUG("dpg pause state changed %d -> %d",
1657 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based);
1658 reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) &
1659 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1660
1661 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
1662 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1663 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1664
1665 if (!ret_code) {
1666 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
1667
1668 /* pause DPG */
1669 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1670 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1671
1672 /* wait for ACK */
1673 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE,
1674 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
1675 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1676
1677 /* Stall DPG before WPTR/RPTR reset */
1678 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1679 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1680 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1681
1682 /* Restore */
1683 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
1684 ring = &adev->vcn.inst[inst_idx].ring_enc[0];
1685 ring->wptr = 0;
1686 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
1687 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1688 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
1689 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1690 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1691 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
1692
1693 fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
1694 ring = &adev->vcn.inst[inst_idx].ring_enc[1];
1695 ring->wptr = 0;
1696 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1697 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1698 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
1699 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1700 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1701 fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
1702
1703 /* Unstall DPG */
1704 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1705 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1706
1707 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS,
1708 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1709 }
1710 } else {
1711 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1712 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1713 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1714 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1715 }
1716 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
1717 }
1718
1719 return 0;
1720 }
1721
1722 /**
1723 * vcn_v2_5_dec_ring_get_rptr - get read pointer
1724 *
1725 * @ring: amdgpu_ring pointer
1726 *
1727 * Returns the current hardware read pointer
1728 */
vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring * ring)1729 static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
1730 {
1731 struct amdgpu_device *adev = ring->adev;
1732
1733 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR);
1734 }
1735
1736 /**
1737 * vcn_v2_5_dec_ring_get_wptr - get write pointer
1738 *
1739 * @ring: amdgpu_ring pointer
1740 *
1741 * Returns the current hardware write pointer
1742 */
vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring * ring)1743 static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
1744 {
1745 struct amdgpu_device *adev = ring->adev;
1746
1747 if (ring->use_doorbell)
1748 return *ring->wptr_cpu_addr;
1749 else
1750 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR);
1751 }
1752
1753 /**
1754 * vcn_v2_5_dec_ring_set_wptr - set write pointer
1755 *
1756 * @ring: amdgpu_ring pointer
1757 *
1758 * Commits the write pointer to the hardware
1759 */
vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring * ring)1760 static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
1761 {
1762 struct amdgpu_device *adev = ring->adev;
1763
1764 if (ring->use_doorbell) {
1765 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1766 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1767 } else {
1768 WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
1769 }
1770 }
1771
1772 static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
1773 .type = AMDGPU_RING_TYPE_VCN_DEC,
1774 .align_mask = 0xf,
1775 .secure_submission_supported = true,
1776 .get_rptr = vcn_v2_5_dec_ring_get_rptr,
1777 .get_wptr = vcn_v2_5_dec_ring_get_wptr,
1778 .set_wptr = vcn_v2_5_dec_ring_set_wptr,
1779 .emit_frame_size =
1780 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1781 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1782 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
1783 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
1784 6,
1785 .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
1786 .emit_ib = vcn_v2_0_dec_ring_emit_ib,
1787 .emit_fence = vcn_v2_0_dec_ring_emit_fence,
1788 .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1789 .test_ring = vcn_v2_0_dec_ring_test_ring,
1790 .test_ib = amdgpu_vcn_dec_ring_test_ib,
1791 .insert_nop = vcn_v2_0_dec_ring_insert_nop,
1792 .insert_start = vcn_v2_0_dec_ring_insert_start,
1793 .insert_end = vcn_v2_0_dec_ring_insert_end,
1794 .pad_ib = amdgpu_ring_generic_pad_ib,
1795 .begin_use = vcn_v2_5_ring_begin_use,
1796 .end_use = vcn_v2_5_ring_end_use,
1797 .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1798 .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1799 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1800 };
1801
1802 /**
1803 * vcn_v2_5_enc_ring_get_rptr - get enc read pointer
1804 *
1805 * @ring: amdgpu_ring pointer
1806 *
1807 * Returns the current hardware enc read pointer
1808 */
vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring * ring)1809 static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
1810 {
1811 struct amdgpu_device *adev = ring->adev;
1812
1813 if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1814 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR);
1815 else
1816 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2);
1817 }
1818
1819 /**
1820 * vcn_v2_5_enc_ring_get_wptr - get enc write pointer
1821 *
1822 * @ring: amdgpu_ring pointer
1823 *
1824 * Returns the current hardware enc write pointer
1825 */
vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring * ring)1826 static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
1827 {
1828 struct amdgpu_device *adev = ring->adev;
1829
1830 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1831 if (ring->use_doorbell)
1832 return *ring->wptr_cpu_addr;
1833 else
1834 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR);
1835 } else {
1836 if (ring->use_doorbell)
1837 return *ring->wptr_cpu_addr;
1838 else
1839 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2);
1840 }
1841 }
1842
1843 /**
1844 * vcn_v2_5_enc_ring_set_wptr - set enc write pointer
1845 *
1846 * @ring: amdgpu_ring pointer
1847 *
1848 * Commits the enc write pointer to the hardware
1849 */
vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring * ring)1850 static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
1851 {
1852 struct amdgpu_device *adev = ring->adev;
1853
1854 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1855 if (ring->use_doorbell) {
1856 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1857 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1858 } else {
1859 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1860 }
1861 } else {
1862 if (ring->use_doorbell) {
1863 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1864 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1865 } else {
1866 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1867 }
1868 }
1869 }
1870
1871 static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
1872 .type = AMDGPU_RING_TYPE_VCN_ENC,
1873 .align_mask = 0x3f,
1874 .nop = VCN_ENC_CMD_NO_OP,
1875 .get_rptr = vcn_v2_5_enc_ring_get_rptr,
1876 .get_wptr = vcn_v2_5_enc_ring_get_wptr,
1877 .set_wptr = vcn_v2_5_enc_ring_set_wptr,
1878 .emit_frame_size =
1879 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1880 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1881 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1882 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1883 1, /* vcn_v2_0_enc_ring_insert_end */
1884 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1885 .emit_ib = vcn_v2_0_enc_ring_emit_ib,
1886 .emit_fence = vcn_v2_0_enc_ring_emit_fence,
1887 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1888 .test_ring = amdgpu_vcn_enc_ring_test_ring,
1889 .test_ib = amdgpu_vcn_enc_ring_test_ib,
1890 .insert_nop = amdgpu_ring_insert_nop,
1891 .insert_end = vcn_v2_0_enc_ring_insert_end,
1892 .pad_ib = amdgpu_ring_generic_pad_ib,
1893 .begin_use = vcn_v2_5_ring_begin_use,
1894 .end_use = vcn_v2_5_ring_end_use,
1895 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1896 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1897 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1898 };
1899
vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device * adev)1900 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
1901 {
1902 int i;
1903
1904 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1905 if (adev->vcn.harvest_config & (1 << i))
1906 continue;
1907 adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
1908 adev->vcn.inst[i].ring_dec.me = i;
1909 }
1910 }
1911
vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device * adev)1912 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
1913 {
1914 int i, j;
1915
1916 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
1917 if (adev->vcn.harvest_config & (1 << j))
1918 continue;
1919 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
1920 adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
1921 adev->vcn.inst[j].ring_enc[i].me = j;
1922 }
1923 }
1924 }
1925
vcn_v2_5_is_idle(struct amdgpu_ip_block * ip_block)1926 static bool vcn_v2_5_is_idle(struct amdgpu_ip_block *ip_block)
1927 {
1928 struct amdgpu_device *adev = ip_block->adev;
1929 int i, ret = 1;
1930
1931 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1932 if (adev->vcn.harvest_config & (1 << i))
1933 continue;
1934
1935 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1936 }
1937
1938 return ret;
1939 }
1940
vcn_v2_5_wait_for_idle(struct amdgpu_ip_block * ip_block)1941 static int vcn_v2_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
1942 {
1943 struct amdgpu_device *adev = ip_block->adev;
1944 int i, ret = 0;
1945
1946 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1947 if (adev->vcn.harvest_config & (1 << i))
1948 continue;
1949 ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1950 UVD_STATUS__IDLE);
1951 if (ret)
1952 return ret;
1953 }
1954
1955 return ret;
1956 }
1957
vcn_v2_5_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)1958 static int vcn_v2_5_set_clockgating_state(struct amdgpu_ip_block *ip_block,
1959 enum amd_clockgating_state state)
1960 {
1961 struct amdgpu_device *adev = ip_block->adev;
1962 bool enable = (state == AMD_CG_STATE_GATE);
1963 int i;
1964
1965 if (amdgpu_sriov_vf(adev))
1966 return 0;
1967
1968 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1969 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
1970
1971 if (enable) {
1972 if (!vcn_v2_5_is_idle(ip_block))
1973 return -EBUSY;
1974 vcn_v2_5_enable_clock_gating(vinst);
1975 } else {
1976 vcn_v2_5_disable_clock_gating(vinst);
1977 }
1978 }
1979
1980 return 0;
1981 }
1982
vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst * vinst,enum amd_powergating_state state)1983 static int vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst *vinst,
1984 enum amd_powergating_state state)
1985 {
1986 struct amdgpu_device *adev = vinst->adev;
1987 int ret;
1988
1989 if (amdgpu_sriov_vf(adev))
1990 return 0;
1991
1992 if (state == vinst->cur_state)
1993 return 0;
1994
1995 if (state == AMD_PG_STATE_GATE)
1996 ret = vcn_v2_5_stop(vinst);
1997 else
1998 ret = vcn_v2_5_start(vinst);
1999
2000 if (!ret)
2001 vinst->cur_state = state;
2002
2003 return ret;
2004 }
2005
vcn_v2_5_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)2006 static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
2007 struct amdgpu_irq_src *source,
2008 unsigned type,
2009 enum amdgpu_interrupt_state state)
2010 {
2011 return 0;
2012 }
2013
vcn_v2_6_set_ras_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned int type,enum amdgpu_interrupt_state state)2014 static int vcn_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev,
2015 struct amdgpu_irq_src *source,
2016 unsigned int type,
2017 enum amdgpu_interrupt_state state)
2018 {
2019 return 0;
2020 }
2021
vcn_v2_5_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)2022 static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
2023 struct amdgpu_irq_src *source,
2024 struct amdgpu_iv_entry *entry)
2025 {
2026 uint32_t ip_instance;
2027
2028 switch (entry->client_id) {
2029 case SOC15_IH_CLIENTID_VCN:
2030 ip_instance = 0;
2031 break;
2032 case SOC15_IH_CLIENTID_VCN1:
2033 ip_instance = 1;
2034 break;
2035 default:
2036 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
2037 return 0;
2038 }
2039
2040 DRM_DEBUG("IH: VCN TRAP\n");
2041
2042 switch (entry->src_id) {
2043 case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
2044 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
2045 break;
2046 case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
2047 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
2048 break;
2049 case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
2050 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
2051 break;
2052 default:
2053 DRM_ERROR("Unhandled interrupt: %d %d\n",
2054 entry->src_id, entry->src_data[0]);
2055 break;
2056 }
2057
2058 return 0;
2059 }
2060
2061 static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
2062 .set = vcn_v2_5_set_interrupt_state,
2063 .process = vcn_v2_5_process_interrupt,
2064 };
2065
2066 static const struct amdgpu_irq_src_funcs vcn_v2_6_ras_irq_funcs = {
2067 .set = vcn_v2_6_set_ras_interrupt_state,
2068 .process = amdgpu_vcn_process_poison_irq,
2069 };
2070
vcn_v2_5_set_irq_funcs(struct amdgpu_device * adev)2071 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
2072 {
2073 int i;
2074
2075 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2076 if (adev->vcn.harvest_config & (1 << i))
2077 continue;
2078 adev->vcn.inst[i].irq.num_types = adev->vcn.inst[i].num_enc_rings + 1;
2079 adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
2080
2081 adev->vcn.inst[i].ras_poison_irq.num_types = adev->vcn.inst[i].num_enc_rings + 1;
2082 adev->vcn.inst[i].ras_poison_irq.funcs = &vcn_v2_6_ras_irq_funcs;
2083 }
2084 }
2085
vcn_v2_5_print_ip_state(struct amdgpu_ip_block * ip_block,struct drm_printer * p)2086 static void vcn_v2_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
2087 {
2088 struct amdgpu_device *adev = ip_block->adev;
2089 int i, j;
2090 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5);
2091 uint32_t inst_off, is_powered;
2092
2093 if (!adev->vcn.ip_dump)
2094 return;
2095
2096 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst);
2097 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
2098 if (adev->vcn.harvest_config & (1 << i)) {
2099 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i);
2100 continue;
2101 }
2102
2103 inst_off = i * reg_count;
2104 is_powered = (adev->vcn.ip_dump[inst_off] &
2105 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1;
2106
2107 if (is_powered) {
2108 drm_printf(p, "\nActive Instance:VCN%d\n", i);
2109 for (j = 0; j < reg_count; j++)
2110 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_2_5[j].reg_name,
2111 adev->vcn.ip_dump[inst_off + j]);
2112 } else {
2113 drm_printf(p, "\nInactive Instance:VCN%d\n", i);
2114 }
2115 }
2116 }
2117
vcn_v2_5_dump_ip_state(struct amdgpu_ip_block * ip_block)2118 static void vcn_v2_5_dump_ip_state(struct amdgpu_ip_block *ip_block)
2119 {
2120 struct amdgpu_device *adev = ip_block->adev;
2121 int i, j;
2122 bool is_powered;
2123 uint32_t inst_off;
2124 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5);
2125
2126 if (!adev->vcn.ip_dump)
2127 return;
2128
2129 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
2130 if (adev->vcn.harvest_config & (1 << i))
2131 continue;
2132
2133 inst_off = i * reg_count;
2134 /* mmUVD_POWER_STATUS is always readable and is first element of the array */
2135 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS);
2136 is_powered = (adev->vcn.ip_dump[inst_off] &
2137 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1;
2138
2139 if (is_powered)
2140 for (j = 1; j < reg_count; j++)
2141 adev->vcn.ip_dump[inst_off + j] =
2142 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_2_5[j], i));
2143 }
2144 }
2145
2146 static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
2147 .name = "vcn_v2_5",
2148 .early_init = vcn_v2_5_early_init,
2149 .sw_init = vcn_v2_5_sw_init,
2150 .sw_fini = vcn_v2_5_sw_fini,
2151 .hw_init = vcn_v2_5_hw_init,
2152 .hw_fini = vcn_v2_5_hw_fini,
2153 .suspend = vcn_v2_5_suspend,
2154 .resume = vcn_v2_5_resume,
2155 .is_idle = vcn_v2_5_is_idle,
2156 .wait_for_idle = vcn_v2_5_wait_for_idle,
2157 .set_clockgating_state = vcn_v2_5_set_clockgating_state,
2158 .set_powergating_state = vcn_set_powergating_state,
2159 .dump_ip_state = vcn_v2_5_dump_ip_state,
2160 .print_ip_state = vcn_v2_5_print_ip_state,
2161 };
2162
2163 static const struct amd_ip_funcs vcn_v2_6_ip_funcs = {
2164 .name = "vcn_v2_6",
2165 .early_init = vcn_v2_5_early_init,
2166 .sw_init = vcn_v2_5_sw_init,
2167 .sw_fini = vcn_v2_5_sw_fini,
2168 .hw_init = vcn_v2_5_hw_init,
2169 .hw_fini = vcn_v2_5_hw_fini,
2170 .suspend = vcn_v2_5_suspend,
2171 .resume = vcn_v2_5_resume,
2172 .is_idle = vcn_v2_5_is_idle,
2173 .wait_for_idle = vcn_v2_5_wait_for_idle,
2174 .set_clockgating_state = vcn_v2_5_set_clockgating_state,
2175 .set_powergating_state = vcn_set_powergating_state,
2176 .dump_ip_state = vcn_v2_5_dump_ip_state,
2177 .print_ip_state = vcn_v2_5_print_ip_state,
2178 };
2179
2180 const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
2181 {
2182 .type = AMD_IP_BLOCK_TYPE_VCN,
2183 .major = 2,
2184 .minor = 5,
2185 .rev = 0,
2186 .funcs = &vcn_v2_5_ip_funcs,
2187 };
2188
2189 const struct amdgpu_ip_block_version vcn_v2_6_ip_block =
2190 {
2191 .type = AMD_IP_BLOCK_TYPE_VCN,
2192 .major = 2,
2193 .minor = 6,
2194 .rev = 0,
2195 .funcs = &vcn_v2_6_ip_funcs,
2196 };
2197
vcn_v2_6_query_poison_by_instance(struct amdgpu_device * adev,uint32_t instance,uint32_t sub_block)2198 static uint32_t vcn_v2_6_query_poison_by_instance(struct amdgpu_device *adev,
2199 uint32_t instance, uint32_t sub_block)
2200 {
2201 uint32_t poison_stat = 0, reg_value = 0;
2202
2203 switch (sub_block) {
2204 case AMDGPU_VCN_V2_6_VCPU_VCODEC:
2205 reg_value = RREG32_SOC15(VCN, instance, mmUVD_RAS_VCPU_VCODEC_STATUS);
2206 poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF);
2207 break;
2208 default:
2209 break;
2210 }
2211
2212 if (poison_stat)
2213 dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n",
2214 instance, sub_block);
2215
2216 return poison_stat;
2217 }
2218
vcn_v2_6_query_poison_status(struct amdgpu_device * adev)2219 static bool vcn_v2_6_query_poison_status(struct amdgpu_device *adev)
2220 {
2221 uint32_t inst, sub;
2222 uint32_t poison_stat = 0;
2223
2224 for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++)
2225 for (sub = 0; sub < AMDGPU_VCN_V2_6_MAX_SUB_BLOCK; sub++)
2226 poison_stat +=
2227 vcn_v2_6_query_poison_by_instance(adev, inst, sub);
2228
2229 return !!poison_stat;
2230 }
2231
2232 const struct amdgpu_ras_block_hw_ops vcn_v2_6_ras_hw_ops = {
2233 .query_poison_status = vcn_v2_6_query_poison_status,
2234 };
2235
2236 static struct amdgpu_vcn_ras vcn_v2_6_ras = {
2237 .ras_block = {
2238 .hw_ops = &vcn_v2_6_ras_hw_ops,
2239 .ras_late_init = amdgpu_vcn_ras_late_init,
2240 },
2241 };
2242
vcn_v2_5_set_ras_funcs(struct amdgpu_device * adev)2243 static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev)
2244 {
2245 switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) {
2246 case IP_VERSION(2, 6, 0):
2247 adev->vcn.ras = &vcn_v2_6_ras;
2248 break;
2249 default:
2250 break;
2251 }
2252 }
2253