1 /* 2 * Copyright 2021 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include <linux/firmware.h> 25 #include "amdgpu.h" 26 #include "amdgpu_vcn.h" 27 #include "amdgpu_pm.h" 28 #include "amdgpu_cs.h" 29 #include "soc15.h" 30 #include "soc15d.h" 31 #include "soc15_hw_ip.h" 32 #include "vcn_v2_0.h" 33 #include "mmsch_v4_0.h" 34 #include "vcn_v4_0.h" 35 36 #include "vcn/vcn_4_0_0_offset.h" 37 #include "vcn/vcn_4_0_0_sh_mask.h" 38 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h" 39 40 #include <drm/drm_drv.h> 41 42 #define mmUVD_DPG_LMA_CTL regUVD_DPG_LMA_CTL 43 #define mmUVD_DPG_LMA_CTL_BASE_IDX regUVD_DPG_LMA_CTL_BASE_IDX 44 #define mmUVD_DPG_LMA_DATA regUVD_DPG_LMA_DATA 45 #define mmUVD_DPG_LMA_DATA_BASE_IDX regUVD_DPG_LMA_DATA_BASE_IDX 46 47 #define VCN_VID_SOC_ADDRESS_2_0 0x1fb00 48 #define VCN1_VID_SOC_ADDRESS_3_0 0x48300 49 #define VCN1_AON_SOC_ADDRESS_3_0 0x48000 50 51 #define VCN_HARVEST_MMSCH 0 52 53 #define RDECODE_MSG_CREATE 0x00000000 54 #define RDECODE_MESSAGE_CREATE 0x00000001 55 56 static const struct amdgpu_hwip_reg_entry vcn_reg_list_4_0[] = { 57 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS), 58 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS), 59 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID), 60 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2), 61 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0), 62 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1), 63 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD), 64 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI), 65 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO), 66 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2), 67 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2), 68 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3), 69 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3), 70 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4), 71 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4), 72 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR), 73 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR), 74 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2), 75 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2), 76 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3), 77 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3), 78 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4), 79 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4), 80 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE), 81 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2), 82 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3), 83 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4), 84 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_CONFIG), 85 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_STATUS), 86 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL), 87 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA), 88 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK), 89 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE) 90 }; 91 92 static int amdgpu_ih_clientid_vcns[] = { 93 SOC15_IH_CLIENTID_VCN, 94 SOC15_IH_CLIENTID_VCN1 95 }; 96 97 static int vcn_v4_0_start_sriov(struct amdgpu_device *adev); 98 static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev); 99 static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev); 100 static int vcn_v4_0_set_pg_state(struct amdgpu_vcn_inst *vinst, 101 enum amd_powergating_state state); 102 static int vcn_v4_0_pause_dpg_mode(struct amdgpu_vcn_inst *vinst, 103 struct dpg_pause_state *new_state); 104 static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring); 105 static void vcn_v4_0_set_ras_funcs(struct amdgpu_device *adev); 106 107 /** 108 * vcn_v4_0_early_init - set function pointers and load microcode 109 * 110 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 111 * 112 * Set ring and irq function pointers 113 * Load microcode from filesystem 114 */ 115 static int vcn_v4_0_early_init(struct amdgpu_ip_block *ip_block) 116 { 117 struct amdgpu_device *adev = ip_block->adev; 118 int i, r; 119 120 if (amdgpu_sriov_vf(adev)) { 121 adev->vcn.harvest_config = VCN_HARVEST_MMSCH; 122 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 123 if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) { 124 adev->vcn.harvest_config |= 1 << i; 125 dev_info(adev->dev, "VCN%d is disabled by hypervisor\n", i); 126 } 127 } 128 } 129 130 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) 131 /* re-use enc ring as unified ring */ 132 adev->vcn.inst[i].num_enc_rings = 1; 133 134 vcn_v4_0_set_unified_ring_funcs(adev); 135 vcn_v4_0_set_irq_funcs(adev); 136 vcn_v4_0_set_ras_funcs(adev); 137 138 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 139 adev->vcn.inst[i].set_pg_state = vcn_v4_0_set_pg_state; 140 141 r = amdgpu_vcn_early_init(adev, i); 142 if (r) 143 return r; 144 } 145 146 return 0; 147 } 148 149 static int vcn_v4_0_fw_shared_init(struct amdgpu_device *adev, int inst_idx) 150 { 151 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 152 153 fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 154 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); 155 fw_shared->sq.is_enabled = 1; 156 157 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG); 158 fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ? 159 AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU; 160 161 if (amdgpu_ip_version(adev, VCN_HWIP, 0) == 162 IP_VERSION(4, 0, 2)) { 163 fw_shared->present_flag_0 |= AMDGPU_FW_SHARED_FLAG_0_DRM_KEY_INJECT; 164 fw_shared->drm_key_wa.method = 165 AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING; 166 } 167 168 if (amdgpu_vcnfw_log) 169 amdgpu_vcn_fwlog_init(&adev->vcn.inst[inst_idx]); 170 171 return 0; 172 } 173 174 /** 175 * vcn_v4_0_sw_init - sw init for VCN block 176 * 177 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 178 * 179 * Load firmware and sw initialization 180 */ 181 static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block) 182 { 183 struct amdgpu_ring *ring; 184 struct amdgpu_device *adev = ip_block->adev; 185 int i, r; 186 187 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 188 if (adev->vcn.harvest_config & (1 << i)) 189 continue; 190 191 r = amdgpu_vcn_sw_init(adev, i); 192 if (r) 193 return r; 194 195 amdgpu_vcn_setup_ucode(adev, i); 196 197 r = amdgpu_vcn_resume(adev, i); 198 if (r) 199 return r; 200 201 /* Init instance 0 sched_score to 1, so it's scheduled after other instances */ 202 if (i == 0) 203 atomic_set(&adev->vcn.inst[i].sched_score, 1); 204 else 205 atomic_set(&adev->vcn.inst[i].sched_score, 0); 206 207 /* VCN UNIFIED TRAP */ 208 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i], 209 VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq); 210 if (r) 211 return r; 212 213 /* VCN POISON TRAP */ 214 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i], 215 VCN_4_0__SRCID_UVD_POISON, &adev->vcn.inst[i].ras_poison_irq); 216 if (r) 217 return r; 218 219 ring = &adev->vcn.inst[i].ring_enc[0]; 220 ring->use_doorbell = true; 221 if (amdgpu_sriov_vf(adev)) 222 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + i * 223 (adev->vcn.inst[i].num_enc_rings + 1) + 1; 224 else 225 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i; 226 ring->vm_hub = AMDGPU_MMHUB0(0); 227 sprintf(ring->name, "vcn_unified_%d", i); 228 229 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0, 230 AMDGPU_RING_PRIO_0, &adev->vcn.inst[i].sched_score); 231 if (r) 232 return r; 233 234 vcn_v4_0_fw_shared_init(adev, i); 235 236 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 237 adev->vcn.inst[i].pause_dpg_mode = vcn_v4_0_pause_dpg_mode; 238 } 239 240 adev->vcn.supported_reset = 241 amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); 242 if (!amdgpu_sriov_vf(adev)) 243 adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 244 245 if (amdgpu_sriov_vf(adev)) { 246 r = amdgpu_virt_alloc_mm_table(adev); 247 if (r) 248 return r; 249 } 250 251 252 r = amdgpu_vcn_ras_sw_init(adev); 253 if (r) 254 return r; 255 256 r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0, ARRAY_SIZE(vcn_reg_list_4_0)); 257 if (r) 258 return r; 259 260 r = amdgpu_vcn_sysfs_reset_mask_init(adev); 261 if (r) 262 return r; 263 264 return 0; 265 } 266 267 /** 268 * vcn_v4_0_sw_fini - sw fini for VCN block 269 * 270 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 271 * 272 * VCN suspend and free up sw allocation 273 */ 274 static int vcn_v4_0_sw_fini(struct amdgpu_ip_block *ip_block) 275 { 276 struct amdgpu_device *adev = ip_block->adev; 277 int i, r, idx; 278 279 if (drm_dev_enter(adev_to_drm(adev), &idx)) { 280 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 281 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 282 283 if (adev->vcn.harvest_config & (1 << i)) 284 continue; 285 286 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 287 fw_shared->present_flag_0 = 0; 288 fw_shared->sq.is_enabled = 0; 289 } 290 291 drm_dev_exit(idx); 292 } 293 294 if (amdgpu_sriov_vf(adev)) 295 amdgpu_virt_free_mm_table(adev); 296 297 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 298 r = amdgpu_vcn_suspend(adev, i); 299 if (r) 300 return r; 301 } 302 303 amdgpu_vcn_sysfs_reset_mask_fini(adev); 304 305 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 306 r = amdgpu_vcn_sw_fini(adev, i); 307 if (r) 308 return r; 309 } 310 311 return 0; 312 } 313 314 /** 315 * vcn_v4_0_hw_init - start and test VCN block 316 * 317 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 318 * 319 * Initialize the hardware, boot up the VCPU and do some testing 320 */ 321 static int vcn_v4_0_hw_init(struct amdgpu_ip_block *ip_block) 322 { 323 struct amdgpu_device *adev = ip_block->adev; 324 struct amdgpu_ring *ring; 325 int i, r; 326 327 if (amdgpu_sriov_vf(adev)) { 328 r = vcn_v4_0_start_sriov(adev); 329 if (r) 330 return r; 331 332 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 333 if (adev->vcn.harvest_config & (1 << i)) 334 continue; 335 336 ring = &adev->vcn.inst[i].ring_enc[0]; 337 ring->wptr = 0; 338 ring->wptr_old = 0; 339 vcn_v4_0_unified_ring_set_wptr(ring); 340 ring->sched.ready = true; 341 } 342 } else { 343 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 344 if (adev->vcn.harvest_config & (1 << i)) 345 continue; 346 347 ring = &adev->vcn.inst[i].ring_enc[0]; 348 349 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 350 ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i); 351 352 r = amdgpu_ring_test_helper(ring); 353 if (r) 354 return r; 355 } 356 } 357 358 return 0; 359 } 360 361 /** 362 * vcn_v4_0_hw_fini - stop the hardware block 363 * 364 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 365 * 366 * Stop the VCN block, mark ring as not ready any more 367 */ 368 static int vcn_v4_0_hw_fini(struct amdgpu_ip_block *ip_block) 369 { 370 struct amdgpu_device *adev = ip_block->adev; 371 int i; 372 373 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 374 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 375 376 if (adev->vcn.harvest_config & (1 << i)) 377 continue; 378 379 cancel_delayed_work_sync(&vinst->idle_work); 380 381 if (!amdgpu_sriov_vf(adev)) { 382 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || 383 (vinst->cur_state != AMD_PG_STATE_GATE && 384 RREG32_SOC15(VCN, i, regUVD_STATUS))) { 385 vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); 386 } 387 } 388 if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) 389 amdgpu_irq_put(adev, &vinst->ras_poison_irq, 0); 390 } 391 392 return 0; 393 } 394 395 /** 396 * vcn_v4_0_suspend - suspend VCN block 397 * 398 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 399 * 400 * HW fini and suspend VCN block 401 */ 402 static int vcn_v4_0_suspend(struct amdgpu_ip_block *ip_block) 403 { 404 struct amdgpu_device *adev = ip_block->adev; 405 int r, i; 406 407 r = vcn_v4_0_hw_fini(ip_block); 408 if (r) 409 return r; 410 411 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 412 r = amdgpu_vcn_suspend(ip_block->adev, i); 413 if (r) 414 return r; 415 } 416 417 return 0; 418 } 419 420 /** 421 * vcn_v4_0_resume - resume VCN block 422 * 423 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 424 * 425 * Resume firmware and hw init VCN block 426 */ 427 static int vcn_v4_0_resume(struct amdgpu_ip_block *ip_block) 428 { 429 struct amdgpu_device *adev = ip_block->adev; 430 int r, i; 431 432 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 433 r = amdgpu_vcn_resume(ip_block->adev, i); 434 if (r) 435 return r; 436 } 437 438 r = vcn_v4_0_hw_init(ip_block); 439 440 return r; 441 } 442 443 /** 444 * vcn_v4_0_mc_resume - memory controller programming 445 * 446 * @vinst: VCN instance 447 * 448 * Let the VCN memory controller know it's offsets 449 */ 450 static void vcn_v4_0_mc_resume(struct amdgpu_vcn_inst *vinst) 451 { 452 struct amdgpu_device *adev = vinst->adev; 453 int inst = vinst->inst; 454 uint32_t offset, size; 455 const struct common_firmware_header *hdr; 456 457 hdr = (const struct common_firmware_header *)adev->vcn.inst[inst].fw->data; 458 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 459 460 /* cache window 0: fw */ 461 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 462 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 463 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo)); 464 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 465 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi)); 466 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, 0); 467 offset = 0; 468 } else { 469 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 470 lower_32_bits(adev->vcn.inst[inst].gpu_addr)); 471 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 472 upper_32_bits(adev->vcn.inst[inst].gpu_addr)); 473 offset = size; 474 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 475 } 476 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE0, size); 477 478 /* cache window 1: stack */ 479 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 480 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset)); 481 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 482 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset)); 483 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET1, 0); 484 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE); 485 486 /* cache window 2: context */ 487 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 488 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 489 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 490 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 491 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET2, 0); 492 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE); 493 494 /* non-cache window */ 495 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW, 496 lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr)); 497 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH, 498 upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr)); 499 WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_OFFSET0, 0); 500 WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_SIZE0, 501 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); 502 } 503 504 /** 505 * vcn_v4_0_mc_resume_dpg_mode - memory controller programming for dpg mode 506 * 507 * @vinst: VCN instance 508 * @indirect: indirectly write sram 509 * 510 * Let the VCN memory controller know it's offsets with dpg mode 511 */ 512 static void vcn_v4_0_mc_resume_dpg_mode(struct amdgpu_vcn_inst *vinst, 513 bool indirect) 514 { 515 struct amdgpu_device *adev = vinst->adev; 516 int inst_idx = vinst->inst; 517 uint32_t offset, size; 518 const struct common_firmware_header *hdr; 519 hdr = (const struct common_firmware_header *)adev->vcn.inst[inst_idx].fw->data; 520 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 521 522 /* cache window 0: fw */ 523 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 524 if (!indirect) { 525 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 526 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 527 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect); 528 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 529 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 530 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect); 531 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 532 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 533 } else { 534 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 535 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect); 536 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 537 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect); 538 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 539 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 540 } 541 offset = 0; 542 } else { 543 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 544 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 545 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 546 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 547 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 548 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 549 offset = size; 550 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 551 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 552 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect); 553 } 554 555 if (!indirect) 556 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 557 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect); 558 else 559 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 560 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect); 561 562 /* cache window 1: stack */ 563 if (!indirect) { 564 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 565 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 566 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 567 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 568 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 569 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 570 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 571 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 572 } else { 573 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 574 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect); 575 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 576 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect); 577 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 578 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 579 } 580 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 581 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect); 582 583 /* cache window 2: context */ 584 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 585 VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 586 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect); 587 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 588 VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 589 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect); 590 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 591 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect); 592 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 593 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect); 594 595 /* non-cache window */ 596 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 597 VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 598 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 599 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 600 VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 601 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 602 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 603 VCN, inst_idx, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect); 604 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 605 VCN, inst_idx, regUVD_VCPU_NONCACHE_SIZE0), 606 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect); 607 608 /* VCN global tiling registers */ 609 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 610 VCN, inst_idx, regUVD_GFX10_ADDR_CONFIG), 611 adev->gfx.config.gb_addr_config, 0, indirect); 612 } 613 614 /** 615 * vcn_v4_0_disable_static_power_gating - disable VCN static power gating 616 * 617 * @vinst: VCN instance 618 * 619 * Disable static power gating for VCN block 620 */ 621 static void vcn_v4_0_disable_static_power_gating(struct amdgpu_vcn_inst *vinst) 622 { 623 struct amdgpu_device *adev = vinst->adev; 624 int inst = vinst->inst; 625 uint32_t data = 0; 626 627 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { 628 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT 629 | 1 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT 630 | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT 631 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT 632 | 2 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT 633 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT 634 | 2 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT 635 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT 636 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT 637 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT 638 | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT 639 | 2 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT 640 | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT 641 | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT); 642 643 WREG32_SOC15(VCN, inst, regUVD_PGFSM_CONFIG, data); 644 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_PGFSM_STATUS, 645 UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0, 0x3F3FFFFF); 646 } else { 647 uint32_t value; 648 649 value = (inst) ? 0x2200800 : 0; 650 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT 651 | 1 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT 652 | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT 653 | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT 654 | 1 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT 655 | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT 656 | 1 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT 657 | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT 658 | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT 659 | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT 660 | 1 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT 661 | 1 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT 662 | 1 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT 663 | 1 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT); 664 665 WREG32_SOC15(VCN, inst, regUVD_PGFSM_CONFIG, data); 666 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_PGFSM_STATUS, value, 0x3F3FFFFF); 667 } 668 669 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS); 670 data &= ~0x103; 671 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) 672 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | 673 UVD_POWER_STATUS__UVD_PG_EN_MASK; 674 675 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data); 676 677 return; 678 } 679 680 /** 681 * vcn_v4_0_enable_static_power_gating - enable VCN static power gating 682 * 683 * @vinst: VCN instance 684 * 685 * Enable static power gating for VCN block 686 */ 687 static void vcn_v4_0_enable_static_power_gating(struct amdgpu_vcn_inst *vinst) 688 { 689 struct amdgpu_device *adev = vinst->adev; 690 int inst = vinst->inst; 691 uint32_t data; 692 693 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { 694 /* Before power off, this indicator has to be turned on */ 695 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS); 696 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK; 697 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; 698 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data); 699 700 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT 701 | 2 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT 702 | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT 703 | 2 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT 704 | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT 705 | 2 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT 706 | 2 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT 707 | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT 708 | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT 709 | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT 710 | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT 711 | 2 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT 712 | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT 713 | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT); 714 WREG32_SOC15(VCN, inst, regUVD_PGFSM_CONFIG, data); 715 716 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT 717 | 2 << UVD_PGFSM_STATUS__UVDS_PWR_STATUS__SHIFT 718 | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT 719 | 2 << UVD_PGFSM_STATUS__UVDTC_PWR_STATUS__SHIFT 720 | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT 721 | 2 << UVD_PGFSM_STATUS__UVDTA_PWR_STATUS__SHIFT 722 | 2 << UVD_PGFSM_STATUS__UVDLM_PWR_STATUS__SHIFT 723 | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT 724 | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT 725 | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT 726 | 2 << UVD_PGFSM_STATUS__UVDAB_PWR_STATUS__SHIFT 727 | 2 << UVD_PGFSM_STATUS__UVDTB_PWR_STATUS__SHIFT 728 | 2 << UVD_PGFSM_STATUS__UVDNA_PWR_STATUS__SHIFT 729 | 2 << UVD_PGFSM_STATUS__UVDNB_PWR_STATUS__SHIFT); 730 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_PGFSM_STATUS, data, 0x3F3FFFFF); 731 } 732 733 return; 734 } 735 736 /** 737 * vcn_v4_0_disable_clock_gating - disable VCN clock gating 738 * 739 * @vinst: VCN instance 740 * 741 * Disable clock gating for VCN block 742 */ 743 static void vcn_v4_0_disable_clock_gating(struct amdgpu_vcn_inst *vinst) 744 { 745 struct amdgpu_device *adev = vinst->adev; 746 int inst = vinst->inst; 747 uint32_t data; 748 749 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 750 return; 751 752 /* VCN disable CGC */ 753 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 754 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; 755 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 756 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 757 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 758 759 data = RREG32_SOC15(VCN, inst, regUVD_CGC_GATE); 760 data &= ~(UVD_CGC_GATE__SYS_MASK 761 | UVD_CGC_GATE__UDEC_MASK 762 | UVD_CGC_GATE__MPEG2_MASK 763 | UVD_CGC_GATE__REGS_MASK 764 | UVD_CGC_GATE__RBC_MASK 765 | UVD_CGC_GATE__LMI_MC_MASK 766 | UVD_CGC_GATE__LMI_UMC_MASK 767 | UVD_CGC_GATE__IDCT_MASK 768 | UVD_CGC_GATE__MPRD_MASK 769 | UVD_CGC_GATE__MPC_MASK 770 | UVD_CGC_GATE__LBSI_MASK 771 | UVD_CGC_GATE__LRBBM_MASK 772 | UVD_CGC_GATE__UDEC_RE_MASK 773 | UVD_CGC_GATE__UDEC_CM_MASK 774 | UVD_CGC_GATE__UDEC_IT_MASK 775 | UVD_CGC_GATE__UDEC_DB_MASK 776 | UVD_CGC_GATE__UDEC_MP_MASK 777 | UVD_CGC_GATE__WCB_MASK 778 | UVD_CGC_GATE__VCPU_MASK 779 | UVD_CGC_GATE__MMSCH_MASK); 780 781 WREG32_SOC15(VCN, inst, regUVD_CGC_GATE, data); 782 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_CGC_GATE, 0, 0xFFFFFFFF); 783 784 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 785 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK 786 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK 787 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK 788 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK 789 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK 790 | UVD_CGC_CTRL__SYS_MODE_MASK 791 | UVD_CGC_CTRL__UDEC_MODE_MASK 792 | UVD_CGC_CTRL__MPEG2_MODE_MASK 793 | UVD_CGC_CTRL__REGS_MODE_MASK 794 | UVD_CGC_CTRL__RBC_MODE_MASK 795 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 796 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 797 | UVD_CGC_CTRL__IDCT_MODE_MASK 798 | UVD_CGC_CTRL__MPRD_MODE_MASK 799 | UVD_CGC_CTRL__MPC_MODE_MASK 800 | UVD_CGC_CTRL__LBSI_MODE_MASK 801 | UVD_CGC_CTRL__LRBBM_MODE_MASK 802 | UVD_CGC_CTRL__WCB_MODE_MASK 803 | UVD_CGC_CTRL__VCPU_MODE_MASK 804 | UVD_CGC_CTRL__MMSCH_MODE_MASK); 805 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 806 807 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE); 808 data |= (UVD_SUVD_CGC_GATE__SRE_MASK 809 | UVD_SUVD_CGC_GATE__SIT_MASK 810 | UVD_SUVD_CGC_GATE__SMP_MASK 811 | UVD_SUVD_CGC_GATE__SCM_MASK 812 | UVD_SUVD_CGC_GATE__SDB_MASK 813 | UVD_SUVD_CGC_GATE__SRE_H264_MASK 814 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK 815 | UVD_SUVD_CGC_GATE__SIT_H264_MASK 816 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK 817 | UVD_SUVD_CGC_GATE__SCM_H264_MASK 818 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK 819 | UVD_SUVD_CGC_GATE__SDB_H264_MASK 820 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK 821 | UVD_SUVD_CGC_GATE__SCLR_MASK 822 | UVD_SUVD_CGC_GATE__UVD_SC_MASK 823 | UVD_SUVD_CGC_GATE__ENT_MASK 824 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK 825 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK 826 | UVD_SUVD_CGC_GATE__SITE_MASK 827 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK 828 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK 829 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK 830 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK 831 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK); 832 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE, data); 833 834 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL); 835 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 836 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 837 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 838 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 839 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 840 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK 841 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK 842 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 843 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 844 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 845 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data); 846 } 847 848 /** 849 * vcn_v4_0_disable_clock_gating_dpg_mode - disable VCN clock gating dpg mode 850 * 851 * @vinst: VCN instance 852 * @sram_sel: sram select 853 * @indirect: indirectly write sram 854 * 855 * Disable clock gating for VCN block with dpg mode 856 */ 857 static void vcn_v4_0_disable_clock_gating_dpg_mode(struct amdgpu_vcn_inst *vinst, 858 uint8_t sram_sel, 859 uint8_t indirect) 860 { 861 struct amdgpu_device *adev = vinst->adev; 862 int inst_idx = vinst->inst; 863 uint32_t reg_data = 0; 864 865 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 866 return; 867 868 /* enable sw clock gating control */ 869 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 870 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 871 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 872 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK | 873 UVD_CGC_CTRL__UDEC_CM_MODE_MASK | 874 UVD_CGC_CTRL__UDEC_IT_MODE_MASK | 875 UVD_CGC_CTRL__UDEC_DB_MODE_MASK | 876 UVD_CGC_CTRL__UDEC_MP_MODE_MASK | 877 UVD_CGC_CTRL__SYS_MODE_MASK | 878 UVD_CGC_CTRL__UDEC_MODE_MASK | 879 UVD_CGC_CTRL__MPEG2_MODE_MASK | 880 UVD_CGC_CTRL__REGS_MODE_MASK | 881 UVD_CGC_CTRL__RBC_MODE_MASK | 882 UVD_CGC_CTRL__LMI_MC_MODE_MASK | 883 UVD_CGC_CTRL__LMI_UMC_MODE_MASK | 884 UVD_CGC_CTRL__IDCT_MODE_MASK | 885 UVD_CGC_CTRL__MPRD_MODE_MASK | 886 UVD_CGC_CTRL__MPC_MODE_MASK | 887 UVD_CGC_CTRL__LBSI_MODE_MASK | 888 UVD_CGC_CTRL__LRBBM_MODE_MASK | 889 UVD_CGC_CTRL__WCB_MODE_MASK | 890 UVD_CGC_CTRL__VCPU_MODE_MASK); 891 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 892 VCN, inst_idx, regUVD_CGC_CTRL), reg_data, sram_sel, indirect); 893 894 /* turn off clock gating */ 895 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 896 VCN, inst_idx, regUVD_CGC_GATE), 0, sram_sel, indirect); 897 898 /* turn on SUVD clock gating */ 899 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 900 VCN, inst_idx, regUVD_SUVD_CGC_GATE), 1, sram_sel, indirect); 901 902 /* turn on sw mode in UVD_SUVD_CGC_CTRL */ 903 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 904 VCN, inst_idx, regUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect); 905 } 906 907 /** 908 * vcn_v4_0_enable_clock_gating - enable VCN clock gating 909 * 910 * @vinst: VCN instance 911 * 912 * Enable clock gating for VCN block 913 */ 914 static void vcn_v4_0_enable_clock_gating(struct amdgpu_vcn_inst *vinst) 915 { 916 struct amdgpu_device *adev = vinst->adev; 917 int inst = vinst->inst; 918 uint32_t data; 919 920 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 921 return; 922 923 /* enable VCN CGC */ 924 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 925 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 926 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 927 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 928 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 929 930 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 931 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK 932 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK 933 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK 934 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK 935 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK 936 | UVD_CGC_CTRL__SYS_MODE_MASK 937 | UVD_CGC_CTRL__UDEC_MODE_MASK 938 | UVD_CGC_CTRL__MPEG2_MODE_MASK 939 | UVD_CGC_CTRL__REGS_MODE_MASK 940 | UVD_CGC_CTRL__RBC_MODE_MASK 941 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 942 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 943 | UVD_CGC_CTRL__IDCT_MODE_MASK 944 | UVD_CGC_CTRL__MPRD_MODE_MASK 945 | UVD_CGC_CTRL__MPC_MODE_MASK 946 | UVD_CGC_CTRL__LBSI_MODE_MASK 947 | UVD_CGC_CTRL__LRBBM_MODE_MASK 948 | UVD_CGC_CTRL__WCB_MODE_MASK 949 | UVD_CGC_CTRL__VCPU_MODE_MASK 950 | UVD_CGC_CTRL__MMSCH_MODE_MASK); 951 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 952 953 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL); 954 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 955 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 956 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 957 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 958 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 959 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK 960 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK 961 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 962 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 963 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 964 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data); 965 } 966 967 static void vcn_v4_0_enable_ras(struct amdgpu_vcn_inst *vinst, 968 bool indirect) 969 { 970 struct amdgpu_device *adev = vinst->adev; 971 int inst_idx = vinst->inst; 972 uint32_t tmp; 973 974 if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) 975 return; 976 977 tmp = VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK | 978 VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK | 979 VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK | 980 VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK; 981 WREG32_SOC15_DPG_MODE(inst_idx, 982 SOC15_DPG_MODE_OFFSET(VCN, 0, regVCN_RAS_CNTL), 983 tmp, 0, indirect); 984 985 tmp = UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK; 986 WREG32_SOC15_DPG_MODE(inst_idx, 987 SOC15_DPG_MODE_OFFSET(VCN, 0, regUVD_SYS_INT_EN), 988 tmp, 0, indirect); 989 } 990 991 /** 992 * vcn_v4_0_start_dpg_mode - VCN start with dpg mode 993 * 994 * @vinst: VCN instance 995 * @indirect: indirectly write sram 996 * 997 * Start VCN block with dpg mode 998 */ 999 static int vcn_v4_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst, bool indirect) 1000 { 1001 struct amdgpu_device *adev = vinst->adev; 1002 int inst_idx = vinst->inst; 1003 volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 1004 struct amdgpu_ring *ring; 1005 uint32_t tmp; 1006 int ret; 1007 1008 /* disable register anti-hang mechanism */ 1009 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1, 1010 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1011 /* enable dynamic power gating mode */ 1012 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS); 1013 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; 1014 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK; 1015 WREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS, tmp); 1016 1017 if (indirect) 1018 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; 1019 1020 /* enable clock gating */ 1021 vcn_v4_0_disable_clock_gating_dpg_mode(vinst, 0, indirect); 1022 1023 /* enable VCPU clock */ 1024 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 1025 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK; 1026 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1027 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect); 1028 1029 /* disable master interupt */ 1030 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1031 VCN, inst_idx, regUVD_MASTINT_EN), 0, 0, indirect); 1032 1033 /* setup regUVD_LMI_CTRL */ 1034 tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1035 UVD_LMI_CTRL__REQ_MODE_MASK | 1036 UVD_LMI_CTRL__CRC_RESET_MASK | 1037 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1038 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1039 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 1040 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 1041 0x00100000L); 1042 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1043 VCN, inst_idx, regUVD_LMI_CTRL), tmp, 0, indirect); 1044 1045 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1046 VCN, inst_idx, regUVD_MPC_CNTL), 1047 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect); 1048 1049 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1050 VCN, inst_idx, regUVD_MPC_SET_MUXA0), 1051 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1052 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1053 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1054 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect); 1055 1056 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1057 VCN, inst_idx, regUVD_MPC_SET_MUXB0), 1058 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1059 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1060 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1061 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect); 1062 1063 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1064 VCN, inst_idx, regUVD_MPC_SET_MUX), 1065 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1066 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1067 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect); 1068 1069 vcn_v4_0_mc_resume_dpg_mode(vinst, indirect); 1070 1071 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 1072 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 1073 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1074 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect); 1075 1076 /* enable LMI MC and UMC channels */ 1077 tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT; 1078 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1079 VCN, inst_idx, regUVD_LMI_CTRL2), tmp, 0, indirect); 1080 1081 vcn_v4_0_enable_ras(vinst, indirect); 1082 1083 /* enable master interrupt */ 1084 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1085 VCN, inst_idx, regUVD_MASTINT_EN), 1086 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 1087 1088 1089 if (indirect) { 1090 ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1091 if (ret) { 1092 dev_err(adev->dev, "vcn sram load failed %d\n", ret); 1093 return ret; 1094 } 1095 } 1096 1097 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 1098 1099 WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_LO, ring->gpu_addr); 1100 WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1101 WREG32_SOC15(VCN, inst_idx, regUVD_RB_SIZE, ring->ring_size / 4); 1102 1103 tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE); 1104 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 1105 WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp); 1106 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 1107 WREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR, 0); 1108 WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, 0); 1109 1110 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR); 1111 WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, tmp); 1112 ring->wptr = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR); 1113 1114 tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE); 1115 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 1116 WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp); 1117 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 1118 1119 WREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL, 1120 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 1121 VCN_RB1_DB_CTRL__EN_MASK); 1122 1123 /* Keeping one read-back to ensure all register writes are done, 1124 * otherwise it may introduce race conditions. 1125 */ 1126 RREG32_SOC15(VCN, inst_idx, regUVD_STATUS); 1127 1128 return 0; 1129 } 1130 1131 1132 /** 1133 * vcn_v4_0_start - VCN start 1134 * 1135 * @vinst: VCN instance 1136 * 1137 * Start VCN block 1138 */ 1139 static int vcn_v4_0_start(struct amdgpu_vcn_inst *vinst) 1140 { 1141 struct amdgpu_device *adev = vinst->adev; 1142 int i = vinst->inst; 1143 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1144 struct amdgpu_ring *ring; 1145 uint32_t tmp; 1146 int j, k, r; 1147 1148 if (adev->vcn.harvest_config & (1 << i)) 1149 return 0; 1150 1151 if (adev->pm.dpm_enabled) 1152 amdgpu_dpm_enable_vcn(adev, true, i); 1153 1154 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1155 1156 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 1157 return vcn_v4_0_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram); 1158 1159 /* disable VCN power gating */ 1160 vcn_v4_0_disable_static_power_gating(vinst); 1161 1162 /* set VCN status busy */ 1163 tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; 1164 WREG32_SOC15(VCN, i, regUVD_STATUS, tmp); 1165 1166 /*SW clock gating */ 1167 vcn_v4_0_disable_clock_gating(vinst); 1168 1169 /* enable VCPU clock */ 1170 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1171 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); 1172 1173 /* disable master interrupt */ 1174 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0, 1175 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1176 1177 /* enable LMI MC and UMC channels */ 1178 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0, 1179 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1180 1181 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1182 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1183 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1184 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1185 1186 /* setup regUVD_LMI_CTRL */ 1187 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL); 1188 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp | 1189 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1190 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1191 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1192 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 1193 1194 /* setup regUVD_MPC_CNTL */ 1195 tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL); 1196 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; 1197 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; 1198 WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp); 1199 1200 /* setup UVD_MPC_SET_MUXA0 */ 1201 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0, 1202 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1203 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1204 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1205 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); 1206 1207 /* setup UVD_MPC_SET_MUXB0 */ 1208 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0, 1209 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1210 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1211 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1212 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); 1213 1214 /* setup UVD_MPC_SET_MUX */ 1215 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX, 1216 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1217 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1218 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); 1219 1220 vcn_v4_0_mc_resume(vinst); 1221 1222 /* VCN global tiling registers */ 1223 WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG, 1224 adev->gfx.config.gb_addr_config); 1225 1226 /* unblock VCPU register access */ 1227 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0, 1228 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1229 1230 /* release VCPU reset to boot */ 1231 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1232 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1233 1234 for (j = 0; j < 10; ++j) { 1235 uint32_t status; 1236 1237 for (k = 0; k < 100; ++k) { 1238 status = RREG32_SOC15(VCN, i, regUVD_STATUS); 1239 if (status & 2) 1240 break; 1241 mdelay(10); 1242 if (amdgpu_emu_mode == 1) 1243 msleep(1); 1244 } 1245 1246 if (amdgpu_emu_mode == 1) { 1247 r = -1; 1248 if (status & 2) { 1249 r = 0; 1250 break; 1251 } 1252 } else { 1253 r = 0; 1254 if (status & 2) 1255 break; 1256 1257 dev_err(adev->dev, "VCN[%d] is not responding, trying to reset the VCPU!!!\n", i); 1258 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1259 UVD_VCPU_CNTL__BLK_RST_MASK, 1260 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1261 mdelay(10); 1262 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1263 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1264 1265 mdelay(10); 1266 r = -1; 1267 } 1268 } 1269 1270 if (r) { 1271 dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i); 1272 return r; 1273 } 1274 1275 /* enable master interrupt */ 1276 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 1277 UVD_MASTINT_EN__VCPU_EN_MASK, 1278 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1279 1280 /* clear the busy bit of VCN_STATUS */ 1281 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0, 1282 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 1283 1284 ring = &adev->vcn.inst[i].ring_enc[0]; 1285 WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL, 1286 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 1287 VCN_RB1_DB_CTRL__EN_MASK); 1288 1289 WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr); 1290 WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1291 WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4); 1292 1293 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); 1294 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 1295 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); 1296 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 1297 WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0); 1298 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0); 1299 1300 tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR); 1301 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp); 1302 ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR); 1303 1304 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); 1305 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 1306 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); 1307 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 1308 1309 /* Keeping one read-back to ensure all register writes are done, 1310 * otherwise it may introduce race conditions. 1311 */ 1312 RREG32_SOC15(VCN, i, regUVD_STATUS); 1313 1314 return 0; 1315 } 1316 1317 static int vcn_v4_0_init_ring_metadata(struct amdgpu_device *adev, uint32_t vcn_inst, struct amdgpu_ring *ring_enc) 1318 { 1319 struct amdgpu_vcn_rb_metadata *rb_metadata = NULL; 1320 uint8_t *rb_ptr = (uint8_t *)ring_enc->ring; 1321 1322 rb_ptr += ring_enc->ring_size; 1323 rb_metadata = (struct amdgpu_vcn_rb_metadata *)rb_ptr; 1324 1325 memset(rb_metadata, 0, sizeof(struct amdgpu_vcn_rb_metadata)); 1326 rb_metadata->size = sizeof(struct amdgpu_vcn_rb_metadata); 1327 rb_metadata->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); 1328 rb_metadata->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_DECOUPLE_FLAG); 1329 rb_metadata->version = 1; 1330 rb_metadata->ring_id = vcn_inst & 0xFF; 1331 1332 return 0; 1333 } 1334 1335 static int vcn_v4_0_start_sriov(struct amdgpu_device *adev) 1336 { 1337 int i; 1338 struct amdgpu_ring *ring_enc; 1339 uint64_t cache_addr; 1340 uint64_t rb_enc_addr; 1341 uint64_t ctx_addr; 1342 uint32_t param, resp, expected; 1343 uint32_t offset, cache_size; 1344 uint32_t tmp, timeout; 1345 1346 struct amdgpu_mm_table *table = &adev->virt.mm_table; 1347 uint32_t *table_loc; 1348 uint32_t table_size; 1349 uint32_t size, size_dw; 1350 uint32_t init_status; 1351 uint32_t enabled_vcn; 1352 1353 struct mmsch_v4_0_cmd_direct_write 1354 direct_wt = { {0} }; 1355 struct mmsch_v4_0_cmd_direct_read_modify_write 1356 direct_rd_mod_wt = { {0} }; 1357 struct mmsch_v4_0_cmd_end end = { {0} }; 1358 struct mmsch_v4_0_init_header header; 1359 1360 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1361 volatile struct amdgpu_fw_shared_rb_setup *rb_setup; 1362 1363 direct_wt.cmd_header.command_type = 1364 MMSCH_COMMAND__DIRECT_REG_WRITE; 1365 direct_rd_mod_wt.cmd_header.command_type = 1366 MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; 1367 end.cmd_header.command_type = 1368 MMSCH_COMMAND__END; 1369 1370 header.version = MMSCH_VERSION; 1371 header.total_size = sizeof(struct mmsch_v4_0_init_header) >> 2; 1372 for (i = 0; i < MMSCH_V4_0_VCN_INSTANCES; i++) { 1373 header.inst[i].init_status = 0; 1374 header.inst[i].table_offset = 0; 1375 header.inst[i].table_size = 0; 1376 } 1377 1378 table_loc = (uint32_t *)table->cpu_addr; 1379 table_loc += header.total_size; 1380 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1381 if (adev->vcn.harvest_config & (1 << i)) 1382 continue; 1383 1384 // Must re/init fw_shared at beginning 1385 vcn_v4_0_fw_shared_init(adev, i); 1386 1387 table_size = 0; 1388 1389 MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i, 1390 regUVD_STATUS), 1391 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY); 1392 1393 cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4); 1394 1395 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 1396 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1397 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 1398 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); 1399 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1400 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 1401 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); 1402 offset = 0; 1403 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1404 regUVD_VCPU_CACHE_OFFSET0), 1405 0); 1406 } else { 1407 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1408 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 1409 lower_32_bits(adev->vcn.inst[i].gpu_addr)); 1410 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1411 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 1412 upper_32_bits(adev->vcn.inst[i].gpu_addr)); 1413 offset = cache_size; 1414 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1415 regUVD_VCPU_CACHE_OFFSET0), 1416 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 1417 } 1418 1419 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1420 regUVD_VCPU_CACHE_SIZE0), 1421 cache_size); 1422 1423 cache_addr = adev->vcn.inst[i].gpu_addr + offset; 1424 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1425 regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 1426 lower_32_bits(cache_addr)); 1427 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1428 regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 1429 upper_32_bits(cache_addr)); 1430 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1431 regUVD_VCPU_CACHE_OFFSET1), 1432 0); 1433 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1434 regUVD_VCPU_CACHE_SIZE1), 1435 AMDGPU_VCN_STACK_SIZE); 1436 1437 cache_addr = adev->vcn.inst[i].gpu_addr + offset + 1438 AMDGPU_VCN_STACK_SIZE; 1439 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1440 regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 1441 lower_32_bits(cache_addr)); 1442 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1443 regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 1444 upper_32_bits(cache_addr)); 1445 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1446 regUVD_VCPU_CACHE_OFFSET2), 1447 0); 1448 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1449 regUVD_VCPU_CACHE_SIZE2), 1450 AMDGPU_VCN_CONTEXT_SIZE); 1451 1452 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1453 rb_setup = &fw_shared->rb_setup; 1454 1455 ring_enc = &adev->vcn.inst[i].ring_enc[0]; 1456 ring_enc->wptr = 0; 1457 rb_enc_addr = ring_enc->gpu_addr; 1458 1459 rb_setup->is_rb_enabled_flags |= RB_ENABLED; 1460 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); 1461 1462 if (amdgpu_sriov_is_vcn_rb_decouple(adev)) { 1463 vcn_v4_0_init_ring_metadata(adev, i, ring_enc); 1464 1465 memset((void *)&rb_setup->rb_info, 0, sizeof(struct amdgpu_vcn_rb_setup_info) * MAX_NUM_VCN_RB_SETUP); 1466 if (!(adev->vcn.harvest_config & (1 << 0))) { 1467 rb_setup->rb_info[0].rb_addr_lo = lower_32_bits(adev->vcn.inst[0].ring_enc[0].gpu_addr); 1468 rb_setup->rb_info[0].rb_addr_hi = upper_32_bits(adev->vcn.inst[0].ring_enc[0].gpu_addr); 1469 rb_setup->rb_info[0].rb_size = adev->vcn.inst[0].ring_enc[0].ring_size / 4; 1470 } 1471 if (!(adev->vcn.harvest_config & (1 << 1))) { 1472 rb_setup->rb_info[2].rb_addr_lo = lower_32_bits(adev->vcn.inst[1].ring_enc[0].gpu_addr); 1473 rb_setup->rb_info[2].rb_addr_hi = upper_32_bits(adev->vcn.inst[1].ring_enc[0].gpu_addr); 1474 rb_setup->rb_info[2].rb_size = adev->vcn.inst[1].ring_enc[0].ring_size / 4; 1475 } 1476 fw_shared->decouple.is_enabled = 1; 1477 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_DECOUPLE_FLAG); 1478 } else { 1479 rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr); 1480 rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr); 1481 rb_setup->rb_size = ring_enc->ring_size / 4; 1482 } 1483 1484 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1485 regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 1486 lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr)); 1487 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1488 regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 1489 upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr)); 1490 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, 1491 regUVD_VCPU_NONCACHE_SIZE0), 1492 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); 1493 1494 /* add end packet */ 1495 MMSCH_V4_0_INSERT_END(); 1496 1497 /* refine header */ 1498 header.inst[i].init_status = 0; 1499 header.inst[i].table_offset = header.total_size; 1500 header.inst[i].table_size = table_size; 1501 header.total_size += table_size; 1502 } 1503 1504 /* Update init table header in memory */ 1505 size = sizeof(struct mmsch_v4_0_init_header); 1506 table_loc = (uint32_t *)table->cpu_addr; 1507 memcpy((void *)table_loc, &header, size); 1508 1509 /* message MMSCH (in VCN[0]) to initialize this client 1510 * 1, write to mmsch_vf_ctx_addr_lo/hi register with GPU mc addr 1511 * of memory descriptor location 1512 */ 1513 ctx_addr = table->gpu_addr; 1514 WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); 1515 WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); 1516 1517 /* 2, update vmid of descriptor */ 1518 tmp = RREG32_SOC15(VCN, 0, regMMSCH_VF_VMID); 1519 tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; 1520 /* use domain0 for MM scheduler */ 1521 tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); 1522 WREG32_SOC15(VCN, 0, regMMSCH_VF_VMID, tmp); 1523 1524 /* 3, notify mmsch about the size of this descriptor */ 1525 size = header.total_size; 1526 WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_SIZE, size); 1527 1528 /* 4, set resp to zero */ 1529 WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP, 0); 1530 1531 /* 5, kick off the initialization and wait until 1532 * MMSCH_VF_MAILBOX_RESP becomes non-zero 1533 */ 1534 param = 0x00000001; 1535 WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_HOST, param); 1536 tmp = 0; 1537 timeout = 1000; 1538 resp = 0; 1539 expected = MMSCH_VF_MAILBOX_RESP__OK; 1540 while (resp != expected) { 1541 resp = RREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP); 1542 if (resp != 0) 1543 break; 1544 1545 udelay(10); 1546 tmp = tmp + 10; 1547 if (tmp >= timeout) { 1548 DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ 1549 " waiting for regMMSCH_VF_MAILBOX_RESP "\ 1550 "(expected=0x%08x, readback=0x%08x)\n", 1551 tmp, expected, resp); 1552 return -EBUSY; 1553 } 1554 } 1555 enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0; 1556 init_status = ((struct mmsch_v4_0_init_header *)(table_loc))->inst[enabled_vcn].init_status; 1557 if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE 1558 && init_status != MMSCH_VF_ENGINE_STATUS__PASS) 1559 DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\ 1560 "status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status); 1561 1562 return 0; 1563 } 1564 1565 /** 1566 * vcn_v4_0_stop_dpg_mode - VCN stop with dpg mode 1567 * 1568 * @vinst: VCN instance 1569 * 1570 * Stop VCN block with dpg mode 1571 */ 1572 static void vcn_v4_0_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) 1573 { 1574 struct amdgpu_device *adev = vinst->adev; 1575 int inst_idx = vinst->inst; 1576 struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE}; 1577 uint32_t tmp; 1578 1579 vcn_v4_0_pause_dpg_mode(vinst, &state); 1580 /* Wait for power status to be 1 */ 1581 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1582 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1583 1584 /* wait for read ptr to be equal to write ptr */ 1585 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR); 1586 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1587 1588 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1589 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1590 1591 /* disable dynamic power gating mode */ 1592 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0, 1593 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1594 1595 /* Keeping one read-back to ensure all register writes are done, 1596 * otherwise it may introduce race conditions. 1597 */ 1598 RREG32_SOC15(VCN, inst_idx, regUVD_STATUS); 1599 } 1600 1601 /** 1602 * vcn_v4_0_stop - VCN stop 1603 * 1604 * @vinst: VCN instance 1605 * 1606 * Stop VCN block 1607 */ 1608 static int vcn_v4_0_stop(struct amdgpu_vcn_inst *vinst) 1609 { 1610 struct amdgpu_device *adev = vinst->adev; 1611 int i = vinst->inst; 1612 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1613 uint32_t tmp; 1614 int r = 0; 1615 1616 if (adev->vcn.harvest_config & (1 << i)) 1617 return 0; 1618 1619 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1620 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; 1621 1622 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1623 vcn_v4_0_stop_dpg_mode(vinst); 1624 goto done; 1625 } 1626 1627 /* wait for vcn idle */ 1628 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1629 if (r) 1630 goto done; 1631 1632 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1633 UVD_LMI_STATUS__READ_CLEAN_MASK | 1634 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1635 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1636 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1637 if (r) 1638 goto done; 1639 1640 /* disable LMI UMC channel */ 1641 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2); 1642 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1643 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp); 1644 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | 1645 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1646 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1647 if (r) 1648 goto done; 1649 1650 /* block VCPU register access */ 1651 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 1652 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1653 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1654 1655 /* reset VCPU */ 1656 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1657 UVD_VCPU_CNTL__BLK_RST_MASK, 1658 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1659 1660 /* disable VCPU clock */ 1661 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1662 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1663 1664 /* apply soft reset */ 1665 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1666 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1667 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1668 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1669 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1670 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1671 1672 /* clear status */ 1673 WREG32_SOC15(VCN, i, regUVD_STATUS, 0); 1674 1675 /* apply HW clock gating */ 1676 vcn_v4_0_enable_clock_gating(vinst); 1677 1678 /* enable VCN power gating */ 1679 vcn_v4_0_enable_static_power_gating(vinst); 1680 1681 /* Keeping one read-back to ensure all register writes are done, 1682 * otherwise it may introduce race conditions. 1683 */ 1684 RREG32_SOC15(VCN, i, regUVD_STATUS); 1685 1686 done: 1687 if (adev->pm.dpm_enabled) 1688 amdgpu_dpm_enable_vcn(adev, false, i); 1689 1690 return 0; 1691 } 1692 1693 /** 1694 * vcn_v4_0_pause_dpg_mode - VCN pause with dpg mode 1695 * 1696 * @vinst: VCN instance 1697 * @new_state: pause state 1698 * 1699 * Pause dpg mode for VCN block 1700 */ 1701 static int vcn_v4_0_pause_dpg_mode(struct amdgpu_vcn_inst *vinst, 1702 struct dpg_pause_state *new_state) 1703 { 1704 struct amdgpu_device *adev = vinst->adev; 1705 int inst_idx = vinst->inst; 1706 uint32_t reg_data = 0; 1707 int ret_code; 1708 1709 /* pause/unpause if state is changed */ 1710 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) { 1711 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d", 1712 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based); 1713 reg_data = RREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE) & 1714 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1715 1716 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { 1717 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 0x1, 1718 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1719 1720 if (!ret_code) { 1721 /* pause DPG */ 1722 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1723 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1724 1725 /* wait for ACK */ 1726 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_DPG_PAUSE, 1727 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, 1728 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1729 1730 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1731 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1732 } 1733 } else { 1734 /* unpause dpg, no need to wait */ 1735 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1736 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1737 } 1738 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based; 1739 } 1740 1741 return 0; 1742 } 1743 1744 /** 1745 * vcn_v4_0_unified_ring_get_rptr - get unified read pointer 1746 * 1747 * @ring: amdgpu_ring pointer 1748 * 1749 * Returns the current hardware unified read pointer 1750 */ 1751 static uint64_t vcn_v4_0_unified_ring_get_rptr(struct amdgpu_ring *ring) 1752 { 1753 struct amdgpu_device *adev = ring->adev; 1754 1755 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1756 DRM_ERROR("wrong ring id is identified in %s", __func__); 1757 1758 return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR); 1759 } 1760 1761 /** 1762 * vcn_v4_0_unified_ring_get_wptr - get unified write pointer 1763 * 1764 * @ring: amdgpu_ring pointer 1765 * 1766 * Returns the current hardware unified write pointer 1767 */ 1768 static uint64_t vcn_v4_0_unified_ring_get_wptr(struct amdgpu_ring *ring) 1769 { 1770 struct amdgpu_device *adev = ring->adev; 1771 1772 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1773 DRM_ERROR("wrong ring id is identified in %s", __func__); 1774 1775 if (ring->use_doorbell) 1776 return *ring->wptr_cpu_addr; 1777 else 1778 return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR); 1779 } 1780 1781 /** 1782 * vcn_v4_0_unified_ring_set_wptr - set enc write pointer 1783 * 1784 * @ring: amdgpu_ring pointer 1785 * 1786 * Commits the enc write pointer to the hardware 1787 */ 1788 static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring) 1789 { 1790 struct amdgpu_device *adev = ring->adev; 1791 1792 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1793 DRM_ERROR("wrong ring id is identified in %s", __func__); 1794 1795 if (ring->use_doorbell) { 1796 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1797 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1798 } else { 1799 WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1800 } 1801 } 1802 1803 static int vcn_v4_0_limit_sched(struct amdgpu_cs_parser *p, 1804 struct amdgpu_job *job) 1805 { 1806 struct drm_gpu_scheduler **scheds; 1807 1808 /* The create msg must be in the first IB submitted */ 1809 if (atomic_read(&job->base.entity->fence_seq)) 1810 return -EINVAL; 1811 1812 /* if VCN0 is harvested, we can't support AV1 */ 1813 if (p->adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) 1814 return -EINVAL; 1815 1816 scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC] 1817 [AMDGPU_RING_PRIO_0].sched; 1818 drm_sched_entity_modify_sched(job->base.entity, scheds, 1); 1819 return 0; 1820 } 1821 1822 static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job, 1823 uint64_t addr) 1824 { 1825 struct ttm_operation_ctx ctx = { false, false }; 1826 struct amdgpu_bo_va_mapping *map; 1827 uint32_t *msg, num_buffers; 1828 struct amdgpu_bo *bo; 1829 uint64_t start, end; 1830 unsigned int i; 1831 void *ptr; 1832 int r; 1833 1834 addr &= AMDGPU_GMC_HOLE_MASK; 1835 r = amdgpu_cs_find_mapping(p, addr, &bo, &map); 1836 if (r) { 1837 DRM_ERROR("Can't find BO for addr 0x%08llx\n", addr); 1838 return r; 1839 } 1840 1841 start = map->start * AMDGPU_GPU_PAGE_SIZE; 1842 end = (map->last + 1) * AMDGPU_GPU_PAGE_SIZE; 1843 if (addr & 0x7) { 1844 DRM_ERROR("VCN messages must be 8 byte aligned!\n"); 1845 return -EINVAL; 1846 } 1847 1848 bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; 1849 amdgpu_bo_placement_from_domain(bo, bo->allowed_domains); 1850 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); 1851 if (r) { 1852 DRM_ERROR("Failed validating the VCN message BO (%d)!\n", r); 1853 return r; 1854 } 1855 1856 r = amdgpu_bo_kmap(bo, &ptr); 1857 if (r) { 1858 DRM_ERROR("Failed mapping the VCN message (%d)!\n", r); 1859 return r; 1860 } 1861 1862 msg = ptr + addr - start; 1863 1864 /* Check length */ 1865 if (msg[1] > end - addr) { 1866 r = -EINVAL; 1867 goto out; 1868 } 1869 1870 if (msg[3] != RDECODE_MSG_CREATE) 1871 goto out; 1872 1873 num_buffers = msg[2]; 1874 for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) { 1875 uint32_t offset, size, *create; 1876 1877 if (msg[0] != RDECODE_MESSAGE_CREATE) 1878 continue; 1879 1880 offset = msg[1]; 1881 size = msg[2]; 1882 1883 if (offset + size > end) { 1884 r = -EINVAL; 1885 goto out; 1886 } 1887 1888 create = ptr + addr + offset - start; 1889 1890 /* H264, HEVC and VP9 can run on any instance */ 1891 if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11) 1892 continue; 1893 1894 r = vcn_v4_0_limit_sched(p, job); 1895 if (r) 1896 goto out; 1897 } 1898 1899 out: 1900 amdgpu_bo_kunmap(bo); 1901 return r; 1902 } 1903 1904 #define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002) 1905 #define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003) 1906 1907 #define RADEON_VCN_ENGINE_INFO (0x30000001) 1908 #define RADEON_VCN_ENGINE_INFO_MAX_OFFSET 16 1909 1910 #define RENCODE_ENCODE_STANDARD_AV1 2 1911 #define RENCODE_IB_PARAM_SESSION_INIT 0x00000003 1912 #define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET 64 1913 1914 /* return the offset in ib if id is found, -1 otherwise 1915 * to speed up the searching we only search upto max_offset 1916 */ 1917 static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int max_offset) 1918 { 1919 int i; 1920 1921 for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) { 1922 if (ib->ptr[i + 1] == id) 1923 return i; 1924 } 1925 return -1; 1926 } 1927 1928 static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, 1929 struct amdgpu_job *job, 1930 struct amdgpu_ib *ib) 1931 { 1932 struct amdgpu_ring *ring = amdgpu_job_ring(job); 1933 struct amdgpu_vcn_decode_buffer *decode_buffer; 1934 uint64_t addr; 1935 uint32_t val; 1936 int idx; 1937 1938 /* The first instance can decode anything */ 1939 if (!ring->me) 1940 return 0; 1941 1942 /* RADEON_VCN_ENGINE_INFO is at the top of ib block */ 1943 idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, 1944 RADEON_VCN_ENGINE_INFO_MAX_OFFSET); 1945 if (idx < 0) /* engine info is missing */ 1946 return 0; 1947 1948 val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */ 1949 if (val == RADEON_VCN_ENGINE_TYPE_DECODE) { 1950 decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6]; 1951 1952 if (!(decode_buffer->valid_buf_flag & 0x1)) 1953 return 0; 1954 1955 addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 | 1956 decode_buffer->msg_buffer_address_lo; 1957 return vcn_v4_0_dec_msg(p, job, addr); 1958 } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) { 1959 idx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, 1960 RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET); 1961 if (idx >= 0 && ib->ptr[idx + 2] == RENCODE_ENCODE_STANDARD_AV1) 1962 return vcn_v4_0_limit_sched(p, job); 1963 } 1964 return 0; 1965 } 1966 1967 static int vcn_v4_0_ring_reset(struct amdgpu_ring *ring, 1968 unsigned int vmid, 1969 struct amdgpu_fence *timedout_fence) 1970 { 1971 struct amdgpu_device *adev = ring->adev; 1972 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me]; 1973 int r; 1974 1975 amdgpu_ring_reset_helper_begin(ring, timedout_fence); 1976 r = vcn_v4_0_stop(vinst); 1977 if (r) 1978 return r; 1979 r = vcn_v4_0_start(vinst); 1980 if (r) 1981 return r; 1982 return amdgpu_ring_reset_helper_end(ring, timedout_fence); 1983 } 1984 1985 static struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = { 1986 .type = AMDGPU_RING_TYPE_VCN_ENC, 1987 .align_mask = 0x3f, 1988 .nop = VCN_ENC_CMD_NO_OP, 1989 .extra_dw = sizeof(struct amdgpu_vcn_rb_metadata), 1990 .get_rptr = vcn_v4_0_unified_ring_get_rptr, 1991 .get_wptr = vcn_v4_0_unified_ring_get_wptr, 1992 .set_wptr = vcn_v4_0_unified_ring_set_wptr, 1993 .patch_cs_in_place = vcn_v4_0_ring_patch_cs_in_place, 1994 .emit_frame_size = 1995 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1996 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1997 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1998 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 1999 1, /* vcn_v2_0_enc_ring_insert_end */ 2000 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 2001 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 2002 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 2003 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush, 2004 .test_ring = amdgpu_vcn_enc_ring_test_ring, 2005 .test_ib = amdgpu_vcn_unified_ring_test_ib, 2006 .insert_nop = amdgpu_ring_insert_nop, 2007 .insert_end = vcn_v2_0_enc_ring_insert_end, 2008 .pad_ib = amdgpu_ring_generic_pad_ib, 2009 .begin_use = amdgpu_vcn_ring_begin_use, 2010 .end_use = amdgpu_vcn_ring_end_use, 2011 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg, 2012 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait, 2013 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 2014 .reset = vcn_v4_0_ring_reset, 2015 }; 2016 2017 /** 2018 * vcn_v4_0_set_unified_ring_funcs - set unified ring functions 2019 * 2020 * @adev: amdgpu_device pointer 2021 * 2022 * Set unified ring functions 2023 */ 2024 static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev) 2025 { 2026 int i; 2027 2028 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2029 if (adev->vcn.harvest_config & (1 << i)) 2030 continue; 2031 2032 if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(4, 0, 2)) 2033 vcn_v4_0_unified_ring_vm_funcs.secure_submission_supported = true; 2034 2035 adev->vcn.inst[i].ring_enc[0].funcs = 2036 (const struct amdgpu_ring_funcs *)&vcn_v4_0_unified_ring_vm_funcs; 2037 adev->vcn.inst[i].ring_enc[0].me = i; 2038 } 2039 } 2040 2041 /** 2042 * vcn_v4_0_is_idle - check VCN block is idle 2043 * 2044 * @ip_block: Pointer to the amdgpu_ip_block structure 2045 * 2046 * Check whether VCN block is idle 2047 */ 2048 static bool vcn_v4_0_is_idle(struct amdgpu_ip_block *ip_block) 2049 { 2050 struct amdgpu_device *adev = ip_block->adev; 2051 int i, ret = 1; 2052 2053 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2054 if (adev->vcn.harvest_config & (1 << i)) 2055 continue; 2056 2057 ret &= (RREG32_SOC15(VCN, i, regUVD_STATUS) == UVD_STATUS__IDLE); 2058 } 2059 2060 return ret; 2061 } 2062 2063 /** 2064 * vcn_v4_0_wait_for_idle - wait for VCN block idle 2065 * 2066 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 2067 * 2068 * Wait for VCN block idle 2069 */ 2070 static int vcn_v4_0_wait_for_idle(struct amdgpu_ip_block *ip_block) 2071 { 2072 struct amdgpu_device *adev = ip_block->adev; 2073 int i, ret = 0; 2074 2075 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2076 if (adev->vcn.harvest_config & (1 << i)) 2077 continue; 2078 2079 ret = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 2080 UVD_STATUS__IDLE); 2081 if (ret) 2082 return ret; 2083 } 2084 2085 return ret; 2086 } 2087 2088 /** 2089 * vcn_v4_0_set_clockgating_state - set VCN block clockgating state 2090 * 2091 * @ip_block: amdgpu_ip_block pointer 2092 * @state: clock gating state 2093 * 2094 * Set VCN block clockgating state 2095 */ 2096 static int vcn_v4_0_set_clockgating_state(struct amdgpu_ip_block *ip_block, 2097 enum amd_clockgating_state state) 2098 { 2099 struct amdgpu_device *adev = ip_block->adev; 2100 bool enable = state == AMD_CG_STATE_GATE; 2101 int i; 2102 2103 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2104 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 2105 2106 if (adev->vcn.harvest_config & (1 << i)) 2107 continue; 2108 2109 if (enable) { 2110 if (RREG32_SOC15(VCN, i, regUVD_STATUS) != UVD_STATUS__IDLE) 2111 return -EBUSY; 2112 vcn_v4_0_enable_clock_gating(vinst); 2113 } else { 2114 vcn_v4_0_disable_clock_gating(vinst); 2115 } 2116 } 2117 2118 return 0; 2119 } 2120 2121 static int vcn_v4_0_set_pg_state(struct amdgpu_vcn_inst *vinst, 2122 enum amd_powergating_state state) 2123 { 2124 struct amdgpu_device *adev = vinst->adev; 2125 int ret = 0; 2126 2127 /* for SRIOV, guest should not control VCN Power-gating 2128 * MMSCH FW should control Power-gating and clock-gating 2129 * guest should avoid touching CGC and PG 2130 */ 2131 if (amdgpu_sriov_vf(adev)) { 2132 vinst->cur_state = AMD_PG_STATE_UNGATE; 2133 return 0; 2134 } 2135 2136 if (state == vinst->cur_state) 2137 return 0; 2138 2139 if (state == AMD_PG_STATE_GATE) 2140 ret = vcn_v4_0_stop(vinst); 2141 else 2142 ret = vcn_v4_0_start(vinst); 2143 2144 if (!ret) 2145 vinst->cur_state = state; 2146 2147 return ret; 2148 } 2149 2150 /** 2151 * vcn_v4_0_set_ras_interrupt_state - set VCN block RAS interrupt state 2152 * 2153 * @adev: amdgpu_device pointer 2154 * @source: interrupt sources 2155 * @type: interrupt types 2156 * @state: interrupt states 2157 * 2158 * Set VCN block RAS interrupt state 2159 */ 2160 static int vcn_v4_0_set_ras_interrupt_state(struct amdgpu_device *adev, 2161 struct amdgpu_irq_src *source, 2162 unsigned int type, 2163 enum amdgpu_interrupt_state state) 2164 { 2165 return 0; 2166 } 2167 2168 /** 2169 * vcn_v4_0_process_interrupt - process VCN block interrupt 2170 * 2171 * @adev: amdgpu_device pointer 2172 * @source: interrupt sources 2173 * @entry: interrupt entry from clients and sources 2174 * 2175 * Process VCN block interrupt 2176 */ 2177 static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, 2178 struct amdgpu_iv_entry *entry) 2179 { 2180 uint32_t ip_instance; 2181 2182 if (amdgpu_sriov_is_vcn_rb_decouple(adev)) { 2183 ip_instance = entry->ring_id; 2184 } else { 2185 switch (entry->client_id) { 2186 case SOC15_IH_CLIENTID_VCN: 2187 ip_instance = 0; 2188 break; 2189 case SOC15_IH_CLIENTID_VCN1: 2190 ip_instance = 1; 2191 break; 2192 default: 2193 DRM_ERROR("Unhandled client id: %d\n", entry->client_id); 2194 return 0; 2195 } 2196 } 2197 2198 DRM_DEBUG("IH: VCN TRAP\n"); 2199 2200 switch (entry->src_id) { 2201 case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 2202 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]); 2203 break; 2204 default: 2205 DRM_ERROR("Unhandled interrupt: %d %d\n", 2206 entry->src_id, entry->src_data[0]); 2207 break; 2208 } 2209 2210 return 0; 2211 } 2212 2213 static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = { 2214 .process = vcn_v4_0_process_interrupt, 2215 }; 2216 2217 static const struct amdgpu_irq_src_funcs vcn_v4_0_ras_irq_funcs = { 2218 .set = vcn_v4_0_set_ras_interrupt_state, 2219 .process = amdgpu_vcn_process_poison_irq, 2220 }; 2221 2222 /** 2223 * vcn_v4_0_set_irq_funcs - set VCN block interrupt irq functions 2224 * 2225 * @adev: amdgpu_device pointer 2226 * 2227 * Set VCN block interrupt irq functions 2228 */ 2229 static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev) 2230 { 2231 int i; 2232 2233 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2234 if (adev->vcn.harvest_config & (1 << i)) 2235 continue; 2236 2237 adev->vcn.inst[i].irq.num_types = adev->vcn.inst[i].num_enc_rings + 1; 2238 adev->vcn.inst[i].irq.funcs = &vcn_v4_0_irq_funcs; 2239 2240 adev->vcn.inst[i].ras_poison_irq.num_types = adev->vcn.inst[i].num_enc_rings + 1; 2241 adev->vcn.inst[i].ras_poison_irq.funcs = &vcn_v4_0_ras_irq_funcs; 2242 } 2243 } 2244 2245 static const struct amd_ip_funcs vcn_v4_0_ip_funcs = { 2246 .name = "vcn_v4_0", 2247 .early_init = vcn_v4_0_early_init, 2248 .sw_init = vcn_v4_0_sw_init, 2249 .sw_fini = vcn_v4_0_sw_fini, 2250 .hw_init = vcn_v4_0_hw_init, 2251 .hw_fini = vcn_v4_0_hw_fini, 2252 .suspend = vcn_v4_0_suspend, 2253 .resume = vcn_v4_0_resume, 2254 .is_idle = vcn_v4_0_is_idle, 2255 .wait_for_idle = vcn_v4_0_wait_for_idle, 2256 .set_clockgating_state = vcn_v4_0_set_clockgating_state, 2257 .set_powergating_state = vcn_set_powergating_state, 2258 .dump_ip_state = amdgpu_vcn_dump_ip_state, 2259 .print_ip_state = amdgpu_vcn_print_ip_state, 2260 }; 2261 2262 const struct amdgpu_ip_block_version vcn_v4_0_ip_block = { 2263 .type = AMD_IP_BLOCK_TYPE_VCN, 2264 .major = 4, 2265 .minor = 0, 2266 .rev = 0, 2267 .funcs = &vcn_v4_0_ip_funcs, 2268 }; 2269 2270 static uint32_t vcn_v4_0_query_poison_by_instance(struct amdgpu_device *adev, 2271 uint32_t instance, uint32_t sub_block) 2272 { 2273 uint32_t poison_stat = 0, reg_value = 0; 2274 2275 switch (sub_block) { 2276 case AMDGPU_VCN_V4_0_VCPU_VCODEC: 2277 reg_value = RREG32_SOC15(VCN, instance, regUVD_RAS_VCPU_VCODEC_STATUS); 2278 poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF); 2279 break; 2280 default: 2281 break; 2282 } 2283 2284 if (poison_stat) 2285 dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n", 2286 instance, sub_block); 2287 2288 return poison_stat; 2289 } 2290 2291 static bool vcn_v4_0_query_ras_poison_status(struct amdgpu_device *adev) 2292 { 2293 uint32_t inst, sub; 2294 uint32_t poison_stat = 0; 2295 2296 for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++) 2297 for (sub = 0; sub < AMDGPU_VCN_V4_0_MAX_SUB_BLOCK; sub++) 2298 poison_stat += 2299 vcn_v4_0_query_poison_by_instance(adev, inst, sub); 2300 2301 return !!poison_stat; 2302 } 2303 2304 const struct amdgpu_ras_block_hw_ops vcn_v4_0_ras_hw_ops = { 2305 .query_poison_status = vcn_v4_0_query_ras_poison_status, 2306 }; 2307 2308 static struct amdgpu_vcn_ras vcn_v4_0_ras = { 2309 .ras_block = { 2310 .hw_ops = &vcn_v4_0_ras_hw_ops, 2311 .ras_late_init = amdgpu_vcn_ras_late_init, 2312 }, 2313 }; 2314 2315 static void vcn_v4_0_set_ras_funcs(struct amdgpu_device *adev) 2316 { 2317 switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) { 2318 case IP_VERSION(4, 0, 0): 2319 adev->vcn.ras = &vcn_v4_0_ras; 2320 break; 2321 default: 2322 break; 2323 } 2324 } 2325