162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright 2016 Advanced Micro Devices, Inc.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1262306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_ci#include <linux/firmware.h>
2462306a36Sopenharmony_ci#include <linux/slab.h>
2562306a36Sopenharmony_ci#include <linux/module.h>
2662306a36Sopenharmony_ci#include <linux/pci.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include <drm/amdgpu_drm.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include "amdgpu.h"
3162306a36Sopenharmony_ci#include "amdgpu_atombios.h"
3262306a36Sopenharmony_ci#include "amdgpu_ih.h"
3362306a36Sopenharmony_ci#include "amdgpu_uvd.h"
3462306a36Sopenharmony_ci#include "amdgpu_vce.h"
3562306a36Sopenharmony_ci#include "amdgpu_ucode.h"
3662306a36Sopenharmony_ci#include "amdgpu_psp.h"
3762306a36Sopenharmony_ci#include "atom.h"
3862306a36Sopenharmony_ci#include "amd_pcie.h"
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#include "uvd/uvd_7_0_offset.h"
4162306a36Sopenharmony_ci#include "gc/gc_9_0_offset.h"
4262306a36Sopenharmony_ci#include "gc/gc_9_0_sh_mask.h"
4362306a36Sopenharmony_ci#include "sdma0/sdma0_4_0_offset.h"
4462306a36Sopenharmony_ci#include "sdma1/sdma1_4_0_offset.h"
4562306a36Sopenharmony_ci#include "nbio/nbio_7_0_default.h"
4662306a36Sopenharmony_ci#include "nbio/nbio_7_0_offset.h"
4762306a36Sopenharmony_ci#include "nbio/nbio_7_0_sh_mask.h"
4862306a36Sopenharmony_ci#include "nbio/nbio_7_0_smn.h"
4962306a36Sopenharmony_ci#include "mp/mp_9_0_offset.h"
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#include "soc15.h"
5262306a36Sopenharmony_ci#include "soc15_common.h"
5362306a36Sopenharmony_ci#include "gfx_v9_0.h"
5462306a36Sopenharmony_ci#include "gmc_v9_0.h"
5562306a36Sopenharmony_ci#include "gfxhub_v1_0.h"
5662306a36Sopenharmony_ci#include "mmhub_v1_0.h"
5762306a36Sopenharmony_ci#include "df_v1_7.h"
5862306a36Sopenharmony_ci#include "df_v3_6.h"
5962306a36Sopenharmony_ci#include "nbio_v6_1.h"
6062306a36Sopenharmony_ci#include "nbio_v7_0.h"
6162306a36Sopenharmony_ci#include "nbio_v7_4.h"
6262306a36Sopenharmony_ci#include "hdp_v4_0.h"
6362306a36Sopenharmony_ci#include "vega10_ih.h"
6462306a36Sopenharmony_ci#include "vega20_ih.h"
6562306a36Sopenharmony_ci#include "navi10_ih.h"
6662306a36Sopenharmony_ci#include "sdma_v4_0.h"
6762306a36Sopenharmony_ci#include "uvd_v7_0.h"
6862306a36Sopenharmony_ci#include "vce_v4_0.h"
6962306a36Sopenharmony_ci#include "vcn_v1_0.h"
7062306a36Sopenharmony_ci#include "vcn_v2_0.h"
7162306a36Sopenharmony_ci#include "jpeg_v2_0.h"
7262306a36Sopenharmony_ci#include "vcn_v2_5.h"
7362306a36Sopenharmony_ci#include "jpeg_v2_5.h"
7462306a36Sopenharmony_ci#include "smuio_v9_0.h"
7562306a36Sopenharmony_ci#include "smuio_v11_0.h"
7662306a36Sopenharmony_ci#include "smuio_v13_0.h"
7762306a36Sopenharmony_ci#include "amdgpu_vkms.h"
7862306a36Sopenharmony_ci#include "mxgpu_ai.h"
7962306a36Sopenharmony_ci#include "amdgpu_ras.h"
8062306a36Sopenharmony_ci#include "amdgpu_xgmi.h"
8162306a36Sopenharmony_ci#include <uapi/linux/kfd_ioctl.h>
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci#define mmMP0_MISC_CGTT_CTRL0                                                                   0x01b9
8462306a36Sopenharmony_ci#define mmMP0_MISC_CGTT_CTRL0_BASE_IDX                                                          0
8562306a36Sopenharmony_ci#define mmMP0_MISC_LIGHT_SLEEP_CTRL                                                             0x01ba
8662306a36Sopenharmony_ci#define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX                                                    0
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic const struct amd_ip_funcs soc15_common_ip_funcs;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/* Vega, Raven, Arcturus */
9162306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] =
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
9462306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vega_video_codecs_encode =
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	.codec_count = ARRAY_SIZE(vega_video_codecs_encode_array),
10062306a36Sopenharmony_ci	.codec_array = vega_video_codecs_encode_array,
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* Vega */
10462306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] =
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
10762306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
10862306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
10962306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
11062306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
11162306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vega_video_codecs_decode =
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci	.codec_count = ARRAY_SIZE(vega_video_codecs_decode_array),
11762306a36Sopenharmony_ci	.codec_array = vega_video_codecs_decode_array,
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/* Raven */
12162306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] =
12262306a36Sopenharmony_ci{
12362306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
12462306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
12562306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
12662306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
12762306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
12862306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
12962306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)},
13062306a36Sopenharmony_ci};
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic const struct amdgpu_video_codecs rv_video_codecs_decode =
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	.codec_count = ARRAY_SIZE(rv_video_codecs_decode_array),
13562306a36Sopenharmony_ci	.codec_array = rv_video_codecs_decode_array,
13662306a36Sopenharmony_ci};
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci/* Renoir, Arcturus */
13962306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] =
14062306a36Sopenharmony_ci{
14162306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
14262306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
14362306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
14462306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
14562306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
14662306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
14762306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
14862306a36Sopenharmony_ci};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic const struct amdgpu_video_codecs rn_video_codecs_decode =
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	.codec_count = ARRAY_SIZE(rn_video_codecs_decode_array),
15362306a36Sopenharmony_ci	.codec_array = rn_video_codecs_decode_array,
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info vcn_4_0_3_video_codecs_decode_array[] = {
15762306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
15862306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
15962306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
16062306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
16162306a36Sopenharmony_ci	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vcn_4_0_3_video_codecs_decode = {
16562306a36Sopenharmony_ci	.codec_count = ARRAY_SIZE(vcn_4_0_3_video_codecs_decode_array),
16662306a36Sopenharmony_ci	.codec_array = vcn_4_0_3_video_codecs_decode_array,
16762306a36Sopenharmony_ci};
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vcn_4_0_3_video_codecs_encode = {
17062306a36Sopenharmony_ci	.codec_count = 0,
17162306a36Sopenharmony_ci	.codec_array = NULL,
17262306a36Sopenharmony_ci};
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic int soc15_query_video_codecs(struct amdgpu_device *adev, bool encode,
17562306a36Sopenharmony_ci				    const struct amdgpu_video_codecs **codecs)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	if (adev->ip_versions[VCE_HWIP][0]) {
17862306a36Sopenharmony_ci		switch (adev->ip_versions[VCE_HWIP][0]) {
17962306a36Sopenharmony_ci		case IP_VERSION(4, 0, 0):
18062306a36Sopenharmony_ci		case IP_VERSION(4, 1, 0):
18162306a36Sopenharmony_ci			if (encode)
18262306a36Sopenharmony_ci				*codecs = &vega_video_codecs_encode;
18362306a36Sopenharmony_ci			else
18462306a36Sopenharmony_ci				*codecs = &vega_video_codecs_decode;
18562306a36Sopenharmony_ci			return 0;
18662306a36Sopenharmony_ci		default:
18762306a36Sopenharmony_ci			return -EINVAL;
18862306a36Sopenharmony_ci		}
18962306a36Sopenharmony_ci	} else {
19062306a36Sopenharmony_ci		switch (adev->ip_versions[UVD_HWIP][0]) {
19162306a36Sopenharmony_ci		case IP_VERSION(1, 0, 0):
19262306a36Sopenharmony_ci		case IP_VERSION(1, 0, 1):
19362306a36Sopenharmony_ci			if (encode)
19462306a36Sopenharmony_ci				*codecs = &vega_video_codecs_encode;
19562306a36Sopenharmony_ci			else
19662306a36Sopenharmony_ci				*codecs = &rv_video_codecs_decode;
19762306a36Sopenharmony_ci			return 0;
19862306a36Sopenharmony_ci		case IP_VERSION(2, 5, 0):
19962306a36Sopenharmony_ci		case IP_VERSION(2, 6, 0):
20062306a36Sopenharmony_ci		case IP_VERSION(2, 2, 0):
20162306a36Sopenharmony_ci			if (encode)
20262306a36Sopenharmony_ci				*codecs = &vega_video_codecs_encode;
20362306a36Sopenharmony_ci			else
20462306a36Sopenharmony_ci				*codecs = &rn_video_codecs_decode;
20562306a36Sopenharmony_ci			return 0;
20662306a36Sopenharmony_ci		case IP_VERSION(4, 0, 3):
20762306a36Sopenharmony_ci			if (encode)
20862306a36Sopenharmony_ci				*codecs = &vcn_4_0_3_video_codecs_encode;
20962306a36Sopenharmony_ci			else
21062306a36Sopenharmony_ci				*codecs = &vcn_4_0_3_video_codecs_decode;
21162306a36Sopenharmony_ci			return 0;
21262306a36Sopenharmony_ci		default:
21362306a36Sopenharmony_ci			return -EINVAL;
21462306a36Sopenharmony_ci		}
21562306a36Sopenharmony_ci	}
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_cistatic u32 soc15_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	unsigned long flags, address, data;
22162306a36Sopenharmony_ci	u32 r;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);
22462306a36Sopenharmony_ci	data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
22762306a36Sopenharmony_ci	WREG32(address, ((reg) & 0x1ff));
22862306a36Sopenharmony_ci	r = RREG32(data);
22962306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);
23062306a36Sopenharmony_ci	return r;
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic void soc15_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	unsigned long flags, address, data;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX);
23862306a36Sopenharmony_ci	data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags);
24162306a36Sopenharmony_ci	WREG32(address, ((reg) & 0x1ff));
24262306a36Sopenharmony_ci	WREG32(data, (v));
24362306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags);
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg)
24762306a36Sopenharmony_ci{
24862306a36Sopenharmony_ci	unsigned long flags, address, data;
24962306a36Sopenharmony_ci	u32 r;
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
25262306a36Sopenharmony_ci	data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	spin_lock_irqsave(&adev->didt_idx_lock, flags);
25562306a36Sopenharmony_ci	WREG32(address, (reg));
25662306a36Sopenharmony_ci	r = RREG32(data);
25762306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
25862306a36Sopenharmony_ci	return r;
25962306a36Sopenharmony_ci}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_cistatic void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
26262306a36Sopenharmony_ci{
26362306a36Sopenharmony_ci	unsigned long flags, address, data;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
26662306a36Sopenharmony_ci	data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	spin_lock_irqsave(&adev->didt_idx_lock, flags);
26962306a36Sopenharmony_ci	WREG32(address, (reg));
27062306a36Sopenharmony_ci	WREG32(data, (v));
27162306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_cistatic u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	unsigned long flags;
27762306a36Sopenharmony_ci	u32 r;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
28062306a36Sopenharmony_ci	WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
28162306a36Sopenharmony_ci	r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA);
28262306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);
28362306a36Sopenharmony_ci	return r;
28462306a36Sopenharmony_ci}
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_cistatic void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
28762306a36Sopenharmony_ci{
28862306a36Sopenharmony_ci	unsigned long flags;
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
29162306a36Sopenharmony_ci	WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
29262306a36Sopenharmony_ci	WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v));
29362306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);
29462306a36Sopenharmony_ci}
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cistatic u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg)
29762306a36Sopenharmony_ci{
29862306a36Sopenharmony_ci	unsigned long flags;
29962306a36Sopenharmony_ci	u32 r;
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
30262306a36Sopenharmony_ci	WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
30362306a36Sopenharmony_ci	r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA);
30462306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);
30562306a36Sopenharmony_ci	return r;
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistatic void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	unsigned long flags;
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
31362306a36Sopenharmony_ci	WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
31462306a36Sopenharmony_ci	WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v));
31562306a36Sopenharmony_ci	spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic u32 soc15_get_config_memsize(struct amdgpu_device *adev)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	return adev->nbio.funcs->get_memsize(adev);
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic u32 soc15_get_xclk(struct amdgpu_device *adev)
32462306a36Sopenharmony_ci{
32562306a36Sopenharmony_ci	u32 reference_clock = adev->clock.spll.reference_freq;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) ||
32862306a36Sopenharmony_ci	    adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1) ||
32962306a36Sopenharmony_ci	    adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6))
33062306a36Sopenharmony_ci		return 10000;
33162306a36Sopenharmony_ci	if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) ||
33262306a36Sopenharmony_ci	    adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1))
33362306a36Sopenharmony_ci		return reference_clock / 4;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	return reference_clock;
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_civoid soc15_grbm_select(struct amdgpu_device *adev,
34062306a36Sopenharmony_ci		     u32 me, u32 pipe, u32 queue, u32 vmid, int xcc_id)
34162306a36Sopenharmony_ci{
34262306a36Sopenharmony_ci	u32 grbm_gfx_cntl = 0;
34362306a36Sopenharmony_ci	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe);
34462306a36Sopenharmony_ci	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me);
34562306a36Sopenharmony_ci	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
34662306a36Sopenharmony_ci	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	WREG32_SOC15_RLC_SHADOW(GC, xcc_id, mmGRBM_GFX_CNTL, grbm_gfx_cntl);
34962306a36Sopenharmony_ci}
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic bool soc15_read_disabled_bios(struct amdgpu_device *adev)
35262306a36Sopenharmony_ci{
35362306a36Sopenharmony_ci	/* todo */
35462306a36Sopenharmony_ci	return false;
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_cistatic struct soc15_allowed_register_entry soc15_allowed_read_registers[] = {
35862306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)},
35962306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)},
36062306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE0)},
36162306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE1)},
36262306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE2)},
36362306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE3)},
36462306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_STATUS_REG)},
36562306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_STATUS_REG)},
36662306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_STAT)},
36762306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT1)},
36862306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT2)},
36962306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT3)},
37062306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)},
37162306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)},
37262306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)},
37362306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)},
37462306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
37562306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
37662306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
37762306a36Sopenharmony_ci	{ SOC15_REG_ENTRY(GC, 0, mmDB_DEBUG2)},
37862306a36Sopenharmony_ci};
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_cistatic uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
38162306a36Sopenharmony_ci					 u32 sh_num, u32 reg_offset)
38262306a36Sopenharmony_ci{
38362306a36Sopenharmony_ci	uint32_t val;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	mutex_lock(&adev->grbm_idx_mutex);
38662306a36Sopenharmony_ci	if (se_num != 0xffffffff || sh_num != 0xffffffff)
38762306a36Sopenharmony_ci		amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff, 0);
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	val = RREG32(reg_offset);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	if (se_num != 0xffffffff || sh_num != 0xffffffff)
39262306a36Sopenharmony_ci		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, 0);
39362306a36Sopenharmony_ci	mutex_unlock(&adev->grbm_idx_mutex);
39462306a36Sopenharmony_ci	return val;
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cistatic uint32_t soc15_get_register_value(struct amdgpu_device *adev,
39862306a36Sopenharmony_ci					 bool indexed, u32 se_num,
39962306a36Sopenharmony_ci					 u32 sh_num, u32 reg_offset)
40062306a36Sopenharmony_ci{
40162306a36Sopenharmony_ci	if (indexed) {
40262306a36Sopenharmony_ci		return soc15_read_indexed_register(adev, se_num, sh_num, reg_offset);
40362306a36Sopenharmony_ci	} else {
40462306a36Sopenharmony_ci		if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG))
40562306a36Sopenharmony_ci			return adev->gfx.config.gb_addr_config;
40662306a36Sopenharmony_ci		else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2))
40762306a36Sopenharmony_ci			return adev->gfx.config.db_debug2;
40862306a36Sopenharmony_ci		return RREG32(reg_offset);
40962306a36Sopenharmony_ci	}
41062306a36Sopenharmony_ci}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_cistatic int soc15_read_register(struct amdgpu_device *adev, u32 se_num,
41362306a36Sopenharmony_ci			    u32 sh_num, u32 reg_offset, u32 *value)
41462306a36Sopenharmony_ci{
41562306a36Sopenharmony_ci	uint32_t i;
41662306a36Sopenharmony_ci	struct soc15_allowed_register_entry  *en;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	*value = 0;
41962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) {
42062306a36Sopenharmony_ci		en = &soc15_allowed_read_registers[i];
42162306a36Sopenharmony_ci		if (!adev->reg_offset[en->hwip][en->inst])
42262306a36Sopenharmony_ci			continue;
42362306a36Sopenharmony_ci		else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
42462306a36Sopenharmony_ci					+ en->reg_offset))
42562306a36Sopenharmony_ci			continue;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci		*value = soc15_get_register_value(adev,
42862306a36Sopenharmony_ci						  soc15_allowed_read_registers[i].grbm_indexed,
42962306a36Sopenharmony_ci						  se_num, sh_num, reg_offset);
43062306a36Sopenharmony_ci		return 0;
43162306a36Sopenharmony_ci	}
43262306a36Sopenharmony_ci	return -EINVAL;
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci/**
43762306a36Sopenharmony_ci * soc15_program_register_sequence - program an array of registers.
43862306a36Sopenharmony_ci *
43962306a36Sopenharmony_ci * @adev: amdgpu_device pointer
44062306a36Sopenharmony_ci * @regs: pointer to the register array
44162306a36Sopenharmony_ci * @array_size: size of the register array
44262306a36Sopenharmony_ci *
44362306a36Sopenharmony_ci * Programs an array or registers with and and or masks.
44462306a36Sopenharmony_ci * This is a helper for setting golden registers.
44562306a36Sopenharmony_ci */
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_civoid soc15_program_register_sequence(struct amdgpu_device *adev,
44862306a36Sopenharmony_ci					     const struct soc15_reg_golden *regs,
44962306a36Sopenharmony_ci					     const u32 array_size)
45062306a36Sopenharmony_ci{
45162306a36Sopenharmony_ci	const struct soc15_reg_golden *entry;
45262306a36Sopenharmony_ci	u32 tmp, reg;
45362306a36Sopenharmony_ci	int i;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	for (i = 0; i < array_size; ++i) {
45662306a36Sopenharmony_ci		entry = &regs[i];
45762306a36Sopenharmony_ci		reg =  adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg;
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci		if (entry->and_mask == 0xffffffff) {
46062306a36Sopenharmony_ci			tmp = entry->or_mask;
46162306a36Sopenharmony_ci		} else {
46262306a36Sopenharmony_ci			tmp = (entry->hwip == GC_HWIP) ?
46362306a36Sopenharmony_ci				RREG32_SOC15_IP(GC, reg) : RREG32(reg);
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci			tmp &= ~(entry->and_mask);
46662306a36Sopenharmony_ci			tmp |= (entry->or_mask & entry->and_mask);
46762306a36Sopenharmony_ci		}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci		if (reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3) ||
47062306a36Sopenharmony_ci			reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE) ||
47162306a36Sopenharmony_ci			reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE_1) ||
47262306a36Sopenharmony_ci			reg == SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG))
47362306a36Sopenharmony_ci			WREG32_RLC(reg, tmp);
47462306a36Sopenharmony_ci		else
47562306a36Sopenharmony_ci			(entry->hwip == GC_HWIP) ?
47662306a36Sopenharmony_ci				WREG32_SOC15_IP(GC, reg, tmp) : WREG32(reg, tmp);
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	}
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_cistatic int soc15_asic_baco_reset(struct amdgpu_device *adev)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
48562306a36Sopenharmony_ci	int ret = 0;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	/* avoid NBIF got stuck when do RAS recovery in BACO reset */
48862306a36Sopenharmony_ci	if (ras && adev->ras_enabled)
48962306a36Sopenharmony_ci		adev->nbio.funcs->enable_doorbell_interrupt(adev, false);
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	ret = amdgpu_dpm_baco_reset(adev);
49262306a36Sopenharmony_ci	if (ret)
49362306a36Sopenharmony_ci		return ret;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	/* re-enable doorbell interrupt after BACO exit */
49662306a36Sopenharmony_ci	if (ras && adev->ras_enabled)
49762306a36Sopenharmony_ci		adev->nbio.funcs->enable_doorbell_interrupt(adev, true);
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	return 0;
50062306a36Sopenharmony_ci}
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_cistatic enum amd_reset_method
50362306a36Sopenharmony_cisoc15_asic_reset_method(struct amdgpu_device *adev)
50462306a36Sopenharmony_ci{
50562306a36Sopenharmony_ci	bool baco_reset = false;
50662306a36Sopenharmony_ci	bool connected_to_cpu = false;
50762306a36Sopenharmony_ci	struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci        if (adev->gmc.xgmi.supported && adev->gmc.xgmi.connected_to_cpu)
51062306a36Sopenharmony_ci                connected_to_cpu = true;
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 ||
51362306a36Sopenharmony_ci	    amdgpu_reset_method == AMD_RESET_METHOD_MODE2 ||
51462306a36Sopenharmony_ci	    amdgpu_reset_method == AMD_RESET_METHOD_BACO ||
51562306a36Sopenharmony_ci	    amdgpu_reset_method == AMD_RESET_METHOD_PCI) {
51662306a36Sopenharmony_ci		/* If connected to cpu, driver only support mode2 */
51762306a36Sopenharmony_ci                if (connected_to_cpu)
51862306a36Sopenharmony_ci                        return AMD_RESET_METHOD_MODE2;
51962306a36Sopenharmony_ci                return amdgpu_reset_method;
52062306a36Sopenharmony_ci        }
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	if (amdgpu_reset_method != -1)
52362306a36Sopenharmony_ci		dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n",
52462306a36Sopenharmony_ci				  amdgpu_reset_method);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	switch (adev->ip_versions[MP1_HWIP][0]) {
52762306a36Sopenharmony_ci	case IP_VERSION(10, 0, 0):
52862306a36Sopenharmony_ci	case IP_VERSION(10, 0, 1):
52962306a36Sopenharmony_ci	case IP_VERSION(12, 0, 0):
53062306a36Sopenharmony_ci	case IP_VERSION(12, 0, 1):
53162306a36Sopenharmony_ci		return AMD_RESET_METHOD_MODE2;
53262306a36Sopenharmony_ci	case IP_VERSION(9, 0, 0):
53362306a36Sopenharmony_ci	case IP_VERSION(11, 0, 2):
53462306a36Sopenharmony_ci		if (adev->asic_type == CHIP_VEGA20) {
53562306a36Sopenharmony_ci			if (adev->psp.sos.fw_version >= 0x80067)
53662306a36Sopenharmony_ci				baco_reset = amdgpu_dpm_is_baco_supported(adev);
53762306a36Sopenharmony_ci			/*
53862306a36Sopenharmony_ci			 * 1. PMFW version > 0x284300: all cases use baco
53962306a36Sopenharmony_ci			 * 2. PMFW version <= 0x284300: only sGPU w/o RAS use baco
54062306a36Sopenharmony_ci			 */
54162306a36Sopenharmony_ci			if (ras && adev->ras_enabled &&
54262306a36Sopenharmony_ci			    adev->pm.fw_version <= 0x283400)
54362306a36Sopenharmony_ci				baco_reset = false;
54462306a36Sopenharmony_ci		} else {
54562306a36Sopenharmony_ci			baco_reset = amdgpu_dpm_is_baco_supported(adev);
54662306a36Sopenharmony_ci		}
54762306a36Sopenharmony_ci		break;
54862306a36Sopenharmony_ci	case IP_VERSION(13, 0, 2):
54962306a36Sopenharmony_ci		 /*
55062306a36Sopenharmony_ci		 * 1.connected to cpu: driver issue mode2 reset
55162306a36Sopenharmony_ci		 * 2.discret gpu: driver issue mode1 reset
55262306a36Sopenharmony_ci		 */
55362306a36Sopenharmony_ci		if (connected_to_cpu)
55462306a36Sopenharmony_ci			return AMD_RESET_METHOD_MODE2;
55562306a36Sopenharmony_ci		break;
55662306a36Sopenharmony_ci	case IP_VERSION(13, 0, 6):
55762306a36Sopenharmony_ci		/* Use gpu_recovery param to target a reset method.
55862306a36Sopenharmony_ci		 * Enable triggering of GPU reset only if specified
55962306a36Sopenharmony_ci		 * by module parameter.
56062306a36Sopenharmony_ci		 */
56162306a36Sopenharmony_ci		if (amdgpu_gpu_recovery == 4 || amdgpu_gpu_recovery == 5)
56262306a36Sopenharmony_ci			return AMD_RESET_METHOD_MODE2;
56362306a36Sopenharmony_ci		else if (!(adev->flags & AMD_IS_APU))
56462306a36Sopenharmony_ci			return AMD_RESET_METHOD_MODE1;
56562306a36Sopenharmony_ci		else
56662306a36Sopenharmony_ci			return AMD_RESET_METHOD_MODE2;
56762306a36Sopenharmony_ci	default:
56862306a36Sopenharmony_ci		break;
56962306a36Sopenharmony_ci	}
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	if (baco_reset)
57262306a36Sopenharmony_ci		return AMD_RESET_METHOD_BACO;
57362306a36Sopenharmony_ci	else
57462306a36Sopenharmony_ci		return AMD_RESET_METHOD_MODE1;
57562306a36Sopenharmony_ci}
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_cistatic bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
57862306a36Sopenharmony_ci{
57962306a36Sopenharmony_ci	u32 sol_reg;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	/* Will reset for the following suspend abort cases.
58462306a36Sopenharmony_ci	 * 1) Only reset limit on APU side, dGPU hasn't checked yet.
58562306a36Sopenharmony_ci	 * 2) S3 suspend abort and TOS already launched.
58662306a36Sopenharmony_ci	 */
58762306a36Sopenharmony_ci	if (adev->flags & AMD_IS_APU && adev->in_s3 &&
58862306a36Sopenharmony_ci			!adev->suspend_complete &&
58962306a36Sopenharmony_ci			sol_reg)
59062306a36Sopenharmony_ci		return true;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	return false;
59362306a36Sopenharmony_ci}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_cistatic int soc15_asic_reset(struct amdgpu_device *adev)
59662306a36Sopenharmony_ci{
59762306a36Sopenharmony_ci	/* original raven doesn't have full asic reset */
59862306a36Sopenharmony_ci	/* On the latest Raven, the GPU reset can be performed
59962306a36Sopenharmony_ci	 * successfully. So now, temporarily enable it for the
60062306a36Sopenharmony_ci	 * S3 suspend abort case.
60162306a36Sopenharmony_ci	 */
60262306a36Sopenharmony_ci	if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
60362306a36Sopenharmony_ci	    (adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
60462306a36Sopenharmony_ci		!soc15_need_reset_on_resume(adev))
60562306a36Sopenharmony_ci		return 0;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	switch (soc15_asic_reset_method(adev)) {
60862306a36Sopenharmony_ci	case AMD_RESET_METHOD_PCI:
60962306a36Sopenharmony_ci		dev_info(adev->dev, "PCI reset\n");
61062306a36Sopenharmony_ci		return amdgpu_device_pci_reset(adev);
61162306a36Sopenharmony_ci	case AMD_RESET_METHOD_BACO:
61262306a36Sopenharmony_ci		dev_info(adev->dev, "BACO reset\n");
61362306a36Sopenharmony_ci		return soc15_asic_baco_reset(adev);
61462306a36Sopenharmony_ci	case AMD_RESET_METHOD_MODE2:
61562306a36Sopenharmony_ci		dev_info(adev->dev, "MODE2 reset\n");
61662306a36Sopenharmony_ci		return amdgpu_dpm_mode2_reset(adev);
61762306a36Sopenharmony_ci	default:
61862306a36Sopenharmony_ci		dev_info(adev->dev, "MODE1 reset\n");
61962306a36Sopenharmony_ci		return amdgpu_device_mode1_reset(adev);
62062306a36Sopenharmony_ci	}
62162306a36Sopenharmony_ci}
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_cistatic bool soc15_supports_baco(struct amdgpu_device *adev)
62462306a36Sopenharmony_ci{
62562306a36Sopenharmony_ci	switch (adev->ip_versions[MP1_HWIP][0]) {
62662306a36Sopenharmony_ci	case IP_VERSION(9, 0, 0):
62762306a36Sopenharmony_ci	case IP_VERSION(11, 0, 2):
62862306a36Sopenharmony_ci		if (adev->asic_type == CHIP_VEGA20) {
62962306a36Sopenharmony_ci			if (adev->psp.sos.fw_version >= 0x80067)
63062306a36Sopenharmony_ci				return amdgpu_dpm_is_baco_supported(adev);
63162306a36Sopenharmony_ci			return false;
63262306a36Sopenharmony_ci		} else {
63362306a36Sopenharmony_ci			return amdgpu_dpm_is_baco_supported(adev);
63462306a36Sopenharmony_ci		}
63562306a36Sopenharmony_ci		break;
63662306a36Sopenharmony_ci	default:
63762306a36Sopenharmony_ci		return false;
63862306a36Sopenharmony_ci	}
63962306a36Sopenharmony_ci}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci/*static int soc15_set_uvd_clock(struct amdgpu_device *adev, u32 clock,
64262306a36Sopenharmony_ci			u32 cntl_reg, u32 status_reg)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	return 0;
64562306a36Sopenharmony_ci}*/
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_cistatic int soc15_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
64862306a36Sopenharmony_ci{
64962306a36Sopenharmony_ci	/*int r;
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci	r = soc15_set_uvd_clock(adev, vclk, ixCG_VCLK_CNTL, ixCG_VCLK_STATUS);
65262306a36Sopenharmony_ci	if (r)
65362306a36Sopenharmony_ci		return r;
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	r = soc15_set_uvd_clock(adev, dclk, ixCG_DCLK_CNTL, ixCG_DCLK_STATUS);
65662306a36Sopenharmony_ci	*/
65762306a36Sopenharmony_ci	return 0;
65862306a36Sopenharmony_ci}
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_cistatic int soc15_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
66162306a36Sopenharmony_ci{
66262306a36Sopenharmony_ci	/* todo */
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	return 0;
66562306a36Sopenharmony_ci}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_cistatic void soc15_program_aspm(struct amdgpu_device *adev)
66862306a36Sopenharmony_ci{
66962306a36Sopenharmony_ci	if (!amdgpu_device_should_use_aspm(adev))
67062306a36Sopenharmony_ci		return;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	if (!(adev->flags & AMD_IS_APU) &&
67362306a36Sopenharmony_ci	    (adev->nbio.funcs->program_aspm))
67462306a36Sopenharmony_ci		adev->nbio.funcs->program_aspm(adev);
67562306a36Sopenharmony_ci}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ciconst struct amdgpu_ip_block_version vega10_common_ip_block =
67862306a36Sopenharmony_ci{
67962306a36Sopenharmony_ci	.type = AMD_IP_BLOCK_TYPE_COMMON,
68062306a36Sopenharmony_ci	.major = 2,
68162306a36Sopenharmony_ci	.minor = 0,
68262306a36Sopenharmony_ci	.rev = 0,
68362306a36Sopenharmony_ci	.funcs = &soc15_common_ip_funcs,
68462306a36Sopenharmony_ci};
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_cistatic void soc15_reg_base_init(struct amdgpu_device *adev)
68762306a36Sopenharmony_ci{
68862306a36Sopenharmony_ci	/* Set IP register base before any HW register access */
68962306a36Sopenharmony_ci	switch (adev->asic_type) {
69062306a36Sopenharmony_ci	case CHIP_VEGA10:
69162306a36Sopenharmony_ci	case CHIP_VEGA12:
69262306a36Sopenharmony_ci	case CHIP_RAVEN:
69362306a36Sopenharmony_ci	case CHIP_RENOIR:
69462306a36Sopenharmony_ci		vega10_reg_base_init(adev);
69562306a36Sopenharmony_ci		break;
69662306a36Sopenharmony_ci	case CHIP_VEGA20:
69762306a36Sopenharmony_ci		vega20_reg_base_init(adev);
69862306a36Sopenharmony_ci		break;
69962306a36Sopenharmony_ci	case CHIP_ARCTURUS:
70062306a36Sopenharmony_ci		arct_reg_base_init(adev);
70162306a36Sopenharmony_ci		break;
70262306a36Sopenharmony_ci	case CHIP_ALDEBARAN:
70362306a36Sopenharmony_ci		aldebaran_reg_base_init(adev);
70462306a36Sopenharmony_ci		break;
70562306a36Sopenharmony_ci	default:
70662306a36Sopenharmony_ci		DRM_ERROR("Unsupported asic type: %d!\n", adev->asic_type);
70762306a36Sopenharmony_ci		break;
70862306a36Sopenharmony_ci	}
70962306a36Sopenharmony_ci}
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_civoid soc15_set_virt_ops(struct amdgpu_device *adev)
71262306a36Sopenharmony_ci{
71362306a36Sopenharmony_ci	adev->virt.ops = &xgpu_ai_virt_ops;
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	/* init soc15 reg base early enough so we can
71662306a36Sopenharmony_ci	 * request request full access for sriov before
71762306a36Sopenharmony_ci	 * set_ip_blocks. */
71862306a36Sopenharmony_ci	soc15_reg_base_init(adev);
71962306a36Sopenharmony_ci}
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_cistatic bool soc15_need_full_reset(struct amdgpu_device *adev)
72262306a36Sopenharmony_ci{
72362306a36Sopenharmony_ci	/* change this when we implement soft reset */
72462306a36Sopenharmony_ci	return true;
72562306a36Sopenharmony_ci}
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_cistatic void soc15_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0,
72862306a36Sopenharmony_ci				 uint64_t *count1)
72962306a36Sopenharmony_ci{
73062306a36Sopenharmony_ci	uint32_t perfctr = 0;
73162306a36Sopenharmony_ci	uint64_t cnt0_of, cnt1_of;
73262306a36Sopenharmony_ci	int tmp;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	/* This reports 0 on APUs, so return to avoid writing/reading registers
73562306a36Sopenharmony_ci	 * that may or may not be different from their GPU counterparts
73662306a36Sopenharmony_ci	 */
73762306a36Sopenharmony_ci	if (adev->flags & AMD_IS_APU)
73862306a36Sopenharmony_ci		return;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	/* Set the 2 events that we wish to watch, defined above */
74162306a36Sopenharmony_ci	/* Reg 40 is # received msgs */
74262306a36Sopenharmony_ci	/* Reg 104 is # of posted requests sent */
74362306a36Sopenharmony_ci	perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT0_SEL, 40);
74462306a36Sopenharmony_ci	perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT1_SEL, 104);
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	/* Write to enable desired perf counters */
74762306a36Sopenharmony_ci	WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK, perfctr);
74862306a36Sopenharmony_ci	/* Zero out and enable the perf counters
74962306a36Sopenharmony_ci	 * Write 0x5:
75062306a36Sopenharmony_ci	 * Bit 0 = Start all counters(1)
75162306a36Sopenharmony_ci	 * Bit 2 = Global counter reset enable(1)
75262306a36Sopenharmony_ci	 */
75362306a36Sopenharmony_ci	WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005);
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci	msleep(1000);
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci	/* Load the shadow and disable the perf counters
75862306a36Sopenharmony_ci	 * Write 0x2:
75962306a36Sopenharmony_ci	 * Bit 0 = Stop counters(0)
76062306a36Sopenharmony_ci	 * Bit 1 = Load the shadow counters(1)
76162306a36Sopenharmony_ci	 */
76262306a36Sopenharmony_ci	WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002);
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	/* Read register values to get any >32bit overflow */
76562306a36Sopenharmony_ci	tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK);
76662306a36Sopenharmony_ci	cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER0_UPPER);
76762306a36Sopenharmony_ci	cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER1_UPPER);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	/* Get the values and add the overflow */
77062306a36Sopenharmony_ci	*count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK) | (cnt0_of << 32);
77162306a36Sopenharmony_ci	*count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK) | (cnt1_of << 32);
77262306a36Sopenharmony_ci}
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_cistatic void vega20_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0,
77562306a36Sopenharmony_ci				 uint64_t *count1)
77662306a36Sopenharmony_ci{
77762306a36Sopenharmony_ci	uint32_t perfctr = 0;
77862306a36Sopenharmony_ci	uint64_t cnt0_of, cnt1_of;
77962306a36Sopenharmony_ci	int tmp;
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	/* This reports 0 on APUs, so return to avoid writing/reading registers
78262306a36Sopenharmony_ci	 * that may or may not be different from their GPU counterparts
78362306a36Sopenharmony_ci	 */
78462306a36Sopenharmony_ci	if (adev->flags & AMD_IS_APU)
78562306a36Sopenharmony_ci		return;
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci	/* Set the 2 events that we wish to watch, defined above */
78862306a36Sopenharmony_ci	/* Reg 40 is # received msgs */
78962306a36Sopenharmony_ci	/* Reg 108 is # of posted requests sent on VG20 */
79062306a36Sopenharmony_ci	perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3,
79162306a36Sopenharmony_ci				EVENT0_SEL, 40);
79262306a36Sopenharmony_ci	perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3,
79362306a36Sopenharmony_ci				EVENT1_SEL, 108);
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	/* Write to enable desired perf counters */
79662306a36Sopenharmony_ci	WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3, perfctr);
79762306a36Sopenharmony_ci	/* Zero out and enable the perf counters
79862306a36Sopenharmony_ci	 * Write 0x5:
79962306a36Sopenharmony_ci	 * Bit 0 = Start all counters(1)
80062306a36Sopenharmony_ci	 * Bit 2 = Global counter reset enable(1)
80162306a36Sopenharmony_ci	 */
80262306a36Sopenharmony_ci	WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	msleep(1000);
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	/* Load the shadow and disable the perf counters
80762306a36Sopenharmony_ci	 * Write 0x2:
80862306a36Sopenharmony_ci	 * Bit 0 = Stop counters(0)
80962306a36Sopenharmony_ci	 * Bit 1 = Load the shadow counters(1)
81062306a36Sopenharmony_ci	 */
81162306a36Sopenharmony_ci	WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002);
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	/* Read register values to get any >32bit overflow */
81462306a36Sopenharmony_ci	tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3);
81562306a36Sopenharmony_ci	cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER0_UPPER);
81662306a36Sopenharmony_ci	cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER1_UPPER);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	/* Get the values and add the overflow */
81962306a36Sopenharmony_ci	*count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK3) | (cnt0_of << 32);
82062306a36Sopenharmony_ci	*count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK3) | (cnt1_of << 32);
82162306a36Sopenharmony_ci}
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_cistatic bool soc15_need_reset_on_init(struct amdgpu_device *adev)
82462306a36Sopenharmony_ci{
82562306a36Sopenharmony_ci	u32 sol_reg;
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	/* CP hangs in IGT reloading test on RN, reset to WA */
82862306a36Sopenharmony_ci	if (adev->asic_type == CHIP_RENOIR)
82962306a36Sopenharmony_ci		return true;
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	/* Just return false for soc15 GPUs.  Reset does not seem to
83262306a36Sopenharmony_ci	 * be necessary.
83362306a36Sopenharmony_ci	 */
83462306a36Sopenharmony_ci	if (!amdgpu_passthrough(adev))
83562306a36Sopenharmony_ci		return false;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	if (adev->flags & AMD_IS_APU)
83862306a36Sopenharmony_ci		return false;
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	/* Check sOS sign of life register to confirm sys driver and sOS
84162306a36Sopenharmony_ci	 * are already been loaded.
84262306a36Sopenharmony_ci	 */
84362306a36Sopenharmony_ci	sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
84462306a36Sopenharmony_ci	if (sol_reg)
84562306a36Sopenharmony_ci		return true;
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	return false;
84862306a36Sopenharmony_ci}
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_cistatic uint64_t soc15_get_pcie_replay_count(struct amdgpu_device *adev)
85162306a36Sopenharmony_ci{
85262306a36Sopenharmony_ci	uint64_t nak_r, nak_g;
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci	/* Get the number of NAKs received and generated */
85562306a36Sopenharmony_ci	nak_r = RREG32_PCIE(smnPCIE_RX_NUM_NAK);
85662306a36Sopenharmony_ci	nak_g = RREG32_PCIE(smnPCIE_RX_NUM_NAK_GENERATED);
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	/* Add the total number of NAKs, i.e the number of replays */
85962306a36Sopenharmony_ci	return (nak_r + nak_g);
86062306a36Sopenharmony_ci}
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_cistatic void soc15_pre_asic_init(struct amdgpu_device *adev)
86362306a36Sopenharmony_ci{
86462306a36Sopenharmony_ci	gmc_v9_0_restore_registers(adev);
86562306a36Sopenharmony_ci}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_cistatic const struct amdgpu_asic_funcs soc15_asic_funcs =
86862306a36Sopenharmony_ci{
86962306a36Sopenharmony_ci	.read_disabled_bios = &soc15_read_disabled_bios,
87062306a36Sopenharmony_ci	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
87162306a36Sopenharmony_ci	.read_register = &soc15_read_register,
87262306a36Sopenharmony_ci	.reset = &soc15_asic_reset,
87362306a36Sopenharmony_ci	.reset_method = &soc15_asic_reset_method,
87462306a36Sopenharmony_ci	.get_xclk = &soc15_get_xclk,
87562306a36Sopenharmony_ci	.set_uvd_clocks = &soc15_set_uvd_clocks,
87662306a36Sopenharmony_ci	.set_vce_clocks = &soc15_set_vce_clocks,
87762306a36Sopenharmony_ci	.get_config_memsize = &soc15_get_config_memsize,
87862306a36Sopenharmony_ci	.need_full_reset = &soc15_need_full_reset,
87962306a36Sopenharmony_ci	.init_doorbell_index = &vega10_doorbell_index_init,
88062306a36Sopenharmony_ci	.get_pcie_usage = &soc15_get_pcie_usage,
88162306a36Sopenharmony_ci	.need_reset_on_init = &soc15_need_reset_on_init,
88262306a36Sopenharmony_ci	.get_pcie_replay_count = &soc15_get_pcie_replay_count,
88362306a36Sopenharmony_ci	.supports_baco = &soc15_supports_baco,
88462306a36Sopenharmony_ci	.pre_asic_init = &soc15_pre_asic_init,
88562306a36Sopenharmony_ci	.query_video_codecs = &soc15_query_video_codecs,
88662306a36Sopenharmony_ci};
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_cistatic const struct amdgpu_asic_funcs vega20_asic_funcs =
88962306a36Sopenharmony_ci{
89062306a36Sopenharmony_ci	.read_disabled_bios = &soc15_read_disabled_bios,
89162306a36Sopenharmony_ci	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
89262306a36Sopenharmony_ci	.read_register = &soc15_read_register,
89362306a36Sopenharmony_ci	.reset = &soc15_asic_reset,
89462306a36Sopenharmony_ci	.reset_method = &soc15_asic_reset_method,
89562306a36Sopenharmony_ci	.get_xclk = &soc15_get_xclk,
89662306a36Sopenharmony_ci	.set_uvd_clocks = &soc15_set_uvd_clocks,
89762306a36Sopenharmony_ci	.set_vce_clocks = &soc15_set_vce_clocks,
89862306a36Sopenharmony_ci	.get_config_memsize = &soc15_get_config_memsize,
89962306a36Sopenharmony_ci	.need_full_reset = &soc15_need_full_reset,
90062306a36Sopenharmony_ci	.init_doorbell_index = &vega20_doorbell_index_init,
90162306a36Sopenharmony_ci	.get_pcie_usage = &vega20_get_pcie_usage,
90262306a36Sopenharmony_ci	.need_reset_on_init = &soc15_need_reset_on_init,
90362306a36Sopenharmony_ci	.get_pcie_replay_count = &soc15_get_pcie_replay_count,
90462306a36Sopenharmony_ci	.supports_baco = &soc15_supports_baco,
90562306a36Sopenharmony_ci	.pre_asic_init = &soc15_pre_asic_init,
90662306a36Sopenharmony_ci	.query_video_codecs = &soc15_query_video_codecs,
90762306a36Sopenharmony_ci};
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_cistatic const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs =
91062306a36Sopenharmony_ci{
91162306a36Sopenharmony_ci	.read_disabled_bios = &soc15_read_disabled_bios,
91262306a36Sopenharmony_ci	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
91362306a36Sopenharmony_ci	.read_register = &soc15_read_register,
91462306a36Sopenharmony_ci	.reset = &soc15_asic_reset,
91562306a36Sopenharmony_ci	.reset_method = &soc15_asic_reset_method,
91662306a36Sopenharmony_ci	.get_xclk = &soc15_get_xclk,
91762306a36Sopenharmony_ci	.set_uvd_clocks = &soc15_set_uvd_clocks,
91862306a36Sopenharmony_ci	.set_vce_clocks = &soc15_set_vce_clocks,
91962306a36Sopenharmony_ci	.get_config_memsize = &soc15_get_config_memsize,
92062306a36Sopenharmony_ci	.need_full_reset = &soc15_need_full_reset,
92162306a36Sopenharmony_ci	.init_doorbell_index = &aqua_vanjaram_doorbell_index_init,
92262306a36Sopenharmony_ci	.get_pcie_usage = &amdgpu_nbio_get_pcie_usage,
92362306a36Sopenharmony_ci	.need_reset_on_init = &soc15_need_reset_on_init,
92462306a36Sopenharmony_ci	.get_pcie_replay_count = &amdgpu_nbio_get_pcie_replay_count,
92562306a36Sopenharmony_ci	.supports_baco = &soc15_supports_baco,
92662306a36Sopenharmony_ci	.pre_asic_init = &soc15_pre_asic_init,
92762306a36Sopenharmony_ci	.query_video_codecs = &soc15_query_video_codecs,
92862306a36Sopenharmony_ci	.encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing,
92962306a36Sopenharmony_ci};
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_cistatic int soc15_common_early_init(void *handle)
93262306a36Sopenharmony_ci{
93362306a36Sopenharmony_ci#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
93462306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci	if (!amdgpu_sriov_vf(adev)) {
93762306a36Sopenharmony_ci		adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
93862306a36Sopenharmony_ci		adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
93962306a36Sopenharmony_ci	}
94062306a36Sopenharmony_ci	adev->smc_rreg = NULL;
94162306a36Sopenharmony_ci	adev->smc_wreg = NULL;
94262306a36Sopenharmony_ci	adev->pcie_rreg = &amdgpu_device_indirect_rreg;
94362306a36Sopenharmony_ci	adev->pcie_wreg = &amdgpu_device_indirect_wreg;
94462306a36Sopenharmony_ci	adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext;
94562306a36Sopenharmony_ci	adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;
94662306a36Sopenharmony_ci	adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
94762306a36Sopenharmony_ci	adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
94862306a36Sopenharmony_ci	adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;
94962306a36Sopenharmony_ci	adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
95062306a36Sopenharmony_ci	adev->didt_rreg = &soc15_didt_rreg;
95162306a36Sopenharmony_ci	adev->didt_wreg = &soc15_didt_wreg;
95262306a36Sopenharmony_ci	adev->gc_cac_rreg = &soc15_gc_cac_rreg;
95362306a36Sopenharmony_ci	adev->gc_cac_wreg = &soc15_gc_cac_wreg;
95462306a36Sopenharmony_ci	adev->se_cac_rreg = &soc15_se_cac_rreg;
95562306a36Sopenharmony_ci	adev->se_cac_wreg = &soc15_se_cac_wreg;
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci	adev->rev_id = amdgpu_device_get_rev_id(adev);
95862306a36Sopenharmony_ci	adev->external_rev_id = 0xFF;
95962306a36Sopenharmony_ci	/* TODO: split the GC and PG flags based on the relevant IP version for which
96062306a36Sopenharmony_ci	 * they are relevant.
96162306a36Sopenharmony_ci	 */
96262306a36Sopenharmony_ci	switch (adev->ip_versions[GC_HWIP][0]) {
96362306a36Sopenharmony_ci	case IP_VERSION(9, 0, 1):
96462306a36Sopenharmony_ci		adev->asic_funcs = &soc15_asic_funcs;
96562306a36Sopenharmony_ci		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
96662306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_MGLS |
96762306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_RLC_LS |
96862306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CP_LS |
96962306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_3D_CGCG |
97062306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_3D_CGLS |
97162306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGCG |
97262306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGLS |
97362306a36Sopenharmony_ci			AMD_CG_SUPPORT_BIF_MGCG |
97462306a36Sopenharmony_ci			AMD_CG_SUPPORT_BIF_LS |
97562306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_LS |
97662306a36Sopenharmony_ci			AMD_CG_SUPPORT_DRM_MGCG |
97762306a36Sopenharmony_ci			AMD_CG_SUPPORT_DRM_LS |
97862306a36Sopenharmony_ci			AMD_CG_SUPPORT_ROM_MGCG |
97962306a36Sopenharmony_ci			AMD_CG_SUPPORT_DF_MGCG |
98062306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_MGCG |
98162306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_LS |
98262306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_MGCG |
98362306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_LS;
98462306a36Sopenharmony_ci		adev->pg_flags = 0;
98562306a36Sopenharmony_ci		adev->external_rev_id = 0x1;
98662306a36Sopenharmony_ci		break;
98762306a36Sopenharmony_ci	case IP_VERSION(9, 2, 1):
98862306a36Sopenharmony_ci		adev->asic_funcs = &soc15_asic_funcs;
98962306a36Sopenharmony_ci		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
99062306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_MGLS |
99162306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGCG |
99262306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGLS |
99362306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_3D_CGCG |
99462306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_3D_CGLS |
99562306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CP_LS |
99662306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_LS |
99762306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_MGCG |
99862306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_MGCG |
99962306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_LS |
100062306a36Sopenharmony_ci			AMD_CG_SUPPORT_BIF_MGCG |
100162306a36Sopenharmony_ci			AMD_CG_SUPPORT_BIF_LS |
100262306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_MGCG |
100362306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_LS |
100462306a36Sopenharmony_ci			AMD_CG_SUPPORT_ROM_MGCG |
100562306a36Sopenharmony_ci			AMD_CG_SUPPORT_VCE_MGCG |
100662306a36Sopenharmony_ci			AMD_CG_SUPPORT_UVD_MGCG;
100762306a36Sopenharmony_ci		adev->pg_flags = 0;
100862306a36Sopenharmony_ci		adev->external_rev_id = adev->rev_id + 0x14;
100962306a36Sopenharmony_ci		break;
101062306a36Sopenharmony_ci	case IP_VERSION(9, 4, 0):
101162306a36Sopenharmony_ci		adev->asic_funcs = &vega20_asic_funcs;
101262306a36Sopenharmony_ci		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
101362306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_MGLS |
101462306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGCG |
101562306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGLS |
101662306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_3D_CGCG |
101762306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_3D_CGLS |
101862306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CP_LS |
101962306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_LS |
102062306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_MGCG |
102162306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_MGCG |
102262306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_LS |
102362306a36Sopenharmony_ci			AMD_CG_SUPPORT_BIF_MGCG |
102462306a36Sopenharmony_ci			AMD_CG_SUPPORT_BIF_LS |
102562306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_MGCG |
102662306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_LS |
102762306a36Sopenharmony_ci			AMD_CG_SUPPORT_ROM_MGCG |
102862306a36Sopenharmony_ci			AMD_CG_SUPPORT_VCE_MGCG |
102962306a36Sopenharmony_ci			AMD_CG_SUPPORT_UVD_MGCG;
103062306a36Sopenharmony_ci		adev->pg_flags = 0;
103162306a36Sopenharmony_ci		adev->external_rev_id = adev->rev_id + 0x28;
103262306a36Sopenharmony_ci		break;
103362306a36Sopenharmony_ci	case IP_VERSION(9, 1, 0):
103462306a36Sopenharmony_ci	case IP_VERSION(9, 2, 2):
103562306a36Sopenharmony_ci		adev->asic_funcs = &soc15_asic_funcs;
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci		if (adev->rev_id >= 0x8)
103862306a36Sopenharmony_ci			adev->apu_flags |= AMD_APU_IS_RAVEN2;
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci		if (adev->apu_flags & AMD_APU_IS_RAVEN2)
104162306a36Sopenharmony_ci			adev->external_rev_id = adev->rev_id + 0x79;
104262306a36Sopenharmony_ci		else if (adev->apu_flags & AMD_APU_IS_PICASSO)
104362306a36Sopenharmony_ci			adev->external_rev_id = adev->rev_id + 0x41;
104462306a36Sopenharmony_ci		else if (adev->rev_id == 1)
104562306a36Sopenharmony_ci			adev->external_rev_id = adev->rev_id + 0x20;
104662306a36Sopenharmony_ci		else
104762306a36Sopenharmony_ci			adev->external_rev_id = adev->rev_id + 0x01;
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci		if (adev->apu_flags & AMD_APU_IS_RAVEN2) {
105062306a36Sopenharmony_ci			adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
105162306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_MGLS |
105262306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CP_LS |
105362306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_3D_CGCG |
105462306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_3D_CGLS |
105562306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CGCG |
105662306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CGLS |
105762306a36Sopenharmony_ci				AMD_CG_SUPPORT_BIF_LS |
105862306a36Sopenharmony_ci				AMD_CG_SUPPORT_HDP_LS |
105962306a36Sopenharmony_ci				AMD_CG_SUPPORT_MC_MGCG |
106062306a36Sopenharmony_ci				AMD_CG_SUPPORT_MC_LS |
106162306a36Sopenharmony_ci				AMD_CG_SUPPORT_SDMA_MGCG |
106262306a36Sopenharmony_ci				AMD_CG_SUPPORT_SDMA_LS |
106362306a36Sopenharmony_ci				AMD_CG_SUPPORT_VCN_MGCG;
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci			adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN;
106662306a36Sopenharmony_ci		} else if (adev->apu_flags & AMD_APU_IS_PICASSO) {
106762306a36Sopenharmony_ci			adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
106862306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_MGLS |
106962306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CP_LS |
107062306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_3D_CGLS |
107162306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CGCG |
107262306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CGLS |
107362306a36Sopenharmony_ci				AMD_CG_SUPPORT_BIF_LS |
107462306a36Sopenharmony_ci				AMD_CG_SUPPORT_HDP_LS |
107562306a36Sopenharmony_ci				AMD_CG_SUPPORT_MC_MGCG |
107662306a36Sopenharmony_ci				AMD_CG_SUPPORT_MC_LS |
107762306a36Sopenharmony_ci				AMD_CG_SUPPORT_SDMA_MGCG |
107862306a36Sopenharmony_ci				AMD_CG_SUPPORT_SDMA_LS |
107962306a36Sopenharmony_ci				AMD_CG_SUPPORT_VCN_MGCG;
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci			/*
108262306a36Sopenharmony_ci			 * MMHUB PG needs to be disabled for Picasso for
108362306a36Sopenharmony_ci			 * stability reasons.
108462306a36Sopenharmony_ci			 */
108562306a36Sopenharmony_ci			adev->pg_flags = AMD_PG_SUPPORT_SDMA |
108662306a36Sopenharmony_ci				AMD_PG_SUPPORT_VCN;
108762306a36Sopenharmony_ci		} else {
108862306a36Sopenharmony_ci			adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
108962306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_MGLS |
109062306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_RLC_LS |
109162306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CP_LS |
109262306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_3D_CGLS |
109362306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CGCG |
109462306a36Sopenharmony_ci				AMD_CG_SUPPORT_GFX_CGLS |
109562306a36Sopenharmony_ci				AMD_CG_SUPPORT_BIF_MGCG |
109662306a36Sopenharmony_ci				AMD_CG_SUPPORT_BIF_LS |
109762306a36Sopenharmony_ci				AMD_CG_SUPPORT_HDP_MGCG |
109862306a36Sopenharmony_ci				AMD_CG_SUPPORT_HDP_LS |
109962306a36Sopenharmony_ci				AMD_CG_SUPPORT_DRM_MGCG |
110062306a36Sopenharmony_ci				AMD_CG_SUPPORT_DRM_LS |
110162306a36Sopenharmony_ci				AMD_CG_SUPPORT_MC_MGCG |
110262306a36Sopenharmony_ci				AMD_CG_SUPPORT_MC_LS |
110362306a36Sopenharmony_ci				AMD_CG_SUPPORT_SDMA_MGCG |
110462306a36Sopenharmony_ci				AMD_CG_SUPPORT_SDMA_LS |
110562306a36Sopenharmony_ci				AMD_CG_SUPPORT_VCN_MGCG;
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci			adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN;
110862306a36Sopenharmony_ci		}
110962306a36Sopenharmony_ci		break;
111062306a36Sopenharmony_ci	case IP_VERSION(9, 4, 1):
111162306a36Sopenharmony_ci		adev->asic_funcs = &vega20_asic_funcs;
111262306a36Sopenharmony_ci		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
111362306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_MGLS |
111462306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGCG |
111562306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGLS |
111662306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CP_LS |
111762306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_MGCG |
111862306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_LS |
111962306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_MGCG |
112062306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_LS |
112162306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_MGCG |
112262306a36Sopenharmony_ci			AMD_CG_SUPPORT_MC_LS |
112362306a36Sopenharmony_ci			AMD_CG_SUPPORT_IH_CG |
112462306a36Sopenharmony_ci			AMD_CG_SUPPORT_VCN_MGCG |
112562306a36Sopenharmony_ci			AMD_CG_SUPPORT_JPEG_MGCG;
112662306a36Sopenharmony_ci		adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG;
112762306a36Sopenharmony_ci		adev->external_rev_id = adev->rev_id + 0x32;
112862306a36Sopenharmony_ci		break;
112962306a36Sopenharmony_ci	case IP_VERSION(9, 3, 0):
113062306a36Sopenharmony_ci		adev->asic_funcs = &soc15_asic_funcs;
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci		if (adev->apu_flags & AMD_APU_IS_RENOIR)
113362306a36Sopenharmony_ci			adev->external_rev_id = adev->rev_id + 0x91;
113462306a36Sopenharmony_ci		else
113562306a36Sopenharmony_ci			adev->external_rev_id = adev->rev_id + 0xa1;
113662306a36Sopenharmony_ci		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
113762306a36Sopenharmony_ci				 AMD_CG_SUPPORT_GFX_MGLS |
113862306a36Sopenharmony_ci				 AMD_CG_SUPPORT_GFX_3D_CGCG |
113962306a36Sopenharmony_ci				 AMD_CG_SUPPORT_GFX_3D_CGLS |
114062306a36Sopenharmony_ci				 AMD_CG_SUPPORT_GFX_CGCG |
114162306a36Sopenharmony_ci				 AMD_CG_SUPPORT_GFX_CGLS |
114262306a36Sopenharmony_ci				 AMD_CG_SUPPORT_GFX_CP_LS |
114362306a36Sopenharmony_ci				 AMD_CG_SUPPORT_MC_MGCG |
114462306a36Sopenharmony_ci				 AMD_CG_SUPPORT_MC_LS |
114562306a36Sopenharmony_ci				 AMD_CG_SUPPORT_SDMA_MGCG |
114662306a36Sopenharmony_ci				 AMD_CG_SUPPORT_SDMA_LS |
114762306a36Sopenharmony_ci				 AMD_CG_SUPPORT_BIF_LS |
114862306a36Sopenharmony_ci				 AMD_CG_SUPPORT_HDP_LS |
114962306a36Sopenharmony_ci				 AMD_CG_SUPPORT_VCN_MGCG |
115062306a36Sopenharmony_ci				 AMD_CG_SUPPORT_JPEG_MGCG |
115162306a36Sopenharmony_ci				 AMD_CG_SUPPORT_IH_CG |
115262306a36Sopenharmony_ci				 AMD_CG_SUPPORT_ATHUB_LS |
115362306a36Sopenharmony_ci				 AMD_CG_SUPPORT_ATHUB_MGCG |
115462306a36Sopenharmony_ci				 AMD_CG_SUPPORT_DF_MGCG;
115562306a36Sopenharmony_ci		adev->pg_flags = AMD_PG_SUPPORT_SDMA |
115662306a36Sopenharmony_ci				 AMD_PG_SUPPORT_VCN |
115762306a36Sopenharmony_ci				 AMD_PG_SUPPORT_JPEG |
115862306a36Sopenharmony_ci				 AMD_PG_SUPPORT_VCN_DPG;
115962306a36Sopenharmony_ci		break;
116062306a36Sopenharmony_ci	case IP_VERSION(9, 4, 2):
116162306a36Sopenharmony_ci		adev->asic_funcs = &vega20_asic_funcs;
116262306a36Sopenharmony_ci		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
116362306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_MGLS |
116462306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CP_LS |
116562306a36Sopenharmony_ci			AMD_CG_SUPPORT_HDP_LS |
116662306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_MGCG |
116762306a36Sopenharmony_ci			AMD_CG_SUPPORT_SDMA_LS |
116862306a36Sopenharmony_ci			AMD_CG_SUPPORT_IH_CG |
116962306a36Sopenharmony_ci			AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG;
117062306a36Sopenharmony_ci		adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG;
117162306a36Sopenharmony_ci		adev->external_rev_id = adev->rev_id + 0x3c;
117262306a36Sopenharmony_ci		break;
117362306a36Sopenharmony_ci	case IP_VERSION(9, 4, 3):
117462306a36Sopenharmony_ci		adev->asic_funcs = &aqua_vanjaram_asic_funcs;
117562306a36Sopenharmony_ci		adev->cg_flags =
117662306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG |
117762306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_SDMA_MGCG |
117862306a36Sopenharmony_ci			AMD_CG_SUPPORT_GFX_FGCG | AMD_CG_SUPPORT_REPEATER_FGCG |
117962306a36Sopenharmony_ci			AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG |
118062306a36Sopenharmony_ci			AMD_CG_SUPPORT_IH_CG;
118162306a36Sopenharmony_ci		adev->pg_flags =
118262306a36Sopenharmony_ci			AMD_PG_SUPPORT_VCN |
118362306a36Sopenharmony_ci			AMD_PG_SUPPORT_VCN_DPG |
118462306a36Sopenharmony_ci			AMD_PG_SUPPORT_JPEG;
118562306a36Sopenharmony_ci		adev->external_rev_id = adev->rev_id + 0x46;
118662306a36Sopenharmony_ci		/* GC 9.4.3 uses MMIO register region hole at a different offset */
118762306a36Sopenharmony_ci		if (!amdgpu_sriov_vf(adev)) {
118862306a36Sopenharmony_ci			adev->rmmio_remap.reg_offset = 0x1A000;
118962306a36Sopenharmony_ci			adev->rmmio_remap.bus_addr = adev->rmmio_base + 0x1A000;
119062306a36Sopenharmony_ci		}
119162306a36Sopenharmony_ci		break;
119262306a36Sopenharmony_ci	default:
119362306a36Sopenharmony_ci		/* FIXME: not supported yet */
119462306a36Sopenharmony_ci		return -EINVAL;
119562306a36Sopenharmony_ci	}
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	if (amdgpu_sriov_vf(adev)) {
119862306a36Sopenharmony_ci		amdgpu_virt_init_setting(adev);
119962306a36Sopenharmony_ci		xgpu_ai_mailbox_set_irq_funcs(adev);
120062306a36Sopenharmony_ci	}
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	return 0;
120362306a36Sopenharmony_ci}
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_cistatic int soc15_common_late_init(void *handle)
120662306a36Sopenharmony_ci{
120762306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci	if (amdgpu_sriov_vf(adev))
121062306a36Sopenharmony_ci		xgpu_ai_mailbox_get_irq(adev);
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci	/* Enable selfring doorbell aperture late because doorbell BAR
121362306a36Sopenharmony_ci	 * aperture will change if resize BAR successfully in gmc sw_init.
121462306a36Sopenharmony_ci	 */
121562306a36Sopenharmony_ci	adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, true);
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci	return 0;
121862306a36Sopenharmony_ci}
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_cistatic int soc15_common_sw_init(void *handle)
122162306a36Sopenharmony_ci{
122262306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci	if (amdgpu_sriov_vf(adev))
122562306a36Sopenharmony_ci		xgpu_ai_mailbox_add_irq_id(adev);
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci	if (adev->df.funcs &&
122862306a36Sopenharmony_ci	    adev->df.funcs->sw_init)
122962306a36Sopenharmony_ci		adev->df.funcs->sw_init(adev);
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	return 0;
123262306a36Sopenharmony_ci}
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_cistatic int soc15_common_sw_fini(void *handle)
123562306a36Sopenharmony_ci{
123662306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci	if (adev->df.funcs &&
123962306a36Sopenharmony_ci	    adev->df.funcs->sw_fini)
124062306a36Sopenharmony_ci		adev->df.funcs->sw_fini(adev);
124162306a36Sopenharmony_ci	return 0;
124262306a36Sopenharmony_ci}
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_cistatic void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev)
124562306a36Sopenharmony_ci{
124662306a36Sopenharmony_ci	int i;
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci	/* sdma doorbell range is programed by hypervisor */
124962306a36Sopenharmony_ci	if (!amdgpu_sriov_vf(adev)) {
125062306a36Sopenharmony_ci		for (i = 0; i < adev->sdma.num_instances; i++) {
125162306a36Sopenharmony_ci			adev->nbio.funcs->sdma_doorbell_range(adev, i,
125262306a36Sopenharmony_ci				true, adev->doorbell_index.sdma_engine[i] << 1,
125362306a36Sopenharmony_ci				adev->doorbell_index.sdma_doorbell_range);
125462306a36Sopenharmony_ci		}
125562306a36Sopenharmony_ci	}
125662306a36Sopenharmony_ci}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_cistatic int soc15_common_hw_init(void *handle)
125962306a36Sopenharmony_ci{
126062306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci	/* enable aspm */
126362306a36Sopenharmony_ci	soc15_program_aspm(adev);
126462306a36Sopenharmony_ci	/* setup nbio registers */
126562306a36Sopenharmony_ci	adev->nbio.funcs->init_registers(adev);
126662306a36Sopenharmony_ci	/* remap HDP registers to a hole in mmio space,
126762306a36Sopenharmony_ci	 * for the purpose of expose those registers
126862306a36Sopenharmony_ci	 * to process space
126962306a36Sopenharmony_ci	 */
127062306a36Sopenharmony_ci	if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev))
127162306a36Sopenharmony_ci		adev->nbio.funcs->remap_hdp_registers(adev);
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	/* enable the doorbell aperture */
127462306a36Sopenharmony_ci	adev->nbio.funcs->enable_doorbell_aperture(adev, true);
127562306a36Sopenharmony_ci
127662306a36Sopenharmony_ci	/* HW doorbell routing policy: doorbell writing not
127762306a36Sopenharmony_ci	 * in SDMA/IH/MM/ACV range will be routed to CP. So
127862306a36Sopenharmony_ci	 * we need to init SDMA doorbell range prior
127962306a36Sopenharmony_ci	 * to CP ip block init and ring test.  IH already
128062306a36Sopenharmony_ci	 * happens before CP.
128162306a36Sopenharmony_ci	 */
128262306a36Sopenharmony_ci	soc15_sdma_doorbell_range_init(adev);
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	return 0;
128562306a36Sopenharmony_ci}
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_cistatic int soc15_common_hw_fini(void *handle)
128862306a36Sopenharmony_ci{
128962306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	/* Disable the doorbell aperture and selfring doorbell aperture
129262306a36Sopenharmony_ci	 * separately in hw_fini because soc15_enable_doorbell_aperture
129362306a36Sopenharmony_ci	 * has been removed and there is no need to delay disabling
129462306a36Sopenharmony_ci	 * selfring doorbell.
129562306a36Sopenharmony_ci	 */
129662306a36Sopenharmony_ci	adev->nbio.funcs->enable_doorbell_aperture(adev, false);
129762306a36Sopenharmony_ci	adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, false);
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ci	if (amdgpu_sriov_vf(adev))
130062306a36Sopenharmony_ci		xgpu_ai_mailbox_put_irq(adev);
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci	if (adev->nbio.ras_if &&
130362306a36Sopenharmony_ci	    amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) {
130462306a36Sopenharmony_ci		if (adev->nbio.ras &&
130562306a36Sopenharmony_ci		    adev->nbio.ras->init_ras_controller_interrupt)
130662306a36Sopenharmony_ci			amdgpu_irq_put(adev, &adev->nbio.ras_controller_irq, 0);
130762306a36Sopenharmony_ci		if (adev->nbio.ras &&
130862306a36Sopenharmony_ci		    adev->nbio.ras->init_ras_err_event_athub_interrupt)
130962306a36Sopenharmony_ci			amdgpu_irq_put(adev, &adev->nbio.ras_err_event_athub_irq, 0);
131062306a36Sopenharmony_ci	}
131162306a36Sopenharmony_ci
131262306a36Sopenharmony_ci	return 0;
131362306a36Sopenharmony_ci}
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_cistatic int soc15_common_suspend(void *handle)
131662306a36Sopenharmony_ci{
131762306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	return soc15_common_hw_fini(adev);
132062306a36Sopenharmony_ci}
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_cistatic int soc15_common_resume(void *handle)
132362306a36Sopenharmony_ci{
132462306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci	if (soc15_need_reset_on_resume(adev)) {
132762306a36Sopenharmony_ci		dev_info(adev->dev, "S3 suspend abort case, let's reset ASIC.\n");
132862306a36Sopenharmony_ci		soc15_asic_reset(adev);
132962306a36Sopenharmony_ci	}
133062306a36Sopenharmony_ci	return soc15_common_hw_init(adev);
133162306a36Sopenharmony_ci}
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_cistatic bool soc15_common_is_idle(void *handle)
133462306a36Sopenharmony_ci{
133562306a36Sopenharmony_ci	return true;
133662306a36Sopenharmony_ci}
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_cistatic int soc15_common_wait_for_idle(void *handle)
133962306a36Sopenharmony_ci{
134062306a36Sopenharmony_ci	return 0;
134162306a36Sopenharmony_ci}
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_cistatic int soc15_common_soft_reset(void *handle)
134462306a36Sopenharmony_ci{
134562306a36Sopenharmony_ci	return 0;
134662306a36Sopenharmony_ci}
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_cistatic void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable)
134962306a36Sopenharmony_ci{
135062306a36Sopenharmony_ci	uint32_t def, data;
135162306a36Sopenharmony_ci
135262306a36Sopenharmony_ci	def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0));
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_MGCG))
135562306a36Sopenharmony_ci		data &= ~(0x01000000 |
135662306a36Sopenharmony_ci			  0x02000000 |
135762306a36Sopenharmony_ci			  0x04000000 |
135862306a36Sopenharmony_ci			  0x08000000 |
135962306a36Sopenharmony_ci			  0x10000000 |
136062306a36Sopenharmony_ci			  0x20000000 |
136162306a36Sopenharmony_ci			  0x40000000 |
136262306a36Sopenharmony_ci			  0x80000000);
136362306a36Sopenharmony_ci	else
136462306a36Sopenharmony_ci		data |= (0x01000000 |
136562306a36Sopenharmony_ci			 0x02000000 |
136662306a36Sopenharmony_ci			 0x04000000 |
136762306a36Sopenharmony_ci			 0x08000000 |
136862306a36Sopenharmony_ci			 0x10000000 |
136962306a36Sopenharmony_ci			 0x20000000 |
137062306a36Sopenharmony_ci			 0x40000000 |
137162306a36Sopenharmony_ci			 0x80000000);
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci	if (def != data)
137462306a36Sopenharmony_ci		WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0), data);
137562306a36Sopenharmony_ci}
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_cistatic void soc15_update_drm_light_sleep(struct amdgpu_device *adev, bool enable)
137862306a36Sopenharmony_ci{
137962306a36Sopenharmony_ci	uint32_t def, data;
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci	def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL));
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_ci	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS))
138462306a36Sopenharmony_ci		data |= 1;
138562306a36Sopenharmony_ci	else
138662306a36Sopenharmony_ci		data &= ~1;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	if (def != data)
138962306a36Sopenharmony_ci		WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL), data);
139062306a36Sopenharmony_ci}
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_cistatic int soc15_common_set_clockgating_state(void *handle,
139362306a36Sopenharmony_ci					    enum amd_clockgating_state state)
139462306a36Sopenharmony_ci{
139562306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	if (amdgpu_sriov_vf(adev))
139862306a36Sopenharmony_ci		return 0;
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci	switch (adev->ip_versions[NBIO_HWIP][0]) {
140162306a36Sopenharmony_ci	case IP_VERSION(6, 1, 0):
140262306a36Sopenharmony_ci	case IP_VERSION(6, 2, 0):
140362306a36Sopenharmony_ci	case IP_VERSION(7, 4, 0):
140462306a36Sopenharmony_ci		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
140562306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
140662306a36Sopenharmony_ci		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
140762306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
140862306a36Sopenharmony_ci		adev->hdp.funcs->update_clock_gating(adev,
140962306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
141062306a36Sopenharmony_ci		soc15_update_drm_clock_gating(adev,
141162306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
141262306a36Sopenharmony_ci		soc15_update_drm_light_sleep(adev,
141362306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
141462306a36Sopenharmony_ci		adev->smuio.funcs->update_rom_clock_gating(adev,
141562306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
141662306a36Sopenharmony_ci		adev->df.funcs->update_medium_grain_clock_gating(adev,
141762306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
141862306a36Sopenharmony_ci		break;
141962306a36Sopenharmony_ci	case IP_VERSION(7, 0, 0):
142062306a36Sopenharmony_ci	case IP_VERSION(7, 0, 1):
142162306a36Sopenharmony_ci	case IP_VERSION(2, 5, 0):
142262306a36Sopenharmony_ci		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
142362306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
142462306a36Sopenharmony_ci		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
142562306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
142662306a36Sopenharmony_ci		adev->hdp.funcs->update_clock_gating(adev,
142762306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
142862306a36Sopenharmony_ci		soc15_update_drm_clock_gating(adev,
142962306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
143062306a36Sopenharmony_ci		soc15_update_drm_light_sleep(adev,
143162306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
143262306a36Sopenharmony_ci		break;
143362306a36Sopenharmony_ci	case IP_VERSION(7, 4, 1):
143462306a36Sopenharmony_ci	case IP_VERSION(7, 4, 4):
143562306a36Sopenharmony_ci		adev->hdp.funcs->update_clock_gating(adev,
143662306a36Sopenharmony_ci				state == AMD_CG_STATE_GATE);
143762306a36Sopenharmony_ci		break;
143862306a36Sopenharmony_ci	default:
143962306a36Sopenharmony_ci		break;
144062306a36Sopenharmony_ci	}
144162306a36Sopenharmony_ci	return 0;
144262306a36Sopenharmony_ci}
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_cistatic void soc15_common_get_clockgating_state(void *handle, u64 *flags)
144562306a36Sopenharmony_ci{
144662306a36Sopenharmony_ci	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
144762306a36Sopenharmony_ci	int data;
144862306a36Sopenharmony_ci
144962306a36Sopenharmony_ci	if (amdgpu_sriov_vf(adev))
145062306a36Sopenharmony_ci		*flags = 0;
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci	if (adev->nbio.funcs && adev->nbio.funcs->get_clockgating_state)
145362306a36Sopenharmony_ci		adev->nbio.funcs->get_clockgating_state(adev, flags);
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ci	if (adev->hdp.funcs && adev->hdp.funcs->get_clock_gating_state)
145662306a36Sopenharmony_ci		adev->hdp.funcs->get_clock_gating_state(adev, flags);
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci	if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(13, 0, 2)) {
145962306a36Sopenharmony_ci
146062306a36Sopenharmony_ci		/* AMD_CG_SUPPORT_DRM_MGCG */
146162306a36Sopenharmony_ci		data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0));
146262306a36Sopenharmony_ci		if (!(data & 0x01000000))
146362306a36Sopenharmony_ci			*flags |= AMD_CG_SUPPORT_DRM_MGCG;
146462306a36Sopenharmony_ci
146562306a36Sopenharmony_ci		/* AMD_CG_SUPPORT_DRM_LS */
146662306a36Sopenharmony_ci		data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL));
146762306a36Sopenharmony_ci		if (data & 0x1)
146862306a36Sopenharmony_ci			*flags |= AMD_CG_SUPPORT_DRM_LS;
146962306a36Sopenharmony_ci	}
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci	/* AMD_CG_SUPPORT_ROM_MGCG */
147262306a36Sopenharmony_ci	if (adev->smuio.funcs && adev->smuio.funcs->get_clock_gating_state)
147362306a36Sopenharmony_ci		adev->smuio.funcs->get_clock_gating_state(adev, flags);
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ci	if (adev->df.funcs && adev->df.funcs->get_clockgating_state)
147662306a36Sopenharmony_ci		adev->df.funcs->get_clockgating_state(adev, flags);
147762306a36Sopenharmony_ci}
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_cistatic int soc15_common_set_powergating_state(void *handle,
148062306a36Sopenharmony_ci					    enum amd_powergating_state state)
148162306a36Sopenharmony_ci{
148262306a36Sopenharmony_ci	/* todo */
148362306a36Sopenharmony_ci	return 0;
148462306a36Sopenharmony_ci}
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_cistatic const struct amd_ip_funcs soc15_common_ip_funcs = {
148762306a36Sopenharmony_ci	.name = "soc15_common",
148862306a36Sopenharmony_ci	.early_init = soc15_common_early_init,
148962306a36Sopenharmony_ci	.late_init = soc15_common_late_init,
149062306a36Sopenharmony_ci	.sw_init = soc15_common_sw_init,
149162306a36Sopenharmony_ci	.sw_fini = soc15_common_sw_fini,
149262306a36Sopenharmony_ci	.hw_init = soc15_common_hw_init,
149362306a36Sopenharmony_ci	.hw_fini = soc15_common_hw_fini,
149462306a36Sopenharmony_ci	.suspend = soc15_common_suspend,
149562306a36Sopenharmony_ci	.resume = soc15_common_resume,
149662306a36Sopenharmony_ci	.is_idle = soc15_common_is_idle,
149762306a36Sopenharmony_ci	.wait_for_idle = soc15_common_wait_for_idle,
149862306a36Sopenharmony_ci	.soft_reset = soc15_common_soft_reset,
149962306a36Sopenharmony_ci	.set_clockgating_state = soc15_common_set_clockgating_state,
150062306a36Sopenharmony_ci	.set_powergating_state = soc15_common_set_powergating_state,
150162306a36Sopenharmony_ci	.get_clockgating_state= soc15_common_get_clockgating_state,
150262306a36Sopenharmony_ci};
1503