1 /* 2 * Copyright 2023 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include <linux/firmware.h> 25 #include "amdgpu.h" 26 #include "amdgpu_vcn.h" 27 #include "amdgpu_pm.h" 28 #include "amdgpu_cs.h" 29 #include "soc15.h" 30 #include "soc15d.h" 31 #include "soc15_hw_ip.h" 32 #include "vcn_v2_0.h" 33 #include "mmsch_v4_0.h" 34 #include "vcn_v4_0_5.h" 35 36 #include "vcn/vcn_4_0_5_offset.h" 37 #include "vcn/vcn_4_0_5_sh_mask.h" 38 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h" 39 40 #include <drm/drm_drv.h> 41 42 #define mmUVD_DPG_LMA_CTL regUVD_DPG_LMA_CTL 43 #define mmUVD_DPG_LMA_CTL_BASE_IDX regUVD_DPG_LMA_CTL_BASE_IDX 44 #define mmUVD_DPG_LMA_DATA regUVD_DPG_LMA_DATA 45 #define mmUVD_DPG_LMA_DATA_BASE_IDX regUVD_DPG_LMA_DATA_BASE_IDX 46 47 #define VCN_VID_SOC_ADDRESS_2_0 0x1fb00 48 #define VCN1_VID_SOC_ADDRESS_3_0 (0x48300 + 0x38000) 49 50 #define VCN_HARVEST_MMSCH 0 51 52 #define RDECODE_MSG_CREATE 0x00000000 53 #define RDECODE_MESSAGE_CREATE 0x00000001 54 55 static const struct amdgpu_hwip_reg_entry vcn_reg_list_4_0_5[] = { 56 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS), 57 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS), 58 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID), 59 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2), 60 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0), 61 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1), 62 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD), 63 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI), 64 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO), 65 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2), 66 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2), 67 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3), 68 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3), 69 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4), 70 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4), 71 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR), 72 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR), 73 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2), 74 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2), 75 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3), 76 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3), 77 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4), 78 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4), 79 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE), 80 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2), 81 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3), 82 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4), 83 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_CONFIG), 84 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_STATUS), 85 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL), 86 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA), 87 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK), 88 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE) 89 }; 90 91 static int amdgpu_ih_clientid_vcns[] = { 92 SOC15_IH_CLIENTID_VCN, 93 SOC15_IH_CLIENTID_VCN1 94 }; 95 96 static void vcn_v4_0_5_set_unified_ring_funcs(struct amdgpu_device *adev); 97 static void vcn_v4_0_5_set_irq_funcs(struct amdgpu_device *adev); 98 static int vcn_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block, 99 enum amd_powergating_state state); 100 static int vcn_v4_0_5_pause_dpg_mode(struct amdgpu_device *adev, 101 int inst_idx, struct dpg_pause_state *new_state); 102 static void vcn_v4_0_5_unified_ring_set_wptr(struct amdgpu_ring *ring); 103 104 /** 105 * vcn_v4_0_5_early_init - set function pointers and load microcode 106 * 107 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 108 * 109 * Set ring and irq function pointers 110 * Load microcode from filesystem 111 */ 112 static int vcn_v4_0_5_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 vcn_v4_0_5_set_unified_ring_funcs(adev); 119 vcn_v4_0_5_set_irq_funcs(adev); 120 121 return amdgpu_vcn_early_init(adev); 122 } 123 124 /** 125 * vcn_v4_0_5_sw_init - sw init for VCN block 126 * 127 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 128 * 129 * Load firmware and sw initialization 130 */ 131 static int vcn_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block) 132 { 133 struct amdgpu_ring *ring; 134 struct amdgpu_device *adev = ip_block->adev; 135 int i, r; 136 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 137 uint32_t *ptr; 138 139 r = amdgpu_vcn_sw_init(adev); 140 if (r) 141 return r; 142 143 amdgpu_vcn_setup_ucode(adev); 144 145 r = amdgpu_vcn_resume(adev); 146 if (r) 147 return r; 148 149 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 150 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 151 152 if (adev->vcn.harvest_config & (1 << i)) 153 continue; 154 155 atomic_set(&adev->vcn.inst[i].sched_score, 0); 156 157 /* VCN UNIFIED TRAP */ 158 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i], 159 VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq); 160 if (r) 161 return r; 162 163 /* VCN POISON TRAP */ 164 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i], 165 VCN_4_0__SRCID_UVD_POISON, &adev->vcn.inst[i].irq); 166 if (r) 167 return r; 168 169 ring = &adev->vcn.inst[i].ring_enc[0]; 170 ring->use_doorbell = true; 171 if (amdgpu_sriov_vf(adev)) 172 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 173 i * (adev->vcn.num_enc_rings + 1) + 1; 174 else 175 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 176 2 + 8 * i; 177 ring->vm_hub = AMDGPU_MMHUB0(0); 178 sprintf(ring->name, "vcn_unified_%d", i); 179 180 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0, 181 AMDGPU_RING_PRIO_0, &adev->vcn.inst[i].sched_score); 182 if (r) 183 return r; 184 185 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 186 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); 187 fw_shared->sq.is_enabled = 1; 188 189 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG); 190 fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ? 191 AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU; 192 193 if (amdgpu_sriov_vf(adev)) 194 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); 195 196 if (amdgpu_vcnfw_log) 197 amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); 198 } 199 200 if (amdgpu_sriov_vf(adev)) { 201 r = amdgpu_virt_alloc_mm_table(adev); 202 if (r) 203 return r; 204 } 205 206 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 207 adev->vcn.pause_dpg_mode = vcn_v4_0_5_pause_dpg_mode; 208 209 /* Allocate memory for VCN IP Dump buffer */ 210 ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 211 if (!ptr) { 212 DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 213 adev->vcn.ip_dump = NULL; 214 } else { 215 adev->vcn.ip_dump = ptr; 216 } 217 return 0; 218 } 219 220 /** 221 * vcn_v4_0_5_sw_fini - sw fini for VCN block 222 * 223 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 224 * 225 * VCN suspend and free up sw allocation 226 */ 227 static int vcn_v4_0_5_sw_fini(struct amdgpu_ip_block *ip_block) 228 { 229 struct amdgpu_device *adev = ip_block->adev; 230 int i, r, idx; 231 232 if (drm_dev_enter(adev_to_drm(adev), &idx)) { 233 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 234 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 235 236 if (adev->vcn.harvest_config & (1 << i)) 237 continue; 238 239 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 240 fw_shared->present_flag_0 = 0; 241 fw_shared->sq.is_enabled = 0; 242 } 243 244 drm_dev_exit(idx); 245 } 246 247 if (amdgpu_sriov_vf(adev)) 248 amdgpu_virt_free_mm_table(adev); 249 250 r = amdgpu_vcn_suspend(adev); 251 if (r) 252 return r; 253 254 r = amdgpu_vcn_sw_fini(adev); 255 256 kfree(adev->vcn.ip_dump); 257 258 return r; 259 } 260 261 /** 262 * vcn_v4_0_5_hw_init - start and test VCN block 263 * 264 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 265 * 266 * Initialize the hardware, boot up the VCPU and do some testing 267 */ 268 static int vcn_v4_0_5_hw_init(struct amdgpu_ip_block *ip_block) 269 { 270 struct amdgpu_device *adev = ip_block->adev; 271 struct amdgpu_ring *ring; 272 int i, r; 273 274 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 275 if (adev->vcn.harvest_config & (1 << i)) 276 continue; 277 278 ring = &adev->vcn.inst[i].ring_enc[0]; 279 280 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 281 ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i); 282 283 r = amdgpu_ring_test_helper(ring); 284 if (r) 285 return r; 286 } 287 288 return 0; 289 } 290 291 /** 292 * vcn_v4_0_5_hw_fini - stop the hardware block 293 * 294 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 295 * 296 * Stop the VCN block, mark ring as not ready any more 297 */ 298 static int vcn_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block) 299 { 300 struct amdgpu_device *adev = ip_block->adev; 301 int i; 302 303 cancel_delayed_work_sync(&adev->vcn.idle_work); 304 305 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 306 if (adev->vcn.harvest_config & (1 << i)) 307 continue; 308 if (!amdgpu_sriov_vf(adev)) { 309 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || 310 (adev->vcn.cur_state != AMD_PG_STATE_GATE && 311 RREG32_SOC15(VCN, i, regUVD_STATUS))) { 312 vcn_v4_0_5_set_powergating_state(ip_block, AMD_PG_STATE_GATE); 313 } 314 } 315 } 316 317 return 0; 318 } 319 320 /** 321 * vcn_v4_0_5_suspend - suspend VCN block 322 * 323 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 324 * 325 * HW fini and suspend VCN block 326 */ 327 static int vcn_v4_0_5_suspend(struct amdgpu_ip_block *ip_block) 328 { 329 int r; 330 331 r = vcn_v4_0_5_hw_fini(ip_block); 332 if (r) 333 return r; 334 335 r = amdgpu_vcn_suspend(ip_block->adev); 336 337 return r; 338 } 339 340 /** 341 * vcn_v4_0_5_resume - resume VCN block 342 * 343 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 344 * 345 * Resume firmware and hw init VCN block 346 */ 347 static int vcn_v4_0_5_resume(struct amdgpu_ip_block *ip_block) 348 { 349 int r; 350 351 r = amdgpu_vcn_resume(ip_block->adev); 352 if (r) 353 return r; 354 355 r = vcn_v4_0_5_hw_init(ip_block); 356 357 return r; 358 } 359 360 /** 361 * vcn_v4_0_5_mc_resume - memory controller programming 362 * 363 * @adev: amdgpu_device pointer 364 * @inst: instance number 365 * 366 * Let the VCN memory controller know it's offsets 367 */ 368 static void vcn_v4_0_5_mc_resume(struct amdgpu_device *adev, int inst) 369 { 370 uint32_t offset, size; 371 const struct common_firmware_header *hdr; 372 373 hdr = (const struct common_firmware_header *)adev->vcn.inst[inst].fw->data; 374 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 375 376 /* cache window 0: fw */ 377 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 378 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 379 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo)); 380 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 381 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi)); 382 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, 0); 383 offset = 0; 384 } else { 385 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 386 lower_32_bits(adev->vcn.inst[inst].gpu_addr)); 387 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 388 upper_32_bits(adev->vcn.inst[inst].gpu_addr)); 389 offset = size; 390 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 391 } 392 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE0, size); 393 394 /* cache window 1: stack */ 395 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 396 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset)); 397 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 398 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset)); 399 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET1, 0); 400 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE); 401 402 /* cache window 2: context */ 403 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 404 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 405 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 406 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 407 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET2, 0); 408 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE); 409 410 /* non-cache window */ 411 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW, 412 lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr)); 413 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH, 414 upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr)); 415 WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_OFFSET0, 0); 416 WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_SIZE0, 417 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); 418 } 419 420 /** 421 * vcn_v4_0_5_mc_resume_dpg_mode - memory controller programming for dpg mode 422 * 423 * @adev: amdgpu_device pointer 424 * @inst_idx: instance number index 425 * @indirect: indirectly write sram 426 * 427 * Let the VCN memory controller know it's offsets with dpg mode 428 */ 429 static void vcn_v4_0_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 430 { 431 uint32_t offset, size; 432 const struct common_firmware_header *hdr; 433 434 hdr = (const struct common_firmware_header *)adev->vcn.inst[inst_idx].fw->data; 435 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 436 437 /* cache window 0: fw */ 438 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 439 if (!indirect) { 440 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 441 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 442 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 443 0, indirect); 444 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 445 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 446 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 447 0, indirect); 448 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 449 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 450 } else { 451 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 452 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect); 453 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 454 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect); 455 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 456 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 457 } 458 offset = 0; 459 } else { 460 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 461 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 462 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 463 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 464 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 465 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 466 offset = size; 467 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 468 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 469 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect); 470 } 471 472 if (!indirect) 473 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 474 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect); 475 else 476 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 477 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect); 478 479 /* cache window 1: stack */ 480 if (!indirect) { 481 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 482 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 483 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 484 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 485 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 486 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 487 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 488 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 489 } else { 490 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 491 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect); 492 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 493 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect); 494 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 495 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 496 } 497 498 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 499 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect); 500 501 /* cache window 2: context */ 502 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 503 VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 504 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 505 0, indirect); 506 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 507 VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 508 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 509 0, indirect); 510 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 511 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect); 512 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 513 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect); 514 515 /* non-cache window */ 516 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 517 VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 518 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 519 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 520 VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 521 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 522 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 523 VCN, inst_idx, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect); 524 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 525 VCN, inst_idx, regUVD_VCPU_NONCACHE_SIZE0), 526 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect); 527 528 /* VCN global tiling registers */ 529 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 530 VCN, inst_idx, regUVD_GFX10_ADDR_CONFIG), 531 adev->gfx.config.gb_addr_config, 0, indirect); 532 } 533 534 /** 535 * vcn_v4_0_5_disable_static_power_gating - disable VCN static power gating 536 * 537 * @adev: amdgpu_device pointer 538 * @inst: instance number 539 * 540 * Disable static power gating for VCN block 541 */ 542 static void vcn_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst) 543 { 544 uint32_t data = 0; 545 546 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { 547 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 548 1 << UVD_IPX_DLDO_CONFIG__ONO2_PWR_CONFIG__SHIFT); 549 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 0, 550 UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS_MASK); 551 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 552 2 << UVD_IPX_DLDO_CONFIG__ONO3_PWR_CONFIG__SHIFT); 553 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 554 1 << UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS__SHIFT, 555 UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS_MASK); 556 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 557 2 << UVD_IPX_DLDO_CONFIG__ONO4_PWR_CONFIG__SHIFT); 558 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 559 1 << UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS__SHIFT, 560 UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS_MASK); 561 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 562 2 << UVD_IPX_DLDO_CONFIG__ONO5_PWR_CONFIG__SHIFT); 563 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 564 1 << UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS__SHIFT, 565 UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS_MASK); 566 } else { 567 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 568 1 << UVD_IPX_DLDO_CONFIG__ONO2_PWR_CONFIG__SHIFT); 569 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 570 0, UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS_MASK); 571 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 572 1 << UVD_IPX_DLDO_CONFIG__ONO3_PWR_CONFIG__SHIFT); 573 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 574 0, UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS_MASK); 575 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 576 1 << UVD_IPX_DLDO_CONFIG__ONO4_PWR_CONFIG__SHIFT); 577 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 578 0, UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS_MASK); 579 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 580 1 << UVD_IPX_DLDO_CONFIG__ONO5_PWR_CONFIG__SHIFT); 581 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 582 0, UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS_MASK); 583 } 584 585 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS); 586 data &= ~0x103; 587 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) 588 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | 589 UVD_POWER_STATUS__UVD_PG_EN_MASK; 590 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data); 591 } 592 593 /** 594 * vcn_v4_0_5_enable_static_power_gating - enable VCN static power gating 595 * 596 * @adev: amdgpu_device pointer 597 * @inst: instance number 598 * 599 * Enable static power gating for VCN block 600 */ 601 static void vcn_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst) 602 { 603 uint32_t data; 604 605 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { 606 /* Before power off, this indicator has to be turned on */ 607 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS); 608 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK; 609 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; 610 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data); 611 612 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 613 2 << UVD_IPX_DLDO_CONFIG__ONO5_PWR_CONFIG__SHIFT); 614 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 615 1 << UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS__SHIFT, 616 UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS_MASK); 617 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 618 2 << UVD_IPX_DLDO_CONFIG__ONO4_PWR_CONFIG__SHIFT); 619 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 620 1 << UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS__SHIFT, 621 UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS_MASK); 622 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 623 2 << UVD_IPX_DLDO_CONFIG__ONO3_PWR_CONFIG__SHIFT); 624 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 625 1 << UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS__SHIFT, 626 UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS_MASK); 627 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG, 628 2 << UVD_IPX_DLDO_CONFIG__ONO2_PWR_CONFIG__SHIFT); 629 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 630 1 << UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS__SHIFT, 631 UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS_MASK); 632 } 633 } 634 635 /** 636 * vcn_v4_0_5_disable_clock_gating - disable VCN clock gating 637 * 638 * @adev: amdgpu_device pointer 639 * @inst: instance number 640 * 641 * Disable clock gating for VCN block 642 */ 643 static void vcn_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst) 644 { 645 uint32_t data; 646 647 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 648 return; 649 650 /* VCN disable CGC */ 651 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 652 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; 653 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 654 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 655 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 656 657 data = RREG32_SOC15(VCN, inst, regUVD_CGC_GATE); 658 data &= ~(UVD_CGC_GATE__SYS_MASK 659 | UVD_CGC_GATE__UDEC_MASK 660 | UVD_CGC_GATE__MPEG2_MASK 661 | UVD_CGC_GATE__REGS_MASK 662 | UVD_CGC_GATE__RBC_MASK 663 | UVD_CGC_GATE__LMI_MC_MASK 664 | UVD_CGC_GATE__LMI_UMC_MASK 665 | UVD_CGC_GATE__IDCT_MASK 666 | UVD_CGC_GATE__MPRD_MASK 667 | UVD_CGC_GATE__MPC_MASK 668 | UVD_CGC_GATE__LBSI_MASK 669 | UVD_CGC_GATE__LRBBM_MASK 670 | UVD_CGC_GATE__UDEC_RE_MASK 671 | UVD_CGC_GATE__UDEC_CM_MASK 672 | UVD_CGC_GATE__UDEC_IT_MASK 673 | UVD_CGC_GATE__UDEC_DB_MASK 674 | UVD_CGC_GATE__UDEC_MP_MASK 675 | UVD_CGC_GATE__WCB_MASK 676 | UVD_CGC_GATE__VCPU_MASK 677 | UVD_CGC_GATE__MMSCH_MASK); 678 679 WREG32_SOC15(VCN, inst, regUVD_CGC_GATE, data); 680 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_CGC_GATE, 0, 0xFFFFFFFF); 681 682 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 683 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK 684 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK 685 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK 686 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK 687 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK 688 | UVD_CGC_CTRL__SYS_MODE_MASK 689 | UVD_CGC_CTRL__UDEC_MODE_MASK 690 | UVD_CGC_CTRL__MPEG2_MODE_MASK 691 | UVD_CGC_CTRL__REGS_MODE_MASK 692 | UVD_CGC_CTRL__RBC_MODE_MASK 693 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 694 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 695 | UVD_CGC_CTRL__IDCT_MODE_MASK 696 | UVD_CGC_CTRL__MPRD_MODE_MASK 697 | UVD_CGC_CTRL__MPC_MODE_MASK 698 | UVD_CGC_CTRL__LBSI_MODE_MASK 699 | UVD_CGC_CTRL__LRBBM_MODE_MASK 700 | UVD_CGC_CTRL__WCB_MODE_MASK 701 | UVD_CGC_CTRL__VCPU_MODE_MASK 702 | UVD_CGC_CTRL__MMSCH_MODE_MASK); 703 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 704 705 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE); 706 data |= (UVD_SUVD_CGC_GATE__SRE_MASK 707 | UVD_SUVD_CGC_GATE__SIT_MASK 708 | UVD_SUVD_CGC_GATE__SMP_MASK 709 | UVD_SUVD_CGC_GATE__SCM_MASK 710 | UVD_SUVD_CGC_GATE__SDB_MASK 711 | UVD_SUVD_CGC_GATE__SRE_H264_MASK 712 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK 713 | UVD_SUVD_CGC_GATE__SIT_H264_MASK 714 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK 715 | UVD_SUVD_CGC_GATE__SCM_H264_MASK 716 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK 717 | UVD_SUVD_CGC_GATE__SDB_H264_MASK 718 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK 719 | UVD_SUVD_CGC_GATE__SCLR_MASK 720 | UVD_SUVD_CGC_GATE__UVD_SC_MASK 721 | UVD_SUVD_CGC_GATE__ENT_MASK 722 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK 723 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK 724 | UVD_SUVD_CGC_GATE__SITE_MASK 725 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK 726 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK 727 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK 728 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK 729 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK); 730 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE, data); 731 732 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL); 733 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 734 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 735 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 736 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 737 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 738 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK 739 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK 740 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 741 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 742 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 743 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data); 744 } 745 746 /** 747 * vcn_v4_0_5_disable_clock_gating_dpg_mode - disable VCN clock gating dpg mode 748 * 749 * @adev: amdgpu_device pointer 750 * @sram_sel: sram select 751 * @inst_idx: instance number index 752 * @indirect: indirectly write sram 753 * 754 * Disable clock gating for VCN block with dpg mode 755 */ 756 static void vcn_v4_0_5_disable_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel, 757 int inst_idx, uint8_t indirect) 758 { 759 uint32_t reg_data = 0; 760 761 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 762 return; 763 764 /* enable sw clock gating control */ 765 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 766 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 767 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 768 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK | 769 UVD_CGC_CTRL__UDEC_CM_MODE_MASK | 770 UVD_CGC_CTRL__UDEC_IT_MODE_MASK | 771 UVD_CGC_CTRL__UDEC_DB_MODE_MASK | 772 UVD_CGC_CTRL__UDEC_MP_MODE_MASK | 773 UVD_CGC_CTRL__SYS_MODE_MASK | 774 UVD_CGC_CTRL__UDEC_MODE_MASK | 775 UVD_CGC_CTRL__MPEG2_MODE_MASK | 776 UVD_CGC_CTRL__REGS_MODE_MASK | 777 UVD_CGC_CTRL__RBC_MODE_MASK | 778 UVD_CGC_CTRL__LMI_MC_MODE_MASK | 779 UVD_CGC_CTRL__LMI_UMC_MODE_MASK | 780 UVD_CGC_CTRL__IDCT_MODE_MASK | 781 UVD_CGC_CTRL__MPRD_MODE_MASK | 782 UVD_CGC_CTRL__MPC_MODE_MASK | 783 UVD_CGC_CTRL__LBSI_MODE_MASK | 784 UVD_CGC_CTRL__LRBBM_MODE_MASK | 785 UVD_CGC_CTRL__WCB_MODE_MASK | 786 UVD_CGC_CTRL__VCPU_MODE_MASK); 787 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 788 VCN, inst_idx, regUVD_CGC_CTRL), reg_data, sram_sel, indirect); 789 790 /* turn off clock gating */ 791 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 792 VCN, inst_idx, regUVD_CGC_GATE), 0, sram_sel, indirect); 793 794 /* turn on SUVD clock gating */ 795 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 796 VCN, inst_idx, regUVD_SUVD_CGC_GATE), 1, sram_sel, indirect); 797 798 /* turn on sw mode in UVD_SUVD_CGC_CTRL */ 799 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 800 VCN, inst_idx, regUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect); 801 } 802 803 /** 804 * vcn_v4_0_5_enable_clock_gating - enable VCN clock gating 805 * 806 * @adev: amdgpu_device pointer 807 * @inst: instance number 808 * 809 * Enable clock gating for VCN block 810 */ 811 static void vcn_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst) 812 { 813 uint32_t data; 814 815 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 816 return; 817 818 /* enable VCN CGC */ 819 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 820 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 821 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 822 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 823 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 824 825 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL); 826 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK 827 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK 828 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK 829 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK 830 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK 831 | UVD_CGC_CTRL__SYS_MODE_MASK 832 | UVD_CGC_CTRL__UDEC_MODE_MASK 833 | UVD_CGC_CTRL__MPEG2_MODE_MASK 834 | UVD_CGC_CTRL__REGS_MODE_MASK 835 | UVD_CGC_CTRL__RBC_MODE_MASK 836 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 837 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 838 | UVD_CGC_CTRL__IDCT_MODE_MASK 839 | UVD_CGC_CTRL__MPRD_MODE_MASK 840 | UVD_CGC_CTRL__MPC_MODE_MASK 841 | UVD_CGC_CTRL__LBSI_MODE_MASK 842 | UVD_CGC_CTRL__LRBBM_MODE_MASK 843 | UVD_CGC_CTRL__WCB_MODE_MASK 844 | UVD_CGC_CTRL__VCPU_MODE_MASK 845 | UVD_CGC_CTRL__MMSCH_MODE_MASK); 846 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data); 847 848 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL); 849 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 850 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 851 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 852 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 853 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 854 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK 855 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK 856 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 857 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 858 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 859 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data); 860 } 861 862 /** 863 * vcn_v4_0_5_start_dpg_mode - VCN start with dpg mode 864 * 865 * @adev: amdgpu_device pointer 866 * @inst_idx: instance number index 867 * @indirect: indirectly write sram 868 * 869 * Start VCN block with dpg mode 870 */ 871 static int vcn_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 872 { 873 volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 874 struct amdgpu_ring *ring; 875 uint32_t tmp; 876 877 /* disable register anti-hang mechanism */ 878 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1, 879 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 880 /* enable dynamic power gating mode */ 881 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS); 882 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; 883 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK; 884 WREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS, tmp); 885 886 if (indirect) 887 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = 888 (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; 889 890 /* enable clock gating */ 891 vcn_v4_0_5_disable_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); 892 893 /* enable VCPU clock */ 894 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 895 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK; 896 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 897 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect); 898 899 /* disable master interrupt */ 900 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 901 VCN, inst_idx, regUVD_MASTINT_EN), 0, 0, indirect); 902 903 /* setup regUVD_LMI_CTRL */ 904 tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 905 UVD_LMI_CTRL__REQ_MODE_MASK | 906 UVD_LMI_CTRL__CRC_RESET_MASK | 907 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 908 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 909 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 910 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 911 0x00100000L); 912 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 913 VCN, inst_idx, regUVD_LMI_CTRL), tmp, 0, indirect); 914 915 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 916 VCN, inst_idx, regUVD_MPC_CNTL), 917 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect); 918 919 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 920 VCN, inst_idx, regUVD_MPC_SET_MUXA0), 921 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 922 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 923 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 924 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect); 925 926 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 927 VCN, inst_idx, regUVD_MPC_SET_MUXB0), 928 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 929 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 930 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 931 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect); 932 933 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 934 VCN, inst_idx, regUVD_MPC_SET_MUX), 935 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 936 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 937 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect); 938 939 vcn_v4_0_5_mc_resume_dpg_mode(adev, inst_idx, indirect); 940 941 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 942 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 943 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 944 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect); 945 946 /* enable LMI MC and UMC channels */ 947 tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT; 948 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 949 VCN, inst_idx, regUVD_LMI_CTRL2), tmp, 0, indirect); 950 951 /* enable master interrupt */ 952 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 953 VCN, inst_idx, regUVD_MASTINT_EN), 954 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 955 956 if (indirect) 957 amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 958 959 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 960 961 WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_LO, ring->gpu_addr); 962 WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 963 WREG32_SOC15(VCN, inst_idx, regUVD_RB_SIZE, ring->ring_size / 4); 964 965 tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE); 966 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 967 WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp); 968 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 969 WREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR, 0); 970 WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, 0); 971 972 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR); 973 WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, tmp); 974 ring->wptr = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR); 975 976 tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE); 977 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 978 WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp); 979 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 980 981 WREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL, 982 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 983 VCN_RB1_DB_CTRL__EN_MASK); 984 985 return 0; 986 } 987 988 989 /** 990 * vcn_v4_0_5_start - VCN start 991 * 992 * @adev: amdgpu_device pointer 993 * 994 * Start VCN block 995 */ 996 static int vcn_v4_0_5_start(struct amdgpu_device *adev) 997 { 998 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 999 struct amdgpu_ring *ring; 1000 uint32_t tmp; 1001 int i, j, k, r; 1002 1003 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1004 if (adev->pm.dpm_enabled) 1005 amdgpu_dpm_enable_vcn(adev, true, i); 1006 } 1007 1008 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1009 if (adev->vcn.harvest_config & (1 << i)) 1010 continue; 1011 1012 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1013 1014 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1015 r = vcn_v4_0_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram); 1016 continue; 1017 } 1018 1019 /* disable VCN power gating */ 1020 vcn_v4_0_5_disable_static_power_gating(adev, i); 1021 1022 /* set VCN status busy */ 1023 tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; 1024 WREG32_SOC15(VCN, i, regUVD_STATUS, tmp); 1025 1026 /*SW clock gating */ 1027 vcn_v4_0_5_disable_clock_gating(adev, i); 1028 1029 /* enable VCPU clock */ 1030 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1031 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); 1032 1033 /* disable master interrupt */ 1034 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0, 1035 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1036 1037 /* enable LMI MC and UMC channels */ 1038 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0, 1039 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1040 1041 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1042 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1043 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1044 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1045 1046 /* setup regUVD_LMI_CTRL */ 1047 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL); 1048 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp | 1049 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1050 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1051 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1052 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 1053 1054 /* setup regUVD_MPC_CNTL */ 1055 tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL); 1056 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; 1057 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; 1058 WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp); 1059 1060 /* setup UVD_MPC_SET_MUXA0 */ 1061 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0, 1062 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1063 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1064 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1065 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); 1066 1067 /* setup UVD_MPC_SET_MUXB0 */ 1068 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0, 1069 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1070 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1071 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1072 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); 1073 1074 /* setup UVD_MPC_SET_MUX */ 1075 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX, 1076 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1077 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1078 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); 1079 1080 vcn_v4_0_5_mc_resume(adev, i); 1081 1082 /* VCN global tiling registers */ 1083 WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG, 1084 adev->gfx.config.gb_addr_config); 1085 1086 /* unblock VCPU register access */ 1087 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0, 1088 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1089 1090 /* release VCPU reset to boot */ 1091 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1092 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1093 1094 for (j = 0; j < 10; ++j) { 1095 uint32_t status; 1096 1097 for (k = 0; k < 100; ++k) { 1098 status = RREG32_SOC15(VCN, i, regUVD_STATUS); 1099 if (status & 2) 1100 break; 1101 mdelay(10); 1102 if (amdgpu_emu_mode == 1) 1103 msleep(1); 1104 } 1105 1106 if (amdgpu_emu_mode == 1) { 1107 r = -1; 1108 if (status & 2) { 1109 r = 0; 1110 break; 1111 } 1112 } else { 1113 r = 0; 1114 if (status & 2) 1115 break; 1116 1117 dev_err(adev->dev, 1118 "VCN[%d] is not responding, trying to reset VCPU!!!\n", i); 1119 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1120 UVD_VCPU_CNTL__BLK_RST_MASK, 1121 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1122 mdelay(10); 1123 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1124 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1125 1126 mdelay(10); 1127 r = -1; 1128 } 1129 } 1130 1131 if (r) { 1132 dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i); 1133 return r; 1134 } 1135 1136 /* enable master interrupt */ 1137 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 1138 UVD_MASTINT_EN__VCPU_EN_MASK, 1139 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1140 1141 /* clear the busy bit of VCN_STATUS */ 1142 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0, 1143 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 1144 1145 ring = &adev->vcn.inst[i].ring_enc[0]; 1146 WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL, 1147 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 1148 VCN_RB1_DB_CTRL__EN_MASK); 1149 1150 WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr); 1151 WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1152 WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4); 1153 1154 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); 1155 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 1156 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); 1157 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 1158 WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0); 1159 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0); 1160 1161 tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR); 1162 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp); 1163 ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR); 1164 1165 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); 1166 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 1167 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); 1168 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 1169 } 1170 1171 return 0; 1172 } 1173 1174 /** 1175 * vcn_v4_0_5_stop_dpg_mode - VCN stop with dpg mode 1176 * 1177 * @adev: amdgpu_device pointer 1178 * @inst_idx: instance number index 1179 * 1180 * Stop VCN block with dpg mode 1181 */ 1182 static void vcn_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 1183 { 1184 uint32_t tmp; 1185 1186 /* Wait for power status to be 1 */ 1187 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1188 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1189 1190 /* wait for read ptr to be equal to write ptr */ 1191 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR); 1192 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1193 1194 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1195 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1196 1197 /* disable dynamic power gating mode */ 1198 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0, 1199 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1200 } 1201 1202 /** 1203 * vcn_v4_0_5_stop - VCN stop 1204 * 1205 * @adev: amdgpu_device pointer 1206 * 1207 * Stop VCN block 1208 */ 1209 static int vcn_v4_0_5_stop(struct amdgpu_device *adev) 1210 { 1211 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1212 uint32_t tmp; 1213 int i, r = 0; 1214 1215 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1216 if (adev->vcn.harvest_config & (1 << i)) 1217 continue; 1218 1219 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1220 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; 1221 1222 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1223 vcn_v4_0_5_stop_dpg_mode(adev, i); 1224 continue; 1225 } 1226 1227 /* wait for vcn idle */ 1228 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1229 if (r) 1230 return r; 1231 1232 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1233 UVD_LMI_STATUS__READ_CLEAN_MASK | 1234 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1235 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1236 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1237 if (r) 1238 return r; 1239 1240 /* disable LMI UMC channel */ 1241 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2); 1242 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1243 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp); 1244 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | 1245 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1246 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1247 if (r) 1248 return r; 1249 1250 /* block VCPU register access */ 1251 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 1252 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1253 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1254 1255 /* reset VCPU */ 1256 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1257 UVD_VCPU_CNTL__BLK_RST_MASK, 1258 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1259 1260 /* disable VCPU clock */ 1261 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1262 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1263 1264 /* apply soft reset */ 1265 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1266 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1267 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1268 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1269 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1270 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1271 1272 /* clear status */ 1273 WREG32_SOC15(VCN, i, regUVD_STATUS, 0); 1274 1275 /* apply HW clock gating */ 1276 vcn_v4_0_5_enable_clock_gating(adev, i); 1277 1278 /* enable VCN power gating */ 1279 vcn_v4_0_5_enable_static_power_gating(adev, i); 1280 } 1281 1282 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1283 if (adev->pm.dpm_enabled) 1284 amdgpu_dpm_enable_vcn(adev, false, i); 1285 } 1286 1287 return 0; 1288 } 1289 1290 /** 1291 * vcn_v4_0_5_pause_dpg_mode - VCN pause with dpg mode 1292 * 1293 * @adev: amdgpu_device pointer 1294 * @inst_idx: instance number index 1295 * @new_state: pause state 1296 * 1297 * Pause dpg mode for VCN block 1298 */ 1299 static int vcn_v4_0_5_pause_dpg_mode(struct amdgpu_device *adev, int inst_idx, 1300 struct dpg_pause_state *new_state) 1301 { 1302 uint32_t reg_data = 0; 1303 int ret_code; 1304 1305 /* pause/unpause if state is changed */ 1306 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) { 1307 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d", 1308 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based); 1309 reg_data = RREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE) & 1310 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1311 1312 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { 1313 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 0x1, 1314 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1315 1316 if (!ret_code) { 1317 /* pause DPG */ 1318 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1319 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1320 1321 /* wait for ACK */ 1322 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_DPG_PAUSE, 1323 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, 1324 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1325 1326 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1327 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, 1328 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1329 } 1330 } else { 1331 /* unpause dpg, no need to wait */ 1332 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1333 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1334 } 1335 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based; 1336 } 1337 1338 return 0; 1339 } 1340 1341 /** 1342 * vcn_v4_0_5_unified_ring_get_rptr - get unified read pointer 1343 * 1344 * @ring: amdgpu_ring pointer 1345 * 1346 * Returns the current hardware unified read pointer 1347 */ 1348 static uint64_t vcn_v4_0_5_unified_ring_get_rptr(struct amdgpu_ring *ring) 1349 { 1350 struct amdgpu_device *adev = ring->adev; 1351 1352 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1353 DRM_ERROR("wrong ring id is identified in %s", __func__); 1354 1355 return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR); 1356 } 1357 1358 /** 1359 * vcn_v4_0_5_unified_ring_get_wptr - get unified write pointer 1360 * 1361 * @ring: amdgpu_ring pointer 1362 * 1363 * Returns the current hardware unified write pointer 1364 */ 1365 static uint64_t vcn_v4_0_5_unified_ring_get_wptr(struct amdgpu_ring *ring) 1366 { 1367 struct amdgpu_device *adev = ring->adev; 1368 1369 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1370 DRM_ERROR("wrong ring id is identified in %s", __func__); 1371 1372 if (ring->use_doorbell) 1373 return *ring->wptr_cpu_addr; 1374 else 1375 return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR); 1376 } 1377 1378 /** 1379 * vcn_v4_0_5_unified_ring_set_wptr - set enc write pointer 1380 * 1381 * @ring: amdgpu_ring pointer 1382 * 1383 * Commits the enc write pointer to the hardware 1384 */ 1385 static void vcn_v4_0_5_unified_ring_set_wptr(struct amdgpu_ring *ring) 1386 { 1387 struct amdgpu_device *adev = ring->adev; 1388 1389 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1390 DRM_ERROR("wrong ring id is identified in %s", __func__); 1391 1392 if (ring->use_doorbell) { 1393 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1394 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1395 } else { 1396 WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1397 } 1398 } 1399 1400 static const struct amdgpu_ring_funcs vcn_v4_0_5_unified_ring_vm_funcs = { 1401 .type = AMDGPU_RING_TYPE_VCN_ENC, 1402 .align_mask = 0x3f, 1403 .nop = VCN_ENC_CMD_NO_OP, 1404 .get_rptr = vcn_v4_0_5_unified_ring_get_rptr, 1405 .get_wptr = vcn_v4_0_5_unified_ring_get_wptr, 1406 .set_wptr = vcn_v4_0_5_unified_ring_set_wptr, 1407 .emit_frame_size = 1408 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1409 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1410 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1411 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 1412 1, /* vcn_v2_0_enc_ring_insert_end */ 1413 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 1414 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 1415 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 1416 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush, 1417 .test_ring = amdgpu_vcn_enc_ring_test_ring, 1418 .test_ib = amdgpu_vcn_unified_ring_test_ib, 1419 .insert_nop = amdgpu_ring_insert_nop, 1420 .insert_end = vcn_v2_0_enc_ring_insert_end, 1421 .pad_ib = amdgpu_ring_generic_pad_ib, 1422 .begin_use = amdgpu_vcn_ring_begin_use, 1423 .end_use = amdgpu_vcn_ring_end_use, 1424 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg, 1425 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait, 1426 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1427 }; 1428 1429 /** 1430 * vcn_v4_0_5_set_unified_ring_funcs - set unified ring functions 1431 * 1432 * @adev: amdgpu_device pointer 1433 * 1434 * Set unified ring functions 1435 */ 1436 static void vcn_v4_0_5_set_unified_ring_funcs(struct amdgpu_device *adev) 1437 { 1438 int i; 1439 1440 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1441 if (adev->vcn.harvest_config & (1 << i)) 1442 continue; 1443 1444 adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v4_0_5_unified_ring_vm_funcs; 1445 adev->vcn.inst[i].ring_enc[0].me = i; 1446 } 1447 } 1448 1449 /** 1450 * vcn_v4_0_5_is_idle - check VCN block is idle 1451 * 1452 * @handle: amdgpu_device pointer 1453 * 1454 * Check whether VCN block is idle 1455 */ 1456 static bool vcn_v4_0_5_is_idle(void *handle) 1457 { 1458 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1459 int i, ret = 1; 1460 1461 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1462 if (adev->vcn.harvest_config & (1 << i)) 1463 continue; 1464 1465 ret &= (RREG32_SOC15(VCN, i, regUVD_STATUS) == UVD_STATUS__IDLE); 1466 } 1467 1468 return ret; 1469 } 1470 1471 /** 1472 * vcn_v4_0_5_wait_for_idle - wait for VCN block idle 1473 * 1474 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 1475 * 1476 * Wait for VCN block idle 1477 */ 1478 static int vcn_v4_0_5_wait_for_idle(struct amdgpu_ip_block *ip_block) 1479 { 1480 struct amdgpu_device *adev = ip_block->adev; 1481 int i, ret = 0; 1482 1483 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1484 if (adev->vcn.harvest_config & (1 << i)) 1485 continue; 1486 1487 ret = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 1488 UVD_STATUS__IDLE); 1489 if (ret) 1490 return ret; 1491 } 1492 1493 return ret; 1494 } 1495 1496 /** 1497 * vcn_v4_0_5_set_clockgating_state - set VCN block clockgating state 1498 * 1499 * @ip_block: amdgpu_ip_block pointer 1500 * @state: clock gating state 1501 * 1502 * Set VCN block clockgating state 1503 */ 1504 static int vcn_v4_0_5_set_clockgating_state(struct amdgpu_ip_block *ip_block, 1505 enum amd_clockgating_state state) 1506 { 1507 struct amdgpu_device *adev = ip_block->adev; 1508 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 1509 int i; 1510 1511 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1512 if (adev->vcn.harvest_config & (1 << i)) 1513 continue; 1514 1515 if (enable) { 1516 if (RREG32_SOC15(VCN, i, regUVD_STATUS) != UVD_STATUS__IDLE) 1517 return -EBUSY; 1518 vcn_v4_0_5_enable_clock_gating(adev, i); 1519 } else { 1520 vcn_v4_0_5_disable_clock_gating(adev, i); 1521 } 1522 } 1523 1524 return 0; 1525 } 1526 1527 /** 1528 * vcn_v4_0_5_set_powergating_state - set VCN block powergating state 1529 * 1530 * @ip_block: amdgpu_ip_block pointer 1531 * @state: power gating state 1532 * 1533 * Set VCN block powergating state 1534 */ 1535 static int vcn_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block, 1536 enum amd_powergating_state state) 1537 { 1538 struct amdgpu_device *adev = ip_block->adev; 1539 int ret; 1540 1541 if (state == adev->vcn.cur_state) 1542 return 0; 1543 1544 if (state == AMD_PG_STATE_GATE) 1545 ret = vcn_v4_0_5_stop(adev); 1546 else 1547 ret = vcn_v4_0_5_start(adev); 1548 1549 if (!ret) 1550 adev->vcn.cur_state = state; 1551 1552 return ret; 1553 } 1554 1555 /** 1556 * vcn_v4_0_5_process_interrupt - process VCN block interrupt 1557 * 1558 * @adev: amdgpu_device pointer 1559 * @source: interrupt sources 1560 * @entry: interrupt entry from clients and sources 1561 * 1562 * Process VCN block interrupt 1563 */ 1564 static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, 1565 struct amdgpu_iv_entry *entry) 1566 { 1567 uint32_t ip_instance; 1568 1569 switch (entry->client_id) { 1570 case SOC15_IH_CLIENTID_VCN: 1571 ip_instance = 0; 1572 break; 1573 case SOC15_IH_CLIENTID_VCN1: 1574 ip_instance = 1; 1575 break; 1576 default: 1577 DRM_ERROR("Unhandled client id: %d\n", entry->client_id); 1578 return 0; 1579 } 1580 1581 DRM_DEBUG("IH: VCN TRAP\n"); 1582 1583 switch (entry->src_id) { 1584 case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 1585 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]); 1586 break; 1587 case VCN_4_0__SRCID_UVD_POISON: 1588 amdgpu_vcn_process_poison_irq(adev, source, entry); 1589 break; 1590 default: 1591 DRM_ERROR("Unhandled interrupt: %d %d\n", 1592 entry->src_id, entry->src_data[0]); 1593 break; 1594 } 1595 1596 return 0; 1597 } 1598 1599 static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = { 1600 .process = vcn_v4_0_5_process_interrupt, 1601 }; 1602 1603 /** 1604 * vcn_v4_0_5_set_irq_funcs - set VCN block interrupt irq functions 1605 * 1606 * @adev: amdgpu_device pointer 1607 * 1608 * Set VCN block interrupt irq functions 1609 */ 1610 static void vcn_v4_0_5_set_irq_funcs(struct amdgpu_device *adev) 1611 { 1612 int i; 1613 1614 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1615 if (adev->vcn.harvest_config & (1 << i)) 1616 continue; 1617 1618 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1; 1619 adev->vcn.inst[i].irq.funcs = &vcn_v4_0_5_irq_funcs; 1620 } 1621 } 1622 1623 static void vcn_v4_0_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 1624 { 1625 struct amdgpu_device *adev = ip_block->adev; 1626 int i, j; 1627 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 1628 uint32_t inst_off, is_powered; 1629 1630 if (!adev->vcn.ip_dump) 1631 return; 1632 1633 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1634 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1635 if (adev->vcn.harvest_config & (1 << i)) { 1636 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1637 continue; 1638 } 1639 1640 inst_off = i * reg_count; 1641 is_powered = (adev->vcn.ip_dump[inst_off] & 1642 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1643 1644 if (is_powered) { 1645 drm_printf(p, "\nActive Instance:VCN%d\n", i); 1646 for (j = 0; j < reg_count; j++) 1647 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_5[j].reg_name, 1648 adev->vcn.ip_dump[inst_off + j]); 1649 } else { 1650 drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1651 } 1652 } 1653 } 1654 1655 static void vcn_v4_0_5_dump_ip_state(struct amdgpu_ip_block *ip_block) 1656 { 1657 struct amdgpu_device *adev = ip_block->adev; 1658 int i, j; 1659 bool is_powered; 1660 uint32_t inst_off; 1661 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 1662 1663 if (!adev->vcn.ip_dump) 1664 return; 1665 1666 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1667 if (adev->vcn.harvest_config & (1 << i)) 1668 continue; 1669 1670 inst_off = i * reg_count; 1671 /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 1672 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); 1673 is_powered = (adev->vcn.ip_dump[inst_off] & 1674 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1675 1676 if (is_powered) 1677 for (j = 1; j < reg_count; j++) 1678 adev->vcn.ip_dump[inst_off + j] = 1679 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_5[j], 1680 i)); 1681 } 1682 } 1683 1684 static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = { 1685 .name = "vcn_v4_0_5", 1686 .early_init = vcn_v4_0_5_early_init, 1687 .sw_init = vcn_v4_0_5_sw_init, 1688 .sw_fini = vcn_v4_0_5_sw_fini, 1689 .hw_init = vcn_v4_0_5_hw_init, 1690 .hw_fini = vcn_v4_0_5_hw_fini, 1691 .suspend = vcn_v4_0_5_suspend, 1692 .resume = vcn_v4_0_5_resume, 1693 .is_idle = vcn_v4_0_5_is_idle, 1694 .wait_for_idle = vcn_v4_0_5_wait_for_idle, 1695 .set_clockgating_state = vcn_v4_0_5_set_clockgating_state, 1696 .set_powergating_state = vcn_v4_0_5_set_powergating_state, 1697 .dump_ip_state = vcn_v4_0_5_dump_ip_state, 1698 .print_ip_state = vcn_v4_0_5_print_ip_state, 1699 }; 1700 1701 const struct amdgpu_ip_block_version vcn_v4_0_5_ip_block = { 1702 .type = AMD_IP_BLOCK_TYPE_VCN, 1703 .major = 4, 1704 .minor = 0, 1705 .rev = 5, 1706 .funcs = &vcn_v4_0_5_ip_funcs, 1707 }; 1708