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