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(void *handle, 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(adev, 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.fw[inst]->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.fw[inst_idx]->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 if (adev->pm.dpm_enabled) 1004 amdgpu_dpm_enable_uvd(adev, true); 1005 1006 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1007 if (adev->vcn.harvest_config & (1 << i)) 1008 continue; 1009 1010 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1011 1012 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1013 r = vcn_v4_0_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram); 1014 continue; 1015 } 1016 1017 /* disable VCN power gating */ 1018 vcn_v4_0_5_disable_static_power_gating(adev, i); 1019 1020 /* set VCN status busy */ 1021 tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; 1022 WREG32_SOC15(VCN, i, regUVD_STATUS, tmp); 1023 1024 /*SW clock gating */ 1025 vcn_v4_0_5_disable_clock_gating(adev, i); 1026 1027 /* enable VCPU clock */ 1028 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1029 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); 1030 1031 /* disable master interrupt */ 1032 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0, 1033 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1034 1035 /* enable LMI MC and UMC channels */ 1036 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0, 1037 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1038 1039 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1040 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1041 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1042 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1043 1044 /* setup regUVD_LMI_CTRL */ 1045 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL); 1046 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp | 1047 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1048 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1049 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1050 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 1051 1052 /* setup regUVD_MPC_CNTL */ 1053 tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL); 1054 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; 1055 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; 1056 WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp); 1057 1058 /* setup UVD_MPC_SET_MUXA0 */ 1059 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0, 1060 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1061 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1062 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1063 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); 1064 1065 /* setup UVD_MPC_SET_MUXB0 */ 1066 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0, 1067 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1068 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1069 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1070 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); 1071 1072 /* setup UVD_MPC_SET_MUX */ 1073 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX, 1074 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1075 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1076 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); 1077 1078 vcn_v4_0_5_mc_resume(adev, i); 1079 1080 /* VCN global tiling registers */ 1081 WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG, 1082 adev->gfx.config.gb_addr_config); 1083 1084 /* unblock VCPU register access */ 1085 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0, 1086 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1087 1088 /* release VCPU reset to boot */ 1089 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1090 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1091 1092 for (j = 0; j < 10; ++j) { 1093 uint32_t status; 1094 1095 for (k = 0; k < 100; ++k) { 1096 status = RREG32_SOC15(VCN, i, regUVD_STATUS); 1097 if (status & 2) 1098 break; 1099 mdelay(10); 1100 if (amdgpu_emu_mode == 1) 1101 msleep(1); 1102 } 1103 1104 if (amdgpu_emu_mode == 1) { 1105 r = -1; 1106 if (status & 2) { 1107 r = 0; 1108 break; 1109 } 1110 } else { 1111 r = 0; 1112 if (status & 2) 1113 break; 1114 1115 dev_err(adev->dev, 1116 "VCN[%d] is not responding, trying to reset VCPU!!!\n", i); 1117 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1118 UVD_VCPU_CNTL__BLK_RST_MASK, 1119 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1120 mdelay(10); 1121 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1122 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1123 1124 mdelay(10); 1125 r = -1; 1126 } 1127 } 1128 1129 if (r) { 1130 dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i); 1131 return r; 1132 } 1133 1134 /* enable master interrupt */ 1135 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 1136 UVD_MASTINT_EN__VCPU_EN_MASK, 1137 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1138 1139 /* clear the busy bit of VCN_STATUS */ 1140 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0, 1141 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 1142 1143 ring = &adev->vcn.inst[i].ring_enc[0]; 1144 WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL, 1145 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | 1146 VCN_RB1_DB_CTRL__EN_MASK); 1147 1148 WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr); 1149 WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1150 WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4); 1151 1152 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); 1153 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); 1154 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); 1155 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; 1156 WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0); 1157 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0); 1158 1159 tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR); 1160 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp); 1161 ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR); 1162 1163 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); 1164 tmp |= VCN_RB_ENABLE__RB1_EN_MASK; 1165 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); 1166 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); 1167 } 1168 1169 return 0; 1170 } 1171 1172 /** 1173 * vcn_v4_0_5_stop_dpg_mode - VCN stop with dpg mode 1174 * 1175 * @adev: amdgpu_device pointer 1176 * @inst_idx: instance number index 1177 * 1178 * Stop VCN block with dpg mode 1179 */ 1180 static void vcn_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 1181 { 1182 uint32_t tmp; 1183 1184 /* Wait for power status to be 1 */ 1185 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1186 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1187 1188 /* wait for read ptr to be equal to write ptr */ 1189 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR); 1190 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1191 1192 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1193 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1194 1195 /* disable dynamic power gating mode */ 1196 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0, 1197 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1198 } 1199 1200 /** 1201 * vcn_v4_0_5_stop - VCN stop 1202 * 1203 * @adev: amdgpu_device pointer 1204 * 1205 * Stop VCN block 1206 */ 1207 static int vcn_v4_0_5_stop(struct amdgpu_device *adev) 1208 { 1209 volatile struct amdgpu_vcn4_fw_shared *fw_shared; 1210 uint32_t tmp; 1211 int i, r = 0; 1212 1213 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1214 if (adev->vcn.harvest_config & (1 << i)) 1215 continue; 1216 1217 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 1218 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF; 1219 1220 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1221 vcn_v4_0_5_stop_dpg_mode(adev, i); 1222 continue; 1223 } 1224 1225 /* wait for vcn idle */ 1226 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1227 if (r) 1228 return r; 1229 1230 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1231 UVD_LMI_STATUS__READ_CLEAN_MASK | 1232 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1233 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1234 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1235 if (r) 1236 return r; 1237 1238 /* disable LMI UMC channel */ 1239 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2); 1240 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1241 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp); 1242 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK | 1243 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1244 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp); 1245 if (r) 1246 return r; 1247 1248 /* block VCPU register access */ 1249 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 1250 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1251 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1252 1253 /* reset VCPU */ 1254 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 1255 UVD_VCPU_CNTL__BLK_RST_MASK, 1256 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1257 1258 /* disable VCPU clock */ 1259 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0, 1260 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1261 1262 /* apply soft reset */ 1263 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1264 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1265 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1266 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET); 1267 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1268 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp); 1269 1270 /* clear status */ 1271 WREG32_SOC15(VCN, i, regUVD_STATUS, 0); 1272 1273 /* apply HW clock gating */ 1274 vcn_v4_0_5_enable_clock_gating(adev, i); 1275 1276 /* enable VCN power gating */ 1277 vcn_v4_0_5_enable_static_power_gating(adev, i); 1278 } 1279 1280 if (adev->pm.dpm_enabled) 1281 amdgpu_dpm_enable_uvd(adev, false); 1282 1283 return 0; 1284 } 1285 1286 /** 1287 * vcn_v4_0_5_pause_dpg_mode - VCN pause with dpg mode 1288 * 1289 * @adev: amdgpu_device pointer 1290 * @inst_idx: instance number index 1291 * @new_state: pause state 1292 * 1293 * Pause dpg mode for VCN block 1294 */ 1295 static int vcn_v4_0_5_pause_dpg_mode(struct amdgpu_device *adev, int inst_idx, 1296 struct dpg_pause_state *new_state) 1297 { 1298 uint32_t reg_data = 0; 1299 int ret_code; 1300 1301 /* pause/unpause if state is changed */ 1302 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) { 1303 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d", 1304 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based); 1305 reg_data = RREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE) & 1306 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1307 1308 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { 1309 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 0x1, 1310 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1311 1312 if (!ret_code) { 1313 /* pause DPG */ 1314 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1315 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1316 1317 /* wait for ACK */ 1318 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_DPG_PAUSE, 1319 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, 1320 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1321 1322 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1323 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, 1324 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1325 } 1326 } else { 1327 /* unpause dpg, no need to wait */ 1328 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1329 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data); 1330 } 1331 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based; 1332 } 1333 1334 return 0; 1335 } 1336 1337 /** 1338 * vcn_v4_0_5_unified_ring_get_rptr - get unified read pointer 1339 * 1340 * @ring: amdgpu_ring pointer 1341 * 1342 * Returns the current hardware unified read pointer 1343 */ 1344 static uint64_t vcn_v4_0_5_unified_ring_get_rptr(struct amdgpu_ring *ring) 1345 { 1346 struct amdgpu_device *adev = ring->adev; 1347 1348 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1349 DRM_ERROR("wrong ring id is identified in %s", __func__); 1350 1351 return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR); 1352 } 1353 1354 /** 1355 * vcn_v4_0_5_unified_ring_get_wptr - get unified write pointer 1356 * 1357 * @ring: amdgpu_ring pointer 1358 * 1359 * Returns the current hardware unified write pointer 1360 */ 1361 static uint64_t vcn_v4_0_5_unified_ring_get_wptr(struct amdgpu_ring *ring) 1362 { 1363 struct amdgpu_device *adev = ring->adev; 1364 1365 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1366 DRM_ERROR("wrong ring id is identified in %s", __func__); 1367 1368 if (ring->use_doorbell) 1369 return *ring->wptr_cpu_addr; 1370 else 1371 return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR); 1372 } 1373 1374 /** 1375 * vcn_v4_0_5_unified_ring_set_wptr - set enc write pointer 1376 * 1377 * @ring: amdgpu_ring pointer 1378 * 1379 * Commits the enc write pointer to the hardware 1380 */ 1381 static void vcn_v4_0_5_unified_ring_set_wptr(struct amdgpu_ring *ring) 1382 { 1383 struct amdgpu_device *adev = ring->adev; 1384 1385 if (ring != &adev->vcn.inst[ring->me].ring_enc[0]) 1386 DRM_ERROR("wrong ring id is identified in %s", __func__); 1387 1388 if (ring->use_doorbell) { 1389 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1390 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1391 } else { 1392 WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1393 } 1394 } 1395 1396 static const struct amdgpu_ring_funcs vcn_v4_0_5_unified_ring_vm_funcs = { 1397 .type = AMDGPU_RING_TYPE_VCN_ENC, 1398 .align_mask = 0x3f, 1399 .nop = VCN_ENC_CMD_NO_OP, 1400 .get_rptr = vcn_v4_0_5_unified_ring_get_rptr, 1401 .get_wptr = vcn_v4_0_5_unified_ring_get_wptr, 1402 .set_wptr = vcn_v4_0_5_unified_ring_set_wptr, 1403 .emit_frame_size = 1404 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1405 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1406 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1407 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 1408 1, /* vcn_v2_0_enc_ring_insert_end */ 1409 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 1410 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 1411 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 1412 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush, 1413 .test_ring = amdgpu_vcn_enc_ring_test_ring, 1414 .test_ib = amdgpu_vcn_unified_ring_test_ib, 1415 .insert_nop = amdgpu_ring_insert_nop, 1416 .insert_end = vcn_v2_0_enc_ring_insert_end, 1417 .pad_ib = amdgpu_ring_generic_pad_ib, 1418 .begin_use = amdgpu_vcn_ring_begin_use, 1419 .end_use = amdgpu_vcn_ring_end_use, 1420 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg, 1421 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait, 1422 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1423 }; 1424 1425 /** 1426 * vcn_v4_0_5_set_unified_ring_funcs - set unified ring functions 1427 * 1428 * @adev: amdgpu_device pointer 1429 * 1430 * Set unified ring functions 1431 */ 1432 static void vcn_v4_0_5_set_unified_ring_funcs(struct amdgpu_device *adev) 1433 { 1434 int i; 1435 1436 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1437 if (adev->vcn.harvest_config & (1 << i)) 1438 continue; 1439 1440 adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v4_0_5_unified_ring_vm_funcs; 1441 adev->vcn.inst[i].ring_enc[0].me = i; 1442 } 1443 } 1444 1445 /** 1446 * vcn_v4_0_5_is_idle - check VCN block is idle 1447 * 1448 * @handle: amdgpu_device pointer 1449 * 1450 * Check whether VCN block is idle 1451 */ 1452 static bool vcn_v4_0_5_is_idle(void *handle) 1453 { 1454 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1455 int i, ret = 1; 1456 1457 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1458 if (adev->vcn.harvest_config & (1 << i)) 1459 continue; 1460 1461 ret &= (RREG32_SOC15(VCN, i, regUVD_STATUS) == UVD_STATUS__IDLE); 1462 } 1463 1464 return ret; 1465 } 1466 1467 /** 1468 * vcn_v4_0_5_wait_for_idle - wait for VCN block idle 1469 * 1470 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 1471 * 1472 * Wait for VCN block idle 1473 */ 1474 static int vcn_v4_0_5_wait_for_idle(struct amdgpu_ip_block *ip_block) 1475 { 1476 struct amdgpu_device *adev = ip_block->adev; 1477 int i, ret = 0; 1478 1479 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1480 if (adev->vcn.harvest_config & (1 << i)) 1481 continue; 1482 1483 ret = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 1484 UVD_STATUS__IDLE); 1485 if (ret) 1486 return ret; 1487 } 1488 1489 return ret; 1490 } 1491 1492 /** 1493 * vcn_v4_0_5_set_clockgating_state - set VCN block clockgating state 1494 * 1495 * @handle: amdgpu_device pointer 1496 * @state: clock gating state 1497 * 1498 * Set VCN block clockgating state 1499 */ 1500 static int vcn_v4_0_5_set_clockgating_state(void *handle, enum amd_clockgating_state state) 1501 { 1502 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1503 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 1504 int i; 1505 1506 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1507 if (adev->vcn.harvest_config & (1 << i)) 1508 continue; 1509 1510 if (enable) { 1511 if (RREG32_SOC15(VCN, i, regUVD_STATUS) != UVD_STATUS__IDLE) 1512 return -EBUSY; 1513 vcn_v4_0_5_enable_clock_gating(adev, i); 1514 } else { 1515 vcn_v4_0_5_disable_clock_gating(adev, i); 1516 } 1517 } 1518 1519 return 0; 1520 } 1521 1522 /** 1523 * vcn_v4_0_5_set_powergating_state - set VCN block powergating state 1524 * 1525 * @handle: amdgpu_device pointer 1526 * @state: power gating state 1527 * 1528 * Set VCN block powergating state 1529 */ 1530 static int vcn_v4_0_5_set_powergating_state(void *handle, enum amd_powergating_state state) 1531 { 1532 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1533 int ret; 1534 1535 if (state == adev->vcn.cur_state) 1536 return 0; 1537 1538 if (state == AMD_PG_STATE_GATE) 1539 ret = vcn_v4_0_5_stop(adev); 1540 else 1541 ret = vcn_v4_0_5_start(adev); 1542 1543 if (!ret) 1544 adev->vcn.cur_state = state; 1545 1546 return ret; 1547 } 1548 1549 /** 1550 * vcn_v4_0_5_process_interrupt - process VCN block interrupt 1551 * 1552 * @adev: amdgpu_device pointer 1553 * @source: interrupt sources 1554 * @entry: interrupt entry from clients and sources 1555 * 1556 * Process VCN block interrupt 1557 */ 1558 static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, 1559 struct amdgpu_iv_entry *entry) 1560 { 1561 uint32_t ip_instance; 1562 1563 switch (entry->client_id) { 1564 case SOC15_IH_CLIENTID_VCN: 1565 ip_instance = 0; 1566 break; 1567 case SOC15_IH_CLIENTID_VCN1: 1568 ip_instance = 1; 1569 break; 1570 default: 1571 DRM_ERROR("Unhandled client id: %d\n", entry->client_id); 1572 return 0; 1573 } 1574 1575 DRM_DEBUG("IH: VCN TRAP\n"); 1576 1577 switch (entry->src_id) { 1578 case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 1579 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]); 1580 break; 1581 case VCN_4_0__SRCID_UVD_POISON: 1582 amdgpu_vcn_process_poison_irq(adev, source, entry); 1583 break; 1584 default: 1585 DRM_ERROR("Unhandled interrupt: %d %d\n", 1586 entry->src_id, entry->src_data[0]); 1587 break; 1588 } 1589 1590 return 0; 1591 } 1592 1593 static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = { 1594 .process = vcn_v4_0_5_process_interrupt, 1595 }; 1596 1597 /** 1598 * vcn_v4_0_5_set_irq_funcs - set VCN block interrupt irq functions 1599 * 1600 * @adev: amdgpu_device pointer 1601 * 1602 * Set VCN block interrupt irq functions 1603 */ 1604 static void vcn_v4_0_5_set_irq_funcs(struct amdgpu_device *adev) 1605 { 1606 int i; 1607 1608 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1609 if (adev->vcn.harvest_config & (1 << i)) 1610 continue; 1611 1612 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1; 1613 adev->vcn.inst[i].irq.funcs = &vcn_v4_0_5_irq_funcs; 1614 } 1615 } 1616 1617 static void vcn_v4_0_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 1618 { 1619 struct amdgpu_device *adev = ip_block->adev; 1620 int i, j; 1621 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 1622 uint32_t inst_off, is_powered; 1623 1624 if (!adev->vcn.ip_dump) 1625 return; 1626 1627 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 1628 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1629 if (adev->vcn.harvest_config & (1 << i)) { 1630 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 1631 continue; 1632 } 1633 1634 inst_off = i * reg_count; 1635 is_powered = (adev->vcn.ip_dump[inst_off] & 1636 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1637 1638 if (is_powered) { 1639 drm_printf(p, "\nActive Instance:VCN%d\n", i); 1640 for (j = 0; j < reg_count; j++) 1641 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_5[j].reg_name, 1642 adev->vcn.ip_dump[inst_off + j]); 1643 } else { 1644 drm_printf(p, "\nInactive Instance:VCN%d\n", i); 1645 } 1646 } 1647 } 1648 1649 static void vcn_v4_0_5_dump_ip_state(struct amdgpu_ip_block *ip_block) 1650 { 1651 struct amdgpu_device *adev = ip_block->adev; 1652 int i, j; 1653 bool is_powered; 1654 uint32_t inst_off; 1655 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); 1656 1657 if (!adev->vcn.ip_dump) 1658 return; 1659 1660 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1661 if (adev->vcn.harvest_config & (1 << i)) 1662 continue; 1663 1664 inst_off = i * reg_count; 1665 /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 1666 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); 1667 is_powered = (adev->vcn.ip_dump[inst_off] & 1668 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 1669 1670 if (is_powered) 1671 for (j = 1; j < reg_count; j++) 1672 adev->vcn.ip_dump[inst_off + j] = 1673 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_5[j], 1674 i)); 1675 } 1676 } 1677 1678 static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = { 1679 .name = "vcn_v4_0_5", 1680 .early_init = vcn_v4_0_5_early_init, 1681 .sw_init = vcn_v4_0_5_sw_init, 1682 .sw_fini = vcn_v4_0_5_sw_fini, 1683 .hw_init = vcn_v4_0_5_hw_init, 1684 .hw_fini = vcn_v4_0_5_hw_fini, 1685 .suspend = vcn_v4_0_5_suspend, 1686 .resume = vcn_v4_0_5_resume, 1687 .is_idle = vcn_v4_0_5_is_idle, 1688 .wait_for_idle = vcn_v4_0_5_wait_for_idle, 1689 .set_clockgating_state = vcn_v4_0_5_set_clockgating_state, 1690 .set_powergating_state = vcn_v4_0_5_set_powergating_state, 1691 .dump_ip_state = vcn_v4_0_5_dump_ip_state, 1692 .print_ip_state = vcn_v4_0_5_print_ip_state, 1693 }; 1694 1695 const struct amdgpu_ip_block_version vcn_v4_0_5_ip_block = { 1696 .type = AMD_IP_BLOCK_TYPE_VCN, 1697 .major = 4, 1698 .minor = 0, 1699 .rev = 5, 1700 .funcs = &vcn_v4_0_5_ip_funcs, 1701 }; 1702