xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/soc21.c (revision ea64228d)
171199aa4SStanley.Yang /*
271199aa4SStanley.Yang  * Copyright 2021 Advanced Micro Devices, Inc.
371199aa4SStanley.Yang  *
471199aa4SStanley.Yang  * Permission is hereby granted, free of charge, to any person obtaining a
571199aa4SStanley.Yang  * copy of this software and associated documentation files (the "Software"),
671199aa4SStanley.Yang  * to deal in the Software without restriction, including without limitation
771199aa4SStanley.Yang  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
871199aa4SStanley.Yang  * and/or sell copies of the Software, and to permit persons to whom the
971199aa4SStanley.Yang  * Software is furnished to do so, subject to the following conditions:
1071199aa4SStanley.Yang  *
1171199aa4SStanley.Yang  * The above copyright notice and this permission notice shall be included in
1271199aa4SStanley.Yang  * all copies or substantial portions of the Software.
1371199aa4SStanley.Yang  *
1471199aa4SStanley.Yang  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1571199aa4SStanley.Yang  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1671199aa4SStanley.Yang  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1771199aa4SStanley.Yang  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1871199aa4SStanley.Yang  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1971199aa4SStanley.Yang  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2071199aa4SStanley.Yang  * OTHER DEALINGS IN THE SOFTWARE.
2171199aa4SStanley.Yang  *
2271199aa4SStanley.Yang  */
2371199aa4SStanley.Yang #include <linux/firmware.h>
2471199aa4SStanley.Yang #include <linux/slab.h>
2571199aa4SStanley.Yang #include <linux/module.h>
2671199aa4SStanley.Yang #include <linux/pci.h>
2771199aa4SStanley.Yang 
2871199aa4SStanley.Yang #include "amdgpu.h"
2971199aa4SStanley.Yang #include "amdgpu_atombios.h"
3071199aa4SStanley.Yang #include "amdgpu_ih.h"
3171199aa4SStanley.Yang #include "amdgpu_uvd.h"
3271199aa4SStanley.Yang #include "amdgpu_vce.h"
3371199aa4SStanley.Yang #include "amdgpu_ucode.h"
3471199aa4SStanley.Yang #include "amdgpu_psp.h"
3571199aa4SStanley.Yang #include "amdgpu_smu.h"
3671199aa4SStanley.Yang #include "atom.h"
3771199aa4SStanley.Yang #include "amd_pcie.h"
3871199aa4SStanley.Yang 
3971199aa4SStanley.Yang #include "gc/gc_11_0_0_offset.h"
4071199aa4SStanley.Yang #include "gc/gc_11_0_0_sh_mask.h"
4171199aa4SStanley.Yang #include "mp/mp_13_0_0_offset.h"
4271199aa4SStanley.Yang 
4371199aa4SStanley.Yang #include "soc15.h"
4471199aa4SStanley.Yang #include "soc15_common.h"
45caa5eadcSEvan Quan #include "soc21.h"
4671199aa4SStanley.Yang 
4771199aa4SStanley.Yang static const struct amd_ip_funcs soc21_common_ip_funcs;
4871199aa4SStanley.Yang 
499ac0edaaSJames Zhu /* SOC21 */
509ac0edaaSJames Zhu static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array[] =
519ac0edaaSJames Zhu {
529ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
539ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
549ac0edaaSJames Zhu };
559ac0edaaSJames Zhu 
569ac0edaaSJames Zhu static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode =
579ac0edaaSJames Zhu {
589ac0edaaSJames Zhu 	.codec_count = ARRAY_SIZE(vcn_4_0_0_video_codecs_encode_array),
599ac0edaaSJames Zhu 	.codec_array = vcn_4_0_0_video_codecs_encode_array,
609ac0edaaSJames Zhu };
619ac0edaaSJames Zhu 
629ac0edaaSJames Zhu static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] =
639ac0edaaSJames Zhu {
649ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
659ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
669ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
679ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
689ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
699ac0edaaSJames Zhu };
709ac0edaaSJames Zhu 
719ac0edaaSJames Zhu static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_decode =
729ac0edaaSJames Zhu {
739ac0edaaSJames Zhu 	.codec_count = ARRAY_SIZE(vcn_4_0_0_video_codecs_decode_array),
749ac0edaaSJames Zhu 	.codec_array = vcn_4_0_0_video_codecs_decode_array,
759ac0edaaSJames Zhu };
769ac0edaaSJames Zhu 
779ac0edaaSJames Zhu static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
789ac0edaaSJames Zhu 				 const struct amdgpu_video_codecs **codecs)
799ac0edaaSJames Zhu {
809ac0edaaSJames Zhu 	switch (adev->ip_versions[UVD_HWIP][0]) {
819ac0edaaSJames Zhu 
829ac0edaaSJames Zhu 	case IP_VERSION(4, 0, 0):
839ac0edaaSJames Zhu 		if (encode)
849ac0edaaSJames Zhu 			*codecs = &vcn_4_0_0_video_codecs_encode;
859ac0edaaSJames Zhu 		else
869ac0edaaSJames Zhu 			*codecs = &vcn_4_0_0_video_codecs_decode;
879ac0edaaSJames Zhu 		return 0;
889ac0edaaSJames Zhu 	default:
899ac0edaaSJames Zhu 		return -EINVAL;
909ac0edaaSJames Zhu 	}
919ac0edaaSJames Zhu }
9271199aa4SStanley.Yang /*
9371199aa4SStanley.Yang  * Indirect registers accessor
9471199aa4SStanley.Yang  */
9571199aa4SStanley.Yang static u32 soc21_pcie_rreg(struct amdgpu_device *adev, u32 reg)
9671199aa4SStanley.Yang {
9771199aa4SStanley.Yang 	unsigned long address, data;
9871199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
9971199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
10071199aa4SStanley.Yang 
10171199aa4SStanley.Yang 	return amdgpu_device_indirect_rreg(adev, address, data, reg);
10271199aa4SStanley.Yang }
10371199aa4SStanley.Yang 
10471199aa4SStanley.Yang static void soc21_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
10571199aa4SStanley.Yang {
10671199aa4SStanley.Yang 	unsigned long address, data;
10771199aa4SStanley.Yang 
10871199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
10971199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
11071199aa4SStanley.Yang 
11171199aa4SStanley.Yang 	amdgpu_device_indirect_wreg(adev, address, data, reg, v);
11271199aa4SStanley.Yang }
11371199aa4SStanley.Yang 
11471199aa4SStanley.Yang static u64 soc21_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
11571199aa4SStanley.Yang {
11671199aa4SStanley.Yang 	unsigned long address, data;
11771199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
11871199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
11971199aa4SStanley.Yang 
12071199aa4SStanley.Yang 	return amdgpu_device_indirect_rreg64(adev, address, data, reg);
12171199aa4SStanley.Yang }
12271199aa4SStanley.Yang 
12371199aa4SStanley.Yang static void soc21_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
12471199aa4SStanley.Yang {
12571199aa4SStanley.Yang 	unsigned long address, data;
12671199aa4SStanley.Yang 
12771199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
12871199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
12971199aa4SStanley.Yang 
13071199aa4SStanley.Yang 	amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
13171199aa4SStanley.Yang }
13271199aa4SStanley.Yang 
13371199aa4SStanley.Yang static u32 soc21_didt_rreg(struct amdgpu_device *adev, u32 reg)
13471199aa4SStanley.Yang {
13571199aa4SStanley.Yang 	unsigned long flags, address, data;
13671199aa4SStanley.Yang 	u32 r;
13771199aa4SStanley.Yang 
13871199aa4SStanley.Yang 	address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
13971199aa4SStanley.Yang 	data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
14071199aa4SStanley.Yang 
14171199aa4SStanley.Yang 	spin_lock_irqsave(&adev->didt_idx_lock, flags);
14271199aa4SStanley.Yang 	WREG32(address, (reg));
14371199aa4SStanley.Yang 	r = RREG32(data);
14471199aa4SStanley.Yang 	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
14571199aa4SStanley.Yang 	return r;
14671199aa4SStanley.Yang }
14771199aa4SStanley.Yang 
14871199aa4SStanley.Yang static void soc21_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
14971199aa4SStanley.Yang {
15071199aa4SStanley.Yang 	unsigned long flags, address, data;
15171199aa4SStanley.Yang 
15271199aa4SStanley.Yang 	address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
15371199aa4SStanley.Yang 	data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
15471199aa4SStanley.Yang 
15571199aa4SStanley.Yang 	spin_lock_irqsave(&adev->didt_idx_lock, flags);
15671199aa4SStanley.Yang 	WREG32(address, (reg));
15771199aa4SStanley.Yang 	WREG32(data, (v));
15871199aa4SStanley.Yang 	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
15971199aa4SStanley.Yang }
16071199aa4SStanley.Yang 
16171199aa4SStanley.Yang static u32 soc21_get_config_memsize(struct amdgpu_device *adev)
16271199aa4SStanley.Yang {
16371199aa4SStanley.Yang 	return adev->nbio.funcs->get_memsize(adev);
16471199aa4SStanley.Yang }
16571199aa4SStanley.Yang 
16671199aa4SStanley.Yang static u32 soc21_get_xclk(struct amdgpu_device *adev)
16771199aa4SStanley.Yang {
16871199aa4SStanley.Yang 	return adev->clock.spll.reference_freq;
16971199aa4SStanley.Yang }
17071199aa4SStanley.Yang 
17171199aa4SStanley.Yang 
17271199aa4SStanley.Yang void soc21_grbm_select(struct amdgpu_device *adev,
17371199aa4SStanley.Yang 		     u32 me, u32 pipe, u32 queue, u32 vmid)
17471199aa4SStanley.Yang {
17571199aa4SStanley.Yang 	u32 grbm_gfx_cntl = 0;
17671199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe);
17771199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me);
17871199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
17971199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
18071199aa4SStanley.Yang 
18171199aa4SStanley.Yang 	WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_CNTL), grbm_gfx_cntl);
18271199aa4SStanley.Yang }
18371199aa4SStanley.Yang 
18471199aa4SStanley.Yang static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
18571199aa4SStanley.Yang {
18671199aa4SStanley.Yang 	/* todo */
18771199aa4SStanley.Yang }
18871199aa4SStanley.Yang 
18971199aa4SStanley.Yang static bool soc21_read_disabled_bios(struct amdgpu_device *adev)
19071199aa4SStanley.Yang {
19171199aa4SStanley.Yang 	/* todo */
19271199aa4SStanley.Yang 	return false;
19371199aa4SStanley.Yang }
19471199aa4SStanley.Yang 
19571199aa4SStanley.Yang static struct soc15_allowed_register_entry soc21_allowed_read_registers[] = {
19671199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS)},
19771199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS2)},
19871199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE0)},
19971199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE1)},
20071199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE2)},
20171199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE3)},
20271199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(SDMA0, 0, regSDMA0_STATUS_REG)},
20371199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(SDMA1, 0, regSDMA1_STATUS_REG)},
20471199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STAT)},
20571199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT1)},
20671199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT2)},
20771199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT3)},
20871199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_BUSY_STAT)},
20971199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_STALLED_STAT1)},
21071199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_STATUS)},
21171199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_BUSY_STAT)},
21271199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_STALLED_STAT1)},
21371199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_STATUS)},
21471199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGB_ADDR_CONFIG)},
21571199aa4SStanley.Yang };
21671199aa4SStanley.Yang 
21771199aa4SStanley.Yang static uint32_t soc21_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
21871199aa4SStanley.Yang 					 u32 sh_num, u32 reg_offset)
21971199aa4SStanley.Yang {
22071199aa4SStanley.Yang 	uint32_t val;
22171199aa4SStanley.Yang 
22271199aa4SStanley.Yang 	mutex_lock(&adev->grbm_idx_mutex);
22371199aa4SStanley.Yang 	if (se_num != 0xffffffff || sh_num != 0xffffffff)
22471199aa4SStanley.Yang 		amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff);
22571199aa4SStanley.Yang 
22671199aa4SStanley.Yang 	val = RREG32(reg_offset);
22771199aa4SStanley.Yang 
22871199aa4SStanley.Yang 	if (se_num != 0xffffffff || sh_num != 0xffffffff)
22971199aa4SStanley.Yang 		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
23071199aa4SStanley.Yang 	mutex_unlock(&adev->grbm_idx_mutex);
23171199aa4SStanley.Yang 	return val;
23271199aa4SStanley.Yang }
23371199aa4SStanley.Yang 
23471199aa4SStanley.Yang static uint32_t soc21_get_register_value(struct amdgpu_device *adev,
23571199aa4SStanley.Yang 				      bool indexed, u32 se_num,
23671199aa4SStanley.Yang 				      u32 sh_num, u32 reg_offset)
23771199aa4SStanley.Yang {
23871199aa4SStanley.Yang 	if (indexed) {
23971199aa4SStanley.Yang 		return soc21_read_indexed_register(adev, se_num, sh_num, reg_offset);
24071199aa4SStanley.Yang 	} else {
24171199aa4SStanley.Yang 		if (reg_offset == SOC15_REG_OFFSET(GC, 0, regGB_ADDR_CONFIG) && adev->gfx.config.gb_addr_config)
24271199aa4SStanley.Yang 			return adev->gfx.config.gb_addr_config;
24371199aa4SStanley.Yang 		return RREG32(reg_offset);
24471199aa4SStanley.Yang 	}
24571199aa4SStanley.Yang }
24671199aa4SStanley.Yang 
24771199aa4SStanley.Yang static int soc21_read_register(struct amdgpu_device *adev, u32 se_num,
24871199aa4SStanley.Yang 			    u32 sh_num, u32 reg_offset, u32 *value)
24971199aa4SStanley.Yang {
25071199aa4SStanley.Yang 	uint32_t i;
25171199aa4SStanley.Yang 	struct soc15_allowed_register_entry  *en;
25271199aa4SStanley.Yang 
25371199aa4SStanley.Yang 	*value = 0;
25471199aa4SStanley.Yang 	for (i = 0; i < ARRAY_SIZE(soc21_allowed_read_registers); i++) {
25571199aa4SStanley.Yang 		en = &soc21_allowed_read_registers[i];
256bf1781e1SAlex Deucher 		if (adev->reg_offset[en->hwip][en->inst] &&
257bf1781e1SAlex Deucher 		    reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
258bf1781e1SAlex Deucher 				   + en->reg_offset))
25971199aa4SStanley.Yang 			continue;
26071199aa4SStanley.Yang 
26171199aa4SStanley.Yang 		*value = soc21_get_register_value(adev,
26271199aa4SStanley.Yang 					       soc21_allowed_read_registers[i].grbm_indexed,
26371199aa4SStanley.Yang 					       se_num, sh_num, reg_offset);
26471199aa4SStanley.Yang 		return 0;
26571199aa4SStanley.Yang 	}
26671199aa4SStanley.Yang 	return -EINVAL;
26771199aa4SStanley.Yang }
26871199aa4SStanley.Yang 
26971199aa4SStanley.Yang #if 0
27071199aa4SStanley.Yang static int soc21_asic_mode1_reset(struct amdgpu_device *adev)
27171199aa4SStanley.Yang {
27271199aa4SStanley.Yang 	u32 i;
27371199aa4SStanley.Yang 	int ret = 0;
27471199aa4SStanley.Yang 
27571199aa4SStanley.Yang 	amdgpu_atombios_scratch_regs_engine_hung(adev, true);
27671199aa4SStanley.Yang 
27771199aa4SStanley.Yang 	/* disable BM */
27871199aa4SStanley.Yang 	pci_clear_master(adev->pdev);
27971199aa4SStanley.Yang 
28071199aa4SStanley.Yang 	amdgpu_device_cache_pci_state(adev->pdev);
28171199aa4SStanley.Yang 
28271199aa4SStanley.Yang 	if (amdgpu_dpm_is_mode1_reset_supported(adev)) {
28371199aa4SStanley.Yang 		dev_info(adev->dev, "GPU smu mode1 reset\n");
28471199aa4SStanley.Yang 		ret = amdgpu_dpm_mode1_reset(adev);
28571199aa4SStanley.Yang 	} else {
28671199aa4SStanley.Yang 		dev_info(adev->dev, "GPU psp mode1 reset\n");
28771199aa4SStanley.Yang 		ret = psp_gpu_reset(adev);
28871199aa4SStanley.Yang 	}
28971199aa4SStanley.Yang 
29071199aa4SStanley.Yang 	if (ret)
29171199aa4SStanley.Yang 		dev_err(adev->dev, "GPU mode1 reset failed\n");
29271199aa4SStanley.Yang 	amdgpu_device_load_pci_state(adev->pdev);
29371199aa4SStanley.Yang 
29471199aa4SStanley.Yang 	/* wait for asic to come out of reset */
29571199aa4SStanley.Yang 	for (i = 0; i < adev->usec_timeout; i++) {
29671199aa4SStanley.Yang 		u32 memsize = adev->nbio.funcs->get_memsize(adev);
29771199aa4SStanley.Yang 
29871199aa4SStanley.Yang 		if (memsize != 0xffffffff)
29971199aa4SStanley.Yang 			break;
30071199aa4SStanley.Yang 		udelay(1);
30171199aa4SStanley.Yang 	}
30271199aa4SStanley.Yang 
30371199aa4SStanley.Yang 	amdgpu_atombios_scratch_regs_engine_hung(adev, false);
30471199aa4SStanley.Yang 
30571199aa4SStanley.Yang 	return ret;
30671199aa4SStanley.Yang }
30771199aa4SStanley.Yang #endif
30871199aa4SStanley.Yang 
30971199aa4SStanley.Yang static enum amd_reset_method
31071199aa4SStanley.Yang soc21_asic_reset_method(struct amdgpu_device *adev)
31171199aa4SStanley.Yang {
31271199aa4SStanley.Yang 	if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 ||
313*ea64228dSAlex Deucher 	    amdgpu_reset_method == AMD_RESET_METHOD_MODE2 ||
31471199aa4SStanley.Yang 	    amdgpu_reset_method == AMD_RESET_METHOD_BACO)
31571199aa4SStanley.Yang 		return amdgpu_reset_method;
31671199aa4SStanley.Yang 
31771199aa4SStanley.Yang 	if (amdgpu_reset_method != -1)
31871199aa4SStanley.Yang 		dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n",
31971199aa4SStanley.Yang 				  amdgpu_reset_method);
32071199aa4SStanley.Yang 
32171199aa4SStanley.Yang 	switch (adev->ip_versions[MP1_HWIP][0]) {
32271199aa4SStanley.Yang 	case IP_VERSION(13, 0, 0):
32371199aa4SStanley.Yang 		return AMD_RESET_METHOD_MODE1;
324*ea64228dSAlex Deucher 	case IP_VERSION(13, 0, 4):
325*ea64228dSAlex Deucher 		return AMD_RESET_METHOD_MODE2;
32671199aa4SStanley.Yang 	default:
32771199aa4SStanley.Yang 		if (amdgpu_dpm_is_baco_supported(adev))
32871199aa4SStanley.Yang 			return AMD_RESET_METHOD_BACO;
32971199aa4SStanley.Yang 		else
33071199aa4SStanley.Yang 			return AMD_RESET_METHOD_MODE1;
33171199aa4SStanley.Yang 	}
33271199aa4SStanley.Yang }
33371199aa4SStanley.Yang 
33471199aa4SStanley.Yang static int soc21_asic_reset(struct amdgpu_device *adev)
33571199aa4SStanley.Yang {
33671199aa4SStanley.Yang 	int ret = 0;
33771199aa4SStanley.Yang 
33871199aa4SStanley.Yang 	switch (soc21_asic_reset_method(adev)) {
33971199aa4SStanley.Yang 	case AMD_RESET_METHOD_PCI:
34071199aa4SStanley.Yang 		dev_info(adev->dev, "PCI reset\n");
34171199aa4SStanley.Yang 		ret = amdgpu_device_pci_reset(adev);
34271199aa4SStanley.Yang 		break;
34371199aa4SStanley.Yang 	case AMD_RESET_METHOD_BACO:
34471199aa4SStanley.Yang 		dev_info(adev->dev, "BACO reset\n");
34571199aa4SStanley.Yang 		ret = amdgpu_dpm_baco_reset(adev);
34671199aa4SStanley.Yang 		break;
347*ea64228dSAlex Deucher 	case AMD_RESET_METHOD_MODE2:
348*ea64228dSAlex Deucher 		dev_info(adev->dev, "MODE2 reset\n");
349*ea64228dSAlex Deucher 		ret = amdgpu_dpm_mode2_reset(adev);
350*ea64228dSAlex Deucher 		break;
35171199aa4SStanley.Yang 	default:
35271199aa4SStanley.Yang 		dev_info(adev->dev, "MODE1 reset\n");
35371199aa4SStanley.Yang 		ret = amdgpu_device_mode1_reset(adev);
35471199aa4SStanley.Yang 		break;
35571199aa4SStanley.Yang 	}
35671199aa4SStanley.Yang 
35771199aa4SStanley.Yang 	return ret;
35871199aa4SStanley.Yang }
35971199aa4SStanley.Yang 
36071199aa4SStanley.Yang static int soc21_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
36171199aa4SStanley.Yang {
36271199aa4SStanley.Yang 	/* todo */
36371199aa4SStanley.Yang 	return 0;
36471199aa4SStanley.Yang }
36571199aa4SStanley.Yang 
36671199aa4SStanley.Yang static int soc21_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
36771199aa4SStanley.Yang {
36871199aa4SStanley.Yang 	/* todo */
36971199aa4SStanley.Yang 	return 0;
37071199aa4SStanley.Yang }
37171199aa4SStanley.Yang 
37271199aa4SStanley.Yang static void soc21_pcie_gen3_enable(struct amdgpu_device *adev)
37371199aa4SStanley.Yang {
37471199aa4SStanley.Yang 	if (pci_is_root_bus(adev->pdev->bus))
37571199aa4SStanley.Yang 		return;
37671199aa4SStanley.Yang 
37771199aa4SStanley.Yang 	if (amdgpu_pcie_gen2 == 0)
37871199aa4SStanley.Yang 		return;
37971199aa4SStanley.Yang 
38071199aa4SStanley.Yang 	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
38171199aa4SStanley.Yang 					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
38271199aa4SStanley.Yang 		return;
38371199aa4SStanley.Yang 
38471199aa4SStanley.Yang 	/* todo */
38571199aa4SStanley.Yang }
38671199aa4SStanley.Yang 
38771199aa4SStanley.Yang static void soc21_program_aspm(struct amdgpu_device *adev)
38871199aa4SStanley.Yang {
38971199aa4SStanley.Yang 
39071199aa4SStanley.Yang 	if (amdgpu_aspm == 0)
39171199aa4SStanley.Yang 		return;
39271199aa4SStanley.Yang 
39371199aa4SStanley.Yang 	/* todo */
39471199aa4SStanley.Yang }
39571199aa4SStanley.Yang 
39671199aa4SStanley.Yang static void soc21_enable_doorbell_aperture(struct amdgpu_device *adev,
39771199aa4SStanley.Yang 					bool enable)
39871199aa4SStanley.Yang {
39971199aa4SStanley.Yang 	adev->nbio.funcs->enable_doorbell_aperture(adev, enable);
40071199aa4SStanley.Yang 	adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable);
40171199aa4SStanley.Yang }
40271199aa4SStanley.Yang 
40371199aa4SStanley.Yang const struct amdgpu_ip_block_version soc21_common_ip_block =
40471199aa4SStanley.Yang {
40571199aa4SStanley.Yang 	.type = AMD_IP_BLOCK_TYPE_COMMON,
40671199aa4SStanley.Yang 	.major = 1,
40771199aa4SStanley.Yang 	.minor = 0,
40871199aa4SStanley.Yang 	.rev = 0,
40971199aa4SStanley.Yang 	.funcs = &soc21_common_ip_funcs,
41071199aa4SStanley.Yang };
41171199aa4SStanley.Yang 
41271199aa4SStanley.Yang static uint32_t soc21_get_rev_id(struct amdgpu_device *adev)
41371199aa4SStanley.Yang {
41471199aa4SStanley.Yang 	return adev->nbio.funcs->get_rev_id(adev);
41571199aa4SStanley.Yang }
41671199aa4SStanley.Yang 
41771199aa4SStanley.Yang static bool soc21_need_full_reset(struct amdgpu_device *adev)
41871199aa4SStanley.Yang {
41971199aa4SStanley.Yang 	return true;
42071199aa4SStanley.Yang }
42171199aa4SStanley.Yang 
42271199aa4SStanley.Yang static bool soc21_need_reset_on_init(struct amdgpu_device *adev)
42371199aa4SStanley.Yang {
42471199aa4SStanley.Yang 	u32 sol_reg;
42571199aa4SStanley.Yang 
42671199aa4SStanley.Yang 	if (adev->flags & AMD_IS_APU)
42771199aa4SStanley.Yang 		return false;
42871199aa4SStanley.Yang 
42971199aa4SStanley.Yang 	/* Check sOS sign of life register to confirm sys driver and sOS
43071199aa4SStanley.Yang 	 * are already been loaded.
43171199aa4SStanley.Yang 	 */
43271199aa4SStanley.Yang 	sol_reg = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);
43371199aa4SStanley.Yang 	if (sol_reg)
43471199aa4SStanley.Yang 		return true;
43571199aa4SStanley.Yang 
43671199aa4SStanley.Yang 	return false;
43771199aa4SStanley.Yang }
43871199aa4SStanley.Yang 
43971199aa4SStanley.Yang static uint64_t soc21_get_pcie_replay_count(struct amdgpu_device *adev)
44071199aa4SStanley.Yang {
44171199aa4SStanley.Yang 
44271199aa4SStanley.Yang 	/* TODO
44371199aa4SStanley.Yang 	 * dummy implement for pcie_replay_count sysfs interface
44471199aa4SStanley.Yang 	 * */
44571199aa4SStanley.Yang 
44671199aa4SStanley.Yang 	return 0;
44771199aa4SStanley.Yang }
44871199aa4SStanley.Yang 
44971199aa4SStanley.Yang static void soc21_init_doorbell_index(struct amdgpu_device *adev)
45071199aa4SStanley.Yang {
45171199aa4SStanley.Yang 	adev->doorbell_index.kiq = AMDGPU_NAVI10_DOORBELL_KIQ;
45271199aa4SStanley.Yang 	adev->doorbell_index.mec_ring0 = AMDGPU_NAVI10_DOORBELL_MEC_RING0;
45371199aa4SStanley.Yang 	adev->doorbell_index.mec_ring1 = AMDGPU_NAVI10_DOORBELL_MEC_RING1;
45471199aa4SStanley.Yang 	adev->doorbell_index.mec_ring2 = AMDGPU_NAVI10_DOORBELL_MEC_RING2;
45571199aa4SStanley.Yang 	adev->doorbell_index.mec_ring3 = AMDGPU_NAVI10_DOORBELL_MEC_RING3;
45671199aa4SStanley.Yang 	adev->doorbell_index.mec_ring4 = AMDGPU_NAVI10_DOORBELL_MEC_RING4;
45771199aa4SStanley.Yang 	adev->doorbell_index.mec_ring5 = AMDGPU_NAVI10_DOORBELL_MEC_RING5;
45871199aa4SStanley.Yang 	adev->doorbell_index.mec_ring6 = AMDGPU_NAVI10_DOORBELL_MEC_RING6;
45971199aa4SStanley.Yang 	adev->doorbell_index.mec_ring7 = AMDGPU_NAVI10_DOORBELL_MEC_RING7;
46071199aa4SStanley.Yang 	adev->doorbell_index.userqueue_start = AMDGPU_NAVI10_DOORBELL_USERQUEUE_START;
46171199aa4SStanley.Yang 	adev->doorbell_index.userqueue_end = AMDGPU_NAVI10_DOORBELL_USERQUEUE_END;
46271199aa4SStanley.Yang 	adev->doorbell_index.gfx_ring0 = AMDGPU_NAVI10_DOORBELL_GFX_RING0;
46371199aa4SStanley.Yang 	adev->doorbell_index.gfx_ring1 = AMDGPU_NAVI10_DOORBELL_GFX_RING1;
464fd0ed91aSJack Xiao 	adev->doorbell_index.gfx_userqueue_start =
465fd0ed91aSJack Xiao 		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_START;
466fd0ed91aSJack Xiao 	adev->doorbell_index.gfx_userqueue_end =
467fd0ed91aSJack Xiao 		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_END;
468b608e785SJack Xiao 	adev->doorbell_index.mes_ring0 = AMDGPU_NAVI10_DOORBELL_MES_RING0;
469b608e785SJack Xiao 	adev->doorbell_index.mes_ring1 = AMDGPU_NAVI10_DOORBELL_MES_RING1;
47071199aa4SStanley.Yang 	adev->doorbell_index.sdma_engine[0] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0;
47171199aa4SStanley.Yang 	adev->doorbell_index.sdma_engine[1] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1;
47271199aa4SStanley.Yang 	adev->doorbell_index.ih = AMDGPU_NAVI10_DOORBELL_IH;
47371199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_NAVI10_DOORBELL64_VCN0_1;
47471199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_NAVI10_DOORBELL64_VCN2_3;
47571199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_NAVI10_DOORBELL64_VCN4_5;
47671199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_NAVI10_DOORBELL64_VCN6_7;
47771199aa4SStanley.Yang 	adev->doorbell_index.first_non_cp = AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP;
47871199aa4SStanley.Yang 	adev->doorbell_index.last_non_cp = AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP;
47971199aa4SStanley.Yang 
48071199aa4SStanley.Yang 	adev->doorbell_index.max_assignment = AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT << 1;
48171199aa4SStanley.Yang 	adev->doorbell_index.sdma_doorbell_range = 20;
48271199aa4SStanley.Yang }
48371199aa4SStanley.Yang 
48471199aa4SStanley.Yang static void soc21_pre_asic_init(struct amdgpu_device *adev)
48571199aa4SStanley.Yang {
48671199aa4SStanley.Yang }
48771199aa4SStanley.Yang 
48871199aa4SStanley.Yang static const struct amdgpu_asic_funcs soc21_asic_funcs =
48971199aa4SStanley.Yang {
49071199aa4SStanley.Yang 	.read_disabled_bios = &soc21_read_disabled_bios,
49171199aa4SStanley.Yang 	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
49271199aa4SStanley.Yang 	.read_register = &soc21_read_register,
49371199aa4SStanley.Yang 	.reset = &soc21_asic_reset,
49471199aa4SStanley.Yang 	.reset_method = &soc21_asic_reset_method,
49571199aa4SStanley.Yang 	.set_vga_state = &soc21_vga_set_state,
49671199aa4SStanley.Yang 	.get_xclk = &soc21_get_xclk,
49771199aa4SStanley.Yang 	.set_uvd_clocks = &soc21_set_uvd_clocks,
49871199aa4SStanley.Yang 	.set_vce_clocks = &soc21_set_vce_clocks,
49971199aa4SStanley.Yang 	.get_config_memsize = &soc21_get_config_memsize,
50071199aa4SStanley.Yang 	.init_doorbell_index = &soc21_init_doorbell_index,
50171199aa4SStanley.Yang 	.need_full_reset = &soc21_need_full_reset,
50271199aa4SStanley.Yang 	.need_reset_on_init = &soc21_need_reset_on_init,
50371199aa4SStanley.Yang 	.get_pcie_replay_count = &soc21_get_pcie_replay_count,
50471199aa4SStanley.Yang 	.supports_baco = &amdgpu_dpm_is_baco_supported,
50571199aa4SStanley.Yang 	.pre_asic_init = &soc21_pre_asic_init,
5069ac0edaaSJames Zhu 	.query_video_codecs = &soc21_query_video_codecs,
50771199aa4SStanley.Yang };
50871199aa4SStanley.Yang 
50971199aa4SStanley.Yang static int soc21_common_early_init(void *handle)
51071199aa4SStanley.Yang {
51171199aa4SStanley.Yang #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
51271199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
51371199aa4SStanley.Yang 
51471199aa4SStanley.Yang 	adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
51571199aa4SStanley.Yang 	adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
51671199aa4SStanley.Yang 	adev->smc_rreg = NULL;
51771199aa4SStanley.Yang 	adev->smc_wreg = NULL;
51871199aa4SStanley.Yang 	adev->pcie_rreg = &soc21_pcie_rreg;
51971199aa4SStanley.Yang 	adev->pcie_wreg = &soc21_pcie_wreg;
52071199aa4SStanley.Yang 	adev->pcie_rreg64 = &soc21_pcie_rreg64;
52171199aa4SStanley.Yang 	adev->pcie_wreg64 = &soc21_pcie_wreg64;
522bafd6cbeSXiaojian Du 	adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
523bafd6cbeSXiaojian Du 	adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
52471199aa4SStanley.Yang 
52571199aa4SStanley.Yang 	/* TODO: will add them during VCN v2 implementation */
52671199aa4SStanley.Yang 	adev->uvd_ctx_rreg = NULL;
52771199aa4SStanley.Yang 	adev->uvd_ctx_wreg = NULL;
52871199aa4SStanley.Yang 
52971199aa4SStanley.Yang 	adev->didt_rreg = &soc21_didt_rreg;
53071199aa4SStanley.Yang 	adev->didt_wreg = &soc21_didt_wreg;
53171199aa4SStanley.Yang 
53271199aa4SStanley.Yang 	adev->asic_funcs = &soc21_asic_funcs;
53371199aa4SStanley.Yang 
53471199aa4SStanley.Yang 	adev->rev_id = soc21_get_rev_id(adev);
53571199aa4SStanley.Yang 	adev->external_rev_id = 0xff;
53671199aa4SStanley.Yang 	switch (adev->ip_versions[GC_HWIP][0]) {
53771199aa4SStanley.Yang 	case IP_VERSION(11, 0, 0):
538390db4b8SEvan Quan 		adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG |
539b21348a2SEvan Quan 			AMD_CG_SUPPORT_GFX_CGLS |
540915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_3D_CGCG |
541915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_3D_CGLS |
542915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_MGCG |
5438b719b96SLeo Liu 			AMD_CG_SUPPORT_REPEATER_FGCG |
544915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_FGCG |
545915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_PERF_CLK |
5467c507d35SJames Zhu 			AMD_CG_SUPPORT_VCN_MGCG |
547c649ed05SEvan Quan 			AMD_CG_SUPPORT_JPEG_MGCG |
548c649ed05SEvan Quan 			AMD_CG_SUPPORT_ATHUB_MGCG |
5497ccf6eb0SEvan Quan 			AMD_CG_SUPPORT_ATHUB_LS |
5507ccf6eb0SEvan Quan 			AMD_CG_SUPPORT_MC_MGCG |
55120139069SEvan Quan 			AMD_CG_SUPPORT_MC_LS |
552d386f645SEvan Quan 			AMD_CG_SUPPORT_IH_CG |
553d386f645SEvan Quan 			AMD_CG_SUPPORT_HDP_SD;
5548b719b96SLeo Liu 		adev->pg_flags = AMD_PG_SUPPORT_VCN |
55504270390SJames Zhu 			AMD_PG_SUPPORT_VCN_DPG |
5567c507d35SJames Zhu 			AMD_PG_SUPPORT_JPEG |
5578b719b96SLeo Liu 			AMD_PG_SUPPORT_ATHUB |
558a6dec868SEvan Quan 			AMD_PG_SUPPORT_MMHUB;
55971199aa4SStanley.Yang 		adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
56071199aa4SStanley.Yang 		break;
56192fd2153SFlora Cui 	case IP_VERSION(11, 0, 2):
56271dae221SJames Zhu 		adev->cg_flags =
5639503a944SLikun Gao 			AMD_CG_SUPPORT_GFX_CGCG |
5649503a944SLikun Gao 			AMD_CG_SUPPORT_GFX_CGLS |
56549401d3aSKenneth Feng 			AMD_CG_SUPPORT_REPEATER_FGCG |
5667ece9314SJames Zhu 			AMD_CG_SUPPORT_VCN_MGCG |
56749401d3aSKenneth Feng 			AMD_CG_SUPPORT_JPEG_MGCG |
56849401d3aSKenneth Feng 			AMD_CG_SUPPORT_ATHUB_MGCG |
56949401d3aSKenneth Feng 			AMD_CG_SUPPORT_ATHUB_LS;
570ebac66a3SJames Zhu 		adev->pg_flags =
571143a34a0SJames Zhu 			AMD_PG_SUPPORT_VCN |
572ec9db74eSJames Zhu 			AMD_PG_SUPPORT_VCN_DPG |
57327e3911cSKenneth Feng 			AMD_PG_SUPPORT_JPEG |
57427e3911cSKenneth Feng 			AMD_PG_SUPPORT_ATHUB |
57527e3911cSKenneth Feng 			AMD_PG_SUPPORT_MMHUB;
57692fd2153SFlora Cui 		adev->external_rev_id = adev->rev_id + 0x10;
57792fd2153SFlora Cui 		break;
57811417a92SHuang Rui 	case IP_VERSION(11, 0, 1):
57911417a92SHuang Rui 		adev->cg_flags = 0;
58011417a92SHuang Rui 		adev->pg_flags = 0;
58111417a92SHuang Rui 		adev->external_rev_id = adev->rev_id + 0x1;
58211417a92SHuang Rui 		break;
58371199aa4SStanley.Yang 	default:
58471199aa4SStanley.Yang 		/* FIXME: not supported yet */
58571199aa4SStanley.Yang 		return -EINVAL;
58671199aa4SStanley.Yang 	}
58771199aa4SStanley.Yang 
58871199aa4SStanley.Yang 	return 0;
58971199aa4SStanley.Yang }
59071199aa4SStanley.Yang 
59171199aa4SStanley.Yang static int soc21_common_late_init(void *handle)
59271199aa4SStanley.Yang {
59371199aa4SStanley.Yang 	return 0;
59471199aa4SStanley.Yang }
59571199aa4SStanley.Yang 
59671199aa4SStanley.Yang static int soc21_common_sw_init(void *handle)
59771199aa4SStanley.Yang {
59871199aa4SStanley.Yang 	return 0;
59971199aa4SStanley.Yang }
60071199aa4SStanley.Yang 
60171199aa4SStanley.Yang static int soc21_common_sw_fini(void *handle)
60271199aa4SStanley.Yang {
60371199aa4SStanley.Yang 	return 0;
60471199aa4SStanley.Yang }
60571199aa4SStanley.Yang 
60671199aa4SStanley.Yang static int soc21_common_hw_init(void *handle)
60771199aa4SStanley.Yang {
60871199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
60971199aa4SStanley.Yang 
61071199aa4SStanley.Yang 	/* enable pcie gen2/3 link */
61171199aa4SStanley.Yang 	soc21_pcie_gen3_enable(adev);
61271199aa4SStanley.Yang 	/* enable aspm */
61371199aa4SStanley.Yang 	soc21_program_aspm(adev);
61471199aa4SStanley.Yang 	/* setup nbio registers */
61571199aa4SStanley.Yang 	adev->nbio.funcs->init_registers(adev);
61671199aa4SStanley.Yang 	/* remap HDP registers to a hole in mmio space,
61771199aa4SStanley.Yang 	 * for the purpose of expose those registers
61871199aa4SStanley.Yang 	 * to process space
61971199aa4SStanley.Yang 	 */
62071199aa4SStanley.Yang 	if (adev->nbio.funcs->remap_hdp_registers)
62171199aa4SStanley.Yang 		adev->nbio.funcs->remap_hdp_registers(adev);
62271199aa4SStanley.Yang 	/* enable the doorbell aperture */
62371199aa4SStanley.Yang 	soc21_enable_doorbell_aperture(adev, true);
62471199aa4SStanley.Yang 
62571199aa4SStanley.Yang 	return 0;
62671199aa4SStanley.Yang }
62771199aa4SStanley.Yang 
62871199aa4SStanley.Yang static int soc21_common_hw_fini(void *handle)
62971199aa4SStanley.Yang {
63071199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
63171199aa4SStanley.Yang 
63271199aa4SStanley.Yang 	/* disable the doorbell aperture */
63371199aa4SStanley.Yang 	soc21_enable_doorbell_aperture(adev, false);
63471199aa4SStanley.Yang 
63571199aa4SStanley.Yang 	return 0;
63671199aa4SStanley.Yang }
63771199aa4SStanley.Yang 
63871199aa4SStanley.Yang static int soc21_common_suspend(void *handle)
63971199aa4SStanley.Yang {
64071199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
64171199aa4SStanley.Yang 
64271199aa4SStanley.Yang 	return soc21_common_hw_fini(adev);
64371199aa4SStanley.Yang }
64471199aa4SStanley.Yang 
64571199aa4SStanley.Yang static int soc21_common_resume(void *handle)
64671199aa4SStanley.Yang {
64771199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
64871199aa4SStanley.Yang 
64971199aa4SStanley.Yang 	return soc21_common_hw_init(adev);
65071199aa4SStanley.Yang }
65171199aa4SStanley.Yang 
65271199aa4SStanley.Yang static bool soc21_common_is_idle(void *handle)
65371199aa4SStanley.Yang {
65471199aa4SStanley.Yang 	return true;
65571199aa4SStanley.Yang }
65671199aa4SStanley.Yang 
65771199aa4SStanley.Yang static int soc21_common_wait_for_idle(void *handle)
65871199aa4SStanley.Yang {
65971199aa4SStanley.Yang 	return 0;
66071199aa4SStanley.Yang }
66171199aa4SStanley.Yang 
66271199aa4SStanley.Yang static int soc21_common_soft_reset(void *handle)
66371199aa4SStanley.Yang {
66471199aa4SStanley.Yang 	return 0;
66571199aa4SStanley.Yang }
66671199aa4SStanley.Yang 
66771199aa4SStanley.Yang static int soc21_common_set_clockgating_state(void *handle,
66871199aa4SStanley.Yang 					   enum amd_clockgating_state state)
66971199aa4SStanley.Yang {
67071199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
67171199aa4SStanley.Yang 
67271199aa4SStanley.Yang 	switch (adev->ip_versions[NBIO_HWIP][0]) {
67371199aa4SStanley.Yang 	case IP_VERSION(4, 3, 0):
67471199aa4SStanley.Yang 		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
67571199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
67671199aa4SStanley.Yang 		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
67771199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
67871199aa4SStanley.Yang 		adev->hdp.funcs->update_clock_gating(adev,
67971199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
68071199aa4SStanley.Yang 		break;
68171199aa4SStanley.Yang 	default:
68271199aa4SStanley.Yang 		break;
68371199aa4SStanley.Yang 	}
68471199aa4SStanley.Yang 	return 0;
68571199aa4SStanley.Yang }
68671199aa4SStanley.Yang 
68771199aa4SStanley.Yang static int soc21_common_set_powergating_state(void *handle,
68871199aa4SStanley.Yang 					   enum amd_powergating_state state)
68971199aa4SStanley.Yang {
69041967850SLikun Gao 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
69141967850SLikun Gao 
69241967850SLikun Gao 	switch (adev->ip_versions[LSDMA_HWIP][0]) {
69341967850SLikun Gao 	case IP_VERSION(6, 0, 0):
694362c3c70SLikun Gao 	case IP_VERSION(6, 0, 2):
69541967850SLikun Gao 		adev->lsdma.funcs->update_memory_power_gating(adev,
69641967850SLikun Gao 				state == AMD_PG_STATE_GATE);
69741967850SLikun Gao 		break;
69841967850SLikun Gao 	default:
69941967850SLikun Gao 		break;
70041967850SLikun Gao 	}
70141967850SLikun Gao 
70271199aa4SStanley.Yang 	return 0;
70371199aa4SStanley.Yang }
70471199aa4SStanley.Yang 
70571199aa4SStanley.Yang static void soc21_common_get_clockgating_state(void *handle, u64 *flags)
70671199aa4SStanley.Yang {
70771199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
70871199aa4SStanley.Yang 
70971199aa4SStanley.Yang 	adev->nbio.funcs->get_clockgating_state(adev, flags);
71071199aa4SStanley.Yang 
71171199aa4SStanley.Yang 	adev->hdp.funcs->get_clock_gating_state(adev, flags);
71271199aa4SStanley.Yang 
71371199aa4SStanley.Yang 	return;
71471199aa4SStanley.Yang }
71571199aa4SStanley.Yang 
71671199aa4SStanley.Yang static const struct amd_ip_funcs soc21_common_ip_funcs = {
71771199aa4SStanley.Yang 	.name = "soc21_common",
71871199aa4SStanley.Yang 	.early_init = soc21_common_early_init,
71971199aa4SStanley.Yang 	.late_init = soc21_common_late_init,
72071199aa4SStanley.Yang 	.sw_init = soc21_common_sw_init,
72171199aa4SStanley.Yang 	.sw_fini = soc21_common_sw_fini,
72271199aa4SStanley.Yang 	.hw_init = soc21_common_hw_init,
72371199aa4SStanley.Yang 	.hw_fini = soc21_common_hw_fini,
72471199aa4SStanley.Yang 	.suspend = soc21_common_suspend,
72571199aa4SStanley.Yang 	.resume = soc21_common_resume,
72671199aa4SStanley.Yang 	.is_idle = soc21_common_is_idle,
72771199aa4SStanley.Yang 	.wait_for_idle = soc21_common_wait_for_idle,
72871199aa4SStanley.Yang 	.soft_reset = soc21_common_soft_reset,
72971199aa4SStanley.Yang 	.set_clockgating_state = soc21_common_set_clockgating_state,
73071199aa4SStanley.Yang 	.set_powergating_state = soc21_common_set_powergating_state,
73171199aa4SStanley.Yang 	.get_clockgating_state = soc21_common_get_clockgating_state,
73271199aa4SStanley.Yang };
733