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 r = 0; 1625 goto done; 1626 } 1627 1628 /* wait for vcn idle */ 1629 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1630 if (r) 1631 goto done; 1632 1633 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1634 UVD_LMI_STATUS__READ_CLEAN_MASK | 1635 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1636 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1637 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1638 if (r) 1639 goto done; 1640 1641 /* disable LMI UMC channel */ 1642 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2); 1643 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1644 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp); 1645 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | 1646 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1647 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1648 if (r) 1649 goto done; 1650 1651 /* block VCPU register access */ 1652 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 1653 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1654 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1655 1656 /* reset VCPU */ 1657 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1658 UVD_VCPU_CNTL__BLK_RST_MASK, 1659 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1660 1661 /* disable VCPU clock */ 1662 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1663 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1664 1665 /* apply soft reset */ 1666 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1667 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1668 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1669 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1670 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1671 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1672 1673 /* clear status */ 1674 WREG32_SOC15(VCN, i, regUVD_STATUS, 0); 1675 1676 /* apply HW clock gating */ 1677 vcn_v4_0_enable_clock_gating(vinst); 1678 1679 /* enable VCN power gating */ 1680 vcn_v4_0_enable_static_power_gating(vinst); 1681 1682 /* Keeping one read-back to ensure all register writes are done, 1683 * otherwise it may introduce race conditions. 1684 */ 1685 RREG32_SOC15(VCN, i, regUVD_STATUS); 1686 1687 done: 1688 if (adev->pm.dpm_enabled) 1689 amdgpu_dpm_enable_vcn(adev, false, i); 1690 1691 return 0; 1692 } 1693 1694 /** 1695 * vcn_v4_0_pause_dpg_mode - VCN pause with dpg mode 1696 * 1697 * @vinst: VCN instance 1698 * @new_state: pause state 1699 * 1700 * Pause dpg mode for VCN block 1701 */ 1702 static int vcn_v4_0_pause_dpg_mode(struct amdgpu_vcn_inst *vinst, 1703 struct dpg_pause_state *new_state) 1704 { 1705 struct amdgpu_device *adev = vinst->adev; 1706 int inst_idx = vinst->inst; 1707 uint32_t reg_data = 0; 1708 int ret_code; 1709 1710 /* pause/unpause if state is changed */ 1711 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) { 1712 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d", 1713 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based); 1714 reg_data = RREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE) & 1715 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1716 1717 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { 1718 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 0x1, 1719 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1720 1721 if (!ret_code) { 1722 /* pause DPG */ 1723 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1724 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1725 1726 /* wait for ACK */ 1727 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_DPG_PAUSE, 1728 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, 1729 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1730 1731 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1732 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1733 } 1734 } else { 1735 /* unpause dpg, no need to wait */ 1736 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1737 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1738 } 1739 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based; 1740 } 1741 1742 return 0; 1743 } 1744 1745 /** 1746 * vcn_v4_0_unified_ring_get_rptr - get unified read pointer 1747 * 1748 * @ring: amdgpu_ring pointer 1749 * 1750 * Returns the current hardware unified read pointer 1751 */ 1752 static uint64_t vcn_v4_0_unified_ring_get_rptr(struct amdgpu_ring *ring) 1753 { 1754 struct amdgpu_device *adev = ring->adev; 1755 1756 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1757 DRM_ERROR("wrong ring id is identified in %s", __func__); 1758 1759 return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR); 1760 } 1761 1762 /** 1763 * vcn_v4_0_unified_ring_get_wptr - get unified write pointer 1764 * 1765 * @ring: amdgpu_ring pointer 1766 * 1767 * Returns the current hardware unified write pointer 1768 */ 1769 static uint64_t vcn_v4_0_unified_ring_get_wptr(struct amdgpu_ring *ring) 1770 { 1771 struct amdgpu_device *adev = ring->adev; 1772 1773 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1774 DRM_ERROR("wrong ring id is identified in %s", __func__); 1775 1776 if (ring->use_doorbell) 1777 return *ring->wptr_cpu_addr; 1778 else 1779 return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR); 1780 } 1781 1782 /** 1783 * vcn_v4_0_unified_ring_set_wptr - set enc write pointer 1784 * 1785 * @ring: amdgpu_ring pointer 1786 * 1787 * Commits the enc write pointer to the hardware 1788 */ 1789 static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring) 1790 { 1791 struct amdgpu_device *adev = ring->adev; 1792 1793 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1794 DRM_ERROR("wrong ring id is identified in %s", __func__); 1795 1796 if (ring->use_doorbell) { 1797 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1798 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1799 } else { 1800 WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1801 } 1802 } 1803 1804 static int vcn_v4_0_limit_sched(struct amdgpu_cs_parser *p, 1805 struct amdgpu_job *job) 1806 { 1807 struct drm_gpu_scheduler **scheds; 1808 1809 /* The create msg must be in the first IB submitted */ 1810 if (atomic_read(&job->base.entity->fence_seq)) 1811 return -EINVAL; 1812 1813 /* if VCN0 is harvested, we can't support AV1 */ 1814 if (p->adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) 1815 return -EINVAL; 1816 1817 scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC] 1818 [AMDGPU_RING_PRIO_0].sched; 1819 drm_sched_entity_modify_sched(job->base.entity, scheds, 1); 1820 return 0; 1821 } 1822 1823 static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job, 1824 uint64_t addr) 1825 { 1826 struct ttm_operation_ctx ctx = { false, false }; 1827 struct amdgpu_bo_va_mapping *map; 1828 uint32_t *msg, num_buffers; 1829 struct amdgpu_bo *bo; 1830 uint64_t start, end; 1831 unsigned int i; 1832 void *ptr; 1833 int r; 1834 1835 addr &= AMDGPU_GMC_HOLE_MASK; 1836 r = amdgpu_cs_find_mapping(p, addr, &bo, &map); 1837 if (r) { 1838 DRM_ERROR("Can't find BO for addr 0x%08llx\n", addr); 1839 return r; 1840 } 1841 1842 start = map->start * AMDGPU_GPU_PAGE_SIZE; 1843 end = (map->last + 1) * AMDGPU_GPU_PAGE_SIZE; 1844 if (addr & 0x7) { 1845 DRM_ERROR("VCN messages must be 8 byte aligned!\n"); 1846 return -EINVAL; 1847 } 1848 1849 bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; 1850 amdgpu_bo_placement_from_domain(bo, bo->allowed_domains); 1851 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); 1852 if (r) { 1853 DRM_ERROR("Failed validating the VCN message BO (%d)!\n", r); 1854 return r; 1855 } 1856 1857 r = amdgpu_bo_kmap(bo, &ptr); 1858 if (r) { 1859 DRM_ERROR("Failed mapping the VCN message (%d)!\n", r); 1860 return r; 1861 } 1862 1863 msg = ptr + addr - start; 1864 1865 /* Check length */ 1866 if (msg[1] > end - addr) { 1867 r = -EINVAL; 1868 goto out; 1869 } 1870 1871 if (msg[3] != RDECODE_MSG_CREATE) 1872 goto out; 1873 1874 num_buffers = msg[2]; 1875 for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) { 1876 uint32_t offset, size, *create; 1877 1878 if (msg[0] != RDECODE_MESSAGE_CREATE) 1879 continue; 1880 1881 offset = msg[1]; 1882 size = msg[2]; 1883 1884 if (offset + size > end) { 1885 r = -EINVAL; 1886 goto out; 1887 } 1888 1889 create = ptr + addr + offset - start; 1890 1891 /* H264, HEVC and VP9 can run on any instance */ 1892 if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11) 1893 continue; 1894 1895 r = vcn_v4_0_limit_sched(p, job); 1896 if (r) 1897 goto out; 1898 } 1899 1900 out: 1901 amdgpu_bo_kunmap(bo); 1902 return r; 1903 } 1904 1905 #define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002) 1906 #define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003) 1907 1908 #define RADEON_VCN_ENGINE_INFO (0x30000001) 1909 #define RADEON_VCN_ENGINE_INFO_MAX_OFFSET 16 1910 1911 #define RENCODE_ENCODE_STANDARD_AV1 2 1912 #define RENCODE_IB_PARAM_SESSION_INIT 0x00000003 1913 #define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET 64 1914 1915 /* return the offset in ib if id is found, -1 otherwise 1916 * to speed up the searching we only search upto max_offset 1917 */ 1918 static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int max_offset) 1919 { 1920 int i; 1921 1922 for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) { 1923 if (ib->ptr[i + 1] == id) 1924 return i; 1925 } 1926 return -1; 1927 } 1928 1929 static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, 1930 struct amdgpu_job *job, 1931 struct amdgpu_ib *ib) 1932 { 1933 struct amdgpu_ring *ring = amdgpu_job_ring(job); 1934 struct amdgpu_vcn_decode_buffer *decode_buffer; 1935 uint64_t addr; 1936 uint32_t val; 1937 int idx; 1938 1939 /* The first instance can decode anything */ 1940 if (!ring->me) 1941 return 0; 1942 1943 /* RADEON_VCN_ENGINE_INFO is at the top of ib block */ 1944 idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, 1945 RADEON_VCN_ENGINE_INFO_MAX_OFFSET); 1946 if (idx < 0) /* engine info is missing */ 1947 return 0; 1948 1949 val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */ 1950 if (val == RADEON_VCN_ENGINE_TYPE_DECODE) { 1951 decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6]; 1952 1953 if (!(decode_buffer->valid_buf_flag & 0x1)) 1954 return 0; 1955 1956 addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 | 1957 decode_buffer->msg_buffer_address_lo; 1958 return vcn_v4_0_dec_msg(p, job, addr); 1959 } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) { 1960 idx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, 1961 RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET); 1962 if (idx >= 0 && ib->ptr[idx + 2] == RENCODE_ENCODE_STANDARD_AV1) 1963 return vcn_v4_0_limit_sched(p, job); 1964 } 1965 return 0; 1966 } 1967 1968 static int vcn_v4_0_ring_reset(struct amdgpu_ring *ring, 1969 unsigned int vmid, 1970 struct amdgpu_fence *timedout_fence) 1971 { 1972 struct amdgpu_device *adev = ring->adev; 1973 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me]; 1974 int r; 1975 1976 amdgpu_ring_reset_helper_begin(ring, timedout_fence); 1977 r = vcn_v4_0_stop(vinst); 1978 if (r) 1979 return r; 1980 r = vcn_v4_0_start(vinst); 1981 if (r) 1982 return r; 1983 return amdgpu_ring_reset_helper_end(ring, timedout_fence); 1984 } 1985 1986 static struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = { 1987 .type = AMDGPU_RING_TYPE_VCN_ENC, 1988 .align_mask = 0x3f, 1989 .nop = VCN_ENC_CMD_NO_OP, 1990 .extra_dw = sizeof(struct amdgpu_vcn_rb_metadata), 1991 .get_rptr = vcn_v4_0_unified_ring_get_rptr, 1992 .get_wptr = vcn_v4_0_unified_ring_get_wptr, 1993 .set_wptr = vcn_v4_0_unified_ring_set_wptr, 1994 .patch_cs_in_place = vcn_v4_0_ring_patch_cs_in_place, 1995 .emit_frame_size = 1996 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1997 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1998 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1999 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 2000 1, /* vcn_v2_0_enc_ring_insert_end */ 2001 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 2002 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 2003 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 2004 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush, 2005 .test_ring = amdgpu_vcn_enc_ring_test_ring, 2006 .test_ib = amdgpu_vcn_unified_ring_test_ib, 2007 .insert_nop = amdgpu_ring_insert_nop, 2008 .insert_end = vcn_v2_0_enc_ring_insert_end, 2009 .pad_ib = amdgpu_ring_generic_pad_ib, 2010 .begin_use = amdgpu_vcn_ring_begin_use, 2011 .end_use = amdgpu_vcn_ring_end_use, 2012 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg, 2013 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait, 2014 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 2015 .reset = vcn_v4_0_ring_reset, 2016 }; 2017 2018 /** 2019 * vcn_v4_0_set_unified_ring_funcs - set unified ring functions 2020 * 2021 * @adev: amdgpu_device pointer 2022 * 2023 * Set unified ring functions 2024 */ 2025 static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev) 2026 { 2027 int i; 2028 2029 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2030 if (adev->vcn.harvest_config & (1 << i)) 2031 continue; 2032 2033 if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(4, 0, 2)) 2034 vcn_v4_0_unified_ring_vm_funcs.secure_submission_supported = true; 2035 2036 adev->vcn.inst[i].ring_enc[0].funcs = 2037 (const struct amdgpu_ring_funcs *)&vcn_v4_0_unified_ring_vm_funcs; 2038 adev->vcn.inst[i].ring_enc[0].me = i; 2039 } 2040 } 2041 2042 /** 2043 * vcn_v4_0_is_idle - check VCN block is idle 2044 * 2045 * @ip_block: Pointer to the amdgpu_ip_block structure 2046 * 2047 * Check whether VCN block is idle 2048 */ 2049 static bool vcn_v4_0_is_idle(struct amdgpu_ip_block *ip_block) 2050 { 2051 struct amdgpu_device *adev = ip_block->adev; 2052 int i, ret = 1; 2053 2054 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2055 if (adev->vcn.harvest_config & (1 << i)) 2056 continue; 2057 2058 ret &= (RREG32_SOC15(VCN, i, regUVD_STATUS) == UVD_STATUS__IDLE); 2059 } 2060 2061 return ret; 2062 } 2063 2064 /** 2065 * vcn_v4_0_wait_for_idle - wait for VCN block idle 2066 * 2067 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 2068 * 2069 * Wait for VCN block idle 2070 */ 2071 static int vcn_v4_0_wait_for_idle(struct amdgpu_ip_block *ip_block) 2072 { 2073 struct amdgpu_device *adev = ip_block->adev; 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, regUVD_STATUS, UVD_STATUS__IDLE, 2081 UVD_STATUS__IDLE); 2082 if (ret) 2083 return ret; 2084 } 2085 2086 return ret; 2087 } 2088 2089 /** 2090 * vcn_v4_0_set_clockgating_state - set VCN block clockgating state 2091 * 2092 * @ip_block: amdgpu_ip_block pointer 2093 * @state: clock gating state 2094 * 2095 * Set VCN block clockgating state 2096 */ 2097 static int vcn_v4_0_set_clockgating_state(struct amdgpu_ip_block *ip_block, 2098 enum amd_clockgating_state state) 2099 { 2100 struct amdgpu_device *adev = ip_block->adev; 2101 bool enable = state == AMD_CG_STATE_GATE; 2102 int i; 2103 2104 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2105 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 2106 2107 if (adev->vcn.harvest_config & (1 << i)) 2108 continue; 2109 2110 if (enable) { 2111 if (RREG32_SOC15(VCN, i, regUVD_STATUS) != UVD_STATUS__IDLE) 2112 return -EBUSY; 2113 vcn_v4_0_enable_clock_gating(vinst); 2114 } else { 2115 vcn_v4_0_disable_clock_gating(vinst); 2116 } 2117 } 2118 2119 return 0; 2120 } 2121 2122 static int vcn_v4_0_set_pg_state(struct amdgpu_vcn_inst *vinst, 2123 enum amd_powergating_state state) 2124 { 2125 struct amdgpu_device *adev = vinst->adev; 2126 int ret = 0; 2127 2128 /* for SRIOV, guest should not control VCN Power-gating 2129 * MMSCH FW should control Power-gating and clock-gating 2130 * guest should avoid touching CGC and PG 2131 */ 2132 if (amdgpu_sriov_vf(adev)) { 2133 vinst->cur_state = AMD_PG_STATE_UNGATE; 2134 return 0; 2135 } 2136 2137 if (state == vinst->cur_state) 2138 return 0; 2139 2140 if (state == AMD_PG_STATE_GATE) 2141 ret = vcn_v4_0_stop(vinst); 2142 else 2143 ret = vcn_v4_0_start(vinst); 2144 2145 if (!ret) 2146 vinst->cur_state = state; 2147 2148 return ret; 2149 } 2150 2151 /** 2152 * vcn_v4_0_set_ras_interrupt_state - set VCN block RAS interrupt state 2153 * 2154 * @adev: amdgpu_device pointer 2155 * @source: interrupt sources 2156 * @type: interrupt types 2157 * @state: interrupt states 2158 * 2159 * Set VCN block RAS interrupt state 2160 */ 2161 static int vcn_v4_0_set_ras_interrupt_state(struct amdgpu_device *adev, 2162 struct amdgpu_irq_src *source, 2163 unsigned int type, 2164 enum amdgpu_interrupt_state state) 2165 { 2166 return 0; 2167 } 2168 2169 /** 2170 * vcn_v4_0_process_interrupt - process VCN block interrupt 2171 * 2172 * @adev: amdgpu_device pointer 2173 * @source: interrupt sources 2174 * @entry: interrupt entry from clients and sources 2175 * 2176 * Process VCN block interrupt 2177 */ 2178 static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, 2179 struct amdgpu_iv_entry *entry) 2180 { 2181 uint32_t ip_instance; 2182 2183 if (amdgpu_sriov_is_vcn_rb_decouple(adev)) { 2184 ip_instance = entry->ring_id; 2185 } else { 2186 switch (entry->client_id) { 2187 case SOC15_IH_CLIENTID_VCN: 2188 ip_instance = 0; 2189 break; 2190 case SOC15_IH_CLIENTID_VCN1: 2191 ip_instance = 1; 2192 break; 2193 default: 2194 DRM_ERROR("Unhandled client id: %d\n", entry->client_id); 2195 return 0; 2196 } 2197 } 2198 2199 DRM_DEBUG("IH: VCN TRAP\n"); 2200 2201 switch (entry->src_id) { 2202 case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 2203 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]); 2204 break; 2205 default: 2206 DRM_ERROR("Unhandled interrupt: %d %d\n", 2207 entry->src_id, entry->src_data[0]); 2208 break; 2209 } 2210 2211 return 0; 2212 } 2213 2214 static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = { 2215 .process = vcn_v4_0_process_interrupt, 2216 }; 2217 2218 static const struct amdgpu_irq_src_funcs vcn_v4_0_ras_irq_funcs = { 2219 .set = vcn_v4_0_set_ras_interrupt_state, 2220 .process = amdgpu_vcn_process_poison_irq, 2221 }; 2222 2223 /** 2224 * vcn_v4_0_set_irq_funcs - set VCN block interrupt irq functions 2225 * 2226 * @adev: amdgpu_device pointer 2227 * 2228 * Set VCN block interrupt irq functions 2229 */ 2230 static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev) 2231 { 2232 int i; 2233 2234 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2235 if (adev->vcn.harvest_config & (1 << i)) 2236 continue; 2237 2238 adev->vcn.inst[i].irq.num_types = adev->vcn.inst[i].num_enc_rings + 1; 2239 adev->vcn.inst[i].irq.funcs = &vcn_v4_0_irq_funcs; 2240 2241 adev->vcn.inst[i].ras_poison_irq.num_types = adev->vcn.inst[i].num_enc_rings + 1; 2242 adev->vcn.inst[i].ras_poison_irq.funcs = &vcn_v4_0_ras_irq_funcs; 2243 } 2244 } 2245 2246 static const struct amd_ip_funcs vcn_v4_0_ip_funcs = { 2247 .name = "vcn_v4_0", 2248 .early_init = vcn_v4_0_early_init, 2249 .sw_init = vcn_v4_0_sw_init, 2250 .sw_fini = vcn_v4_0_sw_fini, 2251 .hw_init = vcn_v4_0_hw_init, 2252 .hw_fini = vcn_v4_0_hw_fini, 2253 .suspend = vcn_v4_0_suspend, 2254 .resume = vcn_v4_0_resume, 2255 .is_idle = vcn_v4_0_is_idle, 2256 .wait_for_idle = vcn_v4_0_wait_for_idle, 2257 .set_clockgating_state = vcn_v4_0_set_clockgating_state, 2258 .set_powergating_state = vcn_set_powergating_state, 2259 .dump_ip_state = amdgpu_vcn_dump_ip_state, 2260 .print_ip_state = amdgpu_vcn_print_ip_state, 2261 }; 2262 2263 const struct amdgpu_ip_block_version vcn_v4_0_ip_block = { 2264 .type = AMD_IP_BLOCK_TYPE_VCN, 2265 .major = 4, 2266 .minor = 0, 2267 .rev = 0, 2268 .funcs = &vcn_v4_0_ip_funcs, 2269 }; 2270 2271 static uint32_t vcn_v4_0_query_poison_by_instance(struct amdgpu_device *adev, 2272 uint32_t instance, uint32_t sub_block) 2273 { 2274 uint32_t poison_stat = 0, reg_value = 0; 2275 2276 switch (sub_block) { 2277 case AMDGPU_VCN_V4_0_VCPU_VCODEC: 2278 reg_value = RREG32_SOC15(VCN, instance, regUVD_RAS_VCPU_VCODEC_STATUS); 2279 poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF); 2280 break; 2281 default: 2282 break; 2283 } 2284 2285 if (poison_stat) 2286 dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n", 2287 instance, sub_block); 2288 2289 return poison_stat; 2290 } 2291 2292 static bool vcn_v4_0_query_ras_poison_status(struct amdgpu_device *adev) 2293 { 2294 uint32_t inst, sub; 2295 uint32_t poison_stat = 0; 2296 2297 for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++) 2298 for (sub = 0; sub < AMDGPU_VCN_V4_0_MAX_SUB_BLOCK; sub++) 2299 poison_stat += 2300 vcn_v4_0_query_poison_by_instance(adev, inst, sub); 2301 2302 return !!poison_stat; 2303 } 2304 2305 const struct amdgpu_ras_block_hw_ops vcn_v4_0_ras_hw_ops = { 2306 .query_poison_status = vcn_v4_0_query_ras_poison_status, 2307 }; 2308 2309 static struct amdgpu_vcn_ras vcn_v4_0_ras = { 2310 .ras_block = { 2311 .hw_ops = &vcn_v4_0_ras_hw_ops, 2312 .ras_late_init = amdgpu_vcn_ras_late_init, 2313 }, 2314 }; 2315 2316 static void vcn_v4_0_set_ras_funcs(struct amdgpu_device *adev) 2317 { 2318 switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) { 2319 case IP_VERSION(4, 0, 0): 2320 adev->vcn.ras = &vcn_v4_0_ras; 2321 break; 2322 default: 2323 break; 2324 } 2325 } 2326