1 /* 2 * Copyright 2019 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include <linux/firmware.h> 25 #include <drm/drm_drv.h> 26 27 #include "amdgpu.h" 28 #include "amdgpu_vcn.h" 29 #include "amdgpu_pm.h" 30 #include "soc15.h" 31 #include "soc15d.h" 32 #include "vcn_v2_0.h" 33 #include "mmsch_v1_0.h" 34 #include "vcn_v2_5.h" 35 36 #include "vcn/vcn_2_5_offset.h" 37 #include "vcn/vcn_2_5_sh_mask.h" 38 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" 39 40 #define VCN_VID_SOC_ADDRESS_2_0 0x1fa00 41 #define VCN1_VID_SOC_ADDRESS_3_0 0x48200 42 43 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27 44 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f 45 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10 46 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET 0x11 47 #define mmUVD_NO_OP_INTERNAL_OFFSET 0x29 48 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET 0x66 49 #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d 50 51 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 52 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4 53 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5 54 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c 55 56 #define VCN25_MAX_HW_INSTANCES_ARCTURUS 2 57 58 static const struct amdgpu_hwip_reg_entry vcn_reg_list_2_5[] = { 59 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS), 60 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS), 61 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_STATUS), 62 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID), 63 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID2), 64 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA0), 65 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA1), 66 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_CMD), 67 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI), 68 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO), 69 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI2), 70 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO2), 71 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI3), 72 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO3), 73 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI4), 74 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO4), 75 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR), 76 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR), 77 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR2), 78 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR2), 79 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR3), 80 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR3), 81 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR4), 82 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR4), 83 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE), 84 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE2), 85 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE3), 86 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE4), 87 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_CONFIG), 88 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_STATUS), 89 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_CTL), 90 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_DATA), 91 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_MASK), 92 SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_PAUSE) 93 }; 94 95 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev); 96 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev); 97 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev); 98 static int vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst *vinst, 99 enum amd_powergating_state state); 100 static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst, 101 struct dpg_pause_state *new_state); 102 static int vcn_v2_5_sriov_start(struct amdgpu_device *adev); 103 static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev); 104 105 static int amdgpu_ih_clientid_vcns[] = { 106 SOC15_IH_CLIENTID_VCN, 107 SOC15_IH_CLIENTID_VCN1 108 }; 109 110 static void vcn_v2_5_idle_work_handler(struct work_struct *work) 111 { 112 struct amdgpu_vcn_inst *vcn_inst = 113 container_of(work, struct amdgpu_vcn_inst, idle_work.work); 114 struct amdgpu_device *adev = vcn_inst->adev; 115 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; 116 unsigned int i, j; 117 int r = 0; 118 119 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 120 struct amdgpu_vcn_inst *v = &adev->vcn.inst[i]; 121 122 if (adev->vcn.harvest_config & (1 << i)) 123 continue; 124 125 for (j = 0; j < v->num_enc_rings; ++j) 126 fence[i] += amdgpu_fence_count_emitted(&v->ring_enc[j]); 127 128 /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */ 129 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG && 130 !v->using_unified_queue) { 131 struct dpg_pause_state new_state; 132 133 if (fence[i] || 134 unlikely(atomic_read(&v->dpg_enc_submission_cnt))) 135 new_state.fw_based = VCN_DPG_STATE__PAUSE; 136 else 137 new_state.fw_based = VCN_DPG_STATE__UNPAUSE; 138 139 v->pause_dpg_mode(v, &new_state); 140 } 141 142 fence[i] += amdgpu_fence_count_emitted(&v->ring_dec); 143 fences += fence[i]; 144 145 } 146 147 if (!fences && !atomic_read(&adev->vcn.inst[0].total_submission_cnt)) { 148 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 149 AMD_PG_STATE_GATE); 150 mutex_lock(&adev->vcn.workload_profile_mutex); 151 if (adev->vcn.workload_profile_active) { 152 r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 153 false); 154 if (r) 155 dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r); 156 adev->vcn.workload_profile_active = false; 157 } 158 mutex_unlock(&adev->vcn.workload_profile_mutex); 159 } else { 160 schedule_delayed_work(&adev->vcn.inst[0].idle_work, VCN_IDLE_TIMEOUT); 161 } 162 } 163 164 static void vcn_v2_5_ring_begin_use(struct amdgpu_ring *ring) 165 { 166 struct amdgpu_device *adev = ring->adev; 167 struct amdgpu_vcn_inst *v = &adev->vcn.inst[ring->me]; 168 int r = 0; 169 170 atomic_inc(&adev->vcn.inst[0].total_submission_cnt); 171 172 cancel_delayed_work_sync(&adev->vcn.inst[0].idle_work); 173 174 /* We can safely return early here because we've cancelled the 175 * the delayed work so there is no one else to set it to false 176 * and we don't care if someone else sets it to true. 177 */ 178 if (adev->vcn.workload_profile_active) 179 goto pg_lock; 180 181 mutex_lock(&adev->vcn.workload_profile_mutex); 182 if (!adev->vcn.workload_profile_active) { 183 r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, 184 true); 185 if (r) 186 dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r); 187 adev->vcn.workload_profile_active = true; 188 } 189 mutex_unlock(&adev->vcn.workload_profile_mutex); 190 191 pg_lock: 192 mutex_lock(&adev->vcn.inst[0].vcn_pg_lock); 193 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 194 AMD_PG_STATE_UNGATE); 195 196 /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */ 197 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG && 198 !v->using_unified_queue) { 199 struct dpg_pause_state new_state; 200 201 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) { 202 atomic_inc(&v->dpg_enc_submission_cnt); 203 new_state.fw_based = VCN_DPG_STATE__PAUSE; 204 } else { 205 unsigned int fences = 0; 206 unsigned int i; 207 208 for (i = 0; i < v->num_enc_rings; ++i) 209 fences += amdgpu_fence_count_emitted(&v->ring_enc[i]); 210 211 if (fences || atomic_read(&v->dpg_enc_submission_cnt)) 212 new_state.fw_based = VCN_DPG_STATE__PAUSE; 213 else 214 new_state.fw_based = VCN_DPG_STATE__UNPAUSE; 215 } 216 v->pause_dpg_mode(v, &new_state); 217 } 218 mutex_unlock(&adev->vcn.inst[0].vcn_pg_lock); 219 } 220 221 static void vcn_v2_5_ring_end_use(struct amdgpu_ring *ring) 222 { 223 struct amdgpu_device *adev = ring->adev; 224 225 /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */ 226 if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG && 227 ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC && 228 !adev->vcn.inst[ring->me].using_unified_queue) 229 atomic_dec(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt); 230 231 atomic_dec(&adev->vcn.inst[0].total_submission_cnt); 232 233 schedule_delayed_work(&adev->vcn.inst[0].idle_work, 234 VCN_IDLE_TIMEOUT); 235 } 236 237 /** 238 * vcn_v2_5_early_init - set function pointers and load microcode 239 * 240 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 241 * 242 * Set ring and irq function pointers 243 * Load microcode from filesystem 244 */ 245 static int vcn_v2_5_early_init(struct amdgpu_ip_block *ip_block) 246 { 247 struct amdgpu_device *adev = ip_block->adev; 248 int i, r; 249 250 if (amdgpu_sriov_vf(adev)) { 251 adev->vcn.num_vcn_inst = 2; 252 adev->vcn.harvest_config = 0; 253 for (i = 0; i < adev->vcn.num_vcn_inst; i++) 254 adev->vcn.inst[i].num_enc_rings = 1; 255 } else { 256 u32 harvest; 257 int i; 258 259 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 260 harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING); 261 if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK) 262 adev->vcn.harvest_config |= 1 << i; 263 adev->vcn.inst[i].num_enc_rings = 2; 264 } 265 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 | 266 AMDGPU_VCN_HARVEST_VCN1)) 267 /* both instances are harvested, disable the block */ 268 return -ENOENT; 269 } 270 271 vcn_v2_5_set_dec_ring_funcs(adev); 272 vcn_v2_5_set_enc_ring_funcs(adev); 273 vcn_v2_5_set_irq_funcs(adev); 274 vcn_v2_5_set_ras_funcs(adev); 275 276 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 277 adev->vcn.inst[i].set_pg_state = vcn_v2_5_set_pg_state; 278 279 r = amdgpu_vcn_early_init(adev, i); 280 if (r) 281 return r; 282 } 283 284 return 0; 285 } 286 287 /** 288 * vcn_v2_5_sw_init - sw init for VCN block 289 * 290 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 291 * 292 * Load firmware and sw initialization 293 */ 294 static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block) 295 { 296 struct amdgpu_ring *ring; 297 int i, j, r; 298 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); 299 uint32_t *ptr; 300 struct amdgpu_device *adev = ip_block->adev; 301 302 for (j = 0; j < adev->vcn.num_vcn_inst; j++) { 303 volatile struct amdgpu_fw_shared *fw_shared; 304 305 if (adev->vcn.harvest_config & (1 << j)) 306 continue; 307 /* VCN DEC TRAP */ 308 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j], 309 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq); 310 if (r) 311 return r; 312 313 /* VCN ENC TRAP */ 314 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) { 315 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j], 316 i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq); 317 if (r) 318 return r; 319 } 320 321 /* VCN POISON TRAP */ 322 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j], 323 VCN_2_6__SRCID_UVD_POISON, &adev->vcn.inst[j].ras_poison_irq); 324 if (r) 325 return r; 326 327 r = amdgpu_vcn_sw_init(adev, j); 328 if (r) 329 return r; 330 331 /* Override the work func */ 332 adev->vcn.inst[j].idle_work.work.func = vcn_v2_5_idle_work_handler; 333 334 amdgpu_vcn_setup_ucode(adev, j); 335 336 r = amdgpu_vcn_resume(adev, j); 337 if (r) 338 return r; 339 340 adev->vcn.inst[j].internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET; 341 adev->vcn.inst[j].internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET; 342 adev->vcn.inst[j].internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET; 343 adev->vcn.inst[j].internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET; 344 adev->vcn.inst[j].internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET; 345 adev->vcn.inst[j].internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET; 346 347 adev->vcn.inst[j].internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET; 348 adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(VCN, j, mmUVD_SCRATCH9); 349 adev->vcn.inst[j].internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET; 350 adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA0); 351 adev->vcn.inst[j].internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET; 352 adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA1); 353 adev->vcn.inst[j].internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET; 354 adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_CMD); 355 adev->vcn.inst[j].internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET; 356 adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(VCN, j, mmUVD_NO_OP); 357 358 ring = &adev->vcn.inst[j].ring_dec; 359 ring->use_doorbell = true; 360 361 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 362 (amdgpu_sriov_vf(adev) ? 2*j : 8*j); 363 364 if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(2, 5, 0)) 365 ring->vm_hub = AMDGPU_MMHUB1(0); 366 else 367 ring->vm_hub = AMDGPU_MMHUB0(0); 368 369 sprintf(ring->name, "vcn_dec_%d", j); 370 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 371 0, AMDGPU_RING_PRIO_DEFAULT, NULL); 372 if (r) 373 return r; 374 375 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) { 376 enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i); 377 378 ring = &adev->vcn.inst[j].ring_enc[i]; 379 ring->use_doorbell = true; 380 381 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 382 (amdgpu_sriov_vf(adev) ? (1 + i + 2*j) : (2 + i + 8*j)); 383 384 if (amdgpu_ip_version(adev, UVD_HWIP, 0) == 385 IP_VERSION(2, 5, 0)) 386 ring->vm_hub = AMDGPU_MMHUB1(0); 387 else 388 ring->vm_hub = AMDGPU_MMHUB0(0); 389 390 sprintf(ring->name, "vcn_enc_%d.%d", j, i); 391 r = amdgpu_ring_init(adev, ring, 512, 392 &adev->vcn.inst[j].irq, 0, 393 hw_prio, NULL); 394 if (r) 395 return r; 396 } 397 398 fw_shared = adev->vcn.inst[j].fw_shared.cpu_addr; 399 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG); 400 401 if (amdgpu_vcnfw_log) 402 amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); 403 404 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 405 adev->vcn.inst[j].pause_dpg_mode = vcn_v2_5_pause_dpg_mode; 406 } 407 408 if (amdgpu_sriov_vf(adev)) { 409 r = amdgpu_virt_alloc_mm_table(adev); 410 if (r) 411 return r; 412 } 413 414 r = amdgpu_vcn_ras_sw_init(adev); 415 if (r) 416 return r; 417 418 /* Allocate memory for VCN IP Dump buffer */ 419 ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); 420 if (!ptr) { 421 DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); 422 adev->vcn.ip_dump = NULL; 423 } else { 424 adev->vcn.ip_dump = ptr; 425 } 426 427 return 0; 428 } 429 430 /** 431 * vcn_v2_5_sw_fini - sw fini for VCN block 432 * 433 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 434 * 435 * VCN suspend and free up sw allocation 436 */ 437 static int vcn_v2_5_sw_fini(struct amdgpu_ip_block *ip_block) 438 { 439 int i, r, idx; 440 struct amdgpu_device *adev = ip_block->adev; 441 volatile struct amdgpu_fw_shared *fw_shared; 442 443 if (drm_dev_enter(adev_to_drm(adev), &idx)) { 444 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 445 if (adev->vcn.harvest_config & (1 << i)) 446 continue; 447 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr; 448 fw_shared->present_flag_0 = 0; 449 } 450 drm_dev_exit(idx); 451 } 452 453 454 if (amdgpu_sriov_vf(adev)) 455 amdgpu_virt_free_mm_table(adev); 456 457 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 458 r = amdgpu_vcn_suspend(adev, i); 459 if (r) 460 return r; 461 r = amdgpu_vcn_sw_fini(adev, i); 462 if (r) 463 return r; 464 } 465 466 kfree(adev->vcn.ip_dump); 467 468 return 0; 469 } 470 471 /** 472 * vcn_v2_5_hw_init - start and test VCN block 473 * 474 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 475 * 476 * Initialize the hardware, boot up the VCPU and do some testing 477 */ 478 static int vcn_v2_5_hw_init(struct amdgpu_ip_block *ip_block) 479 { 480 struct amdgpu_device *adev = ip_block->adev; 481 struct amdgpu_ring *ring; 482 int i, j, r = 0; 483 484 if (amdgpu_sriov_vf(adev)) 485 r = vcn_v2_5_sriov_start(adev); 486 487 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { 488 if (adev->vcn.harvest_config & (1 << j)) 489 continue; 490 491 if (amdgpu_sriov_vf(adev)) { 492 adev->vcn.inst[j].ring_enc[0].sched.ready = true; 493 adev->vcn.inst[j].ring_enc[1].sched.ready = false; 494 adev->vcn.inst[j].ring_enc[2].sched.ready = false; 495 adev->vcn.inst[j].ring_dec.sched.ready = true; 496 } else { 497 498 ring = &adev->vcn.inst[j].ring_dec; 499 500 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 501 ring->doorbell_index, j); 502 503 r = amdgpu_ring_test_helper(ring); 504 if (r) 505 return r; 506 507 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) { 508 ring = &adev->vcn.inst[j].ring_enc[i]; 509 r = amdgpu_ring_test_helper(ring); 510 if (r) 511 return r; 512 } 513 } 514 } 515 516 return r; 517 } 518 519 /** 520 * vcn_v2_5_hw_fini - stop the hardware block 521 * 522 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 523 * 524 * Stop the VCN block, mark ring as not ready any more 525 */ 526 static int vcn_v2_5_hw_fini(struct amdgpu_ip_block *ip_block) 527 { 528 struct amdgpu_device *adev = ip_block->adev; 529 int i; 530 531 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 532 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 533 534 if (adev->vcn.harvest_config & (1 << i)) 535 continue; 536 537 cancel_delayed_work_sync(&vinst->idle_work); 538 539 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || 540 (vinst->cur_state != AMD_PG_STATE_GATE && 541 RREG32_SOC15(VCN, i, mmUVD_STATUS))) 542 vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); 543 544 if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) 545 amdgpu_irq_put(adev, &vinst->ras_poison_irq, 0); 546 } 547 548 return 0; 549 } 550 551 /** 552 * vcn_v2_5_suspend - suspend VCN block 553 * 554 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 555 * 556 * HW fini and suspend VCN block 557 */ 558 static int vcn_v2_5_suspend(struct amdgpu_ip_block *ip_block) 559 { 560 struct amdgpu_device *adev = ip_block->adev; 561 int r, i; 562 563 r = vcn_v2_5_hw_fini(ip_block); 564 if (r) 565 return r; 566 567 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 568 r = amdgpu_vcn_suspend(ip_block->adev, i); 569 if (r) 570 return r; 571 } 572 573 return 0; 574 } 575 576 /** 577 * vcn_v2_5_resume - resume VCN block 578 * 579 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 580 * 581 * Resume firmware and hw init VCN block 582 */ 583 static int vcn_v2_5_resume(struct amdgpu_ip_block *ip_block) 584 { 585 struct amdgpu_device *adev = ip_block->adev; 586 int r, i; 587 588 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 589 r = amdgpu_vcn_resume(ip_block->adev, i); 590 if (r) 591 return r; 592 } 593 594 r = vcn_v2_5_hw_init(ip_block); 595 596 return r; 597 } 598 599 /** 600 * vcn_v2_5_mc_resume - memory controller programming 601 * 602 * @vinst: VCN instance 603 * 604 * Let the VCN memory controller know it's offsets 605 */ 606 static void vcn_v2_5_mc_resume(struct amdgpu_vcn_inst *vinst) 607 { 608 struct amdgpu_device *adev = vinst->adev; 609 int i = vinst->inst; 610 uint32_t size; 611 uint32_t offset; 612 613 if (adev->vcn.harvest_config & (1 << i)) 614 return; 615 616 size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4); 617 /* cache window 0: fw */ 618 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 619 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 620 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo)); 621 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 622 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi)); 623 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0, 0); 624 offset = 0; 625 } else { 626 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 627 lower_32_bits(adev->vcn.inst[i].gpu_addr)); 628 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 629 upper_32_bits(adev->vcn.inst[i].gpu_addr)); 630 offset = size; 631 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0, 632 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 633 } 634 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE0, size); 635 636 /* cache window 1: stack */ 637 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 638 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset)); 639 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 640 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset)); 641 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET1, 0); 642 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE); 643 644 /* cache window 2: context */ 645 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 646 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 647 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 648 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 649 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET2, 0); 650 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE); 651 652 /* non-cache window */ 653 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW, 654 lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr)); 655 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH, 656 upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr)); 657 WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_OFFSET0, 0); 658 WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_SIZE0, 659 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared))); 660 } 661 662 static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_vcn_inst *vinst, 663 bool indirect) 664 { 665 struct amdgpu_device *adev = vinst->adev; 666 int inst_idx = vinst->inst; 667 uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[inst_idx].fw->size + 4); 668 uint32_t offset; 669 670 /* cache window 0: fw */ 671 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 672 if (!indirect) { 673 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 674 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 675 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect); 676 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 677 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 678 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect); 679 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 680 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 681 } else { 682 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 683 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect); 684 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 685 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect); 686 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 687 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 688 } 689 offset = 0; 690 } else { 691 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 692 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 693 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 694 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 695 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 696 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect); 697 offset = size; 698 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 699 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 700 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect); 701 } 702 703 if (!indirect) 704 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 705 VCN, 0, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect); 706 else 707 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 708 VCN, 0, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect); 709 710 /* cache window 1: stack */ 711 if (!indirect) { 712 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 713 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 714 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 715 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 716 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 717 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect); 718 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 719 VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 720 } else { 721 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 722 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect); 723 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 724 VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect); 725 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 726 VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 727 } 728 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 729 VCN, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect); 730 731 /* cache window 2: context */ 732 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 733 VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 734 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect); 735 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 736 VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 737 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect); 738 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 739 VCN, 0, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect); 740 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 741 VCN, 0, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect); 742 743 /* non-cache window */ 744 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 745 VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 746 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 747 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 748 VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 749 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect); 750 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 751 VCN, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect); 752 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 753 VCN, 0, mmUVD_VCPU_NONCACHE_SIZE0), 754 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect); 755 756 /* VCN global tiling registers */ 757 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 758 VCN, 0, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect); 759 } 760 761 /** 762 * vcn_v2_5_disable_clock_gating - disable VCN clock gating 763 * 764 * @vinst: VCN instance 765 * 766 * Disable clock gating for VCN block 767 */ 768 static void vcn_v2_5_disable_clock_gating(struct amdgpu_vcn_inst *vinst) 769 { 770 struct amdgpu_device *adev = vinst->adev; 771 int i = vinst->inst; 772 uint32_t data; 773 774 if (adev->vcn.harvest_config & (1 << i)) 775 return; 776 /* UVD disable CGC */ 777 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL); 778 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 779 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 780 else 781 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; 782 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 783 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 784 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data); 785 786 data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE); 787 data &= ~(UVD_CGC_GATE__SYS_MASK 788 | UVD_CGC_GATE__UDEC_MASK 789 | UVD_CGC_GATE__MPEG2_MASK 790 | UVD_CGC_GATE__REGS_MASK 791 | UVD_CGC_GATE__RBC_MASK 792 | UVD_CGC_GATE__LMI_MC_MASK 793 | UVD_CGC_GATE__LMI_UMC_MASK 794 | UVD_CGC_GATE__IDCT_MASK 795 | UVD_CGC_GATE__MPRD_MASK 796 | UVD_CGC_GATE__MPC_MASK 797 | UVD_CGC_GATE__LBSI_MASK 798 | UVD_CGC_GATE__LRBBM_MASK 799 | UVD_CGC_GATE__UDEC_RE_MASK 800 | UVD_CGC_GATE__UDEC_CM_MASK 801 | UVD_CGC_GATE__UDEC_IT_MASK 802 | UVD_CGC_GATE__UDEC_DB_MASK 803 | UVD_CGC_GATE__UDEC_MP_MASK 804 | UVD_CGC_GATE__WCB_MASK 805 | UVD_CGC_GATE__VCPU_MASK 806 | UVD_CGC_GATE__MMSCH_MASK); 807 808 WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data); 809 810 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0, 0xFFFFFFFF); 811 812 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL); 813 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK 814 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK 815 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK 816 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK 817 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK 818 | UVD_CGC_CTRL__SYS_MODE_MASK 819 | UVD_CGC_CTRL__UDEC_MODE_MASK 820 | UVD_CGC_CTRL__MPEG2_MODE_MASK 821 | UVD_CGC_CTRL__REGS_MODE_MASK 822 | UVD_CGC_CTRL__RBC_MODE_MASK 823 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 824 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 825 | UVD_CGC_CTRL__IDCT_MODE_MASK 826 | UVD_CGC_CTRL__MPRD_MODE_MASK 827 | UVD_CGC_CTRL__MPC_MODE_MASK 828 | UVD_CGC_CTRL__LBSI_MODE_MASK 829 | UVD_CGC_CTRL__LRBBM_MODE_MASK 830 | UVD_CGC_CTRL__WCB_MODE_MASK 831 | UVD_CGC_CTRL__VCPU_MODE_MASK 832 | UVD_CGC_CTRL__MMSCH_MODE_MASK); 833 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data); 834 835 /* turn on */ 836 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE); 837 data |= (UVD_SUVD_CGC_GATE__SRE_MASK 838 | UVD_SUVD_CGC_GATE__SIT_MASK 839 | UVD_SUVD_CGC_GATE__SMP_MASK 840 | UVD_SUVD_CGC_GATE__SCM_MASK 841 | UVD_SUVD_CGC_GATE__SDB_MASK 842 | UVD_SUVD_CGC_GATE__SRE_H264_MASK 843 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK 844 | UVD_SUVD_CGC_GATE__SIT_H264_MASK 845 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK 846 | UVD_SUVD_CGC_GATE__SCM_H264_MASK 847 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK 848 | UVD_SUVD_CGC_GATE__SDB_H264_MASK 849 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK 850 | UVD_SUVD_CGC_GATE__SCLR_MASK 851 | UVD_SUVD_CGC_GATE__UVD_SC_MASK 852 | UVD_SUVD_CGC_GATE__ENT_MASK 853 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK 854 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK 855 | UVD_SUVD_CGC_GATE__SITE_MASK 856 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK 857 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK 858 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK 859 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK 860 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK); 861 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data); 862 863 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL); 864 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 865 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 866 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 867 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 868 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 869 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK 870 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK 871 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 872 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 873 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 874 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data); 875 } 876 877 static void vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_vcn_inst *vinst, 878 uint8_t sram_sel, uint8_t indirect) 879 { 880 struct amdgpu_device *adev = vinst->adev; 881 int inst_idx = vinst->inst; 882 uint32_t reg_data = 0; 883 884 /* enable sw clock gating control */ 885 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 886 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 887 else 888 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 889 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 890 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 891 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK | 892 UVD_CGC_CTRL__UDEC_CM_MODE_MASK | 893 UVD_CGC_CTRL__UDEC_IT_MODE_MASK | 894 UVD_CGC_CTRL__UDEC_DB_MODE_MASK | 895 UVD_CGC_CTRL__UDEC_MP_MODE_MASK | 896 UVD_CGC_CTRL__SYS_MODE_MASK | 897 UVD_CGC_CTRL__UDEC_MODE_MASK | 898 UVD_CGC_CTRL__MPEG2_MODE_MASK | 899 UVD_CGC_CTRL__REGS_MODE_MASK | 900 UVD_CGC_CTRL__RBC_MODE_MASK | 901 UVD_CGC_CTRL__LMI_MC_MODE_MASK | 902 UVD_CGC_CTRL__LMI_UMC_MODE_MASK | 903 UVD_CGC_CTRL__IDCT_MODE_MASK | 904 UVD_CGC_CTRL__MPRD_MODE_MASK | 905 UVD_CGC_CTRL__MPC_MODE_MASK | 906 UVD_CGC_CTRL__LBSI_MODE_MASK | 907 UVD_CGC_CTRL__LRBBM_MODE_MASK | 908 UVD_CGC_CTRL__WCB_MODE_MASK | 909 UVD_CGC_CTRL__VCPU_MODE_MASK | 910 UVD_CGC_CTRL__MMSCH_MODE_MASK); 911 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 912 VCN, 0, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect); 913 914 /* turn off clock gating */ 915 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 916 VCN, 0, mmUVD_CGC_GATE), 0, sram_sel, indirect); 917 918 /* turn on SUVD clock gating */ 919 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 920 VCN, 0, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect); 921 922 /* turn on sw mode in UVD_SUVD_CGC_CTRL */ 923 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 924 VCN, 0, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect); 925 } 926 927 /** 928 * vcn_v2_5_enable_clock_gating - enable VCN clock gating 929 * 930 * @vinst: VCN instance 931 * 932 * Enable clock gating for VCN block 933 */ 934 static void vcn_v2_5_enable_clock_gating(struct amdgpu_vcn_inst *vinst) 935 { 936 struct amdgpu_device *adev = vinst->adev; 937 int i = vinst->inst; 938 uint32_t data = 0; 939 940 if (adev->vcn.harvest_config & (1 << i)) 941 return; 942 /* enable UVD CGC */ 943 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL); 944 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 945 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 946 else 947 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 948 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 949 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 950 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data); 951 952 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL); 953 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK 954 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK 955 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK 956 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK 957 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK 958 | UVD_CGC_CTRL__SYS_MODE_MASK 959 | UVD_CGC_CTRL__UDEC_MODE_MASK 960 | UVD_CGC_CTRL__MPEG2_MODE_MASK 961 | UVD_CGC_CTRL__REGS_MODE_MASK 962 | UVD_CGC_CTRL__RBC_MODE_MASK 963 | UVD_CGC_CTRL__LMI_MC_MODE_MASK 964 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 965 | UVD_CGC_CTRL__IDCT_MODE_MASK 966 | UVD_CGC_CTRL__MPRD_MODE_MASK 967 | UVD_CGC_CTRL__MPC_MODE_MASK 968 | UVD_CGC_CTRL__LBSI_MODE_MASK 969 | UVD_CGC_CTRL__LRBBM_MODE_MASK 970 | UVD_CGC_CTRL__WCB_MODE_MASK 971 | UVD_CGC_CTRL__VCPU_MODE_MASK); 972 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data); 973 974 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL); 975 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 976 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 977 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 978 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 979 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 980 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK 981 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK 982 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 983 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 984 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 985 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data); 986 } 987 988 static void vcn_v2_6_enable_ras(struct amdgpu_vcn_inst *vinst, 989 bool indirect) 990 { 991 struct amdgpu_device *adev = vinst->adev; 992 int inst_idx = vinst->inst; 993 uint32_t tmp; 994 995 if (amdgpu_ip_version(adev, UVD_HWIP, 0) != IP_VERSION(2, 6, 0)) 996 return; 997 998 tmp = VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK | 999 VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK | 1000 VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK | 1001 VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK; 1002 WREG32_SOC15_DPG_MODE(inst_idx, 1003 SOC15_DPG_MODE_OFFSET(VCN, 0, mmVCN_RAS_CNTL), 1004 tmp, 0, indirect); 1005 1006 tmp = UVD_VCPU_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK; 1007 WREG32_SOC15_DPG_MODE(inst_idx, 1008 SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_VCPU_INT_EN), 1009 tmp, 0, indirect); 1010 1011 tmp = UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK; 1012 WREG32_SOC15_DPG_MODE(inst_idx, 1013 SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_SYS_INT_EN), 1014 tmp, 0, indirect); 1015 } 1016 1017 static int vcn_v2_5_start_dpg_mode(struct amdgpu_vcn_inst *vinst, bool indirect) 1018 { 1019 struct amdgpu_device *adev = vinst->adev; 1020 int inst_idx = vinst->inst; 1021 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 1022 struct amdgpu_ring *ring; 1023 uint32_t rb_bufsz, tmp; 1024 1025 /* disable register anti-hang mechanism */ 1026 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1, 1027 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1028 /* enable dynamic power gating mode */ 1029 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS); 1030 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; 1031 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK; 1032 WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); 1033 1034 if (indirect) 1035 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; 1036 1037 /* enable clock gating */ 1038 vcn_v2_5_clock_gating_dpg_mode(vinst, 0, indirect); 1039 1040 /* enable VCPU clock */ 1041 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 1042 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 1043 tmp |= UVD_VCPU_CNTL__BLK_RST_MASK; 1044 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1045 VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect); 1046 1047 /* disable master interupt */ 1048 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1049 VCN, 0, mmUVD_MASTINT_EN), 0, 0, indirect); 1050 1051 /* setup mmUVD_LMI_CTRL */ 1052 tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1053 UVD_LMI_CTRL__REQ_MODE_MASK | 1054 UVD_LMI_CTRL__CRC_RESET_MASK | 1055 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1056 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1057 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 1058 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 1059 0x00100000L); 1060 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1061 VCN, 0, mmUVD_LMI_CTRL), tmp, 0, indirect); 1062 1063 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1064 VCN, 0, mmUVD_MPC_CNTL), 1065 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect); 1066 1067 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1068 VCN, 0, mmUVD_MPC_SET_MUXA0), 1069 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1070 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1071 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1072 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect); 1073 1074 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1075 VCN, 0, mmUVD_MPC_SET_MUXB0), 1076 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1077 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1078 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1079 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect); 1080 1081 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1082 VCN, 0, mmUVD_MPC_SET_MUX), 1083 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1084 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1085 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect); 1086 1087 vcn_v2_5_mc_resume_dpg_mode(vinst, indirect); 1088 1089 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1090 VCN, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect); 1091 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1092 VCN, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect); 1093 1094 /* enable LMI MC and UMC channels */ 1095 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1096 VCN, 0, mmUVD_LMI_CTRL2), 0, 0, indirect); 1097 1098 vcn_v2_6_enable_ras(vinst, indirect); 1099 1100 /* unblock VCPU register access */ 1101 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1102 VCN, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect); 1103 1104 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 1105 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 1106 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1107 VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect); 1108 1109 /* enable master interrupt */ 1110 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET( 1111 VCN, 0, mmUVD_MASTINT_EN), 1112 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 1113 1114 if (indirect) 1115 amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); 1116 1117 ring = &adev->vcn.inst[inst_idx].ring_dec; 1118 /* force RBC into idle state */ 1119 rb_bufsz = order_base_2(ring->ring_size); 1120 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); 1121 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); 1122 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); 1123 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); 1124 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); 1125 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp); 1126 1127 /* Stall DPG before WPTR/RPTR reset */ 1128 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1129 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK, 1130 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); 1131 fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET; 1132 1133 /* set the write pointer delay */ 1134 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0); 1135 1136 /* set the wb address */ 1137 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR, 1138 (upper_32_bits(ring->gpu_addr) >> 2)); 1139 1140 /* program the RB_BASE for ring buffer */ 1141 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, 1142 lower_32_bits(ring->gpu_addr)); 1143 WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, 1144 upper_32_bits(ring->gpu_addr)); 1145 1146 /* Initialize the ring buffer's read and write pointers */ 1147 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0); 1148 1149 WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0); 1150 1151 ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR); 1152 WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR, 1153 lower_32_bits(ring->wptr)); 1154 1155 fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET; 1156 /* Unstall DPG */ 1157 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1158 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); 1159 1160 return 0; 1161 } 1162 1163 static int vcn_v2_5_start(struct amdgpu_vcn_inst *vinst) 1164 { 1165 struct amdgpu_device *adev = vinst->adev; 1166 int i = vinst->inst; 1167 volatile struct amdgpu_fw_shared *fw_shared = 1168 adev->vcn.inst[i].fw_shared.cpu_addr; 1169 struct amdgpu_ring *ring; 1170 uint32_t rb_bufsz, tmp; 1171 int j, k, r; 1172 1173 if (adev->vcn.harvest_config & (1 << i)) 1174 return 0; 1175 1176 if (adev->pm.dpm_enabled) 1177 amdgpu_dpm_enable_vcn(adev, true, i); 1178 1179 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 1180 return vcn_v2_5_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram); 1181 1182 /* disable register anti-hang mechanism */ 1183 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS), 0, 1184 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1185 1186 /* set uvd status busy */ 1187 tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY; 1188 WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp); 1189 1190 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 1191 return 0; 1192 1193 /* SW clock gating */ 1194 vcn_v2_5_disable_clock_gating(vinst); 1195 1196 /* enable VCPU clock */ 1197 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 1198 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); 1199 1200 /* disable master interrupt */ 1201 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0, 1202 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1203 1204 /* setup mmUVD_LMI_CTRL */ 1205 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL); 1206 tmp &= ~0xff; 1207 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp | 0x8| 1208 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 1209 UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 1210 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 1211 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 1212 1213 /* setup mmUVD_MPC_CNTL */ 1214 tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL); 1215 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; 1216 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; 1217 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp); 1218 1219 /* setup UVD_MPC_SET_MUXA0 */ 1220 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0, 1221 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 1222 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 1223 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 1224 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); 1225 1226 /* setup UVD_MPC_SET_MUXB0 */ 1227 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0, 1228 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 1229 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 1230 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 1231 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); 1232 1233 /* setup mmUVD_MPC_SET_MUX */ 1234 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX, 1235 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 1236 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 1237 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); 1238 1239 vcn_v2_5_mc_resume(vinst); 1240 1241 /* VCN global tiling registers */ 1242 WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG, 1243 adev->gfx.config.gb_addr_config); 1244 WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG, 1245 adev->gfx.config.gb_addr_config); 1246 1247 /* enable LMI MC and UMC channels */ 1248 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0, 1249 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 1250 1251 /* unblock VCPU register access */ 1252 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0, 1253 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1254 1255 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0, 1256 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1257 1258 for (k = 0; k < 10; ++k) { 1259 uint32_t status; 1260 1261 for (j = 0; j < 100; ++j) { 1262 status = RREG32_SOC15(VCN, i, mmUVD_STATUS); 1263 if (status & 2) 1264 break; 1265 if (amdgpu_emu_mode == 1) 1266 msleep(500); 1267 else 1268 mdelay(10); 1269 } 1270 r = 0; 1271 if (status & 2) 1272 break; 1273 1274 DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n"); 1275 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 1276 UVD_VCPU_CNTL__BLK_RST_MASK, 1277 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1278 mdelay(10); 1279 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0, 1280 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1281 1282 mdelay(10); 1283 r = -1; 1284 } 1285 1286 if (r) { 1287 DRM_ERROR("VCN decode not responding, giving up!!!\n"); 1288 return r; 1289 } 1290 1291 /* enable master interrupt */ 1292 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 1293 UVD_MASTINT_EN__VCPU_EN_MASK, 1294 ~UVD_MASTINT_EN__VCPU_EN_MASK); 1295 1296 /* clear the busy bit of VCN_STATUS */ 1297 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0, 1298 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 1299 1300 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0); 1301 1302 ring = &adev->vcn.inst[i].ring_dec; 1303 /* force RBC into idle state */ 1304 rb_bufsz = order_base_2(ring->ring_size); 1305 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); 1306 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); 1307 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); 1308 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); 1309 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); 1310 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp); 1311 1312 fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET; 1313 /* program the RB_BASE for ring buffer */ 1314 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, 1315 lower_32_bits(ring->gpu_addr)); 1316 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, 1317 upper_32_bits(ring->gpu_addr)); 1318 1319 /* Initialize the ring buffer's read and write pointers */ 1320 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0); 1321 1322 ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR); 1323 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR, 1324 lower_32_bits(ring->wptr)); 1325 fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET; 1326 1327 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET; 1328 ring = &adev->vcn.inst[i].ring_enc[0]; 1329 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); 1330 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1331 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr); 1332 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1333 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4); 1334 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET; 1335 1336 fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET; 1337 ring = &adev->vcn.inst[i].ring_enc[1]; 1338 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); 1339 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); 1340 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr); 1341 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 1342 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4); 1343 fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET; 1344 1345 return 0; 1346 } 1347 1348 static int vcn_v2_5_mmsch_start(struct amdgpu_device *adev, 1349 struct amdgpu_mm_table *table) 1350 { 1351 uint32_t data = 0, loop = 0, size = 0; 1352 uint64_t addr = table->gpu_addr; 1353 struct mmsch_v1_1_init_header *header = NULL; 1354 1355 header = (struct mmsch_v1_1_init_header *)table->cpu_addr; 1356 size = header->total_size; 1357 1358 /* 1359 * 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of 1360 * memory descriptor location 1361 */ 1362 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr)); 1363 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr)); 1364 1365 /* 2, update vmid of descriptor */ 1366 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID); 1367 data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; 1368 /* use domain0 for MM scheduler */ 1369 data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); 1370 WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, data); 1371 1372 /* 3, notify mmsch about the size of this descriptor */ 1373 WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size); 1374 1375 /* 4, set resp to zero */ 1376 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0); 1377 1378 /* 1379 * 5, kick off the initialization and wait until 1380 * VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero 1381 */ 1382 WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, 0x10000001); 1383 1384 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP); 1385 loop = 10; 1386 while ((data & 0x10000002) != 0x10000002) { 1387 udelay(100); 1388 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP); 1389 loop--; 1390 if (!loop) 1391 break; 1392 } 1393 1394 if (!loop) { 1395 dev_err(adev->dev, 1396 "failed to init MMSCH, mmMMSCH_VF_MAILBOX_RESP = %x\n", 1397 data); 1398 return -EBUSY; 1399 } 1400 1401 return 0; 1402 } 1403 1404 static int vcn_v2_5_sriov_start(struct amdgpu_device *adev) 1405 { 1406 struct amdgpu_ring *ring; 1407 uint32_t offset, size, tmp, i, rb_bufsz; 1408 uint32_t table_size = 0; 1409 struct mmsch_v1_0_cmd_direct_write direct_wt = { { 0 } }; 1410 struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt = { { 0 } }; 1411 struct mmsch_v1_0_cmd_end end = { { 0 } }; 1412 uint32_t *init_table = adev->virt.mm_table.cpu_addr; 1413 struct mmsch_v1_1_init_header *header = (struct mmsch_v1_1_init_header *)init_table; 1414 1415 direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE; 1416 direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; 1417 end.cmd_header.command_type = MMSCH_COMMAND__END; 1418 1419 header->version = MMSCH_VERSION; 1420 header->total_size = sizeof(struct mmsch_v1_1_init_header) >> 2; 1421 init_table += header->total_size; 1422 1423 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1424 header->eng[i].table_offset = header->total_size; 1425 header->eng[i].init_status = 0; 1426 header->eng[i].table_size = 0; 1427 1428 table_size = 0; 1429 1430 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT( 1431 SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 1432 ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY); 1433 1434 size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4); 1435 /* mc resume*/ 1436 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 1437 MMSCH_V1_0_INSERT_DIRECT_WT( 1438 SOC15_REG_OFFSET(VCN, i, 1439 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 1440 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); 1441 MMSCH_V1_0_INSERT_DIRECT_WT( 1442 SOC15_REG_OFFSET(VCN, i, 1443 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 1444 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); 1445 offset = 0; 1446 MMSCH_V1_0_INSERT_DIRECT_WT( 1447 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), 0); 1448 } else { 1449 MMSCH_V1_0_INSERT_DIRECT_WT( 1450 SOC15_REG_OFFSET(VCN, i, 1451 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 1452 lower_32_bits(adev->vcn.inst[i].gpu_addr)); 1453 MMSCH_V1_0_INSERT_DIRECT_WT( 1454 SOC15_REG_OFFSET(VCN, i, 1455 mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 1456 upper_32_bits(adev->vcn.inst[i].gpu_addr)); 1457 offset = size; 1458 MMSCH_V1_0_INSERT_DIRECT_WT( 1459 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), 1460 AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 1461 } 1462 1463 MMSCH_V1_0_INSERT_DIRECT_WT( 1464 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE0), 1465 size); 1466 MMSCH_V1_0_INSERT_DIRECT_WT( 1467 SOC15_REG_OFFSET(VCN, i, 1468 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 1469 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset)); 1470 MMSCH_V1_0_INSERT_DIRECT_WT( 1471 SOC15_REG_OFFSET(VCN, i, 1472 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 1473 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset)); 1474 MMSCH_V1_0_INSERT_DIRECT_WT( 1475 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET1), 1476 0); 1477 MMSCH_V1_0_INSERT_DIRECT_WT( 1478 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE1), 1479 AMDGPU_VCN_STACK_SIZE); 1480 MMSCH_V1_0_INSERT_DIRECT_WT( 1481 SOC15_REG_OFFSET(VCN, i, 1482 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 1483 lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + 1484 AMDGPU_VCN_STACK_SIZE)); 1485 MMSCH_V1_0_INSERT_DIRECT_WT( 1486 SOC15_REG_OFFSET(VCN, i, 1487 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 1488 upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + 1489 AMDGPU_VCN_STACK_SIZE)); 1490 MMSCH_V1_0_INSERT_DIRECT_WT( 1491 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET2), 1492 0); 1493 MMSCH_V1_0_INSERT_DIRECT_WT( 1494 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE2), 1495 AMDGPU_VCN_CONTEXT_SIZE); 1496 1497 ring = &adev->vcn.inst[i].ring_enc[0]; 1498 ring->wptr = 0; 1499 1500 MMSCH_V1_0_INSERT_DIRECT_WT( 1501 SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_LO), 1502 lower_32_bits(ring->gpu_addr)); 1503 MMSCH_V1_0_INSERT_DIRECT_WT( 1504 SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_HI), 1505 upper_32_bits(ring->gpu_addr)); 1506 MMSCH_V1_0_INSERT_DIRECT_WT( 1507 SOC15_REG_OFFSET(VCN, i, mmUVD_RB_SIZE), 1508 ring->ring_size / 4); 1509 1510 ring = &adev->vcn.inst[i].ring_dec; 1511 ring->wptr = 0; 1512 MMSCH_V1_0_INSERT_DIRECT_WT( 1513 SOC15_REG_OFFSET(VCN, i, 1514 mmUVD_LMI_RBC_RB_64BIT_BAR_LOW), 1515 lower_32_bits(ring->gpu_addr)); 1516 MMSCH_V1_0_INSERT_DIRECT_WT( 1517 SOC15_REG_OFFSET(VCN, i, 1518 mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH), 1519 upper_32_bits(ring->gpu_addr)); 1520 1521 /* force RBC into idle state */ 1522 rb_bufsz = order_base_2(ring->ring_size); 1523 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); 1524 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); 1525 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); 1526 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); 1527 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); 1528 MMSCH_V1_0_INSERT_DIRECT_WT( 1529 SOC15_REG_OFFSET(VCN, i, mmUVD_RBC_RB_CNTL), tmp); 1530 1531 /* add end packet */ 1532 memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end)); 1533 table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4; 1534 init_table += sizeof(struct mmsch_v1_0_cmd_end) / 4; 1535 1536 /* refine header */ 1537 header->eng[i].table_size = table_size; 1538 header->total_size += table_size; 1539 } 1540 1541 return vcn_v2_5_mmsch_start(adev, &adev->virt.mm_table); 1542 } 1543 1544 static int vcn_v2_5_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) 1545 { 1546 struct amdgpu_device *adev = vinst->adev; 1547 int inst_idx = vinst->inst; 1548 uint32_t tmp; 1549 1550 /* Wait for power status to be 1 */ 1551 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1, 1552 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1553 1554 /* wait for read ptr to be equal to write ptr */ 1555 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR); 1556 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1557 1558 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2); 1559 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF); 1560 1561 tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF; 1562 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF); 1563 1564 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1, 1565 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1566 1567 /* disable dynamic power gating mode */ 1568 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0, 1569 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1570 1571 return 0; 1572 } 1573 1574 static int vcn_v2_5_stop(struct amdgpu_vcn_inst *vinst) 1575 { 1576 struct amdgpu_device *adev = vinst->adev; 1577 int i = vinst->inst; 1578 uint32_t tmp; 1579 int r; 1580 1581 if (adev->vcn.harvest_config & (1 << i)) 1582 return 0; 1583 1584 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1585 r = vcn_v2_5_stop_dpg_mode(vinst); 1586 goto done; 1587 } 1588 1589 /* wait for vcn idle */ 1590 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1591 if (r) 1592 goto done; 1593 1594 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1595 UVD_LMI_STATUS__READ_CLEAN_MASK | 1596 UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1597 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1598 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp); 1599 if (r) 1600 goto done; 1601 1602 /* block LMI UMC channel */ 1603 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2); 1604 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1605 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp); 1606 1607 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK| 1608 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1609 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp); 1610 if (r) 1611 goto done; 1612 1613 /* block VCPU register access */ 1614 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 1615 UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1616 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1617 1618 /* reset VCPU */ 1619 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 1620 UVD_VCPU_CNTL__BLK_RST_MASK, 1621 ~UVD_VCPU_CNTL__BLK_RST_MASK); 1622 1623 /* disable VCPU clock */ 1624 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0, 1625 ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1626 1627 /* clear status */ 1628 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0); 1629 1630 vcn_v2_5_enable_clock_gating(vinst); 1631 1632 /* enable register anti-hang mechanism */ 1633 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS), 1634 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, 1635 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1636 1637 done: 1638 if (adev->pm.dpm_enabled) 1639 amdgpu_dpm_enable_vcn(adev, false, i); 1640 1641 return r; 1642 } 1643 1644 static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst, 1645 struct dpg_pause_state *new_state) 1646 { 1647 struct amdgpu_device *adev = vinst->adev; 1648 int inst_idx = vinst->inst; 1649 struct amdgpu_ring *ring; 1650 uint32_t reg_data = 0; 1651 int ret_code = 0; 1652 1653 /* pause/unpause if state is changed */ 1654 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) { 1655 DRM_DEBUG("dpg pause state changed %d -> %d", 1656 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based); 1657 reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) & 1658 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1659 1660 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { 1661 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1, 1662 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1663 1664 if (!ret_code) { 1665 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr; 1666 1667 /* pause DPG */ 1668 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1669 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data); 1670 1671 /* wait for ACK */ 1672 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE, 1673 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, 1674 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); 1675 1676 /* Stall DPG before WPTR/RPTR reset */ 1677 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1678 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK, 1679 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); 1680 1681 /* Restore */ 1682 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET; 1683 ring = &adev->vcn.inst[inst_idx].ring_enc[0]; 1684 ring->wptr = 0; 1685 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr); 1686 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 1687 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4); 1688 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); 1689 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1690 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET; 1691 1692 fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET; 1693 ring = &adev->vcn.inst[inst_idx].ring_enc[1]; 1694 ring->wptr = 0; 1695 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr); 1696 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 1697 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4); 1698 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); 1699 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); 1700 fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET; 1701 1702 /* Unstall DPG */ 1703 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1704 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); 1705 1706 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1707 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1708 } 1709 } else { 1710 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; 1711 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data); 1712 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1, 1713 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1714 } 1715 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based; 1716 } 1717 1718 return 0; 1719 } 1720 1721 /** 1722 * vcn_v2_5_dec_ring_get_rptr - get read pointer 1723 * 1724 * @ring: amdgpu_ring pointer 1725 * 1726 * Returns the current hardware read pointer 1727 */ 1728 static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring) 1729 { 1730 struct amdgpu_device *adev = ring->adev; 1731 1732 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR); 1733 } 1734 1735 /** 1736 * vcn_v2_5_dec_ring_get_wptr - get write pointer 1737 * 1738 * @ring: amdgpu_ring pointer 1739 * 1740 * Returns the current hardware write pointer 1741 */ 1742 static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring) 1743 { 1744 struct amdgpu_device *adev = ring->adev; 1745 1746 if (ring->use_doorbell) 1747 return *ring->wptr_cpu_addr; 1748 else 1749 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR); 1750 } 1751 1752 /** 1753 * vcn_v2_5_dec_ring_set_wptr - set write pointer 1754 * 1755 * @ring: amdgpu_ring pointer 1756 * 1757 * Commits the write pointer to the hardware 1758 */ 1759 static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring) 1760 { 1761 struct amdgpu_device *adev = ring->adev; 1762 1763 if (ring->use_doorbell) { 1764 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1765 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1766 } else { 1767 WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); 1768 } 1769 } 1770 1771 static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = { 1772 .type = AMDGPU_RING_TYPE_VCN_DEC, 1773 .align_mask = 0xf, 1774 .secure_submission_supported = true, 1775 .get_rptr = vcn_v2_5_dec_ring_get_rptr, 1776 .get_wptr = vcn_v2_5_dec_ring_get_wptr, 1777 .set_wptr = vcn_v2_5_dec_ring_set_wptr, 1778 .emit_frame_size = 1779 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 1780 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 1781 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */ 1782 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */ 1783 6, 1784 .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */ 1785 .emit_ib = vcn_v2_0_dec_ring_emit_ib, 1786 .emit_fence = vcn_v2_0_dec_ring_emit_fence, 1787 .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush, 1788 .test_ring = vcn_v2_0_dec_ring_test_ring, 1789 .test_ib = amdgpu_vcn_dec_ring_test_ib, 1790 .insert_nop = vcn_v2_0_dec_ring_insert_nop, 1791 .insert_start = vcn_v2_0_dec_ring_insert_start, 1792 .insert_end = vcn_v2_0_dec_ring_insert_end, 1793 .pad_ib = amdgpu_ring_generic_pad_ib, 1794 .begin_use = vcn_v2_5_ring_begin_use, 1795 .end_use = vcn_v2_5_ring_end_use, 1796 .emit_wreg = vcn_v2_0_dec_ring_emit_wreg, 1797 .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait, 1798 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1799 }; 1800 1801 /** 1802 * vcn_v2_5_enc_ring_get_rptr - get enc read pointer 1803 * 1804 * @ring: amdgpu_ring pointer 1805 * 1806 * Returns the current hardware enc read pointer 1807 */ 1808 static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring) 1809 { 1810 struct amdgpu_device *adev = ring->adev; 1811 1812 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) 1813 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR); 1814 else 1815 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2); 1816 } 1817 1818 /** 1819 * vcn_v2_5_enc_ring_get_wptr - get enc write pointer 1820 * 1821 * @ring: amdgpu_ring pointer 1822 * 1823 * Returns the current hardware enc write pointer 1824 */ 1825 static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring) 1826 { 1827 struct amdgpu_device *adev = ring->adev; 1828 1829 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) { 1830 if (ring->use_doorbell) 1831 return *ring->wptr_cpu_addr; 1832 else 1833 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR); 1834 } else { 1835 if (ring->use_doorbell) 1836 return *ring->wptr_cpu_addr; 1837 else 1838 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2); 1839 } 1840 } 1841 1842 /** 1843 * vcn_v2_5_enc_ring_set_wptr - set enc write pointer 1844 * 1845 * @ring: amdgpu_ring pointer 1846 * 1847 * Commits the enc write pointer to the hardware 1848 */ 1849 static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring) 1850 { 1851 struct amdgpu_device *adev = ring->adev; 1852 1853 if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) { 1854 if (ring->use_doorbell) { 1855 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1856 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1857 } else { 1858 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); 1859 } 1860 } else { 1861 if (ring->use_doorbell) { 1862 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 1863 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1864 } else { 1865 WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); 1866 } 1867 } 1868 } 1869 1870 static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = { 1871 .type = AMDGPU_RING_TYPE_VCN_ENC, 1872 .align_mask = 0x3f, 1873 .nop = VCN_ENC_CMD_NO_OP, 1874 .get_rptr = vcn_v2_5_enc_ring_get_rptr, 1875 .get_wptr = vcn_v2_5_enc_ring_get_wptr, 1876 .set_wptr = vcn_v2_5_enc_ring_set_wptr, 1877 .emit_frame_size = 1878 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1879 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1880 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */ 1881 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */ 1882 1, /* vcn_v2_0_enc_ring_insert_end */ 1883 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */ 1884 .emit_ib = vcn_v2_0_enc_ring_emit_ib, 1885 .emit_fence = vcn_v2_0_enc_ring_emit_fence, 1886 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush, 1887 .test_ring = amdgpu_vcn_enc_ring_test_ring, 1888 .test_ib = amdgpu_vcn_enc_ring_test_ib, 1889 .insert_nop = amdgpu_ring_insert_nop, 1890 .insert_end = vcn_v2_0_enc_ring_insert_end, 1891 .pad_ib = amdgpu_ring_generic_pad_ib, 1892 .begin_use = vcn_v2_5_ring_begin_use, 1893 .end_use = vcn_v2_5_ring_end_use, 1894 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg, 1895 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait, 1896 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1897 }; 1898 1899 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev) 1900 { 1901 int i; 1902 1903 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1904 if (adev->vcn.harvest_config & (1 << i)) 1905 continue; 1906 adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs; 1907 adev->vcn.inst[i].ring_dec.me = i; 1908 } 1909 } 1910 1911 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev) 1912 { 1913 int i, j; 1914 1915 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { 1916 if (adev->vcn.harvest_config & (1 << j)) 1917 continue; 1918 for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) { 1919 adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs; 1920 adev->vcn.inst[j].ring_enc[i].me = j; 1921 } 1922 } 1923 } 1924 1925 static bool vcn_v2_5_is_idle(struct amdgpu_ip_block *ip_block) 1926 { 1927 struct amdgpu_device *adev = ip_block->adev; 1928 int i, ret = 1; 1929 1930 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1931 if (adev->vcn.harvest_config & (1 << i)) 1932 continue; 1933 1934 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE); 1935 } 1936 1937 return ret; 1938 } 1939 1940 static int vcn_v2_5_wait_for_idle(struct amdgpu_ip_block *ip_block) 1941 { 1942 struct amdgpu_device *adev = ip_block->adev; 1943 int i, ret = 0; 1944 1945 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1946 if (adev->vcn.harvest_config & (1 << i)) 1947 continue; 1948 ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 1949 UVD_STATUS__IDLE); 1950 if (ret) 1951 return ret; 1952 } 1953 1954 return ret; 1955 } 1956 1957 static int vcn_v2_5_set_clockgating_state(struct amdgpu_ip_block *ip_block, 1958 enum amd_clockgating_state state) 1959 { 1960 struct amdgpu_device *adev = ip_block->adev; 1961 bool enable = (state == AMD_CG_STATE_GATE); 1962 int i; 1963 1964 if (amdgpu_sriov_vf(adev)) 1965 return 0; 1966 1967 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1968 struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i]; 1969 1970 if (enable) { 1971 if (!vcn_v2_5_is_idle(ip_block)) 1972 return -EBUSY; 1973 vcn_v2_5_enable_clock_gating(vinst); 1974 } else { 1975 vcn_v2_5_disable_clock_gating(vinst); 1976 } 1977 } 1978 1979 return 0; 1980 } 1981 1982 static int vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst *vinst, 1983 enum amd_powergating_state state) 1984 { 1985 struct amdgpu_device *adev = vinst->adev; 1986 int ret; 1987 1988 if (amdgpu_sriov_vf(adev)) 1989 return 0; 1990 1991 if (state == vinst->cur_state) 1992 return 0; 1993 1994 if (state == AMD_PG_STATE_GATE) 1995 ret = vcn_v2_5_stop(vinst); 1996 else 1997 ret = vcn_v2_5_start(vinst); 1998 1999 if (!ret) 2000 vinst->cur_state = state; 2001 2002 return ret; 2003 } 2004 2005 static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev, 2006 struct amdgpu_irq_src *source, 2007 unsigned type, 2008 enum amdgpu_interrupt_state state) 2009 { 2010 return 0; 2011 } 2012 2013 static int vcn_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev, 2014 struct amdgpu_irq_src *source, 2015 unsigned int type, 2016 enum amdgpu_interrupt_state state) 2017 { 2018 return 0; 2019 } 2020 2021 static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev, 2022 struct amdgpu_irq_src *source, 2023 struct amdgpu_iv_entry *entry) 2024 { 2025 uint32_t ip_instance; 2026 2027 switch (entry->client_id) { 2028 case SOC15_IH_CLIENTID_VCN: 2029 ip_instance = 0; 2030 break; 2031 case SOC15_IH_CLIENTID_VCN1: 2032 ip_instance = 1; 2033 break; 2034 default: 2035 DRM_ERROR("Unhandled client id: %d\n", entry->client_id); 2036 return 0; 2037 } 2038 2039 DRM_DEBUG("IH: VCN TRAP\n"); 2040 2041 switch (entry->src_id) { 2042 case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT: 2043 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec); 2044 break; 2045 case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE: 2046 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]); 2047 break; 2048 case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY: 2049 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]); 2050 break; 2051 default: 2052 DRM_ERROR("Unhandled interrupt: %d %d\n", 2053 entry->src_id, entry->src_data[0]); 2054 break; 2055 } 2056 2057 return 0; 2058 } 2059 2060 static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = { 2061 .set = vcn_v2_5_set_interrupt_state, 2062 .process = vcn_v2_5_process_interrupt, 2063 }; 2064 2065 static const struct amdgpu_irq_src_funcs vcn_v2_6_ras_irq_funcs = { 2066 .set = vcn_v2_6_set_ras_interrupt_state, 2067 .process = amdgpu_vcn_process_poison_irq, 2068 }; 2069 2070 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev) 2071 { 2072 int i; 2073 2074 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 2075 if (adev->vcn.harvest_config & (1 << i)) 2076 continue; 2077 adev->vcn.inst[i].irq.num_types = adev->vcn.inst[i].num_enc_rings + 1; 2078 adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs; 2079 2080 adev->vcn.inst[i].ras_poison_irq.num_types = adev->vcn.inst[i].num_enc_rings + 1; 2081 adev->vcn.inst[i].ras_poison_irq.funcs = &vcn_v2_6_ras_irq_funcs; 2082 } 2083 } 2084 2085 static void vcn_v2_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 2086 { 2087 struct amdgpu_device *adev = ip_block->adev; 2088 int i, j; 2089 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); 2090 uint32_t inst_off, is_powered; 2091 2092 if (!adev->vcn.ip_dump) 2093 return; 2094 2095 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); 2096 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2097 if (adev->vcn.harvest_config & (1 << i)) { 2098 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); 2099 continue; 2100 } 2101 2102 inst_off = i * reg_count; 2103 is_powered = (adev->vcn.ip_dump[inst_off] & 2104 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2105 2106 if (is_powered) { 2107 drm_printf(p, "\nActive Instance:VCN%d\n", i); 2108 for (j = 0; j < reg_count; j++) 2109 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_2_5[j].reg_name, 2110 adev->vcn.ip_dump[inst_off + j]); 2111 } else { 2112 drm_printf(p, "\nInactive Instance:VCN%d\n", i); 2113 } 2114 } 2115 } 2116 2117 static void vcn_v2_5_dump_ip_state(struct amdgpu_ip_block *ip_block) 2118 { 2119 struct amdgpu_device *adev = ip_block->adev; 2120 int i, j; 2121 bool is_powered; 2122 uint32_t inst_off; 2123 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); 2124 2125 if (!adev->vcn.ip_dump) 2126 return; 2127 2128 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 2129 if (adev->vcn.harvest_config & (1 << i)) 2130 continue; 2131 2132 inst_off = i * reg_count; 2133 /* mmUVD_POWER_STATUS is always readable and is first element of the array */ 2134 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); 2135 is_powered = (adev->vcn.ip_dump[inst_off] & 2136 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; 2137 2138 if (is_powered) 2139 for (j = 1; j < reg_count; j++) 2140 adev->vcn.ip_dump[inst_off + j] = 2141 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_2_5[j], i)); 2142 } 2143 } 2144 2145 static const struct amd_ip_funcs vcn_v2_5_ip_funcs = { 2146 .name = "vcn_v2_5", 2147 .early_init = vcn_v2_5_early_init, 2148 .sw_init = vcn_v2_5_sw_init, 2149 .sw_fini = vcn_v2_5_sw_fini, 2150 .hw_init = vcn_v2_5_hw_init, 2151 .hw_fini = vcn_v2_5_hw_fini, 2152 .suspend = vcn_v2_5_suspend, 2153 .resume = vcn_v2_5_resume, 2154 .is_idle = vcn_v2_5_is_idle, 2155 .wait_for_idle = vcn_v2_5_wait_for_idle, 2156 .set_clockgating_state = vcn_v2_5_set_clockgating_state, 2157 .set_powergating_state = vcn_set_powergating_state, 2158 .dump_ip_state = vcn_v2_5_dump_ip_state, 2159 .print_ip_state = vcn_v2_5_print_ip_state, 2160 }; 2161 2162 static const struct amd_ip_funcs vcn_v2_6_ip_funcs = { 2163 .name = "vcn_v2_6", 2164 .early_init = vcn_v2_5_early_init, 2165 .sw_init = vcn_v2_5_sw_init, 2166 .sw_fini = vcn_v2_5_sw_fini, 2167 .hw_init = vcn_v2_5_hw_init, 2168 .hw_fini = vcn_v2_5_hw_fini, 2169 .suspend = vcn_v2_5_suspend, 2170 .resume = vcn_v2_5_resume, 2171 .is_idle = vcn_v2_5_is_idle, 2172 .wait_for_idle = vcn_v2_5_wait_for_idle, 2173 .set_clockgating_state = vcn_v2_5_set_clockgating_state, 2174 .set_powergating_state = vcn_set_powergating_state, 2175 .dump_ip_state = vcn_v2_5_dump_ip_state, 2176 .print_ip_state = vcn_v2_5_print_ip_state, 2177 }; 2178 2179 const struct amdgpu_ip_block_version vcn_v2_5_ip_block = 2180 { 2181 .type = AMD_IP_BLOCK_TYPE_VCN, 2182 .major = 2, 2183 .minor = 5, 2184 .rev = 0, 2185 .funcs = &vcn_v2_5_ip_funcs, 2186 }; 2187 2188 const struct amdgpu_ip_block_version vcn_v2_6_ip_block = 2189 { 2190 .type = AMD_IP_BLOCK_TYPE_VCN, 2191 .major = 2, 2192 .minor = 6, 2193 .rev = 0, 2194 .funcs = &vcn_v2_6_ip_funcs, 2195 }; 2196 2197 static uint32_t vcn_v2_6_query_poison_by_instance(struct amdgpu_device *adev, 2198 uint32_t instance, uint32_t sub_block) 2199 { 2200 uint32_t poison_stat = 0, reg_value = 0; 2201 2202 switch (sub_block) { 2203 case AMDGPU_VCN_V2_6_VCPU_VCODEC: 2204 reg_value = RREG32_SOC15(VCN, instance, mmUVD_RAS_VCPU_VCODEC_STATUS); 2205 poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF); 2206 break; 2207 default: 2208 break; 2209 } 2210 2211 if (poison_stat) 2212 dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n", 2213 instance, sub_block); 2214 2215 return poison_stat; 2216 } 2217 2218 static bool vcn_v2_6_query_poison_status(struct amdgpu_device *adev) 2219 { 2220 uint32_t inst, sub; 2221 uint32_t poison_stat = 0; 2222 2223 for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++) 2224 for (sub = 0; sub < AMDGPU_VCN_V2_6_MAX_SUB_BLOCK; sub++) 2225 poison_stat += 2226 vcn_v2_6_query_poison_by_instance(adev, inst, sub); 2227 2228 return !!poison_stat; 2229 } 2230 2231 const struct amdgpu_ras_block_hw_ops vcn_v2_6_ras_hw_ops = { 2232 .query_poison_status = vcn_v2_6_query_poison_status, 2233 }; 2234 2235 static struct amdgpu_vcn_ras vcn_v2_6_ras = { 2236 .ras_block = { 2237 .hw_ops = &vcn_v2_6_ras_hw_ops, 2238 .ras_late_init = amdgpu_vcn_ras_late_init, 2239 }, 2240 }; 2241 2242 static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev) 2243 { 2244 switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) { 2245 case IP_VERSION(2, 6, 0): 2246 adev->vcn.ras = &vcn_v2_6_ras; 2247 break; 2248 default: 2249 break; 2250 } 2251 } 2252