This source file includes following definitions.
- vcn_v2_5_early_init
- vcn_v2_5_sw_init
- vcn_v2_5_sw_fini
- vcn_v2_5_hw_init
- vcn_v2_5_hw_fini
- vcn_v2_5_suspend
- vcn_v2_5_resume
- vcn_v2_5_mc_resume
- vcn_v2_5_disable_clock_gating
- vcn_v2_5_enable_clock_gating
- jpeg_v2_5_start
- jpeg_v2_5_stop
- vcn_v2_5_start
- vcn_v2_5_stop
- vcn_v2_5_dec_ring_get_rptr
- vcn_v2_5_dec_ring_get_wptr
- vcn_v2_5_dec_ring_set_wptr
- vcn_v2_5_enc_ring_get_rptr
- vcn_v2_5_enc_ring_get_wptr
- vcn_v2_5_enc_ring_set_wptr
- vcn_v2_5_jpeg_ring_get_rptr
- vcn_v2_5_jpeg_ring_get_wptr
- vcn_v2_5_jpeg_ring_set_wptr
- vcn_v2_5_set_dec_ring_funcs
- vcn_v2_5_set_enc_ring_funcs
- vcn_v2_5_set_jpeg_ring_funcs
- vcn_v2_5_is_idle
- vcn_v2_5_wait_for_idle
- vcn_v2_5_set_clockgating_state
- vcn_v2_5_set_powergating_state
- vcn_v2_5_set_interrupt_state
- vcn_v2_5_process_interrupt
- vcn_v2_5_set_irq_funcs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <linux/firmware.h>
25
26 #include "amdgpu.h"
27 #include "amdgpu_vcn.h"
28 #include "soc15.h"
29 #include "soc15d.h"
30 #include "vcn_v2_0.h"
31
32 #include "vcn/vcn_2_5_offset.h"
33 #include "vcn/vcn_2_5_sh_mask.h"
34 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
35
36 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
37 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
38 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10
39 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET 0x11
40 #define mmUVD_NO_OP_INTERNAL_OFFSET 0x29
41 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET 0x66
42 #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d
43
44 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431
45 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4
46 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5
47 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c
48
49 #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
50
51 #define VCN25_MAX_HW_INSTANCES_ARCTURUS 2
52
53 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
54 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
55 static void vcn_v2_5_set_jpeg_ring_funcs(struct amdgpu_device *adev);
56 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
57 static int vcn_v2_5_set_powergating_state(void *handle,
58 enum amd_powergating_state state);
59
60 static int amdgpu_ih_clientid_vcns[] = {
61 SOC15_IH_CLIENTID_VCN,
62 SOC15_IH_CLIENTID_VCN1
63 };
64
65
66
67
68
69
70
71
72 static int vcn_v2_5_early_init(void *handle)
73 {
74 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
75 if (adev->asic_type == CHIP_ARCTURUS) {
76 u32 harvest;
77 int i;
78
79 adev->vcn.num_vcn_inst = VCN25_MAX_HW_INSTANCES_ARCTURUS;
80 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
81 harvest = RREG32_SOC15(UVD, i, mmCC_UVD_HARVESTING);
82 if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
83 adev->vcn.harvest_config |= 1 << i;
84 }
85
86 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
87 AMDGPU_VCN_HARVEST_VCN1))
88
89 return -ENOENT;
90 } else
91 adev->vcn.num_vcn_inst = 1;
92
93 adev->vcn.num_enc_rings = 2;
94
95 vcn_v2_5_set_dec_ring_funcs(adev);
96 vcn_v2_5_set_enc_ring_funcs(adev);
97 vcn_v2_5_set_jpeg_ring_funcs(adev);
98 vcn_v2_5_set_irq_funcs(adev);
99
100 return 0;
101 }
102
103
104
105
106
107
108
109
110 static int vcn_v2_5_sw_init(void *handle)
111 {
112 struct amdgpu_ring *ring;
113 int i, j, r;
114 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
115
116 for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
117 if (adev->vcn.harvest_config & (1 << j))
118 continue;
119
120 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
121 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
122 if (r)
123 return r;
124
125
126 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
127 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
128 i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
129 if (r)
130 return r;
131 }
132
133
134 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
135 VCN_2_0__SRCID__JPEG_DECODE, &adev->vcn.inst[j].irq);
136 if (r)
137 return r;
138 }
139
140 r = amdgpu_vcn_sw_init(adev);
141 if (r)
142 return r;
143
144 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
145 const struct common_firmware_header *hdr;
146 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
147 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
148 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
149 adev->firmware.fw_size +=
150 ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
151
152 if (adev->vcn.num_vcn_inst == VCN25_MAX_HW_INSTANCES_ARCTURUS) {
153 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
154 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
155 adev->firmware.fw_size +=
156 ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
157 }
158 DRM_INFO("PSP loading VCN firmware\n");
159 }
160
161 r = amdgpu_vcn_resume(adev);
162 if (r)
163 return r;
164
165 for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
166 if (adev->vcn.harvest_config & (1 << j))
167 continue;
168 adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
169 adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
170 adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
171 adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
172 adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
173 adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
174
175 adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
176 adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(UVD, j, mmUVD_SCRATCH9);
177 adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
178 adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_DATA0);
179 adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
180 adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_DATA1);
181 adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
182 adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_CMD);
183 adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
184 adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(UVD, j, mmUVD_NO_OP);
185
186 adev->vcn.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
187 adev->vcn.inst[j].external.jpeg_pitch = SOC15_REG_OFFSET(UVD, j, mmUVD_JPEG_PITCH);
188
189 ring = &adev->vcn.inst[j].ring_dec;
190 ring->use_doorbell = true;
191 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8*j;
192 sprintf(ring->name, "vcn_dec_%d", j);
193 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
194 if (r)
195 return r;
196
197 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
198 ring = &adev->vcn.inst[j].ring_enc[i];
199 ring->use_doorbell = true;
200 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + i + 8*j;
201 sprintf(ring->name, "vcn_enc_%d.%d", j, i);
202 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
203 if (r)
204 return r;
205 }
206
207 ring = &adev->vcn.inst[j].ring_jpeg;
208 ring->use_doorbell = true;
209 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8*j;
210 sprintf(ring->name, "vcn_jpeg_%d", j);
211 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
212 if (r)
213 return r;
214 }
215
216 return 0;
217 }
218
219
220
221
222
223
224
225
226 static int vcn_v2_5_sw_fini(void *handle)
227 {
228 int r;
229 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
230
231 r = amdgpu_vcn_suspend(adev);
232 if (r)
233 return r;
234
235 r = amdgpu_vcn_sw_fini(adev);
236
237 return r;
238 }
239
240
241
242
243
244
245
246
247 static int vcn_v2_5_hw_init(void *handle)
248 {
249 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
250 struct amdgpu_ring *ring;
251 int i, j, r;
252
253 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
254 if (adev->vcn.harvest_config & (1 << j))
255 continue;
256 ring = &adev->vcn.inst[j].ring_dec;
257
258 adev->nbio_funcs->vcn_doorbell_range(adev, ring->use_doorbell,
259 ring->doorbell_index, j);
260
261 r = amdgpu_ring_test_ring(ring);
262 if (r) {
263 ring->sched.ready = false;
264 goto done;
265 }
266
267 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
268 ring = &adev->vcn.inst[j].ring_enc[i];
269 ring->sched.ready = false;
270 continue;
271 r = amdgpu_ring_test_ring(ring);
272 if (r) {
273 ring->sched.ready = false;
274 goto done;
275 }
276 }
277
278 ring = &adev->vcn.inst[j].ring_jpeg;
279 r = amdgpu_ring_test_ring(ring);
280 if (r) {
281 ring->sched.ready = false;
282 goto done;
283 }
284 }
285 done:
286 if (!r)
287 DRM_INFO("VCN decode and encode initialized successfully.\n");
288
289 return r;
290 }
291
292
293
294
295
296
297
298
299 static int vcn_v2_5_hw_fini(void *handle)
300 {
301 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
302 struct amdgpu_ring *ring;
303 int i;
304
305 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
306 if (adev->vcn.harvest_config & (1 << i))
307 continue;
308 ring = &adev->vcn.inst[i].ring_dec;
309
310 if (RREG32_SOC15(VCN, i, mmUVD_STATUS))
311 vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
312
313 ring->sched.ready = false;
314
315 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
316 ring = &adev->vcn.inst[i].ring_enc[i];
317 ring->sched.ready = false;
318 }
319
320 ring = &adev->vcn.inst[i].ring_jpeg;
321 ring->sched.ready = false;
322 }
323
324 return 0;
325 }
326
327
328
329
330
331
332
333
334 static int vcn_v2_5_suspend(void *handle)
335 {
336 int r;
337 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
338
339 r = vcn_v2_5_hw_fini(adev);
340 if (r)
341 return r;
342
343 r = amdgpu_vcn_suspend(adev);
344
345 return r;
346 }
347
348
349
350
351
352
353
354
355 static int vcn_v2_5_resume(void *handle)
356 {
357 int r;
358 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
359
360 r = amdgpu_vcn_resume(adev);
361 if (r)
362 return r;
363
364 r = vcn_v2_5_hw_init(adev);
365
366 return r;
367 }
368
369
370
371
372
373
374
375
376 static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
377 {
378 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
379 uint32_t offset;
380 int i;
381
382 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
383 if (adev->vcn.harvest_config & (1 << i))
384 continue;
385
386 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
387 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
388 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
389 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
390 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));
391 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
392 offset = 0;
393 } else {
394 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
395 lower_32_bits(adev->vcn.inst[i].gpu_addr));
396 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
397 upper_32_bits(adev->vcn.inst[i].gpu_addr));
398 offset = size;
399 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0,
400 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
401 }
402 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size);
403
404
405 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
406 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
407 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
408 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
409 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, 0);
410 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
411
412
413 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
414 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
415 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
416 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
417 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
418 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
419 }
420 }
421
422
423
424
425
426
427
428
429 static void vcn_v2_5_disable_clock_gating(struct amdgpu_device *adev)
430 {
431 uint32_t data;
432 int ret = 0;
433 int i;
434
435 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
436 if (adev->vcn.harvest_config & (1 << i))
437 continue;
438
439 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
440 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
441 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
442 else
443 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
444 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
445 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
446 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
447
448 data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE);
449 data &= ~(UVD_CGC_GATE__SYS_MASK
450 | UVD_CGC_GATE__UDEC_MASK
451 | UVD_CGC_GATE__MPEG2_MASK
452 | UVD_CGC_GATE__REGS_MASK
453 | UVD_CGC_GATE__RBC_MASK
454 | UVD_CGC_GATE__LMI_MC_MASK
455 | UVD_CGC_GATE__LMI_UMC_MASK
456 | UVD_CGC_GATE__IDCT_MASK
457 | UVD_CGC_GATE__MPRD_MASK
458 | UVD_CGC_GATE__MPC_MASK
459 | UVD_CGC_GATE__LBSI_MASK
460 | UVD_CGC_GATE__LRBBM_MASK
461 | UVD_CGC_GATE__UDEC_RE_MASK
462 | UVD_CGC_GATE__UDEC_CM_MASK
463 | UVD_CGC_GATE__UDEC_IT_MASK
464 | UVD_CGC_GATE__UDEC_DB_MASK
465 | UVD_CGC_GATE__UDEC_MP_MASK
466 | UVD_CGC_GATE__WCB_MASK
467 | UVD_CGC_GATE__VCPU_MASK
468 | UVD_CGC_GATE__MMSCH_MASK);
469
470 WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data);
471
472 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0, 0xFFFFFFFF, ret);
473
474 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
475 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
476 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
477 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
478 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
479 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
480 | UVD_CGC_CTRL__SYS_MODE_MASK
481 | UVD_CGC_CTRL__UDEC_MODE_MASK
482 | UVD_CGC_CTRL__MPEG2_MODE_MASK
483 | UVD_CGC_CTRL__REGS_MODE_MASK
484 | UVD_CGC_CTRL__RBC_MODE_MASK
485 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
486 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
487 | UVD_CGC_CTRL__IDCT_MODE_MASK
488 | UVD_CGC_CTRL__MPRD_MODE_MASK
489 | UVD_CGC_CTRL__MPC_MODE_MASK
490 | UVD_CGC_CTRL__LBSI_MODE_MASK
491 | UVD_CGC_CTRL__LRBBM_MODE_MASK
492 | UVD_CGC_CTRL__WCB_MODE_MASK
493 | UVD_CGC_CTRL__VCPU_MODE_MASK
494 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
495 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
496
497
498 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE);
499 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
500 | UVD_SUVD_CGC_GATE__SIT_MASK
501 | UVD_SUVD_CGC_GATE__SMP_MASK
502 | UVD_SUVD_CGC_GATE__SCM_MASK
503 | UVD_SUVD_CGC_GATE__SDB_MASK
504 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
505 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
506 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
507 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
508 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
509 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
510 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
511 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
512 | UVD_SUVD_CGC_GATE__SCLR_MASK
513 | UVD_SUVD_CGC_GATE__UVD_SC_MASK
514 | UVD_SUVD_CGC_GATE__ENT_MASK
515 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
516 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
517 | UVD_SUVD_CGC_GATE__SITE_MASK
518 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
519 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
520 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
521 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
522 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
523 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data);
524
525 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
526 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
527 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
528 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
529 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
530 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
531 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
532 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
533 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
534 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
535 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
536 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
537 }
538 }
539
540
541
542
543
544
545
546
547 static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
548 {
549 uint32_t data = 0;
550 int i;
551
552 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
553 if (adev->vcn.harvest_config & (1 << i))
554 continue;
555
556 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
557 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
558 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
559 else
560 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
561 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
562 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
563 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
564
565 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
566 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
567 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
568 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
569 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
570 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
571 | UVD_CGC_CTRL__SYS_MODE_MASK
572 | UVD_CGC_CTRL__UDEC_MODE_MASK
573 | UVD_CGC_CTRL__MPEG2_MODE_MASK
574 | UVD_CGC_CTRL__REGS_MODE_MASK
575 | UVD_CGC_CTRL__RBC_MODE_MASK
576 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
577 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
578 | UVD_CGC_CTRL__IDCT_MODE_MASK
579 | UVD_CGC_CTRL__MPRD_MODE_MASK
580 | UVD_CGC_CTRL__MPC_MODE_MASK
581 | UVD_CGC_CTRL__LBSI_MODE_MASK
582 | UVD_CGC_CTRL__LRBBM_MODE_MASK
583 | UVD_CGC_CTRL__WCB_MODE_MASK
584 | UVD_CGC_CTRL__VCPU_MODE_MASK);
585 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
586
587 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
588 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
589 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
590 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
591 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
592 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
593 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
594 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
595 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
596 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
597 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
598 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
599 }
600 }
601
602
603
604
605
606
607
608
609 static int jpeg_v2_5_start(struct amdgpu_device *adev)
610 {
611 struct amdgpu_ring *ring;
612 uint32_t tmp;
613 int i;
614
615 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
616 if (adev->vcn.harvest_config & (1 << i))
617 continue;
618 ring = &adev->vcn.inst[i].ring_jpeg;
619
620 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JPEG_POWER_STATUS), 0,
621 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
622
623
624 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL);
625 tmp |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
626 tmp |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
627 tmp |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
628 WREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL, tmp);
629
630 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_GATE);
631 tmp &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
632 | JPEG_CGC_GATE__JPEG2_DEC_MASK
633 | JPEG_CGC_GATE__JMCIF_MASK
634 | JPEG_CGC_GATE__JRBBM_MASK);
635 WREG32_SOC15(VCN, i, mmJPEG_CGC_GATE, tmp);
636
637 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL);
638 tmp &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK
639 | JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK
640 | JPEG_CGC_CTRL__JMCIF_MODE_MASK
641 | JPEG_CGC_CTRL__JRBBM_MODE_MASK);
642 WREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL, tmp);
643
644
645 WREG32_SOC15(UVD, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,
646 adev->gfx.config.gb_addr_config);
647 WREG32_SOC15(UVD, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,
648 adev->gfx.config.gb_addr_config);
649
650
651 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JMI_CNTL), 0,
652 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
653
654
655 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmJPEG_SYS_INT_EN),
656 JPEG_SYS_INT_EN__DJRBC_MASK,
657 ~JPEG_SYS_INT_EN__DJRBC_MASK);
658
659 WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_VMID, 0);
660 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
661 WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
662 lower_32_bits(ring->gpu_addr));
663 WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
664 upper_32_bits(ring->gpu_addr));
665 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_RPTR, 0);
666 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_WPTR, 0);
667 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);
668 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
669 ring->wptr = RREG32_SOC15(UVD, i, mmUVD_JRBC_RB_WPTR);
670 }
671
672 return 0;
673 }
674
675
676
677
678
679
680
681
682 static int jpeg_v2_5_stop(struct amdgpu_device *adev)
683 {
684 uint32_t tmp;
685 int i;
686
687 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
688 if (adev->vcn.harvest_config & (1 << i))
689 continue;
690
691 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JMI_CNTL),
692 UVD_JMI_CNTL__SOFT_RESET_MASK,
693 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
694
695 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_GATE);
696 tmp |= (JPEG_CGC_GATE__JPEG_DEC_MASK
697 |JPEG_CGC_GATE__JPEG2_DEC_MASK
698 |JPEG_CGC_GATE__JMCIF_MASK
699 |JPEG_CGC_GATE__JRBBM_MASK);
700 WREG32_SOC15(VCN, i, mmJPEG_CGC_GATE, tmp);
701
702
703 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JPEG_POWER_STATUS),
704 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
705 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
706 }
707
708 return 0;
709 }
710
711 static int vcn_v2_5_start(struct amdgpu_device *adev)
712 {
713 struct amdgpu_ring *ring;
714 uint32_t rb_bufsz, tmp;
715 int i, j, k, r;
716
717 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
718 if (adev->vcn.harvest_config & (1 << i))
719 continue;
720
721 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS), 0,
722 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
723
724
725 tmp = RREG32_SOC15(UVD, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
726 WREG32_SOC15(UVD, i, mmUVD_STATUS, tmp);
727 }
728
729
730 vcn_v2_5_disable_clock_gating(adev);
731
732 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
733 if (adev->vcn.harvest_config & (1 << i))
734 continue;
735
736 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
737 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
738
739
740 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), 0,
741 ~UVD_MASTINT_EN__VCPU_EN_MASK);
742
743
744 tmp = RREG32_SOC15(UVD, i, mmUVD_LMI_CTRL);
745 tmp &= ~0xff;
746 WREG32_SOC15(UVD, i, mmUVD_LMI_CTRL, tmp | 0x8|
747 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
748 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
749 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
750 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
751
752
753 tmp = RREG32_SOC15(UVD, i, mmUVD_MPC_CNTL);
754 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
755 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
756 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
757
758
759 WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUXA0,
760 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
761 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
762 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
763 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
764
765
766 WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUXB0,
767 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
768 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
769 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
770 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
771
772
773 WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUX,
774 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
775 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
776 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
777 }
778
779 vcn_v2_5_mc_resume(adev);
780
781 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
782 if (adev->vcn.harvest_config & (1 << i))
783 continue;
784
785 WREG32_SOC15(UVD, i, mmUVD_GFX8_ADDR_CONFIG,
786 adev->gfx.config.gb_addr_config);
787 WREG32_SOC15(UVD, i, mmUVD_GFX8_ADDR_CONFIG,
788 adev->gfx.config.gb_addr_config);
789
790
791 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0,
792 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
793
794
795 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_ARB_CTRL), 0,
796 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
797
798 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
799 ~UVD_VCPU_CNTL__BLK_RST_MASK);
800
801 for (k = 0; k < 10; ++k) {
802 uint32_t status;
803
804 for (j = 0; j < 100; ++j) {
805 status = RREG32_SOC15(UVD, i, mmUVD_STATUS);
806 if (status & 2)
807 break;
808 if (amdgpu_emu_mode == 1)
809 msleep(500);
810 else
811 mdelay(10);
812 }
813 r = 0;
814 if (status & 2)
815 break;
816
817 DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
818 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
819 UVD_VCPU_CNTL__BLK_RST_MASK,
820 ~UVD_VCPU_CNTL__BLK_RST_MASK);
821 mdelay(10);
822 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
823 ~UVD_VCPU_CNTL__BLK_RST_MASK);
824
825 mdelay(10);
826 r = -1;
827 }
828
829 if (r) {
830 DRM_ERROR("VCN decode not responding, giving up!!!\n");
831 return r;
832 }
833
834
835 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
836 UVD_MASTINT_EN__VCPU_EN_MASK,
837 ~UVD_MASTINT_EN__VCPU_EN_MASK);
838
839
840 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0,
841 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
842
843 WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_VMID, 0);
844
845 ring = &adev->vcn.inst[i].ring_dec;
846
847 rb_bufsz = order_base_2(ring->ring_size);
848 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
849 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
850 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
851 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
852 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
853 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, tmp);
854
855
856 WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
857 lower_32_bits(ring->gpu_addr));
858 WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
859 upper_32_bits(ring->gpu_addr));
860
861
862 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR, 0);
863
864 ring->wptr = RREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR);
865 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_WPTR,
866 lower_32_bits(ring->wptr));
867 ring = &adev->vcn.inst[i].ring_enc[0];
868 WREG32_SOC15(UVD, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
869 WREG32_SOC15(UVD, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
870 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
871 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
872 WREG32_SOC15(UVD, i, mmUVD_RB_SIZE, ring->ring_size / 4);
873
874 ring = &adev->vcn.inst[i].ring_enc[1];
875 WREG32_SOC15(UVD, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
876 WREG32_SOC15(UVD, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
877 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
878 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
879 WREG32_SOC15(UVD, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
880 }
881 r = jpeg_v2_5_start(adev);
882
883 return r;
884 }
885
886 static int vcn_v2_5_stop(struct amdgpu_device *adev)
887 {
888 uint32_t tmp;
889 int i, r;
890
891 r = jpeg_v2_5_stop(adev);
892 if (r)
893 return r;
894
895 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
896 if (adev->vcn.harvest_config & (1 << i))
897 continue;
898
899 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
900 if (r)
901 return r;
902
903 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
904 UVD_LMI_STATUS__READ_CLEAN_MASK |
905 UVD_LMI_STATUS__WRITE_CLEAN_MASK |
906 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
907 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp, r);
908 if (r)
909 return r;
910
911
912 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
913 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
914 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
915
916 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
917 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
918 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp, r);
919 if (r)
920 return r;
921
922
923 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_ARB_CTRL),
924 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
925 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
926
927
928 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
929 UVD_VCPU_CNTL__BLK_RST_MASK,
930 ~UVD_VCPU_CNTL__BLK_RST_MASK);
931
932
933 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
934 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
935
936
937 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
938
939 vcn_v2_5_enable_clock_gating(adev);
940
941
942 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS),
943 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
944 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
945 }
946
947 return 0;
948 }
949
950
951
952
953
954
955
956
957 static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
958 {
959 struct amdgpu_device *adev = ring->adev;
960
961 return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR);
962 }
963
964
965
966
967
968
969
970
971 static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
972 {
973 struct amdgpu_device *adev = ring->adev;
974
975 if (ring->use_doorbell)
976 return adev->wb.wb[ring->wptr_offs];
977 else
978 return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR);
979 }
980
981
982
983
984
985
986
987
988 static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
989 {
990 struct amdgpu_device *adev = ring->adev;
991
992 if (ring->use_doorbell) {
993 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
994 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
995 } else {
996 WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
997 }
998 }
999
1000 static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
1001 .type = AMDGPU_RING_TYPE_VCN_DEC,
1002 .align_mask = 0xf,
1003 .vmhub = AMDGPU_MMHUB_1,
1004 .get_rptr = vcn_v2_5_dec_ring_get_rptr,
1005 .get_wptr = vcn_v2_5_dec_ring_get_wptr,
1006 .set_wptr = vcn_v2_5_dec_ring_set_wptr,
1007 .emit_frame_size =
1008 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1009 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1010 8 +
1011 14 + 14 +
1012 6,
1013 .emit_ib_size = 8,
1014 .emit_ib = vcn_v2_0_dec_ring_emit_ib,
1015 .emit_fence = vcn_v2_0_dec_ring_emit_fence,
1016 .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1017 .test_ring = amdgpu_vcn_dec_ring_test_ring,
1018 .test_ib = amdgpu_vcn_dec_ring_test_ib,
1019 .insert_nop = vcn_v2_0_dec_ring_insert_nop,
1020 .insert_start = vcn_v2_0_dec_ring_insert_start,
1021 .insert_end = vcn_v2_0_dec_ring_insert_end,
1022 .pad_ib = amdgpu_ring_generic_pad_ib,
1023 .begin_use = amdgpu_vcn_ring_begin_use,
1024 .end_use = amdgpu_vcn_ring_end_use,
1025 .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1026 .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1027 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1028 };
1029
1030
1031
1032
1033
1034
1035
1036
1037 static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
1038 {
1039 struct amdgpu_device *adev = ring->adev;
1040
1041 if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1042 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR);
1043 else
1044 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2);
1045 }
1046
1047
1048
1049
1050
1051
1052
1053
1054 static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
1055 {
1056 struct amdgpu_device *adev = ring->adev;
1057
1058 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1059 if (ring->use_doorbell)
1060 return adev->wb.wb[ring->wptr_offs];
1061 else
1062 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR);
1063 } else {
1064 if (ring->use_doorbell)
1065 return adev->wb.wb[ring->wptr_offs];
1066 else
1067 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2);
1068 }
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078 static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
1079 {
1080 struct amdgpu_device *adev = ring->adev;
1081
1082 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1083 if (ring->use_doorbell) {
1084 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1085 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1086 } else {
1087 WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1088 }
1089 } else {
1090 if (ring->use_doorbell) {
1091 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1092 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1093 } else {
1094 WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1095 }
1096 }
1097 }
1098
1099 static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
1100 .type = AMDGPU_RING_TYPE_VCN_ENC,
1101 .align_mask = 0x3f,
1102 .nop = VCN_ENC_CMD_NO_OP,
1103 .vmhub = AMDGPU_MMHUB_1,
1104 .get_rptr = vcn_v2_5_enc_ring_get_rptr,
1105 .get_wptr = vcn_v2_5_enc_ring_get_wptr,
1106 .set_wptr = vcn_v2_5_enc_ring_set_wptr,
1107 .emit_frame_size =
1108 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1109 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1110 4 +
1111 5 + 5 +
1112 1,
1113 .emit_ib_size = 5,
1114 .emit_ib = vcn_v2_0_enc_ring_emit_ib,
1115 .emit_fence = vcn_v2_0_enc_ring_emit_fence,
1116 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1117 .test_ring = amdgpu_vcn_enc_ring_test_ring,
1118 .test_ib = amdgpu_vcn_enc_ring_test_ib,
1119 .insert_nop = amdgpu_ring_insert_nop,
1120 .insert_end = vcn_v2_0_enc_ring_insert_end,
1121 .pad_ib = amdgpu_ring_generic_pad_ib,
1122 .begin_use = amdgpu_vcn_ring_begin_use,
1123 .end_use = amdgpu_vcn_ring_end_use,
1124 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1125 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1126 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1127 };
1128
1129
1130
1131
1132
1133
1134
1135
1136 static uint64_t vcn_v2_5_jpeg_ring_get_rptr(struct amdgpu_ring *ring)
1137 {
1138 struct amdgpu_device *adev = ring->adev;
1139
1140 return RREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_RPTR);
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150 static uint64_t vcn_v2_5_jpeg_ring_get_wptr(struct amdgpu_ring *ring)
1151 {
1152 struct amdgpu_device *adev = ring->adev;
1153
1154 if (ring->use_doorbell)
1155 return adev->wb.wb[ring->wptr_offs];
1156 else
1157 return RREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_WPTR);
1158 }
1159
1160
1161
1162
1163
1164
1165
1166
1167 static void vcn_v2_5_jpeg_ring_set_wptr(struct amdgpu_ring *ring)
1168 {
1169 struct amdgpu_device *adev = ring->adev;
1170
1171 if (ring->use_doorbell) {
1172 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1173 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1174 } else {
1175 WREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
1176 }
1177 }
1178
1179 static const struct amdgpu_ring_funcs vcn_v2_5_jpeg_ring_vm_funcs = {
1180 .type = AMDGPU_RING_TYPE_VCN_JPEG,
1181 .align_mask = 0xf,
1182 .vmhub = AMDGPU_MMHUB_1,
1183 .get_rptr = vcn_v2_5_jpeg_ring_get_rptr,
1184 .get_wptr = vcn_v2_5_jpeg_ring_get_wptr,
1185 .set_wptr = vcn_v2_5_jpeg_ring_set_wptr,
1186 .emit_frame_size =
1187 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1188 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1189 8 +
1190 18 + 18 +
1191 8 + 16,
1192 .emit_ib_size = 22,
1193 .emit_ib = vcn_v2_0_jpeg_ring_emit_ib,
1194 .emit_fence = vcn_v2_0_jpeg_ring_emit_fence,
1195 .emit_vm_flush = vcn_v2_0_jpeg_ring_emit_vm_flush,
1196 .test_ring = amdgpu_vcn_jpeg_ring_test_ring,
1197 .test_ib = amdgpu_vcn_jpeg_ring_test_ib,
1198 .insert_nop = vcn_v2_0_jpeg_ring_nop,
1199 .insert_start = vcn_v2_0_jpeg_ring_insert_start,
1200 .insert_end = vcn_v2_0_jpeg_ring_insert_end,
1201 .pad_ib = amdgpu_ring_generic_pad_ib,
1202 .begin_use = amdgpu_vcn_ring_begin_use,
1203 .end_use = amdgpu_vcn_ring_end_use,
1204 .emit_wreg = vcn_v2_0_jpeg_ring_emit_wreg,
1205 .emit_reg_wait = vcn_v2_0_jpeg_ring_emit_reg_wait,
1206 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1207 };
1208
1209 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
1210 {
1211 int i;
1212
1213 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1214 if (adev->vcn.harvest_config & (1 << i))
1215 continue;
1216 adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
1217 adev->vcn.inst[i].ring_dec.me = i;
1218 DRM_INFO("VCN(%d) decode is enabled in VM mode\n", i);
1219 }
1220 }
1221
1222 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
1223 {
1224 int i, j;
1225
1226 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
1227 if (adev->vcn.harvest_config & (1 << j))
1228 continue;
1229 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
1230 adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
1231 adev->vcn.inst[j].ring_enc[i].me = j;
1232 }
1233 DRM_INFO("VCN(%d) encode is enabled in VM mode\n", j);
1234 }
1235 }
1236
1237 static void vcn_v2_5_set_jpeg_ring_funcs(struct amdgpu_device *adev)
1238 {
1239 int i;
1240
1241 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1242 if (adev->vcn.harvest_config & (1 << i))
1243 continue;
1244 adev->vcn.inst[i].ring_jpeg.funcs = &vcn_v2_5_jpeg_ring_vm_funcs;
1245 adev->vcn.inst[i].ring_jpeg.me = i;
1246 DRM_INFO("VCN(%d) jpeg decode is enabled in VM mode\n", i);
1247 }
1248 }
1249
1250 static bool vcn_v2_5_is_idle(void *handle)
1251 {
1252 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1253 int i, ret = 1;
1254
1255 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1256 if (adev->vcn.harvest_config & (1 << i))
1257 continue;
1258 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1259 }
1260
1261 return ret;
1262 }
1263
1264 static int vcn_v2_5_wait_for_idle(void *handle)
1265 {
1266 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1267 int i, ret = 0;
1268
1269 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1270 if (adev->vcn.harvest_config & (1 << i))
1271 continue;
1272 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1273 UVD_STATUS__IDLE, ret);
1274 if (ret)
1275 return ret;
1276 }
1277
1278 return ret;
1279 }
1280
1281 static int vcn_v2_5_set_clockgating_state(void *handle,
1282 enum amd_clockgating_state state)
1283 {
1284 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1285 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
1286
1287 if (enable) {
1288 if (vcn_v2_5_is_idle(handle))
1289 return -EBUSY;
1290 vcn_v2_5_enable_clock_gating(adev);
1291 } else {
1292 vcn_v2_5_disable_clock_gating(adev);
1293 }
1294
1295 return 0;
1296 }
1297
1298 static int vcn_v2_5_set_powergating_state(void *handle,
1299 enum amd_powergating_state state)
1300 {
1301 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1302 int ret;
1303
1304 if(state == adev->vcn.cur_state)
1305 return 0;
1306
1307 if (state == AMD_PG_STATE_GATE)
1308 ret = vcn_v2_5_stop(adev);
1309 else
1310 ret = vcn_v2_5_start(adev);
1311
1312 if(!ret)
1313 adev->vcn.cur_state = state;
1314
1315 return ret;
1316 }
1317
1318 static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
1319 struct amdgpu_irq_src *source,
1320 unsigned type,
1321 enum amdgpu_interrupt_state state)
1322 {
1323 return 0;
1324 }
1325
1326 static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
1327 struct amdgpu_irq_src *source,
1328 struct amdgpu_iv_entry *entry)
1329 {
1330 uint32_t ip_instance;
1331
1332 switch (entry->client_id) {
1333 case SOC15_IH_CLIENTID_VCN:
1334 ip_instance = 0;
1335 break;
1336 case SOC15_IH_CLIENTID_VCN1:
1337 ip_instance = 1;
1338 break;
1339 default:
1340 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1341 return 0;
1342 }
1343
1344 DRM_DEBUG("IH: VCN TRAP\n");
1345
1346 switch (entry->src_id) {
1347 case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
1348 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
1349 break;
1350 case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1351 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
1352 break;
1353 case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
1354 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
1355 break;
1356 case VCN_2_0__SRCID__JPEG_DECODE:
1357 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_jpeg);
1358 break;
1359 default:
1360 DRM_ERROR("Unhandled interrupt: %d %d\n",
1361 entry->src_id, entry->src_data[0]);
1362 break;
1363 }
1364
1365 return 0;
1366 }
1367
1368 static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
1369 .set = vcn_v2_5_set_interrupt_state,
1370 .process = vcn_v2_5_process_interrupt,
1371 };
1372
1373 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
1374 {
1375 int i;
1376
1377 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1378 if (adev->vcn.harvest_config & (1 << i))
1379 continue;
1380 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 2;
1381 adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
1382 }
1383 }
1384
1385 static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
1386 .name = "vcn_v2_5",
1387 .early_init = vcn_v2_5_early_init,
1388 .late_init = NULL,
1389 .sw_init = vcn_v2_5_sw_init,
1390 .sw_fini = vcn_v2_5_sw_fini,
1391 .hw_init = vcn_v2_5_hw_init,
1392 .hw_fini = vcn_v2_5_hw_fini,
1393 .suspend = vcn_v2_5_suspend,
1394 .resume = vcn_v2_5_resume,
1395 .is_idle = vcn_v2_5_is_idle,
1396 .wait_for_idle = vcn_v2_5_wait_for_idle,
1397 .check_soft_reset = NULL,
1398 .pre_soft_reset = NULL,
1399 .soft_reset = NULL,
1400 .post_soft_reset = NULL,
1401 .set_clockgating_state = vcn_v2_5_set_clockgating_state,
1402 .set_powergating_state = vcn_v2_5_set_powergating_state,
1403 };
1404
1405 const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
1406 {
1407 .type = AMD_IP_BLOCK_TYPE_VCN,
1408 .major = 2,
1409 .minor = 5,
1410 .rev = 0,
1411 .funcs = &vcn_v2_5_ip_funcs,
1412 };