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