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