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