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