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