1 /* 2 * Copyright 2022 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 <drm/drm_drv.h> 26 27 #include "amdgpu.h" 28 #include "amdgpu_vcn.h" 29 #include "amdgpu_pm.h" 30 #include "soc15.h" 31 #include "soc15d.h" 32 #include "soc15_hw_ip.h" 33 #include "vcn_v2_0.h" 34 #include "mmsch_v4_0_3.h" 35 36 #include "vcn/vcn_4_0_3_offset.h" 37 #include "vcn/vcn_4_0_3_sh_mask.h" 38 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h" 39 40 #define mmUVD_DPG_LMA_CTL regUVD_DPG_LMA_CTL 41 #define mmUVD_DPG_LMA_CTL_BASE_IDX regUVD_DPG_LMA_CTL_BASE_IDX 42 #define mmUVD_DPG_LMA_DATA regUVD_DPG_LMA_DATA 43 #define mmUVD_DPG_LMA_DATA_BASE_IDX regUVD_DPG_LMA_DATA_BASE_IDX 44 45 #define VCN_VID_SOC_ADDRESS_2_0 0x1fb00 46 #define VCN1_VID_SOC_ADDRESS_3_0 0x48300 47 48 static const struct amdgpu_hwip_reg_entry vcn_reg_list_4_0_3[] = { 49 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS), 50 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS), 51 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID), 52 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2), 53 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0), 54 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1), 55 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD), 56 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI), 57 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO), 58 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2), 59 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2), 60 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3), 61 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3), 62 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4), 63 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4), 64 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR), 65 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR), 66 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2), 67 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2), 68 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3), 69 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3), 70 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4), 71 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4), 72 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE), 73 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2), 74 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3), 75 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4), 76 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_CONFIG), 77 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_STATUS), 78 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL), 79 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA), 80 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK), 81 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE) 82 }; 83 84 #define NORMALIZE_VCN_REG_OFFSET(offset) \ 85 (offset & 0x1FFFF) 86 87 static int vcn_v4_0_3_start_sriov(struct amdgpu_device *adev); 88 static void vcn_v4_0_3_set_unified_ring_funcs(struct amdgpu_device *adev); 89 static void vcn_v4_0_3_set_irq_funcs(struct amdgpu_device *adev); 90 static int vcn_v4_0_3_set_powergating_state(void *handle, 91 enum amd_powergating_state state); 92 static int vcn_v4_0_3_pause_dpg_mode(struct amdgpu_device *adev, 93 int inst_idx, struct dpg_pause_state *new_state); 94 static void vcn_v4_0_3_unified_ring_set_wptr(struct amdgpu_ring *ring); 95 static void vcn_v4_0_3_set_ras_funcs(struct amdgpu_device *adev); 96 static void vcn_v4_0_3_enable_ras(struct amdgpu_device *adev, 97 int inst_idx, bool indirect); 98 99 static inline bool vcn_v4_0_3_normalizn_reqd(struct amdgpu_device *adev) 100 { 101 return (amdgpu_sriov_vf(adev) || 102 (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4))); 103 } 104 105 /** 106 * vcn_v4_0_3_early_init - set function pointers 107 * 108 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 109 * 110 * Set ring and irq function pointers 111 */ 112 static int vcn_v4_0_3_early_init(struct amdgpu_ip_block *ip_block) 113 { 114 struct amdgpu_device *adev = ip_block->adev; 115 116 /* re-use enc ring as unified ring */ 117 adev->vcn.num_enc_rings = 1; 118 119 vcn_v4_0_3_set_unified_ring_funcs(adev); 120 vcn_v4_0_3_set_irq_funcs(adev); 121 vcn_v4_0_3_set_ras_funcs(adev); 122 123 return amdgpu_vcn_early_init(adev); 124 } 125 126 /** 127 * vcn_v4_0_3_sw_init - sw init for VCN block 128 * 129 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 130 * 131 * Load firmware and sw initialization 132 */ 133 static int vcn_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block) 134 { 135 struct amdgpu_device *adev = ip_block->adev; 136 struct amdgpu_ring *ring; 137 int i, r, vcn_inst; 138 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); 139 uint32_t *ptr; 140 141 r = amdgpu_vcn_sw_init(adev); 142 if (r) 143 return r; 144 145 amdgpu_vcn_setup_ucode(adev); 146 147 r = amdgpu_vcn_resume(adev); 148 if (r) 149 return r; 150 151 /* VCN DEC TRAP */ 152 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 153 VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst->irq); 154 if (r) 155 return r; 156 157 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 158 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 159 160 vcn_inst = GET_INST(VCN, i); 161 162 ring = &adev->vcn.inst[i].ring_enc[0]; 163 ring->use_doorbell = true; 164 165 if (!amdgpu_sriov_vf(adev)) 166 ring->doorbell_index = 167 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 168 9 * vcn_inst; 169 else 170 ring->doorbell_index = 171 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 172 32 * vcn_inst; 173 174 ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id); 175 sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id); 176 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0, 177 AMDGPU_RING_PRIO_DEFAULT, 178 &adev->vcn.inst[i].sched_score); 179 if (r) 180 return r; 181 182 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 183 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); 184 fw_shared->sq.is_enabled = true; 185 186 if (amdgpu_vcnfw_log) 187 amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); 188 } 189 190 if (amdgpu_sriov_vf(adev)) { 191 r = amdgpu_virt_alloc_mm_table(adev); 192 if (r) 193 return r; 194 } 195 196 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 197 adev->vcn.pause_dpg_mode = vcn_v4_0_3_pause_dpg_mode; 198 199 if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) { 200 r = amdgpu_vcn_ras_sw_init(adev); 201 if (r) { 202 dev_err(adev->dev, "Failed to initialize vcn ras block!\n"); 203 return r; 204 } 205 } 206 207 /* Allocate memory for VCN IP Dump buffer */ 208 ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 209 if (!ptr) { 210 DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 211 adev->vcn.ip_dump = NULL; 212 } else { 213 adev->vcn.ip_dump = ptr; 214 } 215 216 return 0; 217 } 218 219 /** 220 * vcn_v4_0_3_sw_fini - sw fini for VCN block 221 * 222 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 223 * 224 * VCN suspend and free up sw allocation 225 */ 226 static int vcn_v4_0_3_sw_fini(struct amdgpu_ip_block *ip_block) 227 { 228 struct amdgpu_device *adev = ip_block->adev; 229 int i, r, idx; 230 231 if (drm_dev_enter(&adev->ddev, &idx)) { 232 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 233 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 234 235 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 236 fw_shared->present_flag_0 = 0; 237 fw_shared->sq.is_enabled = cpu_to_le32(false); 238 } 239 drm_dev_exit(idx); 240 } 241 242 if (amdgpu_sriov_vf(adev)) 243 amdgpu_virt_free_mm_table(adev); 244 245 r = amdgpu_vcn_suspend(adev); 246 if (r) 247 return r; 248 249 r = amdgpu_vcn_sw_fini(adev); 250 251 kfree(adev->vcn.ip_dump); 252 253 return r; 254 } 255 256 /** 257 * vcn_v4_0_3_hw_init - start and test VCN block 258 * 259 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 260 * 261 * Initialize the hardware, boot up the VCPU and do some testing 262 */ 263 static int vcn_v4_0_3_hw_init(struct amdgpu_ip_block *ip_block) 264 { 265 struct amdgpu_device *adev = ip_block->adev; 266 struct amdgpu_ring *ring; 267 int i, r, vcn_inst; 268 269 if (amdgpu_sriov_vf(adev)) { 270 r = vcn_v4_0_3_start_sriov(adev); 271 if (r) 272 return r; 273 274 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 275 ring = &adev->vcn.inst[i].ring_enc[0]; 276 ring->wptr = 0; 277 ring->wptr_old = 0; 278 vcn_v4_0_3_unified_ring_set_wptr(ring); 279 ring->sched.ready = true; 280 } 281 } else { 282 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 283 vcn_inst = GET_INST(VCN, i); 284 ring = &adev->vcn.inst[i].ring_enc[0]; 285 286 if (ring->use_doorbell) { 287 adev->nbio.funcs->vcn_doorbell_range( 288 adev, ring->use_doorbell, 289 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 290 9 * vcn_inst, 291 adev->vcn.inst[i].aid_id); 292 293 WREG32_SOC15( 294 VCN, GET_INST(VCN, ring->me), 295 regVCN_RB1_DB_CTRL, 296 ring->doorbell_index 297 << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 298 VCN_RB1_DB_CTRL__EN_MASK); 299 300 /* Read DB_CTRL to flush the write DB_CTRL command. */ 301 RREG32_SOC15( 302 VCN, GET_INST(VCN, ring->me), 303 regVCN_RB1_DB_CTRL); 304 } 305 306 r = amdgpu_ring_test_helper(ring); 307 if (r) 308 return r; 309 } 310 } 311 312 return r; 313 } 314 315 /** 316 * vcn_v4_0_3_hw_fini - stop the hardware block 317 * 318 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 319 * 320 * Stop the VCN block, mark ring as not ready any more 321 */ 322 static int vcn_v4_0_3_hw_fini(struct amdgpu_ip_block *ip_block) 323 { 324 struct amdgpu_device *adev = ip_block->adev; 325 326 cancel_delayed_work_sync(&adev->vcn.idle_work); 327 328 if (adev->vcn.cur_state != AMD_PG_STATE_GATE) 329 vcn_v4_0_3_set_powergating_state(adev, AMD_PG_STATE_GATE); 330 331 return 0; 332 } 333 334 /** 335 * vcn_v4_0_3_suspend - suspend VCN block 336 * 337 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 338 * 339 * HW fini and suspend VCN block 340 */ 341 static int vcn_v4_0_3_suspend(struct amdgpu_ip_block *ip_block) 342 { 343 int r; 344 345 r = vcn_v4_0_3_hw_fini(ip_block); 346 if (r) 347 return r; 348 349 r = amdgpu_vcn_suspend(ip_block->adev); 350 351 return r; 352 } 353 354 /** 355 * vcn_v4_0_3_resume - resume VCN block 356 * 357 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 358 * 359 * Resume firmware and hw init VCN block 360 */ 361 static int vcn_v4_0_3_resume(struct amdgpu_ip_block *ip_block) 362 { 363 int r; 364 365 r = amdgpu_vcn_resume(ip_block->adev); 366 if (r) 367 return r; 368 369 r = vcn_v4_0_3_hw_init(ip_block); 370 371 return r; 372 } 373 374 /** 375 * vcn_v4_0_3_mc_resume - memory controller programming 376 * 377 * @adev: amdgpu_device pointer 378 * @inst_idx: instance number 379 * 380 * Let the VCN memory controller know it's offsets 381 */ 382 static void vcn_v4_0_3_mc_resume(struct amdgpu_device *adev, int inst_idx) 383 { 384 uint32_t offset, size, vcn_inst; 385 const struct common_firmware_header *hdr; 386 387 hdr = (const struct common_firmware_header *)adev->vcn.fw[inst_idx]->data; 388 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 389 390 vcn_inst = GET_INST(VCN, inst_idx); 391 /* cache window 0: fw */ 392 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 393 WREG32_SOC15( 394 VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 395 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx] 396 .tmr_mc_addr_lo)); 397 WREG32_SOC15( 398 VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 399 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx] 400 .tmr_mc_addr_hi)); 401 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0, 0); 402 offset = 0; 403 } else { 404 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 405 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr)); 406 WREG32_SOC15(VCN, vcn_inst, 407 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 408 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr)); 409 offset = size; 410 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0, 411 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 412 } 413 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE0, size); 414 415 /* cache window 1: stack */ 416 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 417 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset)); 418 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 419 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset)); 420 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET1, 0); 421 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE1, 422 AMDGPU_VCN_STACK_SIZE); 423 424 /* cache window 2: context */ 425 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 426 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + 427 AMDGPU_VCN_STACK_SIZE)); 428 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 429 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + 430 AMDGPU_VCN_STACK_SIZE)); 431 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET2, 0); 432 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE2, 433 AMDGPU_VCN_CONTEXT_SIZE); 434 435 /* non-cache window */ 436 WREG32_SOC15( 437 VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW, 438 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr)); 439 WREG32_SOC15( 440 VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH, 441 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr)); 442 WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_OFFSET0, 0); 443 WREG32_SOC15( 444 VCN, vcn_inst, regUVD_VCPU_NONCACHE_SIZE0, 445 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); 446 } 447 448 /** 449 * vcn_v4_0_3_mc_resume_dpg_mode - memory controller programming for dpg mode 450 * 451 * @adev: amdgpu_device pointer 452 * @inst_idx: instance number index 453 * @indirect: indirectly write sram 454 * 455 * Let the VCN memory controller know it's offsets with dpg mode 456 */ 457 static void vcn_v4_0_3_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 458 { 459 uint32_t offset, size; 460 const struct common_firmware_header *hdr; 461 462 hdr = (const struct common_firmware_header *)adev->vcn.fw[inst_idx]->data; 463 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 464 465 /* cache window 0: fw */ 466 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 467 if (!indirect) { 468 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 469 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 470 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + 471 inst_idx].tmr_mc_addr_lo), 0, indirect); 472 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 473 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 474 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + 475 inst_idx].tmr_mc_addr_hi), 0, indirect); 476 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 477 VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 478 } else { 479 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 480 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect); 481 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 482 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect); 483 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 484 VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 485 } 486 offset = 0; 487 } else { 488 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 489 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 490 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 491 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 492 VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 493 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 494 offset = size; 495 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 496 VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 497 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect); 498 } 499 500 if (!indirect) 501 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 502 VCN, 0, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect); 503 else 504 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 505 VCN, 0, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect); 506 507 /* cache window 1: stack */ 508 if (!indirect) { 509 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 510 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 511 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 512 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 513 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 514 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 515 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 516 VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 517 } else { 518 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 519 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect); 520 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 521 VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect); 522 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 523 VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 524 } 525 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 526 VCN, 0, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect); 527 528 /* cache window 2: context */ 529 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 530 VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 531 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + 532 AMDGPU_VCN_STACK_SIZE), 0, indirect); 533 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 534 VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 535 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + 536 AMDGPU_VCN_STACK_SIZE), 0, indirect); 537 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 538 VCN, 0, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect); 539 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 540 VCN, 0, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect); 541 542 /* non-cache window */ 543 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 544 VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 545 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 546 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 547 VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 548 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 549 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 550 VCN, 0, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect); 551 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 552 VCN, 0, regUVD_VCPU_NONCACHE_SIZE0), 553 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect); 554 555 /* VCN global tiling registers */ 556 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 557 VCN, 0, regUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect); 558 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 559 VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect); 560 } 561 562 /** 563 * vcn_v4_0_3_disable_clock_gating - disable VCN clock gating 564 * 565 * @adev: amdgpu_device pointer 566 * @inst_idx: instance number 567 * 568 * Disable clock gating for VCN block 569 */ 570 static void vcn_v4_0_3_disable_clock_gating(struct amdgpu_device *adev, int inst_idx) 571 { 572 uint32_t data; 573 int vcn_inst; 574 575 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 576 return; 577 578 vcn_inst = GET_INST(VCN, inst_idx); 579 580 /* VCN disable CGC */ 581 data = RREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL); 582 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; 583 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 584 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 585 WREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL, data); 586 587 data = RREG32_SOC15(VCN, vcn_inst, regUVD_CGC_GATE); 588 data &= ~(UVD_CGC_GATE__SYS_MASK 589 | UVD_CGC_GATE__MPEG2_MASK 590 | UVD_CGC_GATE__REGS_MASK 591 | UVD_CGC_GATE__RBC_MASK 592 | UVD_CGC_GATE__LMI_MC_MASK 593 | UVD_CGC_GATE__LMI_UMC_MASK 594 | UVD_CGC_GATE__MPC_MASK 595 | UVD_CGC_GATE__LBSI_MASK 596 | UVD_CGC_GATE__LRBBM_MASK 597 | UVD_CGC_GATE__WCB_MASK 598 | UVD_CGC_GATE__VCPU_MASK 599 | UVD_CGC_GATE__MMSCH_MASK); 600 601 WREG32_SOC15(VCN, vcn_inst, regUVD_CGC_GATE, data); 602 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_CGC_GATE, 0, 0xFFFFFFFF); 603 604 data = RREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL); 605 data &= ~(UVD_CGC_CTRL__SYS_MODE_MASK 606 | UVD_CGC_CTRL__MPEG2_MODE_MASK 607 | UVD_CGC_CTRL__REGS_MODE_MASK 608 | UVD_CGC_CTRL__RBC_MODE_MASK 609 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 610 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 611 | UVD_CGC_CTRL__MPC_MODE_MASK 612 | UVD_CGC_CTRL__LBSI_MODE_MASK 613 | UVD_CGC_CTRL__LRBBM_MODE_MASK 614 | UVD_CGC_CTRL__WCB_MODE_MASK 615 | UVD_CGC_CTRL__VCPU_MODE_MASK 616 | UVD_CGC_CTRL__MMSCH_MODE_MASK); 617 WREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL, data); 618 619 data = RREG32_SOC15(VCN, vcn_inst, regUVD_SUVD_CGC_GATE); 620 data |= (UVD_SUVD_CGC_GATE__SRE_MASK 621 | UVD_SUVD_CGC_GATE__SIT_MASK 622 | UVD_SUVD_CGC_GATE__SMP_MASK 623 | UVD_SUVD_CGC_GATE__SCM_MASK 624 | UVD_SUVD_CGC_GATE__SDB_MASK 625 | UVD_SUVD_CGC_GATE__SRE_H264_MASK 626 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK 627 | UVD_SUVD_CGC_GATE__SIT_H264_MASK 628 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK 629 | UVD_SUVD_CGC_GATE__SCM_H264_MASK 630 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK 631 | UVD_SUVD_CGC_GATE__SDB_H264_MASK 632 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK 633 | UVD_SUVD_CGC_GATE__ENT_MASK 634 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK 635 | UVD_SUVD_CGC_GATE__SITE_MASK 636 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK 637 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK 638 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK 639 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK 640 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK); 641 WREG32_SOC15(VCN, vcn_inst, regUVD_SUVD_CGC_GATE, data); 642 643 data = RREG32_SOC15(VCN, vcn_inst, regUVD_SUVD_CGC_CTRL); 644 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 645 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 646 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 647 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 648 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 649 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 650 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 651 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 652 WREG32_SOC15(VCN, vcn_inst, regUVD_SUVD_CGC_CTRL, data); 653 } 654 655 /** 656 * vcn_v4_0_3_disable_clock_gating_dpg_mode - disable VCN clock gating dpg mode 657 * 658 * @adev: amdgpu_device pointer 659 * @sram_sel: sram select 660 * @inst_idx: instance number index 661 * @indirect: indirectly write sram 662 * 663 * Disable clock gating for VCN block with dpg mode 664 */ 665 static void vcn_v4_0_3_disable_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel, 666 int inst_idx, uint8_t indirect) 667 { 668 uint32_t reg_data = 0; 669 670 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 671 return; 672 673 /* enable sw clock gating control */ 674 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 675 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 676 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 677 reg_data &= ~(UVD_CGC_CTRL__SYS_MODE_MASK | 678 UVD_CGC_CTRL__MPEG2_MODE_MASK | 679 UVD_CGC_CTRL__REGS_MODE_MASK | 680 UVD_CGC_CTRL__RBC_MODE_MASK | 681 UVD_CGC_CTRL__LMI_MC_MODE_MASK | 682 UVD_CGC_CTRL__LMI_UMC_MODE_MASK | 683 UVD_CGC_CTRL__IDCT_MODE_MASK | 684 UVD_CGC_CTRL__MPRD_MODE_MASK | 685 UVD_CGC_CTRL__MPC_MODE_MASK | 686 UVD_CGC_CTRL__LBSI_MODE_MASK | 687 UVD_CGC_CTRL__LRBBM_MODE_MASK | 688 UVD_CGC_CTRL__WCB_MODE_MASK | 689 UVD_CGC_CTRL__VCPU_MODE_MASK); 690 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 691 VCN, 0, regUVD_CGC_CTRL), reg_data, sram_sel, indirect); 692 693 /* turn off clock gating */ 694 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 695 VCN, 0, regUVD_CGC_GATE), 0, sram_sel, indirect); 696 697 /* turn on SUVD clock gating */ 698 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 699 VCN, 0, regUVD_SUVD_CGC_GATE), 1, sram_sel, indirect); 700 701 /* turn on sw mode in UVD_SUVD_CGC_CTRL */ 702 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 703 VCN, 0, regUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect); 704 } 705 706 /** 707 * vcn_v4_0_3_enable_clock_gating - enable VCN clock gating 708 * 709 * @adev: amdgpu_device pointer 710 * @inst_idx: instance number 711 * 712 * Enable clock gating for VCN block 713 */ 714 static void vcn_v4_0_3_enable_clock_gating(struct amdgpu_device *adev, int inst_idx) 715 { 716 uint32_t data; 717 int vcn_inst; 718 719 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 720 return; 721 722 vcn_inst = GET_INST(VCN, inst_idx); 723 724 /* enable VCN CGC */ 725 data = RREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL); 726 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 727 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 728 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 729 WREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL, data); 730 731 data = RREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL); 732 data |= (UVD_CGC_CTRL__SYS_MODE_MASK 733 | UVD_CGC_CTRL__MPEG2_MODE_MASK 734 | UVD_CGC_CTRL__REGS_MODE_MASK 735 | UVD_CGC_CTRL__RBC_MODE_MASK 736 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 737 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 738 | UVD_CGC_CTRL__MPC_MODE_MASK 739 | UVD_CGC_CTRL__LBSI_MODE_MASK 740 | UVD_CGC_CTRL__LRBBM_MODE_MASK 741 | UVD_CGC_CTRL__WCB_MODE_MASK 742 | UVD_CGC_CTRL__VCPU_MODE_MASK); 743 WREG32_SOC15(VCN, vcn_inst, regUVD_CGC_CTRL, data); 744 745 data = RREG32_SOC15(VCN, vcn_inst, regUVD_SUVD_CGC_CTRL); 746 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 747 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 748 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 749 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 750 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 751 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 752 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 753 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 754 WREG32_SOC15(VCN, vcn_inst, regUVD_SUVD_CGC_CTRL, data); 755 } 756 757 /** 758 * vcn_v4_0_3_start_dpg_mode - VCN start with dpg mode 759 * 760 * @adev: amdgpu_device pointer 761 * @inst_idx: instance number index 762 * @indirect: indirectly write sram 763 * 764 * Start VCN block with dpg mode 765 */ 766 static int vcn_v4_0_3_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 767 { 768 volatile struct amdgpu_vcn4_fw_shared *fw_shared = 769 adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 770 struct amdgpu_ring *ring; 771 int vcn_inst; 772 uint32_t tmp; 773 774 vcn_inst = GET_INST(VCN, inst_idx); 775 /* disable register anti-hang mechanism */ 776 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 1, 777 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 778 /* enable dynamic power gating mode */ 779 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS); 780 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; 781 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK; 782 WREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS, tmp); 783 784 if (indirect) { 785 DRM_DEV_DEBUG(adev->dev, "VCN %d start: on AID %d", 786 inst_idx, adev->vcn.inst[inst_idx].aid_id); 787 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = 788 (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; 789 /* Use dummy register 0xDEADBEEF passing AID selection to PSP FW */ 790 WREG32_SOC15_DPG_MODE(inst_idx, 0xDEADBEEF, 791 adev->vcn.inst[inst_idx].aid_id, 0, true); 792 } 793 794 /* enable clock gating */ 795 vcn_v4_0_3_disable_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); 796 797 /* enable VCPU clock */ 798 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 799 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 800 tmp |= UVD_VCPU_CNTL__BLK_RST_MASK; 801 802 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 803 VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect); 804 805 /* disable master interrupt */ 806 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 807 VCN, 0, regUVD_MASTINT_EN), 0, 0, indirect); 808 809 /* setup regUVD_LMI_CTRL */ 810 tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 811 UVD_LMI_CTRL__REQ_MODE_MASK | 812 UVD_LMI_CTRL__CRC_RESET_MASK | 813 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 814 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 815 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 816 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 817 0x00100000L); 818 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 819 VCN, 0, regUVD_LMI_CTRL), tmp, 0, indirect); 820 821 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 822 VCN, 0, regUVD_MPC_CNTL), 823 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect); 824 825 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 826 VCN, 0, regUVD_MPC_SET_MUXA0), 827 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 828 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 829 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 830 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect); 831 832 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 833 VCN, 0, regUVD_MPC_SET_MUXB0), 834 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 835 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 836 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 837 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect); 838 839 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 840 VCN, 0, regUVD_MPC_SET_MUX), 841 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 842 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 843 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect); 844 845 vcn_v4_0_3_mc_resume_dpg_mode(adev, inst_idx, indirect); 846 847 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 848 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 849 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 850 VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect); 851 852 /* enable LMI MC and UMC channels */ 853 tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT; 854 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 855 VCN, 0, regUVD_LMI_CTRL2), tmp, 0, indirect); 856 857 vcn_v4_0_3_enable_ras(adev, inst_idx, indirect); 858 859 /* enable master interrupt */ 860 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 861 VCN, 0, regUVD_MASTINT_EN), 862 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 863 864 if (indirect) 865 amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM); 866 867 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 868 869 /* program the RB_BASE for ring buffer */ 870 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, 871 lower_32_bits(ring->gpu_addr)); 872 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, 873 upper_32_bits(ring->gpu_addr)); 874 875 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, 876 ring->ring_size / sizeof(uint32_t)); 877 878 /* resetting ring, fw should not check RB ring */ 879 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 880 tmp &= ~(VCN_RB_ENABLE__RB_EN_MASK); 881 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 882 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 883 884 /* Initialize the ring buffer's read and write pointers */ 885 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0); 886 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0); 887 ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR); 888 889 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 890 tmp |= VCN_RB_ENABLE__RB_EN_MASK; 891 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 892 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 893 894 /*resetting done, fw can check RB ring */ 895 fw_shared->sq.queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); 896 897 return 0; 898 } 899 900 static int vcn_v4_0_3_start_sriov(struct amdgpu_device *adev) 901 { 902 int i, vcn_inst; 903 struct amdgpu_ring *ring_enc; 904 uint64_t cache_addr; 905 uint64_t rb_enc_addr; 906 uint64_t ctx_addr; 907 uint32_t param, resp, expected; 908 uint32_t offset, cache_size; 909 uint32_t tmp, timeout; 910 911 struct amdgpu_mm_table *table = &adev->virt.mm_table; 912 uint32_t *table_loc; 913 uint32_t table_size; 914 uint32_t size, size_dw; 915 uint32_t init_status; 916 uint32_t enabled_vcn; 917 918 struct mmsch_v4_0_cmd_direct_write 919 direct_wt = { {0} }; 920 struct mmsch_v4_0_cmd_direct_read_modify_write 921 direct_rd_mod_wt = { {0} }; 922 struct mmsch_v4_0_cmd_end end = { {0} }; 923 struct mmsch_v4_0_3_init_header header; 924 925 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 926 volatile struct amdgpu_fw_shared_rb_setup *rb_setup; 927 928 direct_wt.cmd_header.command_type = 929 MMSCH_COMMAND__DIRECT_REG_WRITE; 930 direct_rd_mod_wt.cmd_header.command_type = 931 MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; 932 end.cmd_header.command_type = MMSCH_COMMAND__END; 933 934 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 935 vcn_inst = GET_INST(VCN, i); 936 937 memset(&header, 0, sizeof(struct mmsch_v4_0_3_init_header)); 938 header.version = MMSCH_VERSION; 939 header.total_size = sizeof(struct mmsch_v4_0_3_init_header) >> 2; 940 941 table_loc = (uint32_t *)table->cpu_addr; 942 table_loc += header.total_size; 943 944 table_size = 0; 945 946 MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, 0, regUVD_STATUS), 947 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY); 948 949 cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw[i]->size + 4); 950 951 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 952 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 953 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 954 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); 955 956 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 957 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 958 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); 959 960 offset = 0; 961 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 962 regUVD_VCPU_CACHE_OFFSET0), 0); 963 } else { 964 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 965 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 966 lower_32_bits(adev->vcn.inst[i].gpu_addr)); 967 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 968 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 969 upper_32_bits(adev->vcn.inst[i].gpu_addr)); 970 offset = cache_size; 971 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 972 regUVD_VCPU_CACHE_OFFSET0), 973 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 974 } 975 976 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 977 regUVD_VCPU_CACHE_SIZE0), 978 cache_size); 979 980 cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset; 981 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 982 regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), lower_32_bits(cache_addr)); 983 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 984 regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); 985 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 986 regUVD_VCPU_CACHE_OFFSET1), 0); 987 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 988 regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE); 989 990 cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset + 991 AMDGPU_VCN_STACK_SIZE; 992 993 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 994 regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), lower_32_bits(cache_addr)); 995 996 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 997 regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); 998 999 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 1000 regUVD_VCPU_CACHE_OFFSET2), 0); 1001 1002 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 1003 regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE); 1004 1005 fw_shared = adev->vcn.inst[vcn_inst].fw_shared.cpu_addr; 1006 rb_setup = &fw_shared->rb_setup; 1007 1008 ring_enc = &adev->vcn.inst[vcn_inst].ring_enc[0]; 1009 ring_enc->wptr = 0; 1010 rb_enc_addr = ring_enc->gpu_addr; 1011 1012 rb_setup->is_rb_enabled_flags |= RB_ENABLED; 1013 rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr); 1014 rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr); 1015 rb_setup->rb_size = ring_enc->ring_size / 4; 1016 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); 1017 1018 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 1019 regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 1020 lower_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); 1021 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 1022 regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 1023 upper_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); 1024 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, 1025 regUVD_VCPU_NONCACHE_SIZE0), 1026 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); 1027 MMSCH_V4_0_INSERT_END(); 1028 1029 header.vcn0.init_status = 0; 1030 header.vcn0.table_offset = header.total_size; 1031 header.vcn0.table_size = table_size; 1032 header.total_size += table_size; 1033 1034 /* Send init table to mmsch */ 1035 size = sizeof(struct mmsch_v4_0_3_init_header); 1036 table_loc = (uint32_t *)table->cpu_addr; 1037 memcpy((void *)table_loc, &header, size); 1038 1039 ctx_addr = table->gpu_addr; 1040 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); 1041 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); 1042 1043 tmp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID); 1044 tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; 1045 tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); 1046 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID, tmp); 1047 1048 size = header.total_size; 1049 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_SIZE, size); 1050 1051 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP, 0); 1052 1053 param = 0x00000001; 1054 WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_HOST, param); 1055 tmp = 0; 1056 timeout = 1000; 1057 resp = 0; 1058 expected = MMSCH_VF_MAILBOX_RESP__OK; 1059 while (resp != expected) { 1060 resp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP); 1061 if (resp != 0) 1062 break; 1063 1064 udelay(10); 1065 tmp = tmp + 10; 1066 if (tmp >= timeout) { 1067 DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ 1068 " waiting for regMMSCH_VF_MAILBOX_RESP "\ 1069 "(expected=0x%08x, readback=0x%08x)\n", 1070 tmp, expected, resp); 1071 return -EBUSY; 1072 } 1073 } 1074 1075 enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0; 1076 init_status = ((struct mmsch_v4_0_3_init_header *)(table_loc))->vcn0.init_status; 1077 if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE 1078 && init_status != MMSCH_VF_ENGINE_STATUS__PASS) { 1079 DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\ 1080 "status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status); 1081 } 1082 } 1083 1084 return 0; 1085 } 1086 1087 /** 1088 * vcn_v4_0_3_start - VCN start 1089 * 1090 * @adev: amdgpu_device pointer 1091 * 1092 * Start VCN block 1093 */ 1094 static int vcn_v4_0_3_start(struct amdgpu_device *adev) 1095 { 1096 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1097 struct amdgpu_ring *ring; 1098 int i, j, k, r, vcn_inst; 1099 uint32_t tmp; 1100 1101 if (adev->pm.dpm_enabled) 1102 amdgpu_dpm_enable_uvd(adev, true); 1103 1104 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1105 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1106 r = vcn_v4_0_3_start_dpg_mode(adev, i, adev->vcn.indirect_sram); 1107 continue; 1108 } 1109 1110 vcn_inst = GET_INST(VCN, i); 1111 /* set VCN status busy */ 1112 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS) | 1113 UVD_STATUS__UVD_BUSY; 1114 WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, tmp); 1115 1116 /*SW clock gating */ 1117 vcn_v4_0_3_disable_clock_gating(adev, i); 1118 1119 /* enable VCPU clock */ 1120 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 1121 UVD_VCPU_CNTL__CLK_EN_MASK, 1122 ~UVD_VCPU_CNTL__CLK_EN_MASK); 1123 1124 /* disable master interrupt */ 1125 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 0, 1126 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1127 1128 /* enable LMI MC and UMC channels */ 1129 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_LMI_CTRL2), 0, 1130 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1131 1132 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET); 1133 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1134 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1135 WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp); 1136 1137 /* setup regUVD_LMI_CTRL */ 1138 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL); 1139 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL, 1140 tmp | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1141 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1142 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1143 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 1144 1145 /* setup regUVD_MPC_CNTL */ 1146 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_MPC_CNTL); 1147 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; 1148 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; 1149 WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_CNTL, tmp); 1150 1151 /* setup UVD_MPC_SET_MUXA0 */ 1152 WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUXA0, 1153 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1154 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1155 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1156 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); 1157 1158 /* setup UVD_MPC_SET_MUXB0 */ 1159 WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUXB0, 1160 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1161 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1162 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1163 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); 1164 1165 /* setup UVD_MPC_SET_MUX */ 1166 WREG32_SOC15(VCN, vcn_inst, regUVD_MPC_SET_MUX, 1167 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1168 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1169 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); 1170 1171 vcn_v4_0_3_mc_resume(adev, i); 1172 1173 /* VCN global tiling registers */ 1174 WREG32_SOC15(VCN, vcn_inst, regUVD_GFX8_ADDR_CONFIG, 1175 adev->gfx.config.gb_addr_config); 1176 WREG32_SOC15(VCN, vcn_inst, regUVD_GFX10_ADDR_CONFIG, 1177 adev->gfx.config.gb_addr_config); 1178 1179 /* unblock VCPU register access */ 1180 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 0, 1181 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1182 1183 /* release VCPU reset to boot */ 1184 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0, 1185 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1186 1187 for (j = 0; j < 10; ++j) { 1188 uint32_t status; 1189 1190 for (k = 0; k < 100; ++k) { 1191 status = RREG32_SOC15(VCN, vcn_inst, 1192 regUVD_STATUS); 1193 if (status & 2) 1194 break; 1195 mdelay(10); 1196 } 1197 r = 0; 1198 if (status & 2) 1199 break; 1200 1201 DRM_DEV_ERROR(adev->dev, 1202 "VCN decode not responding, trying to reset the VCPU!!!\n"); 1203 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, 1204 regUVD_VCPU_CNTL), 1205 UVD_VCPU_CNTL__BLK_RST_MASK, 1206 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1207 mdelay(10); 1208 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, 1209 regUVD_VCPU_CNTL), 1210 0, ~UVD_VCPU_CNTL__BLK_RST_MASK); 1211 1212 mdelay(10); 1213 r = -1; 1214 } 1215 1216 if (r) { 1217 DRM_DEV_ERROR(adev->dev, "VCN decode not responding, giving up!!!\n"); 1218 return r; 1219 } 1220 1221 /* enable master interrupt */ 1222 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 1223 UVD_MASTINT_EN__VCPU_EN_MASK, 1224 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1225 1226 /* clear the busy bit of VCN_STATUS */ 1227 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_STATUS), 0, 1228 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 1229 1230 ring = &adev->vcn.inst[i].ring_enc[0]; 1231 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1232 1233 /* program the RB_BASE for ring buffer */ 1234 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, 1235 lower_32_bits(ring->gpu_addr)); 1236 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, 1237 upper_32_bits(ring->gpu_addr)); 1238 1239 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, 1240 ring->ring_size / sizeof(uint32_t)); 1241 1242 /* resetting ring, fw should not check RB ring */ 1243 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 1244 tmp &= ~(VCN_RB_ENABLE__RB_EN_MASK); 1245 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 1246 1247 /* Initialize the ring buffer's read and write pointers */ 1248 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0); 1249 WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0); 1250 1251 tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); 1252 tmp |= VCN_RB_ENABLE__RB_EN_MASK; 1253 WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); 1254 1255 ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR); 1256 fw_shared->sq.queue_mode &= 1257 cpu_to_le32(~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF)); 1258 1259 } 1260 return 0; 1261 } 1262 1263 /** 1264 * vcn_v4_0_3_stop_dpg_mode - VCN stop with dpg mode 1265 * 1266 * @adev: amdgpu_device pointer 1267 * @inst_idx: instance number index 1268 * 1269 * Stop VCN block with dpg mode 1270 */ 1271 static int vcn_v4_0_3_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 1272 { 1273 uint32_t tmp; 1274 int vcn_inst; 1275 1276 vcn_inst = GET_INST(VCN, inst_idx); 1277 1278 /* Wait for power status to be 1 */ 1279 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1, 1280 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1281 1282 /* wait for read ptr to be equal to write ptr */ 1283 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR); 1284 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1285 1286 SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1, 1287 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1288 1289 /* disable dynamic power gating mode */ 1290 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 0, 1291 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1292 return 0; 1293 } 1294 1295 /** 1296 * vcn_v4_0_3_stop - VCN stop 1297 * 1298 * @adev: amdgpu_device pointer 1299 * 1300 * Stop VCN block 1301 */ 1302 static int vcn_v4_0_3_stop(struct amdgpu_device *adev) 1303 { 1304 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1305 int i, r = 0, vcn_inst; 1306 uint32_t tmp; 1307 1308 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1309 vcn_inst = GET_INST(VCN, i); 1310 1311 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1312 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; 1313 1314 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1315 vcn_v4_0_3_stop_dpg_mode(adev, i); 1316 continue; 1317 } 1318 1319 /* wait for vcn idle */ 1320 r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_STATUS, 1321 UVD_STATUS__IDLE, 0x7); 1322 if (r) 1323 goto Done; 1324 1325 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1326 UVD_LMI_STATUS__READ_CLEAN_MASK | 1327 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1328 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1329 r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, 1330 tmp); 1331 if (r) 1332 goto Done; 1333 1334 /* stall UMC channel */ 1335 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2); 1336 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1337 WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2, tmp); 1338 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | 1339 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1340 r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, 1341 tmp); 1342 if (r) 1343 goto Done; 1344 1345 /* Unblock VCPU Register access */ 1346 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 1347 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1348 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1349 1350 /* release VCPU reset to boot */ 1351 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 1352 UVD_VCPU_CNTL__BLK_RST_MASK, 1353 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1354 1355 /* disable VCPU clock */ 1356 WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0, 1357 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1358 1359 /* reset LMI UMC/LMI/VCPU */ 1360 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET); 1361 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1362 WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp); 1363 1364 tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET); 1365 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1366 WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp); 1367 1368 /* clear VCN status */ 1369 WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0); 1370 1371 /* apply HW clock gating */ 1372 vcn_v4_0_3_enable_clock_gating(adev, i); 1373 } 1374 Done: 1375 if (adev->pm.dpm_enabled) 1376 amdgpu_dpm_enable_uvd(adev, false); 1377 1378 return 0; 1379 } 1380 1381 /** 1382 * vcn_v4_0_3_pause_dpg_mode - VCN pause with dpg mode 1383 * 1384 * @adev: amdgpu_device pointer 1385 * @inst_idx: instance number index 1386 * @new_state: pause state 1387 * 1388 * Pause dpg mode for VCN block 1389 */ 1390 static int vcn_v4_0_3_pause_dpg_mode(struct amdgpu_device *adev, int inst_idx, 1391 struct dpg_pause_state *new_state) 1392 { 1393 1394 return 0; 1395 } 1396 1397 /** 1398 * vcn_v4_0_3_unified_ring_get_rptr - get unified read pointer 1399 * 1400 * @ring: amdgpu_ring pointer 1401 * 1402 * Returns the current hardware unified read pointer 1403 */ 1404 static uint64_t vcn_v4_0_3_unified_ring_get_rptr(struct amdgpu_ring *ring) 1405 { 1406 struct amdgpu_device *adev = ring->adev; 1407 1408 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1409 DRM_ERROR("wrong ring id is identified in %s", __func__); 1410 1411 return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_RPTR); 1412 } 1413 1414 /** 1415 * vcn_v4_0_3_unified_ring_get_wptr - get unified write pointer 1416 * 1417 * @ring: amdgpu_ring pointer 1418 * 1419 * Returns the current hardware unified write pointer 1420 */ 1421 static uint64_t vcn_v4_0_3_unified_ring_get_wptr(struct amdgpu_ring *ring) 1422 { 1423 struct amdgpu_device *adev = ring->adev; 1424 1425 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1426 DRM_ERROR("wrong ring id is identified in %s", __func__); 1427 1428 if (ring->use_doorbell) 1429 return *ring->wptr_cpu_addr; 1430 else 1431 return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), 1432 regUVD_RB_WPTR); 1433 } 1434 1435 static void vcn_v4_0_3_enc_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, 1436 uint32_t val, uint32_t mask) 1437 { 1438 /* Use normalized offsets when required */ 1439 if (vcn_v4_0_3_normalizn_reqd(ring->adev)) 1440 reg = NORMALIZE_VCN_REG_OFFSET(reg); 1441 1442 amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT); 1443 amdgpu_ring_write(ring, reg << 2); 1444 amdgpu_ring_write(ring, mask); 1445 amdgpu_ring_write(ring, val); 1446 } 1447 1448 static void vcn_v4_0_3_enc_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val) 1449 { 1450 /* Use normalized offsets when required */ 1451 if (vcn_v4_0_3_normalizn_reqd(ring->adev)) 1452 reg = NORMALIZE_VCN_REG_OFFSET(reg); 1453 1454 amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE); 1455 amdgpu_ring_write(ring, reg << 2); 1456 amdgpu_ring_write(ring, val); 1457 } 1458 1459 static void vcn_v4_0_3_enc_ring_emit_vm_flush(struct amdgpu_ring *ring, 1460 unsigned int vmid, uint64_t pd_addr) 1461 { 1462 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->vm_hub]; 1463 1464 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); 1465 1466 /* wait for reg writes */ 1467 vcn_v4_0_3_enc_ring_emit_reg_wait(ring, hub->ctx0_ptb_addr_lo32 + 1468 vmid * hub->ctx_addr_distance, 1469 lower_32_bits(pd_addr), 0xffffffff); 1470 } 1471 1472 static void vcn_v4_0_3_ring_emit_hdp_flush(struct amdgpu_ring *ring) 1473 { 1474 /* VCN engine access for HDP flush doesn't work when RRMT is enabled. 1475 * This is a workaround to avoid any HDP flush through VCN ring. 1476 */ 1477 } 1478 1479 /** 1480 * vcn_v4_0_3_unified_ring_set_wptr - set enc write pointer 1481 * 1482 * @ring: amdgpu_ring pointer 1483 * 1484 * Commits the enc write pointer to the hardware 1485 */ 1486 static void vcn_v4_0_3_unified_ring_set_wptr(struct amdgpu_ring *ring) 1487 { 1488 struct amdgpu_device *adev = ring->adev; 1489 1490 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1491 DRM_ERROR("wrong ring id is identified in %s", __func__); 1492 1493 if (ring->use_doorbell) { 1494 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1495 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1496 } else { 1497 WREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR, 1498 lower_32_bits(ring->wptr)); 1499 } 1500 } 1501 1502 static const struct amdgpu_ring_funcs vcn_v4_0_3_unified_ring_vm_funcs = { 1503 .type = AMDGPU_RING_TYPE_VCN_ENC, 1504 .align_mask = 0x3f, 1505 .nop = VCN_ENC_CMD_NO_OP, 1506 .get_rptr = vcn_v4_0_3_unified_ring_get_rptr, 1507 .get_wptr = vcn_v4_0_3_unified_ring_get_wptr, 1508 .set_wptr = vcn_v4_0_3_unified_ring_set_wptr, 1509 .emit_frame_size = 1510 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1511 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1512 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1513 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 1514 1, /* vcn_v2_0_enc_ring_insert_end */ 1515 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 1516 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 1517 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 1518 .emit_vm_flush = vcn_v4_0_3_enc_ring_emit_vm_flush, 1519 .emit_hdp_flush = vcn_v4_0_3_ring_emit_hdp_flush, 1520 .test_ring = amdgpu_vcn_enc_ring_test_ring, 1521 .test_ib = amdgpu_vcn_unified_ring_test_ib, 1522 .insert_nop = amdgpu_ring_insert_nop, 1523 .insert_end = vcn_v2_0_enc_ring_insert_end, 1524 .pad_ib = amdgpu_ring_generic_pad_ib, 1525 .begin_use = amdgpu_vcn_ring_begin_use, 1526 .end_use = amdgpu_vcn_ring_end_use, 1527 .emit_wreg = vcn_v4_0_3_enc_ring_emit_wreg, 1528 .emit_reg_wait = vcn_v4_0_3_enc_ring_emit_reg_wait, 1529 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1530 }; 1531 1532 /** 1533 * vcn_v4_0_3_set_unified_ring_funcs - set unified ring functions 1534 * 1535 * @adev: amdgpu_device pointer 1536 * 1537 * Set unified ring functions 1538 */ 1539 static void vcn_v4_0_3_set_unified_ring_funcs(struct amdgpu_device *adev) 1540 { 1541 int i, vcn_inst; 1542 1543 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1544 adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v4_0_3_unified_ring_vm_funcs; 1545 adev->vcn.inst[i].ring_enc[0].me = i; 1546 vcn_inst = GET_INST(VCN, i); 1547 adev->vcn.inst[i].aid_id = 1548 vcn_inst / adev->vcn.num_inst_per_aid; 1549 } 1550 } 1551 1552 /** 1553 * vcn_v4_0_3_is_idle - check VCN block is idle 1554 * 1555 * @handle: amdgpu_device pointer 1556 * 1557 * Check whether VCN block is idle 1558 */ 1559 static bool vcn_v4_0_3_is_idle(void *handle) 1560 { 1561 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1562 int i, ret = 1; 1563 1564 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1565 ret &= (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) == 1566 UVD_STATUS__IDLE); 1567 } 1568 1569 return ret; 1570 } 1571 1572 /** 1573 * vcn_v4_0_3_wait_for_idle - wait for VCN block idle 1574 * 1575 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 1576 * 1577 * Wait for VCN block idle 1578 */ 1579 static int vcn_v4_0_3_wait_for_idle(struct amdgpu_ip_block *ip_block) 1580 { 1581 struct amdgpu_device *adev = ip_block->adev; 1582 int i, ret = 0; 1583 1584 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1585 ret = SOC15_WAIT_ON_RREG(VCN, GET_INST(VCN, i), regUVD_STATUS, 1586 UVD_STATUS__IDLE, UVD_STATUS__IDLE); 1587 if (ret) 1588 return ret; 1589 } 1590 1591 return ret; 1592 } 1593 1594 /* vcn_v4_0_3_set_clockgating_state - set VCN block clockgating state 1595 * 1596 * @handle: amdgpu_device pointer 1597 * @state: clock gating state 1598 * 1599 * Set VCN block clockgating state 1600 */ 1601 static int vcn_v4_0_3_set_clockgating_state(void *handle, 1602 enum amd_clockgating_state state) 1603 { 1604 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1605 bool enable = state == AMD_CG_STATE_GATE; 1606 int i; 1607 1608 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1609 if (enable) { 1610 if (RREG32_SOC15(VCN, GET_INST(VCN, i), 1611 regUVD_STATUS) != UVD_STATUS__IDLE) 1612 return -EBUSY; 1613 vcn_v4_0_3_enable_clock_gating(adev, i); 1614 } else { 1615 vcn_v4_0_3_disable_clock_gating(adev, i); 1616 } 1617 } 1618 return 0; 1619 } 1620 1621 /** 1622 * vcn_v4_0_3_set_powergating_state - set VCN block powergating state 1623 * 1624 * @handle: amdgpu_device pointer 1625 * @state: power gating state 1626 * 1627 * Set VCN block powergating state 1628 */ 1629 static int vcn_v4_0_3_set_powergating_state(void *handle, 1630 enum amd_powergating_state state) 1631 { 1632 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1633 int ret; 1634 1635 /* for SRIOV, guest should not control VCN Power-gating 1636 * MMSCH FW should control Power-gating and clock-gating 1637 * guest should avoid touching CGC and PG 1638 */ 1639 if (amdgpu_sriov_vf(adev)) { 1640 adev->vcn.cur_state = AMD_PG_STATE_UNGATE; 1641 return 0; 1642 } 1643 1644 if (state == adev->vcn.cur_state) 1645 return 0; 1646 1647 if (state == AMD_PG_STATE_GATE) 1648 ret = vcn_v4_0_3_stop(adev); 1649 else 1650 ret = vcn_v4_0_3_start(adev); 1651 1652 if (!ret) 1653 adev->vcn.cur_state = state; 1654 1655 return ret; 1656 } 1657 1658 /** 1659 * vcn_v4_0_3_set_interrupt_state - set VCN block interrupt state 1660 * 1661 * @adev: amdgpu_device pointer 1662 * @source: interrupt sources 1663 * @type: interrupt types 1664 * @state: interrupt states 1665 * 1666 * Set VCN block interrupt state 1667 */ 1668 static int vcn_v4_0_3_set_interrupt_state(struct amdgpu_device *adev, 1669 struct amdgpu_irq_src *source, 1670 unsigned int type, 1671 enum amdgpu_interrupt_state state) 1672 { 1673 return 0; 1674 } 1675 1676 /** 1677 * vcn_v4_0_3_process_interrupt - process VCN block interrupt 1678 * 1679 * @adev: amdgpu_device pointer 1680 * @source: interrupt sources 1681 * @entry: interrupt entry from clients and sources 1682 * 1683 * Process VCN block interrupt 1684 */ 1685 static int vcn_v4_0_3_process_interrupt(struct amdgpu_device *adev, 1686 struct amdgpu_irq_src *source, 1687 struct amdgpu_iv_entry *entry) 1688 { 1689 uint32_t i, inst; 1690 1691 i = node_id_to_phys_map[entry->node_id]; 1692 1693 DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n"); 1694 1695 for (inst = 0; inst < adev->vcn.num_vcn_inst; ++inst) 1696 if (adev->vcn.inst[inst].aid_id == i) 1697 break; 1698 1699 if (inst >= adev->vcn.num_vcn_inst) { 1700 dev_WARN_ONCE(adev->dev, 1, 1701 "Interrupt received for unknown VCN instance %d", 1702 entry->node_id); 1703 return 0; 1704 } 1705 1706 switch (entry->src_id) { 1707 case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 1708 amdgpu_fence_process(&adev->vcn.inst[inst].ring_enc[0]); 1709 break; 1710 default: 1711 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 1712 entry->src_id, entry->src_data[0]); 1713 break; 1714 } 1715 1716 return 0; 1717 } 1718 1719 static const struct amdgpu_irq_src_funcs vcn_v4_0_3_irq_funcs = { 1720 .set = vcn_v4_0_3_set_interrupt_state, 1721 .process = vcn_v4_0_3_process_interrupt, 1722 }; 1723 1724 /** 1725 * vcn_v4_0_3_set_irq_funcs - set VCN block interrupt irq functions 1726 * 1727 * @adev: amdgpu_device pointer 1728 * 1729 * Set VCN block interrupt irq functions 1730 */ 1731 static void vcn_v4_0_3_set_irq_funcs(struct amdgpu_device *adev) 1732 { 1733 int i; 1734 1735 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1736 adev->vcn.inst->irq.num_types++; 1737 } 1738 adev->vcn.inst->irq.funcs = &vcn_v4_0_3_irq_funcs; 1739 } 1740 1741 static void vcn_v4_0_3_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 1742 { 1743 struct amdgpu_device *adev = ip_block->adev; 1744 int i, j; 1745 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); 1746 uint32_t inst_off, is_powered; 1747 1748 if (!adev->vcn.ip_dump) 1749 return; 1750 1751 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1752 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1753 if (adev->vcn.harvest_config & (1 << i)) { 1754 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1755 continue; 1756 } 1757 1758 inst_off = i * reg_count; 1759 is_powered = (adev->vcn.ip_dump[inst_off] & 1760 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1761 1762 if (is_powered) { 1763 drm_printf(p, "\nActive Instance:VCN%d\n", i); 1764 for (j = 0; j < reg_count; j++) 1765 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_3[j].reg_name, 1766 adev->vcn.ip_dump[inst_off + j]); 1767 } else { 1768 drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1769 } 1770 } 1771 } 1772 1773 static void vcn_v4_0_3_dump_ip_state(struct amdgpu_ip_block *ip_block) 1774 { 1775 struct amdgpu_device *adev = ip_block->adev; 1776 int i, j; 1777 bool is_powered; 1778 uint32_t inst_off, inst_id; 1779 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); 1780 1781 if (!adev->vcn.ip_dump) 1782 return; 1783 1784 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1785 if (adev->vcn.harvest_config & (1 << i)) 1786 continue; 1787 1788 inst_id = GET_INST(VCN, i); 1789 inst_off = i * reg_count; 1790 /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 1791 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, inst_id, regUVD_POWER_STATUS); 1792 is_powered = (adev->vcn.ip_dump[inst_off] & 1793 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1794 1795 if (is_powered) 1796 for (j = 1; j < reg_count; j++) 1797 adev->vcn.ip_dump[inst_off + j] = 1798 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_3[j], 1799 inst_id)); 1800 } 1801 } 1802 1803 static const struct amd_ip_funcs vcn_v4_0_3_ip_funcs = { 1804 .name = "vcn_v4_0_3", 1805 .early_init = vcn_v4_0_3_early_init, 1806 .sw_init = vcn_v4_0_3_sw_init, 1807 .sw_fini = vcn_v4_0_3_sw_fini, 1808 .hw_init = vcn_v4_0_3_hw_init, 1809 .hw_fini = vcn_v4_0_3_hw_fini, 1810 .suspend = vcn_v4_0_3_suspend, 1811 .resume = vcn_v4_0_3_resume, 1812 .is_idle = vcn_v4_0_3_is_idle, 1813 .wait_for_idle = vcn_v4_0_3_wait_for_idle, 1814 .set_clockgating_state = vcn_v4_0_3_set_clockgating_state, 1815 .set_powergating_state = vcn_v4_0_3_set_powergating_state, 1816 .dump_ip_state = vcn_v4_0_3_dump_ip_state, 1817 .print_ip_state = vcn_v4_0_3_print_ip_state, 1818 }; 1819 1820 const struct amdgpu_ip_block_version vcn_v4_0_3_ip_block = { 1821 .type = AMD_IP_BLOCK_TYPE_VCN, 1822 .major = 4, 1823 .minor = 0, 1824 .rev = 3, 1825 .funcs = &vcn_v4_0_3_ip_funcs, 1826 }; 1827 1828 static const struct amdgpu_ras_err_status_reg_entry vcn_v4_0_3_ue_reg_list[] = { 1829 {AMDGPU_RAS_REG_ENTRY(VCN, 0, regVCN_UE_ERR_STATUS_LO_VIDD, regVCN_UE_ERR_STATUS_HI_VIDD), 1830 1, (AMDGPU_RAS_ERR_INFO_VALID | AMDGPU_RAS_ERR_STATUS_VALID), "VIDD"}, 1831 {AMDGPU_RAS_REG_ENTRY(VCN, 0, regVCN_UE_ERR_STATUS_LO_VIDV, regVCN_UE_ERR_STATUS_HI_VIDV), 1832 1, (AMDGPU_RAS_ERR_INFO_VALID | AMDGPU_RAS_ERR_STATUS_VALID), "VIDV"}, 1833 }; 1834 1835 static void vcn_v4_0_3_inst_query_ras_error_count(struct amdgpu_device *adev, 1836 uint32_t vcn_inst, 1837 void *ras_err_status) 1838 { 1839 struct ras_err_data *err_data = (struct ras_err_data *)ras_err_status; 1840 1841 /* vcn v4_0_3 only support query uncorrectable errors */ 1842 amdgpu_ras_inst_query_ras_error_count(adev, 1843 vcn_v4_0_3_ue_reg_list, 1844 ARRAY_SIZE(vcn_v4_0_3_ue_reg_list), 1845 NULL, 0, GET_INST(VCN, vcn_inst), 1846 AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE, 1847 &err_data->ue_count); 1848 } 1849 1850 static void vcn_v4_0_3_query_ras_error_count(struct amdgpu_device *adev, 1851 void *ras_err_status) 1852 { 1853 uint32_t i; 1854 1855 if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) { 1856 dev_warn(adev->dev, "VCN RAS is not supported\n"); 1857 return; 1858 } 1859 1860 for (i = 0; i < adev->vcn.num_vcn_inst; i++) 1861 vcn_v4_0_3_inst_query_ras_error_count(adev, i, ras_err_status); 1862 } 1863 1864 static void vcn_v4_0_3_inst_reset_ras_error_count(struct amdgpu_device *adev, 1865 uint32_t vcn_inst) 1866 { 1867 amdgpu_ras_inst_reset_ras_error_count(adev, 1868 vcn_v4_0_3_ue_reg_list, 1869 ARRAY_SIZE(vcn_v4_0_3_ue_reg_list), 1870 GET_INST(VCN, vcn_inst)); 1871 } 1872 1873 static void vcn_v4_0_3_reset_ras_error_count(struct amdgpu_device *adev) 1874 { 1875 uint32_t i; 1876 1877 if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) { 1878 dev_warn(adev->dev, "VCN RAS is not supported\n"); 1879 return; 1880 } 1881 1882 for (i = 0; i < adev->vcn.num_vcn_inst; i++) 1883 vcn_v4_0_3_inst_reset_ras_error_count(adev, i); 1884 } 1885 1886 static const struct amdgpu_ras_block_hw_ops vcn_v4_0_3_ras_hw_ops = { 1887 .query_ras_error_count = vcn_v4_0_3_query_ras_error_count, 1888 .reset_ras_error_count = vcn_v4_0_3_reset_ras_error_count, 1889 }; 1890 1891 static struct amdgpu_vcn_ras vcn_v4_0_3_ras = { 1892 .ras_block = { 1893 .hw_ops = &vcn_v4_0_3_ras_hw_ops, 1894 }, 1895 }; 1896 1897 static void vcn_v4_0_3_set_ras_funcs(struct amdgpu_device *adev) 1898 { 1899 adev->vcn.ras = &vcn_v4_0_3_ras; 1900 } 1901 1902 static void vcn_v4_0_3_enable_ras(struct amdgpu_device *adev, 1903 int inst_idx, bool indirect) 1904 { 1905 uint32_t tmp; 1906 1907 if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) 1908 return; 1909 1910 tmp = VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK | 1911 VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK | 1912 VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK | 1913 VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK; 1914 WREG32_SOC15_DPG_MODE(inst_idx, 1915 SOC15_DPG_MODE_OFFSET(VCN, 0, regVCN_RAS_CNTL), 1916 tmp, 0, indirect); 1917 1918 tmp = UVD_VCPU_INT_EN2__RASCNTL_VCPU_VCODEC_EN_MASK; 1919 WREG32_SOC15_DPG_MODE(inst_idx, 1920 SOC15_DPG_MODE_OFFSET(VCN, 0, regUVD_VCPU_INT_EN2), 1921 tmp, 0, indirect); 1922 1923 tmp = UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK; 1924 WREG32_SOC15_DPG_MODE(inst_idx, 1925 SOC15_DPG_MODE_OFFSET(VCN, 0, regUVD_SYS_INT_EN), 1926 tmp, 0, indirect); 1927 } 1928