drm/amdgpu: add initial VCN2.0 support (v2)
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / vcn_v2_0.c
CommitLineData
1b61de45
LL
1/*
2 * Copyright 2018 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/drmP.h>
26#include "amdgpu.h"
27#include "amdgpu_vcn.h"
28#include "soc15.h"
29#include "soc15d.h"
30
31#include "vcn/vcn_2_0_0_offset.h"
32#include "vcn/vcn_2_0_0_sh_mask.h"
33#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
34
35#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x1fd
36#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x503
37#define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x504
38#define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET 0x505
39#define mmUVD_NO_OP_INTERNAL_OFFSET 0x53f
40#define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET 0x54a
41#define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d
42
43#define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x1e1
44#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x5a6
45#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x5a7
46#define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x1e2
47#define mmUVD_GPCOM_SYS_CMD_INTERNAL_OFFSET 0x1bF
48
49#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff
50#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029
51#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a
52#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b
53#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea
54#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb
55#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf
56#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1
57#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8
58#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9
59#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082
60#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec
61#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed
62#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085
63#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084
64#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089
65#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
66
67#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000
68
69static int vcn_v2_0_stop(struct amdgpu_device *adev);
70static void vcn_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev);
71static void vcn_v2_0_set_enc_ring_funcs(struct amdgpu_device *adev);
72static void vcn_v2_0_set_jpeg_ring_funcs(struct amdgpu_device *adev);
73static void vcn_v2_0_set_irq_funcs(struct amdgpu_device *adev);
74static int vcn_v2_0_set_powergating_state(void *handle,
75 enum amd_powergating_state state);
76
77/**
78 * vcn_v2_0_early_init - set function pointers
79 *
80 * @handle: amdgpu_device pointer
81 *
82 * Set ring and irq function pointers
83 */
84static int vcn_v2_0_early_init(void *handle)
85{
86 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
87
88 adev->vcn.num_enc_rings = 2;
89
90 vcn_v2_0_set_dec_ring_funcs(adev);
91 vcn_v2_0_set_enc_ring_funcs(adev);
92 vcn_v2_0_set_jpeg_ring_funcs(adev);
93 vcn_v2_0_set_irq_funcs(adev);
94
95 return 0;
96}
97
98/**
99 * vcn_v2_0_sw_init - sw init for VCN block
100 *
101 * @handle: amdgpu_device pointer
102 *
103 * Load firmware and sw initialization
104 */
105static int vcn_v2_0_sw_init(void *handle)
106{
107 struct amdgpu_ring *ring;
108 int i, r;
109 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
110
111 /* VCN DEC TRAP */
112 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
113 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT,
114 &adev->vcn.irq);
115 if (r)
116 return r;
117
118 /* VCN ENC TRAP */
119 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
120 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
121 i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE,
122 &adev->vcn.irq);
123 if (r)
124 return r;
125 }
126
127 /* VCN JPEG TRAP */
128 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
129 VCN_2_0__SRCID__JPEG_DECODE,
130 &adev->vcn.irq);
131 if (r)
132 return r;
133
134 r = amdgpu_vcn_sw_init(adev);
135 if (r)
136 return r;
137
138 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
139 const struct common_firmware_header *hdr;
140 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
141 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
142 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
143 adev->firmware.fw_size +=
144 ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
145 DRM_INFO("PSP loading VCN firmware\n");
146 }
147
148 r = amdgpu_vcn_resume(adev);
149 if (r)
150 return r;
151
152 ring = &adev->vcn.ring_dec;
153
154 ring->use_doorbell = true;
155 ring->doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 << 1;
156
157 sprintf(ring->name, "vcn_dec");
158 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.irq, 0);
159 if (r)
160 return r;
161
162 adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
163 adev->vcn.external.scratch9 = SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9);
164 adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
165 adev->vcn.external.data0 = SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0);
166 adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
167 adev->vcn.external.data1 = SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1);
168 adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
169 adev->vcn.external.cmd = SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD);
170 adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
171 adev->vcn.external.nop = SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP);
172
173 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
174 ring = &adev->vcn.ring_enc[i];
175 ring->use_doorbell = true;
176 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + i;
177 sprintf(ring->name, "vcn_enc%d", i);
178 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.irq, 0);
179 if (r)
180 return r;
181 }
182
183 ring = &adev->vcn.ring_jpeg;
184 ring->use_doorbell = true;
185 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
186 sprintf(ring->name, "vcn_jpeg");
187 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.irq, 0);
188 if (r)
189 return r;
190
191 adev->vcn.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
192 adev->vcn.external.jpeg_pitch = SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH);
193
194 return 0;
195}
196
197/**
198 * vcn_v2_0_sw_fini - sw fini for VCN block
199 *
200 * @handle: amdgpu_device pointer
201 *
202 * VCN suspend and free up sw allocation
203 */
204static int vcn_v2_0_sw_fini(void *handle)
205{
206 int r;
207 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
208
209 r = amdgpu_vcn_suspend(adev);
210 if (r)
211 return r;
212
213 r = amdgpu_vcn_sw_fini(adev);
214
215 return r;
216}
217
218/**
219 * vcn_v2_0_hw_init - start and test VCN block
220 *
221 * @handle: amdgpu_device pointer
222 *
223 * Initialize the hardware, boot up the VCPU and do some testing
224 */
225static int vcn_v2_0_hw_init(void *handle)
226{
227 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
228 struct amdgpu_ring *ring = &adev->vcn.ring_dec;
229 int i, r;
230
231 adev->nbio_funcs->vcn_doorbell_range(adev, ring->use_doorbell,
232 ring->doorbell_index);
233
234 ring->sched.ready = true;
235 r = amdgpu_ring_test_ring(ring);
236 if (r) {
237 ring->sched.ready = false;
238 goto done;
239 }
240
241 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
242 ring = &adev->vcn.ring_enc[i];
243 ring->sched.ready = true;
244 r = amdgpu_ring_test_ring(ring);
245 if (r) {
246 ring->sched.ready = false;
247 goto done;
248 }
249 }
250
251 ring = &adev->vcn.ring_jpeg;
252 ring->sched.ready = true;
253 r = amdgpu_ring_test_ring(ring);
254 if (r) {
255 ring->sched.ready = false;
256 goto done;
257 }
258
259done:
260 if (!r)
261 DRM_INFO("VCN decode and encode initialized successfully.\n");
262
263 return r;
264}
265
266/**
267 * vcn_v2_0_hw_fini - stop the hardware block
268 *
269 * @handle: amdgpu_device pointer
270 *
271 * Stop the VCN block, mark ring as not ready any more
272 */
273static int vcn_v2_0_hw_fini(void *handle)
274{
275 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
276 struct amdgpu_ring *ring = &adev->vcn.ring_dec;
277 int i;
278
279 if (RREG32_SOC15(VCN, 0, mmUVD_STATUS))
280 vcn_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
281
282 ring->sched.ready = false;
283
284 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
285 ring = &adev->vcn.ring_enc[i];
286 ring->sched.ready = false;
287 }
288
289 ring = &adev->vcn.ring_jpeg;
290 ring->sched.ready = false;
291
292 return 0;
293}
294
295/**
296 * vcn_v2_0_suspend - suspend VCN block
297 *
298 * @handle: amdgpu_device pointer
299 *
300 * HW fini and suspend VCN block
301 */
302static int vcn_v2_0_suspend(void *handle)
303{
304 int r;
305 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
306
307 r = vcn_v2_0_hw_fini(adev);
308 if (r)
309 return r;
310
311 r = amdgpu_vcn_suspend(adev);
312
313 return r;
314}
315
316/**
317 * vcn_v2_0_resume - resume VCN block
318 *
319 * @handle: amdgpu_device pointer
320 *
321 * Resume firmware and hw init VCN block
322 */
323static int vcn_v2_0_resume(void *handle)
324{
325 int r;
326 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
327
328 r = amdgpu_vcn_resume(adev);
329 if (r)
330 return r;
331
332 r = vcn_v2_0_hw_init(adev);
333
334 return r;
335}
336
337/**
338 * vcn_v2_0_mc_resume - memory controller programming
339 *
340 * @adev: amdgpu_device pointer
341 *
342 * Let the VCN memory controller know it's offsets
343 */
344static void vcn_v2_0_mc_resume(struct amdgpu_device *adev)
345{
346 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
347 uint32_t offset;
348
349 /* cache window 0: fw */
350 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
351 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
352 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
353 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
354 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));
355 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0);
356 offset = 0;
357 } else {
358 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
359 lower_32_bits(adev->vcn.gpu_addr));
360 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
361 upper_32_bits(adev->vcn.gpu_addr));
362 offset = size;
363 /* No signed header for now from firmware
364 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0,
365 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
366 */
367 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0);
368 }
369
370 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size);
371
372 /* cache window 1: stack */
373 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
374 lower_32_bits(adev->vcn.gpu_addr + offset));
375 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
376 upper_32_bits(adev->vcn.gpu_addr + offset));
377 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0);
378 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
379
380 /* cache window 2: context */
381 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
382 lower_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
383 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
384 upper_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
385 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0);
386 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
387
388 WREG32_SOC15(UVD, 0, mmUVD_GFX10_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
389 WREG32_SOC15(UVD, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
390}
391
392/**
393 * vcn_v2_0_disable_clock_gating - disable VCN clock gating
394 *
395 * @adev: amdgpu_device pointer
396 * @sw: enable SW clock gating
397 *
398 * Disable clock gating for VCN block
399 */
400static void vcn_v2_0_disable_clock_gating(struct amdgpu_device *adev)
401{
402 uint32_t data;
403
404 /* UVD disable CGC */
405 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
406 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
407 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
408 else
409 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
410 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
411 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
412 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
413
414 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_GATE);
415 data &= ~(UVD_CGC_GATE__SYS_MASK
416 | UVD_CGC_GATE__UDEC_MASK
417 | UVD_CGC_GATE__MPEG2_MASK
418 | UVD_CGC_GATE__REGS_MASK
419 | UVD_CGC_GATE__RBC_MASK
420 | UVD_CGC_GATE__LMI_MC_MASK
421 | UVD_CGC_GATE__LMI_UMC_MASK
422 | UVD_CGC_GATE__IDCT_MASK
423 | UVD_CGC_GATE__MPRD_MASK
424 | UVD_CGC_GATE__MPC_MASK
425 | UVD_CGC_GATE__LBSI_MASK
426 | UVD_CGC_GATE__LRBBM_MASK
427 | UVD_CGC_GATE__UDEC_RE_MASK
428 | UVD_CGC_GATE__UDEC_CM_MASK
429 | UVD_CGC_GATE__UDEC_IT_MASK
430 | UVD_CGC_GATE__UDEC_DB_MASK
431 | UVD_CGC_GATE__UDEC_MP_MASK
432 | UVD_CGC_GATE__WCB_MASK
433 | UVD_CGC_GATE__VCPU_MASK
434 | UVD_CGC_GATE__SCPU_MASK);
435 WREG32_SOC15(VCN, 0, mmUVD_CGC_GATE, data);
436
437 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
438 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
439 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
440 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
441 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
442 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
443 | UVD_CGC_CTRL__SYS_MODE_MASK
444 | UVD_CGC_CTRL__UDEC_MODE_MASK
445 | UVD_CGC_CTRL__MPEG2_MODE_MASK
446 | UVD_CGC_CTRL__REGS_MODE_MASK
447 | UVD_CGC_CTRL__RBC_MODE_MASK
448 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
449 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
450 | UVD_CGC_CTRL__IDCT_MODE_MASK
451 | UVD_CGC_CTRL__MPRD_MODE_MASK
452 | UVD_CGC_CTRL__MPC_MODE_MASK
453 | UVD_CGC_CTRL__LBSI_MODE_MASK
454 | UVD_CGC_CTRL__LRBBM_MODE_MASK
455 | UVD_CGC_CTRL__WCB_MODE_MASK
456 | UVD_CGC_CTRL__VCPU_MODE_MASK
457 | UVD_CGC_CTRL__SCPU_MODE_MASK);
458 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
459
460 /* turn on */
461 data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_GATE);
462 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
463 | UVD_SUVD_CGC_GATE__SIT_MASK
464 | UVD_SUVD_CGC_GATE__SMP_MASK
465 | UVD_SUVD_CGC_GATE__SCM_MASK
466 | UVD_SUVD_CGC_GATE__SDB_MASK
467 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
468 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
469 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
470 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
471 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
472 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
473 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
474 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
475 | UVD_SUVD_CGC_GATE__SCLR_MASK
476 | UVD_SUVD_CGC_GATE__UVD_SC_MASK
477 | UVD_SUVD_CGC_GATE__ENT_MASK
478 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
479 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
480 | UVD_SUVD_CGC_GATE__SITE_MASK
481 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
482 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
483 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
484 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
485 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
486 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_GATE, data);
487
488 data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL);
489 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
490 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
491 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
492 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
493 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
494 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
495 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
496 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
497 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
498 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
499 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);
500}
501
502/**
503 * jpeg_v2_0_start - start JPEG block
504 *
505 * @adev: amdgpu_device pointer
506 *
507 * Setup and start the JPEG block
508 */
509static int jpeg_v2_0_start(struct amdgpu_device *adev)
510{
511 struct amdgpu_ring *ring = &adev->vcn.ring_jpeg;
512 uint32_t tmp;
513 int r = 0;
514
515 /* disable power gating */
516 tmp = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
517 WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_PGFSM_CONFIG), tmp);
518
519 SOC15_WAIT_ON_RREG(VCN, 0,
520 mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON,
521 UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK, r);
522
523 if (r) {
524 DRM_ERROR("amdgpu: JPEG disable power gating failed\n");
525 return r;
526 }
527
528 /* Removing the anti hang mechanism to indicate the UVDJ tile is ON */
529 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_POWER_STATUS)) & ~0x1;
530 WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_POWER_STATUS), tmp);
531
532 /* JPEG disable CGC */
533 tmp = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);
534 tmp |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
535 tmp |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
536 tmp |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
537 WREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL, tmp);
538
539 tmp = RREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE);
540 tmp &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
541 | JPEG_CGC_GATE__JPEG2_DEC_MASK
542 | JPEG_CGC_GATE__JPEG_ENC_MASK
543 | JPEG_CGC_GATE__JMCIF_MASK
544 | JPEG_CGC_GATE__JRBBM_MASK);
545 WREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE, tmp);
546
547 /* enable JMI channel */
548 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_JMI_CNTL), 0,
549 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
550
551 /* enable System Interrupt for JRBC */
552 WREG32_P(SOC15_REG_OFFSET(VCN, 0, mmJPEG_SYS_INT_EN),
553 JPEG_SYS_INT_EN__DJRBC_MASK,
554 ~JPEG_SYS_INT_EN__DJRBC_MASK);
555
556 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
557 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
558 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
559 lower_32_bits(ring->gpu_addr));
560 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
561 upper_32_bits(ring->gpu_addr));
562 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, 0);
563 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, 0);
564 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L);
565 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
566 ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
567
568 return 0;
569}
570
571/**
572 * jpeg_v2_0_stop - stop JPEG block
573 *
574 * @adev: amdgpu_device pointer
575 *
576 * stop the JPEG block
577 */
578static int jpeg_v2_0_stop(struct amdgpu_device *adev)
579{
580 uint32_t tmp;
581 int r = 0;
582
583 /* reset JMI */
584 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_JMI_CNTL),
585 UVD_JMI_CNTL__SOFT_RESET_MASK,
586 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
587
588 /* enable JPEG CGC */
589 tmp = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);
590 tmp |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
591 tmp |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
592 tmp |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
593 WREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL, tmp);
594
595
596 tmp = RREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE);
597 tmp |= (JPEG_CGC_GATE__JPEG_DEC_MASK
598 |JPEG_CGC_GATE__JPEG2_DEC_MASK
599 |JPEG_CGC_GATE__JPEG_ENC_MASK
600 |JPEG_CGC_GATE__JMCIF_MASK
601 |JPEG_CGC_GATE__JRBBM_MASK);
602 WREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE, tmp);
603
604 /* enable power gating */
605 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_POWER_STATUS));
606 tmp &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
607 tmp |= 0x1; //UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_TILES_OFF;
608 WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_POWER_STATUS), tmp);
609
610 tmp = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
611 WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_PGFSM_CONFIG), tmp);
612
613 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS,
614 (2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT),
615 UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK, r);
616
617 if (r) {
618 DRM_ERROR("amdgpu: JPEG enable power gating failed\n");
619 return r;
620 }
621
622 return r;
623}
624
625/**
626 * vcn_v2_0_enable_clock_gating - enable VCN clock gating
627 *
628 * @adev: amdgpu_device pointer
629 * @sw: enable SW clock gating
630 *
631 * Enable clock gating for VCN block
632 */
633static void vcn_v2_0_enable_clock_gating(struct amdgpu_device *adev)
634{
635 uint32_t data = 0;
636
637 /* enable UVD CGC */
638 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
639 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
640 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
641 else
642 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
643 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
644 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
645 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
646
647 data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
648 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
649 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
650 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
651 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
652 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
653 | UVD_CGC_CTRL__SYS_MODE_MASK
654 | UVD_CGC_CTRL__UDEC_MODE_MASK
655 | UVD_CGC_CTRL__MPEG2_MODE_MASK
656 | UVD_CGC_CTRL__REGS_MODE_MASK
657 | UVD_CGC_CTRL__RBC_MODE_MASK
658 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
659 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
660 | UVD_CGC_CTRL__IDCT_MODE_MASK
661 | UVD_CGC_CTRL__MPRD_MODE_MASK
662 | UVD_CGC_CTRL__MPC_MODE_MASK
663 | UVD_CGC_CTRL__LBSI_MODE_MASK
664 | UVD_CGC_CTRL__LRBBM_MODE_MASK
665 | UVD_CGC_CTRL__WCB_MODE_MASK
666 | UVD_CGC_CTRL__VCPU_MODE_MASK
667 | UVD_CGC_CTRL__SCPU_MODE_MASK);
668 WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
669
670 data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL);
671 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
672 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
673 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
674 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
675 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
676 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
677 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
678 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
679 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
680 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
681 WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);
682}
683
684static void vcn_v2_0_disable_static_power_gating(struct amdgpu_device *adev)
685{
686 uint32_t data = 0;
687 int ret;
688
689 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
690 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
691 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
692 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
693 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
694 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
695 | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
696 | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
697 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
698 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
699 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
700 | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
701
702 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
703 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS,
704 UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON, 0xFFFFFF, ret);
705 } else {
706 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
707 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
708 | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
709 | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
710 | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
711 | 1 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
712 | 1 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
713 | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
714 | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
715 | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
716 | 1 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
717 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
718 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, 0, 0xFFFFFFFF, ret);
719 }
720
721 /* polling UVD_PGFSM_STATUS to confirm UVDM_PWR_STATUS,
722 * UVDU_PWR_STATUS are 0 (power on) */
723
724 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);
725 data &= ~0x103;
726 if (adev->pg_flags & AMD_PG_SUPPORT_VCN)
727 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON |
728 UVD_POWER_STATUS__UVD_PG_EN_MASK;
729
730 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);
731}
732
733static void vcn_v2_0_enable_static_power_gating(struct amdgpu_device *adev)
734{
735 uint32_t data = 0;
736 int ret;
737
738 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
739 /* Before power off, this indicator has to be turned on */
740 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);
741 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;
742 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;
743 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);
744
745
746 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
747 | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
748 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
749 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
750 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
751 | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
752 | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
753 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
754 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
755 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
756 | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
757
758 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
759
760 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT
761 | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT
762 | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT
763 | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT
764 | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT
765 | 2 << UVD_PGFSM_STATUS__UVDIL_PWR_STATUS__SHIFT
766 | 2 << UVD_PGFSM_STATUS__UVDIR_PWR_STATUS__SHIFT
767 | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT
768 | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT
769 | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT
770 | 2 << UVD_PGFSM_STATUS__UVDW_PWR_STATUS__SHIFT);
771 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, data, 0xFFFFFFFF, ret);
772 }
773}
774
775static int vcn_v2_0_start(struct amdgpu_device *adev)
776{
777 struct amdgpu_ring *ring = &adev->vcn.ring_dec;
778 uint32_t rb_bufsz, tmp;
779 uint32_t lmi_swap_cntl;
780 int i, j, r;
781
782 vcn_v2_0_disable_static_power_gating(adev);
783
784 /* set uvd status busy */
785 tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
786 WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);
787
788 /*SW clock gating */
789 vcn_v2_0_disable_clock_gating(adev);
790
791 /* enable VCPU clock */
792 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL),
793 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
794
795 /* disable master interrupt */
796 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,
797 ~UVD_MASTINT_EN__VCPU_EN_MASK);
798
799 /* setup mmUVD_LMI_CTRL */
800 tmp = RREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL);
801 WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, tmp |
802 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
803 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
804 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
805 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
806
807 /* setup mmUVD_MPC_CNTL */
808 tmp = RREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL);
809 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
810 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
811 WREG32_SOC15(VCN, 0, mmUVD_MPC_CNTL, tmp);
812
813 /* setup UVD_MPC_SET_MUXA0 */
814 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0,
815 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
816 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
817 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
818 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
819
820 /* setup UVD_MPC_SET_MUXB0 */
821 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0,
822 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
823 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
824 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
825 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
826
827 /* setup mmUVD_MPC_SET_MUX */
828 WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX,
829 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
830 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
831 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
832
833 vcn_v2_0_mc_resume(adev);
834
835 /* release VCPU reset to boot */
836 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
837 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
838
839 /* enable LMI MC and UMC channels */
840 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
841 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
842
843 tmp = RREG32_SOC15(VCN, 0, mmUVD_SOFT_RESET);
844 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
845 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
846 WREG32_SOC15(VCN, 0, mmUVD_SOFT_RESET, tmp);
847
848 /* disable byte swapping */
849 lmi_swap_cntl = 0;
850#ifdef __BIG_ENDIAN
851 /* swap (8 in 32) RB and IB */
852 lmi_swap_cntl = 0xa;
853#endif
854 WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
855
856 for (i = 0; i < 10; ++i) {
857 uint32_t status;
858
859 for (j = 0; j < 100; ++j) {
860 status = RREG32_SOC15(UVD, 0, mmUVD_STATUS);
861 if (status & 2)
862 break;
863 mdelay(10);
864 }
865 r = 0;
866 if (status & 2)
867 break;
868
869 DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
870 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
871 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
872 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
873 mdelay(10);
874 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
875 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
876 mdelay(10);
877 r = -1;
878 }
879
880 if (r) {
881 DRM_ERROR("VCN decode not responding, giving up!!!\n");
882 return r;
883 }
884
885 /* enable master interrupt */
886 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
887 UVD_MASTINT_EN__VCPU_EN_MASK,
888 ~UVD_MASTINT_EN__VCPU_EN_MASK);
889
890 /* clear the busy bit of VCN_STATUS */
891 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0,
892 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
893
894 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_VMID, 0);
895
896 /* force RBC into idle state */
897 rb_bufsz = order_base_2(ring->ring_size);
898 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
899 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
900 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
901 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
902 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
903 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
904
905 /* programm the RB_BASE for ring buffer */
906 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
907 lower_32_bits(ring->gpu_addr));
908 WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
909 upper_32_bits(ring->gpu_addr));
910
911 /* Initialize the ring buffer's read and write pointers */
912 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);
913
914 ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
915 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
916 lower_32_bits(ring->wptr));
917
918 ring = &adev->vcn.ring_enc[0];
919 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
920 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
921 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
922 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
923 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
924
925 ring = &adev->vcn.ring_enc[1];
926 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
927 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
928 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
929 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
930 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
931
932 r = jpeg_v2_0_start(adev);
933
934 return r;
935}
936
937static int vcn_v2_0_stop(struct amdgpu_device *adev)
938{
939 uint32_t tmp;
940 int r;
941
942 r = jpeg_v2_0_stop(adev);
943 if (r)
944 return r;
945 /* wait for uvd idle */
946 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
947 if (r)
948 return r;
949
950 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
951 UVD_LMI_STATUS__READ_CLEAN_MASK |
952 UVD_LMI_STATUS__WRITE_CLEAN_MASK |
953 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
954 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_LMI_STATUS, tmp, tmp, r);
955 if (r)
956 return r;
957
958 /* stall UMC channel */
959 tmp = RREG32_SOC15(VCN, 0, mmUVD_LMI_CTRL2);
960 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
961 WREG32_SOC15(VCN, 0, mmUVD_LMI_CTRL2, tmp);
962
963 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
964 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
965 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_LMI_STATUS, tmp, tmp, r);
966 if (r)
967 return r;
968
969 /* disable VCPU clock */
970 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), 0,
971 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
972
973 /* reset LMI UMC */
974 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
975 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK,
976 ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
977
978 /* reset LMI */
979 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
980 UVD_SOFT_RESET__LMI_SOFT_RESET_MASK,
981 ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK);
982
983 /* reset VCPU */
984 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
985 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
986 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
987
988 /* clear status */
989 WREG32_SOC15(VCN, 0, mmUVD_STATUS, 0);
990
991 vcn_v2_0_enable_clock_gating(adev);
992 vcn_v2_0_enable_static_power_gating(adev);
993
994 return 0;
995}
996
997static bool vcn_v2_0_is_idle(void *handle)
998{
999 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1000
1001 return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == UVD_STATUS__IDLE);
1002}
1003
1004static int vcn_v2_0_wait_for_idle(void *handle)
1005{
1006 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1007 int ret = 0;
1008
1009 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE,
1010 UVD_STATUS__IDLE, ret);
1011
1012 return ret;
1013}
1014
1015static int vcn_v2_0_set_clockgating_state(void *handle,
1016 enum amd_clockgating_state state)
1017{
1018 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1019 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
1020
1021 if (enable) {
1022 /* wait for STATUS to clear */
1023 if (vcn_v2_0_is_idle(handle))
1024 return -EBUSY;
1025 vcn_v2_0_enable_clock_gating(adev);
1026 } else {
1027 /* disable HW gating and enable Sw gating */
1028 vcn_v2_0_disable_clock_gating(adev);
1029 }
1030 return 0;
1031}
1032
1033/**
1034 * vcn_v2_0_dec_ring_get_rptr - get read pointer
1035 *
1036 * @ring: amdgpu_ring pointer
1037 *
1038 * Returns the current hardware read pointer
1039 */
1040static uint64_t vcn_v2_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
1041{
1042 struct amdgpu_device *adev = ring->adev;
1043
1044 return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
1045}
1046
1047/**
1048 * vcn_v2_0_dec_ring_get_wptr - get write pointer
1049 *
1050 * @ring: amdgpu_ring pointer
1051 *
1052 * Returns the current hardware write pointer
1053 */
1054static uint64_t vcn_v2_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
1055{
1056 struct amdgpu_device *adev = ring->adev;
1057
1058 if (ring->use_doorbell)
1059 return adev->wb.wb[ring->wptr_offs];
1060 else
1061 return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR);
1062}
1063
1064/**
1065 * vcn_v2_0_dec_ring_set_wptr - set write pointer
1066 *
1067 * @ring: amdgpu_ring pointer
1068 *
1069 * Commits the write pointer to the hardware
1070 */
1071static void vcn_v2_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
1072{
1073 struct amdgpu_device *adev = ring->adev;
1074
1075 if (ring->use_doorbell) {
1076 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1077 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1078 } else {
1079 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
1080 }
1081}
1082
1083/**
1084 * vcn_v2_0_dec_ring_insert_start - insert a start command
1085 *
1086 * @ring: amdgpu_ring pointer
1087 *
1088 * Write a start command to the ring.
1089 */
1090static void vcn_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring)
1091{
1092 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
1093 amdgpu_ring_write(ring, 0);
1094 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
1095 amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_START << 1);
1096}
1097
1098/**
1099 * vcn_v2_0_dec_ring_insert_end - insert a end command
1100 *
1101 * @ring: amdgpu_ring pointer
1102 *
1103 * Write a end command to the ring.
1104 */
1105static void vcn_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring)
1106{
1107 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
1108 amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_END << 1);
1109}
1110
1111/**
1112 * vcn_v2_0_dec_ring_insert_nop - insert a nop command
1113 *
1114 * @ring: amdgpu_ring pointer
1115 *
1116 * Write a nop command to the ring.
1117 */
1118static void vcn_v2_0_dec_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
1119{
1120 int i;
1121
1122 WARN_ON(ring->wptr % 2 || count % 2);
1123
1124 for (i = 0; i < count / 2; i++) {
1125 amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP_INTERNAL_OFFSET, 0));
1126 amdgpu_ring_write(ring, 0);
1127 }
1128}
1129
1130/**
1131 * vcn_v2_0_dec_ring_emit_fence - emit an fence & trap command
1132 *
1133 * @ring: amdgpu_ring pointer
1134 * @fence: fence to emit
1135 *
1136 * Write a fence and a trap command to the ring.
1137 */
1138static void vcn_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
1139 unsigned flags)
1140{
1141 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
1142
1143 amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID_INTERNAL_OFFSET, 0));
1144 amdgpu_ring_write(ring, seq);
1145
1146 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
1147 amdgpu_ring_write(ring, addr & 0xffffffff);
1148
1149 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET, 0));
1150 amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
1151
1152 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
1153 amdgpu_ring_write(ring, VCN_DEC_CMD_FENCE << 1);
1154
1155 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
1156 amdgpu_ring_write(ring, 0);
1157
1158 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET, 0));
1159 amdgpu_ring_write(ring, 0);
1160
1161 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
1162
1163 amdgpu_ring_write(ring, VCN_DEC_CMD_TRAP << 1);
1164}
1165
1166/**
1167 * vcn_v2_0_dec_ring_emit_ib - execute indirect buffer
1168 *
1169 * @ring: amdgpu_ring pointer
1170 * @ib: indirect buffer to execute
1171 *
1172 * Write ring commands to execute the indirect buffer
1173 */
1174static void vcn_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
1175 struct amdgpu_job *job,
1176 struct amdgpu_ib *ib,
1177 uint32_t flags)
1178{
1179 unsigned vmid = AMDGPU_JOB_GET_VMID(job);
1180
1181 amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET, 0));
1182 amdgpu_ring_write(ring, vmid);
1183
1184 amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET, 0));
1185 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
1186 amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET, 0));
1187 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
1188 amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET, 0));
1189 amdgpu_ring_write(ring, ib->length_dw);
1190}
1191
1192static void vcn_v2_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring,
1193 uint32_t reg, uint32_t val,
1194 uint32_t mask)
1195{
1196 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
1197 amdgpu_ring_write(ring, reg << 2);
1198
1199 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET, 0));
1200 amdgpu_ring_write(ring, val);
1201
1202 amdgpu_ring_write(ring, PACKET0(mmUVD_GP_SCRATCH8_INTERNAL_OFFSET, 0));
1203 amdgpu_ring_write(ring, mask);
1204
1205 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
1206
1207 amdgpu_ring_write(ring, VCN_DEC_CMD_REG_READ_COND_WAIT << 1);
1208}
1209
1210static void vcn_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
1211 unsigned vmid, uint64_t pd_addr)
1212{
1213 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
1214 uint32_t data0, data1, mask;
1215
1216 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
1217
1218 /* wait for register write */
1219 data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2;
1220 data1 = lower_32_bits(pd_addr);
1221 mask = 0xffffffff;
1222 vcn_v2_0_dec_ring_emit_reg_wait(ring, data0, data1, mask);
1223}
1224
1225static void vcn_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring,
1226 uint32_t reg, uint32_t val)
1227{
1228 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0));
1229 amdgpu_ring_write(ring, reg << 2);
1230
1231 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET, 0));
1232 amdgpu_ring_write(ring, val);
1233
1234 amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0));
1235
1236 amdgpu_ring_write(ring, VCN_DEC_CMD_WRITE_REG << 1);
1237}
1238
1239/**
1240 * vcn_v2_0_enc_ring_get_rptr - get enc read pointer
1241 *
1242 * @ring: amdgpu_ring pointer
1243 *
1244 * Returns the current hardware enc read pointer
1245 */
1246static uint64_t vcn_v2_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
1247{
1248 struct amdgpu_device *adev = ring->adev;
1249
1250 if (ring == &adev->vcn.ring_enc[0])
1251 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR);
1252 else
1253 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2);
1254}
1255
1256 /**
1257 * vcn_v2_0_enc_ring_get_wptr - get enc write pointer
1258 *
1259 * @ring: amdgpu_ring pointer
1260 *
1261 * Returns the current hardware enc write pointer
1262 */
1263static uint64_t vcn_v2_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
1264{
1265 struct amdgpu_device *adev = ring->adev;
1266
1267 if (ring == &adev->vcn.ring_enc[0]) {
1268 if (ring->use_doorbell)
1269 return adev->wb.wb[ring->wptr_offs];
1270 else
1271 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR);
1272 } else {
1273 if (ring->use_doorbell)
1274 return adev->wb.wb[ring->wptr_offs];
1275 else
1276 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2);
1277 }
1278}
1279
1280 /**
1281 * vcn_v2_0_enc_ring_set_wptr - set enc write pointer
1282 *
1283 * @ring: amdgpu_ring pointer
1284 *
1285 * Commits the enc write pointer to the hardware
1286 */
1287static void vcn_v2_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
1288{
1289 struct amdgpu_device *adev = ring->adev;
1290
1291 if (ring == &adev->vcn.ring_enc[0]) {
1292 if (ring->use_doorbell) {
1293 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1294 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1295 } else {
1296 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1297 }
1298 } else {
1299 if (ring->use_doorbell) {
1300 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1301 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1302 } else {
1303 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1304 }
1305 }
1306}
1307
1308/**
1309 * vcn_v2_0_enc_ring_emit_fence - emit an enc fence & trap command
1310 *
1311 * @ring: amdgpu_ring pointer
1312 * @fence: fence to emit
1313 *
1314 * Write enc a fence and a trap command to the ring.
1315 */
1316static void vcn_v2_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
1317 u64 seq, unsigned flags)
1318{
1319 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
1320
1321 amdgpu_ring_write(ring, VCN_ENC_CMD_FENCE);
1322 amdgpu_ring_write(ring, addr);
1323 amdgpu_ring_write(ring, upper_32_bits(addr));
1324 amdgpu_ring_write(ring, seq);
1325 amdgpu_ring_write(ring, VCN_ENC_CMD_TRAP);
1326}
1327
1328static void vcn_v2_0_enc_ring_insert_end(struct amdgpu_ring *ring)
1329{
1330 amdgpu_ring_write(ring, VCN_ENC_CMD_END);
1331}
1332
1333/**
1334 * vcn_v2_0_enc_ring_emit_ib - enc execute indirect buffer
1335 *
1336 * @ring: amdgpu_ring pointer
1337 * @ib: indirect buffer to execute
1338 *
1339 * Write enc ring commands to execute the indirect buffer
1340 */
1341static void vcn_v2_0_enc_ring_emit_ib(struct amdgpu_ring *ring,
1342 struct amdgpu_job *job,
1343 struct amdgpu_ib *ib,
1344 uint32_t flags)
1345{
1346 unsigned vmid = AMDGPU_JOB_GET_VMID(job);
1347
1348 amdgpu_ring_write(ring, VCN_ENC_CMD_IB);
1349 amdgpu_ring_write(ring, vmid);
1350 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
1351 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
1352 amdgpu_ring_write(ring, ib->length_dw);
1353}
1354
1355static void vcn_v2_0_enc_ring_emit_reg_wait(struct amdgpu_ring *ring,
1356 uint32_t reg, uint32_t val,
1357 uint32_t mask)
1358{
1359 amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT);
1360 amdgpu_ring_write(ring, reg << 2);
1361 amdgpu_ring_write(ring, mask);
1362 amdgpu_ring_write(ring, val);
1363}
1364
1365static void vcn_v2_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
1366 unsigned int vmid, uint64_t pd_addr)
1367{
1368 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
1369
1370 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
1371
1372 /* wait for reg writes */
1373 vcn_v2_0_enc_ring_emit_reg_wait(ring, hub->ctx0_ptb_addr_lo32 + vmid * 2,
1374 lower_32_bits(pd_addr), 0xffffffff);
1375}
1376
1377static void vcn_v2_0_enc_ring_emit_wreg(struct amdgpu_ring *ring,
1378 uint32_t reg, uint32_t val)
1379{
1380 amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE);
1381 amdgpu_ring_write(ring, reg << 2);
1382 amdgpu_ring_write(ring, val);
1383}
1384
1385/**
1386 * vcn_v2_0_jpeg_ring_get_rptr - get read pointer
1387 *
1388 * @ring: amdgpu_ring pointer
1389 *
1390 * Returns the current hardware read pointer
1391 */
1392static uint64_t vcn_v2_0_jpeg_ring_get_rptr(struct amdgpu_ring *ring)
1393{
1394 struct amdgpu_device *adev = ring->adev;
1395
1396 return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR);
1397}
1398
1399/**
1400 * vcn_v2_0_jpeg_ring_get_wptr - get write pointer
1401 *
1402 * @ring: amdgpu_ring pointer
1403 *
1404 * Returns the current hardware write pointer
1405 */
1406static uint64_t vcn_v2_0_jpeg_ring_get_wptr(struct amdgpu_ring *ring)
1407{
1408 struct amdgpu_device *adev = ring->adev;
1409
1410 if (ring->use_doorbell)
1411 return adev->wb.wb[ring->wptr_offs];
1412 else
1413 return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
1414}
1415
1416/**
1417 * vcn_v2_0_jpeg_ring_set_wptr - set write pointer
1418 *
1419 * @ring: amdgpu_ring pointer
1420 *
1421 * Commits the write pointer to the hardware
1422 */
1423static void vcn_v2_0_jpeg_ring_set_wptr(struct amdgpu_ring *ring)
1424{
1425 struct amdgpu_device *adev = ring->adev;
1426
1427 if (ring->use_doorbell) {
1428 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1429 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1430 } else {
1431 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
1432 }
1433}
1434
1435/**
1436 * vcn_v2_0_jpeg_ring_insert_start - insert a start command
1437 *
1438 * @ring: amdgpu_ring pointer
1439 *
1440 * Write a start command to the ring.
1441 */
1442static void vcn_v2_0_jpeg_ring_insert_start(struct amdgpu_ring *ring)
1443{
1444 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
1445 0, 0, PACKETJ_TYPE0));
1446 amdgpu_ring_write(ring, 0x68e04);
1447
1448 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
1449 0, 0, PACKETJ_TYPE0));
1450 amdgpu_ring_write(ring, 0x80010000);
1451}
1452
1453/**
1454 * vcn_v2_0_jpeg_ring_insert_end - insert a end command
1455 *
1456 * @ring: amdgpu_ring pointer
1457 *
1458 * Write a end command to the ring.
1459 */
1460static void vcn_v2_0_jpeg_ring_insert_end(struct amdgpu_ring *ring)
1461{
1462 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
1463 0, 0, PACKETJ_TYPE0));
1464 amdgpu_ring_write(ring, 0x68e04);
1465
1466 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
1467 0, 0, PACKETJ_TYPE0));
1468 amdgpu_ring_write(ring, 0x00010000);
1469}
1470
1471/**
1472 * vcn_v2_0_jpeg_ring_emit_fence - emit an fence & trap command
1473 *
1474 * @ring: amdgpu_ring pointer
1475 * @fence: fence to emit
1476 *
1477 * Write a fence and a trap command to the ring.
1478 */
1479static void vcn_v2_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
1480 unsigned flags)
1481{
1482 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
1483
1484 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET,
1485 0, 0, PACKETJ_TYPE0));
1486 amdgpu_ring_write(ring, seq);
1487
1488 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET,
1489 0, 0, PACKETJ_TYPE0));
1490 amdgpu_ring_write(ring, seq);
1491
1492 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET,
1493 0, 0, PACKETJ_TYPE0));
1494 amdgpu_ring_write(ring, lower_32_bits(addr));
1495
1496 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET,
1497 0, 0, PACKETJ_TYPE0));
1498 amdgpu_ring_write(ring, upper_32_bits(addr));
1499
1500 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET,
1501 0, 0, PACKETJ_TYPE0));
1502 amdgpu_ring_write(ring, 0x8);
1503
1504 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET,
1505 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4));
1506 amdgpu_ring_write(ring, 0);
1507
1508 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
1509 0, 0, PACKETJ_TYPE0));
1510 amdgpu_ring_write(ring, 0x3fbc);
1511
1512 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
1513 0, 0, PACKETJ_TYPE0));
1514 amdgpu_ring_write(ring, 0x1);
1515
1516 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7));
1517 amdgpu_ring_write(ring, 0);
1518}
1519
1520/**
1521 * vcn_v2_0_jpeg_ring_emit_ib - execute indirect buffer
1522 *
1523 * @ring: amdgpu_ring pointer
1524 * @ib: indirect buffer to execute
1525 *
1526 * Write ring commands to execute the indirect buffer.
1527 */
1528static void vcn_v2_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring,
1529 struct amdgpu_job *job,
1530 struct amdgpu_ib *ib,
1531 uint32_t flags)
1532{
1533 unsigned vmid = AMDGPU_JOB_GET_VMID(job);
1534
1535 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
1536 0, 0, PACKETJ_TYPE0));
1537 amdgpu_ring_write(ring, (vmid | (vmid << 4)));
1538
1539 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
1540 0, 0, PACKETJ_TYPE0));
1541 amdgpu_ring_write(ring, (vmid | (vmid << 4)));
1542
1543 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
1544 0, 0, PACKETJ_TYPE0));
1545 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
1546
1547 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET,
1548 0, 0, PACKETJ_TYPE0));
1549 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
1550
1551 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET,
1552 0, 0, PACKETJ_TYPE0));
1553 amdgpu_ring_write(ring, ib->length_dw);
1554
1555 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET,
1556 0, 0, PACKETJ_TYPE0));
1557 amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr));
1558
1559 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET,
1560 0, 0, PACKETJ_TYPE0));
1561 amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr));
1562
1563 amdgpu_ring_write(ring, PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2));
1564 amdgpu_ring_write(ring, 0);
1565
1566 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET,
1567 0, 0, PACKETJ_TYPE0));
1568 amdgpu_ring_write(ring, 0x01400200);
1569
1570 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET,
1571 0, 0, PACKETJ_TYPE0));
1572 amdgpu_ring_write(ring, 0x2);
1573
1574 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_STATUS_INTERNAL_OFFSET,
1575 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3));
1576 amdgpu_ring_write(ring, 0x2);
1577}
1578
1579static void vcn_v2_0_jpeg_ring_emit_reg_wait(struct amdgpu_ring *ring,
1580 uint32_t reg, uint32_t val,
1581 uint32_t mask)
1582{
1583 uint32_t reg_offset = (reg << 2);
1584
1585 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET,
1586 0, 0, PACKETJ_TYPE0));
1587 amdgpu_ring_write(ring, 0x01400200);
1588
1589 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET,
1590 0, 0, PACKETJ_TYPE0));
1591 amdgpu_ring_write(ring, val);
1592
1593 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
1594 0, 0, PACKETJ_TYPE0));
1595 if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) {
1596 amdgpu_ring_write(ring, 0);
1597 amdgpu_ring_write(ring,
1598 PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3));
1599 } else {
1600 amdgpu_ring_write(ring, reg_offset);
1601 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
1602 0, 0, PACKETJ_TYPE3));
1603 }
1604 amdgpu_ring_write(ring, mask);
1605}
1606
1607static void vcn_v2_0_jpeg_ring_emit_vm_flush(struct amdgpu_ring *ring,
1608 unsigned vmid, uint64_t pd_addr)
1609{
1610 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
1611 uint32_t data0, data1, mask;
1612
1613 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
1614
1615 /* wait for register write */
1616 data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2;
1617 data1 = lower_32_bits(pd_addr);
1618 mask = 0xffffffff;
1619 vcn_v2_0_jpeg_ring_emit_reg_wait(ring, data0, data1, mask);
1620}
1621
1622static void vcn_v2_0_jpeg_ring_emit_wreg(struct amdgpu_ring *ring,
1623 uint32_t reg, uint32_t val)
1624{
1625 uint32_t reg_offset = (reg << 2);
1626
1627 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
1628 0, 0, PACKETJ_TYPE0));
1629 if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) {
1630 amdgpu_ring_write(ring, 0);
1631 amdgpu_ring_write(ring,
1632 PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0));
1633 } else {
1634 amdgpu_ring_write(ring, reg_offset);
1635 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
1636 0, 0, PACKETJ_TYPE0));
1637 }
1638 amdgpu_ring_write(ring, val);
1639}
1640
1641static void vcn_v2_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count)
1642{
1643 int i;
1644
1645 WARN_ON(ring->wptr % 2 || count % 2);
1646
1647 for (i = 0; i < count / 2; i++) {
1648 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
1649 amdgpu_ring_write(ring, 0);
1650 }
1651}
1652
1653static int vcn_v2_0_set_interrupt_state(struct amdgpu_device *adev,
1654 struct amdgpu_irq_src *source,
1655 unsigned type,
1656 enum amdgpu_interrupt_state state)
1657{
1658 return 0;
1659}
1660
1661static int vcn_v2_0_process_interrupt(struct amdgpu_device *adev,
1662 struct amdgpu_irq_src *source,
1663 struct amdgpu_iv_entry *entry)
1664{
1665 DRM_DEBUG("IH: VCN TRAP\n");
1666
1667 switch (entry->src_id) {
1668 case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
1669 amdgpu_fence_process(&adev->vcn.ring_dec);
1670 break;
1671 case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1672 amdgpu_fence_process(&adev->vcn.ring_enc[0]);
1673 break;
1674 case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
1675 amdgpu_fence_process(&adev->vcn.ring_enc[1]);
1676 break;
1677 case VCN_2_0__SRCID__JPEG_DECODE:
1678 amdgpu_fence_process(&adev->vcn.ring_jpeg);
1679 break;
1680 default:
1681 DRM_ERROR("Unhandled interrupt: %d %d\n",
1682 entry->src_id, entry->src_data[0]);
1683 break;
1684 }
1685
1686 return 0;
1687}
1688
1689static int vcn_v2_0_set_powergating_state(void *handle,
1690 enum amd_powergating_state state)
1691{
1692 /* This doesn't actually powergate the VCN block.
1693 * That's done in the dpm code via the SMC. This
1694 * just re-inits the block as necessary. The actual
1695 * gating still happens in the dpm code. We should
1696 * revisit this when there is a cleaner line between
1697 * the smc and the hw blocks
1698 */
1699 int ret;
1700 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1701
1702 if (state == adev->vcn.cur_state)
1703 return 0;
1704
1705 if (state == AMD_PG_STATE_GATE)
1706 ret = vcn_v2_0_stop(adev);
1707 else
1708 ret = vcn_v2_0_start(adev);
1709
1710 if (!ret)
1711 adev->vcn.cur_state = state;
1712 return ret;
1713}
1714
1715static const struct amd_ip_funcs vcn_v2_0_ip_funcs = {
1716 .name = "vcn_v2_0",
1717 .early_init = vcn_v2_0_early_init,
1718 .late_init = NULL,
1719 .sw_init = vcn_v2_0_sw_init,
1720 .sw_fini = vcn_v2_0_sw_fini,
1721 .hw_init = vcn_v2_0_hw_init,
1722 .hw_fini = vcn_v2_0_hw_fini,
1723 .suspend = vcn_v2_0_suspend,
1724 .resume = vcn_v2_0_resume,
1725 .is_idle = vcn_v2_0_is_idle,
1726 .wait_for_idle = vcn_v2_0_wait_for_idle,
1727 .check_soft_reset = NULL,
1728 .pre_soft_reset = NULL,
1729 .soft_reset = NULL,
1730 .post_soft_reset = NULL,
1731 .set_clockgating_state = vcn_v2_0_set_clockgating_state,
1732 .set_powergating_state = vcn_v2_0_set_powergating_state,
1733};
1734
1735static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = {
1736 .type = AMDGPU_RING_TYPE_VCN_DEC,
1737 .align_mask = 0xf,
1738 .vmhub = AMDGPU_MMHUB,
1739 .get_rptr = vcn_v2_0_dec_ring_get_rptr,
1740 .get_wptr = vcn_v2_0_dec_ring_get_wptr,
1741 .set_wptr = vcn_v2_0_dec_ring_set_wptr,
1742 .emit_frame_size =
1743 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1744 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1745 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
1746 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
1747 6,
1748 .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
1749 .emit_ib = vcn_v2_0_dec_ring_emit_ib,
1750 .emit_fence = vcn_v2_0_dec_ring_emit_fence,
1751 .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1752 .test_ring = amdgpu_vcn_dec_ring_test_ring,
1753 .test_ib = amdgpu_vcn_dec_ring_test_ib,
1754 .insert_nop = vcn_v2_0_dec_ring_insert_nop,
1755 .insert_start = vcn_v2_0_dec_ring_insert_start,
1756 .insert_end = vcn_v2_0_dec_ring_insert_end,
1757 .pad_ib = amdgpu_ring_generic_pad_ib,
1758 .begin_use = amdgpu_vcn_ring_begin_use,
1759 .end_use = amdgpu_vcn_ring_end_use,
1760 .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1761 .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1762 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1763};
1764
1765static const struct amdgpu_ring_funcs vcn_v2_0_enc_ring_vm_funcs = {
1766 .type = AMDGPU_RING_TYPE_VCN_ENC,
1767 .align_mask = 0x3f,
1768 .nop = VCN_ENC_CMD_NO_OP,
1769 .vmhub = AMDGPU_MMHUB,
1770 .get_rptr = vcn_v2_0_enc_ring_get_rptr,
1771 .get_wptr = vcn_v2_0_enc_ring_get_wptr,
1772 .set_wptr = vcn_v2_0_enc_ring_set_wptr,
1773 .emit_frame_size =
1774 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1775 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1776 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1777 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1778 1, /* vcn_v2_0_enc_ring_insert_end */
1779 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1780 .emit_ib = vcn_v2_0_enc_ring_emit_ib,
1781 .emit_fence = vcn_v2_0_enc_ring_emit_fence,
1782 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1783 .test_ring = amdgpu_vcn_enc_ring_test_ring,
1784 .test_ib = amdgpu_vcn_enc_ring_test_ib,
1785 .insert_nop = amdgpu_ring_insert_nop,
1786 .insert_end = vcn_v2_0_enc_ring_insert_end,
1787 .pad_ib = amdgpu_ring_generic_pad_ib,
1788 .begin_use = amdgpu_vcn_ring_begin_use,
1789 .end_use = amdgpu_vcn_ring_end_use,
1790 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1791 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1792 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1793};
1794
1795static const struct amdgpu_ring_funcs vcn_v2_0_jpeg_ring_vm_funcs = {
1796 .type = AMDGPU_RING_TYPE_VCN_JPEG,
1797 .align_mask = 0xf,
1798 .vmhub = AMDGPU_MMHUB,
1799 .get_rptr = vcn_v2_0_jpeg_ring_get_rptr,
1800 .get_wptr = vcn_v2_0_jpeg_ring_get_wptr,
1801 .set_wptr = vcn_v2_0_jpeg_ring_set_wptr,
1802 .emit_frame_size =
1803 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1804 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1805 8 + /* vcn_v2_0_jpeg_ring_emit_vm_flush */
1806 18 + 18 + /* vcn_v2_0_jpeg_ring_emit_fence x2 vm fence */
1807 8 + 16,
1808 .emit_ib_size = 22, /* vcn_v2_0_jpeg_ring_emit_ib */
1809 .emit_ib = vcn_v2_0_jpeg_ring_emit_ib,
1810 .emit_fence = vcn_v2_0_jpeg_ring_emit_fence,
1811 .emit_vm_flush = vcn_v2_0_jpeg_ring_emit_vm_flush,
1812 .test_ring = amdgpu_vcn_jpeg_ring_test_ring,
1813 .test_ib = amdgpu_vcn_jpeg_ring_test_ib,
1814 .insert_nop = vcn_v2_0_jpeg_ring_nop,
1815 .insert_start = vcn_v2_0_jpeg_ring_insert_start,
1816 .insert_end = vcn_v2_0_jpeg_ring_insert_end,
1817 .pad_ib = amdgpu_ring_generic_pad_ib,
1818 .begin_use = amdgpu_vcn_ring_begin_use,
1819 .end_use = amdgpu_vcn_ring_end_use,
1820 .emit_wreg = vcn_v2_0_jpeg_ring_emit_wreg,
1821 .emit_reg_wait = vcn_v2_0_jpeg_ring_emit_reg_wait,
1822 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1823};
1824
1825static void vcn_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev)
1826{
1827 adev->vcn.ring_dec.funcs = &vcn_v2_0_dec_ring_vm_funcs;
1828 DRM_INFO("VCN decode is enabled in VM mode\n");
1829}
1830
1831static void vcn_v2_0_set_enc_ring_funcs(struct amdgpu_device *adev)
1832{
1833 int i;
1834
1835 for (i = 0; i < adev->vcn.num_enc_rings; ++i)
1836 adev->vcn.ring_enc[i].funcs = &vcn_v2_0_enc_ring_vm_funcs;
1837
1838 DRM_INFO("VCN encode is enabled in VM mode\n");
1839}
1840
1841static void vcn_v2_0_set_jpeg_ring_funcs(struct amdgpu_device *adev)
1842{
1843 adev->vcn.ring_jpeg.funcs = &vcn_v2_0_jpeg_ring_vm_funcs;
1844 DRM_INFO("VCN jpeg decode is enabled in VM mode\n");
1845}
1846
1847static const struct amdgpu_irq_src_funcs vcn_v2_0_irq_funcs = {
1848 .set = vcn_v2_0_set_interrupt_state,
1849 .process = vcn_v2_0_process_interrupt,
1850};
1851
1852static void vcn_v2_0_set_irq_funcs(struct amdgpu_device *adev)
1853{
1854 adev->vcn.irq.num_types = adev->vcn.num_enc_rings + 2;
1855 adev->vcn.irq.funcs = &vcn_v2_0_irq_funcs;
1856}
1857
1858const struct amdgpu_ip_block_version vcn_v2_0_ip_block =
1859{
1860 .type = AMD_IP_BLOCK_TYPE_VCN,
1861 .major = 2,
1862 .minor = 0,
1863 .rev = 0,
1864 .funcs = &vcn_v2_0_ip_funcs,
1865};