1709 lines · c
1/*2 * Copyright 2023 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 */23 24#include <linux/firmware.h>25#include "amdgpu.h"26#include "amdgpu_vcn.h"27#include "amdgpu_pm.h"28#include "amdgpu_cs.h"29#include "soc15.h"30#include "soc15d.h"31#include "soc15_hw_ip.h"32#include "vcn_v2_0.h"33#include "mmsch_v4_0.h"34#include "vcn_v4_0_5.h"35 36#include "vcn/vcn_4_0_5_offset.h"37#include "vcn/vcn_4_0_5_sh_mask.h"38#include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"39 40#include <drm/drm_drv.h>41 42#define mmUVD_DPG_LMA_CTL regUVD_DPG_LMA_CTL43#define mmUVD_DPG_LMA_CTL_BASE_IDX regUVD_DPG_LMA_CTL_BASE_IDX44#define mmUVD_DPG_LMA_DATA regUVD_DPG_LMA_DATA45#define mmUVD_DPG_LMA_DATA_BASE_IDX regUVD_DPG_LMA_DATA_BASE_IDX46 47#define VCN_VID_SOC_ADDRESS_2_0 0x1fb0048#define VCN1_VID_SOC_ADDRESS_3_0 (0x48300 + 0x38000)49 50#define VCN_HARVEST_MMSCH 051 52#define RDECODE_MSG_CREATE 0x0000000053#define RDECODE_MESSAGE_CREATE 0x0000000154 55static const struct amdgpu_hwip_reg_entry vcn_reg_list_4_0_5[] = {56 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS),57 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS),58 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID),59 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2),60 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0),61 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1),62 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD),63 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI),64 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO),65 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2),66 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2),67 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3),68 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3),69 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4),70 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4),71 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR),72 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR),73 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2),74 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2),75 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3),76 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3),77 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4),78 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4),79 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE),80 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2),81 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3),82 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4),83 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_CONFIG),84 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_PGFSM_STATUS),85 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL),86 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA),87 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK),88 SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE)89};90 91static int amdgpu_ih_clientid_vcns[] = {92 SOC15_IH_CLIENTID_VCN,93 SOC15_IH_CLIENTID_VCN194};95 96static void vcn_v4_0_5_set_unified_ring_funcs(struct amdgpu_device *adev);97static void vcn_v4_0_5_set_irq_funcs(struct amdgpu_device *adev);98static int vcn_v4_0_5_set_powergating_state(void *handle,99 enum amd_powergating_state state);100static int vcn_v4_0_5_pause_dpg_mode(struct amdgpu_device *adev,101 int inst_idx, struct dpg_pause_state *new_state);102static void vcn_v4_0_5_unified_ring_set_wptr(struct amdgpu_ring *ring);103 104/**105 * vcn_v4_0_5_early_init - set function pointers and load microcode106 *107 * @handle: amdgpu_device pointer108 *109 * Set ring and irq function pointers110 * Load microcode from filesystem111 */112static int vcn_v4_0_5_early_init(void *handle)113{114 struct amdgpu_device *adev = (struct amdgpu_device *)handle;115 116 /* re-use enc ring as unified ring */117 adev->vcn.num_enc_rings = 1;118 vcn_v4_0_5_set_unified_ring_funcs(adev);119 vcn_v4_0_5_set_irq_funcs(adev);120 121 return amdgpu_vcn_early_init(adev);122}123 124/**125 * vcn_v4_0_5_sw_init - sw init for VCN block126 *127 * @handle: amdgpu_device pointer128 *129 * Load firmware and sw initialization130 */131static int vcn_v4_0_5_sw_init(void *handle)132{133 struct amdgpu_ring *ring;134 struct amdgpu_device *adev = (struct amdgpu_device *)handle;135 int i, r;136 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5);137 uint32_t *ptr;138 139 r = amdgpu_vcn_sw_init(adev);140 if (r)141 return r;142 143 amdgpu_vcn_setup_ucode(adev);144 145 r = amdgpu_vcn_resume(adev);146 if (r)147 return r;148 149 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {150 volatile struct amdgpu_vcn4_fw_shared *fw_shared;151 152 if (adev->vcn.harvest_config & (1 << i))153 continue;154 155 atomic_set(&adev->vcn.inst[i].sched_score, 0);156 157 /* VCN UNIFIED TRAP */158 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],159 VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq);160 if (r)161 return r;162 163 /* VCN POISON TRAP */164 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],165 VCN_4_0__SRCID_UVD_POISON, &adev->vcn.inst[i].irq);166 if (r)167 return r;168 169 ring = &adev->vcn.inst[i].ring_enc[0];170 ring->use_doorbell = true;171 if (amdgpu_sriov_vf(adev))172 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +173 i * (adev->vcn.num_enc_rings + 1) + 1;174 else175 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +176 2 + 8 * i;177 ring->vm_hub = AMDGPU_MMHUB0(0);178 sprintf(ring->name, "vcn_unified_%d", i);179 180 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,181 AMDGPU_RING_PRIO_0, &adev->vcn.inst[i].sched_score);182 if (r)183 return r;184 185 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;186 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);187 fw_shared->sq.is_enabled = 1;188 189 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);190 fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?191 AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;192 193 if (amdgpu_sriov_vf(adev))194 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);195 196 if (amdgpu_vcnfw_log)197 amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);198 }199 200 if (amdgpu_sriov_vf(adev)) {201 r = amdgpu_virt_alloc_mm_table(adev);202 if (r)203 return r;204 }205 206 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)207 adev->vcn.pause_dpg_mode = vcn_v4_0_5_pause_dpg_mode;208 209 /* Allocate memory for VCN IP Dump buffer */210 ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL);211 if (!ptr) {212 DRM_ERROR("Failed to allocate memory for VCN IP Dump\n");213 adev->vcn.ip_dump = NULL;214 } else {215 adev->vcn.ip_dump = ptr;216 }217 return 0;218}219 220/**221 * vcn_v4_0_5_sw_fini - sw fini for VCN block222 *223 * @handle: amdgpu_device pointer224 *225 * VCN suspend and free up sw allocation226 */227static int vcn_v4_0_5_sw_fini(void *handle)228{229 struct amdgpu_device *adev = (struct amdgpu_device *)handle;230 int i, r, idx;231 232 if (drm_dev_enter(adev_to_drm(adev), &idx)) {233 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {234 volatile struct amdgpu_vcn4_fw_shared *fw_shared;235 236 if (adev->vcn.harvest_config & (1 << i))237 continue;238 239 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;240 fw_shared->present_flag_0 = 0;241 fw_shared->sq.is_enabled = 0;242 }243 244 drm_dev_exit(idx);245 }246 247 if (amdgpu_sriov_vf(adev))248 amdgpu_virt_free_mm_table(adev);249 250 r = amdgpu_vcn_suspend(adev);251 if (r)252 return r;253 254 r = amdgpu_vcn_sw_fini(adev);255 256 kfree(adev->vcn.ip_dump);257 258 return r;259}260 261/**262 * vcn_v4_0_5_hw_init - start and test VCN block263 *264 * @handle: amdgpu_device pointer265 *266 * Initialize the hardware, boot up the VCPU and do some testing267 */268static int vcn_v4_0_5_hw_init(void *handle)269{270 struct amdgpu_device *adev = (struct amdgpu_device *)handle;271 struct amdgpu_ring *ring;272 int i, r;273 274 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {275 if (adev->vcn.harvest_config & (1 << i))276 continue;277 278 ring = &adev->vcn.inst[i].ring_enc[0];279 280 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,281 ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);282 283 r = amdgpu_ring_test_helper(ring);284 if (r)285 return r;286 }287 288 return 0;289}290 291/**292 * vcn_v4_0_5_hw_fini - stop the hardware block293 *294 * @handle: amdgpu_device pointer295 *296 * Stop the VCN block, mark ring as not ready any more297 */298static int vcn_v4_0_5_hw_fini(void *handle)299{300 struct amdgpu_device *adev = (struct amdgpu_device *)handle;301 int i;302 303 cancel_delayed_work_sync(&adev->vcn.idle_work);304 305 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {306 if (adev->vcn.harvest_config & (1 << i))307 continue;308 if (!amdgpu_sriov_vf(adev)) {309 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||310 (adev->vcn.cur_state != AMD_PG_STATE_GATE &&311 RREG32_SOC15(VCN, i, regUVD_STATUS))) {312 vcn_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE);313 }314 }315 }316 317 return 0;318}319 320/**321 * vcn_v4_0_5_suspend - suspend VCN block322 *323 * @handle: amdgpu_device pointer324 *325 * HW fini and suspend VCN block326 */327static int vcn_v4_0_5_suspend(void *handle)328{329 int r;330 struct amdgpu_device *adev = (struct amdgpu_device *)handle;331 332 r = vcn_v4_0_5_hw_fini(adev);333 if (r)334 return r;335 336 r = amdgpu_vcn_suspend(adev);337 338 return r;339}340 341/**342 * vcn_v4_0_5_resume - resume VCN block343 *344 * @handle: amdgpu_device pointer345 *346 * Resume firmware and hw init VCN block347 */348static int vcn_v4_0_5_resume(void *handle)349{350 int r;351 struct amdgpu_device *adev = (struct amdgpu_device *)handle;352 353 r = amdgpu_vcn_resume(adev);354 if (r)355 return r;356 357 r = vcn_v4_0_5_hw_init(adev);358 359 return r;360}361 362/**363 * vcn_v4_0_5_mc_resume - memory controller programming364 *365 * @adev: amdgpu_device pointer366 * @inst: instance number367 *368 * Let the VCN memory controller know it's offsets369 */370static void vcn_v4_0_5_mc_resume(struct amdgpu_device *adev, int inst)371{372 uint32_t offset, size;373 const struct common_firmware_header *hdr;374 375 hdr = (const struct common_firmware_header *)adev->vcn.fw[inst]->data;376 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);377 378 /* cache window 0: fw */379 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {380 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,381 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo));382 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,383 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi));384 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, 0);385 offset = 0;386 } else {387 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,388 lower_32_bits(adev->vcn.inst[inst].gpu_addr));389 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,390 upper_32_bits(adev->vcn.inst[inst].gpu_addr));391 offset = size;392 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, AMDGPU_UVD_FIRMWARE_OFFSET >> 3);393 }394 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE0, size);395 396 /* cache window 1: stack */397 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,398 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset));399 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,400 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset));401 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET1, 0);402 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);403 404 /* cache window 2: context */405 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,406 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));407 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,408 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));409 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET2, 0);410 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);411 412 /* non-cache window */413 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,414 lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));415 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,416 upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));417 WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_OFFSET0, 0);418 WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_SIZE0,419 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));420}421 422/**423 * vcn_v4_0_5_mc_resume_dpg_mode - memory controller programming for dpg mode424 *425 * @adev: amdgpu_device pointer426 * @inst_idx: instance number index427 * @indirect: indirectly write sram428 *429 * Let the VCN memory controller know it's offsets with dpg mode430 */431static void vcn_v4_0_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)432{433 uint32_t offset, size;434 const struct common_firmware_header *hdr;435 436 hdr = (const struct common_firmware_header *)adev->vcn.fw[inst_idx]->data;437 size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);438 439 /* cache window 0: fw */440 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {441 if (!indirect) {442 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(443 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),444 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo),445 0, indirect);446 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(447 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),448 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi),449 0, indirect);450 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(451 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);452 } else {453 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(454 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);455 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(456 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);457 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(458 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);459 }460 offset = 0;461 } else {462 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(463 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),464 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);465 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(466 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),467 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);468 offset = size;469 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(470 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0),471 AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);472 }473 474 if (!indirect)475 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(476 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect);477 else478 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(479 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);480 481 /* cache window 1: stack */482 if (!indirect) {483 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(484 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),485 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);486 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(487 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),488 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);489 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(490 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);491 } else {492 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(493 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);494 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(495 VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);496 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(497 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);498 }499 500 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(501 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);502 503 /* cache window 2: context */504 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(505 VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),506 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),507 0, indirect);508 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(509 VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),510 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),511 0, indirect);512 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(513 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);514 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(515 VCN, inst_idx, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);516 517 /* non-cache window */518 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(519 VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),520 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);521 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(522 VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),523 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);524 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(525 VCN, inst_idx, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);526 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(527 VCN, inst_idx, regUVD_VCPU_NONCACHE_SIZE0),528 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect);529 530 /* VCN global tiling registers */531 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(532 VCN, inst_idx, regUVD_GFX10_ADDR_CONFIG),533 adev->gfx.config.gb_addr_config, 0, indirect);534}535 536/**537 * vcn_v4_0_5_disable_static_power_gating - disable VCN static power gating538 *539 * @adev: amdgpu_device pointer540 * @inst: instance number541 *542 * Disable static power gating for VCN block543 */544static void vcn_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst)545{546 uint32_t data = 0;547 548 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {549 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,550 1 << UVD_IPX_DLDO_CONFIG__ONO2_PWR_CONFIG__SHIFT);551 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS, 0,552 UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS_MASK);553 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,554 2 << UVD_IPX_DLDO_CONFIG__ONO3_PWR_CONFIG__SHIFT);555 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,556 1 << UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS__SHIFT,557 UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS_MASK);558 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,559 2 << UVD_IPX_DLDO_CONFIG__ONO4_PWR_CONFIG__SHIFT);560 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,561 1 << UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS__SHIFT,562 UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS_MASK);563 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,564 2 << UVD_IPX_DLDO_CONFIG__ONO5_PWR_CONFIG__SHIFT);565 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,566 1 << UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS__SHIFT,567 UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS_MASK);568 } else {569 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,570 1 << UVD_IPX_DLDO_CONFIG__ONO2_PWR_CONFIG__SHIFT);571 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,572 0, UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS_MASK);573 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,574 1 << UVD_IPX_DLDO_CONFIG__ONO3_PWR_CONFIG__SHIFT);575 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,576 0, UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS_MASK);577 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,578 1 << UVD_IPX_DLDO_CONFIG__ONO4_PWR_CONFIG__SHIFT);579 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,580 0, UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS_MASK);581 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,582 1 << UVD_IPX_DLDO_CONFIG__ONO5_PWR_CONFIG__SHIFT);583 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,584 0, UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS_MASK);585 }586 587 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS);588 data &= ~0x103;589 if (adev->pg_flags & AMD_PG_SUPPORT_VCN)590 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON |591 UVD_POWER_STATUS__UVD_PG_EN_MASK;592 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data);593}594 595/**596 * vcn_v4_0_5_enable_static_power_gating - enable VCN static power gating597 *598 * @adev: amdgpu_device pointer599 * @inst: instance number600 *601 * Enable static power gating for VCN block602 */603static void vcn_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst)604{605 uint32_t data;606 607 if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {608 /* Before power off, this indicator has to be turned on */609 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS);610 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;611 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;612 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data);613 614 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,615 2 << UVD_IPX_DLDO_CONFIG__ONO5_PWR_CONFIG__SHIFT);616 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,617 1 << UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS__SHIFT,618 UVD_IPX_DLDO_STATUS__ONO5_PWR_STATUS_MASK);619 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,620 2 << UVD_IPX_DLDO_CONFIG__ONO4_PWR_CONFIG__SHIFT);621 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,622 1 << UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS__SHIFT,623 UVD_IPX_DLDO_STATUS__ONO4_PWR_STATUS_MASK);624 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,625 2 << UVD_IPX_DLDO_CONFIG__ONO3_PWR_CONFIG__SHIFT);626 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,627 1 << UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS__SHIFT,628 UVD_IPX_DLDO_STATUS__ONO3_PWR_STATUS_MASK);629 WREG32_SOC15(VCN, inst, regUVD_IPX_DLDO_CONFIG,630 2 << UVD_IPX_DLDO_CONFIG__ONO2_PWR_CONFIG__SHIFT);631 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_IPX_DLDO_STATUS,632 1 << UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS__SHIFT,633 UVD_IPX_DLDO_STATUS__ONO2_PWR_STATUS_MASK);634 }635}636 637/**638 * vcn_v4_0_5_disable_clock_gating - disable VCN clock gating639 *640 * @adev: amdgpu_device pointer641 * @inst: instance number642 *643 * Disable clock gating for VCN block644 */645static void vcn_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst)646{647 uint32_t data;648 649 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)650 return;651 652 /* VCN disable CGC */653 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);654 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;655 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;656 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;657 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);658 659 data = RREG32_SOC15(VCN, inst, regUVD_CGC_GATE);660 data &= ~(UVD_CGC_GATE__SYS_MASK661 | UVD_CGC_GATE__UDEC_MASK662 | UVD_CGC_GATE__MPEG2_MASK663 | UVD_CGC_GATE__REGS_MASK664 | UVD_CGC_GATE__RBC_MASK665 | UVD_CGC_GATE__LMI_MC_MASK666 | UVD_CGC_GATE__LMI_UMC_MASK667 | UVD_CGC_GATE__IDCT_MASK668 | UVD_CGC_GATE__MPRD_MASK669 | UVD_CGC_GATE__MPC_MASK670 | UVD_CGC_GATE__LBSI_MASK671 | UVD_CGC_GATE__LRBBM_MASK672 | UVD_CGC_GATE__UDEC_RE_MASK673 | UVD_CGC_GATE__UDEC_CM_MASK674 | UVD_CGC_GATE__UDEC_IT_MASK675 | UVD_CGC_GATE__UDEC_DB_MASK676 | UVD_CGC_GATE__UDEC_MP_MASK677 | UVD_CGC_GATE__WCB_MASK678 | UVD_CGC_GATE__VCPU_MASK679 | UVD_CGC_GATE__MMSCH_MASK);680 681 WREG32_SOC15(VCN, inst, regUVD_CGC_GATE, data);682 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_CGC_GATE, 0, 0xFFFFFFFF);683 684 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);685 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK686 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK687 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK688 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK689 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK690 | UVD_CGC_CTRL__SYS_MODE_MASK691 | UVD_CGC_CTRL__UDEC_MODE_MASK692 | UVD_CGC_CTRL__MPEG2_MODE_MASK693 | UVD_CGC_CTRL__REGS_MODE_MASK694 | UVD_CGC_CTRL__RBC_MODE_MASK695 | UVD_CGC_CTRL__LMI_MC_MODE_MASK696 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK697 | UVD_CGC_CTRL__IDCT_MODE_MASK698 | UVD_CGC_CTRL__MPRD_MODE_MASK699 | UVD_CGC_CTRL__MPC_MODE_MASK700 | UVD_CGC_CTRL__LBSI_MODE_MASK701 | UVD_CGC_CTRL__LRBBM_MODE_MASK702 | UVD_CGC_CTRL__WCB_MODE_MASK703 | UVD_CGC_CTRL__VCPU_MODE_MASK704 | UVD_CGC_CTRL__MMSCH_MODE_MASK);705 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);706 707 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE);708 data |= (UVD_SUVD_CGC_GATE__SRE_MASK709 | UVD_SUVD_CGC_GATE__SIT_MASK710 | UVD_SUVD_CGC_GATE__SMP_MASK711 | UVD_SUVD_CGC_GATE__SCM_MASK712 | UVD_SUVD_CGC_GATE__SDB_MASK713 | UVD_SUVD_CGC_GATE__SRE_H264_MASK714 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK715 | UVD_SUVD_CGC_GATE__SIT_H264_MASK716 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK717 | UVD_SUVD_CGC_GATE__SCM_H264_MASK718 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK719 | UVD_SUVD_CGC_GATE__SDB_H264_MASK720 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK721 | UVD_SUVD_CGC_GATE__SCLR_MASK722 | UVD_SUVD_CGC_GATE__UVD_SC_MASK723 | UVD_SUVD_CGC_GATE__ENT_MASK724 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK725 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK726 | UVD_SUVD_CGC_GATE__SITE_MASK727 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK728 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK729 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK730 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK731 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);732 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE, data);733 734 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL);735 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK736 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK737 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK738 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK739 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK740 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK741 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK742 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK743 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK744 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);745 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data);746}747 748/**749 * vcn_v4_0_5_disable_clock_gating_dpg_mode - disable VCN clock gating dpg mode750 *751 * @adev: amdgpu_device pointer752 * @sram_sel: sram select753 * @inst_idx: instance number index754 * @indirect: indirectly write sram755 *756 * Disable clock gating for VCN block with dpg mode757 */758static void vcn_v4_0_5_disable_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel,759 int inst_idx, uint8_t indirect)760{761 uint32_t reg_data = 0;762 763 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)764 return;765 766 /* enable sw clock gating control */767 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;768 reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;769 reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;770 reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |771 UVD_CGC_CTRL__UDEC_CM_MODE_MASK |772 UVD_CGC_CTRL__UDEC_IT_MODE_MASK |773 UVD_CGC_CTRL__UDEC_DB_MODE_MASK |774 UVD_CGC_CTRL__UDEC_MP_MODE_MASK |775 UVD_CGC_CTRL__SYS_MODE_MASK |776 UVD_CGC_CTRL__UDEC_MODE_MASK |777 UVD_CGC_CTRL__MPEG2_MODE_MASK |778 UVD_CGC_CTRL__REGS_MODE_MASK |779 UVD_CGC_CTRL__RBC_MODE_MASK |780 UVD_CGC_CTRL__LMI_MC_MODE_MASK |781 UVD_CGC_CTRL__LMI_UMC_MODE_MASK |782 UVD_CGC_CTRL__IDCT_MODE_MASK |783 UVD_CGC_CTRL__MPRD_MODE_MASK |784 UVD_CGC_CTRL__MPC_MODE_MASK |785 UVD_CGC_CTRL__LBSI_MODE_MASK |786 UVD_CGC_CTRL__LRBBM_MODE_MASK |787 UVD_CGC_CTRL__WCB_MODE_MASK |788 UVD_CGC_CTRL__VCPU_MODE_MASK);789 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(790 VCN, inst_idx, regUVD_CGC_CTRL), reg_data, sram_sel, indirect);791 792 /* turn off clock gating */793 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(794 VCN, inst_idx, regUVD_CGC_GATE), 0, sram_sel, indirect);795 796 /* turn on SUVD clock gating */797 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(798 VCN, inst_idx, regUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);799 800 /* turn on sw mode in UVD_SUVD_CGC_CTRL */801 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(802 VCN, inst_idx, regUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);803}804 805/**806 * vcn_v4_0_5_enable_clock_gating - enable VCN clock gating807 *808 * @adev: amdgpu_device pointer809 * @inst: instance number810 *811 * Enable clock gating for VCN block812 */813static void vcn_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst)814{815 uint32_t data;816 817 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)818 return;819 820 /* enable VCN CGC */821 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);822 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;823 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;824 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;825 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);826 827 data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);828 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK829 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK830 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK831 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK832 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK833 | UVD_CGC_CTRL__SYS_MODE_MASK834 | UVD_CGC_CTRL__UDEC_MODE_MASK835 | UVD_CGC_CTRL__MPEG2_MODE_MASK836 | UVD_CGC_CTRL__REGS_MODE_MASK837 | UVD_CGC_CTRL__RBC_MODE_MASK838 | UVD_CGC_CTRL__LMI_MC_MODE_MASK839 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK840 | UVD_CGC_CTRL__IDCT_MODE_MASK841 | UVD_CGC_CTRL__MPRD_MODE_MASK842 | UVD_CGC_CTRL__MPC_MODE_MASK843 | UVD_CGC_CTRL__LBSI_MODE_MASK844 | UVD_CGC_CTRL__LRBBM_MODE_MASK845 | UVD_CGC_CTRL__WCB_MODE_MASK846 | UVD_CGC_CTRL__VCPU_MODE_MASK847 | UVD_CGC_CTRL__MMSCH_MODE_MASK);848 WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);849 850 data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL);851 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK852 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK853 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK854 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK855 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK856 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK857 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK858 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK859 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK860 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);861 WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data);862}863 864/**865 * vcn_v4_0_5_start_dpg_mode - VCN start with dpg mode866 *867 * @adev: amdgpu_device pointer868 * @inst_idx: instance number index869 * @indirect: indirectly write sram870 *871 * Start VCN block with dpg mode872 */873static int vcn_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)874{875 volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;876 struct amdgpu_ring *ring;877 uint32_t tmp;878 879 /* disable register anti-hang mechanism */880 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1,881 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);882 /* enable dynamic power gating mode */883 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS);884 tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;885 tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;886 WREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS, tmp);887 888 if (indirect)889 adev->vcn.inst[inst_idx].dpg_sram_curr_addr =890 (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;891 892 /* enable clock gating */893 vcn_v4_0_5_disable_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);894 895 /* enable VCPU clock */896 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);897 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK;898 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(899 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect);900 901 /* disable master interrupt */902 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(903 VCN, inst_idx, regUVD_MASTINT_EN), 0, 0, indirect);904 905 /* setup regUVD_LMI_CTRL */906 tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |907 UVD_LMI_CTRL__REQ_MODE_MASK |908 UVD_LMI_CTRL__CRC_RESET_MASK |909 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |910 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |911 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |912 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |913 0x00100000L);914 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(915 VCN, inst_idx, regUVD_LMI_CTRL), tmp, 0, indirect);916 917 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(918 VCN, inst_idx, regUVD_MPC_CNTL),919 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);920 921 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(922 VCN, inst_idx, regUVD_MPC_SET_MUXA0),923 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |924 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |925 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |926 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);927 928 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(929 VCN, inst_idx, regUVD_MPC_SET_MUXB0),930 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |931 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |932 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |933 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);934 935 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(936 VCN, inst_idx, regUVD_MPC_SET_MUX),937 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |938 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |939 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);940 941 vcn_v4_0_5_mc_resume_dpg_mode(adev, inst_idx, indirect);942 943 tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);944 tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;945 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(946 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect);947 948 /* enable LMI MC and UMC channels */949 tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT;950 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(951 VCN, inst_idx, regUVD_LMI_CTRL2), tmp, 0, indirect);952 953 /* enable master interrupt */954 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(955 VCN, inst_idx, regUVD_MASTINT_EN),956 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);957 958 if (indirect)959 amdgpu_vcn_psp_update_sram(adev, inst_idx, 0);960 961 ring = &adev->vcn.inst[inst_idx].ring_enc[0];962 963 WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_LO, ring->gpu_addr);964 WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));965 WREG32_SOC15(VCN, inst_idx, regUVD_RB_SIZE, ring->ring_size / 4);966 967 tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE);968 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);969 WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp);970 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;971 WREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR, 0);972 WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, 0);973 974 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR);975 WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, tmp);976 ring->wptr = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR);977 978 tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE);979 tmp |= VCN_RB_ENABLE__RB1_EN_MASK;980 WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp);981 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);982 983 WREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL,984 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |985 VCN_RB1_DB_CTRL__EN_MASK);986 987 return 0;988}989 990 991/**992 * vcn_v4_0_5_start - VCN start993 *994 * @adev: amdgpu_device pointer995 *996 * Start VCN block997 */998static int vcn_v4_0_5_start(struct amdgpu_device *adev)999{1000 volatile struct amdgpu_vcn4_fw_shared *fw_shared;1001 struct amdgpu_ring *ring;1002 uint32_t tmp;1003 int i, j, k, r;1004 1005 if (adev->pm.dpm_enabled)1006 amdgpu_dpm_enable_uvd(adev, true);1007 1008 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1009 if (adev->vcn.harvest_config & (1 << i))1010 continue;1011 1012 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;1013 1014 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {1015 r = vcn_v4_0_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram);1016 continue;1017 }1018 1019 /* disable VCN power gating */1020 vcn_v4_0_5_disable_static_power_gating(adev, i);1021 1022 /* set VCN status busy */1023 tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY;1024 WREG32_SOC15(VCN, i, regUVD_STATUS, tmp);1025 1026 /*SW clock gating */1027 vcn_v4_0_5_disable_clock_gating(adev, i);1028 1029 /* enable VCPU clock */1030 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL),1031 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);1032 1033 /* disable master interrupt */1034 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0,1035 ~UVD_MASTINT_EN__VCPU_EN_MASK);1036 1037 /* enable LMI MC and UMC channels */1038 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0,1039 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);1040 1041 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET);1042 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;1043 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;1044 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp);1045 1046 /* setup regUVD_LMI_CTRL */1047 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL);1048 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp |1049 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |1050 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |1051 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |1052 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);1053 1054 /* setup regUVD_MPC_CNTL */1055 tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL);1056 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;1057 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;1058 WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp);1059 1060 /* setup UVD_MPC_SET_MUXA0 */1061 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0,1062 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |1063 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |1064 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |1065 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));1066 1067 /* setup UVD_MPC_SET_MUXB0 */1068 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0,1069 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |1070 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |1071 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |1072 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));1073 1074 /* setup UVD_MPC_SET_MUX */1075 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX,1076 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |1077 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |1078 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));1079 1080 vcn_v4_0_5_mc_resume(adev, i);1081 1082 /* VCN global tiling registers */1083 WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG,1084 adev->gfx.config.gb_addr_config);1085 1086 /* unblock VCPU register access */1087 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0,1088 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);1089 1090 /* release VCPU reset to boot */1091 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0,1092 ~UVD_VCPU_CNTL__BLK_RST_MASK);1093 1094 for (j = 0; j < 10; ++j) {1095 uint32_t status;1096 1097 for (k = 0; k < 100; ++k) {1098 status = RREG32_SOC15(VCN, i, regUVD_STATUS);1099 if (status & 2)1100 break;1101 mdelay(10);1102 if (amdgpu_emu_mode == 1)1103 msleep(1);1104 }1105 1106 if (amdgpu_emu_mode == 1) {1107 r = -1;1108 if (status & 2) {1109 r = 0;1110 break;1111 }1112 } else {1113 r = 0;1114 if (status & 2)1115 break;1116 1117 dev_err(adev->dev,1118 "VCN[%d] is not responding, trying to reset VCPU!!!\n", i);1119 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL),1120 UVD_VCPU_CNTL__BLK_RST_MASK,1121 ~UVD_VCPU_CNTL__BLK_RST_MASK);1122 mdelay(10);1123 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0,1124 ~UVD_VCPU_CNTL__BLK_RST_MASK);1125 1126 mdelay(10);1127 r = -1;1128 }1129 }1130 1131 if (r) {1132 dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i);1133 return r;1134 }1135 1136 /* enable master interrupt */1137 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN),1138 UVD_MASTINT_EN__VCPU_EN_MASK,1139 ~UVD_MASTINT_EN__VCPU_EN_MASK);1140 1141 /* clear the busy bit of VCN_STATUS */1142 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0,1143 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));1144 1145 ring = &adev->vcn.inst[i].ring_enc[0];1146 WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL,1147 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |1148 VCN_RB1_DB_CTRL__EN_MASK);1149 1150 WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr);1151 WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));1152 WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4);1153 1154 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE);1155 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);1156 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp);1157 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;1158 WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0);1159 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0);1160 1161 tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR);1162 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp);1163 ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR);1164 1165 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE);1166 tmp |= VCN_RB_ENABLE__RB1_EN_MASK;1167 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp);1168 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);1169 }1170 1171 return 0;1172}1173 1174/**1175 * vcn_v4_0_5_stop_dpg_mode - VCN stop with dpg mode1176 *1177 * @adev: amdgpu_device pointer1178 * @inst_idx: instance number index1179 *1180 * Stop VCN block with dpg mode1181 */1182static void vcn_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)1183{1184 uint32_t tmp;1185 1186 /* Wait for power status to be 1 */1187 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1,1188 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1189 1190 /* wait for read ptr to be equal to write ptr */1191 tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR);1192 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_RB_RPTR, tmp, 0xFFFFFFFF);1193 1194 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1,1195 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1196 1197 /* disable dynamic power gating mode */1198 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0,1199 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);1200}1201 1202/**1203 * vcn_v4_0_5_stop - VCN stop1204 *1205 * @adev: amdgpu_device pointer1206 *1207 * Stop VCN block1208 */1209static int vcn_v4_0_5_stop(struct amdgpu_device *adev)1210{1211 volatile struct amdgpu_vcn4_fw_shared *fw_shared;1212 uint32_t tmp;1213 int i, r = 0;1214 1215 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1216 if (adev->vcn.harvest_config & (1 << i))1217 continue;1218 1219 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;1220 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;1221 1222 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {1223 vcn_v4_0_5_stop_dpg_mode(adev, i);1224 continue;1225 }1226 1227 /* wait for vcn idle */1228 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7);1229 if (r)1230 return r;1231 1232 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |1233 UVD_LMI_STATUS__READ_CLEAN_MASK |1234 UVD_LMI_STATUS__WRITE_CLEAN_MASK |1235 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;1236 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp);1237 if (r)1238 return r;1239 1240 /* disable LMI UMC channel */1241 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2);1242 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;1243 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp);1244 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |1245 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;1246 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp);1247 if (r)1248 return r;1249 1250 /* block VCPU register access */1251 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL),1252 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,1253 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);1254 1255 /* reset VCPU */1256 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL),1257 UVD_VCPU_CNTL__BLK_RST_MASK,1258 ~UVD_VCPU_CNTL__BLK_RST_MASK);1259 1260 /* disable VCPU clock */1261 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0,1262 ~(UVD_VCPU_CNTL__CLK_EN_MASK));1263 1264 /* apply soft reset */1265 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET);1266 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;1267 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp);1268 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET);1269 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;1270 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp);1271 1272 /* clear status */1273 WREG32_SOC15(VCN, i, regUVD_STATUS, 0);1274 1275 /* apply HW clock gating */1276 vcn_v4_0_5_enable_clock_gating(adev, i);1277 1278 /* enable VCN power gating */1279 vcn_v4_0_5_enable_static_power_gating(adev, i);1280 }1281 1282 if (adev->pm.dpm_enabled)1283 amdgpu_dpm_enable_uvd(adev, false);1284 1285 return 0;1286}1287 1288/**1289 * vcn_v4_0_5_pause_dpg_mode - VCN pause with dpg mode1290 *1291 * @adev: amdgpu_device pointer1292 * @inst_idx: instance number index1293 * @new_state: pause state1294 *1295 * Pause dpg mode for VCN block1296 */1297static int vcn_v4_0_5_pause_dpg_mode(struct amdgpu_device *adev, int inst_idx,1298 struct dpg_pause_state *new_state)1299{1300 uint32_t reg_data = 0;1301 int ret_code;1302 1303 /* pause/unpause if state is changed */1304 if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {1305 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d",1306 adev->vcn.inst[inst_idx].pause_state.fw_based, new_state->fw_based);1307 reg_data = RREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE) &1308 (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);1309 1310 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {1311 ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 0x1,1312 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1313 1314 if (!ret_code) {1315 /* pause DPG */1316 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;1317 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data);1318 1319 /* wait for ACK */1320 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_DPG_PAUSE,1321 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,1322 UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);1323 1324 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS,1325 UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,1326 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);1327 }1328 } else {1329 /* unpause dpg, no need to wait */1330 reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;1331 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data);1332 }1333 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;1334 }1335 1336 return 0;1337}1338 1339/**1340 * vcn_v4_0_5_unified_ring_get_rptr - get unified read pointer1341 *1342 * @ring: amdgpu_ring pointer1343 *1344 * Returns the current hardware unified read pointer1345 */1346static uint64_t vcn_v4_0_5_unified_ring_get_rptr(struct amdgpu_ring *ring)1347{1348 struct amdgpu_device *adev = ring->adev;1349 1350 if (ring != &adev->vcn.inst[ring->me].ring_enc[0])1351 DRM_ERROR("wrong ring id is identified in %s", __func__);1352 1353 return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR);1354}1355 1356/**1357 * vcn_v4_0_5_unified_ring_get_wptr - get unified write pointer1358 *1359 * @ring: amdgpu_ring pointer1360 *1361 * Returns the current hardware unified write pointer1362 */1363static uint64_t vcn_v4_0_5_unified_ring_get_wptr(struct amdgpu_ring *ring)1364{1365 struct amdgpu_device *adev = ring->adev;1366 1367 if (ring != &adev->vcn.inst[ring->me].ring_enc[0])1368 DRM_ERROR("wrong ring id is identified in %s", __func__);1369 1370 if (ring->use_doorbell)1371 return *ring->wptr_cpu_addr;1372 else1373 return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR);1374}1375 1376/**1377 * vcn_v4_0_5_unified_ring_set_wptr - set enc write pointer1378 *1379 * @ring: amdgpu_ring pointer1380 *1381 * Commits the enc write pointer to the hardware1382 */1383static void vcn_v4_0_5_unified_ring_set_wptr(struct amdgpu_ring *ring)1384{1385 struct amdgpu_device *adev = ring->adev;1386 1387 if (ring != &adev->vcn.inst[ring->me].ring_enc[0])1388 DRM_ERROR("wrong ring id is identified in %s", __func__);1389 1390 if (ring->use_doorbell) {1391 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);1392 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));1393 } else {1394 WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR, lower_32_bits(ring->wptr));1395 }1396}1397 1398static const struct amdgpu_ring_funcs vcn_v4_0_5_unified_ring_vm_funcs = {1399 .type = AMDGPU_RING_TYPE_VCN_ENC,1400 .align_mask = 0x3f,1401 .nop = VCN_ENC_CMD_NO_OP,1402 .get_rptr = vcn_v4_0_5_unified_ring_get_rptr,1403 .get_wptr = vcn_v4_0_5_unified_ring_get_wptr,1404 .set_wptr = vcn_v4_0_5_unified_ring_set_wptr,1405 .emit_frame_size =1406 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +1407 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +1408 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */1409 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */1410 1, /* vcn_v2_0_enc_ring_insert_end */1411 .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */1412 .emit_ib = vcn_v2_0_enc_ring_emit_ib,1413 .emit_fence = vcn_v2_0_enc_ring_emit_fence,1414 .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,1415 .test_ring = amdgpu_vcn_enc_ring_test_ring,1416 .test_ib = amdgpu_vcn_unified_ring_test_ib,1417 .insert_nop = amdgpu_ring_insert_nop,1418 .insert_end = vcn_v2_0_enc_ring_insert_end,1419 .pad_ib = amdgpu_ring_generic_pad_ib,1420 .begin_use = amdgpu_vcn_ring_begin_use,1421 .end_use = amdgpu_vcn_ring_end_use,1422 .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,1423 .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,1424 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,1425};1426 1427/**1428 * vcn_v4_0_5_set_unified_ring_funcs - set unified ring functions1429 *1430 * @adev: amdgpu_device pointer1431 *1432 * Set unified ring functions1433 */1434static void vcn_v4_0_5_set_unified_ring_funcs(struct amdgpu_device *adev)1435{1436 int i;1437 1438 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1439 if (adev->vcn.harvest_config & (1 << i))1440 continue;1441 1442 adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v4_0_5_unified_ring_vm_funcs;1443 adev->vcn.inst[i].ring_enc[0].me = i;1444 }1445}1446 1447/**1448 * vcn_v4_0_5_is_idle - check VCN block is idle1449 *1450 * @handle: amdgpu_device pointer1451 *1452 * Check whether VCN block is idle1453 */1454static bool vcn_v4_0_5_is_idle(void *handle)1455{1456 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1457 int i, ret = 1;1458 1459 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1460 if (adev->vcn.harvest_config & (1 << i))1461 continue;1462 1463 ret &= (RREG32_SOC15(VCN, i, regUVD_STATUS) == UVD_STATUS__IDLE);1464 }1465 1466 return ret;1467}1468 1469/**1470 * vcn_v4_0_5_wait_for_idle - wait for VCN block idle1471 *1472 * @handle: amdgpu_device pointer1473 *1474 * Wait for VCN block idle1475 */1476static int vcn_v4_0_5_wait_for_idle(void *handle)1477{1478 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1479 int i, ret = 0;1480 1481 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1482 if (adev->vcn.harvest_config & (1 << i))1483 continue;1484 1485 ret = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE,1486 UVD_STATUS__IDLE);1487 if (ret)1488 return ret;1489 }1490 1491 return ret;1492}1493 1494/**1495 * vcn_v4_0_5_set_clockgating_state - set VCN block clockgating state1496 *1497 * @handle: amdgpu_device pointer1498 * @state: clock gating state1499 *1500 * Set VCN block clockgating state1501 */1502static int vcn_v4_0_5_set_clockgating_state(void *handle, enum amd_clockgating_state state)1503{1504 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1505 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;1506 int i;1507 1508 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1509 if (adev->vcn.harvest_config & (1 << i))1510 continue;1511 1512 if (enable) {1513 if (RREG32_SOC15(VCN, i, regUVD_STATUS) != UVD_STATUS__IDLE)1514 return -EBUSY;1515 vcn_v4_0_5_enable_clock_gating(adev, i);1516 } else {1517 vcn_v4_0_5_disable_clock_gating(adev, i);1518 }1519 }1520 1521 return 0;1522}1523 1524/**1525 * vcn_v4_0_5_set_powergating_state - set VCN block powergating state1526 *1527 * @handle: amdgpu_device pointer1528 * @state: power gating state1529 *1530 * Set VCN block powergating state1531 */1532static int vcn_v4_0_5_set_powergating_state(void *handle, enum amd_powergating_state state)1533{1534 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1535 int ret;1536 1537 if (state == adev->vcn.cur_state)1538 return 0;1539 1540 if (state == AMD_PG_STATE_GATE)1541 ret = vcn_v4_0_5_stop(adev);1542 else1543 ret = vcn_v4_0_5_start(adev);1544 1545 if (!ret)1546 adev->vcn.cur_state = state;1547 1548 return ret;1549}1550 1551/**1552 * vcn_v4_0_5_process_interrupt - process VCN block interrupt1553 *1554 * @adev: amdgpu_device pointer1555 * @source: interrupt sources1556 * @entry: interrupt entry from clients and sources1557 *1558 * Process VCN block interrupt1559 */1560static int vcn_v4_0_5_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source,1561 struct amdgpu_iv_entry *entry)1562{1563 uint32_t ip_instance;1564 1565 switch (entry->client_id) {1566 case SOC15_IH_CLIENTID_VCN:1567 ip_instance = 0;1568 break;1569 case SOC15_IH_CLIENTID_VCN1:1570 ip_instance = 1;1571 break;1572 default:1573 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);1574 return 0;1575 }1576 1577 DRM_DEBUG("IH: VCN TRAP\n");1578 1579 switch (entry->src_id) {1580 case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE:1581 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);1582 break;1583 case VCN_4_0__SRCID_UVD_POISON:1584 amdgpu_vcn_process_poison_irq(adev, source, entry);1585 break;1586 default:1587 DRM_ERROR("Unhandled interrupt: %d %d\n",1588 entry->src_id, entry->src_data[0]);1589 break;1590 }1591 1592 return 0;1593}1594 1595static const struct amdgpu_irq_src_funcs vcn_v4_0_5_irq_funcs = {1596 .process = vcn_v4_0_5_process_interrupt,1597};1598 1599/**1600 * vcn_v4_0_5_set_irq_funcs - set VCN block interrupt irq functions1601 *1602 * @adev: amdgpu_device pointer1603 *1604 * Set VCN block interrupt irq functions1605 */1606static void vcn_v4_0_5_set_irq_funcs(struct amdgpu_device *adev)1607{1608 int i;1609 1610 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {1611 if (adev->vcn.harvest_config & (1 << i))1612 continue;1613 1614 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1;1615 adev->vcn.inst[i].irq.funcs = &vcn_v4_0_5_irq_funcs;1616 }1617}1618 1619static void vcn_v4_0_5_print_ip_state(void *handle, struct drm_printer *p)1620{1621 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1622 int i, j;1623 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5);1624 uint32_t inst_off, is_powered;1625 1626 if (!adev->vcn.ip_dump)1627 return;1628 1629 drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst);1630 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {1631 if (adev->vcn.harvest_config & (1 << i)) {1632 drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i);1633 continue;1634 }1635 1636 inst_off = i * reg_count;1637 is_powered = (adev->vcn.ip_dump[inst_off] &1638 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1;1639 1640 if (is_powered) {1641 drm_printf(p, "\nActive Instance:VCN%d\n", i);1642 for (j = 0; j < reg_count; j++)1643 drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_5[j].reg_name,1644 adev->vcn.ip_dump[inst_off + j]);1645 } else {1646 drm_printf(p, "\nInactive Instance:VCN%d\n", i);1647 }1648 }1649}1650 1651static void vcn_v4_0_5_dump_ip_state(void *handle)1652{1653 struct amdgpu_device *adev = (struct amdgpu_device *)handle;1654 int i, j;1655 bool is_powered;1656 uint32_t inst_off;1657 uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5);1658 1659 if (!adev->vcn.ip_dump)1660 return;1661 1662 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {1663 if (adev->vcn.harvest_config & (1 << i))1664 continue;1665 1666 inst_off = i * reg_count;1667 /* mmUVD_POWER_STATUS is always readable and is first element of the array */1668 adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS);1669 is_powered = (adev->vcn.ip_dump[inst_off] &1670 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1;1671 1672 if (is_powered)1673 for (j = 1; j < reg_count; j++)1674 adev->vcn.ip_dump[inst_off + j] =1675 RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_5[j],1676 i));1677 }1678}1679 1680static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = {1681 .name = "vcn_v4_0_5",1682 .early_init = vcn_v4_0_5_early_init,1683 .late_init = NULL,1684 .sw_init = vcn_v4_0_5_sw_init,1685 .sw_fini = vcn_v4_0_5_sw_fini,1686 .hw_init = vcn_v4_0_5_hw_init,1687 .hw_fini = vcn_v4_0_5_hw_fini,1688 .suspend = vcn_v4_0_5_suspend,1689 .resume = vcn_v4_0_5_resume,1690 .is_idle = vcn_v4_0_5_is_idle,1691 .wait_for_idle = vcn_v4_0_5_wait_for_idle,1692 .check_soft_reset = NULL,1693 .pre_soft_reset = NULL,1694 .soft_reset = NULL,1695 .post_soft_reset = NULL,1696 .set_clockgating_state = vcn_v4_0_5_set_clockgating_state,1697 .set_powergating_state = vcn_v4_0_5_set_powergating_state,1698 .dump_ip_state = vcn_v4_0_5_dump_ip_state,1699 .print_ip_state = vcn_v4_0_5_print_ip_state,1700};1701 1702const struct amdgpu_ip_block_version vcn_v4_0_5_ip_block = {1703 .type = AMD_IP_BLOCK_TYPE_VCN,1704 .major = 4,1705 .minor = 0,1706 .rev = 5,1707 .funcs = &vcn_v4_0_5_ip_funcs,1708};1709