1f39f5bb1SXiaojie Yuan /*
2178ad3a9SSonny Jiang  * Copyright 2018-2024 Advanced Micro Devices, Inc. All rights reserved.
3f39f5bb1SXiaojie Yuan  *
4f39f5bb1SXiaojie Yuan  * Permission is hereby granted, free of charge, to any person obtaining a
5f39f5bb1SXiaojie Yuan  * copy of this software and associated documentation files (the "Software"),
6f39f5bb1SXiaojie Yuan  * to deal in the Software without restriction, including without limitation
7f39f5bb1SXiaojie Yuan  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f39f5bb1SXiaojie Yuan  * and/or sell copies of the Software, and to permit persons to whom the
9f39f5bb1SXiaojie Yuan  * Software is furnished to do so, subject to the following conditions:
10f39f5bb1SXiaojie Yuan  *
11f39f5bb1SXiaojie Yuan  * The above copyright notice and this permission notice shall be included in
12f39f5bb1SXiaojie Yuan  * all copies or substantial portions of the Software.
13f39f5bb1SXiaojie Yuan  *
14f39f5bb1SXiaojie Yuan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f39f5bb1SXiaojie Yuan  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f39f5bb1SXiaojie Yuan  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17f39f5bb1SXiaojie Yuan  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18f39f5bb1SXiaojie Yuan  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19f39f5bb1SXiaojie Yuan  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20f39f5bb1SXiaojie Yuan  * OTHER DEALINGS IN THE SOFTWARE.
21f39f5bb1SXiaojie Yuan  *
22f39f5bb1SXiaojie Yuan  */
23f39f5bb1SXiaojie Yuan 
24a79d3709SAlex Deucher #include <linux/firmware.h>
25a79d3709SAlex Deucher 
26f39f5bb1SXiaojie Yuan #include "amdgpu.h"
27f39f5bb1SXiaojie Yuan #include "amdgpu_discovery.h"
28f39f5bb1SXiaojie Yuan #include "soc15_hw_ip.h"
29f39f5bb1SXiaojie Yuan #include "discovery.h"
30c8cb7e09SHawking Zhang #include "amdgpu_ras.h"
31f39f5bb1SXiaojie Yuan 
32d4c6e870SAlex Deucher #include "soc15.h"
33d4c6e870SAlex Deucher #include "gfx_v9_0.h"
34c796d7e0SShiwu Zhang #include "gfx_v9_4_3.h"
35d4c6e870SAlex Deucher #include "gmc_v9_0.h"
36d4c6e870SAlex Deucher #include "df_v1_7.h"
37d4c6e870SAlex Deucher #include "df_v3_6.h"
38e4f665deSCandice Li #include "df_v4_3.h"
392cea7bb9STao Zhou #include "df_v4_6_2.h"
40666f14caSDavid Belanger #include "df_v4_15.h"
41d4c6e870SAlex Deucher #include "nbio_v6_1.h"
42d4c6e870SAlex Deucher #include "nbio_v7_0.h"
43d4c6e870SAlex Deucher #include "nbio_v7_4.h"
445d55e1d0SHawking Zhang #include "nbio_v7_9.h"
45d9d68334SPrike Liang #include "nbio_v7_11.h"
46d4c6e870SAlex Deucher #include "hdp_v4_0.h"
47d4c6e870SAlex Deucher #include "vega10_ih.h"
48d4c6e870SAlex Deucher #include "vega20_ih.h"
49d4c6e870SAlex Deucher #include "sdma_v4_0.h"
50051ae8d5SLe Ma #include "sdma_v4_4_2.h"
51d4c6e870SAlex Deucher #include "uvd_v7_0.h"
52d4c6e870SAlex Deucher #include "vce_v4_0.h"
53d4c6e870SAlex Deucher #include "vcn_v1_0.h"
54d4c6e870SAlex Deucher #include "vcn_v2_5.h"
55d4c6e870SAlex Deucher #include "jpeg_v2_5.h"
56d4c6e870SAlex Deucher #include "smuio_v9_0.h"
57795d0839SAlex Deucher #include "gmc_v10_0.h"
580984d384SLikun Gao #include "gmc_v11_0.h"
591b838189SLikun Gao #include "gmc_v12_0.h"
60795d0839SAlex Deucher #include "gfxhub_v2_0.h"
61795d0839SAlex Deucher #include "mmhub_v2_0.h"
62795d0839SAlex Deucher #include "nbio_v2_3.h"
632c0e7dddSLikun Gao #include "nbio_v4_3.h"
64795d0839SAlex Deucher #include "nbio_v7_2.h"
650c1e5527SXiaojian Du #include "nbio_v7_7.h"
6679698b14SLikun Gao #include "nbif_v6_3_1.h"
67795d0839SAlex Deucher #include "hdp_v5_0.h"
686e9e59e2SXiaojian Du #include "hdp_v5_2.h"
691761e5efSLikun Gao #include "hdp_v6_0.h"
70ca46c259SLikun Gao #include "hdp_v7_0.h"
71795d0839SAlex Deucher #include "nv.h"
72759693acSLikun Gao #include "soc21.h"
73d22c0756SLikun Gao #include "soc24.h"
74795d0839SAlex Deucher #include "navi10_ih.h"
752929a6bfSLikun Gao #include "ih_v6_0.h"
764c340d00SPrike Liang #include "ih_v6_1.h"
7756018e83SLikun Gao #include "ih_v7_0.h"
78795d0839SAlex Deucher #include "gfx_v10_0.h"
79f6abd4d9SLikun Gao #include "gfx_v11_0.h"
805e676d71SLikun Gao #include "gfx_v12_0.h"
81795d0839SAlex Deucher #include "sdma_v5_0.h"
82795d0839SAlex Deucher #include "sdma_v5_2.h"
838143b87cSStanley Yang #include "sdma_v6_0.h"
84f45ed399SLikun Gao #include "sdma_v7_0.h"
851b491330SLikun Gao #include "lsdma_v6_0.h"
8639df603dSLikun Gao #include "lsdma_v7_0.h"
87795d0839SAlex Deucher #include "vcn_v2_0.h"
88795d0839SAlex Deucher #include "jpeg_v2_0.h"
89795d0839SAlex Deucher #include "vcn_v3_0.h"
90795d0839SAlex Deucher #include "jpeg_v3_0.h"
91d6ffefccSJames Zhu #include "vcn_v4_0.h"
92d6ffefccSJames Zhu #include "jpeg_v4_0.h"
93ed1f42f0SJames Zhu #include "vcn_v4_0_3.h"
94ed1f42f0SJames Zhu #include "jpeg_v4_0_3.h"
95844d8dd5SSaleemkhan Jamadar #include "vcn_v4_0_5.h"
96844d8dd5SSaleemkhan Jamadar #include "jpeg_v4_0_5.h"
97795d0839SAlex Deucher #include "amdgpu_vkms.h"
98e97b0720SAlex Deucher #include "mes_v11_0.h"
990a75dc98SLikun Gao #include "mes_v12_0.h"
100795d0839SAlex Deucher #include "smuio_v11_0.h"
101795d0839SAlex Deucher #include "smuio_v11_0_6.h"
102d4c6e870SAlex Deucher #include "smuio_v13_0.h"
1036b7ec18bSHawking Zhang #include "smuio_v13_0_3.h"
104996ea859SHawking Zhang #include "smuio_v13_0_6.h"
105a61e2ce9SHawking Zhang #include "smuio_v14_0_2.h"
106470675f6SSonny Jiang #include "vcn_v5_0_0.h"
107178ad3a9SSonny Jiang #include "vcn_v5_0_1.h"
108cff99603SSonny Jiang #include "jpeg_v5_0_0.h"
109c406fca4SSathishkumar S #include "jpeg_v5_0_1.h"
110795d0839SAlex Deucher 
1113ee8fb70SLang Yu #include "amdgpu_vpe.h"
1128930b90bSAlex Deucher #if defined(CONFIG_DRM_AMD_ISP)
113d232584aSPratap Nirujogi #include "amdgpu_isp.h"
1148930b90bSAlex Deucher #endif
1153ee8fb70SLang Yu 
116017fbb66SFlora Cui MODULE_FIRMWARE("amdgpu/ip_discovery.bin");
11725f602fbSFlora Cui MODULE_FIRMWARE("amdgpu/vega10_ip_discovery.bin");
11825f602fbSFlora Cui MODULE_FIRMWARE("amdgpu/vega12_ip_discovery.bin");
11925f602fbSFlora Cui MODULE_FIRMWARE("amdgpu/vega20_ip_discovery.bin");
12025f602fbSFlora Cui MODULE_FIRMWARE("amdgpu/raven_ip_discovery.bin");
12125f602fbSFlora Cui MODULE_FIRMWARE("amdgpu/raven2_ip_discovery.bin");
12225f602fbSFlora Cui MODULE_FIRMWARE("amdgpu/picasso_ip_discovery.bin");
123*2f6dd741SFlora Cui MODULE_FIRMWARE("amdgpu/arcturus_ip_discovery.bin");
124*2f6dd741SFlora Cui MODULE_FIRMWARE("amdgpu/aldebaran_ip_discovery.bin");
125a79d3709SAlex Deucher 
126c8cb7e09SHawking Zhang #define mmIP_DISCOVERY_VERSION  0x16A00
12785f267a7SXiaojie Yuan #define mmRCC_CONFIG_MEMSIZE	0xde3
1283938eb95SAlex Deucher #define mmMP0_SMN_C2PMSG_33	0x16061
129f39f5bb1SXiaojie Yuan #define mmMM_INDEX		0x0
130f39f5bb1SXiaojie Yuan #define mmMM_INDEX_HI		0x6
131f39f5bb1SXiaojie Yuan #define mmMM_DATA		0x1
132f39f5bb1SXiaojie Yuan 
133f3167919SNirmoy Das static const char *hw_id_names[HW_ID_MAX] = {
134f39f5bb1SXiaojie Yuan 	[MP1_HWID]		= "MP1",
135f39f5bb1SXiaojie Yuan 	[MP2_HWID]		= "MP2",
136f39f5bb1SXiaojie Yuan 	[THM_HWID]		= "THM",
137f39f5bb1SXiaojie Yuan 	[SMUIO_HWID]		= "SMUIO",
138f39f5bb1SXiaojie Yuan 	[FUSE_HWID]		= "FUSE",
139f39f5bb1SXiaojie Yuan 	[CLKA_HWID]		= "CLKA",
140f39f5bb1SXiaojie Yuan 	[PWR_HWID]		= "PWR",
141f39f5bb1SXiaojie Yuan 	[GC_HWID]		= "GC",
142f39f5bb1SXiaojie Yuan 	[UVD_HWID]		= "UVD",
143f39f5bb1SXiaojie Yuan 	[AUDIO_AZ_HWID]		= "AUDIO_AZ",
144f39f5bb1SXiaojie Yuan 	[ACP_HWID]		= "ACP",
145f39f5bb1SXiaojie Yuan 	[DCI_HWID]		= "DCI",
146f39f5bb1SXiaojie Yuan 	[DMU_HWID]		= "DMU",
147f39f5bb1SXiaojie Yuan 	[DCO_HWID]		= "DCO",
148f39f5bb1SXiaojie Yuan 	[DIO_HWID]		= "DIO",
149f39f5bb1SXiaojie Yuan 	[XDMA_HWID]		= "XDMA",
150f39f5bb1SXiaojie Yuan 	[DCEAZ_HWID]		= "DCEAZ",
151f39f5bb1SXiaojie Yuan 	[DAZ_HWID]		= "DAZ",
152f39f5bb1SXiaojie Yuan 	[SDPMUX_HWID]		= "SDPMUX",
153f39f5bb1SXiaojie Yuan 	[NTB_HWID]		= "NTB",
154f39f5bb1SXiaojie Yuan 	[IOHC_HWID]		= "IOHC",
155f39f5bb1SXiaojie Yuan 	[L2IMU_HWID]		= "L2IMU",
156f39f5bb1SXiaojie Yuan 	[VCE_HWID]		= "VCE",
157f39f5bb1SXiaojie Yuan 	[MMHUB_HWID]		= "MMHUB",
158f39f5bb1SXiaojie Yuan 	[ATHUB_HWID]		= "ATHUB",
159f39f5bb1SXiaojie Yuan 	[DBGU_NBIO_HWID]	= "DBGU_NBIO",
160f39f5bb1SXiaojie Yuan 	[DFX_HWID]		= "DFX",
161f39f5bb1SXiaojie Yuan 	[DBGU0_HWID]		= "DBGU0",
162f39f5bb1SXiaojie Yuan 	[DBGU1_HWID]		= "DBGU1",
163f39f5bb1SXiaojie Yuan 	[OSSSYS_HWID]		= "OSSSYS",
164f39f5bb1SXiaojie Yuan 	[HDP_HWID]		= "HDP",
165f39f5bb1SXiaojie Yuan 	[SDMA0_HWID]		= "SDMA0",
166f39f5bb1SXiaojie Yuan 	[SDMA1_HWID]		= "SDMA1",
167dac35c42SGuchun Chen 	[SDMA2_HWID]		= "SDMA2",
168dac35c42SGuchun Chen 	[SDMA3_HWID]		= "SDMA3",
1691b491330SLikun Gao 	[LSDMA_HWID]		= "LSDMA",
170f39f5bb1SXiaojie Yuan 	[ISP_HWID]		= "ISP",
171f39f5bb1SXiaojie Yuan 	[DBGU_IO_HWID]		= "DBGU_IO",
172f39f5bb1SXiaojie Yuan 	[DF_HWID]		= "DF",
173f39f5bb1SXiaojie Yuan 	[CLKB_HWID]		= "CLKB",
174f39f5bb1SXiaojie Yuan 	[FCH_HWID]		= "FCH",
175f39f5bb1SXiaojie Yuan 	[DFX_DAP_HWID]		= "DFX_DAP",
176f39f5bb1SXiaojie Yuan 	[L1IMU_PCIE_HWID]	= "L1IMU_PCIE",
177f39f5bb1SXiaojie Yuan 	[L1IMU_NBIF_HWID]	= "L1IMU_NBIF",
178f39f5bb1SXiaojie Yuan 	[L1IMU_IOAGR_HWID]	= "L1IMU_IOAGR",
179f39f5bb1SXiaojie Yuan 	[L1IMU3_HWID]		= "L1IMU3",
180f39f5bb1SXiaojie Yuan 	[L1IMU4_HWID]		= "L1IMU4",
181f39f5bb1SXiaojie Yuan 	[L1IMU5_HWID]		= "L1IMU5",
182f39f5bb1SXiaojie Yuan 	[L1IMU6_HWID]		= "L1IMU6",
183f39f5bb1SXiaojie Yuan 	[L1IMU7_HWID]		= "L1IMU7",
184f39f5bb1SXiaojie Yuan 	[L1IMU8_HWID]		= "L1IMU8",
185f39f5bb1SXiaojie Yuan 	[L1IMU9_HWID]		= "L1IMU9",
186f39f5bb1SXiaojie Yuan 	[L1IMU10_HWID]		= "L1IMU10",
187f39f5bb1SXiaojie Yuan 	[L1IMU11_HWID]		= "L1IMU11",
188f39f5bb1SXiaojie Yuan 	[L1IMU12_HWID]		= "L1IMU12",
189f39f5bb1SXiaojie Yuan 	[L1IMU13_HWID]		= "L1IMU13",
190f39f5bb1SXiaojie Yuan 	[L1IMU14_HWID]		= "L1IMU14",
191f39f5bb1SXiaojie Yuan 	[L1IMU15_HWID]		= "L1IMU15",
192f39f5bb1SXiaojie Yuan 	[WAFLC_HWID]		= "WAFLC",
193f39f5bb1SXiaojie Yuan 	[FCH_USB_PD_HWID]	= "FCH_USB_PD",
194f39f5bb1SXiaojie Yuan 	[PCIE_HWID]		= "PCIE",
195f39f5bb1SXiaojie Yuan 	[PCS_HWID]		= "PCS",
196f39f5bb1SXiaojie Yuan 	[DDCL_HWID]		= "DDCL",
197f39f5bb1SXiaojie Yuan 	[SST_HWID]		= "SST",
198f39f5bb1SXiaojie Yuan 	[IOAGR_HWID]		= "IOAGR",
199f39f5bb1SXiaojie Yuan 	[NBIF_HWID]		= "NBIF",
200f39f5bb1SXiaojie Yuan 	[IOAPIC_HWID]		= "IOAPIC",
201f39f5bb1SXiaojie Yuan 	[SYSTEMHUB_HWID]	= "SYSTEMHUB",
202f39f5bb1SXiaojie Yuan 	[NTBCCP_HWID]		= "NTBCCP",
203f39f5bb1SXiaojie Yuan 	[UMC_HWID]		= "UMC",
204f39f5bb1SXiaojie Yuan 	[SATA_HWID]		= "SATA",
205f39f5bb1SXiaojie Yuan 	[USB_HWID]		= "USB",
206f39f5bb1SXiaojie Yuan 	[CCXSEC_HWID]		= "CCXSEC",
207f39f5bb1SXiaojie Yuan 	[XGMI_HWID]		= "XGMI",
208f39f5bb1SXiaojie Yuan 	[XGBE_HWID]		= "XGBE",
209f39f5bb1SXiaojie Yuan 	[MP0_HWID]		= "MP0",
2100b233357SLang Yu 	[VPE_HWID]		= "VPE",
211f39f5bb1SXiaojie Yuan };
212f39f5bb1SXiaojie Yuan 
213f39f5bb1SXiaojie Yuan static int hw_id_map[MAX_HWIP] = {
214f39f5bb1SXiaojie Yuan 	[GC_HWIP]	= GC_HWID,
215f39f5bb1SXiaojie Yuan 	[HDP_HWIP]	= HDP_HWID,
216f39f5bb1SXiaojie Yuan 	[SDMA0_HWIP]	= SDMA0_HWID,
217f39f5bb1SXiaojie Yuan 	[SDMA1_HWIP]	= SDMA1_HWID,
2187551f70aSGuchun Chen 	[SDMA2_HWIP]    = SDMA2_HWID,
2197551f70aSGuchun Chen 	[SDMA3_HWIP]    = SDMA3_HWID,
2201b491330SLikun Gao 	[LSDMA_HWIP]    = LSDMA_HWID,
221f39f5bb1SXiaojie Yuan 	[MMHUB_HWIP]	= MMHUB_HWID,
222f39f5bb1SXiaojie Yuan 	[ATHUB_HWIP]	= ATHUB_HWID,
2232de00413SXiaojie Yuan 	[NBIO_HWIP]	= NBIF_HWID,
224f39f5bb1SXiaojie Yuan 	[MP0_HWIP]	= MP0_HWID,
225f39f5bb1SXiaojie Yuan 	[MP1_HWIP]	= MP1_HWID,
226f39f5bb1SXiaojie Yuan 	[UVD_HWIP]	= UVD_HWID,
227f39f5bb1SXiaojie Yuan 	[VCE_HWIP]	= VCE_HWID,
228f39f5bb1SXiaojie Yuan 	[DF_HWIP]	= DF_HWID,
229a349b392Stiancyin 	[DCE_HWIP]	= DMU_HWID,
230f39f5bb1SXiaojie Yuan 	[OSSSYS_HWIP]	= OSSSYS_HWID,
231f39f5bb1SXiaojie Yuan 	[SMUIO_HWIP]	= SMUIO_HWID,
232f39f5bb1SXiaojie Yuan 	[PWR_HWIP]	= PWR_HWID,
233f39f5bb1SXiaojie Yuan 	[NBIF_HWIP]	= NBIF_HWID,
234f39f5bb1SXiaojie Yuan 	[THM_HWIP]	= THM_HWID,
235f39f5bb1SXiaojie Yuan 	[CLK_HWIP]	= CLKA_HWID,
2366bfbfe8cSJohn Clements 	[UMC_HWIP]	= UMC_HWID,
2371534db55SAlex Deucher 	[XGMI_HWIP]	= XGMI_HWID,
2385f931489SAlex Deucher 	[DCI_HWIP]	= DCI_HWID,
23962f8f5c3SEvan Quan 	[PCIE_HWIP]	= PCIE_HWID,
2400b233357SLang Yu 	[VPE_HWIP]	= VPE_HWID,
241772e4d56SPratap Nirujogi 	[ISP_HWIP]	= ISP_HWID,
242f39f5bb1SXiaojie Yuan };
243f39f5bb1SXiaojie Yuan 
amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device * adev,uint8_t * binary)244368bb1bcSLijo Lazar static int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev, uint8_t *binary)
245368bb1bcSLijo Lazar {
246368bb1bcSLijo Lazar 	u64 tmr_offset, tmr_size, pos;
247368bb1bcSLijo Lazar 	void *discv_regn;
248368bb1bcSLijo Lazar 	int ret;
249368bb1bcSLijo Lazar 
250368bb1bcSLijo Lazar 	ret = amdgpu_acpi_get_tmr_info(adev, &tmr_offset, &tmr_size);
251368bb1bcSLijo Lazar 	if (ret)
252368bb1bcSLijo Lazar 		return ret;
253368bb1bcSLijo Lazar 
254368bb1bcSLijo Lazar 	pos = tmr_offset + tmr_size - DISCOVERY_TMR_OFFSET;
255368bb1bcSLijo Lazar 
256368bb1bcSLijo Lazar 	/* This region is read-only and reserved from system use */
257368bb1bcSLijo Lazar 	discv_regn = memremap(pos, adev->mman.discovery_tmr_size, MEMREMAP_WC);
258368bb1bcSLijo Lazar 	if (discv_regn) {
259368bb1bcSLijo Lazar 		memcpy(binary, discv_regn, adev->mman.discovery_tmr_size);
260368bb1bcSLijo Lazar 		memunmap(discv_regn);
261368bb1bcSLijo Lazar 		return 0;
262368bb1bcSLijo Lazar 	}
263368bb1bcSLijo Lazar 
264368bb1bcSLijo Lazar 	return -ENOENT;
265368bb1bcSLijo Lazar }
266368bb1bcSLijo Lazar 
267765bea0dSHawking Zhang #define IP_DISCOVERY_V2		2
268765bea0dSHawking Zhang #define IP_DISCOVERY_V4		4
269765bea0dSHawking Zhang 
amdgpu_discovery_read_binary_from_mem(struct amdgpu_device * adev,uint8_t * binary)270ac772a3cSLijo Lazar static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,
271ac772a3cSLijo Lazar 						 uint8_t *binary)
272f39f5bb1SXiaojie Yuan {
2733938eb95SAlex Deucher 	uint64_t vram_size;
2743938eb95SAlex Deucher 	u32 msg;
2753938eb95SAlex Deucher 	int i, ret = 0;
2763938eb95SAlex Deucher 
277b3256385SVictor Lu 	if (!amdgpu_sriov_vf(adev)) {
2783938eb95SAlex Deucher 		/* It can take up to a second for IFWI init to complete on some dGPUs,
2793938eb95SAlex Deucher 		 * but generally it should be in the 60-100ms range.  Normally this starts
2803938eb95SAlex Deucher 		 * as soon as the device gets power so by the time the OS loads this has long
2813938eb95SAlex Deucher 		 * completed.  However, when a card is hotplugged via e.g., USB4, we need to
2823938eb95SAlex Deucher 		 * wait for this to complete.  Once the C2PMSG is updated, we can
2833938eb95SAlex Deucher 		 * continue.
2843938eb95SAlex Deucher 		 */
285765bea0dSHawking Zhang 
2863938eb95SAlex Deucher 		for (i = 0; i < 1000; i++) {
2873938eb95SAlex Deucher 			msg = RREG32(mmMP0_SMN_C2PMSG_33);
2883938eb95SAlex Deucher 			if (msg & 0x80000000)
2893938eb95SAlex Deucher 				break;
290c69b07f7SAlex Deucher 			msleep(1);
2913938eb95SAlex Deucher 		}
292b3256385SVictor Lu 	}
29395905698SMa Jun 
2943938eb95SAlex Deucher 	vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
295f39f5bb1SXiaojie Yuan 
296ac772a3cSLijo Lazar 	if (vram_size) {
297ac772a3cSLijo Lazar 		uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET;
298e0c116c1SHawking Zhang 		amdgpu_device_vram_access(adev, pos, (uint32_t *)binary,
29972de33f8SAlex Deucher 					  adev->mman.discovery_tmr_size, false);
300ac772a3cSLijo Lazar 	} else {
301ac772a3cSLijo Lazar 		ret = amdgpu_discovery_read_binary_from_sysmem(adev, binary);
302ac772a3cSLijo Lazar 	}
303ac772a3cSLijo Lazar 
304ac772a3cSLijo Lazar 	return ret;
305f39f5bb1SXiaojie Yuan }
306f39f5bb1SXiaojie Yuan 
amdgpu_discovery_read_binary_from_file(struct amdgpu_device * adev,uint8_t * binary,const char * fw_name)307017fbb66SFlora Cui static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev,
308017fbb66SFlora Cui 							uint8_t *binary,
309017fbb66SFlora Cui 							const char *fw_name)
31043a80bd5SHawking Zhang {
31143a80bd5SHawking Zhang 	const struct firmware *fw;
31243a80bd5SHawking Zhang 	int r;
31343a80bd5SHawking Zhang 
31443a80bd5SHawking Zhang 	r = request_firmware(&fw, fw_name, adev->dev);
31543a80bd5SHawking Zhang 	if (r) {
31643a80bd5SHawking Zhang 		dev_err(adev->dev, "can't load firmware \"%s\"\n",
31743a80bd5SHawking Zhang 			fw_name);
31843a80bd5SHawking Zhang 		return r;
31943a80bd5SHawking Zhang 	}
32043a80bd5SHawking Zhang 
321a79852a3SLe Ma 	memcpy((u8 *)binary, (u8 *)fw->data, fw->size);
32243a80bd5SHawking Zhang 	release_firmware(fw);
32343a80bd5SHawking Zhang 
32443a80bd5SHawking Zhang 	return 0;
32543a80bd5SHawking Zhang }
32643a80bd5SHawking Zhang 
amdgpu_discovery_calculate_checksum(uint8_t * data,uint32_t size)327f39f5bb1SXiaojie Yuan static uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t size)
328f39f5bb1SXiaojie Yuan {
329f39f5bb1SXiaojie Yuan 	uint16_t checksum = 0;
330f39f5bb1SXiaojie Yuan 	int i;
331f39f5bb1SXiaojie Yuan 
332f39f5bb1SXiaojie Yuan 	for (i = 0; i < size; i++)
333f39f5bb1SXiaojie Yuan 		checksum += data[i];
334f39f5bb1SXiaojie Yuan 
335f39f5bb1SXiaojie Yuan 	return checksum;
336f39f5bb1SXiaojie Yuan }
337f39f5bb1SXiaojie Yuan 
amdgpu_discovery_verify_checksum(uint8_t * data,uint32_t size,uint16_t expected)338f39f5bb1SXiaojie Yuan static inline bool amdgpu_discovery_verify_checksum(uint8_t *data, uint32_t size,
339f39f5bb1SXiaojie Yuan 						    uint16_t expected)
340f39f5bb1SXiaojie Yuan {
341f39f5bb1SXiaojie Yuan 	return !!(amdgpu_discovery_calculate_checksum(data, size) == expected);
342f39f5bb1SXiaojie Yuan }
343f39f5bb1SXiaojie Yuan 
amdgpu_discovery_verify_binary_signature(uint8_t * binary)34432f0e1a3SHawking Zhang static inline bool amdgpu_discovery_verify_binary_signature(uint8_t *binary)
34532f0e1a3SHawking Zhang {
34632f0e1a3SHawking Zhang 	struct binary_header *bhdr;
34732f0e1a3SHawking Zhang 	bhdr = (struct binary_header *)binary;
34832f0e1a3SHawking Zhang 
34932f0e1a3SHawking Zhang 	return (le32_to_cpu(bhdr->binary_signature) == BINARY_SIGNATURE);
35032f0e1a3SHawking Zhang }
35132f0e1a3SHawking Zhang 
amdgpu_discovery_harvest_config_quirk(struct amdgpu_device * adev)35203f6fb84SGuchun Chen static void amdgpu_discovery_harvest_config_quirk(struct amdgpu_device *adev)
35303f6fb84SGuchun Chen {
35403f6fb84SGuchun Chen 	/*
35503f6fb84SGuchun Chen 	 * So far, apply this quirk only on those Navy Flounder boards which
35603f6fb84SGuchun Chen 	 * have a bad harvest table of VCN config.
35703f6fb84SGuchun Chen 	 */
3584e8303cfSLijo Lazar 	if ((amdgpu_ip_version(adev, UVD_HWIP, 1) == IP_VERSION(3, 0, 1)) &&
3594e8303cfSLijo Lazar 	    (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(10, 3, 2))) {
36003f6fb84SGuchun Chen 		switch (adev->pdev->revision) {
36103f6fb84SGuchun Chen 		case 0xC1:
36203f6fb84SGuchun Chen 		case 0xC2:
36303f6fb84SGuchun Chen 		case 0xC3:
36403f6fb84SGuchun Chen 		case 0xC5:
36503f6fb84SGuchun Chen 		case 0xC7:
36603f6fb84SGuchun Chen 		case 0xCF:
36703f6fb84SGuchun Chen 		case 0xDF:
36803f6fb84SGuchun Chen 			adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
3696a944ccbSLijo Lazar 			adev->vcn.inst_mask &= ~AMDGPU_VCN_HARVEST_VCN1;
37003f6fb84SGuchun Chen 			break;
37103f6fb84SGuchun Chen 		default:
37203f6fb84SGuchun Chen 			break;
37303f6fb84SGuchun Chen 		}
37403f6fb84SGuchun Chen 	}
37503f6fb84SGuchun Chen }
37603f6fb84SGuchun Chen 
amdgpu_discovery_verify_npsinfo(struct amdgpu_device * adev,struct binary_header * bhdr)377b194d21bSLijo Lazar static int amdgpu_discovery_verify_npsinfo(struct amdgpu_device *adev,
378b194d21bSLijo Lazar 					   struct binary_header *bhdr)
379b194d21bSLijo Lazar {
380b194d21bSLijo Lazar 	struct table_info *info;
381b194d21bSLijo Lazar 	uint16_t checksum;
382b194d21bSLijo Lazar 	uint16_t offset;
383b194d21bSLijo Lazar 
384b194d21bSLijo Lazar 	info = &bhdr->table_list[NPS_INFO];
385b194d21bSLijo Lazar 	offset = le16_to_cpu(info->offset);
386b194d21bSLijo Lazar 	checksum = le16_to_cpu(info->checksum);
387b194d21bSLijo Lazar 
388b194d21bSLijo Lazar 	struct nps_info_header *nhdr =
389b194d21bSLijo Lazar 		(struct nps_info_header *)(adev->mman.discovery_bin + offset);
390b194d21bSLijo Lazar 
391b194d21bSLijo Lazar 	if (le32_to_cpu(nhdr->table_id) != NPS_INFO_TABLE_ID) {
392b194d21bSLijo Lazar 		dev_dbg(adev->dev, "invalid ip discovery nps info table id\n");
393b194d21bSLijo Lazar 		return -EINVAL;
394b194d21bSLijo Lazar 	}
395b194d21bSLijo Lazar 
396b194d21bSLijo Lazar 	if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
397b194d21bSLijo Lazar 					      le32_to_cpu(nhdr->size_bytes),
398b194d21bSLijo Lazar 					      checksum)) {
399b194d21bSLijo Lazar 		dev_dbg(adev->dev, "invalid nps info data table checksum\n");
400b194d21bSLijo Lazar 		return -EINVAL;
401b194d21bSLijo Lazar 	}
402b194d21bSLijo Lazar 
403b194d21bSLijo Lazar 	return 0;
404b194d21bSLijo Lazar }
405b194d21bSLijo Lazar 
amdgpu_discovery_get_fw_name(struct amdgpu_device * adev)406017fbb66SFlora Cui static const char *amdgpu_discovery_get_fw_name(struct amdgpu_device *adev)
407017fbb66SFlora Cui {
408017fbb66SFlora Cui 	if (amdgpu_discovery == 2)
409017fbb66SFlora Cui 		return "amdgpu/ip_discovery.bin";
410017fbb66SFlora Cui 
41125f602fbSFlora Cui 	switch (adev->asic_type) {
41225f602fbSFlora Cui 	case CHIP_VEGA10:
41325f602fbSFlora Cui 		return "amdgpu/vega10_ip_discovery.bin";
41425f602fbSFlora Cui 	case CHIP_VEGA12:
41525f602fbSFlora Cui 		return "amdgpu/vega12_ip_discovery.bin";
41625f602fbSFlora Cui 	case CHIP_RAVEN:
41725f602fbSFlora Cui 		if (adev->apu_flags & AMD_APU_IS_RAVEN2)
41825f602fbSFlora Cui 			return "amdgpu/raven2_ip_discovery.bin";
41925f602fbSFlora Cui 		else if (adev->apu_flags & AMD_APU_IS_PICASSO)
42025f602fbSFlora Cui 			return "amdgpu/picasso_ip_discovery.bin";
42125f602fbSFlora Cui 		else
42225f602fbSFlora Cui 			return "amdgpu/raven_ip_discovery.bin";
42325f602fbSFlora Cui 	case CHIP_VEGA20:
42425f602fbSFlora Cui 		return "amdgpu/vega20_ip_discovery.bin";
42525f602fbSFlora Cui 	case CHIP_ARCTURUS:
42625f602fbSFlora Cui 		return "amdgpu/arcturus_ip_discovery.bin";
42725f602fbSFlora Cui 	case CHIP_ALDEBARAN:
42825f602fbSFlora Cui 		return "amdgpu/aldebaran_ip_discovery.bin";
42925f602fbSFlora Cui 	default:
430017fbb66SFlora Cui 		return NULL;
431017fbb66SFlora Cui 	}
43225f602fbSFlora Cui }
433017fbb66SFlora Cui 
amdgpu_discovery_init(struct amdgpu_device * adev)434dffa11b4SMonk Liu static int amdgpu_discovery_init(struct amdgpu_device *adev)
435f39f5bb1SXiaojie Yuan {
436f39f5bb1SXiaojie Yuan 	struct table_info *info;
437f39f5bb1SXiaojie Yuan 	struct binary_header *bhdr;
438017fbb66SFlora Cui 	const char *fw_name;
439f39f5bb1SXiaojie Yuan 	uint16_t offset;
440f39f5bb1SXiaojie Yuan 	uint16_t size;
441f39f5bb1SXiaojie Yuan 	uint16_t checksum;
442f39f5bb1SXiaojie Yuan 	int r;
443f39f5bb1SXiaojie Yuan 
44472de33f8SAlex Deucher 	adev->mman.discovery_tmr_size = DISCOVERY_TMR_SIZE;
44572de33f8SAlex Deucher 	adev->mman.discovery_bin = kzalloc(adev->mman.discovery_tmr_size, GFP_KERNEL);
44672de33f8SAlex Deucher 	if (!adev->mman.discovery_bin)
447f39f5bb1SXiaojie Yuan 		return -ENOMEM;
448f39f5bb1SXiaojie Yuan 
44944cbc453SLijo Lazar 	/* Read from file if it is the preferred option */
450017fbb66SFlora Cui 	fw_name = amdgpu_discovery_get_fw_name(adev);
451017fbb66SFlora Cui 	if (fw_name != NULL) {
45244cbc453SLijo Lazar 		dev_info(adev->dev, "use ip discovery information from file");
453017fbb66SFlora Cui 		r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin, fw_name);
45444cbc453SLijo Lazar 
4552cb6577aSHawking Zhang 		if (r) {
4562cb6577aSHawking Zhang 			dev_err(adev->dev, "failed to read ip discovery binary from file\n");
4572cb6577aSHawking Zhang 			r = -EINVAL;
4582cb6577aSHawking Zhang 			goto out;
4592cb6577aSHawking Zhang 		}
46044cbc453SLijo Lazar 
46144cbc453SLijo Lazar 	} else {
462ac772a3cSLijo Lazar 		r = amdgpu_discovery_read_binary_from_mem(
463ac772a3cSLijo Lazar 			adev, adev->mman.discovery_bin);
464ac772a3cSLijo Lazar 		if (r)
465ac772a3cSLijo Lazar 			goto out;
46644cbc453SLijo Lazar 	}
46744cbc453SLijo Lazar 
4682cb6577aSHawking Zhang 	/* check the ip discovery binary signature */
4692cb6577aSHawking Zhang 	if (!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) {
47044cbc453SLijo Lazar 		dev_err(adev->dev,
47144cbc453SLijo Lazar 			"get invalid ip discovery binary signature\n");
4722cb6577aSHawking Zhang 		r = -EINVAL;
473f39f5bb1SXiaojie Yuan 		goto out;
474f39f5bb1SXiaojie Yuan 	}
475f39f5bb1SXiaojie Yuan 
47672de33f8SAlex Deucher 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
477f39f5bb1SXiaojie Yuan 
4788e84aa1bSXiaojie Yuan 	offset = offsetof(struct binary_header, binary_checksum) +
479f39f5bb1SXiaojie Yuan 		sizeof(bhdr->binary_checksum);
480fd08953bSYang Wang 	size = le16_to_cpu(bhdr->binary_size) - offset;
481fd08953bSYang Wang 	checksum = le16_to_cpu(bhdr->binary_checksum);
482f39f5bb1SXiaojie Yuan 
48372de33f8SAlex Deucher 	if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
484f39f5bb1SXiaojie Yuan 					      size, checksum)) {
4852cb6577aSHawking Zhang 		dev_err(adev->dev, "invalid ip discovery binary checksum\n");
486f39f5bb1SXiaojie Yuan 		r = -EINVAL;
487f39f5bb1SXiaojie Yuan 		goto out;
488f39f5bb1SXiaojie Yuan 	}
489f39f5bb1SXiaojie Yuan 
490f39f5bb1SXiaojie Yuan 	info = &bhdr->table_list[IP_DISCOVERY];
491f39f5bb1SXiaojie Yuan 	offset = le16_to_cpu(info->offset);
492f39f5bb1SXiaojie Yuan 	checksum = le16_to_cpu(info->checksum);
493f39f5bb1SXiaojie Yuan 
494f716113aSAlex Deucher 	if (offset) {
495f716113aSAlex Deucher 		struct ip_discovery_header *ihdr =
496f716113aSAlex Deucher 			(struct ip_discovery_header *)(adev->mman.discovery_bin + offset);
497f39f5bb1SXiaojie Yuan 		if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) {
4982cb6577aSHawking Zhang 			dev_err(adev->dev, "invalid ip discovery data table signature\n");
499f39f5bb1SXiaojie Yuan 			r = -EINVAL;
500f39f5bb1SXiaojie Yuan 			goto out;
501f39f5bb1SXiaojie Yuan 		}
502f39f5bb1SXiaojie Yuan 
50372de33f8SAlex Deucher 		if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
504fd08953bSYang Wang 						      le16_to_cpu(ihdr->size), checksum)) {
5052cb6577aSHawking Zhang 			dev_err(adev->dev, "invalid ip discovery data table checksum\n");
506f39f5bb1SXiaojie Yuan 			r = -EINVAL;
507f39f5bb1SXiaojie Yuan 			goto out;
508f39f5bb1SXiaojie Yuan 		}
509f716113aSAlex Deucher 	}
510f39f5bb1SXiaojie Yuan 
511f39f5bb1SXiaojie Yuan 	info = &bhdr->table_list[GC];
512f39f5bb1SXiaojie Yuan 	offset = le16_to_cpu(info->offset);
513f39f5bb1SXiaojie Yuan 	checksum = le16_to_cpu(info->checksum);
514f716113aSAlex Deucher 
515f716113aSAlex Deucher 	if (offset) {
516f716113aSAlex Deucher 		struct gpu_info_header *ghdr =
517f716113aSAlex Deucher 			(struct gpu_info_header *)(adev->mman.discovery_bin + offset);
518f716113aSAlex Deucher 
519f716113aSAlex Deucher 		if (le32_to_cpu(ghdr->table_id) != GC_TABLE_ID) {
520f716113aSAlex Deucher 			dev_err(adev->dev, "invalid ip discovery gc table id\n");
521f716113aSAlex Deucher 			r = -EINVAL;
522f716113aSAlex Deucher 			goto out;
523f716113aSAlex Deucher 		}
524f39f5bb1SXiaojie Yuan 
52572de33f8SAlex Deucher 		if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
526fd08953bSYang Wang 						      le32_to_cpu(ghdr->size), checksum)) {
5272cb6577aSHawking Zhang 			dev_err(adev->dev, "invalid gc data table checksum\n");
528f39f5bb1SXiaojie Yuan 			r = -EINVAL;
529f39f5bb1SXiaojie Yuan 			goto out;
530f39f5bb1SXiaojie Yuan 		}
531f716113aSAlex Deucher 	}
532f716113aSAlex Deucher 
533f716113aSAlex Deucher 	info = &bhdr->table_list[HARVEST_INFO];
534f716113aSAlex Deucher 	offset = le16_to_cpu(info->offset);
535f716113aSAlex Deucher 	checksum = le16_to_cpu(info->checksum);
536f716113aSAlex Deucher 
537f716113aSAlex Deucher 	if (offset) {
538f716113aSAlex Deucher 		struct harvest_info_header *hhdr =
539f716113aSAlex Deucher 			(struct harvest_info_header *)(adev->mman.discovery_bin + offset);
540f716113aSAlex Deucher 
541f716113aSAlex Deucher 		if (le32_to_cpu(hhdr->signature) != HARVEST_TABLE_SIGNATURE) {
542f716113aSAlex Deucher 			dev_err(adev->dev, "invalid ip discovery harvest table signature\n");
543f716113aSAlex Deucher 			r = -EINVAL;
544f716113aSAlex Deucher 			goto out;
545f716113aSAlex Deucher 		}
546f716113aSAlex Deucher 
547f716113aSAlex Deucher 		if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
548f716113aSAlex Deucher 						      sizeof(struct harvest_table), checksum)) {
549f716113aSAlex Deucher 			dev_err(adev->dev, "invalid harvest data table checksum\n");
550f716113aSAlex Deucher 			r = -EINVAL;
551f716113aSAlex Deucher 			goto out;
552f716113aSAlex Deucher 		}
553f716113aSAlex Deucher 	}
554f716113aSAlex Deucher 
555f716113aSAlex Deucher 	info = &bhdr->table_list[VCN_INFO];
556f716113aSAlex Deucher 	offset = le16_to_cpu(info->offset);
557f716113aSAlex Deucher 	checksum = le16_to_cpu(info->checksum);
558f716113aSAlex Deucher 
559f716113aSAlex Deucher 	if (offset) {
560f716113aSAlex Deucher 		struct vcn_info_header *vhdr =
561f716113aSAlex Deucher 			(struct vcn_info_header *)(adev->mman.discovery_bin + offset);
562f716113aSAlex Deucher 
563f716113aSAlex Deucher 		if (le32_to_cpu(vhdr->table_id) != VCN_INFO_TABLE_ID) {
564f716113aSAlex Deucher 			dev_err(adev->dev, "invalid ip discovery vcn table id\n");
565f716113aSAlex Deucher 			r = -EINVAL;
566f716113aSAlex Deucher 			goto out;
567f716113aSAlex Deucher 		}
568f716113aSAlex Deucher 
569f716113aSAlex Deucher 		if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
570f716113aSAlex Deucher 						      le32_to_cpu(vhdr->size_bytes), checksum)) {
571f716113aSAlex Deucher 			dev_err(adev->dev, "invalid vcn data table checksum\n");
572f716113aSAlex Deucher 			r = -EINVAL;
573f716113aSAlex Deucher 			goto out;
574f716113aSAlex Deucher 		}
575f716113aSAlex Deucher 	}
576f716113aSAlex Deucher 
577f716113aSAlex Deucher 	info = &bhdr->table_list[MALL_INFO];
578f716113aSAlex Deucher 	offset = le16_to_cpu(info->offset);
579f716113aSAlex Deucher 	checksum = le16_to_cpu(info->checksum);
580f716113aSAlex Deucher 
581f716113aSAlex Deucher 	if (0 && offset) {
582f716113aSAlex Deucher 		struct mall_info_header *mhdr =
583f716113aSAlex Deucher 			(struct mall_info_header *)(adev->mman.discovery_bin + offset);
584f716113aSAlex Deucher 
585f716113aSAlex Deucher 		if (le32_to_cpu(mhdr->table_id) != MALL_INFO_TABLE_ID) {
586f716113aSAlex Deucher 			dev_err(adev->dev, "invalid ip discovery mall table id\n");
587f716113aSAlex Deucher 			r = -EINVAL;
588f716113aSAlex Deucher 			goto out;
589f716113aSAlex Deucher 		}
590f716113aSAlex Deucher 
591f716113aSAlex Deucher 		if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
592f716113aSAlex Deucher 						      le32_to_cpu(mhdr->size_bytes), checksum)) {
593f716113aSAlex Deucher 			dev_err(adev->dev, "invalid mall data table checksum\n");
594f716113aSAlex Deucher 			r = -EINVAL;
595f716113aSAlex Deucher 			goto out;
596f716113aSAlex Deucher 		}
597f716113aSAlex Deucher 	}
598f39f5bb1SXiaojie Yuan 
599f39f5bb1SXiaojie Yuan 	return 0;
600f39f5bb1SXiaojie Yuan 
601f39f5bb1SXiaojie Yuan out:
60272de33f8SAlex Deucher 	kfree(adev->mman.discovery_bin);
60372de33f8SAlex Deucher 	adev->mman.discovery_bin = NULL;
604c8cb7e09SHawking Zhang 	if ((amdgpu_discovery != 2) &&
605c8cb7e09SHawking Zhang 	    (RREG32(mmIP_DISCOVERY_VERSION) == 4))
606c8cb7e09SHawking Zhang 		amdgpu_ras_query_boot_status(adev, 4);
607f39f5bb1SXiaojie Yuan 	return r;
608f39f5bb1SXiaojie Yuan }
609f39f5bb1SXiaojie Yuan 
610a6c40b17SLuben Tuikov static void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev);
611a6c40b17SLuben Tuikov 
amdgpu_discovery_fini(struct amdgpu_device * adev)612f39f5bb1SXiaojie Yuan void amdgpu_discovery_fini(struct amdgpu_device *adev)
613f39f5bb1SXiaojie Yuan {
614a6c40b17SLuben Tuikov 	amdgpu_discovery_sysfs_fini(adev);
61572de33f8SAlex Deucher 	kfree(adev->mman.discovery_bin);
61672de33f8SAlex Deucher 	adev->mman.discovery_bin = NULL;
617f39f5bb1SXiaojie Yuan }
618f39f5bb1SXiaojie Yuan 
amdgpu_discovery_validate_ip(struct amdgpu_device * adev,uint8_t instance,uint16_t hw_id)61931f9ed58SLijo Lazar static int amdgpu_discovery_validate_ip(struct amdgpu_device *adev,
62031f9ed58SLijo Lazar 					uint8_t instance, uint16_t hw_id)
6215039f529SErnst Sjöstrand {
62231f9ed58SLijo Lazar 	if (instance >= HWIP_MAX_INSTANCE) {
62331f9ed58SLijo Lazar 		dev_err(adev->dev,
62431f9ed58SLijo Lazar 			"Unexpected instance_number (%d) from ip discovery blob\n",
62531f9ed58SLijo Lazar 			instance);
6265039f529SErnst Sjöstrand 		return -EINVAL;
6275039f529SErnst Sjöstrand 	}
62831f9ed58SLijo Lazar 	if (hw_id >= HW_ID_MAX) {
62931f9ed58SLijo Lazar 		dev_err(adev->dev,
63031f9ed58SLijo Lazar 			"Unexpected hw_id (%d) from ip discovery blob\n",
63131f9ed58SLijo Lazar 			hw_id);
6325039f529SErnst Sjöstrand 		return -EINVAL;
6335039f529SErnst Sjöstrand 	}
6345039f529SErnst Sjöstrand 
6355039f529SErnst Sjöstrand 	return 0;
6365039f529SErnst Sjöstrand }
6375039f529SErnst Sjöstrand 
amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device * adev,uint32_t * vcn_harvest_count)638e1dd4bbfSGuchun Chen static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,
639e1dd4bbfSGuchun Chen 						uint32_t *vcn_harvest_count)
640e1dd4bbfSGuchun Chen {
641e1dd4bbfSGuchun Chen 	struct binary_header *bhdr;
642e1dd4bbfSGuchun Chen 	struct ip_discovery_header *ihdr;
643e1dd4bbfSGuchun Chen 	struct die_header *dhdr;
644a01e9342SLijo Lazar 	struct ip *ip;
645e1dd4bbfSGuchun Chen 	uint16_t die_offset, ip_offset, num_dies, num_ips;
64631f9ed58SLijo Lazar 	uint16_t hw_id;
64731f9ed58SLijo Lazar 	uint8_t inst;
648e1dd4bbfSGuchun Chen 	int i, j;
649e1dd4bbfSGuchun Chen 
650e1dd4bbfSGuchun Chen 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
651e1dd4bbfSGuchun Chen 	ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
652e1dd4bbfSGuchun Chen 			le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));
653e1dd4bbfSGuchun Chen 	num_dies = le16_to_cpu(ihdr->num_dies);
654e1dd4bbfSGuchun Chen 
655e1dd4bbfSGuchun Chen 	/* scan harvest bit of all IP data structures */
656e1dd4bbfSGuchun Chen 	for (i = 0; i < num_dies; i++) {
657e1dd4bbfSGuchun Chen 		die_offset = le16_to_cpu(ihdr->die_info[i].die_offset);
658e1dd4bbfSGuchun Chen 		dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset);
659e1dd4bbfSGuchun Chen 		num_ips = le16_to_cpu(dhdr->num_ips);
660e1dd4bbfSGuchun Chen 		ip_offset = die_offset + sizeof(*dhdr);
661e1dd4bbfSGuchun Chen 
662e1dd4bbfSGuchun Chen 		for (j = 0; j < num_ips; j++) {
663a01e9342SLijo Lazar 			ip = (struct ip *)(adev->mman.discovery_bin +
664a01e9342SLijo Lazar 					   ip_offset);
665a01e9342SLijo Lazar 			inst = ip->number_instance;
66631f9ed58SLijo Lazar 			hw_id = le16_to_cpu(ip->hw_id);
66731f9ed58SLijo Lazar 			if (amdgpu_discovery_validate_ip(adev, inst, hw_id))
668e1dd4bbfSGuchun Chen 				goto next_ip;
669e1dd4bbfSGuchun Chen 
670a01e9342SLijo Lazar 			if (ip->harvest == 1) {
67131f9ed58SLijo Lazar 				switch (hw_id) {
672e1dd4bbfSGuchun Chen 				case VCN_HWID:
673e1dd4bbfSGuchun Chen 					(*vcn_harvest_count)++;
67431f9ed58SLijo Lazar 					if (inst == 0) {
675e1dd4bbfSGuchun Chen 						adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;
676aaf1090aSLijo Lazar 						adev->vcn.inst_mask &=
677aaf1090aSLijo Lazar 							~AMDGPU_VCN_HARVEST_VCN0;
678aaf1090aSLijo Lazar 						adev->jpeg.inst_mask &=
679aaf1090aSLijo Lazar 							~AMDGPU_VCN_HARVEST_VCN0;
680aaf1090aSLijo Lazar 					} else {
681e1dd4bbfSGuchun Chen 						adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
682aaf1090aSLijo Lazar 						adev->vcn.inst_mask &=
683aaf1090aSLijo Lazar 							~AMDGPU_VCN_HARVEST_VCN1;
684aaf1090aSLijo Lazar 						adev->jpeg.inst_mask &=
685aaf1090aSLijo Lazar 							~AMDGPU_VCN_HARVEST_VCN1;
686aaf1090aSLijo Lazar 					}
687e1dd4bbfSGuchun Chen 					break;
688e1dd4bbfSGuchun Chen 				case DMU_HWID:
689e1dd4bbfSGuchun Chen 					adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
690e1dd4bbfSGuchun Chen 					break;
691e1dd4bbfSGuchun Chen 				default:
692e1dd4bbfSGuchun Chen 					break;
693e1dd4bbfSGuchun Chen 				}
694e1dd4bbfSGuchun Chen 			}
695e1dd4bbfSGuchun Chen next_ip:
696a01e9342SLijo Lazar 			ip_offset += struct_size(ip, base_address,
697a01e9342SLijo Lazar 						 ip->num_base_address);
698e1dd4bbfSGuchun Chen 		}
699e1dd4bbfSGuchun Chen 	}
700e1dd4bbfSGuchun Chen }
701e1dd4bbfSGuchun Chen 
amdgpu_discovery_read_from_harvest_table(struct amdgpu_device * adev,uint32_t * vcn_harvest_count,uint32_t * umc_harvest_count)702e776a755SAlex Deucher static void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev,
703478d338bSAlex Deucher 						     uint32_t *vcn_harvest_count,
704478d338bSAlex Deucher 						     uint32_t *umc_harvest_count)
705e1dd4bbfSGuchun Chen {
706e1dd4bbfSGuchun Chen 	struct binary_header *bhdr;
707e1dd4bbfSGuchun Chen 	struct harvest_table *harvest_info;
708f716113aSAlex Deucher 	u16 offset;
709e1dd4bbfSGuchun Chen 	int i;
7102b595659SCandice Li 	uint32_t umc_harvest_config = 0;
711e1dd4bbfSGuchun Chen 
712e1dd4bbfSGuchun Chen 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
713f716113aSAlex Deucher 	offset = le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset);
714f716113aSAlex Deucher 
715f716113aSAlex Deucher 	if (!offset) {
716f716113aSAlex Deucher 		dev_err(adev->dev, "invalid harvest table offset\n");
717f716113aSAlex Deucher 		return;
718f716113aSAlex Deucher 	}
719f716113aSAlex Deucher 
720f716113aSAlex Deucher 	harvest_info = (struct harvest_table *)(adev->mman.discovery_bin + offset);
721f716113aSAlex Deucher 
722e1dd4bbfSGuchun Chen 	for (i = 0; i < 32; i++) {
723e1dd4bbfSGuchun Chen 		if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)
724e1dd4bbfSGuchun Chen 			break;
725e1dd4bbfSGuchun Chen 
726e1dd4bbfSGuchun Chen 		switch (le16_to_cpu(harvest_info->list[i].hw_id)) {
727e1dd4bbfSGuchun Chen 		case VCN_HWID:
728e1dd4bbfSGuchun Chen 			(*vcn_harvest_count)++;
72952c293abSLijo Lazar 			adev->vcn.harvest_config |=
73052c293abSLijo Lazar 				(1 << harvest_info->list[i].number_instance);
73152c293abSLijo Lazar 			adev->jpeg.harvest_config |=
73252c293abSLijo Lazar 				(1 << harvest_info->list[i].number_instance);
733aaf1090aSLijo Lazar 
734aaf1090aSLijo Lazar 			adev->vcn.inst_mask &=
735aaf1090aSLijo Lazar 				~(1U << harvest_info->list[i].number_instance);
736aaf1090aSLijo Lazar 			adev->jpeg.inst_mask &=
737aaf1090aSLijo Lazar 				~(1U << harvest_info->list[i].number_instance);
738e1dd4bbfSGuchun Chen 			break;
739e1dd4bbfSGuchun Chen 		case DMU_HWID:
740e1dd4bbfSGuchun Chen 			adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
741e1dd4bbfSGuchun Chen 			break;
742478d338bSAlex Deucher 		case UMC_HWID:
7432b595659SCandice Li 			umc_harvest_config |=
7442b595659SCandice Li 				1 << (le16_to_cpu(harvest_info->list[i].number_instance));
745478d338bSAlex Deucher 			(*umc_harvest_count)++;
746478d338bSAlex Deucher 			break;
74773fa2553SLijo Lazar 		case GC_HWID:
74873fa2553SLijo Lazar 			adev->gfx.xcc_mask &=
74973fa2553SLijo Lazar 				~(1U << harvest_info->list[i].number_instance);
75073fa2553SLijo Lazar 			break;
75173fa2553SLijo Lazar 		case SDMA0_HWID:
75273fa2553SLijo Lazar 			adev->sdma.sdma_mask &=
75373fa2553SLijo Lazar 				~(1U << harvest_info->list[i].number_instance);
75473fa2553SLijo Lazar 			break;
7558930b90bSAlex Deucher #if defined(CONFIG_DRM_AMD_ISP)
756d232584aSPratap Nirujogi 		case ISP_HWID:
757d232584aSPratap Nirujogi 			adev->isp.harvest_config |=
758d232584aSPratap Nirujogi 				~(1U << harvest_info->list[i].number_instance);
759d232584aSPratap Nirujogi 			break;
7608930b90bSAlex Deucher #endif
761e1dd4bbfSGuchun Chen 		default:
762e1dd4bbfSGuchun Chen 			break;
763e1dd4bbfSGuchun Chen 		}
764e1dd4bbfSGuchun Chen 	}
7652b595659SCandice Li 
7662b595659SCandice Li 	adev->umc.active_mask = ((1 << adev->umc.node_inst_num) - 1) &
7672b595659SCandice Li 				~umc_harvest_config;
768e1dd4bbfSGuchun Chen }
769e1dd4bbfSGuchun Chen 
770a6c40b17SLuben Tuikov /* ================================================== */
771a6c40b17SLuben Tuikov 
772a6c40b17SLuben Tuikov struct ip_hw_instance {
773a6c40b17SLuben Tuikov 	struct kobject kobj; /* ip_discovery/die/#die/#hw_id/#instance/<attrs...> */
774a6c40b17SLuben Tuikov 
775a6c40b17SLuben Tuikov 	int hw_id;
776a6c40b17SLuben Tuikov 	u8  num_instance;
777a6c40b17SLuben Tuikov 	u8  major, minor, revision;
7784d7ba312SLuben Tuikov 	u8  harvest;
779a6c40b17SLuben Tuikov 
780a6c40b17SLuben Tuikov 	int num_base_addresses;
781ac8e62abSKees Cook 	u32 base_addr[] __counted_by(num_base_addresses);
782a6c40b17SLuben Tuikov };
783a6c40b17SLuben Tuikov 
784a6c40b17SLuben Tuikov struct ip_hw_id {
785a6c40b17SLuben Tuikov 	struct kset hw_id_kset;  /* ip_discovery/die/#die/#hw_id/, contains ip_hw_instance */
786a6c40b17SLuben Tuikov 	int hw_id;
787a6c40b17SLuben Tuikov };
788a6c40b17SLuben Tuikov 
789a6c40b17SLuben Tuikov struct ip_die_entry {
790a6c40b17SLuben Tuikov 	struct kset ip_kset;     /* ip_discovery/die/#die/, contains ip_hw_id  */
791a6c40b17SLuben Tuikov 	u16 num_ips;
792a6c40b17SLuben Tuikov };
793a6c40b17SLuben Tuikov 
794a6c40b17SLuben Tuikov /* -------------------------------------------------- */
795a6c40b17SLuben Tuikov 
796a6c40b17SLuben Tuikov struct ip_hw_instance_attr {
797a6c40b17SLuben Tuikov 	struct attribute attr;
798a6c40b17SLuben Tuikov 	ssize_t (*show)(struct ip_hw_instance *ip_hw_instance, char *buf);
799a6c40b17SLuben Tuikov };
800a6c40b17SLuben Tuikov 
hw_id_show(struct ip_hw_instance * ip_hw_instance,char * buf)801a6c40b17SLuben Tuikov static ssize_t hw_id_show(struct ip_hw_instance *ip_hw_instance, char *buf)
802a6c40b17SLuben Tuikov {
803a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_hw_instance->hw_id);
804a6c40b17SLuben Tuikov }
805a6c40b17SLuben Tuikov 
num_instance_show(struct ip_hw_instance * ip_hw_instance,char * buf)806a6c40b17SLuben Tuikov static ssize_t num_instance_show(struct ip_hw_instance *ip_hw_instance, char *buf)
807a6c40b17SLuben Tuikov {
808a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_hw_instance->num_instance);
809a6c40b17SLuben Tuikov }
810a6c40b17SLuben Tuikov 
major_show(struct ip_hw_instance * ip_hw_instance,char * buf)811a6c40b17SLuben Tuikov static ssize_t major_show(struct ip_hw_instance *ip_hw_instance, char *buf)
812a6c40b17SLuben Tuikov {
813a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_hw_instance->major);
814a6c40b17SLuben Tuikov }
815a6c40b17SLuben Tuikov 
minor_show(struct ip_hw_instance * ip_hw_instance,char * buf)816a6c40b17SLuben Tuikov static ssize_t minor_show(struct ip_hw_instance *ip_hw_instance, char *buf)
817a6c40b17SLuben Tuikov {
818a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_hw_instance->minor);
819a6c40b17SLuben Tuikov }
820a6c40b17SLuben Tuikov 
revision_show(struct ip_hw_instance * ip_hw_instance,char * buf)821a6c40b17SLuben Tuikov static ssize_t revision_show(struct ip_hw_instance *ip_hw_instance, char *buf)
822a6c40b17SLuben Tuikov {
823a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_hw_instance->revision);
824a6c40b17SLuben Tuikov }
825a6c40b17SLuben Tuikov 
harvest_show(struct ip_hw_instance * ip_hw_instance,char * buf)8264d7ba312SLuben Tuikov static ssize_t harvest_show(struct ip_hw_instance *ip_hw_instance, char *buf)
8274d7ba312SLuben Tuikov {
8284d7ba312SLuben Tuikov 	return sysfs_emit(buf, "0x%01X\n", ip_hw_instance->harvest);
8294d7ba312SLuben Tuikov }
8304d7ba312SLuben Tuikov 
num_base_addresses_show(struct ip_hw_instance * ip_hw_instance,char * buf)831a6c40b17SLuben Tuikov static ssize_t num_base_addresses_show(struct ip_hw_instance *ip_hw_instance, char *buf)
832a6c40b17SLuben Tuikov {
833a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_hw_instance->num_base_addresses);
834a6c40b17SLuben Tuikov }
835a6c40b17SLuben Tuikov 
base_addr_show(struct ip_hw_instance * ip_hw_instance,char * buf)836a6c40b17SLuben Tuikov static ssize_t base_addr_show(struct ip_hw_instance *ip_hw_instance, char *buf)
837a6c40b17SLuben Tuikov {
838a6c40b17SLuben Tuikov 	ssize_t res, at;
839a6c40b17SLuben Tuikov 	int ii;
840a6c40b17SLuben Tuikov 
841a6c40b17SLuben Tuikov 	for (res = at = ii = 0; ii < ip_hw_instance->num_base_addresses; ii++) {
842a6c40b17SLuben Tuikov 		/* Here we satisfy the condition that, at + size <= PAGE_SIZE.
843a6c40b17SLuben Tuikov 		 */
844a6c40b17SLuben Tuikov 		if (at + 12 > PAGE_SIZE)
845a6c40b17SLuben Tuikov 			break;
846a6c40b17SLuben Tuikov 		res = sysfs_emit_at(buf, at, "0x%08X\n",
847a6c40b17SLuben Tuikov 				    ip_hw_instance->base_addr[ii]);
848a6c40b17SLuben Tuikov 		if (res <= 0)
849a6c40b17SLuben Tuikov 			break;
850a6c40b17SLuben Tuikov 		at += res;
851a6c40b17SLuben Tuikov 	}
852a6c40b17SLuben Tuikov 
853a6c40b17SLuben Tuikov 	return res < 0 ? res : at;
854a6c40b17SLuben Tuikov }
855a6c40b17SLuben Tuikov 
856a6c40b17SLuben Tuikov static struct ip_hw_instance_attr ip_hw_attr[] = {
857a6c40b17SLuben Tuikov 	__ATTR_RO(hw_id),
858a6c40b17SLuben Tuikov 	__ATTR_RO(num_instance),
859a6c40b17SLuben Tuikov 	__ATTR_RO(major),
860a6c40b17SLuben Tuikov 	__ATTR_RO(minor),
861a6c40b17SLuben Tuikov 	__ATTR_RO(revision),
8624d7ba312SLuben Tuikov 	__ATTR_RO(harvest),
863a6c40b17SLuben Tuikov 	__ATTR_RO(num_base_addresses),
864a6c40b17SLuben Tuikov 	__ATTR_RO(base_addr),
865a6c40b17SLuben Tuikov };
866a6c40b17SLuben Tuikov 
8676b503383SLuben Tuikov static struct attribute *ip_hw_instance_attrs[ARRAY_SIZE(ip_hw_attr) + 1];
868a6c40b17SLuben Tuikov ATTRIBUTE_GROUPS(ip_hw_instance);
869a6c40b17SLuben Tuikov 
870a6c40b17SLuben Tuikov #define to_ip_hw_instance(x) container_of(x, struct ip_hw_instance, kobj)
871a6c40b17SLuben Tuikov #define to_ip_hw_instance_attr(x) container_of(x, struct ip_hw_instance_attr, attr)
872a6c40b17SLuben Tuikov 
ip_hw_instance_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)873a6c40b17SLuben Tuikov static ssize_t ip_hw_instance_attr_show(struct kobject *kobj,
874a6c40b17SLuben Tuikov 					struct attribute *attr,
875a6c40b17SLuben Tuikov 					char *buf)
876a6c40b17SLuben Tuikov {
877a6c40b17SLuben Tuikov 	struct ip_hw_instance *ip_hw_instance = to_ip_hw_instance(kobj);
878a6c40b17SLuben Tuikov 	struct ip_hw_instance_attr *ip_hw_attr = to_ip_hw_instance_attr(attr);
879a6c40b17SLuben Tuikov 
880a6c40b17SLuben Tuikov 	if (!ip_hw_attr->show)
881a6c40b17SLuben Tuikov 		return -EIO;
882a6c40b17SLuben Tuikov 
883a6c40b17SLuben Tuikov 	return ip_hw_attr->show(ip_hw_instance, buf);
884a6c40b17SLuben Tuikov }
885a6c40b17SLuben Tuikov 
886a6c40b17SLuben Tuikov static const struct sysfs_ops ip_hw_instance_sysfs_ops = {
887a6c40b17SLuben Tuikov 	.show = ip_hw_instance_attr_show,
888a6c40b17SLuben Tuikov };
889a6c40b17SLuben Tuikov 
ip_hw_instance_release(struct kobject * kobj)890a6c40b17SLuben Tuikov static void ip_hw_instance_release(struct kobject *kobj)
891a6c40b17SLuben Tuikov {
892a6c40b17SLuben Tuikov 	struct ip_hw_instance *ip_hw_instance = to_ip_hw_instance(kobj);
893a6c40b17SLuben Tuikov 
894a6c40b17SLuben Tuikov 	kfree(ip_hw_instance);
895a6c40b17SLuben Tuikov }
896a6c40b17SLuben Tuikov 
897b2daaa93SThomas Weißschuh static const struct kobj_type ip_hw_instance_ktype = {
898a6c40b17SLuben Tuikov 	.release = ip_hw_instance_release,
899a6c40b17SLuben Tuikov 	.sysfs_ops = &ip_hw_instance_sysfs_ops,
900a6c40b17SLuben Tuikov 	.default_groups = ip_hw_instance_groups,
901a6c40b17SLuben Tuikov };
902a6c40b17SLuben Tuikov 
903a6c40b17SLuben Tuikov /* -------------------------------------------------- */
904a6c40b17SLuben Tuikov 
905a6c40b17SLuben Tuikov #define to_ip_hw_id(x)  container_of(to_kset(x), struct ip_hw_id, hw_id_kset)
906a6c40b17SLuben Tuikov 
ip_hw_id_release(struct kobject * kobj)907a6c40b17SLuben Tuikov static void ip_hw_id_release(struct kobject *kobj)
908a6c40b17SLuben Tuikov {
909a6c40b17SLuben Tuikov 	struct ip_hw_id *ip_hw_id = to_ip_hw_id(kobj);
910a6c40b17SLuben Tuikov 
911a6c40b17SLuben Tuikov 	if (!list_empty(&ip_hw_id->hw_id_kset.list))
912a6c40b17SLuben Tuikov 		DRM_ERROR("ip_hw_id->hw_id_kset is not empty");
913a6c40b17SLuben Tuikov 	kfree(ip_hw_id);
914a6c40b17SLuben Tuikov }
915a6c40b17SLuben Tuikov 
916b2daaa93SThomas Weißschuh static const struct kobj_type ip_hw_id_ktype = {
917a6c40b17SLuben Tuikov 	.release = ip_hw_id_release,
918a6c40b17SLuben Tuikov 	.sysfs_ops = &kobj_sysfs_ops,
919a6c40b17SLuben Tuikov };
920a6c40b17SLuben Tuikov 
921a6c40b17SLuben Tuikov /* -------------------------------------------------- */
922a6c40b17SLuben Tuikov 
923a6c40b17SLuben Tuikov static void die_kobj_release(struct kobject *kobj);
924a6c40b17SLuben Tuikov static void ip_disc_release(struct kobject *kobj);
925a6c40b17SLuben Tuikov 
926a6c40b17SLuben Tuikov struct ip_die_entry_attribute {
927a6c40b17SLuben Tuikov 	struct attribute attr;
928a6c40b17SLuben Tuikov 	ssize_t (*show)(struct ip_die_entry *ip_die_entry, char *buf);
929a6c40b17SLuben Tuikov };
930a6c40b17SLuben Tuikov 
931a6c40b17SLuben Tuikov #define to_ip_die_entry_attr(x)  container_of(x, struct ip_die_entry_attribute, attr)
932a6c40b17SLuben Tuikov 
num_ips_show(struct ip_die_entry * ip_die_entry,char * buf)933a6c40b17SLuben Tuikov static ssize_t num_ips_show(struct ip_die_entry *ip_die_entry, char *buf)
934a6c40b17SLuben Tuikov {
935a6c40b17SLuben Tuikov 	return sysfs_emit(buf, "%d\n", ip_die_entry->num_ips);
936a6c40b17SLuben Tuikov }
937a6c40b17SLuben Tuikov 
938a6c40b17SLuben Tuikov /* If there are more ip_die_entry attrs, other than the number of IPs,
939a6c40b17SLuben Tuikov  * we can make this intro an array of attrs, and then initialize
940a6c40b17SLuben Tuikov  * ip_die_entry_attrs in a loop.
941a6c40b17SLuben Tuikov  */
942a6c40b17SLuben Tuikov static struct ip_die_entry_attribute num_ips_attr =
943a6c40b17SLuben Tuikov 	__ATTR_RO(num_ips);
944a6c40b17SLuben Tuikov 
945a6c40b17SLuben Tuikov static struct attribute *ip_die_entry_attrs[] = {
946a6c40b17SLuben Tuikov 	&num_ips_attr.attr,
947a6c40b17SLuben Tuikov 	NULL,
948a6c40b17SLuben Tuikov };
949a6c40b17SLuben Tuikov ATTRIBUTE_GROUPS(ip_die_entry); /* ip_die_entry_groups */
950a6c40b17SLuben Tuikov 
951a6c40b17SLuben Tuikov #define to_ip_die_entry(x) container_of(to_kset(x), struct ip_die_entry, ip_kset)
952a6c40b17SLuben Tuikov 
ip_die_entry_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)953a6c40b17SLuben Tuikov static ssize_t ip_die_entry_attr_show(struct kobject *kobj,
954a6c40b17SLuben Tuikov 				      struct attribute *attr,
955a6c40b17SLuben Tuikov 				      char *buf)
956a6c40b17SLuben Tuikov {
957a6c40b17SLuben Tuikov 	struct ip_die_entry_attribute *ip_die_entry_attr = to_ip_die_entry_attr(attr);
958a6c40b17SLuben Tuikov 	struct ip_die_entry *ip_die_entry = to_ip_die_entry(kobj);
959a6c40b17SLuben Tuikov 
960a6c40b17SLuben Tuikov 	if (!ip_die_entry_attr->show)
961a6c40b17SLuben Tuikov 		return -EIO;
962a6c40b17SLuben Tuikov 
963a6c40b17SLuben Tuikov 	return ip_die_entry_attr->show(ip_die_entry, buf);
964a6c40b17SLuben Tuikov }
965a6c40b17SLuben Tuikov 
ip_die_entry_release(struct kobject * kobj)966a6c40b17SLuben Tuikov static void ip_die_entry_release(struct kobject *kobj)
967a6c40b17SLuben Tuikov {
968a6c40b17SLuben Tuikov 	struct ip_die_entry *ip_die_entry = to_ip_die_entry(kobj);
969a6c40b17SLuben Tuikov 
970a6c40b17SLuben Tuikov 	if (!list_empty(&ip_die_entry->ip_kset.list))
971a6c40b17SLuben Tuikov 		DRM_ERROR("ip_die_entry->ip_kset is not empty");
972a6c40b17SLuben Tuikov 	kfree(ip_die_entry);
973a6c40b17SLuben Tuikov }
974a6c40b17SLuben Tuikov 
975a6c40b17SLuben Tuikov static const struct sysfs_ops ip_die_entry_sysfs_ops = {
976a6c40b17SLuben Tuikov 	.show = ip_die_entry_attr_show,
977a6c40b17SLuben Tuikov };
978a6c40b17SLuben Tuikov 
979b2daaa93SThomas Weißschuh static const struct kobj_type ip_die_entry_ktype = {
980a6c40b17SLuben Tuikov 	.release = ip_die_entry_release,
981a6c40b17SLuben Tuikov 	.sysfs_ops = &ip_die_entry_sysfs_ops,
982a6c40b17SLuben Tuikov 	.default_groups = ip_die_entry_groups,
983a6c40b17SLuben Tuikov };
984a6c40b17SLuben Tuikov 
985b2daaa93SThomas Weißschuh static const struct kobj_type die_kobj_ktype = {
986a6c40b17SLuben Tuikov 	.release = die_kobj_release,
987a6c40b17SLuben Tuikov 	.sysfs_ops = &kobj_sysfs_ops,
988a6c40b17SLuben Tuikov };
989a6c40b17SLuben Tuikov 
990b2daaa93SThomas Weißschuh static const struct kobj_type ip_discovery_ktype = {
991a6c40b17SLuben Tuikov 	.release = ip_disc_release,
992a6c40b17SLuben Tuikov 	.sysfs_ops = &kobj_sysfs_ops,
993a6c40b17SLuben Tuikov };
994a6c40b17SLuben Tuikov 
995a6c40b17SLuben Tuikov struct ip_discovery_top {
996a6c40b17SLuben Tuikov 	struct kobject kobj;    /* ip_discovery/ */
997a6c40b17SLuben Tuikov 	struct kset die_kset;   /* ip_discovery/die/, contains ip_die_entry */
998a6c40b17SLuben Tuikov 	struct amdgpu_device *adev;
999a6c40b17SLuben Tuikov };
1000a6c40b17SLuben Tuikov 
die_kobj_release(struct kobject * kobj)1001a6c40b17SLuben Tuikov static void die_kobj_release(struct kobject *kobj)
1002a6c40b17SLuben Tuikov {
1003a6c40b17SLuben Tuikov 	struct ip_discovery_top *ip_top = container_of(to_kset(kobj),
1004a6c40b17SLuben Tuikov 						       struct ip_discovery_top,
1005a6c40b17SLuben Tuikov 						       die_kset);
1006a6c40b17SLuben Tuikov 	if (!list_empty(&ip_top->die_kset.list))
1007a6c40b17SLuben Tuikov 		DRM_ERROR("ip_top->die_kset is not empty");
1008a6c40b17SLuben Tuikov }
1009a6c40b17SLuben Tuikov 
ip_disc_release(struct kobject * kobj)1010a6c40b17SLuben Tuikov static void ip_disc_release(struct kobject *kobj)
1011a6c40b17SLuben Tuikov {
1012a6c40b17SLuben Tuikov 	struct ip_discovery_top *ip_top = container_of(kobj, struct ip_discovery_top,
1013a6c40b17SLuben Tuikov 						       kobj);
1014a6c40b17SLuben Tuikov 	struct amdgpu_device *adev = ip_top->adev;
1015a6c40b17SLuben Tuikov 
1016a6c40b17SLuben Tuikov 	adev->ip_top = NULL;
1017a6c40b17SLuben Tuikov 	kfree(ip_top);
1018a6c40b17SLuben Tuikov }
1019a6c40b17SLuben Tuikov 
amdgpu_discovery_get_harvest_info(struct amdgpu_device * adev,uint16_t hw_id,uint8_t inst)1020f2b8447bSLijo Lazar static uint8_t amdgpu_discovery_get_harvest_info(struct amdgpu_device *adev,
1021f2b8447bSLijo Lazar 						 uint16_t hw_id, uint8_t inst)
1022f2b8447bSLijo Lazar {
1023f2b8447bSLijo Lazar 	uint8_t harvest = 0;
1024f2b8447bSLijo Lazar 
1025f2b8447bSLijo Lazar 	/* Until a uniform way is figured, get mask based on hwid */
1026f2b8447bSLijo Lazar 	switch (hw_id) {
1027f2b8447bSLijo Lazar 	case VCN_HWID:
10286a944ccbSLijo Lazar 		harvest = ((1 << inst) & adev->vcn.inst_mask) == 0;
1029f2b8447bSLijo Lazar 		break;
1030f2b8447bSLijo Lazar 	case DMU_HWID:
1031f2b8447bSLijo Lazar 		if (adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK)
1032f2b8447bSLijo Lazar 			harvest = 0x1;
1033f2b8447bSLijo Lazar 		break;
1034f2b8447bSLijo Lazar 	case UMC_HWID:
1035f2b8447bSLijo Lazar 		/* TODO: It needs another parsing; for now, ignore.*/
1036f2b8447bSLijo Lazar 		break;
1037f2b8447bSLijo Lazar 	case GC_HWID:
1038f2b8447bSLijo Lazar 		harvest = ((1 << inst) & adev->gfx.xcc_mask) == 0;
1039f2b8447bSLijo Lazar 		break;
1040f2b8447bSLijo Lazar 	case SDMA0_HWID:
1041f2b8447bSLijo Lazar 		harvest = ((1 << inst) & adev->sdma.sdma_mask) == 0;
1042f2b8447bSLijo Lazar 		break;
1043f2b8447bSLijo Lazar 	default:
1044f2b8447bSLijo Lazar 		break;
1045f2b8447bSLijo Lazar 	}
1046f2b8447bSLijo Lazar 
1047f2b8447bSLijo Lazar 	return harvest;
1048f2b8447bSLijo Lazar }
1049f2b8447bSLijo Lazar 
amdgpu_discovery_sysfs_ips(struct amdgpu_device * adev,struct ip_die_entry * ip_die_entry,const size_t _ip_offset,const int num_ips,bool reg_base_64)1050a6c40b17SLuben Tuikov static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,
1051a6c40b17SLuben Tuikov 				      struct ip_die_entry *ip_die_entry,
10527d158f52SLe Ma 				      const size_t _ip_offset, const int num_ips,
10537d158f52SLe Ma 				      bool reg_base_64)
1054a6c40b17SLuben Tuikov {
1055a6c40b17SLuben Tuikov 	int ii, jj, kk, res;
105631f9ed58SLijo Lazar 	uint16_t hw_id;
105731f9ed58SLijo Lazar 	uint8_t inst;
1058a6c40b17SLuben Tuikov 
1059a6c40b17SLuben Tuikov 	DRM_DEBUG("num_ips:%d", num_ips);
1060a6c40b17SLuben Tuikov 
1061a6c40b17SLuben Tuikov 	/* Find all IPs of a given HW ID, and add their instance to
1062a6c40b17SLuben Tuikov 	 * #die/#hw_id/#instance/<attributes>
1063a6c40b17SLuben Tuikov 	 */
1064a6c40b17SLuben Tuikov 	for (ii = 0; ii < HW_ID_MAX; ii++) {
1065a6c40b17SLuben Tuikov 		struct ip_hw_id *ip_hw_id = NULL;
1066a6c40b17SLuben Tuikov 		size_t ip_offset = _ip_offset;
1067a6c40b17SLuben Tuikov 
1068a6c40b17SLuben Tuikov 		for (jj = 0; jj < num_ips; jj++) {
1069aabb4784SLe Ma 			struct ip_v4 *ip;
1070a6c40b17SLuben Tuikov 			struct ip_hw_instance *ip_hw_instance;
1071a6c40b17SLuben Tuikov 
1072aabb4784SLe Ma 			ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset);
107331f9ed58SLijo Lazar 			inst = ip->instance_number;
107431f9ed58SLijo Lazar 			hw_id = le16_to_cpu(ip->hw_id);
107531f9ed58SLijo Lazar 			if (amdgpu_discovery_validate_ip(adev, inst, hw_id) ||
107631f9ed58SLijo Lazar 			    hw_id != ii)
1077a6c40b17SLuben Tuikov 				goto next_ip;
1078a6c40b17SLuben Tuikov 
1079f0d54098SLuben Tuikov 			DRM_DEBUG("match:%d @ ip_offset:%zu", ii, ip_offset);
1080a6c40b17SLuben Tuikov 
1081a6c40b17SLuben Tuikov 			/* We have a hw_id match; register the hw
1082a6c40b17SLuben Tuikov 			 * block if not yet registered.
1083a6c40b17SLuben Tuikov 			 */
1084a6c40b17SLuben Tuikov 			if (!ip_hw_id) {
1085a6c40b17SLuben Tuikov 				ip_hw_id = kzalloc(sizeof(*ip_hw_id), GFP_KERNEL);
1086a6c40b17SLuben Tuikov 				if (!ip_hw_id)
1087a6c40b17SLuben Tuikov 					return -ENOMEM;
1088a6c40b17SLuben Tuikov 				ip_hw_id->hw_id = ii;
1089a6c40b17SLuben Tuikov 
1090a6c40b17SLuben Tuikov 				kobject_set_name(&ip_hw_id->hw_id_kset.kobj, "%d", ii);
1091a6c40b17SLuben Tuikov 				ip_hw_id->hw_id_kset.kobj.kset = &ip_die_entry->ip_kset;
1092a6c40b17SLuben Tuikov 				ip_hw_id->hw_id_kset.kobj.ktype = &ip_hw_id_ktype;
1093a6c40b17SLuben Tuikov 				res = kset_register(&ip_hw_id->hw_id_kset);
1094a6c40b17SLuben Tuikov 				if (res) {
1095a6c40b17SLuben Tuikov 					DRM_ERROR("Couldn't register ip_hw_id kset");
1096a6c40b17SLuben Tuikov 					kfree(ip_hw_id);
1097a6c40b17SLuben Tuikov 					return res;
1098a6c40b17SLuben Tuikov 				}
1099a6c40b17SLuben Tuikov 				if (hw_id_names[ii]) {
1100a6c40b17SLuben Tuikov 					res = sysfs_create_link(&ip_die_entry->ip_kset.kobj,
1101a6c40b17SLuben Tuikov 								&ip_hw_id->hw_id_kset.kobj,
1102a6c40b17SLuben Tuikov 								hw_id_names[ii]);
1103a6c40b17SLuben Tuikov 					if (res) {
1104a6c40b17SLuben Tuikov 						DRM_ERROR("Couldn't create IP link %s in IP Die:%s\n",
1105a6c40b17SLuben Tuikov 							  hw_id_names[ii],
1106a6c40b17SLuben Tuikov 							  kobject_name(&ip_die_entry->ip_kset.kobj));
1107a6c40b17SLuben Tuikov 					}
1108a6c40b17SLuben Tuikov 				}
1109a6c40b17SLuben Tuikov 			}
1110a6c40b17SLuben Tuikov 
1111a6c40b17SLuben Tuikov 			/* Now register its instance.
1112a6c40b17SLuben Tuikov 			 */
1113a6c40b17SLuben Tuikov 			ip_hw_instance = kzalloc(struct_size(ip_hw_instance,
1114a6c40b17SLuben Tuikov 							     base_addr,
1115a6c40b17SLuben Tuikov 							     ip->num_base_address),
1116a6c40b17SLuben Tuikov 						 GFP_KERNEL);
1117a6c40b17SLuben Tuikov 			if (!ip_hw_instance) {
1118a6c40b17SLuben Tuikov 				DRM_ERROR("no memory for ip_hw_instance");
1119a6c40b17SLuben Tuikov 				return -ENOMEM;
1120a6c40b17SLuben Tuikov 			}
1121a6c40b17SLuben Tuikov 			ip_hw_instance->hw_id = le16_to_cpu(ip->hw_id); /* == ii */
1122aabb4784SLe Ma 			ip_hw_instance->num_instance = ip->instance_number;
1123a6c40b17SLuben Tuikov 			ip_hw_instance->major = ip->major;
1124a6c40b17SLuben Tuikov 			ip_hw_instance->minor = ip->minor;
1125a6c40b17SLuben Tuikov 			ip_hw_instance->revision = ip->revision;
1126f2b8447bSLijo Lazar 			ip_hw_instance->harvest =
1127f2b8447bSLijo Lazar 				amdgpu_discovery_get_harvest_info(
1128f2b8447bSLijo Lazar 					adev, ip_hw_instance->hw_id,
1129f2b8447bSLijo Lazar 					ip_hw_instance->num_instance);
1130a6c40b17SLuben Tuikov 			ip_hw_instance->num_base_addresses = ip->num_base_address;
1131a6c40b17SLuben Tuikov 
11327d158f52SLe Ma 			for (kk = 0; kk < ip_hw_instance->num_base_addresses; kk++) {
11337d158f52SLe Ma 				if (reg_base_64)
11347d158f52SLe Ma 					ip_hw_instance->base_addr[kk] =
11357d158f52SLe Ma 						lower_32_bits(le64_to_cpu(ip->base_address_64[kk])) & 0x3FFFFFFF;
11367d158f52SLe Ma 				else
1137a6c40b17SLuben Tuikov 					ip_hw_instance->base_addr[kk] = ip->base_address[kk];
11387d158f52SLe Ma 			}
1139a6c40b17SLuben Tuikov 
1140a6c40b17SLuben Tuikov 			kobject_init(&ip_hw_instance->kobj, &ip_hw_instance_ktype);
1141a6c40b17SLuben Tuikov 			ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset;
1142a6c40b17SLuben Tuikov 			res = kobject_add(&ip_hw_instance->kobj, NULL,
1143a6c40b17SLuben Tuikov 					  "%d", ip_hw_instance->num_instance);
1144a6c40b17SLuben Tuikov next_ip:
11457d158f52SLe Ma 			if (reg_base_64)
11467d158f52SLe Ma 				ip_offset += struct_size(ip, base_address_64,
11477d158f52SLe Ma 							 ip->num_base_address);
11487d158f52SLe Ma 			else
11497d158f52SLe Ma 				ip_offset += struct_size(ip, base_address,
11507d158f52SLe Ma 							 ip->num_base_address);
1151a6c40b17SLuben Tuikov 		}
1152a6c40b17SLuben Tuikov 	}
1153a6c40b17SLuben Tuikov 
1154a6c40b17SLuben Tuikov 	return 0;
1155a6c40b17SLuben Tuikov }
1156a6c40b17SLuben Tuikov 
amdgpu_discovery_sysfs_recurse(struct amdgpu_device * adev)1157a6c40b17SLuben Tuikov static int amdgpu_discovery_sysfs_recurse(struct amdgpu_device *adev)
1158a6c40b17SLuben Tuikov {
1159a6c40b17SLuben Tuikov 	struct binary_header *bhdr;
1160a6c40b17SLuben Tuikov 	struct ip_discovery_header *ihdr;
1161a6c40b17SLuben Tuikov 	struct die_header *dhdr;
1162a6c40b17SLuben Tuikov 	struct kset *die_kset = &adev->ip_top->die_kset;
1163a6c40b17SLuben Tuikov 	u16 num_dies, die_offset, num_ips;
1164a6c40b17SLuben Tuikov 	size_t ip_offset;
1165a6c40b17SLuben Tuikov 	int ii, res;
1166a6c40b17SLuben Tuikov 
1167a6c40b17SLuben Tuikov 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
1168a6c40b17SLuben Tuikov 	ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
1169a6c40b17SLuben Tuikov 					      le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));
1170a6c40b17SLuben Tuikov 	num_dies = le16_to_cpu(ihdr->num_dies);
1171a6c40b17SLuben Tuikov 
1172a6c40b17SLuben Tuikov 	DRM_DEBUG("number of dies: %d\n", num_dies);
1173a6c40b17SLuben Tuikov 
1174a6c40b17SLuben Tuikov 	for (ii = 0; ii < num_dies; ii++) {
1175a6c40b17SLuben Tuikov 		struct ip_die_entry *ip_die_entry;
1176a6c40b17SLuben Tuikov 
1177a6c40b17SLuben Tuikov 		die_offset = le16_to_cpu(ihdr->die_info[ii].die_offset);
1178a6c40b17SLuben Tuikov 		dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset);
1179a6c40b17SLuben Tuikov 		num_ips = le16_to_cpu(dhdr->num_ips);
1180a6c40b17SLuben Tuikov 		ip_offset = die_offset + sizeof(*dhdr);
1181a6c40b17SLuben Tuikov 
1182a6c40b17SLuben Tuikov 		/* Add the die to the kset.
1183a6c40b17SLuben Tuikov 		 *
1184a6c40b17SLuben Tuikov 		 * dhdr->die_id == ii, which was checked in
1185a6c40b17SLuben Tuikov 		 * amdgpu_discovery_reg_base_init().
1186a6c40b17SLuben Tuikov 		 */
1187a6c40b17SLuben Tuikov 
1188a6c40b17SLuben Tuikov 		ip_die_entry = kzalloc(sizeof(*ip_die_entry), GFP_KERNEL);
1189a6c40b17SLuben Tuikov 		if (!ip_die_entry)
1190a6c40b17SLuben Tuikov 			return -ENOMEM;
1191a6c40b17SLuben Tuikov 
1192a6c40b17SLuben Tuikov 		ip_die_entry->num_ips = num_ips;
1193a6c40b17SLuben Tuikov 
1194a6c40b17SLuben Tuikov 		kobject_set_name(&ip_die_entry->ip_kset.kobj, "%d", le16_to_cpu(dhdr->die_id));
1195a6c40b17SLuben Tuikov 		ip_die_entry->ip_kset.kobj.kset = die_kset;
1196a6c40b17SLuben Tuikov 		ip_die_entry->ip_kset.kobj.ktype = &ip_die_entry_ktype;
1197a6c40b17SLuben Tuikov 		res = kset_register(&ip_die_entry->ip_kset);
1198a6c40b17SLuben Tuikov 		if (res) {
1199a6c40b17SLuben Tuikov 			DRM_ERROR("Couldn't register ip_die_entry kset");
1200a6c40b17SLuben Tuikov 			kfree(ip_die_entry);
1201a6c40b17SLuben Tuikov 			return res;
1202a6c40b17SLuben Tuikov 		}
1203a6c40b17SLuben Tuikov 
12047d158f52SLe Ma 		amdgpu_discovery_sysfs_ips(adev, ip_die_entry, ip_offset, num_ips, !!ihdr->base_addr_64_bit);
1205a6c40b17SLuben Tuikov 	}
1206a6c40b17SLuben Tuikov 
1207a6c40b17SLuben Tuikov 	return 0;
1208a6c40b17SLuben Tuikov }
1209a6c40b17SLuben Tuikov 
amdgpu_discovery_sysfs_init(struct amdgpu_device * adev)1210a6c40b17SLuben Tuikov static int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev)
1211a6c40b17SLuben Tuikov {
1212a6c40b17SLuben Tuikov 	struct kset *die_kset;
12136b503383SLuben Tuikov 	int res, ii;
1214a6c40b17SLuben Tuikov 
1215f2b8447bSLijo Lazar 	if (!adev->mman.discovery_bin)
1216f2b8447bSLijo Lazar 		return -EINVAL;
1217f2b8447bSLijo Lazar 
1218a6c40b17SLuben Tuikov 	adev->ip_top = kzalloc(sizeof(*adev->ip_top), GFP_KERNEL);
1219a6c40b17SLuben Tuikov 	if (!adev->ip_top)
1220a6c40b17SLuben Tuikov 		return -ENOMEM;
1221a6c40b17SLuben Tuikov 
1222a6c40b17SLuben Tuikov 	adev->ip_top->adev = adev;
1223a6c40b17SLuben Tuikov 
1224a6c40b17SLuben Tuikov 	res = kobject_init_and_add(&adev->ip_top->kobj, &ip_discovery_ktype,
1225a6c40b17SLuben Tuikov 				   &adev->dev->kobj, "ip_discovery");
1226a6c40b17SLuben Tuikov 	if (res) {
1227a6c40b17SLuben Tuikov 		DRM_ERROR("Couldn't init and add ip_discovery/");
1228a6c40b17SLuben Tuikov 		goto Err;
1229a6c40b17SLuben Tuikov 	}
1230a6c40b17SLuben Tuikov 
1231a6c40b17SLuben Tuikov 	die_kset = &adev->ip_top->die_kset;
1232a6c40b17SLuben Tuikov 	kobject_set_name(&die_kset->kobj, "%s", "die");
1233a6c40b17SLuben Tuikov 	die_kset->kobj.parent = &adev->ip_top->kobj;
1234a6c40b17SLuben Tuikov 	die_kset->kobj.ktype = &die_kobj_ktype;
1235a6c40b17SLuben Tuikov 	res = kset_register(&adev->ip_top->die_kset);
1236a6c40b17SLuben Tuikov 	if (res) {
1237a6c40b17SLuben Tuikov 		DRM_ERROR("Couldn't register die_kset");
1238a6c40b17SLuben Tuikov 		goto Err;
1239a6c40b17SLuben Tuikov 	}
1240a6c40b17SLuben Tuikov 
12416b503383SLuben Tuikov 	for (ii = 0; ii < ARRAY_SIZE(ip_hw_attr); ii++)
12426b503383SLuben Tuikov 		ip_hw_instance_attrs[ii] = &ip_hw_attr[ii].attr;
12436b503383SLuben Tuikov 	ip_hw_instance_attrs[ii] = NULL;
12446b503383SLuben Tuikov 
1245a6c40b17SLuben Tuikov 	res = amdgpu_discovery_sysfs_recurse(adev);
1246a6c40b17SLuben Tuikov 
1247a6c40b17SLuben Tuikov 	return res;
1248a6c40b17SLuben Tuikov Err:
1249a6c40b17SLuben Tuikov 	kobject_put(&adev->ip_top->kobj);
1250a6c40b17SLuben Tuikov 	return res;
1251a6c40b17SLuben Tuikov }
1252a6c40b17SLuben Tuikov 
1253a6c40b17SLuben Tuikov /* -------------------------------------------------- */
1254a6c40b17SLuben Tuikov 
1255a6c40b17SLuben Tuikov #define list_to_kobj(el) container_of(el, struct kobject, entry)
1256a6c40b17SLuben Tuikov 
amdgpu_discovery_sysfs_ip_hw_free(struct ip_hw_id * ip_hw_id)1257a6c40b17SLuben Tuikov static void amdgpu_discovery_sysfs_ip_hw_free(struct ip_hw_id *ip_hw_id)
1258a6c40b17SLuben Tuikov {
1259a6c40b17SLuben Tuikov 	struct list_head *el, *tmp;
1260a6c40b17SLuben Tuikov 	struct kset *hw_id_kset;
1261a6c40b17SLuben Tuikov 
1262a6c40b17SLuben Tuikov 	hw_id_kset = &ip_hw_id->hw_id_kset;
1263a6c40b17SLuben Tuikov 	spin_lock(&hw_id_kset->list_lock);
1264a6c40b17SLuben Tuikov 	list_for_each_prev_safe(el, tmp, &hw_id_kset->list) {
1265a6c40b17SLuben Tuikov 		list_del_init(el);
1266a6c40b17SLuben Tuikov 		spin_unlock(&hw_id_kset->list_lock);
1267a6c40b17SLuben Tuikov 		/* kobject is embedded in ip_hw_instance */
1268a6c40b17SLuben Tuikov 		kobject_put(list_to_kobj(el));
1269a6c40b17SLuben Tuikov 		spin_lock(&hw_id_kset->list_lock);
1270a6c40b17SLuben Tuikov 	}
1271a6c40b17SLuben Tuikov 	spin_unlock(&hw_id_kset->list_lock);
1272a6c40b17SLuben Tuikov 	kobject_put(&ip_hw_id->hw_id_kset.kobj);
1273a6c40b17SLuben Tuikov }
1274a6c40b17SLuben Tuikov 
amdgpu_discovery_sysfs_die_free(struct ip_die_entry * ip_die_entry)1275a6c40b17SLuben Tuikov static void amdgpu_discovery_sysfs_die_free(struct ip_die_entry *ip_die_entry)
1276a6c40b17SLuben Tuikov {
1277a6c40b17SLuben Tuikov 	struct list_head *el, *tmp;
1278a6c40b17SLuben Tuikov 	struct kset *ip_kset;
1279a6c40b17SLuben Tuikov 
1280a6c40b17SLuben Tuikov 	ip_kset = &ip_die_entry->ip_kset;
1281a6c40b17SLuben Tuikov 	spin_lock(&ip_kset->list_lock);
1282a6c40b17SLuben Tuikov 	list_for_each_prev_safe(el, tmp, &ip_kset->list) {
1283a6c40b17SLuben Tuikov 		list_del_init(el);
1284a6c40b17SLuben Tuikov 		spin_unlock(&ip_kset->list_lock);
1285a6c40b17SLuben Tuikov 		amdgpu_discovery_sysfs_ip_hw_free(to_ip_hw_id(list_to_kobj(el)));
1286a6c40b17SLuben Tuikov 		spin_lock(&ip_kset->list_lock);
1287a6c40b17SLuben Tuikov 	}
1288a6c40b17SLuben Tuikov 	spin_unlock(&ip_kset->list_lock);
1289a6c40b17SLuben Tuikov 	kobject_put(&ip_die_entry->ip_kset.kobj);
1290a6c40b17SLuben Tuikov }
1291a6c40b17SLuben Tuikov 
amdgpu_discovery_sysfs_fini(struct amdgpu_device * adev)1292a6c40b17SLuben Tuikov static void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev)
1293a6c40b17SLuben Tuikov {
1294a6c40b17SLuben Tuikov 	struct list_head *el, *tmp;
1295a6c40b17SLuben Tuikov 	struct kset *die_kset;
1296a6c40b17SLuben Tuikov 
1297a6c40b17SLuben Tuikov 	die_kset = &adev->ip_top->die_kset;
1298a6c40b17SLuben Tuikov 	spin_lock(&die_kset->list_lock);
1299a6c40b17SLuben Tuikov 	list_for_each_prev_safe(el, tmp, &die_kset->list) {
1300a6c40b17SLuben Tuikov 		list_del_init(el);
1301a6c40b17SLuben Tuikov 		spin_unlock(&die_kset->list_lock);
1302a6c40b17SLuben Tuikov 		amdgpu_discovery_sysfs_die_free(to_ip_die_entry(list_to_kobj(el)));
1303a6c40b17SLuben Tuikov 		spin_lock(&die_kset->list_lock);
1304a6c40b17SLuben Tuikov 	}
1305a6c40b17SLuben Tuikov 	spin_unlock(&die_kset->list_lock);
1306a6c40b17SLuben Tuikov 	kobject_put(&adev->ip_top->die_kset.kobj);
1307a6c40b17SLuben Tuikov 	kobject_put(&adev->ip_top->kobj);
1308a6c40b17SLuben Tuikov }
1309a6c40b17SLuben Tuikov 
1310a6c40b17SLuben Tuikov /* ================================================== */
1311a6c40b17SLuben Tuikov 
amdgpu_discovery_reg_base_init(struct amdgpu_device * adev)1312e24d0e91SAlex Deucher static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
1313f39f5bb1SXiaojie Yuan {
1314ff96ddc3SLijo Lazar 	uint8_t num_base_address, subrev, variant;
1315f39f5bb1SXiaojie Yuan 	struct binary_header *bhdr;
1316f39f5bb1SXiaojie Yuan 	struct ip_discovery_header *ihdr;
1317f39f5bb1SXiaojie Yuan 	struct die_header *dhdr;
1318aabb4784SLe Ma 	struct ip_v4 *ip;
1319f39f5bb1SXiaojie Yuan 	uint16_t die_offset;
1320f39f5bb1SXiaojie Yuan 	uint16_t ip_offset;
1321f39f5bb1SXiaojie Yuan 	uint16_t num_dies;
13226c11d4a8SLijo Lazar 	uint32_t wafl_ver;
1323f39f5bb1SXiaojie Yuan 	uint16_t num_ips;
132431f9ed58SLijo Lazar 	uint16_t hw_id;
132531f9ed58SLijo Lazar 	uint8_t inst;
1326f39f5bb1SXiaojie Yuan 	int hw_ip;
1327f39f5bb1SXiaojie Yuan 	int i, j, k;
1328dffa11b4SMonk Liu 	int r;
1329f39f5bb1SXiaojie Yuan 
1330dffa11b4SMonk Liu 	r = amdgpu_discovery_init(adev);
1331dffa11b4SMonk Liu 	if (r) {
1332dffa11b4SMonk Liu 		DRM_ERROR("amdgpu_discovery_init failed\n");
1333dffa11b4SMonk Liu 		return r;
1334f39f5bb1SXiaojie Yuan 	}
1335f39f5bb1SXiaojie Yuan 
13366c11d4a8SLijo Lazar 	wafl_ver = 0;
133773fa2553SLijo Lazar 	adev->gfx.xcc_mask = 0;
133873fa2553SLijo Lazar 	adev->sdma.sdma_mask = 0;
1339aaf1090aSLijo Lazar 	adev->vcn.inst_mask = 0;
1340aaf1090aSLijo Lazar 	adev->jpeg.inst_mask = 0;
134172de33f8SAlex Deucher 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
134272de33f8SAlex Deucher 	ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
1343f39f5bb1SXiaojie Yuan 			le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));
1344f39f5bb1SXiaojie Yuan 	num_dies = le16_to_cpu(ihdr->num_dies);
1345f39f5bb1SXiaojie Yuan 
1346437298b8SXiaojie Yuan 	DRM_DEBUG("number of dies: %d\n", num_dies);
1347f39f5bb1SXiaojie Yuan 
1348f39f5bb1SXiaojie Yuan 	for (i = 0; i < num_dies; i++) {
1349f39f5bb1SXiaojie Yuan 		die_offset = le16_to_cpu(ihdr->die_info[i].die_offset);
135072de33f8SAlex Deucher 		dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset);
1351f39f5bb1SXiaojie Yuan 		num_ips = le16_to_cpu(dhdr->num_ips);
1352f39f5bb1SXiaojie Yuan 		ip_offset = die_offset + sizeof(*dhdr);
1353f39f5bb1SXiaojie Yuan 
1354437298b8SXiaojie Yuan 		if (le16_to_cpu(dhdr->die_id) != i) {
1355437298b8SXiaojie Yuan 			DRM_ERROR("invalid die id %d, expected %d\n",
1356437298b8SXiaojie Yuan 					le16_to_cpu(dhdr->die_id), i);
1357437298b8SXiaojie Yuan 			return -EINVAL;
1358437298b8SXiaojie Yuan 		}
1359437298b8SXiaojie Yuan 
1360437298b8SXiaojie Yuan 		DRM_DEBUG("number of hardware IPs on die%d: %d\n",
1361437298b8SXiaojie Yuan 				le16_to_cpu(dhdr->die_id), num_ips);
1362437298b8SXiaojie Yuan 
1363f39f5bb1SXiaojie Yuan 		for (j = 0; j < num_ips; j++) {
1364aabb4784SLe Ma 			ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset);
13655039f529SErnst Sjöstrand 
136631f9ed58SLijo Lazar 			inst = ip->instance_number;
136731f9ed58SLijo Lazar 			hw_id = le16_to_cpu(ip->hw_id);
136831f9ed58SLijo Lazar 			if (amdgpu_discovery_validate_ip(adev, inst, hw_id))
13695039f529SErnst Sjöstrand 				goto next_ip;
13705039f529SErnst Sjöstrand 
1371f39f5bb1SXiaojie Yuan 			num_base_address = ip->num_base_address;
1372f39f5bb1SXiaojie Yuan 
1373437298b8SXiaojie Yuan 			DRM_DEBUG("%s(%d) #%d v%d.%d.%d:\n",
1374437298b8SXiaojie Yuan 				  hw_id_names[le16_to_cpu(ip->hw_id)],
1375437298b8SXiaojie Yuan 				  le16_to_cpu(ip->hw_id),
1376aabb4784SLe Ma 				  ip->instance_number,
1377f39f5bb1SXiaojie Yuan 				  ip->major, ip->minor,
1378f39f5bb1SXiaojie Yuan 				  ip->revision);
1379f39f5bb1SXiaojie Yuan 
1380baf3f8f3SAlex Deucher 			if (le16_to_cpu(ip->hw_id) == VCN_HWID) {
1381c40bdfb2SLeslie Shi 				/* Bit [5:0]: original revision value
1382baf3f8f3SAlex Deucher 				 * Bit [7:6]: en/decode capability:
1383baf3f8f3SAlex Deucher 				 *     0b00 : VCN function normally
1384baf3f8f3SAlex Deucher 				 *     0b10 : encode is disabled
1385baf3f8f3SAlex Deucher 				 *     0b01 : decode is disabled
1386baf3f8f3SAlex Deucher 				 */
1387aaf1090aSLijo Lazar 				if (adev->vcn.num_vcn_inst <
1388aaf1090aSLijo Lazar 				    AMDGPU_MAX_VCN_INSTANCES) {
1389cf1aa9ffSBoyuan Zhang 					adev->vcn.inst[adev->vcn.num_vcn_inst].vcn_config =
1390cdb637d3SSrinivasan Shanmugam 						ip->revision & 0xc0;
13917cbe08a9SAlex Deucher 					adev->vcn.num_vcn_inst++;
1392aaf1090aSLijo Lazar 					adev->vcn.inst_mask |=
1393aaf1090aSLijo Lazar 						(1U << ip->instance_number);
1394aaf1090aSLijo Lazar 					adev->jpeg.inst_mask |=
1395aaf1090aSLijo Lazar 						(1U << ip->instance_number);
1396aaf1090aSLijo Lazar 				} else {
1397a0ccc717SAlex Deucher 					dev_err(adev->dev, "Too many VCN instances: %d vs %d\n",
1398a0ccc717SAlex Deucher 						adev->vcn.num_vcn_inst + 1,
1399a0ccc717SAlex Deucher 						AMDGPU_MAX_VCN_INSTANCES);
1400baf3f8f3SAlex Deucher 				}
1401cdb637d3SSrinivasan Shanmugam 				ip->revision &= ~0xc0;
1402aaf1090aSLijo Lazar 			}
14035c3720beSAlex Deucher 			if (le16_to_cpu(ip->hw_id) == SDMA0_HWID ||
14045c3720beSAlex Deucher 			    le16_to_cpu(ip->hw_id) == SDMA1_HWID ||
14055c3720beSAlex Deucher 			    le16_to_cpu(ip->hw_id) == SDMA2_HWID ||
1406a0ccc717SAlex Deucher 			    le16_to_cpu(ip->hw_id) == SDMA3_HWID) {
140773fa2553SLijo Lazar 				if (adev->sdma.num_instances <
140873fa2553SLijo Lazar 				    AMDGPU_MAX_SDMA_INSTANCES) {
14095c3720beSAlex Deucher 					adev->sdma.num_instances++;
141073fa2553SLijo Lazar 					adev->sdma.sdma_mask |=
141173fa2553SLijo Lazar 						(1U << ip->instance_number);
141273fa2553SLijo Lazar 				} else {
1413a0ccc717SAlex Deucher 					dev_err(adev->dev, "Too many SDMA instances: %d vs %d\n",
1414a0ccc717SAlex Deucher 						adev->sdma.num_instances + 1,
1415a0ccc717SAlex Deucher 						AMDGPU_MAX_SDMA_INSTANCES);
1416a0ccc717SAlex Deucher 				}
141773fa2553SLijo Lazar 			}
14187cbe08a9SAlex Deucher 
1419709ef39fSLang Yu 			if (le16_to_cpu(ip->hw_id) == VPE_HWID) {
1420709ef39fSLang Yu 				if (adev->vpe.num_instances < AMDGPU_MAX_VPE_INSTANCES)
1421709ef39fSLang Yu 					adev->vpe.num_instances++;
1422709ef39fSLang Yu 				else
1423709ef39fSLang Yu 					dev_err(adev->dev, "Too many VPE instances: %d vs %d\n",
1424709ef39fSLang Yu 						adev->vpe.num_instances + 1,
1425709ef39fSLang Yu 						AMDGPU_MAX_VPE_INSTANCES);
1426709ef39fSLang Yu 			}
1427709ef39fSLang Yu 
14282b595659SCandice Li 			if (le16_to_cpu(ip->hw_id) == UMC_HWID) {
1429a2efebf1SAlex Deucher 				adev->gmc.num_umc++;
14302b595659SCandice Li 				adev->umc.node_inst_num++;
14312b595659SCandice Li 			}
1432a2efebf1SAlex Deucher 
143373fa2553SLijo Lazar 			if (le16_to_cpu(ip->hw_id) == GC_HWID)
143473fa2553SLijo Lazar 				adev->gfx.xcc_mask |=
143573fa2553SLijo Lazar 					(1U << ip->instance_number);
143673fa2553SLijo Lazar 
14376c11d4a8SLijo Lazar 			if (!wafl_ver && le16_to_cpu(ip->hw_id) == WAFLC_HWID)
14386c11d4a8SLijo Lazar 				wafl_ver = IP_VERSION_FULL(ip->major, ip->minor,
14396c11d4a8SLijo Lazar 							   ip->revision, 0, 0);
14406c11d4a8SLijo Lazar 
1441f39f5bb1SXiaojie Yuan 			for (k = 0; k < num_base_address; k++) {
1442f39f5bb1SXiaojie Yuan 				/*
1443966f1d8fSXiaojie Yuan 				 * convert the endianness of base addresses in place,
1444f39f5bb1SXiaojie Yuan 				 * so that we don't need to convert them when accessing adev->reg_offset.
1445f39f5bb1SXiaojie Yuan 				 */
14467d158f52SLe Ma 				if (ihdr->base_addr_64_bit)
14477d158f52SLe Ma 					/* Truncate the 64bit base address from ip discovery
14487d158f52SLe Ma 					 * and only store lower 32bit ip base in reg_offset[].
14497d158f52SLe Ma 					 * Bits > 32 follows ASIC specific format, thus just
14507d158f52SLe Ma 					 * discard them and handle it within specific ASIC.
14517d158f52SLe Ma 					 * By this way reg_offset[] and related helpers can
14527d158f52SLe Ma 					 * stay unchanged.
14537d158f52SLe Ma 					 * The base address is in dwords, thus clear the
14547d158f52SLe Ma 					 * highest 2 bits to store.
14557d158f52SLe Ma 					 */
14567d158f52SLe Ma 					ip->base_address[k] =
14577d158f52SLe Ma 						lower_32_bits(le64_to_cpu(ip->base_address_64[k])) & 0x3FFFFFFF;
14587d158f52SLe Ma 				else
1459966f1d8fSXiaojie Yuan 					ip->base_address[k] = le32_to_cpu(ip->base_address[k]);
1460966f1d8fSXiaojie Yuan 				DRM_DEBUG("\t0x%08x\n", ip->base_address[k]);
1461f39f5bb1SXiaojie Yuan 			}
1462f39f5bb1SXiaojie Yuan 
1463437298b8SXiaojie Yuan 			for (hw_ip = 0; hw_ip < MAX_HWIP; hw_ip++) {
14647d158f52SLe Ma 				if (hw_id_map[hw_ip] == le16_to_cpu(ip->hw_id) &&
14657d158f52SLe Ma 				    hw_id_map[hw_ip] != 0) {
146691aeda18SAlex Deucher 					DRM_DEBUG("set register base offset for %s\n",
1467437298b8SXiaojie Yuan 							hw_id_names[le16_to_cpu(ip->hw_id)]);
1468aabb4784SLe Ma 					adev->reg_offset[hw_ip][ip->instance_number] =
1469f39f5bb1SXiaojie Yuan 						ip->base_address;
14701d789535SAlex Deucher 					/* Instance support is somewhat inconsistent.
14711d789535SAlex Deucher 					 * SDMA is a good example.  Sienna cichlid has 4 total
14721d789535SAlex Deucher 					 * SDMA instances, each enumerated separately (HWIDs
14731d789535SAlex Deucher 					 * 42, 43, 68, 69).  Arcturus has 8 total SDMA instances,
14741d789535SAlex Deucher 					 * but they are enumerated as multiple instances of the
14751d789535SAlex Deucher 					 * same HWIDs (4x HWID 42, 4x HWID 43).  UMC is another
14761d789535SAlex Deucher 					 * example.  On most chips there are multiple instances
14771d789535SAlex Deucher 					 * with the same HWID.
14781d789535SAlex Deucher 					 */
1479ff96ddc3SLijo Lazar 
1480ff96ddc3SLijo Lazar 					if (ihdr->version < 3) {
1481ff96ddc3SLijo Lazar 						subrev = 0;
1482ff96ddc3SLijo Lazar 						variant = 0;
1483ff96ddc3SLijo Lazar 					} else {
1484ff96ddc3SLijo Lazar 						subrev = ip->sub_revision;
1485ff96ddc3SLijo Lazar 						variant = ip->variant;
1486ff96ddc3SLijo Lazar 					}
1487ff96ddc3SLijo Lazar 
1488ff96ddc3SLijo Lazar 					adev->ip_versions[hw_ip]
1489ff96ddc3SLijo Lazar 							 [ip->instance_number] =
1490ff96ddc3SLijo Lazar 						IP_VERSION_FULL(ip->major,
1491ff96ddc3SLijo Lazar 								ip->minor,
1492ff96ddc3SLijo Lazar 								ip->revision,
1493ff96ddc3SLijo Lazar 								variant,
1494ff96ddc3SLijo Lazar 								subrev);
1495f39f5bb1SXiaojie Yuan 				}
1496f39f5bb1SXiaojie Yuan 			}
1497437298b8SXiaojie Yuan 
14985039f529SErnst Sjöstrand next_ip:
14997d158f52SLe Ma 			if (ihdr->base_addr_64_bit)
15007d158f52SLe Ma 				ip_offset += struct_size(ip, base_address_64, ip->num_base_address);
15017d158f52SLe Ma 			else
150273bce7a4SLijo Lazar 				ip_offset += struct_size(ip, base_address, ip->num_base_address);
1503f39f5bb1SXiaojie Yuan 		}
1504f39f5bb1SXiaojie Yuan 	}
1505f39f5bb1SXiaojie Yuan 
15066c11d4a8SLijo Lazar 	if (wafl_ver && !adev->ip_versions[XGMI_HWIP][0])
15076c11d4a8SLijo Lazar 		adev->ip_versions[XGMI_HWIP][0] = wafl_ver;
15086c11d4a8SLijo Lazar 
1509f39f5bb1SXiaojie Yuan 	return 0;
1510f39f5bb1SXiaojie Yuan }
1511f39f5bb1SXiaojie Yuan 
amdgpu_discovery_harvest_ip(struct amdgpu_device * adev)1512e24d0e91SAlex Deucher static void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
151383a0b863SLikun GAO {
1514a01e9342SLijo Lazar 	struct ip_discovery_header *ihdr;
1515a01e9342SLijo Lazar 	struct binary_header *bhdr;
1516e1dd4bbfSGuchun Chen 	int vcn_harvest_count = 0;
1517478d338bSAlex Deucher 	int umc_harvest_count = 0;
1518a01e9342SLijo Lazar 	uint16_t offset, ihdr_ver;
151983a0b863SLikun GAO 
1520a01e9342SLijo Lazar 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
1521a01e9342SLijo Lazar 	offset = le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset);
1522a01e9342SLijo Lazar 	ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
1523a01e9342SLijo Lazar 					      offset);
1524a01e9342SLijo Lazar 	ihdr_ver = le16_to_cpu(ihdr->version);
1525e1dd4bbfSGuchun Chen 	/*
1526e1dd4bbfSGuchun Chen 	 * Harvest table does not fit Navi1x and legacy GPUs,
1527e1dd4bbfSGuchun Chen 	 * so read harvest bit per IP data structure to set
1528e1dd4bbfSGuchun Chen 	 * harvest configuration.
1529e1dd4bbfSGuchun Chen 	 */
15304e8303cfSLijo Lazar 	if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 2, 0) &&
1531a01e9342SLijo Lazar 	    ihdr_ver <= 2) {
1532e1dd4bbfSGuchun Chen 		if ((adev->pdev->device == 0x731E &&
1533e1dd4bbfSGuchun Chen 			(adev->pdev->revision == 0xC6 ||
1534e1dd4bbfSGuchun Chen 			 adev->pdev->revision == 0xC7)) ||
1535e1dd4bbfSGuchun Chen 			(adev->pdev->device == 0x7340 &&
1536e1dd4bbfSGuchun Chen 			 adev->pdev->revision == 0xC9) ||
1537e1dd4bbfSGuchun Chen 			(adev->pdev->device == 0x7360 &&
1538e1dd4bbfSGuchun Chen 			 adev->pdev->revision == 0xC7))
1539e1dd4bbfSGuchun Chen 			amdgpu_discovery_read_harvest_bit_per_ip(adev,
1540e1dd4bbfSGuchun Chen 				&vcn_harvest_count);
1541e1dd4bbfSGuchun Chen 	} else {
1542e776a755SAlex Deucher 		amdgpu_discovery_read_from_harvest_table(adev,
1543478d338bSAlex Deucher 							 &vcn_harvest_count,
1544478d338bSAlex Deucher 							 &umc_harvest_count);
154583a0b863SLikun GAO 	}
154603f6fb84SGuchun Chen 
154703f6fb84SGuchun Chen 	amdgpu_discovery_harvest_config_quirk(adev);
154803f6fb84SGuchun Chen 
15497cbe08a9SAlex Deucher 	if (vcn_harvest_count == adev->vcn.num_vcn_inst) {
15507cbe08a9SAlex Deucher 		adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK;
15517cbe08a9SAlex Deucher 		adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK;
15527cbe08a9SAlex Deucher 	}
1553478d338bSAlex Deucher 
1554478d338bSAlex Deucher 	if (umc_harvest_count < adev->gmc.num_umc) {
1555478d338bSAlex Deucher 		adev->gmc.num_umc -= umc_harvest_count;
1556478d338bSAlex Deucher 	}
155783a0b863SLikun GAO }
155883a0b863SLikun GAO 
15590cd7f378SAlex Deucher union gc_info {
15600cd7f378SAlex Deucher 	struct gc_info_v1_0 v1;
15615cb1cfd5SAlex Deucher 	struct gc_info_v1_1 v1_1;
15625cb1cfd5SAlex Deucher 	struct gc_info_v1_2 v1_2;
1563875ff9a7SLikun Gao 	struct gc_info_v1_3 v1_3;
15640cd7f378SAlex Deucher 	struct gc_info_v2_0 v2;
156546b55e25SLe Ma 	struct gc_info_v2_1 v2_1;
15660cd7f378SAlex Deucher };
15670cd7f378SAlex Deucher 
amdgpu_discovery_get_gfx_info(struct amdgpu_device * adev)1568e24d0e91SAlex Deucher static int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev)
1569f39f5bb1SXiaojie Yuan {
1570f39f5bb1SXiaojie Yuan 	struct binary_header *bhdr;
15710cd7f378SAlex Deucher 	union gc_info *gc_info;
1572f716113aSAlex Deucher 	u16 offset;
1573f39f5bb1SXiaojie Yuan 
157472de33f8SAlex Deucher 	if (!adev->mman.discovery_bin) {
1575f39f5bb1SXiaojie Yuan 		DRM_ERROR("ip discovery uninitialized\n");
1576f39f5bb1SXiaojie Yuan 		return -EINVAL;
1577f39f5bb1SXiaojie Yuan 	}
1578f39f5bb1SXiaojie Yuan 
157972de33f8SAlex Deucher 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
1580f716113aSAlex Deucher 	offset = le16_to_cpu(bhdr->table_list[GC].offset);
1581f716113aSAlex Deucher 
1582e24d0e91SAlex Deucher 	if (!offset)
1583e24d0e91SAlex Deucher 		return 0;
1584f716113aSAlex Deucher 
1585f716113aSAlex Deucher 	gc_info = (union gc_info *)(adev->mman.discovery_bin + offset);
1586f716113aSAlex Deucher 
15878eece29cSAlex Deucher 	switch (le16_to_cpu(gc_info->v1.header.version_major)) {
15880cd7f378SAlex Deucher 	case 1:
15890cd7f378SAlex Deucher 		adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->v1.gc_num_se);
15900cd7f378SAlex Deucher 		adev->gfx.config.max_cu_per_sh = 2 * (le32_to_cpu(gc_info->v1.gc_num_wgp0_per_sa) +
15910cd7f378SAlex Deucher 						      le32_to_cpu(gc_info->v1.gc_num_wgp1_per_sa));
15920cd7f378SAlex Deucher 		adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->v1.gc_num_sa_per_se);
15930cd7f378SAlex Deucher 		adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->v1.gc_num_rb_per_se);
15940cd7f378SAlex Deucher 		adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->v1.gc_num_gl2c);
15950cd7f378SAlex Deucher 		adev->gfx.config.max_gprs = le32_to_cpu(gc_info->v1.gc_num_gprs);
15960cd7f378SAlex Deucher 		adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->v1.gc_num_max_gs_thds);
15970cd7f378SAlex Deucher 		adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->v1.gc_gs_table_depth);
15980cd7f378SAlex Deucher 		adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->v1.gc_gsprim_buff_depth);
15990cd7f378SAlex Deucher 		adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->v1.gc_double_offchip_lds_buffer);
16000cd7f378SAlex Deucher 		adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->v1.gc_wave_size);
16010cd7f378SAlex Deucher 		adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->v1.gc_max_waves_per_simd);
16020cd7f378SAlex Deucher 		adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->v1.gc_max_scratch_slots_per_cu);
16030cd7f378SAlex Deucher 		adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->v1.gc_lds_size);
16040cd7f378SAlex Deucher 		adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v1.gc_num_sc_per_se) /
16050cd7f378SAlex Deucher 			le32_to_cpu(gc_info->v1.gc_num_sa_per_se);
16060cd7f378SAlex Deucher 		adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v1.gc_num_packer_per_sc);
16070e64c9aaSYifan Zhang 		if (le16_to_cpu(gc_info->v1.header.version_minor) >= 1) {
16085cb1cfd5SAlex Deucher 			adev->gfx.config.gc_num_tcp_per_sa = le32_to_cpu(gc_info->v1_1.gc_num_tcp_per_sa);
16095cb1cfd5SAlex Deucher 			adev->gfx.config.gc_num_sdp_interface = le32_to_cpu(gc_info->v1_1.gc_num_sdp_interface);
16105cb1cfd5SAlex Deucher 			adev->gfx.config.gc_num_tcps = le32_to_cpu(gc_info->v1_1.gc_num_tcps);
16115cb1cfd5SAlex Deucher 		}
16120e64c9aaSYifan Zhang 		if (le16_to_cpu(gc_info->v1.header.version_minor) >= 2) {
16135cb1cfd5SAlex Deucher 			adev->gfx.config.gc_num_tcp_per_wpg = le32_to_cpu(gc_info->v1_2.gc_num_tcp_per_wpg);
16145cb1cfd5SAlex Deucher 			adev->gfx.config.gc_tcp_l1_size = le32_to_cpu(gc_info->v1_2.gc_tcp_l1_size);
16155cb1cfd5SAlex Deucher 			adev->gfx.config.gc_num_sqc_per_wgp = le32_to_cpu(gc_info->v1_2.gc_num_sqc_per_wgp);
16165cb1cfd5SAlex Deucher 			adev->gfx.config.gc_l1_instruction_cache_size_per_sqc = le32_to_cpu(gc_info->v1_2.gc_l1_instruction_cache_size_per_sqc);
16175cb1cfd5SAlex Deucher 			adev->gfx.config.gc_l1_data_cache_size_per_sqc = le32_to_cpu(gc_info->v1_2.gc_l1_data_cache_size_per_sqc);
16185cb1cfd5SAlex Deucher 			adev->gfx.config.gc_gl1c_per_sa = le32_to_cpu(gc_info->v1_2.gc_gl1c_per_sa);
16195cb1cfd5SAlex Deucher 			adev->gfx.config.gc_gl1c_size_per_instance = le32_to_cpu(gc_info->v1_2.gc_gl1c_size_per_instance);
16205cb1cfd5SAlex Deucher 			adev->gfx.config.gc_gl2c_per_gpu = le32_to_cpu(gc_info->v1_2.gc_gl2c_per_gpu);
16215cb1cfd5SAlex Deucher 		}
1622875ff9a7SLikun Gao 		if (le16_to_cpu(gc_info->v1.header.version_minor) >= 3) {
1623875ff9a7SLikun Gao 			adev->gfx.config.gc_tcp_size_per_cu = le32_to_cpu(gc_info->v1_3.gc_tcp_size_per_cu);
1624875ff9a7SLikun Gao 			adev->gfx.config.gc_tcp_cache_line_size = le32_to_cpu(gc_info->v1_3.gc_tcp_cache_line_size);
1625875ff9a7SLikun Gao 			adev->gfx.config.gc_instruction_cache_size_per_sqc = le32_to_cpu(gc_info->v1_3.gc_instruction_cache_size_per_sqc);
1626875ff9a7SLikun Gao 			adev->gfx.config.gc_instruction_cache_line_size = le32_to_cpu(gc_info->v1_3.gc_instruction_cache_line_size);
1627875ff9a7SLikun Gao 			adev->gfx.config.gc_scalar_data_cache_size_per_sqc = le32_to_cpu(gc_info->v1_3.gc_scalar_data_cache_size_per_sqc);
1628875ff9a7SLikun Gao 			adev->gfx.config.gc_scalar_data_cache_line_size = le32_to_cpu(gc_info->v1_3.gc_scalar_data_cache_line_size);
1629875ff9a7SLikun Gao 			adev->gfx.config.gc_tcc_size = le32_to_cpu(gc_info->v1_3.gc_tcc_size);
1630875ff9a7SLikun Gao 			adev->gfx.config.gc_tcc_cache_line_size = le32_to_cpu(gc_info->v1_3.gc_tcc_cache_line_size);
1631875ff9a7SLikun Gao 		}
16320cd7f378SAlex Deucher 		break;
16330cd7f378SAlex Deucher 	case 2:
16340cd7f378SAlex Deucher 		adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->v2.gc_num_se);
16350cd7f378SAlex Deucher 		adev->gfx.config.max_cu_per_sh = le32_to_cpu(gc_info->v2.gc_num_cu_per_sh);
16360cd7f378SAlex Deucher 		adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->v2.gc_num_sh_per_se);
16370cd7f378SAlex Deucher 		adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->v2.gc_num_rb_per_se);
16380cd7f378SAlex Deucher 		adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->v2.gc_num_tccs);
16390cd7f378SAlex Deucher 		adev->gfx.config.max_gprs = le32_to_cpu(gc_info->v2.gc_num_gprs);
16400cd7f378SAlex Deucher 		adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->v2.gc_num_max_gs_thds);
16410cd7f378SAlex Deucher 		adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->v2.gc_gs_table_depth);
16420cd7f378SAlex Deucher 		adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->v2.gc_gsprim_buff_depth);
16430cd7f378SAlex Deucher 		adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->v2.gc_double_offchip_lds_buffer);
16440cd7f378SAlex Deucher 		adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->v2.gc_wave_size);
16450cd7f378SAlex Deucher 		adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->v2.gc_max_waves_per_simd);
16460cd7f378SAlex Deucher 		adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->v2.gc_max_scratch_slots_per_cu);
16470cd7f378SAlex Deucher 		adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->v2.gc_lds_size);
16480cd7f378SAlex Deucher 		adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v2.gc_num_sc_per_se) /
16490cd7f378SAlex Deucher 			le32_to_cpu(gc_info->v2.gc_num_sh_per_se);
16500cd7f378SAlex Deucher 		adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v2.gc_num_packer_per_sc);
1651f7a17b2bSMukul Joshi 		if (le16_to_cpu(gc_info->v2.header.version_minor) == 1) {
165246b55e25SLe Ma 			adev->gfx.config.gc_num_tcp_per_sa = le32_to_cpu(gc_info->v2_1.gc_num_tcp_per_sh);
165346b55e25SLe Ma 			adev->gfx.config.gc_tcp_size_per_cu = le32_to_cpu(gc_info->v2_1.gc_tcp_size_per_cu);
165446b55e25SLe Ma 			adev->gfx.config.gc_num_sdp_interface = le32_to_cpu(gc_info->v2_1.gc_num_sdp_interface); /* per XCD */
165546b55e25SLe Ma 			adev->gfx.config.gc_num_cu_per_sqc = le32_to_cpu(gc_info->v2_1.gc_num_cu_per_sqc);
165646b55e25SLe Ma 			adev->gfx.config.gc_l1_instruction_cache_size_per_sqc = le32_to_cpu(gc_info->v2_1.gc_instruction_cache_size_per_sqc);
165746b55e25SLe Ma 			adev->gfx.config.gc_l1_data_cache_size_per_sqc = le32_to_cpu(gc_info->v2_1.gc_scalar_data_cache_size_per_sqc);
165846b55e25SLe Ma 			adev->gfx.config.gc_tcc_size = le32_to_cpu(gc_info->v2_1.gc_tcc_size); /* per XCD */
165946b55e25SLe Ma 		}
16600cd7f378SAlex Deucher 		break;
16610cd7f378SAlex Deucher 	default:
16620cd7f378SAlex Deucher 		dev_err(adev->dev,
16630cd7f378SAlex Deucher 			"Unhandled GC info table %d.%d\n",
16648eece29cSAlex Deucher 			le16_to_cpu(gc_info->v1.header.version_major),
16658eece29cSAlex Deucher 			le16_to_cpu(gc_info->v1.header.version_minor));
16660cd7f378SAlex Deucher 		return -EINVAL;
16670cd7f378SAlex Deucher 	}
1668f39f5bb1SXiaojie Yuan 	return 0;
1669f39f5bb1SXiaojie Yuan }
1670795d0839SAlex Deucher 
167124681cb5SAlex Deucher union mall_info {
167224681cb5SAlex Deucher 	struct mall_info_v1_0 v1;
1673d4f6425aSLe Ma 	struct mall_info_v2_0 v2;
167424681cb5SAlex Deucher };
167524681cb5SAlex Deucher 
amdgpu_discovery_get_mall_info(struct amdgpu_device * adev)1676caa5eadcSEvan Quan static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev)
167724681cb5SAlex Deucher {
167824681cb5SAlex Deucher 	struct binary_header *bhdr;
167924681cb5SAlex Deucher 	union mall_info *mall_info;
168024681cb5SAlex Deucher 	u32 u, mall_size_per_umc, m_s_present, half_use;
168124681cb5SAlex Deucher 	u64 mall_size;
1682f716113aSAlex Deucher 	u16 offset;
168324681cb5SAlex Deucher 
168424681cb5SAlex Deucher 	if (!adev->mman.discovery_bin) {
168524681cb5SAlex Deucher 		DRM_ERROR("ip discovery uninitialized\n");
168624681cb5SAlex Deucher 		return -EINVAL;
168724681cb5SAlex Deucher 	}
168824681cb5SAlex Deucher 
168924681cb5SAlex Deucher 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
1690f716113aSAlex Deucher 	offset = le16_to_cpu(bhdr->table_list[MALL_INFO].offset);
1691f716113aSAlex Deucher 
1692e24d0e91SAlex Deucher 	if (!offset)
1693e24d0e91SAlex Deucher 		return 0;
1694f716113aSAlex Deucher 
1695f716113aSAlex Deucher 	mall_info = (union mall_info *)(adev->mman.discovery_bin + offset);
169624681cb5SAlex Deucher 
169724681cb5SAlex Deucher 	switch (le16_to_cpu(mall_info->v1.header.version_major)) {
169824681cb5SAlex Deucher 	case 1:
169924681cb5SAlex Deucher 		mall_size = 0;
170024681cb5SAlex Deucher 		mall_size_per_umc = le32_to_cpu(mall_info->v1.mall_size_per_m);
170124681cb5SAlex Deucher 		m_s_present = le32_to_cpu(mall_info->v1.m_s_present);
170224681cb5SAlex Deucher 		half_use = le32_to_cpu(mall_info->v1.m_half_use);
170324681cb5SAlex Deucher 		for (u = 0; u < adev->gmc.num_umc; u++) {
170424681cb5SAlex Deucher 			if (m_s_present & (1 << u))
170524681cb5SAlex Deucher 				mall_size += mall_size_per_umc * 2;
170624681cb5SAlex Deucher 			else if (half_use & (1 << u))
170724681cb5SAlex Deucher 				mall_size += mall_size_per_umc / 2;
170824681cb5SAlex Deucher 			else
170924681cb5SAlex Deucher 				mall_size += mall_size_per_umc;
171024681cb5SAlex Deucher 		}
171124681cb5SAlex Deucher 		adev->gmc.mall_size = mall_size;
1712bcd9a5f8SCandice Li 		adev->gmc.m_half_use = half_use;
171324681cb5SAlex Deucher 		break;
1714d4f6425aSLe Ma 	case 2:
1715d4f6425aSLe Ma 		mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc);
1716c09d2effSJesse Zhang 		adev->gmc.mall_size = (uint64_t)mall_size_per_umc * adev->gmc.num_umc;
1717d4f6425aSLe Ma 		break;
171824681cb5SAlex Deucher 	default:
171924681cb5SAlex Deucher 		dev_err(adev->dev,
172024681cb5SAlex Deucher 			"Unhandled MALL info table %d.%d\n",
172124681cb5SAlex Deucher 			le16_to_cpu(mall_info->v1.header.version_major),
172224681cb5SAlex Deucher 			le16_to_cpu(mall_info->v1.header.version_minor));
172324681cb5SAlex Deucher 		return -EINVAL;
172424681cb5SAlex Deucher 	}
172524681cb5SAlex Deucher 	return 0;
172624681cb5SAlex Deucher }
172724681cb5SAlex Deucher 
1728622469c8SAlex Deucher union vcn_info {
1729622469c8SAlex Deucher 	struct vcn_info_v1_0 v1;
1730622469c8SAlex Deucher };
1731622469c8SAlex Deucher 
amdgpu_discovery_get_vcn_info(struct amdgpu_device * adev)1732e24d0e91SAlex Deucher static int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev)
1733622469c8SAlex Deucher {
1734622469c8SAlex Deucher 	struct binary_header *bhdr;
1735622469c8SAlex Deucher 	union vcn_info *vcn_info;
1736622469c8SAlex Deucher 	u16 offset;
1737622469c8SAlex Deucher 	int v;
1738622469c8SAlex Deucher 
1739622469c8SAlex Deucher 	if (!adev->mman.discovery_bin) {
1740622469c8SAlex Deucher 		DRM_ERROR("ip discovery uninitialized\n");
1741622469c8SAlex Deucher 		return -EINVAL;
1742622469c8SAlex Deucher 	}
1743622469c8SAlex Deucher 
1744031ac4e4SAlex Deucher 	/* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES
1745031ac4e4SAlex Deucher 	 * which is smaller than VCN_INFO_TABLE_MAX_NUM_INSTANCES
1746031ac4e4SAlex Deucher 	 * but that may change in the future with new GPUs so keep this
1747031ac4e4SAlex Deucher 	 * check for defensive purposes.
1748031ac4e4SAlex Deucher 	 */
1749622469c8SAlex Deucher 	if (adev->vcn.num_vcn_inst > VCN_INFO_TABLE_MAX_NUM_INSTANCES) {
1750622469c8SAlex Deucher 		dev_err(adev->dev, "invalid vcn instances\n");
1751622469c8SAlex Deucher 		return -EINVAL;
1752622469c8SAlex Deucher 	}
1753622469c8SAlex Deucher 
1754622469c8SAlex Deucher 	bhdr = (struct binary_header *)adev->mman.discovery_bin;
1755622469c8SAlex Deucher 	offset = le16_to_cpu(bhdr->table_list[VCN_INFO].offset);
1756622469c8SAlex Deucher 
1757e24d0e91SAlex Deucher 	if (!offset)
1758e24d0e91SAlex Deucher 		return 0;
1759622469c8SAlex Deucher 
1760622469c8SAlex Deucher 	vcn_info = (union vcn_info *)(adev->mman.discovery_bin + offset);
1761622469c8SAlex Deucher 
1762622469c8SAlex Deucher 	switch (le16_to_cpu(vcn_info->v1.header.version_major)) {
1763622469c8SAlex Deucher 	case 1:
1764031ac4e4SAlex Deucher 		/* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES
1765031ac4e4SAlex Deucher 		 * so this won't overflow.
1766031ac4e4SAlex Deucher 		 */
1767622469c8SAlex Deucher 		for (v = 0; v < adev->vcn.num_vcn_inst; v++) {
1768cf1aa9ffSBoyuan Zhang 			adev->vcn.inst[v].vcn_codec_disable_mask =
1769622469c8SAlex Deucher 				le32_to_cpu(vcn_info->v1.instance_info[v].fuse_data.all_bits);
1770622469c8SAlex Deucher 		}
1771622469c8SAlex Deucher 		break;
1772622469c8SAlex Deucher 	default:
1773622469c8SAlex Deucher 		dev_err(adev->dev,
1774622469c8SAlex Deucher 			"Unhandled VCN info table %d.%d\n",
1775622469c8SAlex Deucher 			le16_to_cpu(vcn_info->v1.header.version_major),
1776622469c8SAlex Deucher 			le16_to_cpu(vcn_info->v1.header.version_minor));
1777622469c8SAlex Deucher 		return -EINVAL;
1778622469c8SAlex Deucher 	}
1779622469c8SAlex Deucher 	return 0;
1780622469c8SAlex Deucher }
1781622469c8SAlex Deucher 
1782b194d21bSLijo Lazar union nps_info {
1783b194d21bSLijo Lazar 	struct nps_info_v1_0 v1;
1784b194d21bSLijo Lazar };
1785b194d21bSLijo Lazar 
amdgpu_discovery_refresh_nps_info(struct amdgpu_device * adev,union nps_info * nps_data)1786fcd91a95SLijo Lazar static int amdgpu_discovery_refresh_nps_info(struct amdgpu_device *adev,
1787fcd91a95SLijo Lazar 					     union nps_info *nps_data)
1788fcd91a95SLijo Lazar {
1789fcd91a95SLijo Lazar 	uint64_t vram_size, pos, offset;
1790fcd91a95SLijo Lazar 	struct nps_info_header *nhdr;
1791fcd91a95SLijo Lazar 	struct binary_header bhdr;
1792fcd91a95SLijo Lazar 	uint16_t checksum;
1793fcd91a95SLijo Lazar 
1794fcd91a95SLijo Lazar 	vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
1795fcd91a95SLijo Lazar 	pos = vram_size - DISCOVERY_TMR_OFFSET;
1796fcd91a95SLijo Lazar 	amdgpu_device_vram_access(adev, pos, &bhdr, sizeof(bhdr), false);
1797fcd91a95SLijo Lazar 
1798fcd91a95SLijo Lazar 	offset = le16_to_cpu(bhdr.table_list[NPS_INFO].offset);
1799fcd91a95SLijo Lazar 	checksum = le16_to_cpu(bhdr.table_list[NPS_INFO].checksum);
1800fcd91a95SLijo Lazar 
1801fcd91a95SLijo Lazar 	amdgpu_device_vram_access(adev, (pos + offset), nps_data,
1802fcd91a95SLijo Lazar 				  sizeof(*nps_data), false);
1803fcd91a95SLijo Lazar 
1804fcd91a95SLijo Lazar 	nhdr = (struct nps_info_header *)(nps_data);
1805fcd91a95SLijo Lazar 	if (!amdgpu_discovery_verify_checksum((uint8_t *)nps_data,
1806fcd91a95SLijo Lazar 					      le32_to_cpu(nhdr->size_bytes),
1807fcd91a95SLijo Lazar 					      checksum)) {
1808fcd91a95SLijo Lazar 		dev_err(adev->dev, "nps data refresh, checksum mismatch\n");
1809fcd91a95SLijo Lazar 		return -EINVAL;
1810fcd91a95SLijo Lazar 	}
1811fcd91a95SLijo Lazar 
1812fcd91a95SLijo Lazar 	return 0;
1813fcd91a95SLijo Lazar }
1814fcd91a95SLijo Lazar 
amdgpu_discovery_get_nps_info(struct amdgpu_device * adev,uint32_t * nps_type,struct amdgpu_gmc_memrange ** ranges,int * range_cnt,bool refresh)1815b194d21bSLijo Lazar int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev,
1816b194d21bSLijo Lazar 				  uint32_t *nps_type,
1817b194d21bSLijo Lazar 				  struct amdgpu_gmc_memrange **ranges,
1818fcd91a95SLijo Lazar 				  int *range_cnt, bool refresh)
1819b194d21bSLijo Lazar {
1820b194d21bSLijo Lazar 	struct amdgpu_gmc_memrange *mem_ranges;
1821b194d21bSLijo Lazar 	struct binary_header *bhdr;
1822b194d21bSLijo Lazar 	union nps_info *nps_info;
1823fcd91a95SLijo Lazar 	union nps_info nps_data;
1824b194d21bSLijo Lazar 	u16 offset;
1825fcd91a95SLijo Lazar 	int i, r;
1826b194d21bSLijo Lazar 
1827b194d21bSLijo Lazar 	if (!nps_type || !range_cnt || !ranges)
1828b194d21bSLijo Lazar 		return -EINVAL;
1829b194d21bSLijo Lazar 
1830fcd91a95SLijo Lazar 	if (refresh) {
1831fcd91a95SLijo Lazar 		r = amdgpu_discovery_refresh_nps_info(adev, &nps_data);
1832fcd91a95SLijo Lazar 		if (r)
1833fcd91a95SLijo Lazar 			return r;
1834fcd91a95SLijo Lazar 		nps_info = &nps_data;
1835fcd91a95SLijo Lazar 	} else {
1836b194d21bSLijo Lazar 		if (!adev->mman.discovery_bin) {
1837b194d21bSLijo Lazar 			dev_err(adev->dev,
1838b194d21bSLijo Lazar 				"fetch mem range failed, ip discovery uninitialized\n");
1839b194d21bSLijo Lazar 			return -EINVAL;
1840b194d21bSLijo Lazar 		}
1841b194d21bSLijo Lazar 
1842b194d21bSLijo Lazar 		bhdr = (struct binary_header *)adev->mman.discovery_bin;
1843b194d21bSLijo Lazar 		offset = le16_to_cpu(bhdr->table_list[NPS_INFO].offset);
1844b194d21bSLijo Lazar 
1845b194d21bSLijo Lazar 		if (!offset)
1846b194d21bSLijo Lazar 			return -ENOENT;
1847b194d21bSLijo Lazar 
1848b194d21bSLijo Lazar 		/* If verification fails, return as if NPS table doesn't exist */
1849b194d21bSLijo Lazar 		if (amdgpu_discovery_verify_npsinfo(adev, bhdr))
1850b194d21bSLijo Lazar 			return -ENOENT;
1851b194d21bSLijo Lazar 
1852fcd91a95SLijo Lazar 		nps_info =
1853fcd91a95SLijo Lazar 			(union nps_info *)(adev->mman.discovery_bin + offset);
1854fcd91a95SLijo Lazar 	}
1855b194d21bSLijo Lazar 
1856b194d21bSLijo Lazar 	switch (le16_to_cpu(nps_info->v1.header.version_major)) {
1857b194d21bSLijo Lazar 	case 1:
1858a1144da7SLi Huafei 		mem_ranges = kvcalloc(nps_info->v1.count,
1859a1144da7SLi Huafei 				      sizeof(*mem_ranges),
1860a1144da7SLi Huafei 				      GFP_KERNEL);
1861a1144da7SLi Huafei 		if (!mem_ranges)
1862a1144da7SLi Huafei 			return -ENOMEM;
1863b194d21bSLijo Lazar 		*nps_type = nps_info->v1.nps_type;
1864b194d21bSLijo Lazar 		*range_cnt = nps_info->v1.count;
1865b194d21bSLijo Lazar 		for (i = 0; i < *range_cnt; i++) {
1866b194d21bSLijo Lazar 			mem_ranges[i].base_address =
1867b194d21bSLijo Lazar 				nps_info->v1.instance_info[i].base_address;
1868b194d21bSLijo Lazar 			mem_ranges[i].limit_address =
1869b194d21bSLijo Lazar 				nps_info->v1.instance_info[i].limit_address;
1870b194d21bSLijo Lazar 			mem_ranges[i].nid_mask = -1;
1871b194d21bSLijo Lazar 			mem_ranges[i].flags = 0;
1872b194d21bSLijo Lazar 		}
1873b194d21bSLijo Lazar 		*ranges = mem_ranges;
1874b194d21bSLijo Lazar 		break;
1875b194d21bSLijo Lazar 	default:
1876b194d21bSLijo Lazar 		dev_err(adev->dev, "Unhandled NPS info table %d.%d\n",
1877b194d21bSLijo Lazar 			le16_to_cpu(nps_info->v1.header.version_major),
1878b194d21bSLijo Lazar 			le16_to_cpu(nps_info->v1.header.version_minor));
1879b194d21bSLijo Lazar 		return -EINVAL;
1880b194d21bSLijo Lazar 	}
1881b194d21bSLijo Lazar 
1882b194d21bSLijo Lazar 	return 0;
1883b194d21bSLijo Lazar }
1884b194d21bSLijo Lazar 
amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device * adev)1885b05b9c59SAlex Deucher static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
1886b05b9c59SAlex Deucher {
1887b05b9c59SAlex Deucher 	/* what IP to use for this? */
18884e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
1889b05b9c59SAlex Deucher 	case IP_VERSION(9, 0, 1):
1890b05b9c59SAlex Deucher 	case IP_VERSION(9, 1, 0):
1891b05b9c59SAlex Deucher 	case IP_VERSION(9, 2, 1):
1892b05b9c59SAlex Deucher 	case IP_VERSION(9, 2, 2):
1893b05b9c59SAlex Deucher 	case IP_VERSION(9, 3, 0):
1894b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 0):
1895b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 1):
1896b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 2):
18975e5d4b39SHawking Zhang 	case IP_VERSION(9, 4, 3):
18985f571c61SHawking Zhang 	case IP_VERSION(9, 4, 4):
18990b58a55aSLe Ma 	case IP_VERSION(9, 5, 0):
1900b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
1901b05b9c59SAlex Deucher 		break;
1902b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 10):
1903b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 1):
1904b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 2):
1905b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 3):
1906f9ed188dSLang Yu 	case IP_VERSION(10, 1, 4):
1907b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 0):
1908b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 1):
1909b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 2):
1910b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 3):
1911b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 4):
1912b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 5):
19131957f27dSYifan Zhang 	case IP_VERSION(10, 3, 6):
19142fbc5086SPrike Liang 	case IP_VERSION(10, 3, 7):
1915b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
1916b05b9c59SAlex Deucher 		break;
1917759693acSLikun Gao 	case IP_VERSION(11, 0, 0):
19186e4eb7ceSHuang Rui 	case IP_VERSION(11, 0, 1):
19190effe4a0SFlora Cui 	case IP_VERSION(11, 0, 2):
1920fc968efdSHawking Zhang 	case IP_VERSION(11, 0, 3):
192169dc98bbSYifan Zhang 	case IP_VERSION(11, 0, 4):
1922bb7249eeSPrike Liang 	case IP_VERSION(11, 5, 0):
1923f1c40b6eSYifan Zhang 	case IP_VERSION(11, 5, 1):
192423c1ea02STim Huang 	case IP_VERSION(11, 5, 2):
1925b784faebSTim Huang 	case IP_VERSION(11, 5, 3):
1926759693acSLikun Gao 		amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
1927759693acSLikun Gao 		break;
1928d22c0756SLikun Gao 	case IP_VERSION(12, 0, 0):
1929d22c0756SLikun Gao 	case IP_VERSION(12, 0, 1):
1930d22c0756SLikun Gao 		amdgpu_device_ip_block_add(adev, &soc24_common_ip_block);
1931d22c0756SLikun Gao 		break;
1932b05b9c59SAlex Deucher 	default:
193369650a87SGuchun Chen 		dev_err(adev->dev,
193469650a87SGuchun Chen 			"Failed to add common ip block(GC_HWIP:0x%x)\n",
19354e8303cfSLijo Lazar 			amdgpu_ip_version(adev, GC_HWIP, 0));
1936b05b9c59SAlex Deucher 		return -EINVAL;
1937b05b9c59SAlex Deucher 	}
1938b05b9c59SAlex Deucher 	return 0;
1939b05b9c59SAlex Deucher }
1940b05b9c59SAlex Deucher 
amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device * adev)1941b05b9c59SAlex Deucher static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
1942b05b9c59SAlex Deucher {
1943b05b9c59SAlex Deucher 	/* use GC or MMHUB IP version */
19444e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
1945b05b9c59SAlex Deucher 	case IP_VERSION(9, 0, 1):
1946b05b9c59SAlex Deucher 	case IP_VERSION(9, 1, 0):
1947b05b9c59SAlex Deucher 	case IP_VERSION(9, 2, 1):
1948b05b9c59SAlex Deucher 	case IP_VERSION(9, 2, 2):
1949b05b9c59SAlex Deucher 	case IP_VERSION(9, 3, 0):
1950b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 0):
1951b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 1):
1952b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 2):
195369bacf15SHawking Zhang 	case IP_VERSION(9, 4, 3):
19545f571c61SHawking Zhang 	case IP_VERSION(9, 4, 4):
19550b58a55aSLe Ma 	case IP_VERSION(9, 5, 0):
1956b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
1957b05b9c59SAlex Deucher 		break;
1958b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 10):
1959b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 1):
1960b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 2):
1961b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 3):
1962f9ed188dSLang Yu 	case IP_VERSION(10, 1, 4):
1963b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 0):
1964b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 1):
1965b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 2):
1966b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 3):
1967b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 4):
1968b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 5):
1969a142606dSYifan Zhang 	case IP_VERSION(10, 3, 6):
197097437f47SPrike Liang 	case IP_VERSION(10, 3, 7):
1971b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
1972b05b9c59SAlex Deucher 		break;
19730984d384SLikun Gao 	case IP_VERSION(11, 0, 0):
1974a8f24139SHuang Rui 	case IP_VERSION(11, 0, 1):
1975eee5ed42SFlora Cui 	case IP_VERSION(11, 0, 2):
197694ac3233SHawking Zhang 	case IP_VERSION(11, 0, 3):
1977d5fd8c89SYifan Zhang 	case IP_VERSION(11, 0, 4):
1978b90975faSPrike Liang 	case IP_VERSION(11, 5, 0):
1979278318d3SYifan Zhang 	case IP_VERSION(11, 5, 1):
198023c1ea02STim Huang 	case IP_VERSION(11, 5, 2):
1981b784faebSTim Huang 	case IP_VERSION(11, 5, 3):
19820984d384SLikun Gao 		amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
19830984d384SLikun Gao 		break;
19841b838189SLikun Gao 	case IP_VERSION(12, 0, 0):
19851b838189SLikun Gao 	case IP_VERSION(12, 0, 1):
19861b838189SLikun Gao 		amdgpu_device_ip_block_add(adev, &gmc_v12_0_ip_block);
19871b838189SLikun Gao 		break;
1988b05b9c59SAlex Deucher 	default:
19894e8303cfSLijo Lazar 		dev_err(adev->dev, "Failed to add gmc ip block(GC_HWIP:0x%x)\n",
19904e8303cfSLijo Lazar 			amdgpu_ip_version(adev, GC_HWIP, 0));
1991b05b9c59SAlex Deucher 		return -EINVAL;
1992b05b9c59SAlex Deucher 	}
1993b05b9c59SAlex Deucher 	return 0;
1994b05b9c59SAlex Deucher }
1995b05b9c59SAlex Deucher 
amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device * adev)1996b05b9c59SAlex Deucher static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
1997b05b9c59SAlex Deucher {
19984e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, OSSSYS_HWIP, 0)) {
1999b05b9c59SAlex Deucher 	case IP_VERSION(4, 0, 0):
2000b05b9c59SAlex Deucher 	case IP_VERSION(4, 0, 1):
2001b05b9c59SAlex Deucher 	case IP_VERSION(4, 1, 0):
2002b05b9c59SAlex Deucher 	case IP_VERSION(4, 1, 1):
2003b05b9c59SAlex Deucher 	case IP_VERSION(4, 3, 0):
2004b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
2005b05b9c59SAlex Deucher 		break;
2006b05b9c59SAlex Deucher 	case IP_VERSION(4, 2, 0):
2007b05b9c59SAlex Deucher 	case IP_VERSION(4, 2, 1):
2008b05b9c59SAlex Deucher 	case IP_VERSION(4, 4, 0):
20090df2032aSHawking Zhang 	case IP_VERSION(4, 4, 2):
20103d1bb1a2SHawking Zhang 	case IP_VERSION(4, 4, 5):
2011b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
2012b05b9c59SAlex Deucher 		break;
2013b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 0):
2014b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 1):
2015b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 2):
2016b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 3):
2017b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 0):
2018b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 1):
2019b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
2020b05b9c59SAlex Deucher 		break;
20212929a6bfSLikun Gao 	case IP_VERSION(6, 0, 0):
202248858a10SHuang Rui 	case IP_VERSION(6, 0, 1):
20231f926186SFlora Cui 	case IP_VERSION(6, 0, 2):
20242929a6bfSLikun Gao 		amdgpu_device_ip_block_add(adev, &ih_v6_0_ip_block);
20252929a6bfSLikun Gao 		break;
20264c340d00SPrike Liang 	case IP_VERSION(6, 1, 0):
20274c340d00SPrike Liang 		amdgpu_device_ip_block_add(adev, &ih_v6_1_ip_block);
20284c340d00SPrike Liang 		break;
202956018e83SLikun Gao 	case IP_VERSION(7, 0, 0):
203056018e83SLikun Gao 		amdgpu_device_ip_block_add(adev, &ih_v7_0_ip_block);
203156018e83SLikun Gao 		break;
2032b05b9c59SAlex Deucher 	default:
203369650a87SGuchun Chen 		dev_err(adev->dev,
203469650a87SGuchun Chen 			"Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n",
20354e8303cfSLijo Lazar 			amdgpu_ip_version(adev, OSSSYS_HWIP, 0));
2036b05b9c59SAlex Deucher 		return -EINVAL;
2037b05b9c59SAlex Deucher 	}
2038b05b9c59SAlex Deucher 	return 0;
2039b05b9c59SAlex Deucher }
2040b05b9c59SAlex Deucher 
amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device * adev)2041b05b9c59SAlex Deucher static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
2042b05b9c59SAlex Deucher {
20434e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {
2044b05b9c59SAlex Deucher 	case IP_VERSION(9, 0, 0):
2045b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
2046b05b9c59SAlex Deucher 		break;
2047b05b9c59SAlex Deucher 	case IP_VERSION(10, 0, 0):
2048b05b9c59SAlex Deucher 	case IP_VERSION(10, 0, 1):
2049b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block);
2050b05b9c59SAlex Deucher 		break;
2051b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 0):
2052b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 2):
2053b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 4):
2054b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 5):
2055b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 9):
2056b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 7):
2057b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 11):
2058b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 12):
2059b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 13):
2060b05b9c59SAlex Deucher 	case IP_VERSION(11, 5, 0):
206116a5a8feSYing Li 	case IP_VERSION(11, 5, 2):
2062b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
2063b05b9c59SAlex Deucher 		break;
2064b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 8):
2065b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &psp_v11_0_8_ip_block);
2066b05b9c59SAlex Deucher 		break;
2067b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 3):
2068b05b9c59SAlex Deucher 	case IP_VERSION(12, 0, 1):
2069b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
2070b05b9c59SAlex Deucher 		break;
207155a800daSLikun Gao 	case IP_VERSION(13, 0, 0):
2072b05b9c59SAlex Deucher 	case IP_VERSION(13, 0, 1):
2073b05b9c59SAlex Deucher 	case IP_VERSION(13, 0, 2):
2074b05b9c59SAlex Deucher 	case IP_VERSION(13, 0, 3):
2075d7fd297cSYifan Zhang 	case IP_VERSION(13, 0, 5):
2076a32d7d6bSHawking Zhang 	case IP_VERSION(13, 0, 6):
20775681e800SChengming Gui 	case IP_VERSION(13, 0, 7):
2078f99a7eb2SPrike Liang 	case IP_VERSION(13, 0, 8):
2079a60d2191SFrank Min 	case IP_VERSION(13, 0, 10):
20807c1389f1STim Huang 	case IP_VERSION(13, 0, 11):
20812d2f1622SLe Ma 	case IP_VERSION(13, 0, 12):
20821dbd59f3SHawking Zhang 	case IP_VERSION(13, 0, 14):
208382f33504SLi Ma 	case IP_VERSION(14, 0, 0):
2084aec765a4SYifan Zhang 	case IP_VERSION(14, 0, 1):
20859cd2ad14STim Huang 	case IP_VERSION(14, 0, 4):
2086b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
2087b05b9c59SAlex Deucher 		break;
20887e8a3ca9SXiaojian Du 	case IP_VERSION(13, 0, 4):
20897e8a3ca9SXiaojian Du 		amdgpu_device_ip_block_add(adev, &psp_v13_0_4_ip_block);
20907e8a3ca9SXiaojian Du 		break;
2091efc11f34SLikun Gao 	case IP_VERSION(14, 0, 2):
2092efc11f34SLikun Gao 	case IP_VERSION(14, 0, 3):
2093e55565f8STim Huang 	case IP_VERSION(14, 0, 5):
2094efc11f34SLikun Gao 		amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block);
2095efc11f34SLikun Gao 		break;
2096b05b9c59SAlex Deucher 	default:
209769650a87SGuchun Chen 		dev_err(adev->dev,
209869650a87SGuchun Chen 			"Failed to add psp ip block(MP0_HWIP:0x%x)\n",
20994e8303cfSLijo Lazar 			amdgpu_ip_version(adev, MP0_HWIP, 0));
2100b05b9c59SAlex Deucher 		return -EINVAL;
2101b05b9c59SAlex Deucher 	}
2102b05b9c59SAlex Deucher 	return 0;
2103b05b9c59SAlex Deucher }
2104b05b9c59SAlex Deucher 
amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device * adev)2105b05b9c59SAlex Deucher static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
2106b05b9c59SAlex Deucher {
21074e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
2108b05b9c59SAlex Deucher 	case IP_VERSION(9, 0, 0):
2109b05b9c59SAlex Deucher 	case IP_VERSION(10, 0, 0):
2110b05b9c59SAlex Deucher 	case IP_VERSION(10, 0, 1):
2111b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 2):
2112b05b9c59SAlex Deucher 		if (adev->asic_type == CHIP_ARCTURUS)
2113b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
2114b05b9c59SAlex Deucher 		else
2115b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
2116b05b9c59SAlex Deucher 		break;
2117b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 0):
211873bf6671SAlex Deucher 	case IP_VERSION(11, 0, 5):
2119b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 9):
2120b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 7):
2121b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 8):
2122b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 11):
2123b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 12):
2124b05b9c59SAlex Deucher 	case IP_VERSION(11, 0, 13):
2125b05b9c59SAlex Deucher 	case IP_VERSION(11, 5, 0):
212616a5a8feSYing Li 	case IP_VERSION(11, 5, 2):
2127b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
2128b05b9c59SAlex Deucher 		break;
2129b05b9c59SAlex Deucher 	case IP_VERSION(12, 0, 0):
2130b05b9c59SAlex Deucher 	case IP_VERSION(12, 0, 1):
2131b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block);
2132b05b9c59SAlex Deucher 		break;
213340c48740SLikun Gao 	case IP_VERSION(13, 0, 0):
2134b05b9c59SAlex Deucher 	case IP_VERSION(13, 0, 1):
2135b05b9c59SAlex Deucher 	case IP_VERSION(13, 0, 2):
2136b05b9c59SAlex Deucher 	case IP_VERSION(13, 0, 3):
21370d6ec07aSXiaojian Du 	case IP_VERSION(13, 0, 4):
2138068ea8bdSYifan Zhang 	case IP_VERSION(13, 0, 5):
2139c796d7e0SShiwu Zhang 	case IP_VERSION(13, 0, 6):
21401db7b3aaSFlora Cui 	case IP_VERSION(13, 0, 7):
2141db090ff8SPrike Liang 	case IP_VERSION(13, 0, 8):
214277356236SJohn Clements 	case IP_VERSION(13, 0, 10):
214351e7a216SYifan Zhang 	case IP_VERSION(13, 0, 11):
2144a6bcffa5SHawking Zhang 	case IP_VERSION(13, 0, 14):
2145a03f5f8dSMangesh Gadre 	case IP_VERSION(13, 0, 12):
2146b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
2147b05b9c59SAlex Deucher 		break;
2148ad3e54abSLi Ma 	case IP_VERSION(14, 0, 0):
2149f5a3507cSYifan Zhang 	case IP_VERSION(14, 0, 1):
21500c1195caSKenneth Feng 	case IP_VERSION(14, 0, 2):
21510c1195caSKenneth Feng 	case IP_VERSION(14, 0, 3):
215238a16bfeSTim Huang 	case IP_VERSION(14, 0, 4):
2153e7704d7cSTim Huang 	case IP_VERSION(14, 0, 5):
2154ad3e54abSLi Ma 		amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block);
2155ad3e54abSLi Ma 		break;
2156b05b9c59SAlex Deucher 	default:
215769650a87SGuchun Chen 		dev_err(adev->dev,
215869650a87SGuchun Chen 			"Failed to add smu ip block(MP1_HWIP:0x%x)\n",
21594e8303cfSLijo Lazar 			amdgpu_ip_version(adev, MP1_HWIP, 0));
2160b05b9c59SAlex Deucher 		return -EINVAL;
2161b05b9c59SAlex Deucher 	}
2162b05b9c59SAlex Deucher 	return 0;
2163b05b9c59SAlex Deucher }
2164b05b9c59SAlex Deucher 
2165b7a3260cSRen Zhijie #if defined(CONFIG_DRM_AMD_DC)
amdgpu_discovery_set_sriov_display(struct amdgpu_device * adev)216625263da3SAlex Deucher static void amdgpu_discovery_set_sriov_display(struct amdgpu_device *adev)
216725263da3SAlex Deucher {
216825263da3SAlex Deucher 	amdgpu_device_set_sriov_virtual_display(adev);
216925263da3SAlex Deucher 	amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
217025263da3SAlex Deucher }
2171b7a3260cSRen Zhijie #endif
217225263da3SAlex Deucher 
amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device * adev)2173b05b9c59SAlex Deucher static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
2174b05b9c59SAlex Deucher {
217525263da3SAlex Deucher 	if (adev->enable_virtual_display) {
2176b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
21776a6c2ab6SLang Yu 		return 0;
21786a6c2ab6SLang Yu 	}
21796a6c2ab6SLang Yu 
21806a6c2ab6SLang Yu 	if (!amdgpu_device_has_dc_support(adev))
21816a6c2ab6SLang Yu 		return 0;
21826a6c2ab6SLang Yu 
2183b05b9c59SAlex Deucher #if defined(CONFIG_DRM_AMD_DC)
21844e8303cfSLijo Lazar 	if (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
21854e8303cfSLijo Lazar 		switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
2186b05b9c59SAlex Deucher 		case IP_VERSION(1, 0, 0):
2187b05b9c59SAlex Deucher 		case IP_VERSION(1, 0, 1):
2188b05b9c59SAlex Deucher 		case IP_VERSION(2, 0, 2):
2189b05b9c59SAlex Deucher 		case IP_VERSION(2, 0, 0):
2190fe04957eSLang Yu 		case IP_VERSION(2, 0, 3):
2191b05b9c59SAlex Deucher 		case IP_VERSION(2, 1, 0):
2192b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 0):
2193b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 2):
2194b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 3):
2195b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 1):
2196b05b9c59SAlex Deucher 		case IP_VERSION(3, 1, 2):
2197b05b9c59SAlex Deucher 		case IP_VERSION(3, 1, 3):
2198869b10acSRoman Li 		case IP_VERSION(3, 1, 4):
2199181ebed7SYifan Zhang 		case IP_VERSION(3, 1, 5):
2200f83e1401SPrike Liang 		case IP_VERSION(3, 1, 6):
220185b0cc35SAurabindo Pillai 		case IP_VERSION(3, 2, 0):
220285b0cc35SAurabindo Pillai 		case IP_VERSION(3, 2, 1):
2203ce862c49SAaron Liu 		case IP_VERSION(3, 5, 0):
22042bdebcb1SYifan Zhang 		case IP_VERSION(3, 5, 1):
220576e0410fSTim Huang 		case IP_VERSION(3, 6, 0):
2206a5b84326SAurabindo Pillai 		case IP_VERSION(4, 1, 0):
2207c45211adSAurabindo Pillai 			/* TODO: Fix IP version. DC code expects version 4.0.1 */
2208c45211adSAurabindo Pillai 			if (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(4, 1, 0))
2209c45211adSAurabindo Pillai 				adev->ip_versions[DCE_HWIP][0] = IP_VERSION(4, 0, 1);
2210c45211adSAurabindo Pillai 
221125263da3SAlex Deucher 			if (amdgpu_sriov_vf(adev))
221225263da3SAlex Deucher 				amdgpu_discovery_set_sriov_display(adev);
221325263da3SAlex Deucher 			else
2214b05b9c59SAlex Deucher 				amdgpu_device_ip_block_add(adev, &dm_ip_block);
2215b05b9c59SAlex Deucher 			break;
2216b05b9c59SAlex Deucher 		default:
221769650a87SGuchun Chen 			dev_err(adev->dev,
221869650a87SGuchun Chen 				"Failed to add dm ip block(DCE_HWIP:0x%x)\n",
22194e8303cfSLijo Lazar 				amdgpu_ip_version(adev, DCE_HWIP, 0));
2220b05b9c59SAlex Deucher 			return -EINVAL;
2221b05b9c59SAlex Deucher 		}
22224e8303cfSLijo Lazar 	} else if (amdgpu_ip_version(adev, DCI_HWIP, 0)) {
22234e8303cfSLijo Lazar 		switch (amdgpu_ip_version(adev, DCI_HWIP, 0)) {
2224b05b9c59SAlex Deucher 		case IP_VERSION(12, 0, 0):
2225b05b9c59SAlex Deucher 		case IP_VERSION(12, 0, 1):
2226b05b9c59SAlex Deucher 		case IP_VERSION(12, 1, 0):
222725263da3SAlex Deucher 			if (amdgpu_sriov_vf(adev))
222825263da3SAlex Deucher 				amdgpu_discovery_set_sriov_display(adev);
222925263da3SAlex Deucher 			else
2230b05b9c59SAlex Deucher 				amdgpu_device_ip_block_add(adev, &dm_ip_block);
2231b05b9c59SAlex Deucher 			break;
2232b05b9c59SAlex Deucher 		default:
223369650a87SGuchun Chen 			dev_err(adev->dev,
223469650a87SGuchun Chen 				"Failed to add dm ip block(DCI_HWIP:0x%x)\n",
22354e8303cfSLijo Lazar 				amdgpu_ip_version(adev, DCI_HWIP, 0));
2236b05b9c59SAlex Deucher 			return -EINVAL;
2237b05b9c59SAlex Deucher 		}
2238b05b9c59SAlex Deucher 	}
22396a6c2ab6SLang Yu #endif
2240b05b9c59SAlex Deucher 	return 0;
2241b05b9c59SAlex Deucher }
2242b05b9c59SAlex Deucher 
amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device * adev)2243b05b9c59SAlex Deucher static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
2244b05b9c59SAlex Deucher {
22454e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
2246b05b9c59SAlex Deucher 	case IP_VERSION(9, 0, 1):
2247b05b9c59SAlex Deucher 	case IP_VERSION(9, 1, 0):
2248b05b9c59SAlex Deucher 	case IP_VERSION(9, 2, 1):
2249b05b9c59SAlex Deucher 	case IP_VERSION(9, 2, 2):
2250b05b9c59SAlex Deucher 	case IP_VERSION(9, 3, 0):
2251b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 0):
2252b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 1):
2253b05b9c59SAlex Deucher 	case IP_VERSION(9, 4, 2):
2254b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
2255b05b9c59SAlex Deucher 		break;
2256c796d7e0SShiwu Zhang 	case IP_VERSION(9, 4, 3):
22575f571c61SHawking Zhang 	case IP_VERSION(9, 4, 4):
22580b58a55aSLe Ma 	case IP_VERSION(9, 5, 0):
2259c796d7e0SShiwu Zhang 		amdgpu_device_ip_block_add(adev, &gfx_v9_4_3_ip_block);
2260c796d7e0SShiwu Zhang 		break;
2261b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 10):
2262b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 2):
2263b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 1):
2264b05b9c59SAlex Deucher 	case IP_VERSION(10, 1, 3):
2265f9ed188dSLang Yu 	case IP_VERSION(10, 1, 4):
2266b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 0):
2267b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 2):
2268b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 1):
2269b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 4):
2270b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 5):
2271874bfdfaSYifan Zhang 	case IP_VERSION(10, 3, 6):
2272b05b9c59SAlex Deucher 	case IP_VERSION(10, 3, 3):
2273a65dbf7cSPrike Liang 	case IP_VERSION(10, 3, 7):
2274b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
2275b05b9c59SAlex Deucher 		break;
2276f6abd4d9SLikun Gao 	case IP_VERSION(11, 0, 0):
227710eab4e7SHuang Rui 	case IP_VERSION(11, 0, 1):
2278af695849SFlora Cui 	case IP_VERSION(11, 0, 2):
2279a4d002d7SHawking Zhang 	case IP_VERSION(11, 0, 3):
2280b952d6b3SYifan Zhang 	case IP_VERSION(11, 0, 4):
2281b5549a2dSPrike Liang 	case IP_VERSION(11, 5, 0):
2282e2442d3eSYifan Zhang 	case IP_VERSION(11, 5, 1):
228323c1ea02STim Huang 	case IP_VERSION(11, 5, 2):
2284b784faebSTim Huang 	case IP_VERSION(11, 5, 3):
2285f6abd4d9SLikun Gao 		amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
2286f6abd4d9SLikun Gao 		break;
22875e676d71SLikun Gao 	case IP_VERSION(12, 0, 0):
22885e676d71SLikun Gao 	case IP_VERSION(12, 0, 1):
22895e676d71SLikun Gao 		amdgpu_device_ip_block_add(adev, &gfx_v12_0_ip_block);
22905e676d71SLikun Gao 		break;
2291b05b9c59SAlex Deucher 	default:
22924e8303cfSLijo Lazar 		dev_err(adev->dev, "Failed to add gfx ip block(GC_HWIP:0x%x)\n",
22934e8303cfSLijo Lazar 			amdgpu_ip_version(adev, GC_HWIP, 0));
2294b05b9c59SAlex Deucher 		return -EINVAL;
2295b05b9c59SAlex Deucher 	}
2296b05b9c59SAlex Deucher 	return 0;
2297b05b9c59SAlex Deucher }
2298b05b9c59SAlex Deucher 
amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device * adev)2299b05b9c59SAlex Deucher static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
2300b05b9c59SAlex Deucher {
23014e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
2302b05b9c59SAlex Deucher 	case IP_VERSION(4, 0, 0):
2303b05b9c59SAlex Deucher 	case IP_VERSION(4, 0, 1):
2304b05b9c59SAlex Deucher 	case IP_VERSION(4, 1, 0):
2305b05b9c59SAlex Deucher 	case IP_VERSION(4, 1, 1):
2306b05b9c59SAlex Deucher 	case IP_VERSION(4, 1, 2):
2307b05b9c59SAlex Deucher 	case IP_VERSION(4, 2, 0):
2308b05b9c59SAlex Deucher 	case IP_VERSION(4, 2, 2):
2309b05b9c59SAlex Deucher 	case IP_VERSION(4, 4, 0):
2310b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
2311b05b9c59SAlex Deucher 		break;
2312051ae8d5SLe Ma 	case IP_VERSION(4, 4, 2):
23133d1bb1a2SHawking Zhang 	case IP_VERSION(4, 4, 5):
2314968e3811SLe Ma 	case IP_VERSION(4, 4, 4):
2315051ae8d5SLe Ma 		amdgpu_device_ip_block_add(adev, &sdma_v4_4_2_ip_block);
2316051ae8d5SLe Ma 		break;
2317b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 0):
2318b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 1):
2319b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 2):
2320b05b9c59SAlex Deucher 	case IP_VERSION(5, 0, 5):
2321b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
2322b05b9c59SAlex Deucher 		break;
2323b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 0):
2324b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 2):
2325b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 4):
2326b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 5):
232793afe158SYifan Zhang 	case IP_VERSION(5, 2, 6):
2328b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 3):
2329b05b9c59SAlex Deucher 	case IP_VERSION(5, 2, 1):
2330967af863SPrike Liang 	case IP_VERSION(5, 2, 7):
2331b05b9c59SAlex Deucher 		amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
2332b05b9c59SAlex Deucher 		break;
23338143b87cSStanley Yang 	case IP_VERSION(6, 0, 0):
2334500448dcSHuang Rui 	case IP_VERSION(6, 0, 1):
233563b17080SFlora Cui 	case IP_VERSION(6, 0, 2):
23365bb71735SHawking Zhang 	case IP_VERSION(6, 0, 3):
233799af9c95SPrike Liang 	case IP_VERSION(6, 1, 0):
2338a02cfac9SYifan Zhang 	case IP_VERSION(6, 1, 1):
2339dfeccf4dSTim Huang 	case IP_VERSION(6, 1, 2):
2340b2e5a041STim Huang 	case IP_VERSION(6, 1, 3):
23418143b87cSStanley Yang 		amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
23428143b87cSStanley Yang 		break;
2343f45ed399SLikun Gao 	case IP_VERSION(7, 0, 0):
2344f45ed399SLikun Gao 	case IP_VERSION(7, 0, 1):
2345f45ed399SLikun Gao 		amdgpu_device_ip_block_add(adev, &sdma_v7_0_ip_block);
2346f45ed399SLikun Gao 		break;
2347b05b9c59SAlex Deucher 	default:
234869650a87SGuchun Chen 		dev_err(adev->dev,
234969650a87SGuchun Chen 			"Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n",
23504e8303cfSLijo Lazar 			amdgpu_ip_version(adev, SDMA0_HWIP, 0));
2351b05b9c59SAlex Deucher 		return -EINVAL;
2352b05b9c59SAlex Deucher 	}
2353b05b9c59SAlex Deucher 	return 0;
2354b05b9c59SAlex Deucher }
2355b05b9c59SAlex Deucher 
amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device * adev)2356b05b9c59SAlex Deucher static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
2357b05b9c59SAlex Deucher {
23584e8303cfSLijo Lazar 	if (amdgpu_ip_version(adev, VCE_HWIP, 0)) {
23594e8303cfSLijo Lazar 		switch (amdgpu_ip_version(adev, UVD_HWIP, 0)) {
2360b05b9c59SAlex Deucher 		case IP_VERSION(7, 0, 0):
2361b05b9c59SAlex Deucher 		case IP_VERSION(7, 2, 0):
23626d46d419SAlex Deucher 			/* UVD is not supported on vega20 SR-IOV */
23636d46d419SAlex Deucher 			if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev)))
2364b05b9c59SAlex Deucher 				amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
2365b05b9c59SAlex Deucher 			break;
2366b05b9c59SAlex Deucher 		default:
236769650a87SGuchun Chen 			dev_err(adev->dev,
236869650a87SGuchun Chen 				"Failed to add uvd v7 ip block(UVD_HWIP:0x%x)\n",
23694e8303cfSLijo Lazar 				amdgpu_ip_version(adev, UVD_HWIP, 0));
2370b05b9c59SAlex Deucher 			return -EINVAL;
2371b05b9c59SAlex Deucher 		}
23724e8303cfSLijo Lazar 		switch (amdgpu_ip_version(adev, VCE_HWIP, 0)) {
2373b05b9c59SAlex Deucher 		case IP_VERSION(4, 0, 0):
2374b05b9c59SAlex Deucher 		case IP_VERSION(4, 1, 0):
23756d46d419SAlex Deucher 			/* VCE is not supported on vega20 SR-IOV */
23766d46d419SAlex Deucher 			if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev)))
2377b05b9c59SAlex Deucher 				amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block);
2378b05b9c59SAlex Deucher 			break;
2379b05b9c59SAlex Deucher 		default:
238069650a87SGuchun Chen 			dev_err(adev->dev,
238169650a87SGuchun Chen 				"Failed to add VCE v4 ip block(VCE_HWIP:0x%x)\n",
23824e8303cfSLijo Lazar 				amdgpu_ip_version(adev, VCE_HWIP, 0));
2383b05b9c59SAlex Deucher 			return -EINVAL;
2384b05b9c59SAlex Deucher 		}
2385b05b9c59SAlex Deucher 	} else {
23864e8303cfSLijo Lazar 		switch (amdgpu_ip_version(adev, UVD_HWIP, 0)) {
2387b05b9c59SAlex Deucher 		case IP_VERSION(1, 0, 0):
2388b05b9c59SAlex Deucher 		case IP_VERSION(1, 0, 1):
2389b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block);
2390b05b9c59SAlex Deucher 			break;
2391b05b9c59SAlex Deucher 		case IP_VERSION(2, 0, 0):
2392b05b9c59SAlex Deucher 		case IP_VERSION(2, 0, 2):
2393b05b9c59SAlex Deucher 		case IP_VERSION(2, 2, 0):
2394b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
2395b45a3603SGuchun Chen 			if (!amdgpu_sriov_vf(adev))
2396b05b9c59SAlex Deucher 				amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
2397b05b9c59SAlex Deucher 			break;
2398b05b9c59SAlex Deucher 		case IP_VERSION(2, 0, 3):
2399b05b9c59SAlex Deucher 			break;
2400b05b9c59SAlex Deucher 		case IP_VERSION(2, 5, 0):
2401b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
2402b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block);
2403b05b9c59SAlex Deucher 			break;
2404b05b9c59SAlex Deucher 		case IP_VERSION(2, 6, 0):
2405b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block);
2406b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block);
2407b05b9c59SAlex Deucher 			break;
2408b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 0):
2409b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 16):
2410b05b9c59SAlex Deucher 		case IP_VERSION(3, 1, 1):
2411afc2f276SBoyuan Zhang 		case IP_VERSION(3, 1, 2):
2412b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 2):
2413b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
24146d46d419SAlex Deucher 			if (!amdgpu_sriov_vf(adev))
2415b05b9c59SAlex Deucher 				amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
2416b05b9c59SAlex Deucher 			break;
2417b05b9c59SAlex Deucher 		case IP_VERSION(3, 0, 33):
2418b05b9c59SAlex Deucher 			amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
2419b05b9c59SAlex Deucher 			break;
2420d6ffefccSJames Zhu 		case IP_VERSION(4, 0, 0):
2421438eac25SYifan Zhang 		case IP_VERSION(4, 0, 2):
24223a65fbc0SJames Zhu 		case IP_VERSION(4, 0, 4):
2423d6ffefccSJames Zhu 			amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
2424d6ffefccSJames Zhu 			amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
2425ed1f42f0SJames Zhu 			break;
2426ed1f42f0SJames Zhu 		case IP_VERSION(4, 0, 3):
2427ed1f42f0SJames Zhu 			amdgpu_device_ip_block_add(adev, &vcn_v4_0_3_ip_block);
2428ed1f42f0SJames Zhu 			amdgpu_device_ip_block_add(adev, &jpeg_v4_0_3_ip_block);
2429ed1f42f0SJames Zhu 			break;
2430844d8dd5SSaleemkhan Jamadar 		case IP_VERSION(4, 0, 5):
2431a24029ccSYifan Zhang 		case IP_VERSION(4, 0, 6):
2432844d8dd5SSaleemkhan Jamadar 			amdgpu_device_ip_block_add(adev, &vcn_v4_0_5_ip_block);
2433844d8dd5SSaleemkhan Jamadar 			amdgpu_device_ip_block_add(adev, &jpeg_v4_0_5_ip_block);
2434844d8dd5SSaleemkhan Jamadar 			break;
2435470675f6SSonny Jiang 		case IP_VERSION(5, 0, 0):
2436470675f6SSonny Jiang 			amdgpu_device_ip_block_add(adev, &vcn_v5_0_0_ip_block);
2437cff99603SSonny Jiang 			amdgpu_device_ip_block_add(adev, &jpeg_v5_0_0_ip_block);
2438470675f6SSonny Jiang 			break;
2439c406fca4SSathishkumar S 		case IP_VERSION(5, 0, 1):
2440178ad3a9SSonny Jiang 			amdgpu_device_ip_block_add(adev, &vcn_v5_0_1_ip_block);
2441c406fca4SSathishkumar S 			amdgpu_device_ip_block_add(adev, &jpeg_v5_0_1_ip_block);
2442c406fca4SSathishkumar S 			break;
2443b05b9c59SAlex Deucher 		default:
244469650a87SGuchun Chen 			dev_err(adev->dev,
244569650a87SGuchun Chen 				"Failed to add vcn/jpeg ip block(UVD_HWIP:0x%x)\n",
24464e8303cfSLijo Lazar 				amdgpu_ip_version(adev, UVD_HWIP, 0));
2447b05b9c59SAlex Deucher 			return -EINVAL;
2448b05b9c59SAlex Deucher 		}
2449b05b9c59SAlex Deucher 	}
2450b05b9c59SAlex Deucher 	return 0;
2451b05b9c59SAlex Deucher }
2452b05b9c59SAlex Deucher 
amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device * adev)2453b05b9c59SAlex Deucher static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
2454b05b9c59SAlex Deucher {
24554e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
2456e97b0720SAlex Deucher 	case IP_VERSION(11, 0, 0):
2457f333c9c6SHuang Rui 	case IP_VERSION(11, 0, 1):
2458215a65f5SFlora Cui 	case IP_VERSION(11, 0, 2):
2459e7c69a27SHawking Zhang 	case IP_VERSION(11, 0, 3):
24606a6af775SYifan Zhang 	case IP_VERSION(11, 0, 4):
2461d3ff0189SLang Yu 	case IP_VERSION(11, 5, 0):
2462d6a76c0aSYifan Zhang 	case IP_VERSION(11, 5, 1):
246323c1ea02STim Huang 	case IP_VERSION(11, 5, 2):
2464b784faebSTim Huang 	case IP_VERSION(11, 5, 3):
2465e97b0720SAlex Deucher 		amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
2466e97b0720SAlex Deucher 		adev->enable_mes = true;
2467e97b0720SAlex Deucher 		adev->enable_mes_kiq = true;
2468b05b9c59SAlex Deucher 		break;
24690a75dc98SLikun Gao 	case IP_VERSION(12, 0, 0):
24700a75dc98SLikun Gao 	case IP_VERSION(12, 0, 1):
24710a75dc98SLikun Gao 		amdgpu_device_ip_block_add(adev, &mes_v12_0_ip_block);
24720a75dc98SLikun Gao 		adev->enable_mes = true;
24730a75dc98SLikun Gao 		adev->enable_mes_kiq = true;
24740a75dc98SLikun Gao 		if (amdgpu_uni_mes)
24750a75dc98SLikun Gao 			adev->enable_uni_mes = true;
24760a75dc98SLikun Gao 		break;
2477b05b9c59SAlex Deucher 	default:
247845e3d1dbSGuchun Chen 		break;
2479b05b9c59SAlex Deucher 	}
2480b05b9c59SAlex Deucher 	return 0;
2481b05b9c59SAlex Deucher }
2482b05b9c59SAlex Deucher 
amdgpu_discovery_init_soc_config(struct amdgpu_device * adev)2483e56c9ef6SLijo Lazar static void amdgpu_discovery_init_soc_config(struct amdgpu_device *adev)
2484cab7d478SLijo Lazar {
24854e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
2486cab7d478SLijo Lazar 	case IP_VERSION(9, 4, 3):
24875f571c61SHawking Zhang 	case IP_VERSION(9, 4, 4):
24880b58a55aSLe Ma 	case IP_VERSION(9, 5, 0):
2489e56c9ef6SLijo Lazar 		aqua_vanjaram_init_soc_config(adev);
2490cab7d478SLijo Lazar 		break;
2491cab7d478SLijo Lazar 	default:
2492cab7d478SLijo Lazar 		break;
2493cab7d478SLijo Lazar 	}
2494cab7d478SLijo Lazar }
2495cab7d478SLijo Lazar 
amdgpu_discovery_set_vpe_ip_blocks(struct amdgpu_device * adev)24963ee8fb70SLang Yu static int amdgpu_discovery_set_vpe_ip_blocks(struct amdgpu_device *adev)
24973ee8fb70SLang Yu {
24984e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, VPE_HWIP, 0)) {
24993ee8fb70SLang Yu 	case IP_VERSION(6, 1, 0):
2500155d4683SAlex Deucher 	case IP_VERSION(6, 1, 1):
2501ca15cd55STim Huang 	case IP_VERSION(6, 1, 3):
25023ee8fb70SLang Yu 		amdgpu_device_ip_block_add(adev, &vpe_v6_1_ip_block);
25033ee8fb70SLang Yu 		break;
25043ee8fb70SLang Yu 	default:
25053ee8fb70SLang Yu 		break;
25063ee8fb70SLang Yu 	}
25073ee8fb70SLang Yu 
25083ee8fb70SLang Yu 	return 0;
25093ee8fb70SLang Yu }
25103ee8fb70SLang Yu 
amdgpu_discovery_set_umsch_mm_ip_blocks(struct amdgpu_device * adev)2511822f7808SLang Yu static int amdgpu_discovery_set_umsch_mm_ip_blocks(struct amdgpu_device *adev)
2512822f7808SLang Yu {
25134e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) {
2514822f7808SLang Yu 	case IP_VERSION(4, 0, 5):
2515b9a8aee1SLang Yu 	case IP_VERSION(4, 0, 6):
2516eebb06d1SLang Yu 		if (amdgpu_umsch_mm & 0x1) {
2517822f7808SLang Yu 			amdgpu_device_ip_block_add(adev, &umsch_mm_v4_0_ip_block);
2518822f7808SLang Yu 			adev->enable_umsch_mm = true;
2519eebb06d1SLang Yu 		}
2520822f7808SLang Yu 		break;
2521822f7808SLang Yu 	default:
2522822f7808SLang Yu 		break;
2523822f7808SLang Yu 	}
2524822f7808SLang Yu 
2525822f7808SLang Yu 	return 0;
2526822f7808SLang Yu }
2527822f7808SLang Yu 
amdgpu_discovery_set_isp_ip_blocks(struct amdgpu_device * adev)2528d232584aSPratap Nirujogi static int amdgpu_discovery_set_isp_ip_blocks(struct amdgpu_device *adev)
2529d232584aSPratap Nirujogi {
25308930b90bSAlex Deucher #if defined(CONFIG_DRM_AMD_ISP)
2531d232584aSPratap Nirujogi 	switch (amdgpu_ip_version(adev, ISP_HWIP, 0)) {
2532d232584aSPratap Nirujogi 	case IP_VERSION(4, 1, 0):
253305bafe95SPratap Nirujogi 		amdgpu_device_ip_block_add(adev, &isp_v4_1_0_ip_block);
253405bafe95SPratap Nirujogi 		break;
2535d232584aSPratap Nirujogi 	case IP_VERSION(4, 1, 1):
253605bafe95SPratap Nirujogi 		amdgpu_device_ip_block_add(adev, &isp_v4_1_1_ip_block);
2537d232584aSPratap Nirujogi 		break;
2538d232584aSPratap Nirujogi 	default:
2539d232584aSPratap Nirujogi 		break;
2540d232584aSPratap Nirujogi 	}
25418930b90bSAlex Deucher #endif
2542d232584aSPratap Nirujogi 
2543d232584aSPratap Nirujogi 	return 0;
2544d232584aSPratap Nirujogi }
2545d232584aSPratap Nirujogi 
amdgpu_discovery_set_ip_blocks(struct amdgpu_device * adev)2546795d0839SAlex Deucher int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
2547795d0839SAlex Deucher {
2548795d0839SAlex Deucher 	int r;
2549795d0839SAlex Deucher 
2550d4c6e870SAlex Deucher 	switch (adev->asic_type) {
2551d4c6e870SAlex Deucher 	case CHIP_VEGA10:
255280a0e828SAlex Deucher 	case CHIP_VEGA12:
255380a0e828SAlex Deucher 	case CHIP_RAVEN:
255480a0e828SAlex Deucher 	case CHIP_VEGA20:
255580a0e828SAlex Deucher 	case CHIP_ARCTURUS:
255680a0e828SAlex Deucher 	case CHIP_ALDEBARAN:
255780a0e828SAlex Deucher 		/* this is not fatal.  We have a fallback below
255880a0e828SAlex Deucher 		 * if the new firmwares are not present. some of
255980a0e828SAlex Deucher 		 * this will be overridden below to keep things
256080a0e828SAlex Deucher 		 * consistent with the current behavior.
256180a0e828SAlex Deucher 		 */
256280a0e828SAlex Deucher 		r = amdgpu_discovery_reg_base_init(adev);
256380a0e828SAlex Deucher 		if (!r) {
256480a0e828SAlex Deucher 			amdgpu_discovery_harvest_ip(adev);
256580a0e828SAlex Deucher 			amdgpu_discovery_get_gfx_info(adev);
256680a0e828SAlex Deucher 			amdgpu_discovery_get_mall_info(adev);
256780a0e828SAlex Deucher 			amdgpu_discovery_get_vcn_info(adev);
256880a0e828SAlex Deucher 		}
256980a0e828SAlex Deucher 		break;
257080a0e828SAlex Deucher 	default:
257180a0e828SAlex Deucher 		r = amdgpu_discovery_reg_base_init(adev);
257280a0e828SAlex Deucher 		if (r)
257380a0e828SAlex Deucher 			return -EINVAL;
257480a0e828SAlex Deucher 
257580a0e828SAlex Deucher 		amdgpu_discovery_harvest_ip(adev);
257680a0e828SAlex Deucher 		amdgpu_discovery_get_gfx_info(adev);
257780a0e828SAlex Deucher 		amdgpu_discovery_get_mall_info(adev);
257880a0e828SAlex Deucher 		amdgpu_discovery_get_vcn_info(adev);
257980a0e828SAlex Deucher 		break;
258080a0e828SAlex Deucher 	}
258180a0e828SAlex Deucher 
258280a0e828SAlex Deucher 	switch (adev->asic_type) {
258380a0e828SAlex Deucher 	case CHIP_VEGA10:
2584d4c6e870SAlex Deucher 		vega10_reg_base_init(adev);
25855c3720beSAlex Deucher 		adev->sdma.num_instances = 2;
2586a2efebf1SAlex Deucher 		adev->gmc.num_umc = 4;
25871d789535SAlex Deucher 		adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 0, 0);
25881d789535SAlex Deucher 		adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 0, 0);
25891d789535SAlex Deucher 		adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 0);
25901d789535SAlex Deucher 		adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 0);
25911d789535SAlex Deucher 		adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 0);
259258f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 0);
25931d789535SAlex Deucher 		adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0);
25941d789535SAlex Deucher 		adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 1, 0);
25951d789535SAlex Deucher 		adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 0, 0);
25961d789535SAlex Deucher 		adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0);
25971d789535SAlex Deucher 		adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0);
25981d789535SAlex Deucher 		adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0);
25991d789535SAlex Deucher 		adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 0);
26001d789535SAlex Deucher 		adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 0, 1);
26011d789535SAlex Deucher 		adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0);
26021d789535SAlex Deucher 		adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0);
26031d789535SAlex Deucher 		adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 0);
2604d4c6e870SAlex Deucher 		break;
2605d4c6e870SAlex Deucher 	case CHIP_VEGA12:
2606d4c6e870SAlex Deucher 		vega10_reg_base_init(adev);
26075c3720beSAlex Deucher 		adev->sdma.num_instances = 2;
2608a2efebf1SAlex Deucher 		adev->gmc.num_umc = 4;
26091d789535SAlex Deucher 		adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 3, 0);
26101d789535SAlex Deucher 		adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 3, 0);
26111d789535SAlex Deucher 		adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 1);
26121d789535SAlex Deucher 		adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 1);
26131d789535SAlex Deucher 		adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 1);
261458f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 1);
26151d789535SAlex Deucher 		adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 5, 0);
26161d789535SAlex Deucher 		adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 2, 0);
26171d789535SAlex Deucher 		adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 0);
26181d789535SAlex Deucher 		adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0);
26191d789535SAlex Deucher 		adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0);
26201d789535SAlex Deucher 		adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0);
26211d789535SAlex Deucher 		adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 1);
26221d789535SAlex Deucher 		adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 1);
26231d789535SAlex Deucher 		adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0);
26241d789535SAlex Deucher 		adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0);
26251d789535SAlex Deucher 		adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 1);
2626d4c6e870SAlex Deucher 		break;
2627d4c6e870SAlex Deucher 	case CHIP_RAVEN:
2628d4c6e870SAlex Deucher 		vega10_reg_base_init(adev);
26295c3720beSAlex Deucher 		adev->sdma.num_instances = 1;
26305c3720beSAlex Deucher 		adev->vcn.num_vcn_inst = 1;
2631a2efebf1SAlex Deucher 		adev->gmc.num_umc = 2;
2632d4c6e870SAlex Deucher 		if (adev->apu_flags & AMD_APU_IS_RAVEN2) {
26331d789535SAlex Deucher 			adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 2, 0);
26341d789535SAlex Deucher 			adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 2, 0);
26351d789535SAlex Deucher 			adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 1);
26361d789535SAlex Deucher 			adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 1);
26371d789535SAlex Deucher 			adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 1);
26381d789535SAlex Deucher 			adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 1);
26391d789535SAlex Deucher 			adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 1);
26401d789535SAlex Deucher 			adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 5, 0);
26411d789535SAlex Deucher 			adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 1);
26421d789535SAlex Deucher 			adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 1);
26431d789535SAlex Deucher 			adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 1, 0);
26441d789535SAlex Deucher 			adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 1);
26451d789535SAlex Deucher 			adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 2);
26461d789535SAlex Deucher 			adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 1);
26471d789535SAlex Deucher 			adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 1);
2648d2f57b6dSAlex Deucher 			adev->ip_versions[ISP_HWIP][0] = IP_VERSION(2, 0, 0);
2649d4c6e870SAlex Deucher 		} else {
26501d789535SAlex Deucher 			adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 1, 0);
26511d789535SAlex Deucher 			adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 1, 0);
26521d789535SAlex Deucher 			adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 0);
26531d789535SAlex Deucher 			adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 0);
26541d789535SAlex Deucher 			adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 0);
26551d789535SAlex Deucher 			adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0);
26561d789535SAlex Deucher 			adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 0);
26571d789535SAlex Deucher 			adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 0, 0);
26581d789535SAlex Deucher 			adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 0);
26591d789535SAlex Deucher 			adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 0);
26601d789535SAlex Deucher 			adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 0, 0);
26611d789535SAlex Deucher 			adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 0);
26621d789535SAlex Deucher 			adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 1, 0);
26631d789535SAlex Deucher 			adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 0);
26641d789535SAlex Deucher 			adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 0);
2665d2f57b6dSAlex Deucher 			adev->ip_versions[ISP_HWIP][0] = IP_VERSION(2, 0, 0);
2666d4c6e870SAlex Deucher 		}
2667d4c6e870SAlex Deucher 		break;
2668d4c6e870SAlex Deucher 	case CHIP_VEGA20:
2669d4c6e870SAlex Deucher 		vega20_reg_base_init(adev);
26705c3720beSAlex Deucher 		adev->sdma.num_instances = 2;
2671a2efebf1SAlex Deucher 		adev->gmc.num_umc = 8;
26721d789535SAlex Deucher 		adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 0);
26731d789535SAlex Deucher 		adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 0);
26741d789535SAlex Deucher 		adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 0);
26751d789535SAlex Deucher 		adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 0);
26761d789535SAlex Deucher 		adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 0);
267758f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 0);
26781d789535SAlex Deucher 		adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 0);
26791d789535SAlex Deucher 		adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 0);
26801d789535SAlex Deucher 		adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 1);
26811d789535SAlex Deucher 		adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 2);
26821d789535SAlex Deucher 		adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2);
26831d789535SAlex Deucher 		adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 2);
26841d789535SAlex Deucher 		adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 2);
26851d789535SAlex Deucher 		adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 0);
26861d789535SAlex Deucher 		adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 2, 0);
2687074b2092SAlex Deucher 		adev->ip_versions[UVD_HWIP][1] = IP_VERSION(7, 2, 0);
26881d789535SAlex Deucher 		adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 1, 0);
26891d789535SAlex Deucher 		adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 1, 0);
2690d4c6e870SAlex Deucher 		break;
2691d4c6e870SAlex Deucher 	case CHIP_ARCTURUS:
2692d4c6e870SAlex Deucher 		arct_reg_base_init(adev);
26935c3720beSAlex Deucher 		adev->sdma.num_instances = 8;
26945c3720beSAlex Deucher 		adev->vcn.num_vcn_inst = 2;
2695a2efebf1SAlex Deucher 		adev->gmc.num_umc = 8;
26961d789535SAlex Deucher 		adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 1);
26971d789535SAlex Deucher 		adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 1);
26981d789535SAlex Deucher 		adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 1);
26991d789535SAlex Deucher 		adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 1);
27001d789535SAlex Deucher 		adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 2);
270158f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 2);
270258f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][1] = IP_VERSION(4, 2, 2);
270358f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][2] = IP_VERSION(4, 2, 2);
270458f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][3] = IP_VERSION(4, 2, 2);
270558f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][4] = IP_VERSION(4, 2, 2);
270658f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][5] = IP_VERSION(4, 2, 2);
270758f8c7faSAlex Deucher 		adev->ip_versions[SDMA1_HWIP][6] = IP_VERSION(4, 2, 2);
27081d789535SAlex Deucher 		adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 1);
27091d789535SAlex Deucher 		adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 1);
27101d789535SAlex Deucher 		adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 2);
27111d789535SAlex Deucher 		adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 4);
27121d789535SAlex Deucher 		adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2);
27131d789535SAlex Deucher 		adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 3);
27141d789535SAlex Deucher 		adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 3);
27151d789535SAlex Deucher 		adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 1);
27161d789535SAlex Deucher 		adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 5, 0);
2717074b2092SAlex Deucher 		adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 5, 0);
2718d4c6e870SAlex Deucher 		break;
2719d4c6e870SAlex Deucher 	case CHIP_ALDEBARAN:
2720d4c6e870SAlex Deucher 		aldebaran_reg_base_init(adev);
27215c3720beSAlex Deucher 		adev->sdma.num_instances = 5;
27225c3720beSAlex Deucher 		adev->vcn.num_vcn_inst = 2;
2723a2efebf1SAlex Deucher 		adev->gmc.num_umc = 4;
27241d789535SAlex Deucher 		adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 2);
27251d789535SAlex Deucher 		adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 2);
27261d789535SAlex Deucher 		adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 4, 0);
27271d789535SAlex Deucher 		adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 4, 0);
27281d789535SAlex Deucher 		adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 4, 0);
272958f8c7faSAlex Deucher 		adev->ip_versions[SDMA0_HWIP][1] = IP_VERSION(4, 4, 0);
273058f8c7faSAlex Deucher 		adev->ip_versions[SDMA0_HWIP][2] = IP_VERSION(4, 4, 0);
273158f8c7faSAlex Deucher 		adev->ip_versions[SDMA0_HWIP][3] = IP_VERSION(4, 4, 0);
273258f8c7faSAlex Deucher 		adev->ip_versions[SDMA0_HWIP][4] = IP_VERSION(4, 4, 0);
27331d789535SAlex Deucher 		adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 2);
27341d789535SAlex Deucher 		adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 4);
27351d789535SAlex Deucher 		adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 7, 0);
27361d789535SAlex Deucher 		adev->ip_versions[MP0_HWIP][0] = IP_VERSION(13, 0, 2);
27371d789535SAlex Deucher 		adev->ip_versions[MP1_HWIP][0] = IP_VERSION(13, 0, 2);
27381d789535SAlex Deucher 		adev->ip_versions[THM_HWIP][0] = IP_VERSION(13, 0, 2);
27391d789535SAlex Deucher 		adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(13, 0, 2);
27401d789535SAlex Deucher 		adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 2);
27411d789535SAlex Deucher 		adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 6, 0);
2742074b2092SAlex Deucher 		adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 6, 0);
27431d789535SAlex Deucher 		adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 1, 0);
2744d4c6e870SAlex Deucher 		break;
2745d4c6e870SAlex Deucher 	default:
2746d4c6e870SAlex Deucher 		break;
2747d4c6e870SAlex Deucher 	}
2748795d0839SAlex Deucher 
2749e56c9ef6SLijo Lazar 	amdgpu_discovery_init_soc_config(adev);
2750f2b8447bSLijo Lazar 	amdgpu_discovery_sysfs_init(adev);
2751cab7d478SLijo Lazar 
27524e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
2753d4c6e870SAlex Deucher 	case IP_VERSION(9, 0, 1):
2754d4c6e870SAlex Deucher 	case IP_VERSION(9, 2, 1):
2755d4c6e870SAlex Deucher 	case IP_VERSION(9, 4, 0):
2756d4c6e870SAlex Deucher 	case IP_VERSION(9, 4, 1):
2757d4c6e870SAlex Deucher 	case IP_VERSION(9, 4, 2):
2758f3409f76SHawking Zhang 	case IP_VERSION(9, 4, 3):
27595f571c61SHawking Zhang 	case IP_VERSION(9, 4, 4):
27600b58a55aSLe Ma 	case IP_VERSION(9, 5, 0):
2761d4c6e870SAlex Deucher 		adev->family = AMDGPU_FAMILY_AI;
2762d4c6e870SAlex Deucher 		break;
2763d4c6e870SAlex Deucher 	case IP_VERSION(9, 1, 0):
2764d4c6e870SAlex Deucher 	case IP_VERSION(9, 2, 2):
2765d4c6e870SAlex Deucher 	case IP_VERSION(9, 3, 0):
2766d4c6e870SAlex Deucher 		adev->family = AMDGPU_FAMILY_RV;
2767d4c6e870SAlex Deucher 		break;
2768795d0839SAlex Deucher 	case IP_VERSION(10, 1, 10):
2769795d0839SAlex Deucher 	case IP_VERSION(10, 1, 1):
2770795d0839SAlex Deucher 	case IP_VERSION(10, 1, 2):
2771795d0839SAlex Deucher 	case IP_VERSION(10, 1, 3):
2772f9ed188dSLang Yu 	case IP_VERSION(10, 1, 4):
2773795d0839SAlex Deucher 	case IP_VERSION(10, 3, 0):
2774795d0839SAlex Deucher 	case IP_VERSION(10, 3, 2):
2775795d0839SAlex Deucher 	case IP_VERSION(10, 3, 4):
2776795d0839SAlex Deucher 	case IP_VERSION(10, 3, 5):
2777795d0839SAlex Deucher 		adev->family = AMDGPU_FAMILY_NV;
2778795d0839SAlex Deucher 		break;
2779795d0839SAlex Deucher 	case IP_VERSION(10, 3, 1):
2780795d0839SAlex Deucher 		adev->family = AMDGPU_FAMILY_VGH;
27815e0f4c04SPerry Yuan 		adev->apu_flags |= AMD_APU_IS_VANGOGH;
2782795d0839SAlex Deucher 		break;
2783795d0839SAlex Deucher 	case IP_VERSION(10, 3, 3):
2784795d0839SAlex Deucher 		adev->family = AMDGPU_FAMILY_YC;
2785795d0839SAlex Deucher 		break;
2786874bfdfaSYifan Zhang 	case IP_VERSION(10, 3, 6):
2787874bfdfaSYifan Zhang 		adev->family = AMDGPU_FAMILY_GC_10_3_6;
2788874bfdfaSYifan Zhang 		break;
2789a65dbf7cSPrike Liang 	case IP_VERSION(10, 3, 7):
2790a65dbf7cSPrike Liang 		adev->family = AMDGPU_FAMILY_GC_10_3_7;
2791a65dbf7cSPrike Liang 		break;
27927d336142SLikun Gao 	case IP_VERSION(11, 0, 0):
279330ca5b2bSFlora Cui 	case IP_VERSION(11, 0, 2):
27942b569234SHawking Zhang 	case IP_VERSION(11, 0, 3):
27957d336142SLikun Gao 		adev->family = AMDGPU_FAMILY_GC_11_0_0;
27967d336142SLikun Gao 		break;
279723752714SHuang Rui 	case IP_VERSION(11, 0, 1):
279894ab7068SYifan Zhang 	case IP_VERSION(11, 0, 4):
279923752714SHuang Rui 		adev->family = AMDGPU_FAMILY_GC_11_0_1;
280023752714SHuang Rui 		break;
28012c8a7ca1SPrike Liang 	case IP_VERSION(11, 5, 0):
280293c5cc83SYifan Zhang 	case IP_VERSION(11, 5, 1):
280323c1ea02STim Huang 	case IP_VERSION(11, 5, 2):
2804b784faebSTim Huang 	case IP_VERSION(11, 5, 3):
28052c8a7ca1SPrike Liang 		adev->family = AMDGPU_FAMILY_GC_11_5_0;
28062c8a7ca1SPrike Liang 		break;
28075638b1cfSLikun Gao 	case IP_VERSION(12, 0, 0):
28085638b1cfSLikun Gao 	case IP_VERSION(12, 0, 1):
28095638b1cfSLikun Gao 		adev->family = AMDGPU_FAMILY_GC_12_0_0;
28105638b1cfSLikun Gao 		break;
2811795d0839SAlex Deucher 	default:
2812795d0839SAlex Deucher 		return -EINVAL;
2813795d0839SAlex Deucher 	}
2814795d0839SAlex Deucher 
28154e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
281621202129SAlex Deucher 	case IP_VERSION(9, 1, 0):
281721202129SAlex Deucher 	case IP_VERSION(9, 2, 2):
281821202129SAlex Deucher 	case IP_VERSION(9, 3, 0):
281921202129SAlex Deucher 	case IP_VERSION(10, 1, 3):
2820f9ed188dSLang Yu 	case IP_VERSION(10, 1, 4):
282121202129SAlex Deucher 	case IP_VERSION(10, 3, 1):
282221202129SAlex Deucher 	case IP_VERSION(10, 3, 3):
2823874bfdfaSYifan Zhang 	case IP_VERSION(10, 3, 6):
2824a65dbf7cSPrike Liang 	case IP_VERSION(10, 3, 7):
2825921173e2SAlex Deucher 	case IP_VERSION(11, 0, 1):
2826dd2d9c7fSYifan Zhang 	case IP_VERSION(11, 0, 4):
28272c8a7ca1SPrike Liang 	case IP_VERSION(11, 5, 0):
282893c5cc83SYifan Zhang 	case IP_VERSION(11, 5, 1):
282923c1ea02STim Huang 	case IP_VERSION(11, 5, 2):
2830b784faebSTim Huang 	case IP_VERSION(11, 5, 3):
283121202129SAlex Deucher 		adev->flags |= AMD_IS_APU;
283221202129SAlex Deucher 		break;
283321202129SAlex Deucher 	default:
283421202129SAlex Deucher 		break;
283521202129SAlex Deucher 	}
283621202129SAlex Deucher 
2837795d0839SAlex Deucher 	/* set NBIO version */
28384e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) {
2839d4c6e870SAlex Deucher 	case IP_VERSION(6, 1, 0):
2840d4c6e870SAlex Deucher 	case IP_VERSION(6, 2, 0):
2841d4c6e870SAlex Deucher 		adev->nbio.funcs = &nbio_v6_1_funcs;
2842d4c6e870SAlex Deucher 		adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg;
2843d4c6e870SAlex Deucher 		break;
2844d4c6e870SAlex Deucher 	case IP_VERSION(7, 0, 0):
2845d4c6e870SAlex Deucher 	case IP_VERSION(7, 0, 1):
2846d4c6e870SAlex Deucher 	case IP_VERSION(2, 5, 0):
2847d4c6e870SAlex Deucher 		adev->nbio.funcs = &nbio_v7_0_funcs;
2848d4c6e870SAlex Deucher 		adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg;
2849d4c6e870SAlex Deucher 		break;
2850d4c6e870SAlex Deucher 	case IP_VERSION(7, 4, 0):
2851d4c6e870SAlex Deucher 	case IP_VERSION(7, 4, 1):
2852df9feb1aSAlex Deucher 	case IP_VERSION(7, 4, 4):
2853df9feb1aSAlex Deucher 		adev->nbio.funcs = &nbio_v7_4_funcs;
2854912db6a5SAlex Deucher 		adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
2855df9feb1aSAlex Deucher 		break;
28565d55e1d0SHawking Zhang 	case IP_VERSION(7, 9, 0):
285737971df8SMangesh Gadre 	case IP_VERSION(7, 9, 1):
28585d55e1d0SHawking Zhang 		adev->nbio.funcs = &nbio_v7_9_funcs;
28595d55e1d0SHawking Zhang 		adev->nbio.hdp_flush_reg = &nbio_v7_9_hdp_flush_reg;
28605d55e1d0SHawking Zhang 		break;
2861d9d68334SPrike Liang 	case IP_VERSION(7, 11, 0):
2862bd377b12SYifan Zhang 	case IP_VERSION(7, 11, 1):
2863e659c9ebSTim Huang 	case IP_VERSION(7, 11, 2):
28645aea8716STim Huang 	case IP_VERSION(7, 11, 3):
2865d9d68334SPrike Liang 		adev->nbio.funcs = &nbio_v7_11_funcs;
2866d9d68334SPrike Liang 		adev->nbio.hdp_flush_reg = &nbio_v7_11_hdp_flush_reg;
2867d9d68334SPrike Liang 		break;
2868795d0839SAlex Deucher 	case IP_VERSION(7, 2, 0):
2869795d0839SAlex Deucher 	case IP_VERSION(7, 2, 1):
2870935ad3a7SYifan Zhang 	case IP_VERSION(7, 3, 0):
2871795d0839SAlex Deucher 	case IP_VERSION(7, 5, 0):
287201cbf049SPrike Liang 	case IP_VERSION(7, 5, 1):
2873795d0839SAlex Deucher 		adev->nbio.funcs = &nbio_v7_2_funcs;
2874795d0839SAlex Deucher 		adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg;
2875795d0839SAlex Deucher 		break;
2876795d0839SAlex Deucher 	case IP_VERSION(2, 1, 1):
2877795d0839SAlex Deucher 	case IP_VERSION(2, 3, 0):
2878795d0839SAlex Deucher 	case IP_VERSION(2, 3, 1):
2879795d0839SAlex Deucher 	case IP_VERSION(2, 3, 2):
2880795d0839SAlex Deucher 	case IP_VERSION(3, 3, 0):
2881795d0839SAlex Deucher 	case IP_VERSION(3, 3, 1):
2882795d0839SAlex Deucher 	case IP_VERSION(3, 3, 2):
2883795d0839SAlex Deucher 	case IP_VERSION(3, 3, 3):
2884795d0839SAlex Deucher 		adev->nbio.funcs = &nbio_v2_3_funcs;
288598a90f1fSAlex Deucher 		adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
2886795d0839SAlex Deucher 		break;
28872c0e7dddSLikun Gao 	case IP_VERSION(4, 3, 0):
28884dad9d63SFlora Cui 	case IP_VERSION(4, 3, 1):
2889119dc6c5SHorace Chen 		if (amdgpu_sriov_vf(adev))
2890119dc6c5SHorace Chen 			adev->nbio.funcs = &nbio_v4_3_sriov_funcs;
2891119dc6c5SHorace Chen 		else
28922c0e7dddSLikun Gao 			adev->nbio.funcs = &nbio_v4_3_funcs;
28932c0e7dddSLikun Gao 		adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
28942c0e7dddSLikun Gao 		break;
28950c1e5527SXiaojian Du 	case IP_VERSION(7, 7, 0):
28967308ceb4SYifan Zhang 	case IP_VERSION(7, 7, 1):
28970c1e5527SXiaojian Du 		adev->nbio.funcs = &nbio_v7_7_funcs;
28980c1e5527SXiaojian Du 		adev->nbio.hdp_flush_reg = &nbio_v7_7_hdp_flush_reg;
28990c1e5527SXiaojian Du 		break;
290079698b14SLikun Gao 	case IP_VERSION(6, 3, 1):
290179698b14SLikun Gao 		adev->nbio.funcs = &nbif_v6_3_1_funcs;
290279698b14SLikun Gao 		adev->nbio.hdp_flush_reg = &nbif_v6_3_1_hdp_flush_reg;
290379698b14SLikun Gao 		break;
2904795d0839SAlex Deucher 	default:
2905795d0839SAlex Deucher 		break;
2906795d0839SAlex Deucher 	}
2907795d0839SAlex Deucher 
29084e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, HDP_HWIP, 0)) {
2909d4c6e870SAlex Deucher 	case IP_VERSION(4, 0, 0):
2910d4c6e870SAlex Deucher 	case IP_VERSION(4, 0, 1):
2911d4c6e870SAlex Deucher 	case IP_VERSION(4, 1, 0):
2912d4c6e870SAlex Deucher 	case IP_VERSION(4, 1, 1):
291335bdf463SAlex Deucher 	case IP_VERSION(4, 1, 2):
2914d4c6e870SAlex Deucher 	case IP_VERSION(4, 2, 0):
2915d4c6e870SAlex Deucher 	case IP_VERSION(4, 2, 1):
2916d4c6e870SAlex Deucher 	case IP_VERSION(4, 4, 0):
29174688940aSHawking Zhang 	case IP_VERSION(4, 4, 2):
29183d1bb1a2SHawking Zhang 	case IP_VERSION(4, 4, 5):
2919d4c6e870SAlex Deucher 		adev->hdp.funcs = &hdp_v4_0_funcs;
2920d4c6e870SAlex Deucher 		break;
2921795d0839SAlex Deucher 	case IP_VERSION(5, 0, 0):
2922795d0839SAlex Deucher 	case IP_VERSION(5, 0, 1):
2923795d0839SAlex Deucher 	case IP_VERSION(5, 0, 2):
2924795d0839SAlex Deucher 	case IP_VERSION(5, 0, 3):
2925795d0839SAlex Deucher 	case IP_VERSION(5, 0, 4):
2926795d0839SAlex Deucher 	case IP_VERSION(5, 2, 0):
2927795d0839SAlex Deucher 		adev->hdp.funcs = &hdp_v5_0_funcs;
2928795d0839SAlex Deucher 		break;
29296e9e59e2SXiaojian Du 	case IP_VERSION(5, 2, 1):
29306e9e59e2SXiaojian Du 		adev->hdp.funcs = &hdp_v5_2_funcs;
29316e9e59e2SXiaojian Du 		break;
29321761e5efSLikun Gao 	case IP_VERSION(6, 0, 0):
29338742f5f1SFlora Cui 	case IP_VERSION(6, 0, 1):
29349b9a5e34SPrike Liang 	case IP_VERSION(6, 1, 0):
29351761e5efSLikun Gao 		adev->hdp.funcs = &hdp_v6_0_funcs;
29361761e5efSLikun Gao 		break;
2937ca46c259SLikun Gao 	case IP_VERSION(7, 0, 0):
2938ca46c259SLikun Gao 		adev->hdp.funcs = &hdp_v7_0_funcs;
2939ca46c259SLikun Gao 		break;
2940795d0839SAlex Deucher 	default:
2941795d0839SAlex Deucher 		break;
2942795d0839SAlex Deucher 	}
2943795d0839SAlex Deucher 
29444e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, DF_HWIP, 0)) {
2945d4c6e870SAlex Deucher 	case IP_VERSION(3, 6, 0):
2946d4c6e870SAlex Deucher 	case IP_VERSION(3, 6, 1):
2947d4c6e870SAlex Deucher 	case IP_VERSION(3, 6, 2):
2948d4c6e870SAlex Deucher 		adev->df.funcs = &df_v3_6_funcs;
2949d4c6e870SAlex Deucher 		break;
2950d4c6e870SAlex Deucher 	case IP_VERSION(2, 1, 0):
2951d4c6e870SAlex Deucher 	case IP_VERSION(2, 1, 1):
2952d4c6e870SAlex Deucher 	case IP_VERSION(2, 5, 0):
2953d4c6e870SAlex Deucher 	case IP_VERSION(3, 5, 1):
2954d4c6e870SAlex Deucher 	case IP_VERSION(3, 5, 2):
2955d4c6e870SAlex Deucher 		adev->df.funcs = &df_v1_7_funcs;
2956d4c6e870SAlex Deucher 		break;
2957e4f665deSCandice Li 	case IP_VERSION(4, 3, 0):
2958e4f665deSCandice Li 		adev->df.funcs = &df_v4_3_funcs;
2959e4f665deSCandice Li 		break;
29602cea7bb9STao Zhou 	case IP_VERSION(4, 6, 2):
29612cea7bb9STao Zhou 		adev->df.funcs = &df_v4_6_2_funcs;
29622cea7bb9STao Zhou 		break;
2963666f14caSDavid Belanger 	case IP_VERSION(4, 15, 0):
2964666f14caSDavid Belanger 	case IP_VERSION(4, 15, 1):
2965666f14caSDavid Belanger 		adev->df.funcs = &df_v4_15_funcs;
2966666f14caSDavid Belanger 		break;
2967d4c6e870SAlex Deucher 	default:
2968d4c6e870SAlex Deucher 		break;
2969d4c6e870SAlex Deucher 	}
2970d4c6e870SAlex Deucher 
29714e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, SMUIO_HWIP, 0)) {
2972d4c6e870SAlex Deucher 	case IP_VERSION(9, 0, 0):
2973d4c6e870SAlex Deucher 	case IP_VERSION(9, 0, 1):
2974d4c6e870SAlex Deucher 	case IP_VERSION(10, 0, 0):
2975d4c6e870SAlex Deucher 	case IP_VERSION(10, 0, 1):
2976d4c6e870SAlex Deucher 	case IP_VERSION(10, 0, 2):
2977d4c6e870SAlex Deucher 		adev->smuio.funcs = &smuio_v9_0_funcs;
2978d4c6e870SAlex Deucher 		break;
2979795d0839SAlex Deucher 	case IP_VERSION(11, 0, 0):
2980d4c6e870SAlex Deucher 	case IP_VERSION(11, 0, 2):
2981d4c6e870SAlex Deucher 	case IP_VERSION(11, 0, 3):
2982795d0839SAlex Deucher 	case IP_VERSION(11, 0, 4):
2983795d0839SAlex Deucher 	case IP_VERSION(11, 0, 7):
2984795d0839SAlex Deucher 	case IP_VERSION(11, 0, 8):
2985795d0839SAlex Deucher 		adev->smuio.funcs = &smuio_v11_0_funcs;
2986795d0839SAlex Deucher 		break;
2987795d0839SAlex Deucher 	case IP_VERSION(11, 0, 6):
2988795d0839SAlex Deucher 	case IP_VERSION(11, 0, 10):
2989795d0839SAlex Deucher 	case IP_VERSION(11, 0, 11):
2990795d0839SAlex Deucher 	case IP_VERSION(11, 5, 0):
299116a5a8feSYing Li 	case IP_VERSION(11, 5, 2):
2992795d0839SAlex Deucher 	case IP_VERSION(13, 0, 1):
29932019bf7cSPrike Liang 	case IP_VERSION(13, 0, 9):
2994ec3ca078SYifan Zhang 	case IP_VERSION(13, 0, 10):
2995795d0839SAlex Deucher 		adev->smuio.funcs = &smuio_v11_0_6_funcs;
2996795d0839SAlex Deucher 		break;
2997d4c6e870SAlex Deucher 	case IP_VERSION(13, 0, 2):
2998d4c6e870SAlex Deucher 		adev->smuio.funcs = &smuio_v13_0_funcs;
2999d4c6e870SAlex Deucher 		break;
30006b7ec18bSHawking Zhang 	case IP_VERSION(13, 0, 3):
30015caea7a5SMangesh Gadre 	case IP_VERSION(13, 0, 11):
30026b7ec18bSHawking Zhang 		adev->smuio.funcs = &smuio_v13_0_3_funcs;
300320997c04SShiwu Zhang 		if (adev->smuio.funcs->get_pkg_type(adev) == AMDGPU_PKG_TYPE_APU) {
300420997c04SShiwu Zhang 			adev->flags |= AMD_IS_APU;
300520997c04SShiwu Zhang 		}
30066b7ec18bSHawking Zhang 		break;
3007996ea859SHawking Zhang 	case IP_VERSION(13, 0, 6):
300886140844SChengming Gui 	case IP_VERSION(13, 0, 8):
3009eff7a442SPrike Liang 	case IP_VERSION(14, 0, 0):
3010c5ce1f1aSYifan Zhang 	case IP_VERSION(14, 0, 1):
3011996ea859SHawking Zhang 		adev->smuio.funcs = &smuio_v13_0_6_funcs;
3012996ea859SHawking Zhang 		break;
3013a61e2ce9SHawking Zhang 	case IP_VERSION(14, 0, 2):
3014a61e2ce9SHawking Zhang 		adev->smuio.funcs = &smuio_v14_0_2_funcs;
3015a61e2ce9SHawking Zhang 		break;
3016795d0839SAlex Deucher 	default:
3017795d0839SAlex Deucher 		break;
3018795d0839SAlex Deucher 	}
3019795d0839SAlex Deucher 
30204e8303cfSLijo Lazar 	switch (amdgpu_ip_version(adev, LSDMA_HWIP, 0)) {
302104de4afcSLikun Gao 	case IP_VERSION(6, 0, 0):
30220081bc07SYifan Zhang 	case IP_VERSION(6, 0, 1):
302374c9b2e7SLikun Gao 	case IP_VERSION(6, 0, 2):
3024de2b2ae3SHawking Zhang 	case IP_VERSION(6, 0, 3):
302504de4afcSLikun Gao 		adev->lsdma.funcs = &lsdma_v6_0_funcs;
302604de4afcSLikun Gao 		break;
302739df603dSLikun Gao 	case IP_VERSION(7, 0, 0):
302839df603dSLikun Gao 	case IP_VERSION(7, 0, 1):
302939df603dSLikun Gao 		adev->lsdma.funcs = &lsdma_v7_0_funcs;
303039df603dSLikun Gao 		break;
303104de4afcSLikun Gao 	default:
303204de4afcSLikun Gao 		break;
303304de4afcSLikun Gao 	}
303404de4afcSLikun Gao 
3035b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_common_ip_blocks(adev);
3036b05b9c59SAlex Deucher 	if (r)
3037b05b9c59SAlex Deucher 		return r;
3038795d0839SAlex Deucher 
3039b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_gmc_ip_blocks(adev);
3040b05b9c59SAlex Deucher 	if (r)
3041b05b9c59SAlex Deucher 		return r;
3042795d0839SAlex Deucher 
30436d46d419SAlex Deucher 	/* For SR-IOV, PSP needs to be initialized before IH */
30446d46d419SAlex Deucher 	if (amdgpu_sriov_vf(adev)) {
30456d46d419SAlex Deucher 		r = amdgpu_discovery_set_psp_ip_blocks(adev);
30466d46d419SAlex Deucher 		if (r)
30476d46d419SAlex Deucher 			return r;
30486d46d419SAlex Deucher 		r = amdgpu_discovery_set_ih_ip_blocks(adev);
30496d46d419SAlex Deucher 		if (r)
30506d46d419SAlex Deucher 			return r;
30516d46d419SAlex Deucher 	} else {
3052b05b9c59SAlex Deucher 		r = amdgpu_discovery_set_ih_ip_blocks(adev);
3053b05b9c59SAlex Deucher 		if (r)
3054b05b9c59SAlex Deucher 			return r;
3055b05b9c59SAlex Deucher 
3056b05b9c59SAlex Deucher 		if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
3057b05b9c59SAlex Deucher 			r = amdgpu_discovery_set_psp_ip_blocks(adev);
3058b05b9c59SAlex Deucher 			if (r)
3059b05b9c59SAlex Deucher 				return r;
3060795d0839SAlex Deucher 		}
30616d46d419SAlex Deucher 	}
3062795d0839SAlex Deucher 
3063795d0839SAlex Deucher 	if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
3064b05b9c59SAlex Deucher 		r = amdgpu_discovery_set_smu_ip_blocks(adev);
3065b05b9c59SAlex Deucher 		if (r)
3066b05b9c59SAlex Deucher 			return r;
3067795d0839SAlex Deucher 	}
3068795d0839SAlex Deucher 
3069b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_display_ip_blocks(adev);
3070b05b9c59SAlex Deucher 	if (r)
3071b05b9c59SAlex Deucher 		return r;
3072795d0839SAlex Deucher 
3073b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_gc_ip_blocks(adev);
3074b05b9c59SAlex Deucher 	if (r)
3075b05b9c59SAlex Deucher 		return r;
3076795d0839SAlex Deucher 
3077b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_sdma_ip_blocks(adev);
3078b05b9c59SAlex Deucher 	if (r)
3079b05b9c59SAlex Deucher 		return r;
3080795d0839SAlex Deucher 
3081a8bc8923SAlex Deucher 	if ((adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
3082a8bc8923SAlex Deucher 	     !amdgpu_sriov_vf(adev)) ||
3083a8bc8923SAlex Deucher 	    (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO && amdgpu_dpm == 1)) {
3084b05b9c59SAlex Deucher 		r = amdgpu_discovery_set_smu_ip_blocks(adev);
3085b05b9c59SAlex Deucher 		if (r)
3086b05b9c59SAlex Deucher 			return r;
3087795d0839SAlex Deucher 	}
3088795d0839SAlex Deucher 
3089b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_mm_ip_blocks(adev);
3090b05b9c59SAlex Deucher 	if (r)
3091b05b9c59SAlex Deucher 		return r;
3092795d0839SAlex Deucher 
3093b05b9c59SAlex Deucher 	r = amdgpu_discovery_set_mes_ip_blocks(adev);
3094b05b9c59SAlex Deucher 	if (r)
3095b05b9c59SAlex Deucher 		return r;
3096795d0839SAlex Deucher 
30973ee8fb70SLang Yu 	r = amdgpu_discovery_set_vpe_ip_blocks(adev);
30983ee8fb70SLang Yu 	if (r)
30993ee8fb70SLang Yu 		return r;
31003ee8fb70SLang Yu 
3101822f7808SLang Yu 	r = amdgpu_discovery_set_umsch_mm_ip_blocks(adev);
3102822f7808SLang Yu 	if (r)
3103822f7808SLang Yu 		return r;
3104822f7808SLang Yu 
3105d232584aSPratap Nirujogi 	r = amdgpu_discovery_set_isp_ip_blocks(adev);
3106d232584aSPratap Nirujogi 	if (r)
3107d232584aSPratap Nirujogi 		return r;
3108795d0839SAlex Deucher 	return 0;
3109795d0839SAlex Deucher }
3110795d0839SAlex Deucher 
3111