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