xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/soc21.c (revision 18ad1885)
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):
831c0a9036SSonny Jiang 	case IP_VERSION(4, 0, 2):
849ac0edaaSJames Zhu 		if (encode)
859ac0edaaSJames Zhu 			*codecs = &vcn_4_0_0_video_codecs_encode;
869ac0edaaSJames Zhu 		else
879ac0edaaSJames Zhu 			*codecs = &vcn_4_0_0_video_codecs_decode;
889ac0edaaSJames Zhu 		return 0;
899ac0edaaSJames Zhu 	default:
909ac0edaaSJames Zhu 		return -EINVAL;
919ac0edaaSJames Zhu 	}
929ac0edaaSJames Zhu }
9371199aa4SStanley.Yang /*
9471199aa4SStanley.Yang  * Indirect registers accessor
9571199aa4SStanley.Yang  */
9671199aa4SStanley.Yang static u32 soc21_pcie_rreg(struct amdgpu_device *adev, u32 reg)
9771199aa4SStanley.Yang {
9871199aa4SStanley.Yang 	unsigned long address, data;
9971199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
10071199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
10171199aa4SStanley.Yang 
10271199aa4SStanley.Yang 	return amdgpu_device_indirect_rreg(adev, address, data, reg);
10371199aa4SStanley.Yang }
10471199aa4SStanley.Yang 
10571199aa4SStanley.Yang static void soc21_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
10671199aa4SStanley.Yang {
10771199aa4SStanley.Yang 	unsigned long address, data;
10871199aa4SStanley.Yang 
10971199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
11071199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
11171199aa4SStanley.Yang 
11271199aa4SStanley.Yang 	amdgpu_device_indirect_wreg(adev, address, data, reg, v);
11371199aa4SStanley.Yang }
11471199aa4SStanley.Yang 
11571199aa4SStanley.Yang static u64 soc21_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
11671199aa4SStanley.Yang {
11771199aa4SStanley.Yang 	unsigned long address, data;
11871199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
11971199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
12071199aa4SStanley.Yang 
12171199aa4SStanley.Yang 	return amdgpu_device_indirect_rreg64(adev, address, data, reg);
12271199aa4SStanley.Yang }
12371199aa4SStanley.Yang 
12471199aa4SStanley.Yang static void soc21_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
12571199aa4SStanley.Yang {
12671199aa4SStanley.Yang 	unsigned long address, data;
12771199aa4SStanley.Yang 
12871199aa4SStanley.Yang 	address = adev->nbio.funcs->get_pcie_index_offset(adev);
12971199aa4SStanley.Yang 	data = adev->nbio.funcs->get_pcie_data_offset(adev);
13071199aa4SStanley.Yang 
13171199aa4SStanley.Yang 	amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
13271199aa4SStanley.Yang }
13371199aa4SStanley.Yang 
13471199aa4SStanley.Yang static u32 soc21_didt_rreg(struct amdgpu_device *adev, u32 reg)
13571199aa4SStanley.Yang {
13671199aa4SStanley.Yang 	unsigned long flags, address, data;
13771199aa4SStanley.Yang 	u32 r;
13871199aa4SStanley.Yang 
13971199aa4SStanley.Yang 	address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
14071199aa4SStanley.Yang 	data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
14171199aa4SStanley.Yang 
14271199aa4SStanley.Yang 	spin_lock_irqsave(&adev->didt_idx_lock, flags);
14371199aa4SStanley.Yang 	WREG32(address, (reg));
14471199aa4SStanley.Yang 	r = RREG32(data);
14571199aa4SStanley.Yang 	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
14671199aa4SStanley.Yang 	return r;
14771199aa4SStanley.Yang }
14871199aa4SStanley.Yang 
14971199aa4SStanley.Yang static void soc21_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
15071199aa4SStanley.Yang {
15171199aa4SStanley.Yang 	unsigned long flags, address, data;
15271199aa4SStanley.Yang 
15371199aa4SStanley.Yang 	address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX);
15471199aa4SStanley.Yang 	data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA);
15571199aa4SStanley.Yang 
15671199aa4SStanley.Yang 	spin_lock_irqsave(&adev->didt_idx_lock, flags);
15771199aa4SStanley.Yang 	WREG32(address, (reg));
15871199aa4SStanley.Yang 	WREG32(data, (v));
15971199aa4SStanley.Yang 	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
16071199aa4SStanley.Yang }
16171199aa4SStanley.Yang 
16271199aa4SStanley.Yang static u32 soc21_get_config_memsize(struct amdgpu_device *adev)
16371199aa4SStanley.Yang {
16471199aa4SStanley.Yang 	return adev->nbio.funcs->get_memsize(adev);
16571199aa4SStanley.Yang }
16671199aa4SStanley.Yang 
16771199aa4SStanley.Yang static u32 soc21_get_xclk(struct amdgpu_device *adev)
16871199aa4SStanley.Yang {
16971199aa4SStanley.Yang 	return adev->clock.spll.reference_freq;
17071199aa4SStanley.Yang }
17171199aa4SStanley.Yang 
17271199aa4SStanley.Yang 
17371199aa4SStanley.Yang void soc21_grbm_select(struct amdgpu_device *adev,
17471199aa4SStanley.Yang 		     u32 me, u32 pipe, u32 queue, u32 vmid)
17571199aa4SStanley.Yang {
17671199aa4SStanley.Yang 	u32 grbm_gfx_cntl = 0;
17771199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe);
17871199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me);
17971199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
18071199aa4SStanley.Yang 	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
18171199aa4SStanley.Yang 
182bbb860d4SYifan Zha 	WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, grbm_gfx_cntl);
18371199aa4SStanley.Yang }
18471199aa4SStanley.Yang 
18571199aa4SStanley.Yang static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
18671199aa4SStanley.Yang {
18771199aa4SStanley.Yang 	/* todo */
18871199aa4SStanley.Yang }
18971199aa4SStanley.Yang 
19071199aa4SStanley.Yang static bool soc21_read_disabled_bios(struct amdgpu_device *adev)
19171199aa4SStanley.Yang {
19271199aa4SStanley.Yang 	/* todo */
19371199aa4SStanley.Yang 	return false;
19471199aa4SStanley.Yang }
19571199aa4SStanley.Yang 
19671199aa4SStanley.Yang static struct soc15_allowed_register_entry soc21_allowed_read_registers[] = {
19771199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS)},
19871199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS2)},
19971199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE0)},
20071199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE1)},
20171199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE2)},
20271199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE3)},
20371199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(SDMA0, 0, regSDMA0_STATUS_REG)},
20471199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(SDMA1, 0, regSDMA1_STATUS_REG)},
20571199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STAT)},
20671199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT1)},
20771199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT2)},
20871199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT3)},
20971199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_BUSY_STAT)},
21071199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_STALLED_STAT1)},
21171199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPF_STATUS)},
21271199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_BUSY_STAT)},
21371199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_STALLED_STAT1)},
21471199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regCP_CPC_STATUS)},
21571199aa4SStanley.Yang 	{ SOC15_REG_ENTRY(GC, 0, regGB_ADDR_CONFIG)},
21671199aa4SStanley.Yang };
21771199aa4SStanley.Yang 
21871199aa4SStanley.Yang static uint32_t soc21_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
21971199aa4SStanley.Yang 					 u32 sh_num, u32 reg_offset)
22071199aa4SStanley.Yang {
22171199aa4SStanley.Yang 	uint32_t val;
22271199aa4SStanley.Yang 
22371199aa4SStanley.Yang 	mutex_lock(&adev->grbm_idx_mutex);
22471199aa4SStanley.Yang 	if (se_num != 0xffffffff || sh_num != 0xffffffff)
22571199aa4SStanley.Yang 		amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff);
22671199aa4SStanley.Yang 
22771199aa4SStanley.Yang 	val = RREG32(reg_offset);
22871199aa4SStanley.Yang 
22971199aa4SStanley.Yang 	if (se_num != 0xffffffff || sh_num != 0xffffffff)
23071199aa4SStanley.Yang 		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
23171199aa4SStanley.Yang 	mutex_unlock(&adev->grbm_idx_mutex);
23271199aa4SStanley.Yang 	return val;
23371199aa4SStanley.Yang }
23471199aa4SStanley.Yang 
23571199aa4SStanley.Yang static uint32_t soc21_get_register_value(struct amdgpu_device *adev,
23671199aa4SStanley.Yang 				      bool indexed, u32 se_num,
23771199aa4SStanley.Yang 				      u32 sh_num, u32 reg_offset)
23871199aa4SStanley.Yang {
23971199aa4SStanley.Yang 	if (indexed) {
24071199aa4SStanley.Yang 		return soc21_read_indexed_register(adev, se_num, sh_num, reg_offset);
24171199aa4SStanley.Yang 	} else {
24271199aa4SStanley.Yang 		if (reg_offset == SOC15_REG_OFFSET(GC, 0, regGB_ADDR_CONFIG) && adev->gfx.config.gb_addr_config)
24371199aa4SStanley.Yang 			return adev->gfx.config.gb_addr_config;
24471199aa4SStanley.Yang 		return RREG32(reg_offset);
24571199aa4SStanley.Yang 	}
24671199aa4SStanley.Yang }
24771199aa4SStanley.Yang 
24871199aa4SStanley.Yang static int soc21_read_register(struct amdgpu_device *adev, u32 se_num,
24971199aa4SStanley.Yang 			    u32 sh_num, u32 reg_offset, u32 *value)
25071199aa4SStanley.Yang {
25171199aa4SStanley.Yang 	uint32_t i;
25271199aa4SStanley.Yang 	struct soc15_allowed_register_entry  *en;
25371199aa4SStanley.Yang 
25471199aa4SStanley.Yang 	*value = 0;
25571199aa4SStanley.Yang 	for (i = 0; i < ARRAY_SIZE(soc21_allowed_read_registers); i++) {
25671199aa4SStanley.Yang 		en = &soc21_allowed_read_registers[i];
257bf1781e1SAlex Deucher 		if (adev->reg_offset[en->hwip][en->inst] &&
258bf1781e1SAlex Deucher 		    reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
259bf1781e1SAlex Deucher 				   + en->reg_offset))
26071199aa4SStanley.Yang 			continue;
26171199aa4SStanley.Yang 
26271199aa4SStanley.Yang 		*value = soc21_get_register_value(adev,
26371199aa4SStanley.Yang 					       soc21_allowed_read_registers[i].grbm_indexed,
26471199aa4SStanley.Yang 					       se_num, sh_num, reg_offset);
26571199aa4SStanley.Yang 		return 0;
26671199aa4SStanley.Yang 	}
26771199aa4SStanley.Yang 	return -EINVAL;
26871199aa4SStanley.Yang }
26971199aa4SStanley.Yang 
27071199aa4SStanley.Yang #if 0
27171199aa4SStanley.Yang static int soc21_asic_mode1_reset(struct amdgpu_device *adev)
27271199aa4SStanley.Yang {
27371199aa4SStanley.Yang 	u32 i;
27471199aa4SStanley.Yang 	int ret = 0;
27571199aa4SStanley.Yang 
27671199aa4SStanley.Yang 	amdgpu_atombios_scratch_regs_engine_hung(adev, true);
27771199aa4SStanley.Yang 
27871199aa4SStanley.Yang 	/* disable BM */
27971199aa4SStanley.Yang 	pci_clear_master(adev->pdev);
28071199aa4SStanley.Yang 
28171199aa4SStanley.Yang 	amdgpu_device_cache_pci_state(adev->pdev);
28271199aa4SStanley.Yang 
28371199aa4SStanley.Yang 	if (amdgpu_dpm_is_mode1_reset_supported(adev)) {
28471199aa4SStanley.Yang 		dev_info(adev->dev, "GPU smu mode1 reset\n");
28571199aa4SStanley.Yang 		ret = amdgpu_dpm_mode1_reset(adev);
28671199aa4SStanley.Yang 	} else {
28771199aa4SStanley.Yang 		dev_info(adev->dev, "GPU psp mode1 reset\n");
28871199aa4SStanley.Yang 		ret = psp_gpu_reset(adev);
28971199aa4SStanley.Yang 	}
29071199aa4SStanley.Yang 
29171199aa4SStanley.Yang 	if (ret)
29271199aa4SStanley.Yang 		dev_err(adev->dev, "GPU mode1 reset failed\n");
29371199aa4SStanley.Yang 	amdgpu_device_load_pci_state(adev->pdev);
29471199aa4SStanley.Yang 
29571199aa4SStanley.Yang 	/* wait for asic to come out of reset */
29671199aa4SStanley.Yang 	for (i = 0; i < adev->usec_timeout; i++) {
29771199aa4SStanley.Yang 		u32 memsize = adev->nbio.funcs->get_memsize(adev);
29871199aa4SStanley.Yang 
29971199aa4SStanley.Yang 		if (memsize != 0xffffffff)
30071199aa4SStanley.Yang 			break;
30171199aa4SStanley.Yang 		udelay(1);
30271199aa4SStanley.Yang 	}
30371199aa4SStanley.Yang 
30471199aa4SStanley.Yang 	amdgpu_atombios_scratch_regs_engine_hung(adev, false);
30571199aa4SStanley.Yang 
30671199aa4SStanley.Yang 	return ret;
30771199aa4SStanley.Yang }
30871199aa4SStanley.Yang #endif
30971199aa4SStanley.Yang 
31071199aa4SStanley.Yang static enum amd_reset_method
31171199aa4SStanley.Yang soc21_asic_reset_method(struct amdgpu_device *adev)
31271199aa4SStanley.Yang {
31371199aa4SStanley.Yang 	if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 ||
314ea64228dSAlex Deucher 	    amdgpu_reset_method == AMD_RESET_METHOD_MODE2 ||
31571199aa4SStanley.Yang 	    amdgpu_reset_method == AMD_RESET_METHOD_BACO)
31671199aa4SStanley.Yang 		return amdgpu_reset_method;
31771199aa4SStanley.Yang 
31871199aa4SStanley.Yang 	if (amdgpu_reset_method != -1)
31971199aa4SStanley.Yang 		dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n",
32071199aa4SStanley.Yang 				  amdgpu_reset_method);
32171199aa4SStanley.Yang 
32271199aa4SStanley.Yang 	switch (adev->ip_versions[MP1_HWIP][0]) {
32371199aa4SStanley.Yang 	case IP_VERSION(13, 0, 0):
324a53bc321SKenneth Feng 	case IP_VERSION(13, 0, 7):
32560cfad32SKenneth Feng 	case IP_VERSION(13, 0, 10):
32671199aa4SStanley.Yang 		return AMD_RESET_METHOD_MODE1;
327ea64228dSAlex Deucher 	case IP_VERSION(13, 0, 4):
328*18ad1885STim Huang 	case IP_VERSION(13, 0, 11):
329ea64228dSAlex Deucher 		return AMD_RESET_METHOD_MODE2;
33071199aa4SStanley.Yang 	default:
33171199aa4SStanley.Yang 		if (amdgpu_dpm_is_baco_supported(adev))
33271199aa4SStanley.Yang 			return AMD_RESET_METHOD_BACO;
33371199aa4SStanley.Yang 		else
33471199aa4SStanley.Yang 			return AMD_RESET_METHOD_MODE1;
33571199aa4SStanley.Yang 	}
33671199aa4SStanley.Yang }
33771199aa4SStanley.Yang 
33871199aa4SStanley.Yang static int soc21_asic_reset(struct amdgpu_device *adev)
33971199aa4SStanley.Yang {
34071199aa4SStanley.Yang 	int ret = 0;
34171199aa4SStanley.Yang 
34271199aa4SStanley.Yang 	switch (soc21_asic_reset_method(adev)) {
34371199aa4SStanley.Yang 	case AMD_RESET_METHOD_PCI:
34471199aa4SStanley.Yang 		dev_info(adev->dev, "PCI reset\n");
34571199aa4SStanley.Yang 		ret = amdgpu_device_pci_reset(adev);
34671199aa4SStanley.Yang 		break;
34771199aa4SStanley.Yang 	case AMD_RESET_METHOD_BACO:
34871199aa4SStanley.Yang 		dev_info(adev->dev, "BACO reset\n");
34971199aa4SStanley.Yang 		ret = amdgpu_dpm_baco_reset(adev);
35071199aa4SStanley.Yang 		break;
351ea64228dSAlex Deucher 	case AMD_RESET_METHOD_MODE2:
352ea64228dSAlex Deucher 		dev_info(adev->dev, "MODE2 reset\n");
353ea64228dSAlex Deucher 		ret = amdgpu_dpm_mode2_reset(adev);
354ea64228dSAlex Deucher 		break;
35571199aa4SStanley.Yang 	default:
35671199aa4SStanley.Yang 		dev_info(adev->dev, "MODE1 reset\n");
35771199aa4SStanley.Yang 		ret = amdgpu_device_mode1_reset(adev);
35871199aa4SStanley.Yang 		break;
35971199aa4SStanley.Yang 	}
36071199aa4SStanley.Yang 
36171199aa4SStanley.Yang 	return ret;
36271199aa4SStanley.Yang }
36371199aa4SStanley.Yang 
36471199aa4SStanley.Yang static int soc21_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
36571199aa4SStanley.Yang {
36671199aa4SStanley.Yang 	/* todo */
36771199aa4SStanley.Yang 	return 0;
36871199aa4SStanley.Yang }
36971199aa4SStanley.Yang 
37071199aa4SStanley.Yang static int soc21_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
37171199aa4SStanley.Yang {
37271199aa4SStanley.Yang 	/* todo */
37371199aa4SStanley.Yang 	return 0;
37471199aa4SStanley.Yang }
37571199aa4SStanley.Yang 
37671199aa4SStanley.Yang static void soc21_pcie_gen3_enable(struct amdgpu_device *adev)
37771199aa4SStanley.Yang {
37871199aa4SStanley.Yang 	if (pci_is_root_bus(adev->pdev->bus))
37971199aa4SStanley.Yang 		return;
38071199aa4SStanley.Yang 
38171199aa4SStanley.Yang 	if (amdgpu_pcie_gen2 == 0)
38271199aa4SStanley.Yang 		return;
38371199aa4SStanley.Yang 
38471199aa4SStanley.Yang 	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
38571199aa4SStanley.Yang 					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
38671199aa4SStanley.Yang 		return;
38771199aa4SStanley.Yang 
38871199aa4SStanley.Yang 	/* todo */
38971199aa4SStanley.Yang }
39071199aa4SStanley.Yang 
39171199aa4SStanley.Yang static void soc21_program_aspm(struct amdgpu_device *adev)
39271199aa4SStanley.Yang {
39362f8f5c3SEvan Quan 	if (!amdgpu_device_should_use_aspm(adev))
39471199aa4SStanley.Yang 		return;
39571199aa4SStanley.Yang 
39662f8f5c3SEvan Quan 	if (!(adev->flags & AMD_IS_APU) &&
39762f8f5c3SEvan Quan 	    (adev->nbio.funcs->program_aspm))
39862f8f5c3SEvan Quan 		adev->nbio.funcs->program_aspm(adev);
39971199aa4SStanley.Yang }
40071199aa4SStanley.Yang 
40171199aa4SStanley.Yang static void soc21_enable_doorbell_aperture(struct amdgpu_device *adev,
40271199aa4SStanley.Yang 					bool enable)
40371199aa4SStanley.Yang {
40471199aa4SStanley.Yang 	adev->nbio.funcs->enable_doorbell_aperture(adev, enable);
40571199aa4SStanley.Yang 	adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable);
40671199aa4SStanley.Yang }
40771199aa4SStanley.Yang 
40871199aa4SStanley.Yang const struct amdgpu_ip_block_version soc21_common_ip_block =
40971199aa4SStanley.Yang {
41071199aa4SStanley.Yang 	.type = AMD_IP_BLOCK_TYPE_COMMON,
41171199aa4SStanley.Yang 	.major = 1,
41271199aa4SStanley.Yang 	.minor = 0,
41371199aa4SStanley.Yang 	.rev = 0,
41471199aa4SStanley.Yang 	.funcs = &soc21_common_ip_funcs,
41571199aa4SStanley.Yang };
41671199aa4SStanley.Yang 
41771199aa4SStanley.Yang static uint32_t soc21_get_rev_id(struct amdgpu_device *adev)
41871199aa4SStanley.Yang {
41971199aa4SStanley.Yang 	return adev->nbio.funcs->get_rev_id(adev);
42071199aa4SStanley.Yang }
42171199aa4SStanley.Yang 
42271199aa4SStanley.Yang static bool soc21_need_full_reset(struct amdgpu_device *adev)
42371199aa4SStanley.Yang {
424c0ff84cbSLikun Gao 	switch (adev->ip_versions[GC_HWIP][0]) {
425c0ff84cbSLikun Gao 	case IP_VERSION(11, 0, 0):
42634dfca89SCandice Li 		return amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC);
427c0ff84cbSLikun Gao 	case IP_VERSION(11, 0, 2):
4282e26bf1eSYiPeng Chai 	case IP_VERSION(11, 0, 3):
429c0ff84cbSLikun Gao 		return false;
430c0ff84cbSLikun Gao 	default:
43171199aa4SStanley.Yang 		return true;
43271199aa4SStanley.Yang 	}
433c0ff84cbSLikun Gao }
43471199aa4SStanley.Yang 
43571199aa4SStanley.Yang static bool soc21_need_reset_on_init(struct amdgpu_device *adev)
43671199aa4SStanley.Yang {
43771199aa4SStanley.Yang 	u32 sol_reg;
43871199aa4SStanley.Yang 
43971199aa4SStanley.Yang 	if (adev->flags & AMD_IS_APU)
44071199aa4SStanley.Yang 		return false;
44171199aa4SStanley.Yang 
44271199aa4SStanley.Yang 	/* Check sOS sign of life register to confirm sys driver and sOS
44371199aa4SStanley.Yang 	 * are already been loaded.
44471199aa4SStanley.Yang 	 */
44571199aa4SStanley.Yang 	sol_reg = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);
44671199aa4SStanley.Yang 	if (sol_reg)
44771199aa4SStanley.Yang 		return true;
44871199aa4SStanley.Yang 
44971199aa4SStanley.Yang 	return false;
45071199aa4SStanley.Yang }
45171199aa4SStanley.Yang 
45271199aa4SStanley.Yang static uint64_t soc21_get_pcie_replay_count(struct amdgpu_device *adev)
45371199aa4SStanley.Yang {
45471199aa4SStanley.Yang 
45571199aa4SStanley.Yang 	/* TODO
45671199aa4SStanley.Yang 	 * dummy implement for pcie_replay_count sysfs interface
45771199aa4SStanley.Yang 	 * */
45871199aa4SStanley.Yang 
45971199aa4SStanley.Yang 	return 0;
46071199aa4SStanley.Yang }
46171199aa4SStanley.Yang 
46271199aa4SStanley.Yang static void soc21_init_doorbell_index(struct amdgpu_device *adev)
46371199aa4SStanley.Yang {
46471199aa4SStanley.Yang 	adev->doorbell_index.kiq = AMDGPU_NAVI10_DOORBELL_KIQ;
46571199aa4SStanley.Yang 	adev->doorbell_index.mec_ring0 = AMDGPU_NAVI10_DOORBELL_MEC_RING0;
46671199aa4SStanley.Yang 	adev->doorbell_index.mec_ring1 = AMDGPU_NAVI10_DOORBELL_MEC_RING1;
46771199aa4SStanley.Yang 	adev->doorbell_index.mec_ring2 = AMDGPU_NAVI10_DOORBELL_MEC_RING2;
46871199aa4SStanley.Yang 	adev->doorbell_index.mec_ring3 = AMDGPU_NAVI10_DOORBELL_MEC_RING3;
46971199aa4SStanley.Yang 	adev->doorbell_index.mec_ring4 = AMDGPU_NAVI10_DOORBELL_MEC_RING4;
47071199aa4SStanley.Yang 	adev->doorbell_index.mec_ring5 = AMDGPU_NAVI10_DOORBELL_MEC_RING5;
47171199aa4SStanley.Yang 	adev->doorbell_index.mec_ring6 = AMDGPU_NAVI10_DOORBELL_MEC_RING6;
47271199aa4SStanley.Yang 	adev->doorbell_index.mec_ring7 = AMDGPU_NAVI10_DOORBELL_MEC_RING7;
47371199aa4SStanley.Yang 	adev->doorbell_index.userqueue_start = AMDGPU_NAVI10_DOORBELL_USERQUEUE_START;
47471199aa4SStanley.Yang 	adev->doorbell_index.userqueue_end = AMDGPU_NAVI10_DOORBELL_USERQUEUE_END;
47571199aa4SStanley.Yang 	adev->doorbell_index.gfx_ring0 = AMDGPU_NAVI10_DOORBELL_GFX_RING0;
47671199aa4SStanley.Yang 	adev->doorbell_index.gfx_ring1 = AMDGPU_NAVI10_DOORBELL_GFX_RING1;
477fd0ed91aSJack Xiao 	adev->doorbell_index.gfx_userqueue_start =
478fd0ed91aSJack Xiao 		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_START;
479fd0ed91aSJack Xiao 	adev->doorbell_index.gfx_userqueue_end =
480fd0ed91aSJack Xiao 		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_END;
481b608e785SJack Xiao 	adev->doorbell_index.mes_ring0 = AMDGPU_NAVI10_DOORBELL_MES_RING0;
482b608e785SJack Xiao 	adev->doorbell_index.mes_ring1 = AMDGPU_NAVI10_DOORBELL_MES_RING1;
48371199aa4SStanley.Yang 	adev->doorbell_index.sdma_engine[0] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0;
48471199aa4SStanley.Yang 	adev->doorbell_index.sdma_engine[1] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1;
48571199aa4SStanley.Yang 	adev->doorbell_index.ih = AMDGPU_NAVI10_DOORBELL_IH;
48671199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_NAVI10_DOORBELL64_VCN0_1;
48771199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_NAVI10_DOORBELL64_VCN2_3;
48871199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_NAVI10_DOORBELL64_VCN4_5;
48971199aa4SStanley.Yang 	adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_NAVI10_DOORBELL64_VCN6_7;
49071199aa4SStanley.Yang 	adev->doorbell_index.first_non_cp = AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP;
49171199aa4SStanley.Yang 	adev->doorbell_index.last_non_cp = AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP;
49271199aa4SStanley.Yang 
49371199aa4SStanley.Yang 	adev->doorbell_index.max_assignment = AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT << 1;
49471199aa4SStanley.Yang 	adev->doorbell_index.sdma_doorbell_range = 20;
49571199aa4SStanley.Yang }
49671199aa4SStanley.Yang 
49771199aa4SStanley.Yang static void soc21_pre_asic_init(struct amdgpu_device *adev)
49871199aa4SStanley.Yang {
49971199aa4SStanley.Yang }
50071199aa4SStanley.Yang 
50172010239SLikun Gao static int soc21_update_umd_stable_pstate(struct amdgpu_device *adev,
50272010239SLikun Gao 					  bool enter)
50372010239SLikun Gao {
50472010239SLikun Gao 	if (enter)
50572010239SLikun Gao 		amdgpu_gfx_rlc_enter_safe_mode(adev);
50672010239SLikun Gao 	else
50772010239SLikun Gao 		amdgpu_gfx_rlc_exit_safe_mode(adev);
50872010239SLikun Gao 
50972010239SLikun Gao 	if (adev->gfx.funcs->update_perfmon_mgcg)
51072010239SLikun Gao 		adev->gfx.funcs->update_perfmon_mgcg(adev, !enter);
51172010239SLikun Gao 
51272010239SLikun Gao 	return 0;
51372010239SLikun Gao }
51472010239SLikun Gao 
51571199aa4SStanley.Yang static const struct amdgpu_asic_funcs soc21_asic_funcs =
51671199aa4SStanley.Yang {
51771199aa4SStanley.Yang 	.read_disabled_bios = &soc21_read_disabled_bios,
51871199aa4SStanley.Yang 	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
51971199aa4SStanley.Yang 	.read_register = &soc21_read_register,
52071199aa4SStanley.Yang 	.reset = &soc21_asic_reset,
52171199aa4SStanley.Yang 	.reset_method = &soc21_asic_reset_method,
52271199aa4SStanley.Yang 	.set_vga_state = &soc21_vga_set_state,
52371199aa4SStanley.Yang 	.get_xclk = &soc21_get_xclk,
52471199aa4SStanley.Yang 	.set_uvd_clocks = &soc21_set_uvd_clocks,
52571199aa4SStanley.Yang 	.set_vce_clocks = &soc21_set_vce_clocks,
52671199aa4SStanley.Yang 	.get_config_memsize = &soc21_get_config_memsize,
52771199aa4SStanley.Yang 	.init_doorbell_index = &soc21_init_doorbell_index,
52871199aa4SStanley.Yang 	.need_full_reset = &soc21_need_full_reset,
52971199aa4SStanley.Yang 	.need_reset_on_init = &soc21_need_reset_on_init,
53071199aa4SStanley.Yang 	.get_pcie_replay_count = &soc21_get_pcie_replay_count,
53171199aa4SStanley.Yang 	.supports_baco = &amdgpu_dpm_is_baco_supported,
53271199aa4SStanley.Yang 	.pre_asic_init = &soc21_pre_asic_init,
5339ac0edaaSJames Zhu 	.query_video_codecs = &soc21_query_video_codecs,
53472010239SLikun Gao 	.update_umd_stable_pstate = &soc21_update_umd_stable_pstate,
53571199aa4SStanley.Yang };
53671199aa4SStanley.Yang 
53771199aa4SStanley.Yang static int soc21_common_early_init(void *handle)
53871199aa4SStanley.Yang {
53971199aa4SStanley.Yang #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
54071199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
54171199aa4SStanley.Yang 
54271199aa4SStanley.Yang 	adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
54371199aa4SStanley.Yang 	adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
54471199aa4SStanley.Yang 	adev->smc_rreg = NULL;
54571199aa4SStanley.Yang 	adev->smc_wreg = NULL;
54671199aa4SStanley.Yang 	adev->pcie_rreg = &soc21_pcie_rreg;
54771199aa4SStanley.Yang 	adev->pcie_wreg = &soc21_pcie_wreg;
54871199aa4SStanley.Yang 	adev->pcie_rreg64 = &soc21_pcie_rreg64;
54971199aa4SStanley.Yang 	adev->pcie_wreg64 = &soc21_pcie_wreg64;
550bafd6cbeSXiaojian Du 	adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
551bafd6cbeSXiaojian Du 	adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
55271199aa4SStanley.Yang 
55371199aa4SStanley.Yang 	/* TODO: will add them during VCN v2 implementation */
55471199aa4SStanley.Yang 	adev->uvd_ctx_rreg = NULL;
55571199aa4SStanley.Yang 	adev->uvd_ctx_wreg = NULL;
55671199aa4SStanley.Yang 
55771199aa4SStanley.Yang 	adev->didt_rreg = &soc21_didt_rreg;
55871199aa4SStanley.Yang 	adev->didt_wreg = &soc21_didt_wreg;
55971199aa4SStanley.Yang 
56071199aa4SStanley.Yang 	adev->asic_funcs = &soc21_asic_funcs;
56171199aa4SStanley.Yang 
56271199aa4SStanley.Yang 	adev->rev_id = soc21_get_rev_id(adev);
56371199aa4SStanley.Yang 	adev->external_rev_id = 0xff;
56471199aa4SStanley.Yang 	switch (adev->ip_versions[GC_HWIP][0]) {
56571199aa4SStanley.Yang 	case IP_VERSION(11, 0, 0):
566390db4b8SEvan Quan 		adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG |
567b21348a2SEvan Quan 			AMD_CG_SUPPORT_GFX_CGLS |
5681b586595SEvan Quan #if 0
569915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_3D_CGCG |
570915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_3D_CGLS |
5711b586595SEvan Quan #endif
572915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_MGCG |
5738b719b96SLeo Liu 			AMD_CG_SUPPORT_REPEATER_FGCG |
574915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_FGCG |
575915b5ce7SEvan Quan 			AMD_CG_SUPPORT_GFX_PERF_CLK |
5767c507d35SJames Zhu 			AMD_CG_SUPPORT_VCN_MGCG |
577c649ed05SEvan Quan 			AMD_CG_SUPPORT_JPEG_MGCG |
578c649ed05SEvan Quan 			AMD_CG_SUPPORT_ATHUB_MGCG |
5797ccf6eb0SEvan Quan 			AMD_CG_SUPPORT_ATHUB_LS |
5807ccf6eb0SEvan Quan 			AMD_CG_SUPPORT_MC_MGCG |
58120139069SEvan Quan 			AMD_CG_SUPPORT_MC_LS |
582d386f645SEvan Quan 			AMD_CG_SUPPORT_IH_CG |
583d386f645SEvan Quan 			AMD_CG_SUPPORT_HDP_SD;
5848b719b96SLeo Liu 		adev->pg_flags = AMD_PG_SUPPORT_VCN |
58504270390SJames Zhu 			AMD_PG_SUPPORT_VCN_DPG |
5867c507d35SJames Zhu 			AMD_PG_SUPPORT_JPEG |
5878b719b96SLeo Liu 			AMD_PG_SUPPORT_ATHUB |
588a6dec868SEvan Quan 			AMD_PG_SUPPORT_MMHUB;
58971199aa4SStanley.Yang 		adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
59071199aa4SStanley.Yang 		break;
59192fd2153SFlora Cui 	case IP_VERSION(11, 0, 2):
59271dae221SJames Zhu 		adev->cg_flags =
5939503a944SLikun Gao 			AMD_CG_SUPPORT_GFX_CGCG |
5949503a944SLikun Gao 			AMD_CG_SUPPORT_GFX_CGLS |
59549401d3aSKenneth Feng 			AMD_CG_SUPPORT_REPEATER_FGCG |
5967ece9314SJames Zhu 			AMD_CG_SUPPORT_VCN_MGCG |
59749401d3aSKenneth Feng 			AMD_CG_SUPPORT_JPEG_MGCG |
59849401d3aSKenneth Feng 			AMD_CG_SUPPORT_ATHUB_MGCG |
599b4ddb27dSKenneth Feng 			AMD_CG_SUPPORT_ATHUB_LS |
600b4ddb27dSKenneth Feng 			AMD_CG_SUPPORT_IH_CG |
601b4ddb27dSKenneth Feng 			AMD_CG_SUPPORT_HDP_SD;
602ebac66a3SJames Zhu 		adev->pg_flags =
603143a34a0SJames Zhu 			AMD_PG_SUPPORT_VCN |
604ec9db74eSJames Zhu 			AMD_PG_SUPPORT_VCN_DPG |
60527e3911cSKenneth Feng 			AMD_PG_SUPPORT_JPEG |
60627e3911cSKenneth Feng 			AMD_PG_SUPPORT_ATHUB |
60727e3911cSKenneth Feng 			AMD_PG_SUPPORT_MMHUB;
60892fd2153SFlora Cui 		adev->external_rev_id = adev->rev_id + 0x10;
60992fd2153SFlora Cui 		break;
61011417a92SHuang Rui 	case IP_VERSION(11, 0, 1):
61147231d5eSSonny Jiang 		adev->cg_flags =
6128df436d5STim Huang 			AMD_CG_SUPPORT_GFX_CGCG |
6138df436d5STim Huang 			AMD_CG_SUPPORT_GFX_CGLS |
6148df436d5STim Huang 			AMD_CG_SUPPORT_GFX_MGCG |
6158df436d5STim Huang 			AMD_CG_SUPPORT_GFX_FGCG |
6168df436d5STim Huang 			AMD_CG_SUPPORT_REPEATER_FGCG |
6178df436d5STim Huang 			AMD_CG_SUPPORT_GFX_PERF_CLK |
618adcd15dcSTim Huang 			AMD_CG_SUPPORT_MC_MGCG |
619adcd15dcSTim Huang 			AMD_CG_SUPPORT_MC_LS |
6207e4a77deSTim Huang 			AMD_CG_SUPPORT_HDP_MGCG |
6217e4a77deSTim Huang 			AMD_CG_SUPPORT_HDP_LS |
6228e78c7c4STim Huang 			AMD_CG_SUPPORT_ATHUB_MGCG |
6238e78c7c4STim Huang 			AMD_CG_SUPPORT_ATHUB_LS |
624fa0bbd3bSTim Huang 			AMD_CG_SUPPORT_IH_CG |
6259407feacSTim Huang 			AMD_CG_SUPPORT_BIF_MGCG |
6269407feacSTim Huang 			AMD_CG_SUPPORT_BIF_LS |
62747231d5eSSonny Jiang 			AMD_CG_SUPPORT_VCN_MGCG |
62847231d5eSSonny Jiang 			AMD_CG_SUPPORT_JPEG_MGCG;
62947231d5eSSonny Jiang 		adev->pg_flags =
630dc0a096bSTim Huang 			AMD_PG_SUPPORT_GFX_PG |
631e626d9b9SSonny Jiang 			AMD_PG_SUPPORT_VCN |
6320b37f474SSonny Jiang 			AMD_PG_SUPPORT_VCN_DPG |
63347231d5eSSonny Jiang 			AMD_PG_SUPPORT_JPEG;
63411417a92SHuang Rui 		adev->external_rev_id = adev->rev_id + 0x1;
63511417a92SHuang Rui 		break;
6366b46251cSHawking Zhang 	case IP_VERSION(11, 0, 3):
6370f05a2e5SSonny Jiang 		adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG |
6384ecdb30eSKenneth Feng 			AMD_CG_SUPPORT_JPEG_MGCG |
6394ecdb30eSKenneth Feng 			AMD_CG_SUPPORT_GFX_CGCG |
6404ecdb30eSKenneth Feng 			AMD_CG_SUPPORT_GFX_CGLS |
6414ecdb30eSKenneth Feng 			AMD_CG_SUPPORT_REPEATER_FGCG |
6424ecdb30eSKenneth Feng 			AMD_CG_SUPPORT_GFX_MGCG;
6430f05a2e5SSonny Jiang 		adev->pg_flags = AMD_PG_SUPPORT_VCN |
6440f05a2e5SSonny Jiang 			AMD_PG_SUPPORT_VCN_DPG |
6450f05a2e5SSonny Jiang 			AMD_PG_SUPPORT_JPEG;
6466b46251cSHawking Zhang 		adev->external_rev_id = adev->rev_id + 0x20;
6476b46251cSHawking Zhang 		break;
648311d5236SYifan Zhang 	case IP_VERSION(11, 0, 4):
649311d5236SYifan Zhang 		adev->cg_flags = 0;
650311d5236SYifan Zhang 		adev->pg_flags = 0;
651311d5236SYifan Zhang 		adev->external_rev_id = adev->rev_id + 0x1;
652311d5236SYifan Zhang 		break;
653311d5236SYifan Zhang 
65471199aa4SStanley.Yang 	default:
65571199aa4SStanley.Yang 		/* FIXME: not supported yet */
65671199aa4SStanley.Yang 		return -EINVAL;
65771199aa4SStanley.Yang 	}
65871199aa4SStanley.Yang 
6590cfce240SYiqing Yao 	if (amdgpu_sriov_vf(adev))
6600cfce240SYiqing Yao 		amdgpu_virt_init_setting(adev);
6610cfce240SYiqing Yao 
66271199aa4SStanley.Yang 	return 0;
66371199aa4SStanley.Yang }
66471199aa4SStanley.Yang 
66571199aa4SStanley.Yang static int soc21_common_late_init(void *handle)
66671199aa4SStanley.Yang {
66771199aa4SStanley.Yang 	return 0;
66871199aa4SStanley.Yang }
66971199aa4SStanley.Yang 
67071199aa4SStanley.Yang static int soc21_common_sw_init(void *handle)
67171199aa4SStanley.Yang {
67271199aa4SStanley.Yang 	return 0;
67371199aa4SStanley.Yang }
67471199aa4SStanley.Yang 
67571199aa4SStanley.Yang static int soc21_common_sw_fini(void *handle)
67671199aa4SStanley.Yang {
67771199aa4SStanley.Yang 	return 0;
67871199aa4SStanley.Yang }
67971199aa4SStanley.Yang 
68071199aa4SStanley.Yang static int soc21_common_hw_init(void *handle)
68171199aa4SStanley.Yang {
68271199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
68371199aa4SStanley.Yang 
68471199aa4SStanley.Yang 	/* enable pcie gen2/3 link */
68571199aa4SStanley.Yang 	soc21_pcie_gen3_enable(adev);
68671199aa4SStanley.Yang 	/* enable aspm */
68771199aa4SStanley.Yang 	soc21_program_aspm(adev);
68871199aa4SStanley.Yang 	/* setup nbio registers */
68971199aa4SStanley.Yang 	adev->nbio.funcs->init_registers(adev);
69071199aa4SStanley.Yang 	/* remap HDP registers to a hole in mmio space,
69171199aa4SStanley.Yang 	 * for the purpose of expose those registers
69271199aa4SStanley.Yang 	 * to process space
69371199aa4SStanley.Yang 	 */
69471199aa4SStanley.Yang 	if (adev->nbio.funcs->remap_hdp_registers)
69571199aa4SStanley.Yang 		adev->nbio.funcs->remap_hdp_registers(adev);
69671199aa4SStanley.Yang 	/* enable the doorbell aperture */
69771199aa4SStanley.Yang 	soc21_enable_doorbell_aperture(adev, true);
69871199aa4SStanley.Yang 
69971199aa4SStanley.Yang 	return 0;
70071199aa4SStanley.Yang }
70171199aa4SStanley.Yang 
70271199aa4SStanley.Yang static int soc21_common_hw_fini(void *handle)
70371199aa4SStanley.Yang {
70471199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
70571199aa4SStanley.Yang 
70671199aa4SStanley.Yang 	/* disable the doorbell aperture */
70771199aa4SStanley.Yang 	soc21_enable_doorbell_aperture(adev, false);
70871199aa4SStanley.Yang 
70971199aa4SStanley.Yang 	return 0;
71071199aa4SStanley.Yang }
71171199aa4SStanley.Yang 
71271199aa4SStanley.Yang static int soc21_common_suspend(void *handle)
71371199aa4SStanley.Yang {
71471199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
71571199aa4SStanley.Yang 
71671199aa4SStanley.Yang 	return soc21_common_hw_fini(adev);
71771199aa4SStanley.Yang }
71871199aa4SStanley.Yang 
71971199aa4SStanley.Yang static int soc21_common_resume(void *handle)
72071199aa4SStanley.Yang {
72171199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
72271199aa4SStanley.Yang 
72371199aa4SStanley.Yang 	return soc21_common_hw_init(adev);
72471199aa4SStanley.Yang }
72571199aa4SStanley.Yang 
72671199aa4SStanley.Yang static bool soc21_common_is_idle(void *handle)
72771199aa4SStanley.Yang {
72871199aa4SStanley.Yang 	return true;
72971199aa4SStanley.Yang }
73071199aa4SStanley.Yang 
73171199aa4SStanley.Yang static int soc21_common_wait_for_idle(void *handle)
73271199aa4SStanley.Yang {
73371199aa4SStanley.Yang 	return 0;
73471199aa4SStanley.Yang }
73571199aa4SStanley.Yang 
73671199aa4SStanley.Yang static int soc21_common_soft_reset(void *handle)
73771199aa4SStanley.Yang {
73871199aa4SStanley.Yang 	return 0;
73971199aa4SStanley.Yang }
74071199aa4SStanley.Yang 
74171199aa4SStanley.Yang static int soc21_common_set_clockgating_state(void *handle,
74271199aa4SStanley.Yang 					   enum amd_clockgating_state state)
74371199aa4SStanley.Yang {
74471199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
74571199aa4SStanley.Yang 
74671199aa4SStanley.Yang 	switch (adev->ip_versions[NBIO_HWIP][0]) {
74771199aa4SStanley.Yang 	case IP_VERSION(4, 3, 0):
748b4ddb27dSKenneth Feng 	case IP_VERSION(4, 3, 1):
7499407feacSTim Huang 	case IP_VERSION(7, 7, 0):
75071199aa4SStanley.Yang 		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
75171199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
75271199aa4SStanley.Yang 		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
75371199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
75471199aa4SStanley.Yang 		adev->hdp.funcs->update_clock_gating(adev,
75571199aa4SStanley.Yang 				state == AMD_CG_STATE_GATE);
75671199aa4SStanley.Yang 		break;
75771199aa4SStanley.Yang 	default:
75871199aa4SStanley.Yang 		break;
75971199aa4SStanley.Yang 	}
76071199aa4SStanley.Yang 	return 0;
76171199aa4SStanley.Yang }
76271199aa4SStanley.Yang 
76371199aa4SStanley.Yang static int soc21_common_set_powergating_state(void *handle,
76471199aa4SStanley.Yang 					   enum amd_powergating_state state)
76571199aa4SStanley.Yang {
76641967850SLikun Gao 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
76741967850SLikun Gao 
76841967850SLikun Gao 	switch (adev->ip_versions[LSDMA_HWIP][0]) {
76941967850SLikun Gao 	case IP_VERSION(6, 0, 0):
770362c3c70SLikun Gao 	case IP_VERSION(6, 0, 2):
77141967850SLikun Gao 		adev->lsdma.funcs->update_memory_power_gating(adev,
77241967850SLikun Gao 				state == AMD_PG_STATE_GATE);
77341967850SLikun Gao 		break;
77441967850SLikun Gao 	default:
77541967850SLikun Gao 		break;
77641967850SLikun Gao 	}
77741967850SLikun Gao 
77871199aa4SStanley.Yang 	return 0;
77971199aa4SStanley.Yang }
78071199aa4SStanley.Yang 
78171199aa4SStanley.Yang static void soc21_common_get_clockgating_state(void *handle, u64 *flags)
78271199aa4SStanley.Yang {
78371199aa4SStanley.Yang 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78471199aa4SStanley.Yang 
78571199aa4SStanley.Yang 	adev->nbio.funcs->get_clockgating_state(adev, flags);
78671199aa4SStanley.Yang 
78771199aa4SStanley.Yang 	adev->hdp.funcs->get_clock_gating_state(adev, flags);
78871199aa4SStanley.Yang 
78971199aa4SStanley.Yang 	return;
79071199aa4SStanley.Yang }
79171199aa4SStanley.Yang 
79271199aa4SStanley.Yang static const struct amd_ip_funcs soc21_common_ip_funcs = {
79371199aa4SStanley.Yang 	.name = "soc21_common",
79471199aa4SStanley.Yang 	.early_init = soc21_common_early_init,
79571199aa4SStanley.Yang 	.late_init = soc21_common_late_init,
79671199aa4SStanley.Yang 	.sw_init = soc21_common_sw_init,
79771199aa4SStanley.Yang 	.sw_fini = soc21_common_sw_fini,
79871199aa4SStanley.Yang 	.hw_init = soc21_common_hw_init,
79971199aa4SStanley.Yang 	.hw_fini = soc21_common_hw_fini,
80071199aa4SStanley.Yang 	.suspend = soc21_common_suspend,
80171199aa4SStanley.Yang 	.resume = soc21_common_resume,
80271199aa4SStanley.Yang 	.is_idle = soc21_common_is_idle,
80371199aa4SStanley.Yang 	.wait_for_idle = soc21_common_wait_for_idle,
80471199aa4SStanley.Yang 	.soft_reset = soc21_common_soft_reset,
80571199aa4SStanley.Yang 	.set_clockgating_state = soc21_common_set_clockgating_state,
80671199aa4SStanley.Yang 	.set_powergating_state = soc21_common_set_powergating_state,
80771199aa4SStanley.Yang 	.get_clockgating_state = soc21_common_get_clockgating_state,
80871199aa4SStanley.Yang };
809