xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/soc21.c (revision ebac66a3)
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"
4571199aa4SStanley.Yang 
4671199aa4SStanley.Yang static const struct amd_ip_funcs soc21_common_ip_funcs;
4771199aa4SStanley.Yang 
489ac0edaaSJames Zhu /* SOC21 */
499ac0edaaSJames Zhu static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array[] =
509ac0edaaSJames Zhu {
519ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
529ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
539ac0edaaSJames Zhu };
549ac0edaaSJames Zhu 
559ac0edaaSJames Zhu static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode =
569ac0edaaSJames Zhu {
579ac0edaaSJames Zhu 	.codec_count = ARRAY_SIZE(vcn_4_0_0_video_codecs_encode_array),
589ac0edaaSJames Zhu 	.codec_array = vcn_4_0_0_video_codecs_encode_array,
599ac0edaaSJames Zhu };
609ac0edaaSJames Zhu 
619ac0edaaSJames Zhu static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] =
629ac0edaaSJames Zhu {
639ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
649ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
659ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
669ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
679ac0edaaSJames Zhu 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
689ac0edaaSJames Zhu };
699ac0edaaSJames Zhu 
709ac0edaaSJames Zhu static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_decode =
719ac0edaaSJames Zhu {
729ac0edaaSJames Zhu 	.codec_count = ARRAY_SIZE(vcn_4_0_0_video_codecs_decode_array),
739ac0edaaSJames Zhu 	.codec_array = vcn_4_0_0_video_codecs_decode_array,
749ac0edaaSJames Zhu };
759ac0edaaSJames Zhu 
769ac0edaaSJames Zhu static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode,
779ac0edaaSJames Zhu 				 const struct amdgpu_video_codecs **codecs)
789ac0edaaSJames Zhu {
799ac0edaaSJames Zhu 	switch (adev->ip_versions[UVD_HWIP][0]) {
809ac0edaaSJames Zhu 
819ac0edaaSJames Zhu 	case IP_VERSION(4, 0, 0):
829ac0edaaSJames Zhu 		if (encode)
839ac0edaaSJames Zhu 			*codecs = &vcn_4_0_0_video_codecs_encode;
849ac0edaaSJames Zhu 		else
859ac0edaaSJames Zhu 			*codecs = &vcn_4_0_0_video_codecs_decode;
869ac0edaaSJames Zhu 		return 0;
879ac0edaaSJames Zhu 	default:
889ac0edaaSJames Zhu 		return -EINVAL;
899ac0edaaSJames Zhu 	}
909ac0edaaSJames Zhu }
9171199aa4SStanley.Yang /*
9271199aa4SStanley.Yang  * Indirect registers accessor
9371199aa4SStanley.Yang  */
9471199aa4SStanley.Yang static u32 soc21_pcie_rreg(struct amdgpu_device *adev, u32 reg)
9571199aa4SStanley.Yang {
9671199aa4SStanley.Yang 	unsigned long address, data;
9771199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
9871199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
9971199aa4SStanley.Yang 
10071199aa4SStanley.Yang 	return amdgpu_device_indirect_rreg(adev, address, data, reg);
10171199aa4SStanley.Yang }
10271199aa4SStanley.Yang 
10371199aa4SStanley.Yang static void soc21_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
10471199aa4SStanley.Yang {
10571199aa4SStanley.Yang 	unsigned long address, data;
10671199aa4SStanley.Yang 
10771199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
10871199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
10971199aa4SStanley.Yang 
11071199aa4SStanley.Yang 	amdgpu_device_indirect_wreg(adev, address, data, reg, v);
11171199aa4SStanley.Yang }
11271199aa4SStanley.Yang 
11371199aa4SStanley.Yang static u64 soc21_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
11471199aa4SStanley.Yang {
11571199aa4SStanley.Yang 	unsigned long address, data;
11671199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
11771199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
11871199aa4SStanley.Yang 
11971199aa4SStanley.Yang 	return amdgpu_device_indirect_rreg64(adev, address, data, reg);
12071199aa4SStanley.Yang }
12171199aa4SStanley.Yang 
12271199aa4SStanley.Yang static void soc21_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
12371199aa4SStanley.Yang {
12471199aa4SStanley.Yang 	unsigned long address, data;
12571199aa4SStanley.Yang 
12671199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
12771199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
12871199aa4SStanley.Yang 
12971199aa4SStanley.Yang 	amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
13071199aa4SStanley.Yang }
13171199aa4SStanley.Yang 
13271199aa4SStanley.Yang static u32 soc21_didt_rreg(struct amdgpu_device *adev, u32 reg)
13371199aa4SStanley.Yang {
13471199aa4SStanley.Yang 	unsigned long flags, address, data;
13571199aa4SStanley.Yang 	u32 r;
13671199aa4SStanley.Yang 
13771199aa4SStanley.Yang 	address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
13871199aa4SStanley.Yang 	data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
13971199aa4SStanley.Yang 
14071199aa4SStanley.Yang 	spin_lock_irqsave(&adev->didt_idx_lock, flags);
14171199aa4SStanley.Yang 	WREG32(address, (reg));
14271199aa4SStanley.Yang 	r = RREG32(data);
14371199aa4SStanley.Yang 	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
14471199aa4SStanley.Yang 	return r;
14571199aa4SStanley.Yang }
14671199aa4SStanley.Yang 
14771199aa4SStanley.Yang static void soc21_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
14871199aa4SStanley.Yang {
14971199aa4SStanley.Yang 	unsigned long flags, address, data;
15071199aa4SStanley.Yang 
15171199aa4SStanley.Yang 	address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
15271199aa4SStanley.Yang 	data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
15371199aa4SStanley.Yang 
15471199aa4SStanley.Yang 	spin_lock_irqsave(&adev->didt_idx_lock, flags);
15571199aa4SStanley.Yang 	WREG32(address, (reg));
15671199aa4SStanley.Yang 	WREG32(data, (v));
15771199aa4SStanley.Yang 	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
15871199aa4SStanley.Yang }
15971199aa4SStanley.Yang 
16071199aa4SStanley.Yang static u32 soc21_get_config_memsize(struct amdgpu_device *adev)
16171199aa4SStanley.Yang {
16271199aa4SStanley.Yang 	return adev->nbio.funcs->get_memsize(adev);
16371199aa4SStanley.Yang }
16471199aa4SStanley.Yang 
16571199aa4SStanley.Yang static u32 soc21_get_xclk(struct amdgpu_device *adev)
16671199aa4SStanley.Yang {
16771199aa4SStanley.Yang 	return adev->clock.spll.reference_freq;
16871199aa4SStanley.Yang }
16971199aa4SStanley.Yang 
17071199aa4SStanley.Yang 
17171199aa4SStanley.Yang void soc21_grbm_select(struct amdgpu_device *adev,
17271199aa4SStanley.Yang 		     u32 me, u32 pipe, u32 queue, u32 vmid)
17371199aa4SStanley.Yang {
17471199aa4SStanley.Yang 	u32 grbm_gfx_cntl = 0;
17571199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe);
17671199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me);
17771199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
17871199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
17971199aa4SStanley.Yang 
18071199aa4SStanley.Yang 	WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_CNTL), grbm_gfx_cntl);
18171199aa4SStanley.Yang }
18271199aa4SStanley.Yang 
18371199aa4SStanley.Yang static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
18471199aa4SStanley.Yang {
18571199aa4SStanley.Yang 	/* todo */
18671199aa4SStanley.Yang }
18771199aa4SStanley.Yang 
18871199aa4SStanley.Yang static bool soc21_read_disabled_bios(struct amdgpu_device *adev)
18971199aa4SStanley.Yang {
19071199aa4SStanley.Yang 	/* todo */
19171199aa4SStanley.Yang 	return false;
19271199aa4SStanley.Yang }
19371199aa4SStanley.Yang 
19471199aa4SStanley.Yang static struct soc15_allowed_register_entry soc21_allowed_read_registers[] = {
19571199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS)},
19671199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS2)},
19771199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE0)},
19871199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE1)},
19971199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE2)},
20071199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE3)},
20171199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(SDMA0, 0, regSDMA0_STATUS_REG)},
20271199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(SDMA1, 0, regSDMA1_STATUS_REG)},
20371199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STAT)},
20471199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT1)},
20571199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT2)},
20671199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT3)},
20771199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_BUSY_STAT)},
20871199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_STALLED_STAT1)},
20971199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_STATUS)},
21071199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_BUSY_STAT)},
21171199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_STALLED_STAT1)},
21271199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_STATUS)},
21371199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGB_ADDR_CONFIG)},
21471199aa4SStanley.Yang };
21571199aa4SStanley.Yang 
21671199aa4SStanley.Yang static uint32_t soc21_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
21771199aa4SStanley.Yang 					 u32 sh_num, u32 reg_offset)
21871199aa4SStanley.Yang {
21971199aa4SStanley.Yang 	uint32_t val;
22071199aa4SStanley.Yang 
22171199aa4SStanley.Yang 	mutex_lock(&adev->grbm_idx_mutex);
22271199aa4SStanley.Yang 	if (se_num != 0xffffffff || sh_num != 0xffffffff)
22371199aa4SStanley.Yang 		amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff);
22471199aa4SStanley.Yang 
22571199aa4SStanley.Yang 	val = RREG32(reg_offset);
22671199aa4SStanley.Yang 
22771199aa4SStanley.Yang 	if (se_num != 0xffffffff || sh_num != 0xffffffff)
22871199aa4SStanley.Yang 		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
22971199aa4SStanley.Yang 	mutex_unlock(&adev->grbm_idx_mutex);
23071199aa4SStanley.Yang 	return val;
23171199aa4SStanley.Yang }
23271199aa4SStanley.Yang 
23371199aa4SStanley.Yang static uint32_t soc21_get_register_value(struct amdgpu_device *adev,
23471199aa4SStanley.Yang 				      bool indexed, u32 se_num,
23571199aa4SStanley.Yang 				      u32 sh_num, u32 reg_offset)
23671199aa4SStanley.Yang {
23771199aa4SStanley.Yang 	if (indexed) {
23871199aa4SStanley.Yang 		return soc21_read_indexed_register(adev, se_num, sh_num, reg_offset);
23971199aa4SStanley.Yang 	} else {
24071199aa4SStanley.Yang 		if (reg_offset == SOC15_REG_OFFSET(GC, 0, regGB_ADDR_CONFIG) && adev->gfx.config.gb_addr_config)
24171199aa4SStanley.Yang 			return adev->gfx.config.gb_addr_config;
24271199aa4SStanley.Yang 		return RREG32(reg_offset);
24371199aa4SStanley.Yang 	}
24471199aa4SStanley.Yang }
24571199aa4SStanley.Yang 
24671199aa4SStanley.Yang static int soc21_read_register(struct amdgpu_device *adev, u32 se_num,
24771199aa4SStanley.Yang 			    u32 sh_num, u32 reg_offset, u32 *value)
24871199aa4SStanley.Yang {
24971199aa4SStanley.Yang 	uint32_t i;
25071199aa4SStanley.Yang 	struct soc15_allowed_register_entry  *en;
25171199aa4SStanley.Yang 
25271199aa4SStanley.Yang 	*value = 0;
25371199aa4SStanley.Yang 	for (i = 0; i < ARRAY_SIZE(soc21_allowed_read_registers); i++) {
25471199aa4SStanley.Yang 		en = &soc21_allowed_read_registers[i];
25571199aa4SStanley.Yang 		if (reg_offset !=
25671199aa4SStanley.Yang 		    (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset))
25771199aa4SStanley.Yang 			continue;
25871199aa4SStanley.Yang 
25971199aa4SStanley.Yang 		*value = soc21_get_register_value(adev,
26071199aa4SStanley.Yang 					       soc21_allowed_read_registers[i].grbm_indexed,
26171199aa4SStanley.Yang 					       se_num, sh_num, reg_offset);
26271199aa4SStanley.Yang 		return 0;
26371199aa4SStanley.Yang 	}
26471199aa4SStanley.Yang 	return -EINVAL;
26571199aa4SStanley.Yang }
26671199aa4SStanley.Yang 
26771199aa4SStanley.Yang #if 0
26871199aa4SStanley.Yang static int soc21_asic_mode1_reset(struct amdgpu_device *adev)
26971199aa4SStanley.Yang {
27071199aa4SStanley.Yang 	u32 i;
27171199aa4SStanley.Yang 	int ret = 0;
27271199aa4SStanley.Yang 
27371199aa4SStanley.Yang 	amdgpu_atombios_scratch_regs_engine_hung(adev, true);
27471199aa4SStanley.Yang 
27571199aa4SStanley.Yang 	/* disable BM */
27671199aa4SStanley.Yang 	pci_clear_master(adev->pdev);
27771199aa4SStanley.Yang 
27871199aa4SStanley.Yang 	amdgpu_device_cache_pci_state(adev->pdev);
27971199aa4SStanley.Yang 
28071199aa4SStanley.Yang 	if (amdgpu_dpm_is_mode1_reset_supported(adev)) {
28171199aa4SStanley.Yang 		dev_info(adev->dev, "GPU smu mode1 reset\n");
28271199aa4SStanley.Yang 		ret = amdgpu_dpm_mode1_reset(adev);
28371199aa4SStanley.Yang 	} else {
28471199aa4SStanley.Yang 		dev_info(adev->dev, "GPU psp mode1 reset\n");
28571199aa4SStanley.Yang 		ret = psp_gpu_reset(adev);
28671199aa4SStanley.Yang 	}
28771199aa4SStanley.Yang 
28871199aa4SStanley.Yang 	if (ret)
28971199aa4SStanley.Yang 		dev_err(adev->dev, "GPU mode1 reset failed\n");
29071199aa4SStanley.Yang 	amdgpu_device_load_pci_state(adev->pdev);
29171199aa4SStanley.Yang 
29271199aa4SStanley.Yang 	/* wait for asic to come out of reset */
29371199aa4SStanley.Yang 	for (i = 0; i < adev->usec_timeout; i++) {
29471199aa4SStanley.Yang 		u32 memsize = adev->nbio.funcs->get_memsize(adev);
29571199aa4SStanley.Yang 
29671199aa4SStanley.Yang 		if (memsize != 0xffffffff)
29771199aa4SStanley.Yang 			break;
29871199aa4SStanley.Yang 		udelay(1);
29971199aa4SStanley.Yang 	}
30071199aa4SStanley.Yang 
30171199aa4SStanley.Yang 	amdgpu_atombios_scratch_regs_engine_hung(adev, false);
30271199aa4SStanley.Yang 
30371199aa4SStanley.Yang 	return ret;
30471199aa4SStanley.Yang }
30571199aa4SStanley.Yang #endif
30671199aa4SStanley.Yang 
30771199aa4SStanley.Yang static enum amd_reset_method
30871199aa4SStanley.Yang soc21_asic_reset_method(struct amdgpu_device *adev)
30971199aa4SStanley.Yang {
31071199aa4SStanley.Yang 	if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 ||
31171199aa4SStanley.Yang 	    amdgpu_reset_method == AMD_RESET_METHOD_BACO)
31271199aa4SStanley.Yang 		return amdgpu_reset_method;
31371199aa4SStanley.Yang 
31471199aa4SStanley.Yang 	if (amdgpu_reset_method != -1)
31571199aa4SStanley.Yang 		dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n",
31671199aa4SStanley.Yang 				  amdgpu_reset_method);
31771199aa4SStanley.Yang 
31871199aa4SStanley.Yang 	switch (adev->ip_versions[MP1_HWIP][0]) {
31971199aa4SStanley.Yang 	case IP_VERSION(13, 0, 0):
32071199aa4SStanley.Yang 		return AMD_RESET_METHOD_MODE1;
32171199aa4SStanley.Yang 	default:
32271199aa4SStanley.Yang 		if (amdgpu_dpm_is_baco_supported(adev))
32371199aa4SStanley.Yang 			return AMD_RESET_METHOD_BACO;
32471199aa4SStanley.Yang 		else
32571199aa4SStanley.Yang 			return AMD_RESET_METHOD_MODE1;
32671199aa4SStanley.Yang 	}
32771199aa4SStanley.Yang }
32871199aa4SStanley.Yang 
32971199aa4SStanley.Yang static int soc21_asic_reset(struct amdgpu_device *adev)
33071199aa4SStanley.Yang {
33171199aa4SStanley.Yang 	int ret = 0;
33271199aa4SStanley.Yang 
33371199aa4SStanley.Yang 	switch (soc21_asic_reset_method(adev)) {
33471199aa4SStanley.Yang 	case AMD_RESET_METHOD_PCI:
33571199aa4SStanley.Yang 		dev_info(adev->dev, "PCI reset\n");
33671199aa4SStanley.Yang 		ret = amdgpu_device_pci_reset(adev);
33771199aa4SStanley.Yang 		break;
33871199aa4SStanley.Yang 	case AMD_RESET_METHOD_BACO:
33971199aa4SStanley.Yang 		dev_info(adev->dev, "BACO reset\n");
34071199aa4SStanley.Yang 		ret = amdgpu_dpm_baco_reset(adev);
34171199aa4SStanley.Yang 		break;
34271199aa4SStanley.Yang 	default:
34371199aa4SStanley.Yang 		dev_info(adev->dev, "MODE1 reset\n");
34471199aa4SStanley.Yang 		ret = amdgpu_device_mode1_reset(adev);
34571199aa4SStanley.Yang 		break;
34671199aa4SStanley.Yang 	}
34771199aa4SStanley.Yang 
34871199aa4SStanley.Yang 	return ret;
34971199aa4SStanley.Yang }
35071199aa4SStanley.Yang 
35171199aa4SStanley.Yang static int soc21_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
35271199aa4SStanley.Yang {
35371199aa4SStanley.Yang 	/* todo */
35471199aa4SStanley.Yang 	return 0;
35571199aa4SStanley.Yang }
35671199aa4SStanley.Yang 
35771199aa4SStanley.Yang static int soc21_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
35871199aa4SStanley.Yang {
35971199aa4SStanley.Yang 	/* todo */
36071199aa4SStanley.Yang 	return 0;
36171199aa4SStanley.Yang }
36271199aa4SStanley.Yang 
36371199aa4SStanley.Yang static void soc21_pcie_gen3_enable(struct amdgpu_device *adev)
36471199aa4SStanley.Yang {
36571199aa4SStanley.Yang 	if (pci_is_root_bus(adev->pdev->bus))
36671199aa4SStanley.Yang 		return;
36771199aa4SStanley.Yang 
36871199aa4SStanley.Yang 	if (amdgpu_pcie_gen2 == 0)
36971199aa4SStanley.Yang 		return;
37071199aa4SStanley.Yang 
37171199aa4SStanley.Yang 	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
37271199aa4SStanley.Yang 					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
37371199aa4SStanley.Yang 		return;
37471199aa4SStanley.Yang 
37571199aa4SStanley.Yang 	/* todo */
37671199aa4SStanley.Yang }
37771199aa4SStanley.Yang 
37871199aa4SStanley.Yang static void soc21_program_aspm(struct amdgpu_device *adev)
37971199aa4SStanley.Yang {
38071199aa4SStanley.Yang 
38171199aa4SStanley.Yang 	if (amdgpu_aspm == 0)
38271199aa4SStanley.Yang 		return;
38371199aa4SStanley.Yang 
38471199aa4SStanley.Yang 	/* todo */
38571199aa4SStanley.Yang }
38671199aa4SStanley.Yang 
38771199aa4SStanley.Yang static void soc21_enable_doorbell_aperture(struct amdgpu_device *adev,
38871199aa4SStanley.Yang 					bool enable)
38971199aa4SStanley.Yang {
39071199aa4SStanley.Yang 	adev->nbio.funcs->enable_doorbell_aperture(adev, enable);
39171199aa4SStanley.Yang 	adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable);
39271199aa4SStanley.Yang }
39371199aa4SStanley.Yang 
39471199aa4SStanley.Yang const struct amdgpu_ip_block_version soc21_common_ip_block =
39571199aa4SStanley.Yang {
39671199aa4SStanley.Yang 	.type = AMD_IP_BLOCK_TYPE_COMMON,
39771199aa4SStanley.Yang 	.major = 1,
39871199aa4SStanley.Yang 	.minor = 0,
39971199aa4SStanley.Yang 	.rev = 0,
40071199aa4SStanley.Yang 	.funcs = &soc21_common_ip_funcs,
40171199aa4SStanley.Yang };
40271199aa4SStanley.Yang 
40371199aa4SStanley.Yang static uint32_t soc21_get_rev_id(struct amdgpu_device *adev)
40471199aa4SStanley.Yang {
40571199aa4SStanley.Yang 	return adev->nbio.funcs->get_rev_id(adev);
40671199aa4SStanley.Yang }
40771199aa4SStanley.Yang 
40871199aa4SStanley.Yang static bool soc21_need_full_reset(struct amdgpu_device *adev)
40971199aa4SStanley.Yang {
41071199aa4SStanley.Yang 	return true;
41171199aa4SStanley.Yang }
41271199aa4SStanley.Yang 
41371199aa4SStanley.Yang static bool soc21_need_reset_on_init(struct amdgpu_device *adev)
41471199aa4SStanley.Yang {
41571199aa4SStanley.Yang 	u32 sol_reg;
41671199aa4SStanley.Yang 
41771199aa4SStanley.Yang 	if (adev->flags & AMD_IS_APU)
41871199aa4SStanley.Yang 		return false;
41971199aa4SStanley.Yang 
42071199aa4SStanley.Yang 	/* Check sOS sign of life register to confirm sys driver and sOS
42171199aa4SStanley.Yang 	 * are already been loaded.
42271199aa4SStanley.Yang 	 */
42371199aa4SStanley.Yang 	sol_reg = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);
42471199aa4SStanley.Yang 	if (sol_reg)
42571199aa4SStanley.Yang 		return true;
42671199aa4SStanley.Yang 
42771199aa4SStanley.Yang 	return false;
42871199aa4SStanley.Yang }
42971199aa4SStanley.Yang 
43071199aa4SStanley.Yang static uint64_t soc21_get_pcie_replay_count(struct amdgpu_device *adev)
43171199aa4SStanley.Yang {
43271199aa4SStanley.Yang 
43371199aa4SStanley.Yang 	/* TODO
43471199aa4SStanley.Yang 	 * dummy implement for pcie_replay_count sysfs interface
43571199aa4SStanley.Yang 	 * */
43671199aa4SStanley.Yang 
43771199aa4SStanley.Yang 	return 0;
43871199aa4SStanley.Yang }
43971199aa4SStanley.Yang 
44071199aa4SStanley.Yang static void soc21_init_doorbell_index(struct amdgpu_device *adev)
44171199aa4SStanley.Yang {
44271199aa4SStanley.Yang 	adev->doorbell_index.kiq = AMDGPU_NAVI10_DOORBELL_KIQ;
44371199aa4SStanley.Yang 	adev->doorbell_index.mec_ring0 = AMDGPU_NAVI10_DOORBELL_MEC_RING0;
44471199aa4SStanley.Yang 	adev->doorbell_index.mec_ring1 = AMDGPU_NAVI10_DOORBELL_MEC_RING1;
44571199aa4SStanley.Yang 	adev->doorbell_index.mec_ring2 = AMDGPU_NAVI10_DOORBELL_MEC_RING2;
44671199aa4SStanley.Yang 	adev->doorbell_index.mec_ring3 = AMDGPU_NAVI10_DOORBELL_MEC_RING3;
44771199aa4SStanley.Yang 	adev->doorbell_index.mec_ring4 = AMDGPU_NAVI10_DOORBELL_MEC_RING4;
44871199aa4SStanley.Yang 	adev->doorbell_index.mec_ring5 = AMDGPU_NAVI10_DOORBELL_MEC_RING5;
44971199aa4SStanley.Yang 	adev->doorbell_index.mec_ring6 = AMDGPU_NAVI10_DOORBELL_MEC_RING6;
45071199aa4SStanley.Yang 	adev->doorbell_index.mec_ring7 = AMDGPU_NAVI10_DOORBELL_MEC_RING7;
45171199aa4SStanley.Yang 	adev->doorbell_index.userqueue_start = AMDGPU_NAVI10_DOORBELL_USERQUEUE_START;
45271199aa4SStanley.Yang 	adev->doorbell_index.userqueue_end = AMDGPU_NAVI10_DOORBELL_USERQUEUE_END;
45371199aa4SStanley.Yang 	adev->doorbell_index.gfx_ring0 = AMDGPU_NAVI10_DOORBELL_GFX_RING0;
45471199aa4SStanley.Yang 	adev->doorbell_index.gfx_ring1 = AMDGPU_NAVI10_DOORBELL_GFX_RING1;
455fd0ed91aSJack Xiao 	adev->doorbell_index.gfx_userqueue_start =
456fd0ed91aSJack Xiao 		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_START;
457fd0ed91aSJack Xiao 	adev->doorbell_index.gfx_userqueue_end =
458fd0ed91aSJack Xiao 		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_END;
459b608e785SJack Xiao 	adev->doorbell_index.mes_ring0 = AMDGPU_NAVI10_DOORBELL_MES_RING0;
460b608e785SJack Xiao 	adev->doorbell_index.mes_ring1 = AMDGPU_NAVI10_DOORBELL_MES_RING1;
46171199aa4SStanley.Yang 	adev->doorbell_index.sdma_engine[0] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0;
46271199aa4SStanley.Yang 	adev->doorbell_index.sdma_engine[1] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1;
46371199aa4SStanley.Yang 	adev->doorbell_index.ih = AMDGPU_NAVI10_DOORBELL_IH;
46471199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_NAVI10_DOORBELL64_VCN0_1;
46571199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_NAVI10_DOORBELL64_VCN2_3;
46671199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_NAVI10_DOORBELL64_VCN4_5;
46771199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_NAVI10_DOORBELL64_VCN6_7;
46871199aa4SStanley.Yang 	adev->doorbell_index.first_non_cp = AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP;
46971199aa4SStanley.Yang 	adev->doorbell_index.last_non_cp = AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP;
47071199aa4SStanley.Yang 
47171199aa4SStanley.Yang 	adev->doorbell_index.max_assignment = AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT << 1;
47271199aa4SStanley.Yang 	adev->doorbell_index.sdma_doorbell_range = 20;
47371199aa4SStanley.Yang }
47471199aa4SStanley.Yang 
47571199aa4SStanley.Yang static void soc21_pre_asic_init(struct amdgpu_device *adev)
47671199aa4SStanley.Yang {
47771199aa4SStanley.Yang }
47871199aa4SStanley.Yang 
47971199aa4SStanley.Yang static const struct amdgpu_asic_funcs soc21_asic_funcs =
48071199aa4SStanley.Yang {
48171199aa4SStanley.Yang 	.read_disabled_bios = &soc21_read_disabled_bios,
48271199aa4SStanley.Yang 	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
48371199aa4SStanley.Yang 	.read_register = &soc21_read_register,
48471199aa4SStanley.Yang 	.reset = &soc21_asic_reset,
48571199aa4SStanley.Yang 	.reset_method = &soc21_asic_reset_method,
48671199aa4SStanley.Yang 	.set_vga_state = &soc21_vga_set_state,
48771199aa4SStanley.Yang 	.get_xclk = &soc21_get_xclk,
48871199aa4SStanley.Yang 	.set_uvd_clocks = &soc21_set_uvd_clocks,
48971199aa4SStanley.Yang 	.set_vce_clocks = &soc21_set_vce_clocks,
49071199aa4SStanley.Yang 	.get_config_memsize = &soc21_get_config_memsize,
49171199aa4SStanley.Yang 	.init_doorbell_index = &soc21_init_doorbell_index,
49271199aa4SStanley.Yang 	.need_full_reset = &soc21_need_full_reset,
49371199aa4SStanley.Yang 	.need_reset_on_init = &soc21_need_reset_on_init,
49471199aa4SStanley.Yang 	.get_pcie_replay_count = &soc21_get_pcie_replay_count,
49571199aa4SStanley.Yang 	.supports_baco = &amdgpu_dpm_is_baco_supported,
49671199aa4SStanley.Yang 	.pre_asic_init = &soc21_pre_asic_init,
4979ac0edaaSJames Zhu 	.query_video_codecs = &soc21_query_video_codecs,
49871199aa4SStanley.Yang };
49971199aa4SStanley.Yang 
50071199aa4SStanley.Yang static int soc21_common_early_init(void *handle)
50171199aa4SStanley.Yang {
50271199aa4SStanley.Yang #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
50371199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
50471199aa4SStanley.Yang 
50571199aa4SStanley.Yang 	adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
50671199aa4SStanley.Yang 	adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
50771199aa4SStanley.Yang 	adev->smc_rreg = NULL;
50871199aa4SStanley.Yang 	adev->smc_wreg = NULL;
50971199aa4SStanley.Yang 	adev->pcie_rreg = &soc21_pcie_rreg;
51071199aa4SStanley.Yang 	adev->pcie_wreg = &soc21_pcie_wreg;
51171199aa4SStanley.Yang 	adev->pcie_rreg64 = &soc21_pcie_rreg64;
51271199aa4SStanley.Yang 	adev->pcie_wreg64 = &soc21_pcie_wreg64;
51371199aa4SStanley.Yang 
51471199aa4SStanley.Yang 	/* TODO: will add them during VCN v2 implementation */
51571199aa4SStanley.Yang 	adev->uvd_ctx_rreg = NULL;
51671199aa4SStanley.Yang 	adev->uvd_ctx_wreg = NULL;
51771199aa4SStanley.Yang 
51871199aa4SStanley.Yang 	adev->didt_rreg = &soc21_didt_rreg;
51971199aa4SStanley.Yang 	adev->didt_wreg = &soc21_didt_wreg;
52071199aa4SStanley.Yang 
52171199aa4SStanley.Yang 	adev->asic_funcs = &soc21_asic_funcs;
52271199aa4SStanley.Yang 
52371199aa4SStanley.Yang 	adev->rev_id = soc21_get_rev_id(adev);
52471199aa4SStanley.Yang 	adev->external_rev_id = 0xff;
52571199aa4SStanley.Yang 	switch (adev->ip_versions[GC_HWIP][0]) {
52671199aa4SStanley.Yang 	case IP_VERSION(11, 0, 0):
527390db4b8SEvan Quan 		adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG |
528b21348a2SEvan Quan 			AMD_CG_SUPPORT_GFX_CGLS |
529915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_3D_CGCG |
530915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_3D_CGLS |
531915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_MGCG |
5328b719b96SLeo Liu 			AMD_CG_SUPPORT_REPEATER_FGCG |
533915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_FGCG |
534915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_PERF_CLK |
5357c507d35SJames Zhu 			AMD_CG_SUPPORT_VCN_MGCG |
536c649ed05SEvan Quan 			AMD_CG_SUPPORT_JPEG_MGCG |
537c649ed05SEvan Quan 			AMD_CG_SUPPORT_ATHUB_MGCG |
5387ccf6eb0SEvan Quan 			AMD_CG_SUPPORT_ATHUB_LS |
5397ccf6eb0SEvan Quan 			AMD_CG_SUPPORT_MC_MGCG |
54020139069SEvan Quan 			AMD_CG_SUPPORT_MC_LS |
541d386f645SEvan Quan 			AMD_CG_SUPPORT_IH_CG |
542d386f645SEvan Quan 			AMD_CG_SUPPORT_HDP_SD;
5438b719b96SLeo Liu 		adev->pg_flags = AMD_PG_SUPPORT_VCN |
54404270390SJames Zhu 			AMD_PG_SUPPORT_VCN_DPG |
5457c507d35SJames Zhu 			AMD_PG_SUPPORT_JPEG |
5468b719b96SLeo Liu 			AMD_PG_SUPPORT_ATHUB |
547a6dec868SEvan Quan 			AMD_PG_SUPPORT_MMHUB;
54871199aa4SStanley.Yang 		adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
54971199aa4SStanley.Yang 		break;
55092fd2153SFlora Cui 	case IP_VERSION(11, 0, 2):
55171dae221SJames Zhu 		adev->cg_flags =
55271dae221SJames Zhu 			AMD_CG_SUPPORT_JPEG_MGCG;
553*ebac66a3SJames Zhu 		adev->pg_flags =
554*ebac66a3SJames Zhu 			AMD_PG_SUPPORT_JPEG;
55592fd2153SFlora Cui 		adev->external_rev_id = adev->rev_id + 0x10;
55692fd2153SFlora Cui 		break;
55771199aa4SStanley.Yang 	default:
55871199aa4SStanley.Yang 		/* FIXME: not supported yet */
55971199aa4SStanley.Yang 		return -EINVAL;
56071199aa4SStanley.Yang 	}
56171199aa4SStanley.Yang 
56271199aa4SStanley.Yang 	return 0;
56371199aa4SStanley.Yang }
56471199aa4SStanley.Yang 
56571199aa4SStanley.Yang static int soc21_common_late_init(void *handle)
56671199aa4SStanley.Yang {
56771199aa4SStanley.Yang 	return 0;
56871199aa4SStanley.Yang }
56971199aa4SStanley.Yang 
57071199aa4SStanley.Yang static int soc21_common_sw_init(void *handle)
57171199aa4SStanley.Yang {
57271199aa4SStanley.Yang 	return 0;
57371199aa4SStanley.Yang }
57471199aa4SStanley.Yang 
57571199aa4SStanley.Yang static int soc21_common_sw_fini(void *handle)
57671199aa4SStanley.Yang {
57771199aa4SStanley.Yang 	return 0;
57871199aa4SStanley.Yang }
57971199aa4SStanley.Yang 
58071199aa4SStanley.Yang static int soc21_common_hw_init(void *handle)
58171199aa4SStanley.Yang {
58271199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
58371199aa4SStanley.Yang 
58471199aa4SStanley.Yang 	/* enable pcie gen2/3 link */
58571199aa4SStanley.Yang 	soc21_pcie_gen3_enable(adev);
58671199aa4SStanley.Yang 	/* enable aspm */
58771199aa4SStanley.Yang 	soc21_program_aspm(adev);
58871199aa4SStanley.Yang 	/* setup nbio registers */
58971199aa4SStanley.Yang 	adev->nbio.funcs->init_registers(adev);
59071199aa4SStanley.Yang 	/* remap HDP registers to a hole in mmio space,
59171199aa4SStanley.Yang 	 * for the purpose of expose those registers
59271199aa4SStanley.Yang 	 * to process space
59371199aa4SStanley.Yang 	 */
59471199aa4SStanley.Yang 	if (adev->nbio.funcs->remap_hdp_registers)
59571199aa4SStanley.Yang 		adev->nbio.funcs->remap_hdp_registers(adev);
59671199aa4SStanley.Yang 	/* enable the doorbell aperture */
59771199aa4SStanley.Yang 	soc21_enable_doorbell_aperture(adev, true);
59871199aa4SStanley.Yang 
59971199aa4SStanley.Yang 	return 0;
60071199aa4SStanley.Yang }
60171199aa4SStanley.Yang 
60271199aa4SStanley.Yang static int soc21_common_hw_fini(void *handle)
60371199aa4SStanley.Yang {
60471199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
60571199aa4SStanley.Yang 
60671199aa4SStanley.Yang 	/* disable the doorbell aperture */
60771199aa4SStanley.Yang 	soc21_enable_doorbell_aperture(adev, false);
60871199aa4SStanley.Yang 
60971199aa4SStanley.Yang 	return 0;
61071199aa4SStanley.Yang }
61171199aa4SStanley.Yang 
61271199aa4SStanley.Yang static int soc21_common_suspend(void *handle)
61371199aa4SStanley.Yang {
61471199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
61571199aa4SStanley.Yang 
61671199aa4SStanley.Yang 	return soc21_common_hw_fini(adev);
61771199aa4SStanley.Yang }
61871199aa4SStanley.Yang 
61971199aa4SStanley.Yang static int soc21_common_resume(void *handle)
62071199aa4SStanley.Yang {
62171199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
62271199aa4SStanley.Yang 
62371199aa4SStanley.Yang 	return soc21_common_hw_init(adev);
62471199aa4SStanley.Yang }
62571199aa4SStanley.Yang 
62671199aa4SStanley.Yang static bool soc21_common_is_idle(void *handle)
62771199aa4SStanley.Yang {
62871199aa4SStanley.Yang 	return true;
62971199aa4SStanley.Yang }
63071199aa4SStanley.Yang 
63171199aa4SStanley.Yang static int soc21_common_wait_for_idle(void *handle)
63271199aa4SStanley.Yang {
63371199aa4SStanley.Yang 	return 0;
63471199aa4SStanley.Yang }
63571199aa4SStanley.Yang 
63671199aa4SStanley.Yang static int soc21_common_soft_reset(void *handle)
63771199aa4SStanley.Yang {
63871199aa4SStanley.Yang 	return 0;
63971199aa4SStanley.Yang }
64071199aa4SStanley.Yang 
64171199aa4SStanley.Yang static int soc21_common_set_clockgating_state(void *handle,
64271199aa4SStanley.Yang 					   enum amd_clockgating_state state)
64371199aa4SStanley.Yang {
64471199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
64571199aa4SStanley.Yang 
64671199aa4SStanley.Yang 	switch (adev->ip_versions[NBIO_HWIP][0]) {
64771199aa4SStanley.Yang 	case IP_VERSION(4, 3, 0):
64871199aa4SStanley.Yang 		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
64971199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
65071199aa4SStanley.Yang 		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
65171199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
65271199aa4SStanley.Yang 		adev->hdp.funcs->update_clock_gating(adev,
65371199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
65471199aa4SStanley.Yang 		break;
65571199aa4SStanley.Yang 	default:
65671199aa4SStanley.Yang 		break;
65771199aa4SStanley.Yang 	}
65871199aa4SStanley.Yang 	return 0;
65971199aa4SStanley.Yang }
66071199aa4SStanley.Yang 
66171199aa4SStanley.Yang static int soc21_common_set_powergating_state(void *handle,
66271199aa4SStanley.Yang 					   enum amd_powergating_state state)
66371199aa4SStanley.Yang {
66471199aa4SStanley.Yang 	/* TODO */
66571199aa4SStanley.Yang 	return 0;
66671199aa4SStanley.Yang }
66771199aa4SStanley.Yang 
66871199aa4SStanley.Yang static void soc21_common_get_clockgating_state(void *handle, u64 *flags)
66971199aa4SStanley.Yang {
67071199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
67171199aa4SStanley.Yang 
67271199aa4SStanley.Yang 	adev->nbio.funcs->get_clockgating_state(adev, flags);
67371199aa4SStanley.Yang 
67471199aa4SStanley.Yang 	adev->hdp.funcs->get_clock_gating_state(adev, flags);
67571199aa4SStanley.Yang 
67671199aa4SStanley.Yang 	return;
67771199aa4SStanley.Yang }
67871199aa4SStanley.Yang 
67971199aa4SStanley.Yang static const struct amd_ip_funcs soc21_common_ip_funcs = {
68071199aa4SStanley.Yang 	.name = "soc21_common",
68171199aa4SStanley.Yang 	.early_init = soc21_common_early_init,
68271199aa4SStanley.Yang 	.late_init = soc21_common_late_init,
68371199aa4SStanley.Yang 	.sw_init = soc21_common_sw_init,
68471199aa4SStanley.Yang 	.sw_fini = soc21_common_sw_fini,
68571199aa4SStanley.Yang 	.hw_init = soc21_common_hw_init,
68671199aa4SStanley.Yang 	.hw_fini = soc21_common_hw_fini,
68771199aa4SStanley.Yang 	.suspend = soc21_common_suspend,
68871199aa4SStanley.Yang 	.resume = soc21_common_resume,
68971199aa4SStanley.Yang 	.is_idle = soc21_common_is_idle,
69071199aa4SStanley.Yang 	.wait_for_idle = soc21_common_wait_for_idle,
69171199aa4SStanley.Yang 	.soft_reset = soc21_common_soft_reset,
69271199aa4SStanley.Yang 	.set_clockgating_state = soc21_common_set_clockgating_state,
69371199aa4SStanley.Yang 	.set_powergating_state = soc21_common_set_powergating_state,
69471199aa4SStanley.Yang 	.get_clockgating_state = soc21_common_get_clockgating_state,
69571199aa4SStanley.Yang };
696