File Index
Files and directories
Sign in
FILE

vcn_v2_5.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c C
   1/*
   2 * Copyright 2019 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 */
  23
  24#include <linux/firmware.h>
  25#include <drm/drm_drv.h>
  26
  27#include "amdgpu.h"
  28#include "amdgpu_vcn.h"
  29#include "amdgpu_pm.h"
  30#include "soc15.h"
  31#include "soc15d.h"
  32#include "vcn_v2_0.h"
  33#include "mmsch_v1_0.h"
  34#include "vcn_v2_5.h"
  35
  36#include "vcn/vcn_2_5_offset.h"
  37#include "vcn/vcn_2_5_sh_mask.h"
  38#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
  39
  40#define VCN_VID_SOC_ADDRESS_2_0					0x1fa00
  41#define VCN1_VID_SOC_ADDRESS_3_0				0x48200
  42#define VCN1_AON_SOC_ADDRESS_3_0				0x48000
  43
  44#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET			0x27
  45#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET			0x0f
  46#define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET			0x10
  47#define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET			0x11
  48#define mmUVD_NO_OP_INTERNAL_OFFSET				0x29
  49#define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET			0x66
  50#define mmUVD_SCRATCH9_INTERNAL_OFFSET				0xc01d
  51
  52#define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET			0x431
  53#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET		0x3b4
  54#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET		0x3b5
  55#define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET			0x25c
  56
  57#define VCN25_MAX_HW_INSTANCES_ARCTURUS			2
  58
  59static const struct amdgpu_hwip_reg_entry vcn_reg_list_2_5[] = {
  60	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS),
  61	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_POWER_STATUS),
  62	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_STATUS),
  63	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID),
  64	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_CONTEXT_ID2),
  65	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA0),
  66	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_DATA1),
  67	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_GPCOM_VCPU_CMD),
  68	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI),
  69	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO),
  70	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI2),
  71	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO2),
  72	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI3),
  73	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO3),
  74	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_HI4),
  75	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_BASE_LO4),
  76	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR),
  77	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR),
  78	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR2),
  79	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR2),
  80	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR3),
  81	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR3),
  82	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_RPTR4),
  83	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_WPTR4),
  84	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE),
  85	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE2),
  86	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE3),
  87	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_RB_SIZE4),
  88	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_CONFIG),
  89	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_PGFSM_STATUS),
  90	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_CTL),
  91	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_DATA),
  92	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_LMA_MASK),
  93	SOC15_REG_ENTRY_STR(VCN, 0, mmUVD_DPG_PAUSE)
  94};
  95
  96static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
  97static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
  98static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
  99static int vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst *vinst,
 100				 enum amd_powergating_state state);
 101static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
 102				   struct dpg_pause_state *new_state);
 103static int vcn_v2_5_sriov_start(struct amdgpu_device *adev);
 104static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev);
 105static int vcn_v2_5_reset(struct amdgpu_vcn_inst *vinst);
 106
 107static int amdgpu_ih_clientid_vcns[] = {
 108	SOC15_IH_CLIENTID_VCN,
 109	SOC15_IH_CLIENTID_VCN1
 110};
 111
 112static void vcn_v2_5_idle_work_handler(struct work_struct *work)
 113{
 114	struct amdgpu_vcn_inst *vcn_inst =
 115		container_of(work, struct amdgpu_vcn_inst, idle_work.work);
 116	struct amdgpu_device *adev = vcn_inst->adev;
 117	unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
 118	unsigned int i, j;
 119
 120	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 121		struct amdgpu_vcn_inst *v = &adev->vcn.inst[i];
 122
 123		if (adev->vcn.harvest_config & (1 << i))
 124			continue;
 125
 126		for (j = 0; j < v->num_enc_rings; ++j)
 127			fence[i] += amdgpu_fence_count_emitted(&v->ring_enc[j]);
 128
 129		/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
 130		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
 131		    !v->using_unified_queue) {
 132			struct dpg_pause_state new_state;
 133
 134			if (fence[i] ||
 135			    unlikely(atomic_read(&v->dpg_enc_submission_cnt)))
 136				new_state.fw_based = VCN_DPG_STATE__PAUSE;
 137			else
 138				new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
 139
 140			v->pause_dpg_mode(v, &new_state);
 141		}
 142
 143		fence[i] += amdgpu_fence_count_emitted(&v->ring_dec);
 144		fences += fence[i];
 145
 146	}
 147
 148	if (!fences && !atomic_read(&adev->vcn.inst[0].total_submission_cnt)) {
 149		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
 150						       AMD_PG_STATE_GATE);
 151		amdgpu_vcn_put_profile(adev);
 152	} else {
 153		schedule_delayed_work(&adev->vcn.inst[0].idle_work, VCN_IDLE_TIMEOUT);
 154	}
 155}
 156
 157static void vcn_v2_5_ring_begin_use(struct amdgpu_ring *ring)
 158{
 159	struct amdgpu_device *adev = ring->adev;
 160	struct amdgpu_vcn_inst *v = &adev->vcn.inst[ring->me];
 161
 162	atomic_inc(&adev->vcn.inst[0].total_submission_cnt);
 163
 164	cancel_delayed_work_sync(&adev->vcn.inst[0].idle_work);
 165
 166	/* We can safely return early here because we've cancelled the
 167	 * the delayed work so there is no one else to set it to false
 168	 * and we don't care if someone else sets it to true.
 169	 */
 170	mutex_lock(&adev->vcn.inst[0].vcn_pg_lock);
 171	amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
 172					       AMD_PG_STATE_UNGATE);
 173
 174	/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
 175	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
 176	    !v->using_unified_queue) {
 177		struct dpg_pause_state new_state;
 178
 179		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
 180			atomic_inc(&v->dpg_enc_submission_cnt);
 181			new_state.fw_based = VCN_DPG_STATE__PAUSE;
 182		} else {
 183			unsigned int fences = 0;
 184			unsigned int i;
 185
 186			for (i = 0; i < v->num_enc_rings; ++i)
 187				fences += amdgpu_fence_count_emitted(&v->ring_enc[i]);
 188
 189			if (fences || atomic_read(&v->dpg_enc_submission_cnt))
 190				new_state.fw_based = VCN_DPG_STATE__PAUSE;
 191			else
 192				new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
 193		}
 194		v->pause_dpg_mode(v, &new_state);
 195	}
 196	mutex_unlock(&adev->vcn.inst[0].vcn_pg_lock);
 197	amdgpu_vcn_get_profile(adev);
 198}
 199
 200static void vcn_v2_5_ring_end_use(struct amdgpu_ring *ring)
 201{
 202	struct amdgpu_device *adev = ring->adev;
 203
 204	/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
 205	if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
 206	    ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
 207	    !adev->vcn.inst[ring->me].using_unified_queue)
 208		atomic_dec(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
 209
 210	atomic_dec(&adev->vcn.inst[0].total_submission_cnt);
 211
 212	schedule_delayed_work(&adev->vcn.inst[0].idle_work,
 213			      VCN_IDLE_TIMEOUT);
 214}
 215
 216/**
 217 * vcn_v2_5_early_init - set function pointers and load microcode
 218 *
 219 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 220 *
 221 * Set ring and irq function pointers
 222 * Load microcode from filesystem
 223 */
 224static int vcn_v2_5_early_init(struct amdgpu_ip_block *ip_block)
 225{
 226	struct amdgpu_device *adev = ip_block->adev;
 227	int i, r;
 228
 229	if (amdgpu_sriov_vf(adev)) {
 230		adev->vcn.num_vcn_inst = 2;
 231		adev->vcn.harvest_config = 0;
 232		for (i = 0; i < adev->vcn.num_vcn_inst; i++)
 233			adev->vcn.inst[i].num_enc_rings = 1;
 234	} else {
 235		u32 harvest;
 236		int i;
 237
 238		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 239			harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING);
 240			if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
 241				adev->vcn.harvest_config |= 1 << i;
 242			adev->vcn.inst[i].num_enc_rings = 2;
 243		}
 244		if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
 245						 AMDGPU_VCN_HARVEST_VCN1))
 246			/* both instances are harvested, disable the block */
 247			return -ENOENT;
 248	}
 249
 250	vcn_v2_5_set_dec_ring_funcs(adev);
 251	vcn_v2_5_set_enc_ring_funcs(adev);
 252	vcn_v2_5_set_irq_funcs(adev);
 253	vcn_v2_5_set_ras_funcs(adev);
 254
 255	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 256		adev->vcn.inst[i].set_pg_state = vcn_v2_5_set_pg_state;
 257
 258		r = amdgpu_vcn_early_init(adev, i);
 259		if (r)
 260			return r;
 261	}
 262
 263	return 0;
 264}
 265
 266/**
 267 * vcn_v2_5_sw_init - sw init for VCN block
 268 *
 269 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 270 *
 271 * Load firmware and sw initialization
 272 */
 273static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
 274{
 275	struct amdgpu_ring *ring;
 276	int i, j, r;
 277	struct amdgpu_device *adev = ip_block->adev;
 278
 279	for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
 280		struct amdgpu_fw_shared *fw_shared;
 281
 282		if (adev->vcn.harvest_config & (1 << j))
 283			continue;
 284		/* VCN DEC TRAP */
 285		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
 286				VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
 287		if (r)
 288			return r;
 289
 290		/* VCN ENC TRAP */
 291		for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
 292			r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
 293				i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
 294			if (r)
 295				return r;
 296		}
 297
 298		/* VCN POISON TRAP */
 299		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
 300			VCN_2_6__SRCID_UVD_POISON, &adev->vcn.inst[j].ras_poison_irq);
 301		if (r)
 302			return r;
 303
 304		r = amdgpu_vcn_sw_init(adev, j);
 305		if (r)
 306			return r;
 307
 308		/* Override the work func */
 309		adev->vcn.inst[j].idle_work.work.func = vcn_v2_5_idle_work_handler;
 310
 311		amdgpu_vcn_setup_ucode(adev, j);
 312
 313		r = amdgpu_vcn_resume(adev, j);
 314		if (r)
 315			return r;
 316
 317		adev->vcn.inst[j].internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
 318		adev->vcn.inst[j].internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
 319		adev->vcn.inst[j].internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
 320		adev->vcn.inst[j].internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
 321		adev->vcn.inst[j].internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
 322		adev->vcn.inst[j].internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
 323
 324		adev->vcn.inst[j].internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
 325		adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(VCN, j, mmUVD_SCRATCH9);
 326		adev->vcn.inst[j].internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
 327		adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA0);
 328		adev->vcn.inst[j].internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
 329		adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA1);
 330		adev->vcn.inst[j].internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
 331		adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_CMD);
 332		adev->vcn.inst[j].internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
 333		adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(VCN, j, mmUVD_NO_OP);
 334
 335		ring = &adev->vcn.inst[j].ring_dec;
 336		ring->use_doorbell = true;
 337
 338		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
 339				(amdgpu_sriov_vf(adev) ? 2*j : 8*j);
 340
 341		if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(2, 5, 0))
 342			ring->vm_hub = AMDGPU_MMHUB1(0);
 343		else
 344			ring->vm_hub = AMDGPU_MMHUB0(0);
 345
 346		sprintf(ring->name, "vcn_dec_%d", j);
 347		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq,
 348				     0, AMDGPU_RING_PRIO_DEFAULT, NULL);
 349		if (r)
 350			return r;
 351
 352		for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
 353			enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i);
 354
 355			ring = &adev->vcn.inst[j].ring_enc[i];
 356			ring->use_doorbell = true;
 357
 358			ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
 359					(amdgpu_sriov_vf(adev) ? (1 + i + 2*j) : (2 + i + 8*j));
 360
 361			if (amdgpu_ip_version(adev, UVD_HWIP, 0) ==
 362			    IP_VERSION(2, 5, 0))
 363				ring->vm_hub = AMDGPU_MMHUB1(0);
 364			else
 365				ring->vm_hub = AMDGPU_MMHUB0(0);
 366
 367			sprintf(ring->name, "vcn_enc_%d.%d", j, i);
 368			r = amdgpu_ring_init(adev, ring, 512,
 369					     &adev->vcn.inst[j].irq, 0,
 370					     hw_prio, NULL);
 371			if (r)
 372				return r;
 373		}
 374
 375		fw_shared = adev->vcn.inst[j].fw_shared.cpu_addr;
 376		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
 377
 378		if (amdgpu_vcnfw_log)
 379			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
 380
 381		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
 382			adev->vcn.inst[j].pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
 383		adev->vcn.inst[j].reset = vcn_v2_5_reset;
 384	}
 385
 386	adev->vcn.supported_reset =
 387		amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
 388	if (!amdgpu_sriov_vf(adev))
 389		adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
 390
 391	if (amdgpu_sriov_vf(adev)) {
 392		r = amdgpu_virt_alloc_mm_table(adev);
 393		if (r)
 394			return r;
 395	}
 396
 397	r = amdgpu_vcn_ras_sw_init(adev);
 398	if (r)
 399		return r;
 400
 401	r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_2_5, ARRAY_SIZE(vcn_reg_list_2_5));
 402	if (r)
 403		return r;
 404
 405	r = amdgpu_vcn_sysfs_reset_mask_init(adev);
 406	if (r)
 407		return r;
 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 */
 419static 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	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	amdgpu_vcn_sysfs_reset_mask_fini(adev);
 440
 441	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 442		r = amdgpu_vcn_suspend(adev, i);
 443		if (r)
 444			return r;
 445		amdgpu_vcn_sw_fini(adev, i);
 446	}
 447
 448	return 0;
 449}
 450
 451/**
 452 * vcn_v2_5_hw_init - start and test VCN block
 453 *
 454 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 455 *
 456 * Initialize the hardware, boot up the VCPU and do some testing
 457 */
 458static int vcn_v2_5_hw_init(struct amdgpu_ip_block *ip_block)
 459{
 460	struct amdgpu_device *adev = ip_block->adev;
 461	struct amdgpu_ring *ring;
 462	int i, j, r = 0;
 463
 464	if (amdgpu_sriov_vf(adev))
 465		r = vcn_v2_5_sriov_start(adev);
 466
 467	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
 468		if (adev->vcn.harvest_config & (1 << j))
 469			continue;
 470
 471		if (amdgpu_sriov_vf(adev)) {
 472			adev->vcn.inst[j].ring_enc[0].sched.ready = true;
 473			adev->vcn.inst[j].ring_enc[1].sched.ready = false;
 474			adev->vcn.inst[j].ring_enc[2].sched.ready = false;
 475			adev->vcn.inst[j].ring_dec.sched.ready = true;
 476		} else {
 477
 478			ring = &adev->vcn.inst[j].ring_dec;
 479
 480			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 481						     ring->doorbell_index, j);
 482
 483			r = amdgpu_ring_test_helper(ring);
 484			if (r)
 485				return r;
 486
 487			for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
 488				ring = &adev->vcn.inst[j].ring_enc[i];
 489				r = amdgpu_ring_test_helper(ring);
 490				if (r)
 491					return r;
 492			}
 493		}
 494	}
 495
 496	return r;
 497}
 498
 499/**
 500 * vcn_v2_5_hw_fini - stop the hardware block
 501 *
 502 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
 503 *
 504 * Stop the VCN block, mark ring as not ready any more
 505 */
 506static int vcn_v2_5_hw_fini(struct amdgpu_ip_block *ip_block)
 507{
 508	struct amdgpu_device *adev = ip_block->adev;
 509	int i;
 510
 511	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 512		struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
 513
 514		if (adev->vcn.harvest_config & (1 << i))
 515			continue;
 516
 517		cancel_delayed_work_sync(&vinst->idle_work);
 518
 519		if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
 520		    (vinst->cur_state != AMD_PG_STATE_GATE &&
 521		     RREG32_SOC15(VCN, i, mmUVD_STATUS)))
 522			vinst->set_pg_state(vinst, AMD_PG_STATE_GATE);
 523
 524		/* VF doesn't enable interrupt operations for RAS */
 525		if (!amdgpu_sriov_vf(adev) &&
 526		    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 */
 540static 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 */
 565static 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 */
 588static 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
 644static 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 */
 750static 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
 859static 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 */
 916static 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
 970static 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
 999static 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	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	int ret;
1007
1008	/* disable register anti-hang mechanism */
1009	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1,
1010		~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1011	/* enable dynamic power gating mode */
1012	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS);
1013	tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
1014	tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
1015	WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp);
1016
1017	if (indirect)
1018		adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
1019
1020	/* enable clock gating */
1021	vcn_v2_5_clock_gating_dpg_mode(vinst, 0, indirect);
1022
1023	/* enable VCPU clock */
1024	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
1025	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
1026	tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
1027	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1028		VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1029
1030	/* disable master interupt */
1031	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1032		VCN, 0, mmUVD_MASTINT_EN), 0, 0, indirect);
1033
1034	/* setup mmUVD_LMI_CTRL */
1035	tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1036		UVD_LMI_CTRL__REQ_MODE_MASK |
1037		UVD_LMI_CTRL__CRC_RESET_MASK |
1038		UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1039		UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1040		UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
1041		(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
1042		0x00100000L);
1043	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1044		VCN, 0, mmUVD_LMI_CTRL), tmp, 0, indirect);
1045
1046	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1047		VCN, 0, mmUVD_MPC_CNTL),
1048		0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
1049
1050	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1051		VCN, 0, mmUVD_MPC_SET_MUXA0),
1052		((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1053		 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1054		 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1055		 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
1056
1057	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1058		VCN, 0, mmUVD_MPC_SET_MUXB0),
1059		((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1060		 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1061		 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1062		 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
1063
1064	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1065		VCN, 0, mmUVD_MPC_SET_MUX),
1066		((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1067		 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1068		 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
1069
1070	vcn_v2_5_mc_resume_dpg_mode(vinst, indirect);
1071
1072	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1073		VCN, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
1074	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1075		VCN, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
1076
1077	/* enable LMI MC and UMC channels */
1078	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1079		VCN, 0, mmUVD_LMI_CTRL2), 0, 0, indirect);
1080
1081	vcn_v2_6_enable_ras(vinst, indirect);
1082
1083	/* unblock VCPU register access */
1084	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1085		VCN, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
1086
1087	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
1088	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
1089	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1090		VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
1091
1092	/* enable master interrupt */
1093	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
1094		VCN, 0, mmUVD_MASTINT_EN),
1095		UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
1096
1097	if (indirect) {
1098		ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0);
1099		if (ret) {
1100			dev_err(adev->dev, "vcn sram load failed %d\n", ret);
1101			return ret;
1102		}
1103	}
1104
1105	ring = &adev->vcn.inst[inst_idx].ring_dec;
1106	/* force RBC into idle state */
1107	rb_bufsz = order_base_2(ring->ring_size);
1108	tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1109	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1110	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1111	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1112	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1113	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
1114
1115	/* Stall DPG before WPTR/RPTR reset */
1116	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1117		UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1118		~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1119	fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
1120
1121	/* set the write pointer delay */
1122	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
1123
1124	/* set the wb address */
1125	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
1126		(upper_32_bits(ring->gpu_addr) >> 2));
1127
1128	/* program the RB_BASE for ring buffer */
1129	WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1130		lower_32_bits(ring->gpu_addr));
1131	WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1132		upper_32_bits(ring->gpu_addr));
1133
1134	/* Initialize the ring buffer's read and write pointers */
1135	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0);
1136
1137	WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0);
1138
1139	ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR);
1140	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
1141		lower_32_bits(ring->wptr));
1142
1143	fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
1144	/* Unstall DPG */
1145	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1146		0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1147
1148	/* Keeping one read-back to ensure all register writes are done,
1149	 * otherwise it may introduce race conditions.
1150	 */
1151	RREG32_SOC15(VCN, inst_idx, mmUVD_STATUS);
1152
1153	return 0;
1154}
1155
1156static int vcn_v2_5_start(struct amdgpu_vcn_inst *vinst)
1157{
1158	struct amdgpu_device *adev = vinst->adev;
1159	int i = vinst->inst;
1160	struct amdgpu_fw_shared *fw_shared =
1161		adev->vcn.inst[i].fw_shared.cpu_addr;
1162	struct amdgpu_ring *ring;
1163	uint32_t rb_bufsz, tmp;
1164	int j, k, r;
1165
1166	if (adev->vcn.harvest_config & (1 << i))
1167		return 0;
1168
1169	if (adev->pm.dpm_enabled)
1170		amdgpu_dpm_enable_vcn(adev, true, i);
1171
1172	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
1173		return vcn_v2_5_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram);
1174
1175	/* disable register anti-hang mechanism */
1176	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS), 0,
1177		 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1178
1179	/* set uvd status busy */
1180	tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
1181	WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp);
1182
1183	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
1184		return 0;
1185
1186	/* SW clock gating */
1187	vcn_v2_5_disable_clock_gating(vinst);
1188
1189	/* enable VCPU clock */
1190	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1191		 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
1192
1193	/* disable master interrupt */
1194	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0,
1195		 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1196
1197	/* setup mmUVD_LMI_CTRL */
1198	tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL);
1199	tmp &= ~0xff;
1200	WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp | 0x8|
1201		     UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK	|
1202		     UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1203		     UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1204		     UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1205
1206	/* setup mmUVD_MPC_CNTL */
1207	tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL);
1208	tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
1209	tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
1210	WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
1211
1212	/* setup UVD_MPC_SET_MUXA0 */
1213	WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0,
1214		     ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1215		      (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1216		      (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1217		      (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
1218
1219	/* setup UVD_MPC_SET_MUXB0 */
1220	WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0,
1221		     ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1222		      (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1223		      (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1224		      (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
1225
1226	/* setup mmUVD_MPC_SET_MUX */
1227	WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX,
1228		     ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1229		      (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1230		      (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
1231
1232	vcn_v2_5_mc_resume(vinst);
1233
1234	/* VCN global tiling registers */
1235	WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
1236		     adev->gfx.config.gb_addr_config);
1237	WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
1238		     adev->gfx.config.gb_addr_config);
1239
1240	/* enable LMI MC and UMC channels */
1241	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0,
1242		 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1243
1244	/* unblock VCPU register access */
1245	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0,
1246		 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1247
1248	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1249		 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1250
1251	for (k = 0; k < 10; ++k) {
1252		uint32_t status;
1253
1254		for (j = 0; j < 100; ++j) {
1255			status = RREG32_SOC15(VCN, i, mmUVD_STATUS);
1256			if (status & 2)
1257				break;
1258			if (amdgpu_emu_mode == 1)
1259				msleep(500);
1260			else
1261				mdelay(10);
1262		}
1263		r = 0;
1264		if (status & 2)
1265			break;
1266
1267		DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
1268		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1269			 UVD_VCPU_CNTL__BLK_RST_MASK,
1270			 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1271		mdelay(10);
1272		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1273			 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1274
1275		mdelay(10);
1276		r = -1;
1277	}
1278
1279	if (r) {
1280		DRM_ERROR("VCN decode not responding, giving up!!!\n");
1281		return r;
1282	}
1283
1284	/* enable master interrupt */
1285	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN),
1286		 UVD_MASTINT_EN__VCPU_EN_MASK,
1287		 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1288
1289	/* clear the busy bit of VCN_STATUS */
1290	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0,
1291		 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1292
1293	WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0);
1294
1295	ring = &adev->vcn.inst[i].ring_dec;
1296	/* force RBC into idle state */
1297	rb_bufsz = order_base_2(ring->ring_size);
1298	tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1299	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1300	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1301	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1302	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1303	WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
1304
1305	fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
1306	/* program the RB_BASE for ring buffer */
1307	WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1308		     lower_32_bits(ring->gpu_addr));
1309	WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1310		     upper_32_bits(ring->gpu_addr));
1311
1312	/* Initialize the ring buffer's read and write pointers */
1313	WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
1314
1315	ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
1316	WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
1317		     lower_32_bits(ring->wptr));
1318	fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
1319
1320	fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
1321	ring = &adev->vcn.inst[i].ring_enc[0];
1322	WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1323	WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1324	WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
1325	WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1326	WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4);
1327	fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
1328
1329	fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
1330	ring = &adev->vcn.inst[i].ring_enc[1];
1331	WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1332	WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1333	WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1334	WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1335	WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
1336	fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
1337
1338	/* Keeping one read-back to ensure all register writes are done,
1339	 * otherwise it may introduce race conditions.
1340	 */
1341	RREG32_SOC15(VCN, i, mmUVD_STATUS);
1342
1343	return 0;
1344}
1345
1346static int vcn_v2_5_mmsch_start(struct amdgpu_device *adev,
1347				struct amdgpu_mm_table *table)
1348{
1349	uint32_t data = 0, loop = 0, size = 0;
1350	uint64_t addr = table->gpu_addr;
1351	struct mmsch_v1_1_init_header *header = NULL;
1352
1353	header = (struct mmsch_v1_1_init_header *)table->cpu_addr;
1354	size = header->total_size;
1355
1356	/*
1357	 * 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of
1358	 *  memory descriptor location
1359	 */
1360	WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
1361	WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
1362
1363	/* 2, update vmid of descriptor */
1364	data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID);
1365	data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
1366	/* use domain0 for MM scheduler */
1367	data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
1368	WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, data);
1369
1370	/* 3, notify mmsch about the size of this descriptor */
1371	WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size);
1372
1373	/* 4, set resp to zero */
1374	WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
1375
1376	/*
1377	 * 5, kick off the initialization and wait until
1378	 * VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero
1379	 */
1380	WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, 0x10000001);
1381
1382	data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1383	loop = 10;
1384	while ((data & 0x10000002) != 0x10000002) {
1385		udelay(100);
1386		data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1387		loop--;
1388		if (!loop)
1389			break;
1390	}
1391
1392	if (!loop) {
1393		dev_err(adev->dev,
1394			"failed to init MMSCH, mmMMSCH_VF_MAILBOX_RESP = %x\n",
1395			data);
1396		return -EBUSY;
1397	}
1398
1399	return 0;
1400}
1401
1402static int vcn_v2_5_sriov_start(struct amdgpu_device *adev)
1403{
1404	struct amdgpu_ring *ring;
1405	uint32_t offset, size, tmp, i, rb_bufsz;
1406	uint32_t table_size = 0;
1407	struct mmsch_v1_0_cmd_direct_write direct_wt = { { 0 } };
1408	struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt = { { 0 } };
1409	struct mmsch_v1_0_cmd_end end = { { 0 } };
1410	uint32_t *init_table = adev->virt.mm_table.cpu_addr;
1411	struct mmsch_v1_1_init_header *header = (struct mmsch_v1_1_init_header *)init_table;
1412
1413	direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE;
1414	direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
1415	end.cmd_header.command_type = MMSCH_COMMAND__END;
1416
1417	header->version = MMSCH_VERSION;
1418	header->total_size = sizeof(struct mmsch_v1_1_init_header) >> 2;
1419	init_table += header->total_size;
1420
1421	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1422		header->eng[i].table_offset = header->total_size;
1423		header->eng[i].init_status = 0;
1424		header->eng[i].table_size = 0;
1425
1426		table_size = 0;
1427
1428		MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(
1429			SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS),
1430			~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
1431
1432		size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4);
1433		/* mc resume*/
1434		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1435			MMSCH_V1_0_INSERT_DIRECT_WT(
1436				SOC15_REG_OFFSET(VCN, i,
1437					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1438				adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
1439			MMSCH_V1_0_INSERT_DIRECT_WT(
1440				SOC15_REG_OFFSET(VCN, i,
1441					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1442				adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
1443			offset = 0;
1444			MMSCH_V1_0_INSERT_DIRECT_WT(
1445				SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), 0);
1446		} else {
1447			MMSCH_V1_0_INSERT_DIRECT_WT(
1448				SOC15_REG_OFFSET(VCN, i,
1449					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1450				lower_32_bits(adev->vcn.inst[i].gpu_addr));
1451			MMSCH_V1_0_INSERT_DIRECT_WT(
1452				SOC15_REG_OFFSET(VCN, i,
1453					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1454				upper_32_bits(adev->vcn.inst[i].gpu_addr));
1455			offset = size;
1456			MMSCH_V1_0_INSERT_DIRECT_WT(
1457				SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0),
1458				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
1459		}
1460
1461		MMSCH_V1_0_INSERT_DIRECT_WT(
1462			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE0),
1463			size);
1464		MMSCH_V1_0_INSERT_DIRECT_WT(
1465			SOC15_REG_OFFSET(VCN, i,
1466				mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
1467			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
1468		MMSCH_V1_0_INSERT_DIRECT_WT(
1469			SOC15_REG_OFFSET(VCN, i,
1470				mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
1471			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
1472		MMSCH_V1_0_INSERT_DIRECT_WT(
1473			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET1),
1474			0);
1475		MMSCH_V1_0_INSERT_DIRECT_WT(
1476			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE1),
1477			AMDGPU_VCN_STACK_SIZE);
1478		MMSCH_V1_0_INSERT_DIRECT_WT(
1479			SOC15_REG_OFFSET(VCN, i,
1480				mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
1481			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset +
1482				AMDGPU_VCN_STACK_SIZE));
1483		MMSCH_V1_0_INSERT_DIRECT_WT(
1484			SOC15_REG_OFFSET(VCN, i,
1485				mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
1486			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset +
1487				AMDGPU_VCN_STACK_SIZE));
1488		MMSCH_V1_0_INSERT_DIRECT_WT(
1489			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET2),
1490			0);
1491		MMSCH_V1_0_INSERT_DIRECT_WT(
1492			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE2),
1493			AMDGPU_VCN_CONTEXT_SIZE);
1494
1495		ring = &adev->vcn.inst[i].ring_enc[0];
1496		ring->wptr = 0;
1497
1498		MMSCH_V1_0_INSERT_DIRECT_WT(
1499			SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_LO),
1500			lower_32_bits(ring->gpu_addr));
1501		MMSCH_V1_0_INSERT_DIRECT_WT(
1502			SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_HI),
1503			upper_32_bits(ring->gpu_addr));
1504		MMSCH_V1_0_INSERT_DIRECT_WT(
1505			SOC15_REG_OFFSET(VCN, i, mmUVD_RB_SIZE),
1506			ring->ring_size / 4);
1507
1508		ring = &adev->vcn.inst[i].ring_dec;
1509		ring->wptr = 0;
1510		MMSCH_V1_0_INSERT_DIRECT_WT(
1511			SOC15_REG_OFFSET(VCN, i,
1512				mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
1513			lower_32_bits(ring->gpu_addr));
1514		MMSCH_V1_0_INSERT_DIRECT_WT(
1515			SOC15_REG_OFFSET(VCN, i,
1516				mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
1517			upper_32_bits(ring->gpu_addr));
1518
1519		/* force RBC into idle state */
1520		rb_bufsz = order_base_2(ring->ring_size);
1521		tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1522		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1523		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1524		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1525		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1526		MMSCH_V1_0_INSERT_DIRECT_WT(
1527			SOC15_REG_OFFSET(VCN, i, mmUVD_RBC_RB_CNTL), tmp);
1528
1529		/* add end packet */
1530		memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
1531		table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
1532		init_table += sizeof(struct mmsch_v1_0_cmd_end) / 4;
1533
1534		/* refine header */
1535		header->eng[i].table_size = table_size;
1536		header->total_size += table_size;
1537	}
1538
1539	return vcn_v2_5_mmsch_start(adev, &adev->virt.mm_table);
1540}
1541
1542static int vcn_v2_5_stop_dpg_mode(struct amdgpu_vcn_inst *vinst)
1543{
1544	struct amdgpu_device *adev = vinst->adev;
1545	int inst_idx = vinst->inst;
1546	uint32_t tmp;
1547
1548	/* Wait for power status to be 1 */
1549	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1550		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1551
1552	/* wait for read ptr to be equal to write ptr */
1553	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR);
1554	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1555
1556	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2);
1557	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
1558
1559	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
1560	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
1561
1562	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1563		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1564
1565	/* disable dynamic power gating mode */
1566	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0,
1567			~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1568
1569	/* Keeping one read-back to ensure all register writes are done,
1570	 * otherwise it may introduce race conditions.
1571	 */
1572	RREG32_SOC15(VCN, inst_idx, mmUVD_STATUS);
1573
1574	return 0;
1575}
1576
1577static int vcn_v2_5_stop(struct amdgpu_vcn_inst *vinst)
1578{
1579	struct amdgpu_device *adev = vinst->adev;
1580	int i = vinst->inst;
1581	uint32_t tmp;
1582	int r;
1583
1584	if (adev->vcn.harvest_config & (1 << i))
1585		return 0;
1586
1587	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1588		r = vcn_v2_5_stop_dpg_mode(vinst);
1589		goto done;
1590	}
1591
1592	/* wait for vcn idle */
1593	r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1594	if (r)
1595		goto done;
1596
1597	tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1598		UVD_LMI_STATUS__READ_CLEAN_MASK |
1599		UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1600		UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1601	r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1602	if (r)
1603		goto done;
1604
1605	/* block LMI UMC channel */
1606	tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
1607	tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1608	WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
1609
1610	tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
1611		UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1612	r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1613	if (r)
1614		goto done;
1615
1616	/* block VCPU register access */
1617	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL),
1618		 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1619		 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1620
1621	/* reset VCPU */
1622	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1623		 UVD_VCPU_CNTL__BLK_RST_MASK,
1624		 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1625
1626	/* disable VCPU clock */
1627	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1628		 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
1629
1630	/* clear status */
1631	WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
1632
1633	vcn_v2_5_enable_clock_gating(vinst);
1634
1635	/* enable register anti-hang mechanism */
1636	WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS),
1637		 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
1638		 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1639
1640	/* Keeping one read-back to ensure all register writes are done,
1641	 * otherwise it may introduce race conditions.
1642	 */
1643	RREG32_SOC15(VCN, i, mmUVD_STATUS);
1644done:
1645	if (adev->pm.dpm_enabled)
1646		amdgpu_dpm_enable_vcn(adev, false, i);
1647
1648	return r;
1649}
1650
1651static int vcn_v2_5_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
1652				   struct dpg_pause_state *new_state)
1653{
1654	struct amdgpu_device *adev = vinst->adev;
1655	int inst_idx = vinst->inst;
1656	struct amdgpu_ring *ring;
1657	uint32_t reg_data = 0;
1658	int ret_code = 0;
1659
1660	/* pause/unpause if state is changed */
1661	if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
1662		DRM_DEBUG("dpg pause state changed %d -> %d",
1663			adev->vcn.inst[inst_idx].pause_state.fw_based,	new_state->fw_based);
1664		reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) &
1665			(~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1666
1667		if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
1668			ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1669				UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1670
1671			if (!ret_code) {
1672				struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
1673
1674				/* pause DPG */
1675				reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1676				WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1677
1678				/* wait for ACK */
1679				SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE,
1680					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
1681					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1682
1683				/* Stall DPG before WPTR/RPTR reset */
1684				WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1685					   UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1686					   ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1687
1688				/* Restore */
1689				fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
1690				ring = &adev->vcn.inst[inst_idx].ring_enc[0];
1691				ring->wptr = 0;
1692				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
1693				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1694				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
1695				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1696				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1697				fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
1698
1699				fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
1700				ring = &adev->vcn.inst[inst_idx].ring_enc[1];
1701				ring->wptr = 0;
1702				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1703				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1704				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
1705				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1706				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1707				fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
1708
1709				/* Unstall DPG */
1710				WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1711					   0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1712
1713				SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS,
1714					   UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1715			}
1716		} else {
1717			reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1718			WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1719			SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1720				UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1721		}
1722		adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
1723	}
1724
1725	return 0;
1726}
1727
1728/**
1729 * vcn_v2_5_dec_ring_get_rptr - get read pointer
1730 *
1731 * @ring: amdgpu_ring pointer
1732 *
1733 * Returns the current hardware read pointer
1734 */
1735static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
1736{
1737	struct amdgpu_device *adev = ring->adev;
1738
1739	return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR);
1740}
1741
1742/**
1743 * vcn_v2_5_dec_ring_get_wptr - get write pointer
1744 *
1745 * @ring: amdgpu_ring pointer
1746 *
1747 * Returns the current hardware write pointer
1748 */
1749static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
1750{
1751	struct amdgpu_device *adev = ring->adev;
1752
1753	if (ring->use_doorbell)
1754		return *ring->wptr_cpu_addr;
1755	else
1756		return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR);
1757}
1758
1759/**
1760 * vcn_v2_5_dec_ring_set_wptr - set write pointer
1761 *
1762 * @ring: amdgpu_ring pointer
1763 *
1764 * Commits the write pointer to the hardware
1765 */
1766static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
1767{
1768	struct amdgpu_device *adev = ring->adev;
1769
1770	if (ring->use_doorbell) {
1771		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1772		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1773	} else {
1774		WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
1775	}
1776}
1777
1778static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
1779	.type = AMDGPU_RING_TYPE_VCN_DEC,
1780	.align_mask = 0xf,
1781	.secure_submission_supported = true,
1782	.get_rptr = vcn_v2_5_dec_ring_get_rptr,
1783	.get_wptr = vcn_v2_5_dec_ring_get_wptr,
1784	.set_wptr = vcn_v2_5_dec_ring_set_wptr,
1785	.emit_frame_size =
1786		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1787		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1788		8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
1789		14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
1790		6,
1791	.emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
1792	.emit_ib = vcn_v2_0_dec_ring_emit_ib,
1793	.emit_fence = vcn_v2_0_dec_ring_emit_fence,
1794	.emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1795	.test_ring = vcn_v2_0_dec_ring_test_ring,
1796	.test_ib = amdgpu_vcn_dec_ring_test_ib,
1797	.insert_nop = vcn_v2_0_dec_ring_insert_nop,
1798	.insert_start = vcn_v2_0_dec_ring_insert_start,
1799	.insert_end = vcn_v2_0_dec_ring_insert_end,
1800	.pad_ib = amdgpu_ring_generic_pad_ib,
1801	.begin_use = vcn_v2_5_ring_begin_use,
1802	.end_use = vcn_v2_5_ring_end_use,
1803	.emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1804	.emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1805	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1806	.reset = amdgpu_vcn_ring_reset,
1807};
1808
1809/**
1810 * vcn_v2_5_enc_ring_get_rptr - get enc read pointer
1811 *
1812 * @ring: amdgpu_ring pointer
1813 *
1814 * Returns the current hardware enc read pointer
1815 */
1816static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
1817{
1818	struct amdgpu_device *adev = ring->adev;
1819
1820	if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1821		return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR);
1822	else
1823		return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2);
1824}
1825
1826/**
1827 * vcn_v2_5_enc_ring_get_wptr - get enc write pointer
1828 *
1829 * @ring: amdgpu_ring pointer
1830 *
1831 * Returns the current hardware enc write pointer
1832 */
1833static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
1834{
1835	struct amdgpu_device *adev = ring->adev;
1836
1837	if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1838		if (ring->use_doorbell)
1839			return *ring->wptr_cpu_addr;
1840		else
1841			return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR);
1842	} else {
1843		if (ring->use_doorbell)
1844			return *ring->wptr_cpu_addr;
1845		else
1846			return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2);
1847	}
1848}
1849
1850/**
1851 * vcn_v2_5_enc_ring_set_wptr - set enc write pointer
1852 *
1853 * @ring: amdgpu_ring pointer
1854 *
1855 * Commits the enc write pointer to the hardware
1856 */
1857static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
1858{
1859	struct amdgpu_device *adev = ring->adev;
1860
1861	if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1862		if (ring->use_doorbell) {
1863			*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1864			WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1865		} else {
1866			WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1867		}
1868	} else {
1869		if (ring->use_doorbell) {
1870			*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1871			WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1872		} else {
1873			WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1874		}
1875	}
1876}
1877
1878static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
1879	.type = AMDGPU_RING_TYPE_VCN_ENC,
1880	.align_mask = 0x3f,
1881	.nop = VCN_ENC_CMD_NO_OP,
1882	.get_rptr = vcn_v2_5_enc_ring_get_rptr,
1883	.get_wptr = vcn_v2_5_enc_ring_get_wptr,
1884	.set_wptr = vcn_v2_5_enc_ring_set_wptr,
1885	.emit_frame_size =
1886		SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1887		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1888		4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1889		5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1890		1, /* vcn_v2_0_enc_ring_insert_end */
1891	.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1892	.emit_ib = vcn_v2_0_enc_ring_emit_ib,
1893	.emit_fence = vcn_v2_0_enc_ring_emit_fence,
1894	.emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1895	.test_ring = amdgpu_vcn_enc_ring_test_ring,
1896	.test_ib = amdgpu_vcn_enc_ring_test_ib,
1897	.insert_nop = amdgpu_ring_insert_nop,
1898	.insert_end = vcn_v2_0_enc_ring_insert_end,
1899	.pad_ib = amdgpu_ring_generic_pad_ib,
1900	.begin_use = vcn_v2_5_ring_begin_use,
1901	.end_use = vcn_v2_5_ring_end_use,
1902	.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1903	.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1904	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1905	.reset = amdgpu_vcn_ring_reset,
1906};
1907
1908static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
1909{
1910	int i;
1911
1912	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1913		if (adev->vcn.harvest_config & (1 << i))
1914			continue;
1915		adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
1916		adev->vcn.inst[i].ring_dec.me = i;
1917	}
1918}
1919
1920static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
1921{
1922	int i, j;
1923
1924	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
1925		if (adev->vcn.harvest_config & (1 << j))
1926			continue;
1927		for (i = 0; i < adev->vcn.inst[j].num_enc_rings; ++i) {
1928			adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
1929			adev->vcn.inst[j].ring_enc[i].me = j;
1930		}
1931	}
1932}
1933
1934static int vcn_v2_5_reset(struct amdgpu_vcn_inst *vinst)
1935{
1936	int r;
1937
1938	r = vcn_v2_5_stop(vinst);
1939	if (r)
1940		return r;
1941	return vcn_v2_5_start(vinst);
1942}
1943
1944static bool vcn_v2_5_is_idle(struct amdgpu_ip_block *ip_block)
1945{
1946	struct amdgpu_device *adev = ip_block->adev;
1947	int i, ret = 1;
1948
1949	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1950		if (adev->vcn.harvest_config & (1 << i))
1951			continue;
1952
1953		ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1954	}
1955
1956	return ret;
1957}
1958
1959static int vcn_v2_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
1960{
1961	struct amdgpu_device *adev = ip_block->adev;
1962	int i, ret = 0;
1963
1964	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1965		if (adev->vcn.harvest_config & (1 << i))
1966			continue;
1967		ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1968			UVD_STATUS__IDLE);
1969		if (ret)
1970			return ret;
1971	}
1972
1973	return ret;
1974}
1975
1976static int vcn_v2_5_set_clockgating_state(struct amdgpu_ip_block *ip_block,
1977					  enum amd_clockgating_state state)
1978{
1979	struct amdgpu_device *adev = ip_block->adev;
1980	bool enable = (state == AMD_CG_STATE_GATE);
1981	int i;
1982
1983	if (amdgpu_sriov_vf(adev))
1984		return 0;
1985
1986	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1987		struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
1988
1989		if (enable) {
1990			if (!vcn_v2_5_is_idle(ip_block))
1991				return -EBUSY;
1992			vcn_v2_5_enable_clock_gating(vinst);
1993		} else {
1994			vcn_v2_5_disable_clock_gating(vinst);
1995		}
1996	}
1997
1998	return 0;
1999}
2000
2001static int vcn_v2_5_set_pg_state(struct amdgpu_vcn_inst *vinst,
2002				 enum amd_powergating_state state)
2003{
2004	struct amdgpu_device *adev = vinst->adev;
2005	int ret;
2006
2007	if (amdgpu_sriov_vf(adev))
2008		return 0;
2009
2010	if (state == vinst->cur_state)
2011		return 0;
2012
2013	if (state == AMD_PG_STATE_GATE)
2014		ret = vcn_v2_5_stop(vinst);
2015	else
2016		ret = vcn_v2_5_start(vinst);
2017
2018	if (!ret)
2019		vinst->cur_state = state;
2020
2021	return ret;
2022}
2023
2024static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
2025					struct amdgpu_irq_src *source,
2026					unsigned type,
2027					enum amdgpu_interrupt_state state)
2028{
2029	return 0;
2030}
2031
2032static int vcn_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev,
2033					struct amdgpu_irq_src *source,
2034					unsigned int type,
2035					enum amdgpu_interrupt_state state)
2036{
2037	return 0;
2038}
2039
2040static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
2041				      struct amdgpu_irq_src *source,
2042				      struct amdgpu_iv_entry *entry)
2043{
2044	uint32_t ip_instance;
2045
2046	switch (entry->client_id) {
2047	case SOC15_IH_CLIENTID_VCN:
2048		ip_instance = 0;
2049		break;
2050	case SOC15_IH_CLIENTID_VCN1:
2051		ip_instance = 1;
2052		break;
2053	default:
2054		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
2055		return 0;
2056	}
2057
2058	DRM_DEBUG("IH: VCN TRAP\n");
2059
2060	switch (entry->src_id) {
2061	case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
2062		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
2063		break;
2064	case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
2065		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
2066		break;
2067	case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
2068		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
2069		break;
2070	default:
2071		DRM_ERROR("Unhandled interrupt: %d %d\n",
2072			  entry->src_id, entry->src_data[0]);
2073		break;
2074	}
2075
2076	return 0;
2077}
2078
2079static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
2080	.set = vcn_v2_5_set_interrupt_state,
2081	.process = vcn_v2_5_process_interrupt,
2082};
2083
2084static const struct amdgpu_irq_src_funcs vcn_v2_6_ras_irq_funcs = {
2085	.set = vcn_v2_6_set_ras_interrupt_state,
2086	.process = amdgpu_vcn_process_poison_irq,
2087};
2088
2089static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
2090{
2091	int i;
2092
2093	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
2094		if (adev->vcn.harvest_config & (1 << i))
2095			continue;
2096		adev->vcn.inst[i].irq.num_types = adev->vcn.inst[i].num_enc_rings + 1;
2097		adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
2098
2099		adev->vcn.inst[i].ras_poison_irq.num_types = adev->vcn.inst[i].num_enc_rings + 1;
2100		adev->vcn.inst[i].ras_poison_irq.funcs = &vcn_v2_6_ras_irq_funcs;
2101	}
2102}
2103
2104static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
2105	.name = "vcn_v2_5",
2106	.early_init = vcn_v2_5_early_init,
2107	.sw_init = vcn_v2_5_sw_init,
2108	.sw_fini = vcn_v2_5_sw_fini,
2109	.hw_init = vcn_v2_5_hw_init,
2110	.hw_fini = vcn_v2_5_hw_fini,
2111	.suspend = vcn_v2_5_suspend,
2112	.resume = vcn_v2_5_resume,
2113	.is_idle = vcn_v2_5_is_idle,
2114	.wait_for_idle = vcn_v2_5_wait_for_idle,
2115	.set_clockgating_state = vcn_v2_5_set_clockgating_state,
2116	.set_powergating_state = vcn_set_powergating_state,
2117	.dump_ip_state = amdgpu_vcn_dump_ip_state,
2118	.print_ip_state = amdgpu_vcn_print_ip_state,
2119};
2120
2121static const struct amd_ip_funcs vcn_v2_6_ip_funcs = {
2122        .name = "vcn_v2_6",
2123        .early_init = vcn_v2_5_early_init,
2124        .sw_init = vcn_v2_5_sw_init,
2125        .sw_fini = vcn_v2_5_sw_fini,
2126        .hw_init = vcn_v2_5_hw_init,
2127        .hw_fini = vcn_v2_5_hw_fini,
2128        .suspend = vcn_v2_5_suspend,
2129        .resume = vcn_v2_5_resume,
2130        .is_idle = vcn_v2_5_is_idle,
2131        .wait_for_idle = vcn_v2_5_wait_for_idle,
2132        .set_clockgating_state = vcn_v2_5_set_clockgating_state,
2133	.set_powergating_state = vcn_set_powergating_state,
2134	.dump_ip_state = amdgpu_vcn_dump_ip_state,
2135	.print_ip_state = amdgpu_vcn_print_ip_state,
2136};
2137
2138const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
2139{
2140		.type = AMD_IP_BLOCK_TYPE_VCN,
2141		.major = 2,
2142		.minor = 5,
2143		.rev = 0,
2144		.funcs = &vcn_v2_5_ip_funcs,
2145};
2146
2147const struct amdgpu_ip_block_version vcn_v2_6_ip_block =
2148{
2149		.type = AMD_IP_BLOCK_TYPE_VCN,
2150		.major = 2,
2151		.minor = 6,
2152		.rev = 0,
2153		.funcs = &vcn_v2_6_ip_funcs,
2154};
2155
2156static uint32_t vcn_v2_6_query_poison_by_instance(struct amdgpu_device *adev,
2157			uint32_t instance, uint32_t sub_block)
2158{
2159	uint32_t poison_stat = 0, reg_value = 0;
2160
2161	switch (sub_block) {
2162	case AMDGPU_VCN_V2_6_VCPU_VCODEC:
2163		reg_value = RREG32_SOC15(VCN, instance, mmUVD_RAS_VCPU_VCODEC_STATUS);
2164		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF);
2165		break;
2166	default:
2167		break;
2168	}
2169
2170	if (poison_stat)
2171		dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n",
2172			instance, sub_block);
2173
2174	return poison_stat;
2175}
2176
2177static bool vcn_v2_6_query_poison_status(struct amdgpu_device *adev)
2178{
2179	uint32_t inst, sub;
2180	uint32_t poison_stat = 0;
2181
2182	for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++)
2183		for (sub = 0; sub < AMDGPU_VCN_V2_6_MAX_SUB_BLOCK; sub++)
2184			poison_stat +=
2185			vcn_v2_6_query_poison_by_instance(adev, inst, sub);
2186
2187	return !!poison_stat;
2188}
2189
2190const struct amdgpu_ras_block_hw_ops vcn_v2_6_ras_hw_ops = {
2191	.query_poison_status = vcn_v2_6_query_poison_status,
2192};
2193
2194static struct amdgpu_vcn_ras vcn_v2_6_ras = {
2195	.ras_block = {
2196		.hw_ops = &vcn_v2_6_ras_hw_ops,
2197		.ras_late_init = amdgpu_vcn_ras_late_init,
2198	},
2199};
2200
2201static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev)
2202{
2203	switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) {
2204	case IP_VERSION(2, 6, 0):
2205		adev->vcn.ras = &vcn_v2_6_ras;
2206		break;
2207	default:
2208		break;
2209	}
2210}
~/ Read-only file preview.