0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/firmware.h>
0025 #include "amdgpu.h"
0026 #include "amdgpu_vcn.h"
0027 #include "amdgpu_pm.h"
0028 #include "amdgpu_cs.h"
0029 #include "soc15.h"
0030 #include "soc15d.h"
0031 #include "vcn_v2_0.h"
0032 #include "mmsch_v3_0.h"
0033 #include "vcn_sw_ring.h"
0034
0035 #include "vcn/vcn_3_0_0_offset.h"
0036 #include "vcn/vcn_3_0_0_sh_mask.h"
0037 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
0038
0039 #include <drm/drm_drv.h>
0040
0041 #define VCN_VID_SOC_ADDRESS_2_0 0x1fa00
0042 #define VCN1_VID_SOC_ADDRESS_3_0 0x48200
0043
0044 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
0045 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
0046 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10
0047 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET 0x11
0048 #define mmUVD_NO_OP_INTERNAL_OFFSET 0x29
0049 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET 0x66
0050 #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d
0051
0052 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431
0053 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4
0054 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5
0055 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c
0056
0057 #define VCN_INSTANCES_SIENNA_CICHLID 2
0058 #define DEC_SW_RING_ENABLED FALSE
0059
0060 #define RDECODE_MSG_CREATE 0x00000000
0061 #define RDECODE_MESSAGE_CREATE 0x00000001
0062
0063 static int amdgpu_ih_clientid_vcns[] = {
0064 SOC15_IH_CLIENTID_VCN,
0065 SOC15_IH_CLIENTID_VCN1
0066 };
0067
0068 static int vcn_v3_0_start_sriov(struct amdgpu_device *adev);
0069 static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev);
0070 static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev);
0071 static void vcn_v3_0_set_irq_funcs(struct amdgpu_device *adev);
0072 static int vcn_v3_0_set_powergating_state(void *handle,
0073 enum amd_powergating_state state);
0074 static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev,
0075 int inst_idx, struct dpg_pause_state *new_state);
0076
0077 static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring);
0078 static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring);
0079
0080
0081
0082
0083
0084
0085
0086
0087 static int vcn_v3_0_early_init(void *handle)
0088 {
0089 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0090
0091 if (amdgpu_sriov_vf(adev)) {
0092 adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID;
0093 adev->vcn.harvest_config = 0;
0094 adev->vcn.num_enc_rings = 1;
0095
0096 } else {
0097 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
0098 AMDGPU_VCN_HARVEST_VCN1))
0099
0100 return -ENOENT;
0101
0102 if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 0, 33))
0103 adev->vcn.num_enc_rings = 0;
0104 else
0105 adev->vcn.num_enc_rings = 2;
0106 }
0107
0108 vcn_v3_0_set_dec_ring_funcs(adev);
0109 vcn_v3_0_set_enc_ring_funcs(adev);
0110 vcn_v3_0_set_irq_funcs(adev);
0111
0112 return 0;
0113 }
0114
0115
0116
0117
0118
0119
0120
0121
0122 static int vcn_v3_0_sw_init(void *handle)
0123 {
0124 struct amdgpu_ring *ring;
0125 int i, j, r;
0126 int vcn_doorbell_index = 0;
0127 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0128
0129 r = amdgpu_vcn_sw_init(adev);
0130 if (r)
0131 return r;
0132
0133 amdgpu_vcn_setup_ucode(adev);
0134
0135 r = amdgpu_vcn_resume(adev);
0136 if (r)
0137 return r;
0138
0139
0140
0141
0142
0143
0144
0145
0146 if (amdgpu_sriov_vf(adev)) {
0147 vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1;
0148
0149 vcn_doorbell_index = vcn_doorbell_index << 1;
0150 }
0151
0152 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
0153 volatile struct amdgpu_fw_shared *fw_shared;
0154
0155 if (adev->vcn.harvest_config & (1 << i))
0156 continue;
0157
0158 adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
0159 adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
0160 adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
0161 adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
0162 adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
0163 adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
0164
0165 adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
0166 adev->vcn.inst[i].external.scratch9 = SOC15_REG_OFFSET(VCN, i, mmUVD_SCRATCH9);
0167 adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
0168 adev->vcn.inst[i].external.data0 = SOC15_REG_OFFSET(VCN, i, mmUVD_GPCOM_VCPU_DATA0);
0169 adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
0170 adev->vcn.inst[i].external.data1 = SOC15_REG_OFFSET(VCN, i, mmUVD_GPCOM_VCPU_DATA1);
0171 adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
0172 adev->vcn.inst[i].external.cmd = SOC15_REG_OFFSET(VCN, i, mmUVD_GPCOM_VCPU_CMD);
0173 adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
0174 adev->vcn.inst[i].external.nop = SOC15_REG_OFFSET(VCN, i, mmUVD_NO_OP);
0175
0176
0177 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
0178 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[i].irq);
0179 if (r)
0180 return r;
0181
0182 atomic_set(&adev->vcn.inst[i].sched_score, 0);
0183
0184 ring = &adev->vcn.inst[i].ring_dec;
0185 ring->use_doorbell = true;
0186 if (amdgpu_sriov_vf(adev)) {
0187 ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1);
0188 } else {
0189 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i;
0190 }
0191 sprintf(ring->name, "vcn_dec_%d", i);
0192 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
0193 AMDGPU_RING_PRIO_DEFAULT,
0194 &adev->vcn.inst[i].sched_score);
0195 if (r)
0196 return r;
0197
0198 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
0199 enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(j);
0200
0201
0202 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
0203 j + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq);
0204 if (r)
0205 return r;
0206
0207 ring = &adev->vcn.inst[i].ring_enc[j];
0208 ring->use_doorbell = true;
0209 if (amdgpu_sriov_vf(adev)) {
0210 ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1 + j;
0211 } else {
0212 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + j + 8 * i;
0213 }
0214 sprintf(ring->name, "vcn_enc_%d.%d", i, j);
0215 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
0216 hw_prio, &adev->vcn.inst[i].sched_score);
0217 if (r)
0218 return r;
0219 }
0220
0221 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
0222 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SW_RING_FLAG) |
0223 cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG) |
0224 cpu_to_le32(AMDGPU_VCN_FW_SHARED_FLAG_0_RB);
0225 fw_shared->sw_ring.is_enabled = cpu_to_le32(DEC_SW_RING_ENABLED);
0226 fw_shared->present_flag_0 |= AMDGPU_VCN_SMU_VERSION_INFO_FLAG;
0227 if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 1, 2))
0228 fw_shared->smu_interface_info.smu_interface_type = 2;
0229 else if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 1, 1))
0230 fw_shared->smu_interface_info.smu_interface_type = 1;
0231
0232 if (amdgpu_vcnfw_log)
0233 amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
0234 }
0235
0236 if (amdgpu_sriov_vf(adev)) {
0237 r = amdgpu_virt_alloc_mm_table(adev);
0238 if (r)
0239 return r;
0240 }
0241 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
0242 adev->vcn.pause_dpg_mode = vcn_v3_0_pause_dpg_mode;
0243
0244 return 0;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254 static int vcn_v3_0_sw_fini(void *handle)
0255 {
0256 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0257 int i, r, idx;
0258
0259 if (drm_dev_enter(adev_to_drm(adev), &idx)) {
0260 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
0261 volatile struct amdgpu_fw_shared *fw_shared;
0262
0263 if (adev->vcn.harvest_config & (1 << i))
0264 continue;
0265 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
0266 fw_shared->present_flag_0 = 0;
0267 fw_shared->sw_ring.is_enabled = false;
0268 }
0269
0270 drm_dev_exit(idx);
0271 }
0272
0273 if (amdgpu_sriov_vf(adev))
0274 amdgpu_virt_free_mm_table(adev);
0275
0276 r = amdgpu_vcn_suspend(adev);
0277 if (r)
0278 return r;
0279
0280 r = amdgpu_vcn_sw_fini(adev);
0281
0282 return r;
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292 static int vcn_v3_0_hw_init(void *handle)
0293 {
0294 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0295 struct amdgpu_ring *ring;
0296 int i, j, r;
0297
0298 if (amdgpu_sriov_vf(adev)) {
0299 r = vcn_v3_0_start_sriov(adev);
0300 if (r)
0301 goto done;
0302
0303
0304 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
0305 if (adev->vcn.harvest_config & (1 << i))
0306 continue;
0307
0308 ring = &adev->vcn.inst[i].ring_dec;
0309 if (amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, i)) {
0310 ring->sched.ready = false;
0311 ring->no_scheduler = true;
0312 dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
0313 } else {
0314 ring->wptr = 0;
0315 ring->wptr_old = 0;
0316 vcn_v3_0_dec_ring_set_wptr(ring);
0317 ring->sched.ready = true;
0318 }
0319
0320 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
0321 ring = &adev->vcn.inst[i].ring_enc[j];
0322 if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
0323 ring->sched.ready = false;
0324 ring->no_scheduler = true;
0325 dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
0326 } else {
0327 ring->wptr = 0;
0328 ring->wptr_old = 0;
0329 vcn_v3_0_enc_ring_set_wptr(ring);
0330 ring->sched.ready = true;
0331 }
0332 }
0333 }
0334 } else {
0335 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
0336 if (adev->vcn.harvest_config & (1 << i))
0337 continue;
0338
0339 ring = &adev->vcn.inst[i].ring_dec;
0340
0341 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
0342 ring->doorbell_index, i);
0343
0344 r = amdgpu_ring_test_helper(ring);
0345 if (r)
0346 goto done;
0347
0348 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
0349 ring = &adev->vcn.inst[i].ring_enc[j];
0350 r = amdgpu_ring_test_helper(ring);
0351 if (r)
0352 goto done;
0353 }
0354 }
0355 }
0356
0357 done:
0358 if (!r)
0359 DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
0360 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
0361
0362 return r;
0363 }
0364
0365
0366
0367
0368
0369
0370
0371
0372 static int vcn_v3_0_hw_fini(void *handle)
0373 {
0374 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0375 int i;
0376
0377 cancel_delayed_work_sync(&adev->vcn.idle_work);
0378
0379 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
0380 if (adev->vcn.harvest_config & (1 << i))
0381 continue;
0382
0383 if (!amdgpu_sriov_vf(adev)) {
0384 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
0385 (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
0386 RREG32_SOC15(VCN, i, mmUVD_STATUS))) {
0387 vcn_v3_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
0388 }
0389 }
0390 }
0391
0392 return 0;
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402 static int vcn_v3_0_suspend(void *handle)
0403 {
0404 int r;
0405 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0406
0407 r = vcn_v3_0_hw_fini(adev);
0408 if (r)
0409 return r;
0410
0411 r = amdgpu_vcn_suspend(adev);
0412
0413 return r;
0414 }
0415
0416
0417
0418
0419
0420
0421
0422
0423 static int vcn_v3_0_resume(void *handle)
0424 {
0425 int r;
0426 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0427
0428 r = amdgpu_vcn_resume(adev);
0429 if (r)
0430 return r;
0431
0432 r = vcn_v3_0_hw_init(adev);
0433
0434 return r;
0435 }
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445 static void vcn_v3_0_mc_resume(struct amdgpu_device *adev, int inst)
0446 {
0447 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
0448 uint32_t offset;
0449
0450
0451 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0452 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
0453 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo));
0454 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
0455 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi));
0456 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET0, 0);
0457 offset = 0;
0458 } else {
0459 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
0460 lower_32_bits(adev->vcn.inst[inst].gpu_addr));
0461 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
0462 upper_32_bits(adev->vcn.inst[inst].gpu_addr));
0463 offset = size;
0464 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET0,
0465 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
0466 }
0467 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_SIZE0, size);
0468
0469
0470 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
0471 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
0472 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
0473 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
0474 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET1, 0);
0475 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
0476
0477
0478 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
0479 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
0480 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
0481 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
0482 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_OFFSET2, 0);
0483 WREG32_SOC15(VCN, inst, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
0484
0485
0486 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
0487 lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
0488 WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
0489 upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
0490 WREG32_SOC15(VCN, inst, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
0491 WREG32_SOC15(VCN, inst, mmUVD_VCPU_NONCACHE_SIZE0,
0492 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
0493 }
0494
0495 static void vcn_v3_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
0496 {
0497 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
0498 uint32_t offset;
0499
0500
0501 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0502 if (!indirect) {
0503 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0504 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
0505 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
0506 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0507 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
0508 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
0509 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0510 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
0511 } else {
0512 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0513 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
0514 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0515 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
0516 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0517 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
0518 }
0519 offset = 0;
0520 } else {
0521 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0522 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
0523 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
0524 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0525 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
0526 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
0527 offset = size;
0528 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0529 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET0),
0530 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
0531 }
0532
0533 if (!indirect)
0534 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0535 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
0536 else
0537 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0538 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
0539
0540
0541 if (!indirect) {
0542 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0543 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
0544 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
0545 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0546 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
0547 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
0548 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0549 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
0550 } else {
0551 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0552 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
0553 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0554 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
0555 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0556 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
0557 }
0558 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0559 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
0560
0561
0562 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0563 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
0564 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
0565 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0566 VCN, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
0567 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
0568 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0569 VCN, inst_idx, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
0570 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0571 VCN, inst_idx, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
0572
0573
0574 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0575 VCN, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
0576 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
0577 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0578 VCN, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
0579 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
0580 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0581 VCN, inst_idx, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
0582 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0583 VCN, inst_idx, mmUVD_VCPU_NONCACHE_SIZE0),
0584 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
0585
0586
0587 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0588 UVD, inst_idx, mmUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
0589 }
0590
0591 static void vcn_v3_0_disable_static_power_gating(struct amdgpu_device *adev, int inst)
0592 {
0593 uint32_t data = 0;
0594
0595 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
0596 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
0597 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
0598 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
0599 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
0600 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
0601 | 2 << UVD_PGFSM_CONFIG__UVDIRL_PWR_CONFIG__SHIFT
0602 | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
0603 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
0604 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
0605 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
0606 | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
0607 | 2 << UVD_PGFSM_CONFIG__UVDATD_PWR_CONFIG__SHIFT
0608 | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
0609 | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
0610
0611 WREG32_SOC15(VCN, inst, mmUVD_PGFSM_CONFIG, data);
0612 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_PGFSM_STATUS,
0613 UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0, 0x3F3FFFFF);
0614 } else {
0615 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
0616 | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
0617 | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
0618 | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
0619 | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
0620 | 1 << UVD_PGFSM_CONFIG__UVDIRL_PWR_CONFIG__SHIFT
0621 | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
0622 | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
0623 | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
0624 | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
0625 | 1 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
0626 | 1 << UVD_PGFSM_CONFIG__UVDATD_PWR_CONFIG__SHIFT
0627 | 1 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
0628 | 1 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
0629 WREG32_SOC15(VCN, inst, mmUVD_PGFSM_CONFIG, data);
0630 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_PGFSM_STATUS, 0, 0x3F3FFFFF);
0631 }
0632
0633 data = RREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS);
0634 data &= ~0x103;
0635 if (adev->pg_flags & AMD_PG_SUPPORT_VCN)
0636 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON |
0637 UVD_POWER_STATUS__UVD_PG_EN_MASK;
0638
0639 WREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS, data);
0640 }
0641
0642 static void vcn_v3_0_enable_static_power_gating(struct amdgpu_device *adev, int inst)
0643 {
0644 uint32_t data;
0645
0646 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
0647
0648 data = RREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS);
0649 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;
0650 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;
0651 WREG32_SOC15(VCN, inst, mmUVD_POWER_STATUS, data);
0652
0653 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
0654 | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
0655 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
0656 | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
0657 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
0658 | 2 << UVD_PGFSM_CONFIG__UVDIRL_PWR_CONFIG__SHIFT
0659 | 2 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
0660 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
0661 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
0662 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
0663 | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
0664 | 2 << UVD_PGFSM_CONFIG__UVDATD_PWR_CONFIG__SHIFT
0665 | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
0666 | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
0667 WREG32_SOC15(VCN, inst, mmUVD_PGFSM_CONFIG, data);
0668
0669 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT
0670 | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT
0671 | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT
0672 | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT
0673 | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT
0674 | 2 << UVD_PGFSM_STATUS__UVDIRL_PWR_STATUS__SHIFT
0675 | 2 << UVD_PGFSM_STATUS__UVDLM_PWR_STATUS__SHIFT
0676 | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT
0677 | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT
0678 | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT
0679 | 2 << UVD_PGFSM_STATUS__UVDAB_PWR_STATUS__SHIFT
0680 | 2 << UVD_PGFSM_STATUS__UVDATD_PWR_STATUS__SHIFT
0681 | 2 << UVD_PGFSM_STATUS__UVDNA_PWR_STATUS__SHIFT
0682 | 2 << UVD_PGFSM_STATUS__UVDNB_PWR_STATUS__SHIFT);
0683 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_PGFSM_STATUS, data, 0x3F3FFFFF);
0684 }
0685 }
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695 static void vcn_v3_0_disable_clock_gating(struct amdgpu_device *adev, int inst)
0696 {
0697 uint32_t data;
0698
0699
0700 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
0701 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
0702 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0703 else
0704 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
0705 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
0706 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
0707 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
0708
0709 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_GATE);
0710 data &= ~(UVD_CGC_GATE__SYS_MASK
0711 | UVD_CGC_GATE__UDEC_MASK
0712 | UVD_CGC_GATE__MPEG2_MASK
0713 | UVD_CGC_GATE__REGS_MASK
0714 | UVD_CGC_GATE__RBC_MASK
0715 | UVD_CGC_GATE__LMI_MC_MASK
0716 | UVD_CGC_GATE__LMI_UMC_MASK
0717 | UVD_CGC_GATE__IDCT_MASK
0718 | UVD_CGC_GATE__MPRD_MASK
0719 | UVD_CGC_GATE__MPC_MASK
0720 | UVD_CGC_GATE__LBSI_MASK
0721 | UVD_CGC_GATE__LRBBM_MASK
0722 | UVD_CGC_GATE__UDEC_RE_MASK
0723 | UVD_CGC_GATE__UDEC_CM_MASK
0724 | UVD_CGC_GATE__UDEC_IT_MASK
0725 | UVD_CGC_GATE__UDEC_DB_MASK
0726 | UVD_CGC_GATE__UDEC_MP_MASK
0727 | UVD_CGC_GATE__WCB_MASK
0728 | UVD_CGC_GATE__VCPU_MASK
0729 | UVD_CGC_GATE__MMSCH_MASK);
0730
0731 WREG32_SOC15(VCN, inst, mmUVD_CGC_GATE, data);
0732
0733 SOC15_WAIT_ON_RREG(VCN, inst, mmUVD_CGC_GATE, 0, 0xFFFFFFFF);
0734
0735 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
0736 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
0737 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
0738 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
0739 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
0740 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
0741 | UVD_CGC_CTRL__SYS_MODE_MASK
0742 | UVD_CGC_CTRL__UDEC_MODE_MASK
0743 | UVD_CGC_CTRL__MPEG2_MODE_MASK
0744 | UVD_CGC_CTRL__REGS_MODE_MASK
0745 | UVD_CGC_CTRL__RBC_MODE_MASK
0746 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
0747 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
0748 | UVD_CGC_CTRL__IDCT_MODE_MASK
0749 | UVD_CGC_CTRL__MPRD_MODE_MASK
0750 | UVD_CGC_CTRL__MPC_MODE_MASK
0751 | UVD_CGC_CTRL__LBSI_MODE_MASK
0752 | UVD_CGC_CTRL__LRBBM_MODE_MASK
0753 | UVD_CGC_CTRL__WCB_MODE_MASK
0754 | UVD_CGC_CTRL__VCPU_MODE_MASK
0755 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
0756 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
0757
0758 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE);
0759 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
0760 | UVD_SUVD_CGC_GATE__SIT_MASK
0761 | UVD_SUVD_CGC_GATE__SMP_MASK
0762 | UVD_SUVD_CGC_GATE__SCM_MASK
0763 | UVD_SUVD_CGC_GATE__SDB_MASK
0764 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
0765 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
0766 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
0767 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
0768 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
0769 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
0770 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
0771 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
0772 | UVD_SUVD_CGC_GATE__SCLR_MASK
0773 | UVD_SUVD_CGC_GATE__ENT_MASK
0774 | UVD_SUVD_CGC_GATE__IME_MASK
0775 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
0776 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
0777 | UVD_SUVD_CGC_GATE__SITE_MASK
0778 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
0779 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
0780 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
0781 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
0782 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK
0783 | UVD_SUVD_CGC_GATE__EFC_MASK
0784 | UVD_SUVD_CGC_GATE__SAOE_MASK
0785 | UVD_SUVD_CGC_GATE__SRE_AV1_MASK
0786 | UVD_SUVD_CGC_GATE__FBC_PCLK_MASK
0787 | UVD_SUVD_CGC_GATE__FBC_CCLK_MASK
0788 | UVD_SUVD_CGC_GATE__SCM_AV1_MASK
0789 | UVD_SUVD_CGC_GATE__SMPA_MASK);
0790 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE, data);
0791
0792 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE2);
0793 data |= (UVD_SUVD_CGC_GATE2__MPBE0_MASK
0794 | UVD_SUVD_CGC_GATE2__MPBE1_MASK
0795 | UVD_SUVD_CGC_GATE2__SIT_AV1_MASK
0796 | UVD_SUVD_CGC_GATE2__SDB_AV1_MASK
0797 | UVD_SUVD_CGC_GATE2__MPC1_MASK);
0798 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_GATE2, data);
0799
0800 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL);
0801 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
0802 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
0803 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
0804 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
0805 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
0806 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
0807 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
0808 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
0809 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK
0810 | UVD_SUVD_CGC_CTRL__EFC_MODE_MASK
0811 | UVD_SUVD_CGC_CTRL__SAOE_MODE_MASK
0812 | UVD_SUVD_CGC_CTRL__SMPA_MODE_MASK
0813 | UVD_SUVD_CGC_CTRL__MPBE0_MODE_MASK
0814 | UVD_SUVD_CGC_CTRL__MPBE1_MODE_MASK
0815 | UVD_SUVD_CGC_CTRL__SIT_AV1_MODE_MASK
0816 | UVD_SUVD_CGC_CTRL__SDB_AV1_MODE_MASK
0817 | UVD_SUVD_CGC_CTRL__MPC1_MODE_MASK
0818 | UVD_SUVD_CGC_CTRL__FBC_PCLK_MASK
0819 | UVD_SUVD_CGC_CTRL__FBC_CCLK_MASK);
0820 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL, data);
0821 }
0822
0823 static void vcn_v3_0_clock_gating_dpg_mode(struct amdgpu_device *adev,
0824 uint8_t sram_sel, int inst_idx, uint8_t indirect)
0825 {
0826 uint32_t reg_data = 0;
0827
0828
0829 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
0830 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0831 else
0832 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0833 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
0834 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
0835 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
0836 UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
0837 UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
0838 UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
0839 UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
0840 UVD_CGC_CTRL__SYS_MODE_MASK |
0841 UVD_CGC_CTRL__UDEC_MODE_MASK |
0842 UVD_CGC_CTRL__MPEG2_MODE_MASK |
0843 UVD_CGC_CTRL__REGS_MODE_MASK |
0844 UVD_CGC_CTRL__RBC_MODE_MASK |
0845 UVD_CGC_CTRL__LMI_MC_MODE_MASK |
0846 UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
0847 UVD_CGC_CTRL__IDCT_MODE_MASK |
0848 UVD_CGC_CTRL__MPRD_MODE_MASK |
0849 UVD_CGC_CTRL__MPC_MODE_MASK |
0850 UVD_CGC_CTRL__LBSI_MODE_MASK |
0851 UVD_CGC_CTRL__LRBBM_MODE_MASK |
0852 UVD_CGC_CTRL__WCB_MODE_MASK |
0853 UVD_CGC_CTRL__VCPU_MODE_MASK |
0854 UVD_CGC_CTRL__MMSCH_MODE_MASK);
0855 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0856 VCN, inst_idx, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
0857
0858
0859 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0860 VCN, inst_idx, mmUVD_CGC_GATE), 0, sram_sel, indirect);
0861
0862
0863 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0864 VCN, inst_idx, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
0865
0866
0867 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0868 VCN, inst_idx, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
0869 }
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 static void vcn_v3_0_enable_clock_gating(struct amdgpu_device *adev, int inst)
0880 {
0881 uint32_t data;
0882
0883
0884 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
0885 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
0886 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0887 else
0888 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0889 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
0890 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
0891 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
0892
0893 data = RREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL);
0894 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
0895 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
0896 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
0897 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
0898 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
0899 | UVD_CGC_CTRL__SYS_MODE_MASK
0900 | UVD_CGC_CTRL__UDEC_MODE_MASK
0901 | UVD_CGC_CTRL__MPEG2_MODE_MASK
0902 | UVD_CGC_CTRL__REGS_MODE_MASK
0903 | UVD_CGC_CTRL__RBC_MODE_MASK
0904 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
0905 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
0906 | UVD_CGC_CTRL__IDCT_MODE_MASK
0907 | UVD_CGC_CTRL__MPRD_MODE_MASK
0908 | UVD_CGC_CTRL__MPC_MODE_MASK
0909 | UVD_CGC_CTRL__LBSI_MODE_MASK
0910 | UVD_CGC_CTRL__LRBBM_MODE_MASK
0911 | UVD_CGC_CTRL__WCB_MODE_MASK
0912 | UVD_CGC_CTRL__VCPU_MODE_MASK
0913 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
0914 WREG32_SOC15(VCN, inst, mmUVD_CGC_CTRL, data);
0915
0916 data = RREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL);
0917 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
0918 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
0919 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
0920 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
0921 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
0922 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
0923 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
0924 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
0925 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK
0926 | UVD_SUVD_CGC_CTRL__EFC_MODE_MASK
0927 | UVD_SUVD_CGC_CTRL__SAOE_MODE_MASK
0928 | UVD_SUVD_CGC_CTRL__SMPA_MODE_MASK
0929 | UVD_SUVD_CGC_CTRL__MPBE0_MODE_MASK
0930 | UVD_SUVD_CGC_CTRL__MPBE1_MODE_MASK
0931 | UVD_SUVD_CGC_CTRL__SIT_AV1_MODE_MASK
0932 | UVD_SUVD_CGC_CTRL__SDB_AV1_MODE_MASK
0933 | UVD_SUVD_CGC_CTRL__MPC1_MODE_MASK
0934 | UVD_SUVD_CGC_CTRL__FBC_PCLK_MASK
0935 | UVD_SUVD_CGC_CTRL__FBC_CCLK_MASK);
0936 WREG32_SOC15(VCN, inst, mmUVD_SUVD_CGC_CTRL, data);
0937 }
0938
0939 static int vcn_v3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
0940 {
0941 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
0942 struct amdgpu_ring *ring;
0943 uint32_t rb_bufsz, tmp;
0944
0945
0946 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1,
0947 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
0948
0949 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS);
0950 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
0951 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
0952 WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp);
0953
0954 if (indirect)
0955 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
0956
0957
0958 vcn_v3_0_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);
0959
0960
0961 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
0962 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
0963 tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
0964 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0965 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
0966
0967
0968 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0969 VCN, inst_idx, mmUVD_MASTINT_EN), 0, 0, indirect);
0970
0971
0972 tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
0973 UVD_LMI_CTRL__REQ_MODE_MASK |
0974 UVD_LMI_CTRL__CRC_RESET_MASK |
0975 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
0976 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
0977 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
0978 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
0979 0x00100000L);
0980 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0981 VCN, inst_idx, mmUVD_LMI_CTRL), tmp, 0, indirect);
0982
0983 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0984 VCN, inst_idx, mmUVD_MPC_CNTL),
0985 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
0986
0987 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0988 VCN, inst_idx, mmUVD_MPC_SET_MUXA0),
0989 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
0990 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
0991 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
0992 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
0993
0994 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
0995 VCN, inst_idx, mmUVD_MPC_SET_MUXB0),
0996 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
0997 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
0998 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
0999 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
1000
1001 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1002 VCN, inst_idx, mmUVD_MPC_SET_MUX),
1003 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1004 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1005 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
1006
1007 vcn_v3_0_mc_resume_dpg_mode(adev, inst_idx, indirect);
1008
1009 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1010 VCN, inst_idx, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
1011 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1012 VCN, inst_idx, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
1013
1014
1015 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1016 VCN, inst_idx, mmUVD_LMI_CTRL2), 0, 0, indirect);
1017
1018
1019 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1020 VCN, inst_idx, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
1021
1022 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
1023 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
1024 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1025 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1026
1027
1028 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1029 VCN, inst_idx, mmUVD_MASTINT_EN),
1030 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
1031
1032
1033 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1034 VCN, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1035
1036 if (indirect)
1037 psp_update_vcn_sram(adev, inst_idx, adev->vcn.inst[inst_idx].dpg_sram_gpu_addr,
1038 (uint32_t)((uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_curr_addr -
1039 (uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr));
1040
1041 ring = &adev->vcn.inst[inst_idx].ring_dec;
1042
1043 rb_bufsz = order_base_2(ring->ring_size);
1044 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1045 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1046 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1047 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1048 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1049 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
1050
1051
1052 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1053 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1054 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1055 fw_shared->multi_queue.decode_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
1056
1057
1058 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
1059
1060
1061 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
1062 (upper_32_bits(ring->gpu_addr) >> 2));
1063
1064
1065 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1066 lower_32_bits(ring->gpu_addr));
1067 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1068 upper_32_bits(ring->gpu_addr));
1069
1070
1071 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0);
1072
1073 WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0);
1074
1075 ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR);
1076 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
1077 lower_32_bits(ring->wptr));
1078
1079
1080 fw_shared->rb.rptr = 0;
1081 fw_shared->rb.wptr = lower_32_bits(ring->wptr);
1082
1083
1084 fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
1085
1086
1087 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1088 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1089
1090 return 0;
1091 }
1092
1093 static int vcn_v3_0_start(struct amdgpu_device *adev)
1094 {
1095 volatile struct amdgpu_fw_shared *fw_shared;
1096 struct amdgpu_ring *ring;
1097 uint32_t rb_bufsz, tmp;
1098 int i, j, k, r;
1099
1100 if (adev->pm.dpm_enabled)
1101 amdgpu_dpm_enable_uvd(adev, true);
1102
1103 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1104 if (adev->vcn.harvest_config & (1 << i))
1105 continue;
1106
1107 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
1108 r = vcn_v3_0_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
1109 continue;
1110 }
1111
1112
1113 vcn_v3_0_disable_static_power_gating(adev, i);
1114
1115
1116 tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
1117 WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp);
1118
1119
1120 vcn_v3_0_disable_clock_gating(adev, i);
1121
1122
1123 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1124 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
1125
1126
1127 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0,
1128 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1129
1130
1131 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0,
1132 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1133
1134 tmp = RREG32_SOC15(VCN, i, mmUVD_SOFT_RESET);
1135 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1136 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1137 WREG32_SOC15(VCN, i, mmUVD_SOFT_RESET, tmp);
1138
1139
1140 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL);
1141 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp |
1142 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1143 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1144 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1145 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1146
1147
1148 tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL);
1149 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
1150 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
1151 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
1152
1153
1154 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0,
1155 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1156 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1157 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1158 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
1159
1160
1161 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0,
1162 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1163 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1164 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1165 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
1166
1167
1168 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX,
1169 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1170 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1171 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
1172
1173 vcn_v3_0_mc_resume(adev, i);
1174
1175
1176 WREG32_SOC15(VCN, i, mmUVD_GFX10_ADDR_CONFIG,
1177 adev->gfx.config.gb_addr_config);
1178
1179
1180 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0,
1181 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1182
1183
1184 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1185 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1186
1187 for (j = 0; j < 10; ++j) {
1188 uint32_t status;
1189
1190 for (k = 0; k < 100; ++k) {
1191 status = RREG32_SOC15(VCN, i, mmUVD_STATUS);
1192 if (status & 2)
1193 break;
1194 mdelay(10);
1195 }
1196 r = 0;
1197 if (status & 2)
1198 break;
1199
1200 DRM_ERROR("VCN[%d] decode not responding, trying to reset the VCPU!!!\n", i);
1201 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1202 UVD_VCPU_CNTL__BLK_RST_MASK,
1203 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1204 mdelay(10);
1205 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1206 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1207
1208 mdelay(10);
1209 r = -1;
1210 }
1211
1212 if (r) {
1213 DRM_ERROR("VCN[%d] decode not responding, giving up!!!\n", i);
1214 return r;
1215 }
1216
1217
1218 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN),
1219 UVD_MASTINT_EN__VCPU_EN_MASK,
1220 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1221
1222
1223 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0,
1224 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1225
1226 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0);
1227
1228 ring = &adev->vcn.inst[i].ring_dec;
1229
1230 rb_bufsz = order_base_2(ring->ring_size);
1231 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1232 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1233 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1234 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1235 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1236 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
1237
1238 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
1239 fw_shared->multi_queue.decode_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
1240
1241
1242 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1243 lower_32_bits(ring->gpu_addr));
1244 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1245 upper_32_bits(ring->gpu_addr));
1246
1247
1248 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
1249
1250 WREG32_SOC15(VCN, i, mmUVD_SCRATCH2, 0);
1251 ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
1252 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
1253 lower_32_bits(ring->wptr));
1254 fw_shared->rb.wptr = lower_32_bits(ring->wptr);
1255 fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
1256
1257 if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(3, 0, 33)) {
1258 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
1259 ring = &adev->vcn.inst[i].ring_enc[0];
1260 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1261 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1262 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
1263 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1264 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4);
1265 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
1266
1267 fw_shared->multi_queue.encode_lowlatency_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
1268 ring = &adev->vcn.inst[i].ring_enc[1];
1269 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1270 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1271 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1272 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1273 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
1274 fw_shared->multi_queue.encode_lowlatency_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
1275 }
1276 }
1277
1278 return 0;
1279 }
1280
1281 static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
1282 {
1283 int i, j;
1284 struct amdgpu_ring *ring;
1285 uint64_t cache_addr;
1286 uint64_t rb_addr;
1287 uint64_t ctx_addr;
1288 uint32_t param, resp, expected;
1289 uint32_t offset, cache_size;
1290 uint32_t tmp, timeout;
1291
1292 struct amdgpu_mm_table *table = &adev->virt.mm_table;
1293 uint32_t *table_loc;
1294 uint32_t table_size;
1295 uint32_t size, size_dw;
1296
1297 struct mmsch_v3_0_cmd_direct_write
1298 direct_wt = { {0} };
1299 struct mmsch_v3_0_cmd_direct_read_modify_write
1300 direct_rd_mod_wt = { {0} };
1301 struct mmsch_v3_0_cmd_end end = { {0} };
1302 struct mmsch_v3_0_init_header header;
1303
1304 direct_wt.cmd_header.command_type =
1305 MMSCH_COMMAND__DIRECT_REG_WRITE;
1306 direct_rd_mod_wt.cmd_header.command_type =
1307 MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
1308 end.cmd_header.command_type =
1309 MMSCH_COMMAND__END;
1310
1311 header.version = MMSCH_VERSION;
1312 header.total_size = sizeof(struct mmsch_v3_0_init_header) >> 2;
1313 for (i = 0; i < AMDGPU_MAX_VCN_INSTANCES; i++) {
1314 header.inst[i].init_status = 0;
1315 header.inst[i].table_offset = 0;
1316 header.inst[i].table_size = 0;
1317 }
1318
1319 table_loc = (uint32_t *)table->cpu_addr;
1320 table_loc += header.total_size;
1321 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
1322 if (adev->vcn.harvest_config & (1 << i))
1323 continue;
1324
1325 table_size = 0;
1326
1327 MMSCH_V3_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i,
1328 mmUVD_STATUS),
1329 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
1330
1331 cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
1332
1333 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1334 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1335 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1336 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
1337 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1338 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1339 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
1340 offset = 0;
1341 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1342 mmUVD_VCPU_CACHE_OFFSET0),
1343 0);
1344 } else {
1345 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1346 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1347 lower_32_bits(adev->vcn.inst[i].gpu_addr));
1348 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1349 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1350 upper_32_bits(adev->vcn.inst[i].gpu_addr));
1351 offset = cache_size;
1352 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1353 mmUVD_VCPU_CACHE_OFFSET0),
1354 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
1355 }
1356
1357 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1358 mmUVD_VCPU_CACHE_SIZE0),
1359 cache_size);
1360
1361 cache_addr = adev->vcn.inst[i].gpu_addr + offset;
1362 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1363 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
1364 lower_32_bits(cache_addr));
1365 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1366 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
1367 upper_32_bits(cache_addr));
1368 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1369 mmUVD_VCPU_CACHE_OFFSET1),
1370 0);
1371 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1372 mmUVD_VCPU_CACHE_SIZE1),
1373 AMDGPU_VCN_STACK_SIZE);
1374
1375 cache_addr = adev->vcn.inst[i].gpu_addr + offset +
1376 AMDGPU_VCN_STACK_SIZE;
1377 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1378 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
1379 lower_32_bits(cache_addr));
1380 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1381 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
1382 upper_32_bits(cache_addr));
1383 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1384 mmUVD_VCPU_CACHE_OFFSET2),
1385 0);
1386 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1387 mmUVD_VCPU_CACHE_SIZE2),
1388 AMDGPU_VCN_CONTEXT_SIZE);
1389
1390 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
1391 ring = &adev->vcn.inst[i].ring_enc[j];
1392 ring->wptr = 0;
1393 rb_addr = ring->gpu_addr;
1394 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1395 mmUVD_RB_BASE_LO),
1396 lower_32_bits(rb_addr));
1397 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1398 mmUVD_RB_BASE_HI),
1399 upper_32_bits(rb_addr));
1400 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1401 mmUVD_RB_SIZE),
1402 ring->ring_size / 4);
1403 }
1404
1405 ring = &adev->vcn.inst[i].ring_dec;
1406 ring->wptr = 0;
1407 rb_addr = ring->gpu_addr;
1408 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1409 mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
1410 lower_32_bits(rb_addr));
1411 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1412 mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
1413 upper_32_bits(rb_addr));
1414
1415 tmp = order_base_2(ring->ring_size);
1416 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, tmp);
1417 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1418 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1419 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1420 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1421 MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1422 mmUVD_RBC_RB_CNTL),
1423 tmp);
1424
1425
1426 MMSCH_V3_0_INSERT_END();
1427
1428
1429 header.inst[i].init_status = 0;
1430 header.inst[i].table_offset = header.total_size;
1431 header.inst[i].table_size = table_size;
1432 header.total_size += table_size;
1433 }
1434
1435
1436 size = sizeof(struct mmsch_v3_0_init_header);
1437 table_loc = (uint32_t *)table->cpu_addr;
1438 memcpy((void *)table_loc, &header, size);
1439
1440
1441
1442
1443
1444 ctx_addr = table->gpu_addr;
1445 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
1446 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
1447
1448
1449 tmp = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID);
1450 tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
1451
1452 tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
1453 WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, tmp);
1454
1455
1456 size = header.total_size;
1457 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size);
1458
1459
1460 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
1461
1462
1463
1464
1465 param = 0x10000001;
1466 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, param);
1467 tmp = 0;
1468 timeout = 1000;
1469 resp = 0;
1470 expected = param + 1;
1471 while (resp != expected) {
1472 resp = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1473 if (resp == expected)
1474 break;
1475
1476 udelay(10);
1477 tmp = tmp + 10;
1478 if (tmp >= timeout) {
1479 DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
1480 " waiting for mmMMSCH_VF_MAILBOX_RESP "\
1481 "(expected=0x%08x, readback=0x%08x)\n",
1482 tmp, expected, resp);
1483 return -EBUSY;
1484 }
1485 }
1486
1487 return 0;
1488 }
1489
1490 static int vcn_v3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
1491 {
1492 struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};
1493 uint32_t tmp;
1494
1495 vcn_v3_0_pause_dpg_mode(adev, inst_idx, &state);
1496
1497
1498 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1499 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1500
1501
1502 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR);
1503 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1504
1505 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2);
1506 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
1507
1508 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
1509 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
1510
1511 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1512 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1513
1514
1515 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0,
1516 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1517
1518 return 0;
1519 }
1520
1521 static int vcn_v3_0_stop(struct amdgpu_device *adev)
1522 {
1523 uint32_t tmp;
1524 int i, r = 0;
1525
1526 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1527 if (adev->vcn.harvest_config & (1 << i))
1528 continue;
1529
1530 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1531 r = vcn_v3_0_stop_dpg_mode(adev, i);
1532 continue;
1533 }
1534
1535
1536 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1537 if (r)
1538 return r;
1539
1540 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1541 UVD_LMI_STATUS__READ_CLEAN_MASK |
1542 UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1543 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1544 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1545 if (r)
1546 return r;
1547
1548
1549 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
1550 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1551 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
1552 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
1553 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1554 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1555 if (r)
1556 return r;
1557
1558
1559 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL),
1560 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1561 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1562
1563
1564 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1565 UVD_VCPU_CNTL__BLK_RST_MASK,
1566 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1567
1568
1569 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1570 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
1571
1572
1573 tmp = RREG32_SOC15(VCN, i, mmUVD_SOFT_RESET);
1574 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1575 WREG32_SOC15(VCN, i, mmUVD_SOFT_RESET, tmp);
1576 tmp = RREG32_SOC15(VCN, i, mmUVD_SOFT_RESET);
1577 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1578 WREG32_SOC15(VCN, i, mmUVD_SOFT_RESET, tmp);
1579
1580
1581 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
1582
1583
1584 vcn_v3_0_enable_clock_gating(adev, i);
1585
1586
1587 vcn_v3_0_enable_static_power_gating(adev, i);
1588 }
1589
1590 if (adev->pm.dpm_enabled)
1591 amdgpu_dpm_enable_uvd(adev, false);
1592
1593 return 0;
1594 }
1595
1596 static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev,
1597 int inst_idx, struct dpg_pause_state *new_state)
1598 {
1599 volatile struct amdgpu_fw_shared *fw_shared;
1600 struct amdgpu_ring *ring;
1601 uint32_t reg_data = 0;
1602 int ret_code;
1603
1604
1605 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
1606 DRM_DEBUG("dpg pause state changed %d -> %d",
1607 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based);
1608 reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) &
1609 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1610
1611 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
1612 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1613 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1614
1615 if (!ret_code) {
1616
1617 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1618 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1619
1620
1621 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE,
1622 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
1623 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1624
1625
1626 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1627 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1628 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1629
1630 if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(3, 0, 33)) {
1631
1632 fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
1633 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
1634 ring = &adev->vcn.inst[inst_idx].ring_enc[0];
1635 ring->wptr = 0;
1636 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
1637 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1638 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
1639 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1640 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1641 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
1642
1643 fw_shared->multi_queue.encode_lowlatency_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
1644 ring = &adev->vcn.inst[inst_idx].ring_enc[1];
1645 ring->wptr = 0;
1646 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1647 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1648 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
1649 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1650 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1651 fw_shared->multi_queue.encode_lowlatency_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
1652
1653
1654 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, fw_shared->rb.rptr);
1655 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR, fw_shared->rb.wptr);
1656 }
1657
1658
1659 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1660 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1661
1662 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS,
1663 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1664 }
1665 } else {
1666
1667 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1668 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1669 }
1670 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
1671 }
1672
1673 return 0;
1674 }
1675
1676
1677
1678
1679
1680
1681
1682
1683 static uint64_t vcn_v3_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
1684 {
1685 struct amdgpu_device *adev = ring->adev;
1686
1687 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR);
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697 static uint64_t vcn_v3_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
1698 {
1699 struct amdgpu_device *adev = ring->adev;
1700
1701 if (ring->use_doorbell)
1702 return *ring->wptr_cpu_addr;
1703 else
1704 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR);
1705 }
1706
1707
1708
1709
1710
1711
1712
1713
1714 static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
1715 {
1716 struct amdgpu_device *adev = ring->adev;
1717 volatile struct amdgpu_fw_shared *fw_shared;
1718
1719 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1720
1721 fw_shared = adev->vcn.inst[ring->me].fw_shared.cpu_addr;
1722 fw_shared->rb.wptr = lower_32_bits(ring->wptr);
1723 WREG32_SOC15(VCN, ring->me, mmUVD_SCRATCH2,
1724 lower_32_bits(ring->wptr));
1725 }
1726
1727 if (ring->use_doorbell) {
1728 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1729 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1730 } else {
1731 WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
1732 }
1733 }
1734
1735 static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = {
1736 .type = AMDGPU_RING_TYPE_VCN_DEC,
1737 .align_mask = 0x3f,
1738 .nop = VCN_DEC_SW_CMD_NO_OP,
1739 .secure_submission_supported = true,
1740 .vmhub = AMDGPU_MMHUB_0,
1741 .get_rptr = vcn_v3_0_dec_ring_get_rptr,
1742 .get_wptr = vcn_v3_0_dec_ring_get_wptr,
1743 .set_wptr = vcn_v3_0_dec_ring_set_wptr,
1744 .emit_frame_size =
1745 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1746 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1747 VCN_SW_RING_EMIT_FRAME_SIZE,
1748 .emit_ib_size = 5,
1749 .emit_ib = vcn_dec_sw_ring_emit_ib,
1750 .emit_fence = vcn_dec_sw_ring_emit_fence,
1751 .emit_vm_flush = vcn_dec_sw_ring_emit_vm_flush,
1752 .test_ring = amdgpu_vcn_dec_sw_ring_test_ring,
1753 .test_ib = NULL,
1754 .insert_nop = amdgpu_ring_insert_nop,
1755 .insert_end = vcn_dec_sw_ring_insert_end,
1756 .pad_ib = amdgpu_ring_generic_pad_ib,
1757 .begin_use = amdgpu_vcn_ring_begin_use,
1758 .end_use = amdgpu_vcn_ring_end_use,
1759 .emit_wreg = vcn_dec_sw_ring_emit_wreg,
1760 .emit_reg_wait = vcn_dec_sw_ring_emit_reg_wait,
1761 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1762 };
1763
1764 static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p)
1765 {
1766 struct drm_gpu_scheduler **scheds;
1767
1768
1769 if (atomic_read(&p->entity->fence_seq))
1770 return -EINVAL;
1771
1772 scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC]
1773 [AMDGPU_RING_PRIO_DEFAULT].sched;
1774 drm_sched_entity_modify_sched(p->entity, scheds, 1);
1775 return 0;
1776 }
1777
1778 static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
1779 {
1780 struct ttm_operation_ctx ctx = { false, false };
1781 struct amdgpu_bo_va_mapping *map;
1782 uint32_t *msg, num_buffers;
1783 struct amdgpu_bo *bo;
1784 uint64_t start, end;
1785 unsigned int i;
1786 void * ptr;
1787 int r;
1788
1789 addr &= AMDGPU_GMC_HOLE_MASK;
1790 r = amdgpu_cs_find_mapping(p, addr, &bo, &map);
1791 if (r) {
1792 DRM_ERROR("Can't find BO for addr 0x%08Lx\n", addr);
1793 return r;
1794 }
1795
1796 start = map->start * AMDGPU_GPU_PAGE_SIZE;
1797 end = (map->last + 1) * AMDGPU_GPU_PAGE_SIZE;
1798 if (addr & 0x7) {
1799 DRM_ERROR("VCN messages must be 8 byte aligned!\n");
1800 return -EINVAL;
1801 }
1802
1803 bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
1804 amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
1805 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
1806 if (r) {
1807 DRM_ERROR("Failed validating the VCN message BO (%d)!\n", r);
1808 return r;
1809 }
1810
1811 r = amdgpu_bo_kmap(bo, &ptr);
1812 if (r) {
1813 DRM_ERROR("Failed mapping the VCN message (%d)!\n", r);
1814 return r;
1815 }
1816
1817 msg = ptr + addr - start;
1818
1819
1820 if (msg[1] > end - addr) {
1821 r = -EINVAL;
1822 goto out;
1823 }
1824
1825 if (msg[3] != RDECODE_MSG_CREATE)
1826 goto out;
1827
1828 num_buffers = msg[2];
1829 for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
1830 uint32_t offset, size, *create;
1831
1832 if (msg[0] != RDECODE_MESSAGE_CREATE)
1833 continue;
1834
1835 offset = msg[1];
1836 size = msg[2];
1837
1838 if (offset + size > end) {
1839 r = -EINVAL;
1840 goto out;
1841 }
1842
1843 create = ptr + addr + offset - start;
1844
1845
1846 if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
1847 continue;
1848
1849 r = vcn_v3_0_limit_sched(p);
1850 if (r)
1851 goto out;
1852 }
1853
1854 out:
1855 amdgpu_bo_kunmap(bo);
1856 return r;
1857 }
1858
1859 static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
1860 struct amdgpu_job *job,
1861 struct amdgpu_ib *ib)
1862 {
1863 struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
1864 uint32_t msg_lo = 0, msg_hi = 0;
1865 unsigned i;
1866 int r;
1867
1868
1869 if (!ring->me)
1870 return 0;
1871
1872 for (i = 0; i < ib->length_dw; i += 2) {
1873 uint32_t reg = amdgpu_ib_get_value(ib, i);
1874 uint32_t val = amdgpu_ib_get_value(ib, i + 1);
1875
1876 if (reg == PACKET0(p->adev->vcn.internal.data0, 0)) {
1877 msg_lo = val;
1878 } else if (reg == PACKET0(p->adev->vcn.internal.data1, 0)) {
1879 msg_hi = val;
1880 } else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0) &&
1881 val == 0) {
1882 r = vcn_v3_0_dec_msg(p, ((u64)msg_hi) << 32 | msg_lo);
1883 if (r)
1884 return r;
1885 }
1886 }
1887 return 0;
1888 }
1889
1890 static const struct amdgpu_ring_funcs vcn_v3_0_dec_ring_vm_funcs = {
1891 .type = AMDGPU_RING_TYPE_VCN_DEC,
1892 .align_mask = 0xf,
1893 .secure_submission_supported = true,
1894 .vmhub = AMDGPU_MMHUB_0,
1895 .get_rptr = vcn_v3_0_dec_ring_get_rptr,
1896 .get_wptr = vcn_v3_0_dec_ring_get_wptr,
1897 .set_wptr = vcn_v3_0_dec_ring_set_wptr,
1898 .patch_cs_in_place = vcn_v3_0_ring_patch_cs_in_place,
1899 .emit_frame_size =
1900 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1901 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1902 8 +
1903 14 + 14 +
1904 6,
1905 .emit_ib_size = 8,
1906 .emit_ib = vcn_v2_0_dec_ring_emit_ib,
1907 .emit_fence = vcn_v2_0_dec_ring_emit_fence,
1908 .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1909 .test_ring = vcn_v2_0_dec_ring_test_ring,
1910 .test_ib = amdgpu_vcn_dec_ring_test_ib,
1911 .insert_nop = vcn_v2_0_dec_ring_insert_nop,
1912 .insert_start = vcn_v2_0_dec_ring_insert_start,
1913 .insert_end = vcn_v2_0_dec_ring_insert_end,
1914 .pad_ib = amdgpu_ring_generic_pad_ib,
1915 .begin_use = amdgpu_vcn_ring_begin_use,
1916 .end_use = amdgpu_vcn_ring_end_use,
1917 .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1918 .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1919 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1920 };
1921
1922
1923
1924
1925
1926
1927
1928
1929 static uint64_t vcn_v3_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
1930 {
1931 struct amdgpu_device *adev = ring->adev;
1932
1933 if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1934 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR);
1935 else
1936 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2);
1937 }
1938
1939
1940
1941
1942
1943
1944
1945
1946 static uint64_t vcn_v3_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
1947 {
1948 struct amdgpu_device *adev = ring->adev;
1949
1950 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1951 if (ring->use_doorbell)
1952 return *ring->wptr_cpu_addr;
1953 else
1954 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR);
1955 } else {
1956 if (ring->use_doorbell)
1957 return *ring->wptr_cpu_addr;
1958 else
1959 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2);
1960 }
1961 }
1962
1963
1964
1965
1966
1967
1968
1969
1970 static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
1971 {
1972 struct amdgpu_device *adev = ring->adev;
1973
1974 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1975 if (ring->use_doorbell) {
1976 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1977 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1978 } else {
1979 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1980 }
1981 } else {
1982 if (ring->use_doorbell) {
1983 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1984 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1985 } else {
1986 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1987 }
1988 }
1989 }
1990
1991 static const struct amdgpu_ring_funcs vcn_v3_0_enc_ring_vm_funcs = {
1992 .type = AMDGPU_RING_TYPE_VCN_ENC,
1993 .align_mask = 0x3f,
1994 .nop = VCN_ENC_CMD_NO_OP,
1995 .vmhub = AMDGPU_MMHUB_0,
1996 .get_rptr = vcn_v3_0_enc_ring_get_rptr,
1997 .get_wptr = vcn_v3_0_enc_ring_get_wptr,
1998 .set_wptr = vcn_v3_0_enc_ring_set_wptr,
1999 .emit_frame_size =
2000 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
2001 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
2002 4 +
2003 5 + 5 +
2004 1,
2005 .emit_ib_size = 5,
2006 .emit_ib = vcn_v2_0_enc_ring_emit_ib,
2007 .emit_fence = vcn_v2_0_enc_ring_emit_fence,
2008 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
2009 .test_ring = amdgpu_vcn_enc_ring_test_ring,
2010 .test_ib = amdgpu_vcn_enc_ring_test_ib,
2011 .insert_nop = amdgpu_ring_insert_nop,
2012 .insert_end = vcn_v2_0_enc_ring_insert_end,
2013 .pad_ib = amdgpu_ring_generic_pad_ib,
2014 .begin_use = amdgpu_vcn_ring_begin_use,
2015 .end_use = amdgpu_vcn_ring_end_use,
2016 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
2017 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
2018 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
2019 };
2020
2021 static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev)
2022 {
2023 int i;
2024
2025 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2026 if (adev->vcn.harvest_config & (1 << i))
2027 continue;
2028
2029 if (!DEC_SW_RING_ENABLED)
2030 adev->vcn.inst[i].ring_dec.funcs = &vcn_v3_0_dec_ring_vm_funcs;
2031 else
2032 adev->vcn.inst[i].ring_dec.funcs = &vcn_v3_0_dec_sw_ring_vm_funcs;
2033 adev->vcn.inst[i].ring_dec.me = i;
2034 DRM_INFO("VCN(%d) decode%s is enabled in VM mode\n", i,
2035 DEC_SW_RING_ENABLED?"(Software Ring)":"");
2036 }
2037 }
2038
2039 static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev)
2040 {
2041 int i, j;
2042
2043 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2044 if (adev->vcn.harvest_config & (1 << i))
2045 continue;
2046
2047 for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
2048 adev->vcn.inst[i].ring_enc[j].funcs = &vcn_v3_0_enc_ring_vm_funcs;
2049 adev->vcn.inst[i].ring_enc[j].me = i;
2050 }
2051 if (adev->vcn.num_enc_rings > 0)
2052 DRM_INFO("VCN(%d) encode is enabled in VM mode\n", i);
2053 }
2054 }
2055
2056 static bool vcn_v3_0_is_idle(void *handle)
2057 {
2058 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
2059 int i, ret = 1;
2060
2061 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2062 if (adev->vcn.harvest_config & (1 << i))
2063 continue;
2064
2065 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
2066 }
2067
2068 return ret;
2069 }
2070
2071 static int vcn_v3_0_wait_for_idle(void *handle)
2072 {
2073 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
2074 int i, ret = 0;
2075
2076 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2077 if (adev->vcn.harvest_config & (1 << i))
2078 continue;
2079
2080 ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
2081 UVD_STATUS__IDLE);
2082 if (ret)
2083 return ret;
2084 }
2085
2086 return ret;
2087 }
2088
2089 static int vcn_v3_0_set_clockgating_state(void *handle,
2090 enum amd_clockgating_state state)
2091 {
2092 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
2093 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
2094 int i;
2095
2096 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2097 if (adev->vcn.harvest_config & (1 << i))
2098 continue;
2099
2100 if (enable) {
2101 if (RREG32_SOC15(VCN, i, mmUVD_STATUS) != UVD_STATUS__IDLE)
2102 return -EBUSY;
2103 vcn_v3_0_enable_clock_gating(adev, i);
2104 } else {
2105 vcn_v3_0_disable_clock_gating(adev, i);
2106 }
2107 }
2108
2109 return 0;
2110 }
2111
2112 static int vcn_v3_0_set_powergating_state(void *handle,
2113 enum amd_powergating_state state)
2114 {
2115 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
2116 int ret;
2117
2118
2119
2120
2121
2122 if (amdgpu_sriov_vf(adev)) {
2123 adev->vcn.cur_state = AMD_PG_STATE_UNGATE;
2124 return 0;
2125 }
2126
2127 if(state == adev->vcn.cur_state)
2128 return 0;
2129
2130 if (state == AMD_PG_STATE_GATE)
2131 ret = vcn_v3_0_stop(adev);
2132 else
2133 ret = vcn_v3_0_start(adev);
2134
2135 if(!ret)
2136 adev->vcn.cur_state = state;
2137
2138 return ret;
2139 }
2140
2141 static int vcn_v3_0_set_interrupt_state(struct amdgpu_device *adev,
2142 struct amdgpu_irq_src *source,
2143 unsigned type,
2144 enum amdgpu_interrupt_state state)
2145 {
2146 return 0;
2147 }
2148
2149 static int vcn_v3_0_process_interrupt(struct amdgpu_device *adev,
2150 struct amdgpu_irq_src *source,
2151 struct amdgpu_iv_entry *entry)
2152 {
2153 uint32_t ip_instance;
2154
2155 switch (entry->client_id) {
2156 case SOC15_IH_CLIENTID_VCN:
2157 ip_instance = 0;
2158 break;
2159 case SOC15_IH_CLIENTID_VCN1:
2160 ip_instance = 1;
2161 break;
2162 default:
2163 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
2164 return 0;
2165 }
2166
2167 DRM_DEBUG("IH: VCN TRAP\n");
2168
2169 switch (entry->src_id) {
2170 case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
2171 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
2172 break;
2173 case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
2174 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
2175 break;
2176 case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
2177 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
2178 break;
2179 default:
2180 DRM_ERROR("Unhandled interrupt: %d %d\n",
2181 entry->src_id, entry->src_data[0]);
2182 break;
2183 }
2184
2185 return 0;
2186 }
2187
2188 static const struct amdgpu_irq_src_funcs vcn_v3_0_irq_funcs = {
2189 .set = vcn_v3_0_set_interrupt_state,
2190 .process = vcn_v3_0_process_interrupt,
2191 };
2192
2193 static void vcn_v3_0_set_irq_funcs(struct amdgpu_device *adev)
2194 {
2195 int i;
2196
2197 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2198 if (adev->vcn.harvest_config & (1 << i))
2199 continue;
2200
2201 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1;
2202 adev->vcn.inst[i].irq.funcs = &vcn_v3_0_irq_funcs;
2203 }
2204 }
2205
2206 static const struct amd_ip_funcs vcn_v3_0_ip_funcs = {
2207 .name = "vcn_v3_0",
2208 .early_init = vcn_v3_0_early_init,
2209 .late_init = NULL,
2210 .sw_init = vcn_v3_0_sw_init,
2211 .sw_fini = vcn_v3_0_sw_fini,
2212 .hw_init = vcn_v3_0_hw_init,
2213 .hw_fini = vcn_v3_0_hw_fini,
2214 .suspend = vcn_v3_0_suspend,
2215 .resume = vcn_v3_0_resume,
2216 .is_idle = vcn_v3_0_is_idle,
2217 .wait_for_idle = vcn_v3_0_wait_for_idle,
2218 .check_soft_reset = NULL,
2219 .pre_soft_reset = NULL,
2220 .soft_reset = NULL,
2221 .post_soft_reset = NULL,
2222 .set_clockgating_state = vcn_v3_0_set_clockgating_state,
2223 .set_powergating_state = vcn_v3_0_set_powergating_state,
2224 };
2225
2226 const struct amdgpu_ip_block_version vcn_v3_0_ip_block =
2227 {
2228 .type = AMD_IP_BLOCK_TYPE_VCN,
2229 .major = 3,
2230 .minor = 0,
2231 .rev = 0,
2232 .funcs = &vcn_v3_0_ip_funcs,
2233 };