1 /* 2 * Copyright 2024 Advanced Micro Devices, Inc. All rights reserved. 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 "soc15.h" 29 #include "soc15d.h" 30 #include "soc15_hw_ip.h" 31 #include "vcn_v2_0.h" 32 #include "vcn_v4_0_3.h" 33 #include "mmsch_v5_0.h" 34 35 #include "vcn/vcn_5_0_0_offset.h" 36 #include "vcn/vcn_5_0_0_sh_mask.h" 37 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h" 38 #include "vcn_v5_0_0.h" 39 #include "vcn_v5_0_1.h" 40 41 #include <drm/drm_drv.h> 42 43 static const struct amdgpu_hwip_reg_entry vcn_reg_list_5_0_1[] = { 44 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS), 45 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS), 46 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID), 47 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2), 48 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0), 49 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1), 50 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD), 51 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI), 52 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO), 53 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2), 54 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2), 55 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3), 56 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3), 57 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4), 58 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4), 59 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR), 60 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR), 61 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2), 62 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2), 63 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3), 64 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3), 65 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4), 66 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4), 67 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE), 68 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2), 69 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3), 70 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4), 71 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL), 72 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA), 73 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK), 74 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE) 75 }; 76 77 static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev); 78 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev); 79 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev); 80 static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst, 81 enum amd_powergating_state state); 82 static void vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring *ring); 83 static void vcn_v5_0_1_set_ras_funcs(struct amdgpu_device *adev); 84 /** 85 * vcn_v5_0_1_early_init - set function pointers and load microcode 86 * 87 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 88 * 89 * Set ring and irq function pointers 90 * Load microcode from filesystem 91 */ 92 static int vcn_v5_0_1_early_init(struct amdgpu_ip_block *ip_block) 93 { 94 struct amdgpu_device *adev = ip_block->adev; 95 int i, r; 96 97 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) 98 /* re-use enc ring as unified ring */ 99 adev->vcn.inst[i].num_enc_rings = 1; 100 101 vcn_v5_0_1_set_unified_ring_funcs(adev); 102 vcn_v5_0_1_set_irq_funcs(adev); 103 vcn_v5_0_1_set_ras_funcs(adev); 104 105 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 106 adev->vcn.inst[i].set_pg_state = vcn_v5_0_1_set_pg_state; 107 108 r = amdgpu_vcn_early_init(adev, i); 109 if (r) 110 return r; 111 } 112 113 return 0; 114 } 115 116 static int vcn_v5_0_1_late_init(struct amdgpu_ip_block *ip_block) 117 { 118 struct amdgpu_device *adev = ip_block->adev; 119 120 adev->vcn.supported_reset = 121 amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); 122 123 switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) { 124 case IP_VERSION(13, 0, 12): 125 if ((adev->psp.sos.fw_version >= 0x00450025) && amdgpu_dpm_reset_vcn_is_supported(adev)) 126 adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 127 break; 128 default: 129 break; 130 } 131 132 return 0; 133 } 134 135 static void vcn_v5_0_1_fw_shared_init(struct amdgpu_device *adev, int inst_idx) 136 { 137 struct amdgpu_vcn5_fw_shared *fw_shared; 138 139 fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 140 141 if (fw_shared->sq.is_enabled) 142 return; 143 fw_shared->present_flag_0 = 144 cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); 145 fw_shared->sq.is_enabled = 1; 146 147 if (amdgpu_vcnfw_log) 148 amdgpu_vcn_fwlog_init(&adev->vcn.inst[inst_idx]); 149 } 150 151 /** 152 * vcn_v5_0_1_sw_init - sw init for VCN block 153 * 154 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 155 * 156 * Load firmware and sw initialization 157 */ 158 static int vcn_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) 159 { 160 struct amdgpu_device *adev = ip_block->adev; 161 struct amdgpu_ring *ring; 162 int i, r, vcn_inst; 163 164 /* VCN UNIFIED TRAP */ 165 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 166 VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst->irq); 167 if (r) 168 return r; 169 170 /* VCN POISON TRAP */ 171 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 172 VCN_5_0__SRCID_UVD_POISON, &adev->vcn.inst->ras_poison_irq); 173 174 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 175 vcn_inst = GET_INST(VCN, i); 176 177 r = amdgpu_vcn_sw_init(adev, i); 178 if (r) 179 return r; 180 181 amdgpu_vcn_setup_ucode(adev, i); 182 183 r = amdgpu_vcn_resume(adev, i); 184 if (r) 185 return r; 186 187 ring = &adev->vcn.inst[i].ring_enc[0]; 188 ring->use_doorbell = true; 189 if (!amdgpu_sriov_vf(adev)) 190 ring->doorbell_index = 191 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 192 11 * vcn_inst; 193 else 194 ring->doorbell_index = 195 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 196 32 * vcn_inst; 197 198 ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id); 199 sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id); 200 201 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0, 202 AMDGPU_RING_PRIO_DEFAULT, &adev->vcn.inst[i].sched_score); 203 if (r) 204 return r; 205 206 vcn_v5_0_1_fw_shared_init(adev, i); 207 } 208 209 if (amdgpu_sriov_vf(adev)) { 210 r = amdgpu_virt_alloc_mm_table(adev); 211 if (r) 212 return r; 213 } 214 215 if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) { 216 r = amdgpu_vcn_ras_sw_init(adev); 217 if (r) { 218 dev_err(adev->dev, "Failed to initialize vcn ras block!\n"); 219 return r; 220 } 221 } 222 223 r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_5_0_1, ARRAY_SIZE(vcn_reg_list_5_0_1)); 224 if (r) 225 return r; 226 227 return amdgpu_vcn_sysfs_reset_mask_init(adev); 228 } 229 230 /** 231 * vcn_v5_0_1_sw_fini - sw fini for VCN block 232 * 233 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 234 * 235 * VCN suspend and free up sw allocation 236 */ 237 static int vcn_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block) 238 { 239 struct amdgpu_device *adev = ip_block->adev; 240 int i, r, idx; 241 242 if (drm_dev_enter(adev_to_drm(adev), &idx)) { 243 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 244 struct amdgpu_vcn5_fw_shared *fw_shared; 245 246 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 247 fw_shared->present_flag_0 = 0; 248 fw_shared->sq.is_enabled = 0; 249 } 250 251 drm_dev_exit(idx); 252 } 253 254 if (amdgpu_sriov_vf(adev)) 255 amdgpu_virt_free_mm_table(adev); 256 257 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 258 r = amdgpu_vcn_suspend(adev, i); 259 if (r) 260 return r; 261 } 262 263 amdgpu_vcn_sysfs_reset_mask_fini(adev); 264 265 for (i = 0; i < adev->vcn.num_vcn_inst; i++) 266 amdgpu_vcn_sw_fini(adev, i); 267 268 return 0; 269 } 270 271 static int vcn_v5_0_1_hw_init_inst(struct amdgpu_device *adev, int i) 272 { 273 struct amdgpu_ring *ring; 274 int vcn_inst; 275 276 vcn_inst = GET_INST(VCN, i); 277 ring = &adev->vcn.inst[i].ring_enc[0]; 278 279 if (ring->use_doorbell) 280 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 281 ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 282 11 * vcn_inst), 283 adev->vcn.inst[i].aid_id); 284 285 return 0; 286 } 287 288 /** 289 * vcn_v5_0_1_hw_init - start and test VCN block 290 * 291 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 292 * 293 * Initialize the hardware, boot up the VCPU and do some testing 294 */ 295 static int vcn_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block) 296 { 297 struct amdgpu_device *adev = ip_block->adev; 298 struct amdgpu_ring *ring; 299 int i, r; 300 301 if (amdgpu_sriov_vf(adev)) { 302 r = vcn_v5_0_1_start_sriov(adev); 303 if (r) 304 return r; 305 306 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 307 ring = &adev->vcn.inst[i].ring_enc[0]; 308 ring->wptr = 0; 309 ring->wptr_old = 0; 310 vcn_v5_0_1_unified_ring_set_wptr(ring); 311 ring->sched.ready = true; 312 } 313 } else { 314 if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100) 315 adev->vcn.caps |= AMDGPU_VCN_CAPS(RRMT_ENABLED); 316 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 317 ring = &adev->vcn.inst[i].ring_enc[0]; 318 vcn_v5_0_1_hw_init_inst(adev, i); 319 320 /* Re-init fw_shared, if required */ 321 vcn_v5_0_1_fw_shared_init(adev, i); 322 323 r = amdgpu_ring_test_helper(ring); 324 if (r) 325 return r; 326 } 327 } 328 329 return 0; 330 } 331 332 /** 333 * vcn_v5_0_1_hw_fini - stop the hardware block 334 * 335 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 336 * 337 * Stop the VCN block, mark ring as not ready any more 338 */ 339 static int vcn_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block) 340 { 341 struct amdgpu_device *adev = ip_block->adev; 342 int i; 343 344 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 345 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 346 347 cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work); 348 if (vinst->cur_state != AMD_PG_STATE_GATE) 349 vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); 350 } 351 352 if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN) && !amdgpu_sriov_vf(adev)) 353 amdgpu_irq_put(adev, &adev->vcn.inst->ras_poison_irq, 0); 354 355 return 0; 356 } 357 358 /** 359 * vcn_v5_0_1_suspend - suspend VCN block 360 * 361 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 362 * 363 * HW fini and suspend VCN block 364 */ 365 static int vcn_v5_0_1_suspend(struct amdgpu_ip_block *ip_block) 366 { 367 struct amdgpu_device *adev = ip_block->adev; 368 int r, i; 369 370 r = vcn_v5_0_1_hw_fini(ip_block); 371 if (r) 372 return r; 373 374 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 375 r = amdgpu_vcn_suspend(ip_block->adev, i); 376 if (r) 377 return r; 378 } 379 380 return r; 381 } 382 383 /** 384 * vcn_v5_0_1_resume - resume VCN block 385 * 386 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 387 * 388 * Resume firmware and hw init VCN block 389 */ 390 static int vcn_v5_0_1_resume(struct amdgpu_ip_block *ip_block) 391 { 392 struct amdgpu_device *adev = ip_block->adev; 393 int r, i; 394 395 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 396 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 397 398 if (amdgpu_in_reset(adev)) 399 vinst->cur_state = AMD_PG_STATE_GATE; 400 401 r = amdgpu_vcn_resume(ip_block->adev, i); 402 if (r) 403 return r; 404 } 405 406 r = vcn_v5_0_1_hw_init(ip_block); 407 408 return r; 409 } 410 411 /** 412 * vcn_v5_0_1_mc_resume - memory controller programming 413 * 414 * @vinst: VCN instance 415 * 416 * Let the VCN memory controller know it's offsets 417 */ 418 static void vcn_v5_0_1_mc_resume(struct amdgpu_vcn_inst *vinst) 419 { 420 struct amdgpu_device *adev = vinst->adev; 421 int inst = vinst->inst; 422 uint32_t offset, size, vcn_inst; 423 const struct common_firmware_header *hdr; 424 425 hdr = (const struct common_firmware_header *)adev->vcn.inst[inst].fw->data; 426 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 427 428 vcn_inst = GET_INST(VCN, inst); 429 /* cache window 0: fw */ 430 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 431 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 432 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo)); 433 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 434 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi)); 435 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0, 0); 436 offset = 0; 437 } else { 438 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 439 lower_32_bits(adev->vcn.inst[inst].gpu_addr)); 440 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 441 upper_32_bits(adev->vcn.inst[inst].gpu_addr)); 442 offset = size; 443 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0, 444 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 445 } 446 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE0, size); 447 448 /* cache window 1: stack */ 449 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 450 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset)); 451 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 452 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset)); 453 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET1, 0); 454 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE); 455 456 /* cache window 2: context */ 457 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 458 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 459 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 460 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 461 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET2, 0); 462 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE); 463 464 /* non-cache window */ 465 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW, 466 lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr)); 467 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH, 468 upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr)); 469 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_OFFSET0, 0); 470 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_SIZE0, 471 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared))); 472 } 473 474 /** 475 * vcn_v5_0_1_mc_resume_dpg_mode - memory controller programming for dpg mode 476 * 477 * @vinst: VCN instance 478 * @indirect: indirectly write sram 479 * 480 * Let the VCN memory controller know it's offsets with dpg mode 481 */ 482 static void vcn_v5_0_1_mc_resume_dpg_mode(struct amdgpu_vcn_inst *vinst, 483 bool indirect) 484 { 485 struct amdgpu_device *adev = vinst->adev; 486 int inst_idx = vinst->inst; 487 uint32_t offset, size; 488 const struct common_firmware_header *hdr; 489 490 hdr = (const struct common_firmware_header *)adev->vcn.inst[inst_idx].fw->data; 491 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 492 493 /* cache window 0: fw */ 494 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 495 if (!indirect) { 496 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 497 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 498 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + 499 inst_idx].tmr_mc_addr_lo), 0, indirect); 500 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 501 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 502 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + 503 inst_idx].tmr_mc_addr_hi), 0, indirect); 504 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 505 VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 506 } else { 507 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 508 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect); 509 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 510 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect); 511 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 512 VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 513 } 514 offset = 0; 515 } else { 516 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 517 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 518 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 519 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 520 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 521 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 522 offset = size; 523 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 524 VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 525 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect); 526 } 527 528 if (!indirect) 529 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 530 VCN, 0, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect); 531 else 532 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 533 VCN, 0, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect); 534 535 /* cache window 1: stack */ 536 if (!indirect) { 537 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 538 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 539 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 540 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 541 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 542 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 543 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 544 VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 545 } else { 546 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 547 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect); 548 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 549 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect); 550 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 551 VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 552 } 553 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 554 VCN, 0, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect); 555 556 /* cache window 2: context */ 557 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 558 VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 559 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + 560 AMDGPU_VCN_STACK_SIZE), 0, indirect); 561 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 562 VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 563 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + 564 AMDGPU_VCN_STACK_SIZE), 0, indirect); 565 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 566 VCN, 0, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect); 567 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 568 VCN, 0, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect); 569 570 /* non-cache window */ 571 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 572 VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 573 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 574 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 575 VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 576 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 577 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 578 VCN, 0, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect); 579 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 580 VCN, 0, regUVD_VCPU_NONCACHE_SIZE0), 581 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared)), 0, indirect); 582 583 /* VCN global tiling registers */ 584 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 585 VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect); 586 } 587 588 /** 589 * vcn_v5_0_1_disable_clock_gating - disable VCN clock gating 590 * 591 * @vinst: VCN instance 592 * 593 * Disable clock gating for VCN block 594 */ 595 static void vcn_v5_0_1_disable_clock_gating(struct amdgpu_vcn_inst *vinst) 596 { 597 } 598 599 /** 600 * vcn_v5_0_1_enable_clock_gating - enable VCN clock gating 601 * 602 * @vinst: VCN instance 603 * 604 * Enable clock gating for VCN block 605 */ 606 static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_vcn_inst *vinst) 607 { 608 } 609 610 /** 611 * vcn_v5_0_1_pause_dpg_mode - VCN pause with dpg mode 612 * 613 * @vinst: VCN instance 614 * @new_state: pause state 615 * 616 * Pause dpg mode for VCN block 617 */ 618 static int vcn_v5_0_1_pause_dpg_mode(struct amdgpu_vcn_inst *vinst, 619 struct dpg_pause_state *new_state) 620 { 621 struct amdgpu_device *adev = vinst->adev; 622 uint32_t reg_data = 0; 623 int vcn_inst; 624 625 vcn_inst = GET_INST(VCN, vinst->inst); 626 627 /* pause/unpause if state is changed */ 628 if (vinst->pause_state.fw_based != new_state->fw_based) { 629 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d %s\n", 630 vinst->pause_state.fw_based, new_state->fw_based, 631 new_state->fw_based ? "VCN_DPG_STATE__PAUSE" : "VCN_DPG_STATE__UNPAUSE"); 632 reg_data = RREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE) & 633 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 634 635 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { 636 /* pause DPG */ 637 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 638 WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data); 639 640 /* wait for ACK */ 641 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_DPG_PAUSE, 642 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, 643 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 644 } else { 645 /* unpause DPG, no need to wait */ 646 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 647 WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data); 648 } 649 vinst->pause_state.fw_based = new_state->fw_based; 650 } 651 652 return 0; 653 } 654 655 656 /** 657 * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode 658 * 659 * @vinst: VCN instance 660 * @indirect: indirectly write sram 661 * 662 * Start VCN block with dpg mode 663 */ 664 static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst, 665 bool indirect) 666 { 667 struct amdgpu_device *adev = vinst->adev; 668 int inst_idx = vinst->inst; 669 struct amdgpu_vcn5_fw_shared *fw_shared = 670 adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 671 struct amdgpu_ring *ring; 672 struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__PAUSE}; 673 int vcn_inst, ret; 674 uint32_t tmp; 675 676 vcn_inst = GET_INST(VCN, inst_idx); 677 678 /* disable register anti-hang mechanism */ 679 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 1, 680 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 681 682 /* enable dynamic power gating mode */ 683 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS); 684 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; 685 WREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS, tmp); 686 687 if (indirect) { 688 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = 689 (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; 690 /* Use dummy register 0xDEADBEEF passing AID selection to PSP FW */ 691 WREG32_SOC24_DPG_MODE(inst_idx, 0xDEADBEEF, 692 adev->vcn.inst[inst_idx].aid_id, 0, true); 693 } 694 695 /* enable VCPU clock */ 696 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 697 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK; 698 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 699 VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect); 700 701 /* disable master interrupt */ 702 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 703 VCN, 0, regUVD_MASTINT_EN), 0, 0, indirect); 704 705 /* setup regUVD_LMI_CTRL */ 706 tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 707 UVD_LMI_CTRL__REQ_MODE_MASK | 708 UVD_LMI_CTRL__CRC_RESET_MASK | 709 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 710 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 711 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 712 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 713 0x00100000L); 714 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 715 VCN, 0, regUVD_LMI_CTRL), tmp, 0, indirect); 716 717 vcn_v5_0_1_mc_resume_dpg_mode(vinst, indirect); 718 719 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 720 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 721 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 722 VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect); 723 724 /* enable LMI MC and UMC channels */ 725 tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT; 726 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 727 VCN, 0, regUVD_LMI_CTRL2), tmp, 0, indirect); 728 729 /* enable master interrupt */ 730 WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET( 731 VCN, 0, regUVD_MASTINT_EN), 732 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 733 734 if (indirect) { 735 ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM); 736 if (ret) { 737 dev_err(adev->dev, "vcn sram load failed %d\n", ret); 738 return ret; 739 } 740 } 741 742 /* resetting ring, fw should not check RB ring */ 743 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 744 745 /* Pause dpg */ 746 vcn_v5_0_1_pause_dpg_mode(vinst, &state); 747 748 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 749 750 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, lower_32_bits(ring->gpu_addr)); 751 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 752 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, ring->ring_size / sizeof(uint32_t)); 753 754 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 755 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 756 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 757 758 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0); 759 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0); 760 761 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR); 762 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, tmp); 763 ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR); 764 765 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 766 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 767 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 768 /* resetting done, fw can check RB ring */ 769 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 770 771 WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL, 772 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 773 VCN_RB1_DB_CTRL__EN_MASK); 774 /* Read DB_CTRL to flush the write DB_CTRL command. */ 775 RREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL); 776 777 return 0; 778 } 779 780 static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev) 781 { 782 int i, vcn_inst; 783 struct amdgpu_ring *ring_enc; 784 uint64_t cache_addr; 785 uint64_t rb_enc_addr; 786 uint64_t ctx_addr; 787 uint32_t param, resp, expected; 788 uint32_t offset, cache_size; 789 uint32_t tmp, timeout; 790 791 struct amdgpu_mm_table *table = &adev->virt.mm_table; 792 uint32_t *table_loc; 793 uint32_t table_size; 794 uint32_t size, size_dw; 795 uint32_t init_status; 796 uint32_t enabled_vcn; 797 798 struct mmsch_v5_0_cmd_direct_write 799 direct_wt = { {0} }; 800 struct mmsch_v5_0_cmd_direct_read_modify_write 801 direct_rd_mod_wt = { {0} }; 802 struct mmsch_v5_0_cmd_end end = { {0} }; 803 struct mmsch_v5_0_init_header header; 804 805 struct amdgpu_vcn5_fw_shared *fw_shared; 806 struct amdgpu_fw_shared_rb_setup *rb_setup; 807 808 direct_wt.cmd_header.command_type = 809 MMSCH_COMMAND__DIRECT_REG_WRITE; 810 direct_rd_mod_wt.cmd_header.command_type = 811 MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; 812 end.cmd_header.command_type = MMSCH_COMMAND__END; 813 814 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 815 vcn_inst = GET_INST(VCN, i); 816 817 vcn_v5_0_1_fw_shared_init(adev, vcn_inst); 818 819 memset(&header, 0, sizeof(struct mmsch_v5_0_init_header)); 820 header.version = MMSCH_VERSION; 821 header.total_size = sizeof(struct mmsch_v5_0_init_header) >> 2; 822 823 table_loc = (uint32_t *)table->cpu_addr; 824 table_loc += header.total_size; 825 826 table_size = 0; 827 828 MMSCH_V5_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, 0, regUVD_STATUS), 829 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY); 830 831 cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4); 832 833 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 834 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 835 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 836 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); 837 838 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 839 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 840 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); 841 842 offset = 0; 843 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 844 regUVD_VCPU_CACHE_OFFSET0), 0); 845 } else { 846 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 847 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 848 lower_32_bits(adev->vcn.inst[i].gpu_addr)); 849 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 850 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 851 upper_32_bits(adev->vcn.inst[i].gpu_addr)); 852 offset = cache_size; 853 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 854 regUVD_VCPU_CACHE_OFFSET0), 855 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 856 } 857 858 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 859 regUVD_VCPU_CACHE_SIZE0), 860 cache_size); 861 862 cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset; 863 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 864 regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), lower_32_bits(cache_addr)); 865 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 866 regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); 867 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 868 regUVD_VCPU_CACHE_OFFSET1), 0); 869 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 870 regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE); 871 872 cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset + 873 AMDGPU_VCN_STACK_SIZE; 874 875 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 876 regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), lower_32_bits(cache_addr)); 877 878 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 879 regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); 880 881 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 882 regUVD_VCPU_CACHE_OFFSET2), 0); 883 884 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 885 regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE); 886 887 fw_shared = adev->vcn.inst[vcn_inst].fw_shared.cpu_addr; 888 rb_setup = &fw_shared->rb_setup; 889 890 ring_enc = &adev->vcn.inst[vcn_inst].ring_enc[0]; 891 ring_enc->wptr = 0; 892 rb_enc_addr = ring_enc->gpu_addr; 893 894 rb_setup->is_rb_enabled_flags |= RB_ENABLED; 895 rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr); 896 rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr); 897 rb_setup->rb_size = ring_enc->ring_size / 4; 898 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); 899 900 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 901 regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 902 lower_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); 903 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 904 regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 905 upper_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); 906 MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 907 regUVD_VCPU_NONCACHE_SIZE0), 908 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); 909 MMSCH_V5_0_INSERT_END(); 910 911 header.vcn0.init_status = 0; 912 header.vcn0.table_offset = header.total_size; 913 header.vcn0.table_size = table_size; 914 header.total_size += table_size; 915 916 /* Send init table to mmsch */ 917 size = sizeof(struct mmsch_v5_0_init_header); 918 table_loc = (uint32_t *)table->cpu_addr; 919 memcpy((void *)table_loc, &header, size); 920 921 ctx_addr = table->gpu_addr; 922 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); 923 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); 924 925 tmp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID); 926 tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; 927 tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); 928 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID, tmp); 929 930 size = header.total_size; 931 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_SIZE, size); 932 933 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP, 0); 934 935 param = 0x00000001; 936 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_HOST, param); 937 tmp = 0; 938 timeout = 1000; 939 resp = 0; 940 expected = MMSCH_VF_MAILBOX_RESP__OK; 941 while (resp != expected) { 942 resp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP); 943 if (resp != 0) 944 break; 945 946 udelay(10); 947 tmp = tmp + 10; 948 if (tmp >= timeout) { 949 DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ 950 " waiting for regMMSCH_VF_MAILBOX_RESP "\ 951 "(expected=0x%08x, readback=0x%08x)\n", 952 tmp, expected, resp); 953 return -EBUSY; 954 } 955 } 956 957 enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0; 958 init_status = ((struct mmsch_v5_0_init_header *)(table_loc))->vcn0.init_status; 959 if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE 960 && init_status != MMSCH_VF_ENGINE_STATUS__PASS) { 961 DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\ 962 "status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status); 963 } 964 } 965 966 return 0; 967 } 968 969 /** 970 * vcn_v5_0_1_start - VCN start 971 * 972 * @vinst: VCN instance 973 * 974 * Start VCN block 975 */ 976 static int vcn_v5_0_1_start(struct amdgpu_vcn_inst *vinst) 977 { 978 struct amdgpu_device *adev = vinst->adev; 979 int i = vinst->inst; 980 struct amdgpu_vcn5_fw_shared *fw_shared; 981 struct amdgpu_ring *ring; 982 uint32_t tmp; 983 int j, k, r, vcn_inst; 984 985 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 986 987 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 988 return vcn_v5_0_1_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram); 989 990 vcn_inst = GET_INST(VCN, i); 991 992 /* set VCN status busy */ 993 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; 994 WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, tmp); 995 996 /* enable VCPU clock */ 997 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 998 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); 999 1000 /* disable master interrupt */ 1001 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 0, 1002 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1003 1004 /* enable LMI MC and UMC channels */ 1005 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_LMI_CTRL2), 0, 1006 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1007 1008 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET); 1009 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1010 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1011 WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp); 1012 1013 /* setup regUVD_LMI_CTRL */ 1014 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL); 1015 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL, tmp | 1016 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1017 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1018 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1019 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 1020 1021 vcn_v5_0_1_mc_resume(vinst); 1022 1023 /* VCN global tiling registers */ 1024 WREG32_SOC15(VCN, vcn_inst, regUVD_GFX10_ADDR_CONFIG, 1025 adev->gfx.config.gb_addr_config); 1026 1027 /* unblock VCPU register access */ 1028 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 0, 1029 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1030 1031 /* release VCPU reset to boot */ 1032 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0, 1033 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1034 1035 for (j = 0; j < 10; ++j) { 1036 uint32_t status; 1037 1038 for (k = 0; k < 100; ++k) { 1039 status = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); 1040 if (status & 2) 1041 break; 1042 mdelay(100); 1043 if (amdgpu_emu_mode == 1) 1044 msleep(20); 1045 } 1046 1047 if (amdgpu_emu_mode == 1) { 1048 r = -1; 1049 if (status & 2) { 1050 r = 0; 1051 break; 1052 } 1053 } else { 1054 r = 0; 1055 if (status & 2) 1056 break; 1057 1058 dev_err(adev->dev, 1059 "VCN[%d] is not responding, trying to reset the VCPU!!!\n", i); 1060 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 1061 UVD_VCPU_CNTL__BLK_RST_MASK, 1062 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1063 mdelay(10); 1064 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0, 1065 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1066 1067 mdelay(10); 1068 r = -1; 1069 } 1070 } 1071 1072 if (r) { 1073 dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i); 1074 return r; 1075 } 1076 1077 /* enable master interrupt */ 1078 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 1079 UVD_MASTINT_EN__VCPU_EN_MASK, 1080 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1081 1082 /* clear the busy bit of VCN_STATUS */ 1083 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_STATUS), 0, 1084 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 1085 1086 ring = &adev->vcn.inst[i].ring_enc[0]; 1087 1088 WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL, 1089 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 1090 VCN_RB1_DB_CTRL__EN_MASK); 1091 1092 /* Read DB_CTRL to flush the write DB_CTRL command. */ 1093 RREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL); 1094 1095 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, ring->gpu_addr); 1096 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1097 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, ring->ring_size / 4); 1098 1099 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 1100 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 1101 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 1102 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 1103 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0); 1104 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0); 1105 1106 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR); 1107 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, tmp); 1108 ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR); 1109 1110 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 1111 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 1112 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 1113 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 1114 1115 /* Keeping one read-back to ensure all register writes are done, 1116 * otherwise it may introduce race conditions. 1117 */ 1118 RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); 1119 1120 return 0; 1121 } 1122 1123 /** 1124 * vcn_v5_0_1_stop_dpg_mode - VCN stop with dpg mode 1125 * 1126 * @vinst: VCN instance 1127 * 1128 * Stop VCN block with dpg mode 1129 */ 1130 static void vcn_v5_0_1_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) 1131 { 1132 struct amdgpu_device *adev = vinst->adev; 1133 int inst_idx = vinst->inst; 1134 uint32_t tmp; 1135 int vcn_inst; 1136 struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE}; 1137 1138 vcn_inst = GET_INST(VCN, inst_idx); 1139 1140 /* Unpause dpg */ 1141 vcn_v5_0_1_pause_dpg_mode(vinst, &state); 1142 1143 /* Wait for power status to be 1 */ 1144 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1, 1145 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1146 1147 /* wait for read ptr to be equal to write ptr */ 1148 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR); 1149 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1150 1151 /* disable dynamic power gating mode */ 1152 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 0, 1153 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1154 1155 /* Keeping one read-back to ensure all register writes are done, 1156 * otherwise it may introduce race conditions. 1157 */ 1158 RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); 1159 } 1160 1161 /** 1162 * vcn_v5_0_1_stop - VCN stop 1163 * 1164 * @vinst: VCN instance 1165 * 1166 * Stop VCN block 1167 */ 1168 static int vcn_v5_0_1_stop(struct amdgpu_vcn_inst *vinst) 1169 { 1170 struct amdgpu_device *adev = vinst->adev; 1171 int i = vinst->inst; 1172 struct amdgpu_vcn5_fw_shared *fw_shared; 1173 uint32_t tmp; 1174 int r = 0, vcn_inst; 1175 1176 vcn_inst = GET_INST(VCN, i); 1177 1178 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1179 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; 1180 1181 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1182 vcn_v5_0_1_stop_dpg_mode(vinst); 1183 return 0; 1184 } 1185 1186 /* wait for vcn idle */ 1187 r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1188 if (r) 1189 return r; 1190 1191 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1192 UVD_LMI_STATUS__READ_CLEAN_MASK | 1193 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1194 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1195 r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, tmp); 1196 if (r) 1197 return r; 1198 1199 /* disable LMI UMC channel */ 1200 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2); 1201 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1202 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2, tmp); 1203 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | 1204 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1205 r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, tmp); 1206 if (r) 1207 return r; 1208 1209 /* block VCPU register access */ 1210 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 1211 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1212 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1213 1214 /* reset VCPU */ 1215 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 1216 UVD_VCPU_CNTL__BLK_RST_MASK, 1217 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1218 1219 /* disable VCPU clock */ 1220 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0, 1221 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1222 1223 /* apply soft reset */ 1224 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET); 1225 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1226 WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp); 1227 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET); 1228 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1229 WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp); 1230 1231 /* clear status */ 1232 WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0); 1233 1234 /* Keeping one read-back to ensure all register writes are done, 1235 * otherwise it may introduce race conditions. 1236 */ 1237 RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); 1238 1239 return 0; 1240 } 1241 1242 /** 1243 * vcn_v5_0_1_unified_ring_get_rptr - get unified read pointer 1244 * 1245 * @ring: amdgpu_ring pointer 1246 * 1247 * Returns the current hardware unified read pointer 1248 */ 1249 static uint64_t vcn_v5_0_1_unified_ring_get_rptr(struct amdgpu_ring *ring) 1250 { 1251 struct amdgpu_device *adev = ring->adev; 1252 1253 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1254 DRM_ERROR("wrong ring id is identified in %s", __func__); 1255 1256 return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_RPTR); 1257 } 1258 1259 /** 1260 * vcn_v5_0_1_unified_ring_get_wptr - get unified write pointer 1261 * 1262 * @ring: amdgpu_ring pointer 1263 * 1264 * Returns the current hardware unified write pointer 1265 */ 1266 static uint64_t vcn_v5_0_1_unified_ring_get_wptr(struct amdgpu_ring *ring) 1267 { 1268 struct amdgpu_device *adev = ring->adev; 1269 1270 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1271 DRM_ERROR("wrong ring id is identified in %s", __func__); 1272 1273 if (ring->use_doorbell) 1274 return *ring->wptr_cpu_addr; 1275 else 1276 return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR); 1277 } 1278 1279 /** 1280 * vcn_v5_0_1_unified_ring_set_wptr - set enc write pointer 1281 * 1282 * @ring: amdgpu_ring pointer 1283 * 1284 * Commits the enc write pointer to the hardware 1285 */ 1286 static void vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring *ring) 1287 { 1288 struct amdgpu_device *adev = ring->adev; 1289 1290 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1291 DRM_ERROR("wrong ring id is identified in %s", __func__); 1292 1293 if (ring->use_doorbell) { 1294 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1295 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1296 } else { 1297 WREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR, 1298 lower_32_bits(ring->wptr)); 1299 } 1300 } 1301 1302 static int vcn_v5_0_1_ring_reset(struct amdgpu_ring *ring, 1303 unsigned int vmid, 1304 struct amdgpu_fence *timedout_fence) 1305 { 1306 int r = 0; 1307 int vcn_inst; 1308 struct amdgpu_device *adev = ring->adev; 1309 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me]; 1310 1311 amdgpu_ring_reset_helper_begin(ring, timedout_fence); 1312 1313 vcn_inst = GET_INST(VCN, ring->me); 1314 r = amdgpu_dpm_reset_vcn(adev, 1 << vcn_inst); 1315 1316 if (r) { 1317 DRM_DEV_ERROR(adev->dev, "VCN reset fail : %d\n", r); 1318 return r; 1319 } 1320 1321 vcn_v5_0_1_hw_init_inst(adev, ring->me); 1322 vcn_v5_0_1_start_dpg_mode(vinst, vinst->indirect_sram); 1323 1324 return amdgpu_ring_reset_helper_end(ring, timedout_fence); 1325 } 1326 1327 static const struct amdgpu_ring_funcs vcn_v5_0_1_unified_ring_vm_funcs = { 1328 .type = AMDGPU_RING_TYPE_VCN_ENC, 1329 .align_mask = 0x3f, 1330 .nop = VCN_ENC_CMD_NO_OP, 1331 .get_rptr = vcn_v5_0_1_unified_ring_get_rptr, 1332 .get_wptr = vcn_v5_0_1_unified_ring_get_wptr, 1333 .set_wptr = vcn_v5_0_1_unified_ring_set_wptr, 1334 .emit_frame_size = SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1335 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1336 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1337 5 + 1338 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 1339 1, /* vcn_v2_0_enc_ring_insert_end */ 1340 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 1341 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 1342 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 1343 .emit_vm_flush = vcn_v4_0_3_enc_ring_emit_vm_flush, 1344 .emit_hdp_flush = vcn_v4_0_3_ring_emit_hdp_flush, 1345 .test_ring = amdgpu_vcn_enc_ring_test_ring, 1346 .test_ib = amdgpu_vcn_unified_ring_test_ib, 1347 .insert_nop = amdgpu_ring_insert_nop, 1348 .insert_end = vcn_v2_0_enc_ring_insert_end, 1349 .pad_ib = amdgpu_ring_generic_pad_ib, 1350 .begin_use = amdgpu_vcn_ring_begin_use, 1351 .end_use = amdgpu_vcn_ring_end_use, 1352 .emit_wreg = vcn_v4_0_3_enc_ring_emit_wreg, 1353 .emit_reg_wait = vcn_v4_0_3_enc_ring_emit_reg_wait, 1354 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1355 .reset = vcn_v5_0_1_ring_reset, 1356 }; 1357 1358 /** 1359 * vcn_v5_0_1_set_unified_ring_funcs - set unified ring functions 1360 * 1361 * @adev: amdgpu_device pointer 1362 * 1363 * Set unified ring functions 1364 */ 1365 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev) 1366 { 1367 int i, vcn_inst; 1368 1369 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1370 adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v5_0_1_unified_ring_vm_funcs; 1371 adev->vcn.inst[i].ring_enc[0].me = i; 1372 vcn_inst = GET_INST(VCN, i); 1373 adev->vcn.inst[i].aid_id = vcn_inst / adev->vcn.num_inst_per_aid; 1374 } 1375 } 1376 1377 /** 1378 * vcn_v5_0_1_is_idle - check VCN block is idle 1379 * 1380 * @ip_block: Pointer to the amdgpu_ip_block structure 1381 * 1382 * Check whether VCN block is idle 1383 */ 1384 static bool vcn_v5_0_1_is_idle(struct amdgpu_ip_block *ip_block) 1385 { 1386 struct amdgpu_device *adev = ip_block->adev; 1387 int i, ret = 1; 1388 1389 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) 1390 ret &= (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) == UVD_STATUS__IDLE); 1391 1392 return ret; 1393 } 1394 1395 /** 1396 * vcn_v5_0_1_wait_for_idle - wait for VCN block idle 1397 * 1398 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 1399 * 1400 * Wait for VCN block idle 1401 */ 1402 static int vcn_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block) 1403 { 1404 struct amdgpu_device *adev = ip_block->adev; 1405 int i, ret = 0; 1406 1407 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1408 ret = SOC15_WAIT_ON_RREG(VCN, GET_INST(VCN, i), regUVD_STATUS, UVD_STATUS__IDLE, 1409 UVD_STATUS__IDLE); 1410 if (ret) 1411 return ret; 1412 } 1413 1414 return ret; 1415 } 1416 1417 /** 1418 * vcn_v5_0_1_set_clockgating_state - set VCN block clockgating state 1419 * 1420 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 1421 * @state: clock gating state 1422 * 1423 * Set VCN block clockgating state 1424 */ 1425 static int vcn_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block, 1426 enum amd_clockgating_state state) 1427 { 1428 struct amdgpu_device *adev = ip_block->adev; 1429 bool enable = state == AMD_CG_STATE_GATE; 1430 int i; 1431 1432 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1433 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 1434 1435 if (enable) { 1436 if (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) != UVD_STATUS__IDLE) 1437 return -EBUSY; 1438 vcn_v5_0_1_enable_clock_gating(vinst); 1439 } else { 1440 vcn_v5_0_1_disable_clock_gating(vinst); 1441 } 1442 } 1443 1444 return 0; 1445 } 1446 1447 static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst, 1448 enum amd_powergating_state state) 1449 { 1450 struct amdgpu_device *adev = vinst->adev; 1451 int ret = 0; 1452 1453 /* for SRIOV, guest should not control VCN Power-gating 1454 * MMSCH FW should control Power-gating and clock-gating 1455 * guest should avoid touching CGC and PG 1456 */ 1457 if (amdgpu_sriov_vf(adev)) { 1458 vinst->cur_state = AMD_PG_STATE_UNGATE; 1459 return 0; 1460 } 1461 1462 if (state == vinst->cur_state) 1463 return 0; 1464 1465 if (state == AMD_PG_STATE_GATE) 1466 ret = vcn_v5_0_1_stop(vinst); 1467 else 1468 ret = vcn_v5_0_1_start(vinst); 1469 1470 if (!ret) 1471 vinst->cur_state = state; 1472 1473 return ret; 1474 } 1475 1476 /** 1477 * vcn_v5_0_1_process_interrupt - process VCN block interrupt 1478 * 1479 * @adev: amdgpu_device pointer 1480 * @source: interrupt sources 1481 * @entry: interrupt entry from clients and sources 1482 * 1483 * Process VCN block interrupt 1484 */ 1485 static int vcn_v5_0_1_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, 1486 struct amdgpu_iv_entry *entry) 1487 { 1488 uint32_t i, inst; 1489 1490 i = node_id_to_phys_map[entry->node_id]; 1491 1492 DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n"); 1493 1494 for (inst = 0; inst < adev->vcn.num_vcn_inst; ++inst) 1495 if (adev->vcn.inst[inst].aid_id == i) 1496 break; 1497 if (inst >= adev->vcn.num_vcn_inst) { 1498 dev_WARN_ONCE(adev->dev, 1, 1499 "Interrupt received for unknown VCN instance %d", 1500 entry->node_id); 1501 return 0; 1502 } 1503 1504 switch (entry->src_id) { 1505 case VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 1506 amdgpu_fence_process(&adev->vcn.inst[inst].ring_enc[0]); 1507 break; 1508 default: 1509 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 1510 entry->src_id, entry->src_data[0]); 1511 break; 1512 } 1513 1514 return 0; 1515 } 1516 1517 static int vcn_v5_0_1_set_ras_interrupt_state(struct amdgpu_device *adev, 1518 struct amdgpu_irq_src *source, 1519 unsigned int type, 1520 enum amdgpu_interrupt_state state) 1521 { 1522 return 0; 1523 } 1524 1525 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_irq_funcs = { 1526 .process = vcn_v5_0_1_process_interrupt, 1527 }; 1528 1529 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_ras_irq_funcs = { 1530 .set = vcn_v5_0_1_set_ras_interrupt_state, 1531 .process = amdgpu_vcn_process_poison_irq, 1532 }; 1533 1534 1535 /** 1536 * vcn_v5_0_1_set_irq_funcs - set VCN block interrupt irq functions 1537 * 1538 * @adev: amdgpu_device pointer 1539 * 1540 * Set VCN block interrupt irq functions 1541 */ 1542 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev) 1543 { 1544 int i; 1545 1546 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) 1547 adev->vcn.inst->irq.num_types++; 1548 1549 adev->vcn.inst->irq.funcs = &vcn_v5_0_1_irq_funcs; 1550 1551 adev->vcn.inst->ras_poison_irq.num_types = 1; 1552 adev->vcn.inst->ras_poison_irq.funcs = &vcn_v5_0_1_ras_irq_funcs; 1553 1554 } 1555 1556 static const struct amd_ip_funcs vcn_v5_0_1_ip_funcs = { 1557 .name = "vcn_v5_0_1", 1558 .early_init = vcn_v5_0_1_early_init, 1559 .late_init = vcn_v5_0_1_late_init, 1560 .sw_init = vcn_v5_0_1_sw_init, 1561 .sw_fini = vcn_v5_0_1_sw_fini, 1562 .hw_init = vcn_v5_0_1_hw_init, 1563 .hw_fini = vcn_v5_0_1_hw_fini, 1564 .suspend = vcn_v5_0_1_suspend, 1565 .resume = vcn_v5_0_1_resume, 1566 .is_idle = vcn_v5_0_1_is_idle, 1567 .wait_for_idle = vcn_v5_0_1_wait_for_idle, 1568 .check_soft_reset = NULL, 1569 .pre_soft_reset = NULL, 1570 .soft_reset = NULL, 1571 .post_soft_reset = NULL, 1572 .set_clockgating_state = vcn_v5_0_1_set_clockgating_state, 1573 .set_powergating_state = vcn_set_powergating_state, 1574 .dump_ip_state = amdgpu_vcn_dump_ip_state, 1575 .print_ip_state = amdgpu_vcn_print_ip_state, 1576 }; 1577 1578 const struct amdgpu_ip_block_version vcn_v5_0_1_ip_block = { 1579 .type = AMD_IP_BLOCK_TYPE_VCN, 1580 .major = 5, 1581 .minor = 0, 1582 .rev = 1, 1583 .funcs = &vcn_v5_0_1_ip_funcs, 1584 }; 1585 1586 static uint32_t vcn_v5_0_1_query_poison_by_instance(struct amdgpu_device *adev, 1587 uint32_t instance, uint32_t sub_block) 1588 { 1589 uint32_t poison_stat = 0, reg_value = 0; 1590 1591 switch (sub_block) { 1592 case AMDGPU_VCN_V5_0_1_VCPU_VCODEC: 1593 reg_value = RREG32_SOC15(VCN, instance, regUVD_RAS_VCPU_VCODEC_STATUS); 1594 poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF); 1595 break; 1596 default: 1597 break; 1598 } 1599 1600 if (poison_stat) 1601 dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n", 1602 instance, sub_block); 1603 1604 return poison_stat; 1605 } 1606 1607 static bool vcn_v5_0_1_query_poison_status(struct amdgpu_device *adev) 1608 { 1609 uint32_t inst, sub; 1610 uint32_t poison_stat = 0; 1611 1612 for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++) 1613 for (sub = 0; sub < AMDGPU_VCN_V5_0_1_MAX_SUB_BLOCK; sub++) 1614 poison_stat += 1615 vcn_v5_0_1_query_poison_by_instance(adev, inst, sub); 1616 1617 return !!poison_stat; 1618 } 1619 1620 static const struct amdgpu_ras_block_hw_ops vcn_v5_0_1_ras_hw_ops = { 1621 .query_poison_status = vcn_v5_0_1_query_poison_status, 1622 }; 1623 1624 static int vcn_v5_0_1_aca_bank_parser(struct aca_handle *handle, struct aca_bank *bank, 1625 enum aca_smu_type type, void *data) 1626 { 1627 struct aca_bank_info info; 1628 u64 misc0; 1629 int ret; 1630 1631 ret = aca_bank_info_decode(bank, &info); 1632 if (ret) 1633 return ret; 1634 1635 misc0 = bank->regs[ACA_REG_IDX_MISC0]; 1636 switch (type) { 1637 case ACA_SMU_TYPE_UE: 1638 bank->aca_err_type = ACA_ERROR_TYPE_UE; 1639 ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE, 1640 1ULL); 1641 break; 1642 case ACA_SMU_TYPE_CE: 1643 bank->aca_err_type = ACA_ERROR_TYPE_CE; 1644 ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type, 1645 ACA_REG__MISC0__ERRCNT(misc0)); 1646 break; 1647 default: 1648 return -EINVAL; 1649 } 1650 1651 return ret; 1652 } 1653 1654 /* reference to smu driver if header file */ 1655 static int vcn_v5_0_1_err_codes[] = { 1656 14, 15, 47, /* VCN [D|V|S] */ 1657 }; 1658 1659 static bool vcn_v5_0_1_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, 1660 enum aca_smu_type type, void *data) 1661 { 1662 u32 instlo; 1663 1664 instlo = ACA_REG__IPID__INSTANCEIDLO(bank->regs[ACA_REG_IDX_IPID]); 1665 instlo &= GENMASK(31, 1); 1666 1667 if (instlo != mmSMNAID_AID0_MCA_SMU) 1668 return false; 1669 1670 if (aca_bank_check_error_codes(handle->adev, bank, 1671 vcn_v5_0_1_err_codes, 1672 ARRAY_SIZE(vcn_v5_0_1_err_codes))) 1673 return false; 1674 1675 return true; 1676 } 1677 1678 static const struct aca_bank_ops vcn_v5_0_1_aca_bank_ops = { 1679 .aca_bank_parser = vcn_v5_0_1_aca_bank_parser, 1680 .aca_bank_is_valid = vcn_v5_0_1_aca_bank_is_valid, 1681 }; 1682 1683 static const struct aca_info vcn_v5_0_1_aca_info = { 1684 .hwip = ACA_HWIP_TYPE_SMU, 1685 .mask = ACA_ERROR_UE_MASK, 1686 .bank_ops = &vcn_v5_0_1_aca_bank_ops, 1687 }; 1688 1689 static int vcn_v5_0_1_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block) 1690 { 1691 int r; 1692 1693 r = amdgpu_ras_block_late_init(adev, ras_block); 1694 if (r) 1695 return r; 1696 1697 r = amdgpu_ras_bind_aca(adev, AMDGPU_RAS_BLOCK__VCN, 1698 &vcn_v5_0_1_aca_info, NULL); 1699 if (r) 1700 goto late_fini; 1701 1702 if (amdgpu_ras_is_supported(adev, ras_block->block) && 1703 adev->vcn.inst->ras_poison_irq.funcs) { 1704 r = amdgpu_irq_get(adev, &adev->vcn.inst->ras_poison_irq, 0); 1705 if (r) 1706 goto late_fini; 1707 } 1708 1709 return 0; 1710 1711 late_fini: 1712 amdgpu_ras_block_late_fini(adev, ras_block); 1713 1714 return r; 1715 } 1716 1717 static struct amdgpu_vcn_ras vcn_v5_0_1_ras = { 1718 .ras_block = { 1719 .hw_ops = &vcn_v5_0_1_ras_hw_ops, 1720 .ras_late_init = vcn_v5_0_1_ras_late_init, 1721 }, 1722 }; 1723 1724 static void vcn_v5_0_1_set_ras_funcs(struct amdgpu_device *adev) 1725 { 1726 adev->vcn.ras = &vcn_v5_0_1_ras; 1727 } 1728