2 * Copyright 2019 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
24 #include <linux/firmware.h>
26 #include "amdgpu_vcn.h"
27 #include "amdgpu_pm.h"
31 #include "mmsch_v3_0.h"
33 #include "vcn/vcn_3_0_0_offset.h"
34 #include "vcn/vcn_3_0_0_sh_mask.h"
35 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
37 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
38 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
39 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10
40 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET 0x11
41 #define mmUVD_NO_OP_INTERNAL_OFFSET 0x29
42 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET 0x66
43 #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d
45 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431
46 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4
47 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5
48 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c
50 #define VCN_INSTANCES_SIENNA_CICHLID 2
52 static int amdgpu_ih_clientid_vcns[] = {
53 SOC15_IH_CLIENTID_VCN,
54 SOC15_IH_CLIENTID_VCN1
57 static int amdgpu_ucode_id_vcns[] = {
62 static int vcn_v3_0_start_sriov(struct amdgpu_device *adev);
63 static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev);
64 static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev);
65 static void vcn_v3_0_set_irq_funcs(struct amdgpu_device *adev);
66 static int vcn_v3_0_set_powergating_state(void *handle,
67 enum amd_powergating_state state);
68 static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev,
69 int inst_idx, struct dpg_pause_state *new_state);
71 static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring);
72 static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring);
75 * vcn_v3_0_early_init - set function pointers
77 * @handle: amdgpu_device pointer
79 * Set ring and irq function pointers
81 static int vcn_v3_0_early_init(void *handle)
83 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
85 if (amdgpu_sriov_vf(adev)) {
86 adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID;
87 adev->vcn.harvest_config = 0;
88 adev->vcn.num_enc_rings = 1;
91 if (adev->asic_type == CHIP_SIENNA_CICHLID) {
95 adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID;
96 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
97 harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING);
98 if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
99 adev->vcn.harvest_config |= 1 << i;
102 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
103 AMDGPU_VCN_HARVEST_VCN1))
104 /* both instances are harvested, disable the block */
107 adev->vcn.num_vcn_inst = 1;
109 adev->vcn.num_enc_rings = 2;
112 vcn_v3_0_set_dec_ring_funcs(adev);
113 vcn_v3_0_set_enc_ring_funcs(adev);
114 vcn_v3_0_set_irq_funcs(adev);
120 * vcn_v3_0_sw_init - sw init for VCN block
122 * @handle: amdgpu_device pointer
124 * Load firmware and sw initialization
126 static int vcn_v3_0_sw_init(void *handle)
128 struct amdgpu_ring *ring;
130 int vcn_doorbell_index = 0;
131 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
133 r = amdgpu_vcn_sw_init(adev);
137 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
138 const struct common_firmware_header *hdr;
139 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
140 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
141 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
142 adev->firmware.fw_size +=
143 ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
145 if (adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) {
146 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
147 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
148 adev->firmware.fw_size +=
149 ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
151 DRM_INFO("PSP loading VCN firmware\n");
154 r = amdgpu_vcn_resume(adev);
159 * Note: doorbell assignment is fixed for SRIOV multiple VCN engines
161 * vcn_db_base = adev->doorbell_index.vcn.vcn_ring0_1 << 1;
162 * dec_ring_i = vcn_db_base + i * (adev->vcn.num_enc_rings + 1)
163 * enc_ring_i,j = vcn_db_base + i * (adev->vcn.num_enc_rings + 1) + 1 + j
165 if (amdgpu_sriov_vf(adev)) {
166 vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1;
167 /* get DWORD offset */
168 vcn_doorbell_index = vcn_doorbell_index << 1;
171 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
172 if (adev->vcn.harvest_config & (1 << i))
175 adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
176 adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
177 adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
178 adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
179 adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
180 adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
182 adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
183 adev->vcn.inst[i].external.scratch9 = SOC15_REG_OFFSET(VCN, i, mmUVD_SCRATCH9);
184 adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
185 adev->vcn.inst[i].external.data0 = SOC15_REG_OFFSET(VCN, i, mmUVD_GPCOM_VCPU_DATA0);
186 adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
187 adev->vcn.inst[i].external.data1 = SOC15_REG_OFFSET(VCN, i, mmUVD_GPCOM_VCPU_DATA1);
188 adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
189 adev->vcn.inst[i].external.cmd = SOC15_REG_OFFSET(VCN, i, mmUVD_GPCOM_VCPU_CMD);
190 adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
191 adev->vcn.inst[i].external.nop = SOC15_REG_OFFSET(VCN, i, mmUVD_NO_OP);
194 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
195 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[i].irq);
199 ring = &adev->vcn.inst[i].ring_dec;
200 ring->use_doorbell = true;
201 if (amdgpu_sriov_vf(adev)) {
202 ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1);
204 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i;
206 if (adev->asic_type == CHIP_SIENNA_CICHLID && i != 0)
207 ring->no_scheduler = true;
208 sprintf(ring->name, "vcn_dec_%d", i);
209 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
210 AMDGPU_RING_PRIO_DEFAULT);
214 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
216 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
217 j + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq);
221 ring = &adev->vcn.inst[i].ring_enc[j];
222 ring->use_doorbell = true;
223 if (amdgpu_sriov_vf(adev)) {
224 ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1 + j;
226 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + j + 8 * i;
228 if (adev->asic_type == CHIP_SIENNA_CICHLID && i != 1)
229 ring->no_scheduler = true;
230 sprintf(ring->name, "vcn_enc_%d.%d", i, j);
231 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
232 AMDGPU_RING_PRIO_DEFAULT);
238 if (amdgpu_sriov_vf(adev)) {
239 r = amdgpu_virt_alloc_mm_table(adev);
243 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
244 adev->vcn.pause_dpg_mode = vcn_v3_0_pause_dpg_mode;
250 * vcn_v3_0_sw_fini - sw fini for VCN block
252 * @handle: amdgpu_device pointer
254 * VCN suspend and free up sw allocation
256 static int vcn_v3_0_sw_fini(void *handle)
258 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
261 if (amdgpu_sriov_vf(adev))
262 amdgpu_virt_free_mm_table(adev);
264 r = amdgpu_vcn_suspend(adev);
268 r = amdgpu_vcn_sw_fini(adev);
274 * vcn_v3_0_hw_init - start and test VCN block
276 * @handle: amdgpu_device pointer
278 * Initialize the hardware, boot up the VCPU and do some testing
280 static int vcn_v3_0_hw_init(void *handle)
282 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
283 struct amdgpu_ring *ring;
286 if (amdgpu_sriov_vf(adev)) {
287 r = vcn_v3_0_start_sriov(adev);
291 /* initialize VCN dec and enc ring buffers */
292 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
293 if (adev->vcn.harvest_config & (1 << i))
296 ring = &adev->vcn.inst[i].ring_dec;
297 if (ring->sched.ready) {
300 vcn_v3_0_dec_ring_set_wptr(ring);
303 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
304 ring = &adev->vcn.inst[i].ring_enc[j];
305 if (ring->sched.ready) {
308 vcn_v3_0_enc_ring_set_wptr(ring);
313 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
314 if (adev->vcn.harvest_config & (1 << i))
317 ring = &adev->vcn.inst[i].ring_dec;
319 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
320 ring->doorbell_index, i);
322 r = amdgpu_ring_test_helper(ring);
326 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
327 ring = &adev->vcn.inst[i].ring_enc[j];
328 r = amdgpu_ring_test_helper(ring);
337 DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
338 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
344 * vcn_v3_0_hw_fini - stop the hardware block
346 * @handle: amdgpu_device pointer
348 * Stop the VCN block, mark ring as not ready any more
350 static int vcn_v3_0_hw_fini(void *handle)
352 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
353 struct amdgpu_ring *ring;
356 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
357 if (adev->vcn.harvest_config & (1 << i))
360 ring = &adev->vcn.inst[i].ring_dec;
362 if (!amdgpu_sriov_vf(adev)) {
363 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
364 (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
365 RREG32_SOC15(VCN, i, mmUVD_STATUS))) {
366 vcn_v3_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
369 ring->sched.ready = false;
371 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
372 ring = &adev->vcn.inst[i].ring_enc[j];
373 ring->sched.ready = false;
381 * vcn_v3_0_suspend - suspend VCN block
383 * @handle: amdgpu_device pointer
385 * HW fini and suspend VCN block
387 static int vcn_v3_0_suspend(void *handle)
390 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
392 r = vcn_v3_0_hw_fini(adev);
396 r = amdgpu_vcn_suspend(adev);
402 * vcn_v3_0_resume - resume VCN block
404 * @handle: amdgpu_device pointer
406 * Resume firmware and hw init VCN block
408 static int vcn_v3_0_resume(void *handle)
411 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
413 r = amdgpu_vcn_resume(adev);
417 r = vcn_v3_0_hw_init(adev);
423 * vcn_v3_0_mc_resume - memory controller programming
425 * @adev: amdgpu_device pointer
426 * @inst: instance number
428 * Let the VCN memory controller know it's offsets
430 static void vcn_v3_0_mc_resume(struct amdgpu_device *adev, int inst)
432 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
435 /* cache window 0: fw */
436 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
437 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
438 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo));
439 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
440 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi));
441 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET0, 0);
444 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
445 lower_32_bits(adev->vcn.inst[inst].gpu_addr));
446 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
447 upper_32_bits(adev->vcn.inst[inst].gpu_addr));
449 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET0,
450 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
452 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_SIZE0, size);
454 /* cache window 1: stack */
455 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
456 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
457 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
458 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
459 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET1, 0);
460 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
462 /* cache window 2: context */
463 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
464 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
465 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
466 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
467 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET2, 0);
468 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
471 static void vcn_v3_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
473 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
476 /* cache window 0: fw */
477 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
479 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
480 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
481 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
482 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
483 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
484 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
485 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
486 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
488 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
489 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
490 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
491 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
492 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
493 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
497 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
498 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
499 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
500 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
501 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
502 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
504 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
505 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET0),
506 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
510 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
511 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
513 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
514 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
516 /* cache window 1: stack */
518 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
519 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
520 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
521 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
522 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
523 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
524 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
525 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
527 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
528 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
529 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
530 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
531 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
532 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
534 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
535 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
537 /* cache window 2: context */
538 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
539 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
540 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
541 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
542 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
543 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
544 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
545 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
546 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
547 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
549 /* non-cache window */
550 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
551 VCN, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
552 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
553 VCN, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
554 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
555 VCN, inst_idx, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
556 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
557 VCN, inst_idx, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
560 static void vcn_v3_0_disable_static_power_gating(struct amdgpu_device *adev, int inst)
564 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
565 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
566 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
567 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
568 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
569 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
570 | 2 << UVD_PGFSM_CONFIG__UVDIRL_PWR_CONFIG__SHIFT
571 | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
572 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
573 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
574 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
575 | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
576 | 2 << UVD_PGFSM_CONFIG__UVDATD_PWR_CONFIG__SHIFT
577 | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
578 | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
580 WREG32_SOC15(VCN, inst, mmUVD_PGFSM_CONFIG, data);
581 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_PGFSM_STATUS,
582 UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0, 0x3F3FFFFF);
584 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
585 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
586 | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
587 | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
588 | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
589 | 1 << UVD_PGFSM_CONFIG__UVDIRL_PWR_CONFIG__SHIFT
590 | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
591 | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
592 | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
593 | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
594 | 1 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
595 | 1 << UVD_PGFSM_CONFIG__UVDATD_PWR_CONFIG__SHIFT
596 | 1 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
597 | 1 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
598 WREG32_SOC15(VCN, inst, mmUVD_PGFSM_CONFIG, data);
599 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_PGFSM_STATUS, 0, 0x3F3FFFFF);
602 data = RREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS);
604 if (adev->pg_flags & AMD_PG_SUPPORT_VCN)
605 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON |
606 UVD_POWER_STATUS__UVD_PG_EN_MASK;
608 WREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS, data);
611 static void vcn_v3_0_enable_static_power_gating(struct amdgpu_device *adev, int inst)
615 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
616 /* Before power off, this indicator has to be turned on */
617 data = RREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS);
618 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;
619 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;
620 WREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS, data);
622 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
623 | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
624 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
625 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
626 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
627 | 2 << UVD_PGFSM_CONFIG__UVDIRL_PWR_CONFIG__SHIFT
628 | 2 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
629 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
630 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
631 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
632 | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
633 | 2 << UVD_PGFSM_CONFIG__UVDATD_PWR_CONFIG__SHIFT
634 | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
635 | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
636 WREG32_SOC15(VCN, inst, mmUVD_PGFSM_CONFIG, data);
638 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT
639 | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT
640 | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT
641 | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT
642 | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT
643 | 2 << UVD_PGFSM_STATUS__UVDIRL_PWR_STATUS__SHIFT
644 | 2 << UVD_PGFSM_STATUS__UVDLM_PWR_STATUS__SHIFT
645 | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT
646 | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT
647 | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT
648 | 2 << UVD_PGFSM_STATUS__UVDAB_PWR_STATUS__SHIFT
649 | 2 << UVD_PGFSM_STATUS__UVDATD_PWR_STATUS__SHIFT
650 | 2 << UVD_PGFSM_STATUS__UVDNA_PWR_STATUS__SHIFT
651 | 2 << UVD_PGFSM_STATUS__UVDNB_PWR_STATUS__SHIFT);
652 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_PGFSM_STATUS, data, 0x3F3FFFFF);
657 * vcn_v3_0_disable_clock_gating - disable VCN clock gating
659 * @adev: amdgpu_device pointer
660 * @inst: instance number
662 * Disable clock gating for VCN block
664 static void vcn_v3_0_disable_clock_gating(struct amdgpu_device *adev, int inst)
668 /* VCN disable CGC */
669 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
670 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
671 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
673 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
674 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
675 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
676 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
678 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_GATE);
679 data &= ~(UVD_CGC_GATE__SYS_MASK
680 | UVD_CGC_GATE__UDEC_MASK
681 | UVD_CGC_GATE__MPEG2_MASK
682 | UVD_CGC_GATE__REGS_MASK
683 | UVD_CGC_GATE__RBC_MASK
684 | UVD_CGC_GATE__LMI_MC_MASK
685 | UVD_CGC_GATE__LMI_UMC_MASK
686 | UVD_CGC_GATE__IDCT_MASK
687 | UVD_CGC_GATE__MPRD_MASK
688 | UVD_CGC_GATE__MPC_MASK
689 | UVD_CGC_GATE__LBSI_MASK
690 | UVD_CGC_GATE__LRBBM_MASK
691 | UVD_CGC_GATE__UDEC_RE_MASK
692 | UVD_CGC_GATE__UDEC_CM_MASK
693 | UVD_CGC_GATE__UDEC_IT_MASK
694 | UVD_CGC_GATE__UDEC_DB_MASK
695 | UVD_CGC_GATE__UDEC_MP_MASK
696 | UVD_CGC_GATE__WCB_MASK
697 | UVD_CGC_GATE__VCPU_MASK
698 | UVD_CGC_GATE__MMSCH_MASK);
700 WREG32_SOC15(VCN, inst, mmUVD_CGC_GATE, data);
702 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_CGC_GATE, 0, 0xFFFFFFFF);
704 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
705 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
706 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
707 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
708 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
709 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
710 | UVD_CGC_CTRL__SYS_MODE_MASK
711 | UVD_CGC_CTRL__UDEC_MODE_MASK
712 | UVD_CGC_CTRL__MPEG2_MODE_MASK
713 | UVD_CGC_CTRL__REGS_MODE_MASK
714 | UVD_CGC_CTRL__RBC_MODE_MASK
715 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
716 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
717 | UVD_CGC_CTRL__IDCT_MODE_MASK
718 | UVD_CGC_CTRL__MPRD_MODE_MASK
719 | UVD_CGC_CTRL__MPC_MODE_MASK
720 | UVD_CGC_CTRL__LBSI_MODE_MASK
721 | UVD_CGC_CTRL__LRBBM_MODE_MASK
722 | UVD_CGC_CTRL__WCB_MODE_MASK
723 | UVD_CGC_CTRL__VCPU_MODE_MASK
724 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
725 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
727 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE);
728 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
729 | UVD_SUVD_CGC_GATE__SIT_MASK
730 | UVD_SUVD_CGC_GATE__SMP_MASK
731 | UVD_SUVD_CGC_GATE__SCM_MASK
732 | UVD_SUVD_CGC_GATE__SDB_MASK
733 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
734 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
735 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
736 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
737 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
738 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
739 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
740 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
741 | UVD_SUVD_CGC_GATE__SCLR_MASK
742 | UVD_SUVD_CGC_GATE__ENT_MASK
743 | UVD_SUVD_CGC_GATE__IME_MASK
744 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
745 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
746 | UVD_SUVD_CGC_GATE__SITE_MASK
747 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
748 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
749 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
750 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
751 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK
752 | UVD_SUVD_CGC_GATE__EFC_MASK
753 | UVD_SUVD_CGC_GATE__SAOE_MASK
754 | UVD_SUVD_CGC_GATE__SRE_AV1_MASK
755 | UVD_SUVD_CGC_GATE__FBC_PCLK_MASK
756 | UVD_SUVD_CGC_GATE__FBC_CCLK_MASK
757 | UVD_SUVD_CGC_GATE__SCM_AV1_MASK
758 | UVD_SUVD_CGC_GATE__SMPA_MASK);
759 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE, data);
761 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE2);
762 data |= (UVD_SUVD_CGC_GATE2__MPBE0_MASK
763 | UVD_SUVD_CGC_GATE2__MPBE1_MASK
764 | UVD_SUVD_CGC_GATE2__SIT_AV1_MASK
765 | UVD_SUVD_CGC_GATE2__SDB_AV1_MASK
766 | UVD_SUVD_CGC_GATE2__MPC1_MASK);
767 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE2, data);
769 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL);
770 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
771 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
772 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
773 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
774 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
775 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
776 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
777 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
778 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK
779 | UVD_SUVD_CGC_CTRL__EFC_MODE_MASK
780 | UVD_SUVD_CGC_CTRL__SAOE_MODE_MASK
781 | UVD_SUVD_CGC_CTRL__SMPA_MODE_MASK
782 | UVD_SUVD_CGC_CTRL__MPBE0_MODE_MASK
783 | UVD_SUVD_CGC_CTRL__MPBE1_MODE_MASK
784 | UVD_SUVD_CGC_CTRL__SIT_AV1_MODE_MASK
785 | UVD_SUVD_CGC_CTRL__SDB_AV1_MODE_MASK
786 | UVD_SUVD_CGC_CTRL__MPC1_MODE_MASK
787 | UVD_SUVD_CGC_CTRL__FBC_PCLK_MASK
788 | UVD_SUVD_CGC_CTRL__FBC_CCLK_MASK);
789 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL, data);
792 static void vcn_v3_0_clock_gating_dpg_mode(struct amdgpu_device *adev,
793 uint8_t sram_sel, int inst_idx, uint8_t indirect)
795 uint32_t reg_data = 0;
797 /* enable sw clock gating control */
798 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
799 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
801 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
802 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
803 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
804 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
805 UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
806 UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
807 UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
808 UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
809 UVD_CGC_CTRL__SYS_MODE_MASK |
810 UVD_CGC_CTRL__UDEC_MODE_MASK |
811 UVD_CGC_CTRL__MPEG2_MODE_MASK |
812 UVD_CGC_CTRL__REGS_MODE_MASK |
813 UVD_CGC_CTRL__RBC_MODE_MASK |
814 UVD_CGC_CTRL__LMI_MC_MODE_MASK |
815 UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
816 UVD_CGC_CTRL__IDCT_MODE_MASK |
817 UVD_CGC_CTRL__MPRD_MODE_MASK |
818 UVD_CGC_CTRL__MPC_MODE_MASK |
819 UVD_CGC_CTRL__LBSI_MODE_MASK |
820 UVD_CGC_CTRL__LRBBM_MODE_MASK |
821 UVD_CGC_CTRL__WCB_MODE_MASK |
822 UVD_CGC_CTRL__VCPU_MODE_MASK |
823 UVD_CGC_CTRL__MMSCH_MODE_MASK);
824 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
825 VCN, inst_idx, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
827 /* turn off clock gating */
828 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
829 VCN, inst_idx, mmUVD_CGC_GATE), 0, sram_sel, indirect);
831 /* turn on SUVD clock gating */
832 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
833 VCN, inst_idx, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
835 /* turn on sw mode in UVD_SUVD_CGC_CTRL */
836 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
837 VCN, inst_idx, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
841 * vcn_v3_0_enable_clock_gating - enable VCN clock gating
843 * @adev: amdgpu_device pointer
844 * @inst: instance number
846 * Enable clock gating for VCN block
848 static void vcn_v3_0_enable_clock_gating(struct amdgpu_device *adev, int inst)
853 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
854 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
855 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
857 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
858 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
859 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
860 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
862 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
863 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
864 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
865 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
866 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
867 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
868 | UVD_CGC_CTRL__SYS_MODE_MASK
869 | UVD_CGC_CTRL__UDEC_MODE_MASK
870 | UVD_CGC_CTRL__MPEG2_MODE_MASK
871 | UVD_CGC_CTRL__REGS_MODE_MASK
872 | UVD_CGC_CTRL__RBC_MODE_MASK
873 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
874 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
875 | UVD_CGC_CTRL__IDCT_MODE_MASK
876 | UVD_CGC_CTRL__MPRD_MODE_MASK
877 | UVD_CGC_CTRL__MPC_MODE_MASK
878 | UVD_CGC_CTRL__LBSI_MODE_MASK
879 | UVD_CGC_CTRL__LRBBM_MODE_MASK
880 | UVD_CGC_CTRL__WCB_MODE_MASK
881 | UVD_CGC_CTRL__VCPU_MODE_MASK
882 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
883 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
885 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL);
886 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
887 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
888 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
889 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
890 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
891 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
892 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
893 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
894 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK
895 | UVD_SUVD_CGC_CTRL__EFC_MODE_MASK
896 | UVD_SUVD_CGC_CTRL__SAOE_MODE_MASK
897 | UVD_SUVD_CGC_CTRL__SMPA_MODE_MASK
898 | UVD_SUVD_CGC_CTRL__MPBE0_MODE_MASK
899 | UVD_SUVD_CGC_CTRL__MPBE1_MODE_MASK
900 | UVD_SUVD_CGC_CTRL__SIT_AV1_MODE_MASK
901 | UVD_SUVD_CGC_CTRL__SDB_AV1_MODE_MASK
902 | UVD_SUVD_CGC_CTRL__MPC1_MODE_MASK
903 | UVD_SUVD_CGC_CTRL__FBC_PCLK_MASK
904 | UVD_SUVD_CGC_CTRL__FBC_CCLK_MASK);
905 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL, data);
908 static int vcn_v3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
910 struct amdgpu_ring *ring;
911 uint32_t rb_bufsz, tmp;
913 /* disable register anti-hang mechanism */
914 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1,
915 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
916 /* enable dynamic power gating mode */
917 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS);
918 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
919 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
920 WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp);
923 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
925 /* enable clock gating */
926 vcn_v3_0_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);
928 /* enable VCPU clock */
929 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
930 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
931 tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
932 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
933 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
935 /* disable master interupt */
936 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
937 VCN, inst_idx, mmUVD_MASTINT_EN), 0, 0, indirect);
939 /* setup mmUVD_LMI_CTRL */
940 tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
941 UVD_LMI_CTRL__REQ_MODE_MASK |
942 UVD_LMI_CTRL__CRC_RESET_MASK |
943 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
944 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
945 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
946 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
948 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
949 VCN, inst_idx, mmUVD_LMI_CTRL), tmp, 0, indirect);
951 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
952 VCN, inst_idx, mmUVD_MPC_CNTL),
953 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
955 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
956 VCN, inst_idx, mmUVD_MPC_SET_MUXA0),
957 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
958 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
959 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
960 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
962 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
963 VCN, inst_idx, mmUVD_MPC_SET_MUXB0),
964 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
965 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
966 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
967 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
969 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
970 VCN, inst_idx, mmUVD_MPC_SET_MUX),
971 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
972 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
973 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
975 vcn_v3_0_mc_resume_dpg_mode(adev, inst_idx, indirect);
977 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
978 VCN, inst_idx, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
979 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
980 VCN, inst_idx, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
982 /* enable LMI MC and UMC channels */
983 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
984 VCN, inst_idx, mmUVD_LMI_CTRL2), 0, 0, indirect);
986 /* unblock VCPU register access */
987 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
988 VCN, inst_idx, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
990 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
991 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
992 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
993 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
995 /* enable master interrupt */
996 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
997 VCN, inst_idx, mmUVD_MASTINT_EN),
998 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
1000 /* add nop to workaround PSP size check */
1001 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1002 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1005 psp_update_vcn_sram(adev, inst_idx, adev->vcn.inst[inst_idx].dpg_sram_gpu_addr,
1006 (uint32_t)((uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_curr_addr -
1007 (uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr));
1009 ring = &adev->vcn.inst[inst_idx].ring_dec;
1010 /* force RBC into idle state */
1011 rb_bufsz = order_base_2(ring->ring_size);
1012 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1013 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1014 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1015 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1016 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1017 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
1019 /* set the write pointer delay */
1020 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
1022 /* set the wb address */
1023 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
1024 (upper_32_bits(ring->gpu_addr) >> 2));
1026 /* programm the RB_BASE for ring buffer */
1027 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1028 lower_32_bits(ring->gpu_addr));
1029 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1030 upper_32_bits(ring->gpu_addr));
1032 /* Initialize the ring buffer's read and write pointers */
1033 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0);
1035 WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0);
1037 ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR);
1038 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
1039 lower_32_bits(ring->wptr));
1044 static int vcn_v3_0_start(struct amdgpu_device *adev)
1046 struct amdgpu_ring *ring;
1047 uint32_t rb_bufsz, tmp;
1050 if (adev->pm.dpm_enabled)
1051 amdgpu_dpm_enable_uvd(adev, true);
1053 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1054 if (adev->vcn.harvest_config & (1 << i))
1057 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
1058 r = vcn_v3_0_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
1062 /* disable VCN power gating */
1063 vcn_v3_0_disable_static_power_gating(adev, i);
1065 /* set VCN status busy */
1066 tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
1067 WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp);
1069 /*SW clock gating */
1070 vcn_v3_0_disable_clock_gating(adev, i);
1072 /* enable VCPU clock */
1073 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1074 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
1076 /* disable master interrupt */
1077 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0,
1078 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1080 /* enable LMI MC and UMC channels */
1081 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0,
1082 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1084 tmp = RREG32_SOC15(VCN, i, mmUVD_SOFT_RESET);
1085 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1086 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1087 WREG32_SOC15(VCN, i, mmUVD_SOFT_RESET, tmp);
1089 /* setup mmUVD_LMI_CTRL */
1090 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL);
1091 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp |
1092 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1093 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1094 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1095 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1097 /* setup mmUVD_MPC_CNTL */
1098 tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL);
1099 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
1100 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
1101 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
1103 /* setup UVD_MPC_SET_MUXA0 */
1104 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0,
1105 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1106 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1107 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1108 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
1110 /* setup UVD_MPC_SET_MUXB0 */
1111 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0,
1112 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1113 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1114 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1115 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
1117 /* setup mmUVD_MPC_SET_MUX */
1118 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX,
1119 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1120 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1121 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
1123 vcn_v3_0_mc_resume(adev, i);
1125 /* VCN global tiling registers */
1126 WREG32_SOC15(VCN, i, mmUVD_GFX10_ADDR_CONFIG,
1127 adev->gfx.config.gb_addr_config);
1129 /* unblock VCPU register access */
1130 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0,
1131 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1133 /* release VCPU reset to boot */
1134 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1135 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1137 for (j = 0; j < 10; ++j) {
1140 for (k = 0; k < 100; ++k) {
1141 status = RREG32_SOC15(VCN, i, mmUVD_STATUS);
1150 DRM_ERROR("VCN[%d] decode not responding, trying to reset the VCPU!!!\n", i);
1151 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1152 UVD_VCPU_CNTL__BLK_RST_MASK,
1153 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1155 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1156 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1163 DRM_ERROR("VCN[%d] decode not responding, giving up!!!\n", i);
1167 /* enable master interrupt */
1168 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN),
1169 UVD_MASTINT_EN__VCPU_EN_MASK,
1170 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1172 /* clear the busy bit of VCN_STATUS */
1173 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0,
1174 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1176 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0);
1178 ring = &adev->vcn.inst[i].ring_dec;
1179 /* force RBC into idle state */
1180 rb_bufsz = order_base_2(ring->ring_size);
1181 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1182 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1183 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1184 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1185 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1186 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
1188 /* programm the RB_BASE for ring buffer */
1189 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1190 lower_32_bits(ring->gpu_addr));
1191 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1192 upper_32_bits(ring->gpu_addr));
1194 /* Initialize the ring buffer's read and write pointers */
1195 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
1197 ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
1198 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
1199 lower_32_bits(ring->wptr));
1200 ring = &adev->vcn.inst[i].ring_enc[0];
1201 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1202 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1203 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
1204 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1205 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4);
1207 ring = &adev->vcn.inst[i].ring_enc[1];
1208 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1209 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1210 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1211 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1212 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
1218 static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
1221 struct amdgpu_ring *ring;
1222 uint64_t cache_addr;
1225 uint32_t param, resp, expected;
1226 uint32_t offset, cache_size;
1227 uint32_t tmp, timeout;
1230 struct amdgpu_mm_table *table = &adev->virt.mm_table;
1231 uint32_t *table_loc;
1232 uint32_t table_size;
1233 uint32_t size, size_dw;
1237 struct mmsch_v3_0_cmd_direct_write
1238 direct_wt = { {0} };
1239 struct mmsch_v3_0_cmd_direct_read_modify_write
1240 direct_rd_mod_wt = { {0} };
1241 struct mmsch_v3_0_cmd_direct_polling
1242 direct_poll = { {0} };
1243 struct mmsch_v3_0_cmd_end end = { {0} };
1244 struct mmsch_v3_0_init_header header;
1246 direct_wt.cmd_header.command_type =
1247 MMSCH_COMMAND__DIRECT_REG_WRITE;
1248 direct_rd_mod_wt.cmd_header.command_type =
1249 MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
1250 direct_poll.cmd_header.command_type =
1251 MMSCH_COMMAND__DIRECT_REG_POLLING;
1252 end.cmd_header.command_type =
1255 header.version = MMSCH_VERSION;
1256 header.total_size = sizeof(struct mmsch_v3_0_init_header) >> 2;
1257 for (i = 0; i < AMDGPU_MAX_VCN_INSTANCES; i++) {
1258 header.inst[i].init_status = 0;
1259 header.inst[i].table_offset = 0;
1260 header.inst[i].table_size = 0;
1263 table_loc = (uint32_t *)table->cpu_addr;
1264 table_loc += header.total_size;
1265 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
1266 if (adev->vcn.harvest_config & (1 << i))
1271 MMSCH_V3_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i,
1273 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
1275 cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
1277 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1278 id = amdgpu_ucode_id_vcns[i];
1279 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1280 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1281 adev->firmware.ucode[id].tmr_mc_addr_lo);
1282 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1283 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1284 adev->firmware.ucode[id].tmr_mc_addr_hi);
1286 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1287 mmUVD_VCPU_CACHE_OFFSET0),
1290 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1291 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1292 lower_32_bits(adev->vcn.inst[i].gpu_addr));
1293 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1294 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1295 upper_32_bits(adev->vcn.inst[i].gpu_addr));
1296 offset = cache_size;
1297 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1298 mmUVD_VCPU_CACHE_OFFSET0),
1299 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
1302 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1303 mmUVD_VCPU_CACHE_SIZE0),
1306 cache_addr = adev->vcn.inst[i].gpu_addr + offset;
1307 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1308 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
1309 lower_32_bits(cache_addr));
1310 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1311 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
1312 upper_32_bits(cache_addr));
1313 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1314 mmUVD_VCPU_CACHE_OFFSET1),
1316 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1317 mmUVD_VCPU_CACHE_SIZE1),
1318 AMDGPU_VCN_STACK_SIZE);
1320 cache_addr = adev->vcn.inst[i].gpu_addr + offset +
1321 AMDGPU_VCN_STACK_SIZE;
1322 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1323 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
1324 lower_32_bits(cache_addr));
1325 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1326 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
1327 upper_32_bits(cache_addr));
1328 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1329 mmUVD_VCPU_CACHE_OFFSET2),
1331 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1332 mmUVD_VCPU_CACHE_SIZE2),
1333 AMDGPU_VCN_CONTEXT_SIZE);
1335 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
1336 ring = &adev->vcn.inst[i].ring_enc[j];
1338 rb_addr = ring->gpu_addr;
1339 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1341 lower_32_bits(rb_addr));
1342 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1344 upper_32_bits(rb_addr));
1345 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1347 ring->ring_size / 4);
1350 ring = &adev->vcn.inst[i].ring_dec;
1352 rb_addr = ring->gpu_addr;
1353 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1354 mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
1355 lower_32_bits(rb_addr));
1356 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1357 mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
1358 upper_32_bits(rb_addr));
1359 /* force RBC into idle state */
1360 tmp = order_base_2(ring->ring_size);
1361 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, tmp);
1362 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1363 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1364 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1365 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1366 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1370 /* add end packet */
1371 MMSCH_V3_0_INSERT_END();
1374 header.inst[i].init_status = 0;
1375 header.inst[i].table_offset = header.total_size;
1376 header.inst[i].table_size = table_size;
1377 header.total_size += table_size;
1380 /* Update init table header in memory */
1381 size = sizeof(struct mmsch_v3_0_init_header);
1382 table_loc = (uint32_t *)table->cpu_addr;
1383 memcpy((void *)table_loc, &header, size);
1385 /* message MMSCH (in VCN[0]) to initialize this client
1386 * 1, write to mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
1387 * of memory descriptor location
1389 ctx_addr = table->gpu_addr;
1390 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
1391 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
1393 /* 2, update vmid of descriptor */
1394 tmp = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID);
1395 tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
1396 /* use domain0 for MM scheduler */
1397 tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
1398 WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, tmp);
1400 /* 3, notify mmsch about the size of this descriptor */
1401 size = header.total_size;
1402 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size);
1404 /* 4, set resp to zero */
1405 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
1407 /* 5, kick off the initialization and wait until
1408 * MMSCH_VF_MAILBOX_RESP becomes non-zero
1411 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, param);
1415 expected = param + 1;
1416 while (resp != expected) {
1417 resp = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1418 if (resp == expected)
1423 if (tmp >= timeout) {
1424 DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
1425 " waiting for mmMMSCH_VF_MAILBOX_RESP "\
1426 "(expected=0x%08x, readback=0x%08x)\n",
1427 tmp, expected, resp);
1432 /* 6, check each VCN's init_status
1433 * if it remains as 0, then this VCN is not assigned to current VF
1434 * do not start ring for this VCN
1436 size = sizeof(struct mmsch_v3_0_init_header);
1437 table_loc = (uint32_t *)table->cpu_addr;
1438 memcpy(&header, (void *)table_loc, size);
1440 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
1441 if (adev->vcn.harvest_config & (1 << i))
1444 is_vcn_ready = (header.inst[i].init_status == 1);
1446 DRM_INFO("VCN(%d) engine is disabled by hypervisor\n", i);
1448 ring = &adev->vcn.inst[i].ring_dec;
1449 ring->sched.ready = is_vcn_ready;
1450 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
1451 ring = &adev->vcn.inst[i].ring_enc[j];
1452 ring->sched.ready = is_vcn_ready;
1459 static int vcn_v3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
1463 /* Wait for power status to be 1 */
1464 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1465 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1467 /* wait for read ptr to be equal to write ptr */
1468 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR);
1469 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1471 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2);
1472 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
1474 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
1475 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
1477 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1478 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1480 /* disable dynamic power gating mode */
1481 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0,
1482 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1487 static int vcn_v3_0_stop(struct amdgpu_device *adev)
1492 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1493 if (adev->vcn.harvest_config & (1 << i))
1496 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1497 r = vcn_v3_0_stop_dpg_mode(adev, i);
1501 /* wait for vcn idle */
1502 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1506 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1507 UVD_LMI_STATUS__READ_CLEAN_MASK |
1508 UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1509 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1510 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1514 /* disable LMI UMC channel */
1515 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
1516 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1517 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
1518 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
1519 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1520 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1524 /* block VCPU register access */
1525 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL),
1526 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1527 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1530 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1531 UVD_VCPU_CNTL__BLK_RST_MASK,
1532 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1534 /* disable VCPU clock */
1535 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1536 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
1538 /* apply soft reset */
1539 tmp = RREG32_SOC15(VCN, i, mmUVD_SOFT_RESET);
1540 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1541 WREG32_SOC15(VCN, i, mmUVD_SOFT_RESET, tmp);
1542 tmp = RREG32_SOC15(VCN, i, mmUVD_SOFT_RESET);
1543 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1544 WREG32_SOC15(VCN, i, mmUVD_SOFT_RESET, tmp);
1547 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
1549 /* apply HW clock gating */
1550 vcn_v3_0_enable_clock_gating(adev, i);
1552 /* enable VCN power gating */
1553 vcn_v3_0_enable_static_power_gating(adev, i);
1556 if (adev->pm.dpm_enabled)
1557 amdgpu_dpm_enable_uvd(adev, false);
1562 static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev,
1563 int inst_idx, struct dpg_pause_state *new_state)
1565 struct amdgpu_ring *ring;
1566 uint32_t reg_data = 0;
1569 /* pause/unpause if state is changed */
1570 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
1571 DRM_DEBUG("dpg pause state changed %d -> %d",
1572 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based);
1573 reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) &
1574 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1576 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
1577 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1578 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1582 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1583 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1586 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE,
1587 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
1588 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1591 ring = &adev->vcn.inst[inst_idx].ring_enc[0];
1592 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
1593 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1594 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
1595 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1596 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1598 ring = &adev->vcn.inst[inst_idx].ring_enc[1];
1599 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1600 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1601 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
1602 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1603 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1605 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
1606 RREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2) & 0x7FFFFFFF);
1608 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS,
1609 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1612 /* unpause dpg, no need to wait */
1613 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1614 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1616 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
1623 * vcn_v3_0_dec_ring_get_rptr - get read pointer
1625 * @ring: amdgpu_ring pointer
1627 * Returns the current hardware read pointer
1629 static uint64_t vcn_v3_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
1631 struct amdgpu_device *adev = ring->adev;
1633 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR);
1637 * vcn_v3_0_dec_ring_get_wptr - get write pointer
1639 * @ring: amdgpu_ring pointer
1641 * Returns the current hardware write pointer
1643 static uint64_t vcn_v3_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
1645 struct amdgpu_device *adev = ring->adev;
1647 if (ring->use_doorbell)
1648 return adev->wb.wb[ring->wptr_offs];
1650 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR);
1654 * vcn_v3_0_dec_ring_set_wptr - set write pointer
1656 * @ring: amdgpu_ring pointer
1658 * Commits the write pointer to the hardware
1660 static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
1662 struct amdgpu_device *adev = ring->adev;
1664 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
1665 WREG32_SOC15(VCN, ring->me, mmUVD_SCRATCH2,
1666 lower_32_bits(ring->wptr) | 0x80000000);
1668 if (ring->use_doorbell) {
1669 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1670 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1672 WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
1676 static const struct amdgpu_ring_funcs vcn_v3_0_dec_ring_vm_funcs = {
1677 .type = AMDGPU_RING_TYPE_VCN_DEC,
1679 .vmhub = AMDGPU_MMHUB_0,
1680 .get_rptr = vcn_v3_0_dec_ring_get_rptr,
1681 .get_wptr = vcn_v3_0_dec_ring_get_wptr,
1682 .set_wptr = vcn_v3_0_dec_ring_set_wptr,
1684 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1685 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1686 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
1687 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
1689 .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
1690 .emit_ib = vcn_v2_0_dec_ring_emit_ib,
1691 .emit_fence = vcn_v2_0_dec_ring_emit_fence,
1692 .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1693 .test_ring = vcn_v2_0_dec_ring_test_ring,
1694 .test_ib = amdgpu_vcn_dec_ring_test_ib,
1695 .insert_nop = vcn_v2_0_dec_ring_insert_nop,
1696 .insert_start = vcn_v2_0_dec_ring_insert_start,
1697 .insert_end = vcn_v2_0_dec_ring_insert_end,
1698 .pad_ib = amdgpu_ring_generic_pad_ib,
1699 .begin_use = amdgpu_vcn_ring_begin_use,
1700 .end_use = amdgpu_vcn_ring_end_use,
1701 .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1702 .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1703 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1707 * vcn_v3_0_enc_ring_get_rptr - get enc read pointer
1709 * @ring: amdgpu_ring pointer
1711 * Returns the current hardware enc read pointer
1713 static uint64_t vcn_v3_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
1715 struct amdgpu_device *adev = ring->adev;
1717 if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1718 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR);
1720 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2);
1724 * vcn_v3_0_enc_ring_get_wptr - get enc write pointer
1726 * @ring: amdgpu_ring pointer
1728 * Returns the current hardware enc write pointer
1730 static uint64_t vcn_v3_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
1732 struct amdgpu_device *adev = ring->adev;
1734 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1735 if (ring->use_doorbell)
1736 return adev->wb.wb[ring->wptr_offs];
1738 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR);
1740 if (ring->use_doorbell)
1741 return adev->wb.wb[ring->wptr_offs];
1743 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2);
1748 * vcn_v3_0_enc_ring_set_wptr - set enc write pointer
1750 * @ring: amdgpu_ring pointer
1752 * Commits the enc write pointer to the hardware
1754 static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
1756 struct amdgpu_device *adev = ring->adev;
1758 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1759 if (ring->use_doorbell) {
1760 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1761 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1763 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1766 if (ring->use_doorbell) {
1767 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1768 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1770 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1775 static const struct amdgpu_ring_funcs vcn_v3_0_enc_ring_vm_funcs = {
1776 .type = AMDGPU_RING_TYPE_VCN_ENC,
1778 .nop = VCN_ENC_CMD_NO_OP,
1779 .vmhub = AMDGPU_MMHUB_0,
1780 .get_rptr = vcn_v3_0_enc_ring_get_rptr,
1781 .get_wptr = vcn_v3_0_enc_ring_get_wptr,
1782 .set_wptr = vcn_v3_0_enc_ring_set_wptr,
1784 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1785 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1786 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1787 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1788 1, /* vcn_v2_0_enc_ring_insert_end */
1789 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1790 .emit_ib = vcn_v2_0_enc_ring_emit_ib,
1791 .emit_fence = vcn_v2_0_enc_ring_emit_fence,
1792 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1793 .test_ring = amdgpu_vcn_enc_ring_test_ring,
1794 .test_ib = amdgpu_vcn_enc_ring_test_ib,
1795 .insert_nop = amdgpu_ring_insert_nop,
1796 .insert_end = vcn_v2_0_enc_ring_insert_end,
1797 .pad_ib = amdgpu_ring_generic_pad_ib,
1798 .begin_use = amdgpu_vcn_ring_begin_use,
1799 .end_use = amdgpu_vcn_ring_end_use,
1800 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1801 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1802 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1805 static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev)
1809 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1810 if (adev->vcn.harvest_config & (1 << i))
1813 adev->vcn.inst[i].ring_dec.funcs = &vcn_v3_0_dec_ring_vm_funcs;
1814 adev->vcn.inst[i].ring_dec.me = i;
1815 DRM_INFO("VCN(%d) decode is enabled in VM mode\n", i);
1819 static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev)
1823 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1824 if (adev->vcn.harvest_config & (1 << i))
1827 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
1828 adev->vcn.inst[i].ring_enc[j].funcs = &vcn_v3_0_enc_ring_vm_funcs;
1829 adev->vcn.inst[i].ring_enc[j].me = i;
1831 DRM_INFO("VCN(%d) encode is enabled in VM mode\n", i);
1835 static bool vcn_v3_0_is_idle(void *handle)
1837 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1840 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1841 if (adev->vcn.harvest_config & (1 << i))
1844 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1850 static int vcn_v3_0_wait_for_idle(void *handle)
1852 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1855 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1856 if (adev->vcn.harvest_config & (1 << i))
1859 ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1868 static int vcn_v3_0_set_clockgating_state(void *handle,
1869 enum amd_clockgating_state state)
1871 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1872 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
1875 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1876 if (adev->vcn.harvest_config & (1 << i))
1880 if (RREG32_SOC15(VCN, i, mmUVD_STATUS) != UVD_STATUS__IDLE)
1882 vcn_v3_0_enable_clock_gating(adev, i);
1884 vcn_v3_0_disable_clock_gating(adev, i);
1891 static int vcn_v3_0_set_powergating_state(void *handle,
1892 enum amd_powergating_state state)
1894 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1897 /* for SRIOV, guest should not control VCN Power-gating
1898 * MMSCH FW should control Power-gating and clock-gating
1899 * guest should avoid touching CGC and PG
1901 if (amdgpu_sriov_vf(adev)) {
1902 adev->vcn.cur_state = AMD_PG_STATE_UNGATE;
1906 if(state == adev->vcn.cur_state)
1909 if (state == AMD_PG_STATE_GATE)
1910 ret = vcn_v3_0_stop(adev);
1912 ret = vcn_v3_0_start(adev);
1915 adev->vcn.cur_state = state;
1920 static int vcn_v3_0_set_interrupt_state(struct amdgpu_device *adev,
1921 struct amdgpu_irq_src *source,
1923 enum amdgpu_interrupt_state state)
1928 static int vcn_v3_0_process_interrupt(struct amdgpu_device *adev,
1929 struct amdgpu_irq_src *source,
1930 struct amdgpu_iv_entry *entry)
1932 uint32_t ip_instance;
1934 switch (entry->client_id) {
1935 case SOC15_IH_CLIENTID_VCN:
1938 case SOC15_IH_CLIENTID_VCN1:
1942 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1946 DRM_DEBUG("IH: VCN TRAP\n");
1948 switch (entry->src_id) {
1949 case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
1950 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
1952 case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1953 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
1955 case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
1956 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
1959 DRM_ERROR("Unhandled interrupt: %d %d\n",
1960 entry->src_id, entry->src_data[0]);
1967 static const struct amdgpu_irq_src_funcs vcn_v3_0_irq_funcs = {
1968 .set = vcn_v3_0_set_interrupt_state,
1969 .process = vcn_v3_0_process_interrupt,
1972 static void vcn_v3_0_set_irq_funcs(struct amdgpu_device *adev)
1976 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1977 if (adev->vcn.harvest_config & (1 << i))
1980 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1;
1981 adev->vcn.inst[i].irq.funcs = &vcn_v3_0_irq_funcs;
1985 static const struct amd_ip_funcs vcn_v3_0_ip_funcs = {
1987 .early_init = vcn_v3_0_early_init,
1989 .sw_init = vcn_v3_0_sw_init,
1990 .sw_fini = vcn_v3_0_sw_fini,
1991 .hw_init = vcn_v3_0_hw_init,
1992 .hw_fini = vcn_v3_0_hw_fini,
1993 .suspend = vcn_v3_0_suspend,
1994 .resume = vcn_v3_0_resume,
1995 .is_idle = vcn_v3_0_is_idle,
1996 .wait_for_idle = vcn_v3_0_wait_for_idle,
1997 .check_soft_reset = NULL,
1998 .pre_soft_reset = NULL,
2000 .post_soft_reset = NULL,
2001 .set_clockgating_state = vcn_v3_0_set_clockgating_state,
2002 .set_powergating_state = vcn_v3_0_set_powergating_state,
2005 const struct amdgpu_ip_block_version vcn_v3_0_ip_block =
2007 .type = AMD_IP_BLOCK_TYPE_VCN,
2011 .funcs = &vcn_v3_0_ip_funcs,