162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2018 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#include <linux/firmware.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include "amdgpu.h" 2762306a36Sopenharmony_ci#include "amdgpu_discovery.h" 2862306a36Sopenharmony_ci#include "soc15_hw_ip.h" 2962306a36Sopenharmony_ci#include "discovery.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#include "soc15.h" 3262306a36Sopenharmony_ci#include "gfx_v9_0.h" 3362306a36Sopenharmony_ci#include "gfx_v9_4_3.h" 3462306a36Sopenharmony_ci#include "gmc_v9_0.h" 3562306a36Sopenharmony_ci#include "df_v1_7.h" 3662306a36Sopenharmony_ci#include "df_v3_6.h" 3762306a36Sopenharmony_ci#include "df_v4_3.h" 3862306a36Sopenharmony_ci#include "nbio_v6_1.h" 3962306a36Sopenharmony_ci#include "nbio_v7_0.h" 4062306a36Sopenharmony_ci#include "nbio_v7_4.h" 4162306a36Sopenharmony_ci#include "nbio_v7_9.h" 4262306a36Sopenharmony_ci#include "hdp_v4_0.h" 4362306a36Sopenharmony_ci#include "vega10_ih.h" 4462306a36Sopenharmony_ci#include "vega20_ih.h" 4562306a36Sopenharmony_ci#include "sdma_v4_0.h" 4662306a36Sopenharmony_ci#include "sdma_v4_4_2.h" 4762306a36Sopenharmony_ci#include "uvd_v7_0.h" 4862306a36Sopenharmony_ci#include "vce_v4_0.h" 4962306a36Sopenharmony_ci#include "vcn_v1_0.h" 5062306a36Sopenharmony_ci#include "vcn_v2_5.h" 5162306a36Sopenharmony_ci#include "jpeg_v2_5.h" 5262306a36Sopenharmony_ci#include "smuio_v9_0.h" 5362306a36Sopenharmony_ci#include "gmc_v10_0.h" 5462306a36Sopenharmony_ci#include "gmc_v11_0.h" 5562306a36Sopenharmony_ci#include "gfxhub_v2_0.h" 5662306a36Sopenharmony_ci#include "mmhub_v2_0.h" 5762306a36Sopenharmony_ci#include "nbio_v2_3.h" 5862306a36Sopenharmony_ci#include "nbio_v4_3.h" 5962306a36Sopenharmony_ci#include "nbio_v7_2.h" 6062306a36Sopenharmony_ci#include "nbio_v7_7.h" 6162306a36Sopenharmony_ci#include "hdp_v5_0.h" 6262306a36Sopenharmony_ci#include "hdp_v5_2.h" 6362306a36Sopenharmony_ci#include "hdp_v6_0.h" 6462306a36Sopenharmony_ci#include "nv.h" 6562306a36Sopenharmony_ci#include "soc21.h" 6662306a36Sopenharmony_ci#include "navi10_ih.h" 6762306a36Sopenharmony_ci#include "ih_v6_0.h" 6862306a36Sopenharmony_ci#include "ih_v6_1.h" 6962306a36Sopenharmony_ci#include "gfx_v10_0.h" 7062306a36Sopenharmony_ci#include "gfx_v11_0.h" 7162306a36Sopenharmony_ci#include "sdma_v5_0.h" 7262306a36Sopenharmony_ci#include "sdma_v5_2.h" 7362306a36Sopenharmony_ci#include "sdma_v6_0.h" 7462306a36Sopenharmony_ci#include "lsdma_v6_0.h" 7562306a36Sopenharmony_ci#include "vcn_v2_0.h" 7662306a36Sopenharmony_ci#include "jpeg_v2_0.h" 7762306a36Sopenharmony_ci#include "vcn_v3_0.h" 7862306a36Sopenharmony_ci#include "jpeg_v3_0.h" 7962306a36Sopenharmony_ci#include "vcn_v4_0.h" 8062306a36Sopenharmony_ci#include "jpeg_v4_0.h" 8162306a36Sopenharmony_ci#include "vcn_v4_0_3.h" 8262306a36Sopenharmony_ci#include "jpeg_v4_0_3.h" 8362306a36Sopenharmony_ci#include "amdgpu_vkms.h" 8462306a36Sopenharmony_ci#include "mes_v10_1.h" 8562306a36Sopenharmony_ci#include "mes_v11_0.h" 8662306a36Sopenharmony_ci#include "smuio_v11_0.h" 8762306a36Sopenharmony_ci#include "smuio_v11_0_6.h" 8862306a36Sopenharmony_ci#include "smuio_v13_0.h" 8962306a36Sopenharmony_ci#include "smuio_v13_0_3.h" 9062306a36Sopenharmony_ci#include "smuio_v13_0_6.h" 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define FIRMWARE_IP_DISCOVERY "amdgpu/ip_discovery.bin" 9362306a36Sopenharmony_ciMODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#define mmRCC_CONFIG_MEMSIZE 0xde3 9662306a36Sopenharmony_ci#define mmMP0_SMN_C2PMSG_33 0x16061 9762306a36Sopenharmony_ci#define mmMM_INDEX 0x0 9862306a36Sopenharmony_ci#define mmMM_INDEX_HI 0x6 9962306a36Sopenharmony_ci#define mmMM_DATA 0x1 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic const char *hw_id_names[HW_ID_MAX] = { 10262306a36Sopenharmony_ci [MP1_HWID] = "MP1", 10362306a36Sopenharmony_ci [MP2_HWID] = "MP2", 10462306a36Sopenharmony_ci [THM_HWID] = "THM", 10562306a36Sopenharmony_ci [SMUIO_HWID] = "SMUIO", 10662306a36Sopenharmony_ci [FUSE_HWID] = "FUSE", 10762306a36Sopenharmony_ci [CLKA_HWID] = "CLKA", 10862306a36Sopenharmony_ci [PWR_HWID] = "PWR", 10962306a36Sopenharmony_ci [GC_HWID] = "GC", 11062306a36Sopenharmony_ci [UVD_HWID] = "UVD", 11162306a36Sopenharmony_ci [AUDIO_AZ_HWID] = "AUDIO_AZ", 11262306a36Sopenharmony_ci [ACP_HWID] = "ACP", 11362306a36Sopenharmony_ci [DCI_HWID] = "DCI", 11462306a36Sopenharmony_ci [DMU_HWID] = "DMU", 11562306a36Sopenharmony_ci [DCO_HWID] = "DCO", 11662306a36Sopenharmony_ci [DIO_HWID] = "DIO", 11762306a36Sopenharmony_ci [XDMA_HWID] = "XDMA", 11862306a36Sopenharmony_ci [DCEAZ_HWID] = "DCEAZ", 11962306a36Sopenharmony_ci [DAZ_HWID] = "DAZ", 12062306a36Sopenharmony_ci [SDPMUX_HWID] = "SDPMUX", 12162306a36Sopenharmony_ci [NTB_HWID] = "NTB", 12262306a36Sopenharmony_ci [IOHC_HWID] = "IOHC", 12362306a36Sopenharmony_ci [L2IMU_HWID] = "L2IMU", 12462306a36Sopenharmony_ci [VCE_HWID] = "VCE", 12562306a36Sopenharmony_ci [MMHUB_HWID] = "MMHUB", 12662306a36Sopenharmony_ci [ATHUB_HWID] = "ATHUB", 12762306a36Sopenharmony_ci [DBGU_NBIO_HWID] = "DBGU_NBIO", 12862306a36Sopenharmony_ci [DFX_HWID] = "DFX", 12962306a36Sopenharmony_ci [DBGU0_HWID] = "DBGU0", 13062306a36Sopenharmony_ci [DBGU1_HWID] = "DBGU1", 13162306a36Sopenharmony_ci [OSSSYS_HWID] = "OSSSYS", 13262306a36Sopenharmony_ci [HDP_HWID] = "HDP", 13362306a36Sopenharmony_ci [SDMA0_HWID] = "SDMA0", 13462306a36Sopenharmony_ci [SDMA1_HWID] = "SDMA1", 13562306a36Sopenharmony_ci [SDMA2_HWID] = "SDMA2", 13662306a36Sopenharmony_ci [SDMA3_HWID] = "SDMA3", 13762306a36Sopenharmony_ci [LSDMA_HWID] = "LSDMA", 13862306a36Sopenharmony_ci [ISP_HWID] = "ISP", 13962306a36Sopenharmony_ci [DBGU_IO_HWID] = "DBGU_IO", 14062306a36Sopenharmony_ci [DF_HWID] = "DF", 14162306a36Sopenharmony_ci [CLKB_HWID] = "CLKB", 14262306a36Sopenharmony_ci [FCH_HWID] = "FCH", 14362306a36Sopenharmony_ci [DFX_DAP_HWID] = "DFX_DAP", 14462306a36Sopenharmony_ci [L1IMU_PCIE_HWID] = "L1IMU_PCIE", 14562306a36Sopenharmony_ci [L1IMU_NBIF_HWID] = "L1IMU_NBIF", 14662306a36Sopenharmony_ci [L1IMU_IOAGR_HWID] = "L1IMU_IOAGR", 14762306a36Sopenharmony_ci [L1IMU3_HWID] = "L1IMU3", 14862306a36Sopenharmony_ci [L1IMU4_HWID] = "L1IMU4", 14962306a36Sopenharmony_ci [L1IMU5_HWID] = "L1IMU5", 15062306a36Sopenharmony_ci [L1IMU6_HWID] = "L1IMU6", 15162306a36Sopenharmony_ci [L1IMU7_HWID] = "L1IMU7", 15262306a36Sopenharmony_ci [L1IMU8_HWID] = "L1IMU8", 15362306a36Sopenharmony_ci [L1IMU9_HWID] = "L1IMU9", 15462306a36Sopenharmony_ci [L1IMU10_HWID] = "L1IMU10", 15562306a36Sopenharmony_ci [L1IMU11_HWID] = "L1IMU11", 15662306a36Sopenharmony_ci [L1IMU12_HWID] = "L1IMU12", 15762306a36Sopenharmony_ci [L1IMU13_HWID] = "L1IMU13", 15862306a36Sopenharmony_ci [L1IMU14_HWID] = "L1IMU14", 15962306a36Sopenharmony_ci [L1IMU15_HWID] = "L1IMU15", 16062306a36Sopenharmony_ci [WAFLC_HWID] = "WAFLC", 16162306a36Sopenharmony_ci [FCH_USB_PD_HWID] = "FCH_USB_PD", 16262306a36Sopenharmony_ci [PCIE_HWID] = "PCIE", 16362306a36Sopenharmony_ci [PCS_HWID] = "PCS", 16462306a36Sopenharmony_ci [DDCL_HWID] = "DDCL", 16562306a36Sopenharmony_ci [SST_HWID] = "SST", 16662306a36Sopenharmony_ci [IOAGR_HWID] = "IOAGR", 16762306a36Sopenharmony_ci [NBIF_HWID] = "NBIF", 16862306a36Sopenharmony_ci [IOAPIC_HWID] = "IOAPIC", 16962306a36Sopenharmony_ci [SYSTEMHUB_HWID] = "SYSTEMHUB", 17062306a36Sopenharmony_ci [NTBCCP_HWID] = "NTBCCP", 17162306a36Sopenharmony_ci [UMC_HWID] = "UMC", 17262306a36Sopenharmony_ci [SATA_HWID] = "SATA", 17362306a36Sopenharmony_ci [USB_HWID] = "USB", 17462306a36Sopenharmony_ci [CCXSEC_HWID] = "CCXSEC", 17562306a36Sopenharmony_ci [XGMI_HWID] = "XGMI", 17662306a36Sopenharmony_ci [XGBE_HWID] = "XGBE", 17762306a36Sopenharmony_ci [MP0_HWID] = "MP0", 17862306a36Sopenharmony_ci}; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cistatic int hw_id_map[MAX_HWIP] = { 18162306a36Sopenharmony_ci [GC_HWIP] = GC_HWID, 18262306a36Sopenharmony_ci [HDP_HWIP] = HDP_HWID, 18362306a36Sopenharmony_ci [SDMA0_HWIP] = SDMA0_HWID, 18462306a36Sopenharmony_ci [SDMA1_HWIP] = SDMA1_HWID, 18562306a36Sopenharmony_ci [SDMA2_HWIP] = SDMA2_HWID, 18662306a36Sopenharmony_ci [SDMA3_HWIP] = SDMA3_HWID, 18762306a36Sopenharmony_ci [LSDMA_HWIP] = LSDMA_HWID, 18862306a36Sopenharmony_ci [MMHUB_HWIP] = MMHUB_HWID, 18962306a36Sopenharmony_ci [ATHUB_HWIP] = ATHUB_HWID, 19062306a36Sopenharmony_ci [NBIO_HWIP] = NBIF_HWID, 19162306a36Sopenharmony_ci [MP0_HWIP] = MP0_HWID, 19262306a36Sopenharmony_ci [MP1_HWIP] = MP1_HWID, 19362306a36Sopenharmony_ci [UVD_HWIP] = UVD_HWID, 19462306a36Sopenharmony_ci [VCE_HWIP] = VCE_HWID, 19562306a36Sopenharmony_ci [DF_HWIP] = DF_HWID, 19662306a36Sopenharmony_ci [DCE_HWIP] = DMU_HWID, 19762306a36Sopenharmony_ci [OSSSYS_HWIP] = OSSSYS_HWID, 19862306a36Sopenharmony_ci [SMUIO_HWIP] = SMUIO_HWID, 19962306a36Sopenharmony_ci [PWR_HWIP] = PWR_HWID, 20062306a36Sopenharmony_ci [NBIF_HWIP] = NBIF_HWID, 20162306a36Sopenharmony_ci [THM_HWIP] = THM_HWID, 20262306a36Sopenharmony_ci [CLK_HWIP] = CLKA_HWID, 20362306a36Sopenharmony_ci [UMC_HWIP] = UMC_HWID, 20462306a36Sopenharmony_ci [XGMI_HWIP] = XGMI_HWID, 20562306a36Sopenharmony_ci [DCI_HWIP] = DCI_HWID, 20662306a36Sopenharmony_ci [PCIE_HWIP] = PCIE_HWID, 20762306a36Sopenharmony_ci}; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistatic int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev, uint8_t *binary) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci u64 tmr_offset, tmr_size, pos; 21262306a36Sopenharmony_ci void *discv_regn; 21362306a36Sopenharmony_ci int ret; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci ret = amdgpu_acpi_get_tmr_info(adev, &tmr_offset, &tmr_size); 21662306a36Sopenharmony_ci if (ret) 21762306a36Sopenharmony_ci return ret; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci pos = tmr_offset + tmr_size - DISCOVERY_TMR_OFFSET; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* This region is read-only and reserved from system use */ 22262306a36Sopenharmony_ci discv_regn = memremap(pos, adev->mman.discovery_tmr_size, MEMREMAP_WC); 22362306a36Sopenharmony_ci if (discv_regn) { 22462306a36Sopenharmony_ci memcpy(binary, discv_regn, adev->mman.discovery_tmr_size); 22562306a36Sopenharmony_ci memunmap(discv_regn); 22662306a36Sopenharmony_ci return 0; 22762306a36Sopenharmony_ci } 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci return -ENOENT; 23062306a36Sopenharmony_ci} 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cistatic int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev, 23362306a36Sopenharmony_ci uint8_t *binary) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci uint64_t vram_size; 23662306a36Sopenharmony_ci u32 msg; 23762306a36Sopenharmony_ci int i, ret = 0; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci /* It can take up to a second for IFWI init to complete on some dGPUs, 24062306a36Sopenharmony_ci * but generally it should be in the 60-100ms range. Normally this starts 24162306a36Sopenharmony_ci * as soon as the device gets power so by the time the OS loads this has long 24262306a36Sopenharmony_ci * completed. However, when a card is hotplugged via e.g., USB4, we need to 24362306a36Sopenharmony_ci * wait for this to complete. Once the C2PMSG is updated, we can 24462306a36Sopenharmony_ci * continue. 24562306a36Sopenharmony_ci */ 24662306a36Sopenharmony_ci if (dev_is_removable(&adev->pdev->dev)) { 24762306a36Sopenharmony_ci for (i = 0; i < 1000; i++) { 24862306a36Sopenharmony_ci msg = RREG32(mmMP0_SMN_C2PMSG_33); 24962306a36Sopenharmony_ci if (msg & 0x80000000) 25062306a36Sopenharmony_ci break; 25162306a36Sopenharmony_ci msleep(1); 25262306a36Sopenharmony_ci } 25362306a36Sopenharmony_ci } 25462306a36Sopenharmony_ci vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (vram_size) { 25762306a36Sopenharmony_ci uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET; 25862306a36Sopenharmony_ci amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 25962306a36Sopenharmony_ci adev->mman.discovery_tmr_size, false); 26062306a36Sopenharmony_ci } else { 26162306a36Sopenharmony_ci ret = amdgpu_discovery_read_binary_from_sysmem(adev, binary); 26262306a36Sopenharmony_ci } 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci return ret; 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_cistatic int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, uint8_t *binary) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci const struct firmware *fw; 27062306a36Sopenharmony_ci const char *fw_name; 27162306a36Sopenharmony_ci int r; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci switch (amdgpu_discovery) { 27462306a36Sopenharmony_ci case 2: 27562306a36Sopenharmony_ci fw_name = FIRMWARE_IP_DISCOVERY; 27662306a36Sopenharmony_ci break; 27762306a36Sopenharmony_ci default: 27862306a36Sopenharmony_ci dev_warn(adev->dev, "amdgpu_discovery is not set properly\n"); 27962306a36Sopenharmony_ci return -EINVAL; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci r = request_firmware(&fw, fw_name, adev->dev); 28362306a36Sopenharmony_ci if (r) { 28462306a36Sopenharmony_ci dev_err(adev->dev, "can't load firmware \"%s\"\n", 28562306a36Sopenharmony_ci fw_name); 28662306a36Sopenharmony_ci return r; 28762306a36Sopenharmony_ci } 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci memcpy((u8 *)binary, (u8 *)fw->data, fw->size); 29062306a36Sopenharmony_ci release_firmware(fw); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci return 0; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t size) 29662306a36Sopenharmony_ci{ 29762306a36Sopenharmony_ci uint16_t checksum = 0; 29862306a36Sopenharmony_ci int i; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci for (i = 0; i < size; i++) 30162306a36Sopenharmony_ci checksum += data[i]; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci return checksum; 30462306a36Sopenharmony_ci} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistatic inline bool amdgpu_discovery_verify_checksum(uint8_t *data, uint32_t size, 30762306a36Sopenharmony_ci uint16_t expected) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci return !!(amdgpu_discovery_calculate_checksum(data, size) == expected); 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_cistatic inline bool amdgpu_discovery_verify_binary_signature(uint8_t *binary) 31362306a36Sopenharmony_ci{ 31462306a36Sopenharmony_ci struct binary_header *bhdr; 31562306a36Sopenharmony_ci bhdr = (struct binary_header *)binary; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci return (le32_to_cpu(bhdr->binary_signature) == BINARY_SIGNATURE); 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic void amdgpu_discovery_harvest_config_quirk(struct amdgpu_device *adev) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci /* 32362306a36Sopenharmony_ci * So far, apply this quirk only on those Navy Flounder boards which 32462306a36Sopenharmony_ci * have a bad harvest table of VCN config. 32562306a36Sopenharmony_ci */ 32662306a36Sopenharmony_ci if ((adev->ip_versions[UVD_HWIP][1] == IP_VERSION(3, 0, 1)) && 32762306a36Sopenharmony_ci (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 2))) { 32862306a36Sopenharmony_ci switch (adev->pdev->revision) { 32962306a36Sopenharmony_ci case 0xC1: 33062306a36Sopenharmony_ci case 0xC2: 33162306a36Sopenharmony_ci case 0xC3: 33262306a36Sopenharmony_ci case 0xC5: 33362306a36Sopenharmony_ci case 0xC7: 33462306a36Sopenharmony_ci case 0xCF: 33562306a36Sopenharmony_ci case 0xDF: 33662306a36Sopenharmony_ci adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1; 33762306a36Sopenharmony_ci adev->vcn.inst_mask &= ~AMDGPU_VCN_HARVEST_VCN1; 33862306a36Sopenharmony_ci break; 33962306a36Sopenharmony_ci default: 34062306a36Sopenharmony_ci break; 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic int amdgpu_discovery_init(struct amdgpu_device *adev) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci struct table_info *info; 34862306a36Sopenharmony_ci struct binary_header *bhdr; 34962306a36Sopenharmony_ci uint16_t offset; 35062306a36Sopenharmony_ci uint16_t size; 35162306a36Sopenharmony_ci uint16_t checksum; 35262306a36Sopenharmony_ci int r; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci adev->mman.discovery_tmr_size = DISCOVERY_TMR_SIZE; 35562306a36Sopenharmony_ci adev->mman.discovery_bin = kzalloc(adev->mman.discovery_tmr_size, GFP_KERNEL); 35662306a36Sopenharmony_ci if (!adev->mman.discovery_bin) 35762306a36Sopenharmony_ci return -ENOMEM; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* Read from file if it is the preferred option */ 36062306a36Sopenharmony_ci if (amdgpu_discovery == 2) { 36162306a36Sopenharmony_ci dev_info(adev->dev, "use ip discovery information from file"); 36262306a36Sopenharmony_ci r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin); 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci if (r) { 36562306a36Sopenharmony_ci dev_err(adev->dev, "failed to read ip discovery binary from file\n"); 36662306a36Sopenharmony_ci r = -EINVAL; 36762306a36Sopenharmony_ci goto out; 36862306a36Sopenharmony_ci } 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci } else { 37162306a36Sopenharmony_ci r = amdgpu_discovery_read_binary_from_mem( 37262306a36Sopenharmony_ci adev, adev->mman.discovery_bin); 37362306a36Sopenharmony_ci if (r) 37462306a36Sopenharmony_ci goto out; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci /* check the ip discovery binary signature */ 37862306a36Sopenharmony_ci if (!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) { 37962306a36Sopenharmony_ci dev_err(adev->dev, 38062306a36Sopenharmony_ci "get invalid ip discovery binary signature\n"); 38162306a36Sopenharmony_ci r = -EINVAL; 38262306a36Sopenharmony_ci goto out; 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci offset = offsetof(struct binary_header, binary_checksum) + 38862306a36Sopenharmony_ci sizeof(bhdr->binary_checksum); 38962306a36Sopenharmony_ci size = le16_to_cpu(bhdr->binary_size) - offset; 39062306a36Sopenharmony_ci checksum = le16_to_cpu(bhdr->binary_checksum); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, 39362306a36Sopenharmony_ci size, checksum)) { 39462306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery binary checksum\n"); 39562306a36Sopenharmony_ci r = -EINVAL; 39662306a36Sopenharmony_ci goto out; 39762306a36Sopenharmony_ci } 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci info = &bhdr->table_list[IP_DISCOVERY]; 40062306a36Sopenharmony_ci offset = le16_to_cpu(info->offset); 40162306a36Sopenharmony_ci checksum = le16_to_cpu(info->checksum); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci if (offset) { 40462306a36Sopenharmony_ci struct ip_discovery_header *ihdr = 40562306a36Sopenharmony_ci (struct ip_discovery_header *)(adev->mman.discovery_bin + offset); 40662306a36Sopenharmony_ci if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) { 40762306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery data table signature\n"); 40862306a36Sopenharmony_ci r = -EINVAL; 40962306a36Sopenharmony_ci goto out; 41062306a36Sopenharmony_ci } 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, 41362306a36Sopenharmony_ci le16_to_cpu(ihdr->size), checksum)) { 41462306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery data table checksum\n"); 41562306a36Sopenharmony_ci r = -EINVAL; 41662306a36Sopenharmony_ci goto out; 41762306a36Sopenharmony_ci } 41862306a36Sopenharmony_ci } 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci info = &bhdr->table_list[GC]; 42162306a36Sopenharmony_ci offset = le16_to_cpu(info->offset); 42262306a36Sopenharmony_ci checksum = le16_to_cpu(info->checksum); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci if (offset) { 42562306a36Sopenharmony_ci struct gpu_info_header *ghdr = 42662306a36Sopenharmony_ci (struct gpu_info_header *)(adev->mman.discovery_bin + offset); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci if (le32_to_cpu(ghdr->table_id) != GC_TABLE_ID) { 42962306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery gc table id\n"); 43062306a36Sopenharmony_ci r = -EINVAL; 43162306a36Sopenharmony_ci goto out; 43262306a36Sopenharmony_ci } 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, 43562306a36Sopenharmony_ci le32_to_cpu(ghdr->size), checksum)) { 43662306a36Sopenharmony_ci dev_err(adev->dev, "invalid gc data table checksum\n"); 43762306a36Sopenharmony_ci r = -EINVAL; 43862306a36Sopenharmony_ci goto out; 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci } 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci info = &bhdr->table_list[HARVEST_INFO]; 44362306a36Sopenharmony_ci offset = le16_to_cpu(info->offset); 44462306a36Sopenharmony_ci checksum = le16_to_cpu(info->checksum); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci if (offset) { 44762306a36Sopenharmony_ci struct harvest_info_header *hhdr = 44862306a36Sopenharmony_ci (struct harvest_info_header *)(adev->mman.discovery_bin + offset); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci if (le32_to_cpu(hhdr->signature) != HARVEST_TABLE_SIGNATURE) { 45162306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery harvest table signature\n"); 45262306a36Sopenharmony_ci r = -EINVAL; 45362306a36Sopenharmony_ci goto out; 45462306a36Sopenharmony_ci } 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, 45762306a36Sopenharmony_ci sizeof(struct harvest_table), checksum)) { 45862306a36Sopenharmony_ci dev_err(adev->dev, "invalid harvest data table checksum\n"); 45962306a36Sopenharmony_ci r = -EINVAL; 46062306a36Sopenharmony_ci goto out; 46162306a36Sopenharmony_ci } 46262306a36Sopenharmony_ci } 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci info = &bhdr->table_list[VCN_INFO]; 46562306a36Sopenharmony_ci offset = le16_to_cpu(info->offset); 46662306a36Sopenharmony_ci checksum = le16_to_cpu(info->checksum); 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci if (offset) { 46962306a36Sopenharmony_ci struct vcn_info_header *vhdr = 47062306a36Sopenharmony_ci (struct vcn_info_header *)(adev->mman.discovery_bin + offset); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci if (le32_to_cpu(vhdr->table_id) != VCN_INFO_TABLE_ID) { 47362306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery vcn table id\n"); 47462306a36Sopenharmony_ci r = -EINVAL; 47562306a36Sopenharmony_ci goto out; 47662306a36Sopenharmony_ci } 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, 47962306a36Sopenharmony_ci le32_to_cpu(vhdr->size_bytes), checksum)) { 48062306a36Sopenharmony_ci dev_err(adev->dev, "invalid vcn data table checksum\n"); 48162306a36Sopenharmony_ci r = -EINVAL; 48262306a36Sopenharmony_ci goto out; 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci info = &bhdr->table_list[MALL_INFO]; 48762306a36Sopenharmony_ci offset = le16_to_cpu(info->offset); 48862306a36Sopenharmony_ci checksum = le16_to_cpu(info->checksum); 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci if (0 && offset) { 49162306a36Sopenharmony_ci struct mall_info_header *mhdr = 49262306a36Sopenharmony_ci (struct mall_info_header *)(adev->mman.discovery_bin + offset); 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci if (le32_to_cpu(mhdr->table_id) != MALL_INFO_TABLE_ID) { 49562306a36Sopenharmony_ci dev_err(adev->dev, "invalid ip discovery mall table id\n"); 49662306a36Sopenharmony_ci r = -EINVAL; 49762306a36Sopenharmony_ci goto out; 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, 50162306a36Sopenharmony_ci le32_to_cpu(mhdr->size_bytes), checksum)) { 50262306a36Sopenharmony_ci dev_err(adev->dev, "invalid mall data table checksum\n"); 50362306a36Sopenharmony_ci r = -EINVAL; 50462306a36Sopenharmony_ci goto out; 50562306a36Sopenharmony_ci } 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci return 0; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ciout: 51162306a36Sopenharmony_ci kfree(adev->mman.discovery_bin); 51262306a36Sopenharmony_ci adev->mman.discovery_bin = NULL; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci return r; 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_cistatic void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev); 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_civoid amdgpu_discovery_fini(struct amdgpu_device *adev) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci amdgpu_discovery_sysfs_fini(adev); 52262306a36Sopenharmony_ci kfree(adev->mman.discovery_bin); 52362306a36Sopenharmony_ci adev->mman.discovery_bin = NULL; 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic int amdgpu_discovery_validate_ip(const struct ip_v4 *ip) 52762306a36Sopenharmony_ci{ 52862306a36Sopenharmony_ci if (ip->instance_number >= HWIP_MAX_INSTANCE) { 52962306a36Sopenharmony_ci DRM_ERROR("Unexpected instance_number (%d) from ip discovery blob\n", 53062306a36Sopenharmony_ci ip->instance_number); 53162306a36Sopenharmony_ci return -EINVAL; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci if (le16_to_cpu(ip->hw_id) >= HW_ID_MAX) { 53462306a36Sopenharmony_ci DRM_ERROR("Unexpected hw_id (%d) from ip discovery blob\n", 53562306a36Sopenharmony_ci le16_to_cpu(ip->hw_id)); 53662306a36Sopenharmony_ci return -EINVAL; 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci return 0; 54062306a36Sopenharmony_ci} 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_cistatic void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev, 54362306a36Sopenharmony_ci uint32_t *vcn_harvest_count) 54462306a36Sopenharmony_ci{ 54562306a36Sopenharmony_ci struct binary_header *bhdr; 54662306a36Sopenharmony_ci struct ip_discovery_header *ihdr; 54762306a36Sopenharmony_ci struct die_header *dhdr; 54862306a36Sopenharmony_ci struct ip_v4 *ip; 54962306a36Sopenharmony_ci uint16_t die_offset, ip_offset, num_dies, num_ips; 55062306a36Sopenharmony_ci int i, j; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 55362306a36Sopenharmony_ci ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + 55462306a36Sopenharmony_ci le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset)); 55562306a36Sopenharmony_ci num_dies = le16_to_cpu(ihdr->num_dies); 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci /* scan harvest bit of all IP data structures */ 55862306a36Sopenharmony_ci for (i = 0; i < num_dies; i++) { 55962306a36Sopenharmony_ci die_offset = le16_to_cpu(ihdr->die_info[i].die_offset); 56062306a36Sopenharmony_ci dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset); 56162306a36Sopenharmony_ci num_ips = le16_to_cpu(dhdr->num_ips); 56262306a36Sopenharmony_ci ip_offset = die_offset + sizeof(*dhdr); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci for (j = 0; j < num_ips; j++) { 56562306a36Sopenharmony_ci ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset); 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci if (amdgpu_discovery_validate_ip(ip)) 56862306a36Sopenharmony_ci goto next_ip; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci if (le16_to_cpu(ip->variant) == 1) { 57162306a36Sopenharmony_ci switch (le16_to_cpu(ip->hw_id)) { 57262306a36Sopenharmony_ci case VCN_HWID: 57362306a36Sopenharmony_ci (*vcn_harvest_count)++; 57462306a36Sopenharmony_ci if (ip->instance_number == 0) { 57562306a36Sopenharmony_ci adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0; 57662306a36Sopenharmony_ci adev->vcn.inst_mask &= 57762306a36Sopenharmony_ci ~AMDGPU_VCN_HARVEST_VCN0; 57862306a36Sopenharmony_ci adev->jpeg.inst_mask &= 57962306a36Sopenharmony_ci ~AMDGPU_VCN_HARVEST_VCN0; 58062306a36Sopenharmony_ci } else { 58162306a36Sopenharmony_ci adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1; 58262306a36Sopenharmony_ci adev->vcn.inst_mask &= 58362306a36Sopenharmony_ci ~AMDGPU_VCN_HARVEST_VCN1; 58462306a36Sopenharmony_ci adev->jpeg.inst_mask &= 58562306a36Sopenharmony_ci ~AMDGPU_VCN_HARVEST_VCN1; 58662306a36Sopenharmony_ci } 58762306a36Sopenharmony_ci break; 58862306a36Sopenharmony_ci case DMU_HWID: 58962306a36Sopenharmony_ci adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK; 59062306a36Sopenharmony_ci break; 59162306a36Sopenharmony_ci default: 59262306a36Sopenharmony_ci break; 59362306a36Sopenharmony_ci } 59462306a36Sopenharmony_ci } 59562306a36Sopenharmony_cinext_ip: 59662306a36Sopenharmony_ci if (ihdr->base_addr_64_bit) 59762306a36Sopenharmony_ci ip_offset += struct_size(ip, base_address_64, ip->num_base_address); 59862306a36Sopenharmony_ci else 59962306a36Sopenharmony_ci ip_offset += struct_size(ip, base_address, ip->num_base_address); 60062306a36Sopenharmony_ci } 60162306a36Sopenharmony_ci } 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_cistatic void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev, 60562306a36Sopenharmony_ci uint32_t *vcn_harvest_count, 60662306a36Sopenharmony_ci uint32_t *umc_harvest_count) 60762306a36Sopenharmony_ci{ 60862306a36Sopenharmony_ci struct binary_header *bhdr; 60962306a36Sopenharmony_ci struct harvest_table *harvest_info; 61062306a36Sopenharmony_ci u16 offset; 61162306a36Sopenharmony_ci int i; 61262306a36Sopenharmony_ci uint32_t umc_harvest_config = 0; 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 61562306a36Sopenharmony_ci offset = le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset); 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci if (!offset) { 61862306a36Sopenharmony_ci dev_err(adev->dev, "invalid harvest table offset\n"); 61962306a36Sopenharmony_ci return; 62062306a36Sopenharmony_ci } 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci harvest_info = (struct harvest_table *)(adev->mman.discovery_bin + offset); 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci for (i = 0; i < 32; i++) { 62562306a36Sopenharmony_ci if (le16_to_cpu(harvest_info->list[i].hw_id) == 0) 62662306a36Sopenharmony_ci break; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci switch (le16_to_cpu(harvest_info->list[i].hw_id)) { 62962306a36Sopenharmony_ci case VCN_HWID: 63062306a36Sopenharmony_ci (*vcn_harvest_count)++; 63162306a36Sopenharmony_ci adev->vcn.harvest_config |= 63262306a36Sopenharmony_ci (1 << harvest_info->list[i].number_instance); 63362306a36Sopenharmony_ci adev->jpeg.harvest_config |= 63462306a36Sopenharmony_ci (1 << harvest_info->list[i].number_instance); 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci adev->vcn.inst_mask &= 63762306a36Sopenharmony_ci ~(1U << harvest_info->list[i].number_instance); 63862306a36Sopenharmony_ci adev->jpeg.inst_mask &= 63962306a36Sopenharmony_ci ~(1U << harvest_info->list[i].number_instance); 64062306a36Sopenharmony_ci break; 64162306a36Sopenharmony_ci case DMU_HWID: 64262306a36Sopenharmony_ci adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK; 64362306a36Sopenharmony_ci break; 64462306a36Sopenharmony_ci case UMC_HWID: 64562306a36Sopenharmony_ci umc_harvest_config |= 64662306a36Sopenharmony_ci 1 << (le16_to_cpu(harvest_info->list[i].number_instance)); 64762306a36Sopenharmony_ci (*umc_harvest_count)++; 64862306a36Sopenharmony_ci break; 64962306a36Sopenharmony_ci case GC_HWID: 65062306a36Sopenharmony_ci adev->gfx.xcc_mask &= 65162306a36Sopenharmony_ci ~(1U << harvest_info->list[i].number_instance); 65262306a36Sopenharmony_ci break; 65362306a36Sopenharmony_ci case SDMA0_HWID: 65462306a36Sopenharmony_ci adev->sdma.sdma_mask &= 65562306a36Sopenharmony_ci ~(1U << harvest_info->list[i].number_instance); 65662306a36Sopenharmony_ci break; 65762306a36Sopenharmony_ci default: 65862306a36Sopenharmony_ci break; 65962306a36Sopenharmony_ci } 66062306a36Sopenharmony_ci } 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci adev->umc.active_mask = ((1 << adev->umc.node_inst_num) - 1) & 66362306a36Sopenharmony_ci ~umc_harvest_config; 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci/* ================================================== */ 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_cistruct ip_hw_instance { 66962306a36Sopenharmony_ci struct kobject kobj; /* ip_discovery/die/#die/#hw_id/#instance/<attrs...> */ 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci int hw_id; 67262306a36Sopenharmony_ci u8 num_instance; 67362306a36Sopenharmony_ci u8 major, minor, revision; 67462306a36Sopenharmony_ci u8 harvest; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci int num_base_addresses; 67762306a36Sopenharmony_ci u32 base_addr[]; 67862306a36Sopenharmony_ci}; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_cistruct ip_hw_id { 68162306a36Sopenharmony_ci struct kset hw_id_kset; /* ip_discovery/die/#die/#hw_id/, contains ip_hw_instance */ 68262306a36Sopenharmony_ci int hw_id; 68362306a36Sopenharmony_ci}; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_cistruct ip_die_entry { 68662306a36Sopenharmony_ci struct kset ip_kset; /* ip_discovery/die/#die/, contains ip_hw_id */ 68762306a36Sopenharmony_ci u16 num_ips; 68862306a36Sopenharmony_ci}; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci/* -------------------------------------------------- */ 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_cistruct ip_hw_instance_attr { 69362306a36Sopenharmony_ci struct attribute attr; 69462306a36Sopenharmony_ci ssize_t (*show)(struct ip_hw_instance *ip_hw_instance, char *buf); 69562306a36Sopenharmony_ci}; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_cistatic ssize_t hw_id_show(struct ip_hw_instance *ip_hw_instance, char *buf) 69862306a36Sopenharmony_ci{ 69962306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_hw_instance->hw_id); 70062306a36Sopenharmony_ci} 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_cistatic ssize_t num_instance_show(struct ip_hw_instance *ip_hw_instance, char *buf) 70362306a36Sopenharmony_ci{ 70462306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_hw_instance->num_instance); 70562306a36Sopenharmony_ci} 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_cistatic ssize_t major_show(struct ip_hw_instance *ip_hw_instance, char *buf) 70862306a36Sopenharmony_ci{ 70962306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_hw_instance->major); 71062306a36Sopenharmony_ci} 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_cistatic ssize_t minor_show(struct ip_hw_instance *ip_hw_instance, char *buf) 71362306a36Sopenharmony_ci{ 71462306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_hw_instance->minor); 71562306a36Sopenharmony_ci} 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_cistatic ssize_t revision_show(struct ip_hw_instance *ip_hw_instance, char *buf) 71862306a36Sopenharmony_ci{ 71962306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_hw_instance->revision); 72062306a36Sopenharmony_ci} 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_cistatic ssize_t harvest_show(struct ip_hw_instance *ip_hw_instance, char *buf) 72362306a36Sopenharmony_ci{ 72462306a36Sopenharmony_ci return sysfs_emit(buf, "0x%01X\n", ip_hw_instance->harvest); 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_cistatic ssize_t num_base_addresses_show(struct ip_hw_instance *ip_hw_instance, char *buf) 72862306a36Sopenharmony_ci{ 72962306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_hw_instance->num_base_addresses); 73062306a36Sopenharmony_ci} 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_cistatic ssize_t base_addr_show(struct ip_hw_instance *ip_hw_instance, char *buf) 73362306a36Sopenharmony_ci{ 73462306a36Sopenharmony_ci ssize_t res, at; 73562306a36Sopenharmony_ci int ii; 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci for (res = at = ii = 0; ii < ip_hw_instance->num_base_addresses; ii++) { 73862306a36Sopenharmony_ci /* Here we satisfy the condition that, at + size <= PAGE_SIZE. 73962306a36Sopenharmony_ci */ 74062306a36Sopenharmony_ci if (at + 12 > PAGE_SIZE) 74162306a36Sopenharmony_ci break; 74262306a36Sopenharmony_ci res = sysfs_emit_at(buf, at, "0x%08X\n", 74362306a36Sopenharmony_ci ip_hw_instance->base_addr[ii]); 74462306a36Sopenharmony_ci if (res <= 0) 74562306a36Sopenharmony_ci break; 74662306a36Sopenharmony_ci at += res; 74762306a36Sopenharmony_ci } 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci return res < 0 ? res : at; 75062306a36Sopenharmony_ci} 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_cistatic struct ip_hw_instance_attr ip_hw_attr[] = { 75362306a36Sopenharmony_ci __ATTR_RO(hw_id), 75462306a36Sopenharmony_ci __ATTR_RO(num_instance), 75562306a36Sopenharmony_ci __ATTR_RO(major), 75662306a36Sopenharmony_ci __ATTR_RO(minor), 75762306a36Sopenharmony_ci __ATTR_RO(revision), 75862306a36Sopenharmony_ci __ATTR_RO(harvest), 75962306a36Sopenharmony_ci __ATTR_RO(num_base_addresses), 76062306a36Sopenharmony_ci __ATTR_RO(base_addr), 76162306a36Sopenharmony_ci}; 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_cistatic struct attribute *ip_hw_instance_attrs[ARRAY_SIZE(ip_hw_attr) + 1]; 76462306a36Sopenharmony_ciATTRIBUTE_GROUPS(ip_hw_instance); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci#define to_ip_hw_instance(x) container_of(x, struct ip_hw_instance, kobj) 76762306a36Sopenharmony_ci#define to_ip_hw_instance_attr(x) container_of(x, struct ip_hw_instance_attr, attr) 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_cistatic ssize_t ip_hw_instance_attr_show(struct kobject *kobj, 77062306a36Sopenharmony_ci struct attribute *attr, 77162306a36Sopenharmony_ci char *buf) 77262306a36Sopenharmony_ci{ 77362306a36Sopenharmony_ci struct ip_hw_instance *ip_hw_instance = to_ip_hw_instance(kobj); 77462306a36Sopenharmony_ci struct ip_hw_instance_attr *ip_hw_attr = to_ip_hw_instance_attr(attr); 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci if (!ip_hw_attr->show) 77762306a36Sopenharmony_ci return -EIO; 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci return ip_hw_attr->show(ip_hw_instance, buf); 78062306a36Sopenharmony_ci} 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_cistatic const struct sysfs_ops ip_hw_instance_sysfs_ops = { 78362306a36Sopenharmony_ci .show = ip_hw_instance_attr_show, 78462306a36Sopenharmony_ci}; 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_cistatic void ip_hw_instance_release(struct kobject *kobj) 78762306a36Sopenharmony_ci{ 78862306a36Sopenharmony_ci struct ip_hw_instance *ip_hw_instance = to_ip_hw_instance(kobj); 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci kfree(ip_hw_instance); 79162306a36Sopenharmony_ci} 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_cistatic const struct kobj_type ip_hw_instance_ktype = { 79462306a36Sopenharmony_ci .release = ip_hw_instance_release, 79562306a36Sopenharmony_ci .sysfs_ops = &ip_hw_instance_sysfs_ops, 79662306a36Sopenharmony_ci .default_groups = ip_hw_instance_groups, 79762306a36Sopenharmony_ci}; 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci/* -------------------------------------------------- */ 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci#define to_ip_hw_id(x) container_of(to_kset(x), struct ip_hw_id, hw_id_kset) 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_cistatic void ip_hw_id_release(struct kobject *kobj) 80462306a36Sopenharmony_ci{ 80562306a36Sopenharmony_ci struct ip_hw_id *ip_hw_id = to_ip_hw_id(kobj); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci if (!list_empty(&ip_hw_id->hw_id_kset.list)) 80862306a36Sopenharmony_ci DRM_ERROR("ip_hw_id->hw_id_kset is not empty"); 80962306a36Sopenharmony_ci kfree(ip_hw_id); 81062306a36Sopenharmony_ci} 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_cistatic const struct kobj_type ip_hw_id_ktype = { 81362306a36Sopenharmony_ci .release = ip_hw_id_release, 81462306a36Sopenharmony_ci .sysfs_ops = &kobj_sysfs_ops, 81562306a36Sopenharmony_ci}; 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci/* -------------------------------------------------- */ 81862306a36Sopenharmony_ci 81962306a36Sopenharmony_cistatic void die_kobj_release(struct kobject *kobj); 82062306a36Sopenharmony_cistatic void ip_disc_release(struct kobject *kobj); 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_cistruct ip_die_entry_attribute { 82362306a36Sopenharmony_ci struct attribute attr; 82462306a36Sopenharmony_ci ssize_t (*show)(struct ip_die_entry *ip_die_entry, char *buf); 82562306a36Sopenharmony_ci}; 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci#define to_ip_die_entry_attr(x) container_of(x, struct ip_die_entry_attribute, attr) 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_cistatic ssize_t num_ips_show(struct ip_die_entry *ip_die_entry, char *buf) 83062306a36Sopenharmony_ci{ 83162306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", ip_die_entry->num_ips); 83262306a36Sopenharmony_ci} 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci/* If there are more ip_die_entry attrs, other than the number of IPs, 83562306a36Sopenharmony_ci * we can make this intro an array of attrs, and then initialize 83662306a36Sopenharmony_ci * ip_die_entry_attrs in a loop. 83762306a36Sopenharmony_ci */ 83862306a36Sopenharmony_cistatic struct ip_die_entry_attribute num_ips_attr = 83962306a36Sopenharmony_ci __ATTR_RO(num_ips); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_cistatic struct attribute *ip_die_entry_attrs[] = { 84262306a36Sopenharmony_ci &num_ips_attr.attr, 84362306a36Sopenharmony_ci NULL, 84462306a36Sopenharmony_ci}; 84562306a36Sopenharmony_ciATTRIBUTE_GROUPS(ip_die_entry); /* ip_die_entry_groups */ 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci#define to_ip_die_entry(x) container_of(to_kset(x), struct ip_die_entry, ip_kset) 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_cistatic ssize_t ip_die_entry_attr_show(struct kobject *kobj, 85062306a36Sopenharmony_ci struct attribute *attr, 85162306a36Sopenharmony_ci char *buf) 85262306a36Sopenharmony_ci{ 85362306a36Sopenharmony_ci struct ip_die_entry_attribute *ip_die_entry_attr = to_ip_die_entry_attr(attr); 85462306a36Sopenharmony_ci struct ip_die_entry *ip_die_entry = to_ip_die_entry(kobj); 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci if (!ip_die_entry_attr->show) 85762306a36Sopenharmony_ci return -EIO; 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci return ip_die_entry_attr->show(ip_die_entry, buf); 86062306a36Sopenharmony_ci} 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_cistatic void ip_die_entry_release(struct kobject *kobj) 86362306a36Sopenharmony_ci{ 86462306a36Sopenharmony_ci struct ip_die_entry *ip_die_entry = to_ip_die_entry(kobj); 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci if (!list_empty(&ip_die_entry->ip_kset.list)) 86762306a36Sopenharmony_ci DRM_ERROR("ip_die_entry->ip_kset is not empty"); 86862306a36Sopenharmony_ci kfree(ip_die_entry); 86962306a36Sopenharmony_ci} 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_cistatic const struct sysfs_ops ip_die_entry_sysfs_ops = { 87262306a36Sopenharmony_ci .show = ip_die_entry_attr_show, 87362306a36Sopenharmony_ci}; 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic const struct kobj_type ip_die_entry_ktype = { 87662306a36Sopenharmony_ci .release = ip_die_entry_release, 87762306a36Sopenharmony_ci .sysfs_ops = &ip_die_entry_sysfs_ops, 87862306a36Sopenharmony_ci .default_groups = ip_die_entry_groups, 87962306a36Sopenharmony_ci}; 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_cistatic const struct kobj_type die_kobj_ktype = { 88262306a36Sopenharmony_ci .release = die_kobj_release, 88362306a36Sopenharmony_ci .sysfs_ops = &kobj_sysfs_ops, 88462306a36Sopenharmony_ci}; 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_cistatic const struct kobj_type ip_discovery_ktype = { 88762306a36Sopenharmony_ci .release = ip_disc_release, 88862306a36Sopenharmony_ci .sysfs_ops = &kobj_sysfs_ops, 88962306a36Sopenharmony_ci}; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_cistruct ip_discovery_top { 89262306a36Sopenharmony_ci struct kobject kobj; /* ip_discovery/ */ 89362306a36Sopenharmony_ci struct kset die_kset; /* ip_discovery/die/, contains ip_die_entry */ 89462306a36Sopenharmony_ci struct amdgpu_device *adev; 89562306a36Sopenharmony_ci}; 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_cistatic void die_kobj_release(struct kobject *kobj) 89862306a36Sopenharmony_ci{ 89962306a36Sopenharmony_ci struct ip_discovery_top *ip_top = container_of(to_kset(kobj), 90062306a36Sopenharmony_ci struct ip_discovery_top, 90162306a36Sopenharmony_ci die_kset); 90262306a36Sopenharmony_ci if (!list_empty(&ip_top->die_kset.list)) 90362306a36Sopenharmony_ci DRM_ERROR("ip_top->die_kset is not empty"); 90462306a36Sopenharmony_ci} 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_cistatic void ip_disc_release(struct kobject *kobj) 90762306a36Sopenharmony_ci{ 90862306a36Sopenharmony_ci struct ip_discovery_top *ip_top = container_of(kobj, struct ip_discovery_top, 90962306a36Sopenharmony_ci kobj); 91062306a36Sopenharmony_ci struct amdgpu_device *adev = ip_top->adev; 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci adev->ip_top = NULL; 91362306a36Sopenharmony_ci kfree(ip_top); 91462306a36Sopenharmony_ci} 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_cistatic uint8_t amdgpu_discovery_get_harvest_info(struct amdgpu_device *adev, 91762306a36Sopenharmony_ci uint16_t hw_id, uint8_t inst) 91862306a36Sopenharmony_ci{ 91962306a36Sopenharmony_ci uint8_t harvest = 0; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci /* Until a uniform way is figured, get mask based on hwid */ 92262306a36Sopenharmony_ci switch (hw_id) { 92362306a36Sopenharmony_ci case VCN_HWID: 92462306a36Sopenharmony_ci harvest = ((1 << inst) & adev->vcn.inst_mask) == 0; 92562306a36Sopenharmony_ci break; 92662306a36Sopenharmony_ci case DMU_HWID: 92762306a36Sopenharmony_ci if (adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK) 92862306a36Sopenharmony_ci harvest = 0x1; 92962306a36Sopenharmony_ci break; 93062306a36Sopenharmony_ci case UMC_HWID: 93162306a36Sopenharmony_ci /* TODO: It needs another parsing; for now, ignore.*/ 93262306a36Sopenharmony_ci break; 93362306a36Sopenharmony_ci case GC_HWID: 93462306a36Sopenharmony_ci harvest = ((1 << inst) & adev->gfx.xcc_mask) == 0; 93562306a36Sopenharmony_ci break; 93662306a36Sopenharmony_ci case SDMA0_HWID: 93762306a36Sopenharmony_ci harvest = ((1 << inst) & adev->sdma.sdma_mask) == 0; 93862306a36Sopenharmony_ci break; 93962306a36Sopenharmony_ci default: 94062306a36Sopenharmony_ci break; 94162306a36Sopenharmony_ci } 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci return harvest; 94462306a36Sopenharmony_ci} 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_cistatic int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev, 94762306a36Sopenharmony_ci struct ip_die_entry *ip_die_entry, 94862306a36Sopenharmony_ci const size_t _ip_offset, const int num_ips, 94962306a36Sopenharmony_ci bool reg_base_64) 95062306a36Sopenharmony_ci{ 95162306a36Sopenharmony_ci int ii, jj, kk, res; 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_ci DRM_DEBUG("num_ips:%d", num_ips); 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci /* Find all IPs of a given HW ID, and add their instance to 95662306a36Sopenharmony_ci * #die/#hw_id/#instance/<attributes> 95762306a36Sopenharmony_ci */ 95862306a36Sopenharmony_ci for (ii = 0; ii < HW_ID_MAX; ii++) { 95962306a36Sopenharmony_ci struct ip_hw_id *ip_hw_id = NULL; 96062306a36Sopenharmony_ci size_t ip_offset = _ip_offset; 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_ci for (jj = 0; jj < num_ips; jj++) { 96362306a36Sopenharmony_ci struct ip_v4 *ip; 96462306a36Sopenharmony_ci struct ip_hw_instance *ip_hw_instance; 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset); 96762306a36Sopenharmony_ci if (amdgpu_discovery_validate_ip(ip) || 96862306a36Sopenharmony_ci le16_to_cpu(ip->hw_id) != ii) 96962306a36Sopenharmony_ci goto next_ip; 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci DRM_DEBUG("match:%d @ ip_offset:%zu", ii, ip_offset); 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci /* We have a hw_id match; register the hw 97462306a36Sopenharmony_ci * block if not yet registered. 97562306a36Sopenharmony_ci */ 97662306a36Sopenharmony_ci if (!ip_hw_id) { 97762306a36Sopenharmony_ci ip_hw_id = kzalloc(sizeof(*ip_hw_id), GFP_KERNEL); 97862306a36Sopenharmony_ci if (!ip_hw_id) 97962306a36Sopenharmony_ci return -ENOMEM; 98062306a36Sopenharmony_ci ip_hw_id->hw_id = ii; 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_ci kobject_set_name(&ip_hw_id->hw_id_kset.kobj, "%d", ii); 98362306a36Sopenharmony_ci ip_hw_id->hw_id_kset.kobj.kset = &ip_die_entry->ip_kset; 98462306a36Sopenharmony_ci ip_hw_id->hw_id_kset.kobj.ktype = &ip_hw_id_ktype; 98562306a36Sopenharmony_ci res = kset_register(&ip_hw_id->hw_id_kset); 98662306a36Sopenharmony_ci if (res) { 98762306a36Sopenharmony_ci DRM_ERROR("Couldn't register ip_hw_id kset"); 98862306a36Sopenharmony_ci kfree(ip_hw_id); 98962306a36Sopenharmony_ci return res; 99062306a36Sopenharmony_ci } 99162306a36Sopenharmony_ci if (hw_id_names[ii]) { 99262306a36Sopenharmony_ci res = sysfs_create_link(&ip_die_entry->ip_kset.kobj, 99362306a36Sopenharmony_ci &ip_hw_id->hw_id_kset.kobj, 99462306a36Sopenharmony_ci hw_id_names[ii]); 99562306a36Sopenharmony_ci if (res) { 99662306a36Sopenharmony_ci DRM_ERROR("Couldn't create IP link %s in IP Die:%s\n", 99762306a36Sopenharmony_ci hw_id_names[ii], 99862306a36Sopenharmony_ci kobject_name(&ip_die_entry->ip_kset.kobj)); 99962306a36Sopenharmony_ci } 100062306a36Sopenharmony_ci } 100162306a36Sopenharmony_ci } 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci /* Now register its instance. 100462306a36Sopenharmony_ci */ 100562306a36Sopenharmony_ci ip_hw_instance = kzalloc(struct_size(ip_hw_instance, 100662306a36Sopenharmony_ci base_addr, 100762306a36Sopenharmony_ci ip->num_base_address), 100862306a36Sopenharmony_ci GFP_KERNEL); 100962306a36Sopenharmony_ci if (!ip_hw_instance) { 101062306a36Sopenharmony_ci DRM_ERROR("no memory for ip_hw_instance"); 101162306a36Sopenharmony_ci return -ENOMEM; 101262306a36Sopenharmony_ci } 101362306a36Sopenharmony_ci ip_hw_instance->hw_id = le16_to_cpu(ip->hw_id); /* == ii */ 101462306a36Sopenharmony_ci ip_hw_instance->num_instance = ip->instance_number; 101562306a36Sopenharmony_ci ip_hw_instance->major = ip->major; 101662306a36Sopenharmony_ci ip_hw_instance->minor = ip->minor; 101762306a36Sopenharmony_ci ip_hw_instance->revision = ip->revision; 101862306a36Sopenharmony_ci ip_hw_instance->harvest = 101962306a36Sopenharmony_ci amdgpu_discovery_get_harvest_info( 102062306a36Sopenharmony_ci adev, ip_hw_instance->hw_id, 102162306a36Sopenharmony_ci ip_hw_instance->num_instance); 102262306a36Sopenharmony_ci ip_hw_instance->num_base_addresses = ip->num_base_address; 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ci for (kk = 0; kk < ip_hw_instance->num_base_addresses; kk++) { 102562306a36Sopenharmony_ci if (reg_base_64) 102662306a36Sopenharmony_ci ip_hw_instance->base_addr[kk] = 102762306a36Sopenharmony_ci lower_32_bits(le64_to_cpu(ip->base_address_64[kk])) & 0x3FFFFFFF; 102862306a36Sopenharmony_ci else 102962306a36Sopenharmony_ci ip_hw_instance->base_addr[kk] = ip->base_address[kk]; 103062306a36Sopenharmony_ci } 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci kobject_init(&ip_hw_instance->kobj, &ip_hw_instance_ktype); 103362306a36Sopenharmony_ci ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset; 103462306a36Sopenharmony_ci res = kobject_add(&ip_hw_instance->kobj, NULL, 103562306a36Sopenharmony_ci "%d", ip_hw_instance->num_instance); 103662306a36Sopenharmony_cinext_ip: 103762306a36Sopenharmony_ci if (reg_base_64) 103862306a36Sopenharmony_ci ip_offset += struct_size(ip, base_address_64, 103962306a36Sopenharmony_ci ip->num_base_address); 104062306a36Sopenharmony_ci else 104162306a36Sopenharmony_ci ip_offset += struct_size(ip, base_address, 104262306a36Sopenharmony_ci ip->num_base_address); 104362306a36Sopenharmony_ci } 104462306a36Sopenharmony_ci } 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci return 0; 104762306a36Sopenharmony_ci} 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_cistatic int amdgpu_discovery_sysfs_recurse(struct amdgpu_device *adev) 105062306a36Sopenharmony_ci{ 105162306a36Sopenharmony_ci struct binary_header *bhdr; 105262306a36Sopenharmony_ci struct ip_discovery_header *ihdr; 105362306a36Sopenharmony_ci struct die_header *dhdr; 105462306a36Sopenharmony_ci struct kset *die_kset = &adev->ip_top->die_kset; 105562306a36Sopenharmony_ci u16 num_dies, die_offset, num_ips; 105662306a36Sopenharmony_ci size_t ip_offset; 105762306a36Sopenharmony_ci int ii, res; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 106062306a36Sopenharmony_ci ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + 106162306a36Sopenharmony_ci le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset)); 106262306a36Sopenharmony_ci num_dies = le16_to_cpu(ihdr->num_dies); 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci DRM_DEBUG("number of dies: %d\n", num_dies); 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci for (ii = 0; ii < num_dies; ii++) { 106762306a36Sopenharmony_ci struct ip_die_entry *ip_die_entry; 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ci die_offset = le16_to_cpu(ihdr->die_info[ii].die_offset); 107062306a36Sopenharmony_ci dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset); 107162306a36Sopenharmony_ci num_ips = le16_to_cpu(dhdr->num_ips); 107262306a36Sopenharmony_ci ip_offset = die_offset + sizeof(*dhdr); 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci /* Add the die to the kset. 107562306a36Sopenharmony_ci * 107662306a36Sopenharmony_ci * dhdr->die_id == ii, which was checked in 107762306a36Sopenharmony_ci * amdgpu_discovery_reg_base_init(). 107862306a36Sopenharmony_ci */ 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci ip_die_entry = kzalloc(sizeof(*ip_die_entry), GFP_KERNEL); 108162306a36Sopenharmony_ci if (!ip_die_entry) 108262306a36Sopenharmony_ci return -ENOMEM; 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci ip_die_entry->num_ips = num_ips; 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci kobject_set_name(&ip_die_entry->ip_kset.kobj, "%d", le16_to_cpu(dhdr->die_id)); 108762306a36Sopenharmony_ci ip_die_entry->ip_kset.kobj.kset = die_kset; 108862306a36Sopenharmony_ci ip_die_entry->ip_kset.kobj.ktype = &ip_die_entry_ktype; 108962306a36Sopenharmony_ci res = kset_register(&ip_die_entry->ip_kset); 109062306a36Sopenharmony_ci if (res) { 109162306a36Sopenharmony_ci DRM_ERROR("Couldn't register ip_die_entry kset"); 109262306a36Sopenharmony_ci kfree(ip_die_entry); 109362306a36Sopenharmony_ci return res; 109462306a36Sopenharmony_ci } 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci amdgpu_discovery_sysfs_ips(adev, ip_die_entry, ip_offset, num_ips, !!ihdr->base_addr_64_bit); 109762306a36Sopenharmony_ci } 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci return 0; 110062306a36Sopenharmony_ci} 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_cistatic int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev) 110362306a36Sopenharmony_ci{ 110462306a36Sopenharmony_ci struct kset *die_kset; 110562306a36Sopenharmony_ci int res, ii; 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci if (!adev->mman.discovery_bin) 110862306a36Sopenharmony_ci return -EINVAL; 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci adev->ip_top = kzalloc(sizeof(*adev->ip_top), GFP_KERNEL); 111162306a36Sopenharmony_ci if (!adev->ip_top) 111262306a36Sopenharmony_ci return -ENOMEM; 111362306a36Sopenharmony_ci 111462306a36Sopenharmony_ci adev->ip_top->adev = adev; 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_ci res = kobject_init_and_add(&adev->ip_top->kobj, &ip_discovery_ktype, 111762306a36Sopenharmony_ci &adev->dev->kobj, "ip_discovery"); 111862306a36Sopenharmony_ci if (res) { 111962306a36Sopenharmony_ci DRM_ERROR("Couldn't init and add ip_discovery/"); 112062306a36Sopenharmony_ci goto Err; 112162306a36Sopenharmony_ci } 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci die_kset = &adev->ip_top->die_kset; 112462306a36Sopenharmony_ci kobject_set_name(&die_kset->kobj, "%s", "die"); 112562306a36Sopenharmony_ci die_kset->kobj.parent = &adev->ip_top->kobj; 112662306a36Sopenharmony_ci die_kset->kobj.ktype = &die_kobj_ktype; 112762306a36Sopenharmony_ci res = kset_register(&adev->ip_top->die_kset); 112862306a36Sopenharmony_ci if (res) { 112962306a36Sopenharmony_ci DRM_ERROR("Couldn't register die_kset"); 113062306a36Sopenharmony_ci goto Err; 113162306a36Sopenharmony_ci } 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci for (ii = 0; ii < ARRAY_SIZE(ip_hw_attr); ii++) 113462306a36Sopenharmony_ci ip_hw_instance_attrs[ii] = &ip_hw_attr[ii].attr; 113562306a36Sopenharmony_ci ip_hw_instance_attrs[ii] = NULL; 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci res = amdgpu_discovery_sysfs_recurse(adev); 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci return res; 114062306a36Sopenharmony_ciErr: 114162306a36Sopenharmony_ci kobject_put(&adev->ip_top->kobj); 114262306a36Sopenharmony_ci return res; 114362306a36Sopenharmony_ci} 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci/* -------------------------------------------------- */ 114662306a36Sopenharmony_ci 114762306a36Sopenharmony_ci#define list_to_kobj(el) container_of(el, struct kobject, entry) 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_cistatic void amdgpu_discovery_sysfs_ip_hw_free(struct ip_hw_id *ip_hw_id) 115062306a36Sopenharmony_ci{ 115162306a36Sopenharmony_ci struct list_head *el, *tmp; 115262306a36Sopenharmony_ci struct kset *hw_id_kset; 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci hw_id_kset = &ip_hw_id->hw_id_kset; 115562306a36Sopenharmony_ci spin_lock(&hw_id_kset->list_lock); 115662306a36Sopenharmony_ci list_for_each_prev_safe(el, tmp, &hw_id_kset->list) { 115762306a36Sopenharmony_ci list_del_init(el); 115862306a36Sopenharmony_ci spin_unlock(&hw_id_kset->list_lock); 115962306a36Sopenharmony_ci /* kobject is embedded in ip_hw_instance */ 116062306a36Sopenharmony_ci kobject_put(list_to_kobj(el)); 116162306a36Sopenharmony_ci spin_lock(&hw_id_kset->list_lock); 116262306a36Sopenharmony_ci } 116362306a36Sopenharmony_ci spin_unlock(&hw_id_kset->list_lock); 116462306a36Sopenharmony_ci kobject_put(&ip_hw_id->hw_id_kset.kobj); 116562306a36Sopenharmony_ci} 116662306a36Sopenharmony_ci 116762306a36Sopenharmony_cistatic void amdgpu_discovery_sysfs_die_free(struct ip_die_entry *ip_die_entry) 116862306a36Sopenharmony_ci{ 116962306a36Sopenharmony_ci struct list_head *el, *tmp; 117062306a36Sopenharmony_ci struct kset *ip_kset; 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci ip_kset = &ip_die_entry->ip_kset; 117362306a36Sopenharmony_ci spin_lock(&ip_kset->list_lock); 117462306a36Sopenharmony_ci list_for_each_prev_safe(el, tmp, &ip_kset->list) { 117562306a36Sopenharmony_ci list_del_init(el); 117662306a36Sopenharmony_ci spin_unlock(&ip_kset->list_lock); 117762306a36Sopenharmony_ci amdgpu_discovery_sysfs_ip_hw_free(to_ip_hw_id(list_to_kobj(el))); 117862306a36Sopenharmony_ci spin_lock(&ip_kset->list_lock); 117962306a36Sopenharmony_ci } 118062306a36Sopenharmony_ci spin_unlock(&ip_kset->list_lock); 118162306a36Sopenharmony_ci kobject_put(&ip_die_entry->ip_kset.kobj); 118262306a36Sopenharmony_ci} 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_cistatic void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev) 118562306a36Sopenharmony_ci{ 118662306a36Sopenharmony_ci struct list_head *el, *tmp; 118762306a36Sopenharmony_ci struct kset *die_kset; 118862306a36Sopenharmony_ci 118962306a36Sopenharmony_ci die_kset = &adev->ip_top->die_kset; 119062306a36Sopenharmony_ci spin_lock(&die_kset->list_lock); 119162306a36Sopenharmony_ci list_for_each_prev_safe(el, tmp, &die_kset->list) { 119262306a36Sopenharmony_ci list_del_init(el); 119362306a36Sopenharmony_ci spin_unlock(&die_kset->list_lock); 119462306a36Sopenharmony_ci amdgpu_discovery_sysfs_die_free(to_ip_die_entry(list_to_kobj(el))); 119562306a36Sopenharmony_ci spin_lock(&die_kset->list_lock); 119662306a36Sopenharmony_ci } 119762306a36Sopenharmony_ci spin_unlock(&die_kset->list_lock); 119862306a36Sopenharmony_ci kobject_put(&adev->ip_top->die_kset.kobj); 119962306a36Sopenharmony_ci kobject_put(&adev->ip_top->kobj); 120062306a36Sopenharmony_ci} 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci/* ================================================== */ 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_cistatic int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) 120562306a36Sopenharmony_ci{ 120662306a36Sopenharmony_ci struct binary_header *bhdr; 120762306a36Sopenharmony_ci struct ip_discovery_header *ihdr; 120862306a36Sopenharmony_ci struct die_header *dhdr; 120962306a36Sopenharmony_ci struct ip_v4 *ip; 121062306a36Sopenharmony_ci uint16_t die_offset; 121162306a36Sopenharmony_ci uint16_t ip_offset; 121262306a36Sopenharmony_ci uint16_t num_dies; 121362306a36Sopenharmony_ci uint16_t num_ips; 121462306a36Sopenharmony_ci uint8_t num_base_address; 121562306a36Sopenharmony_ci int hw_ip; 121662306a36Sopenharmony_ci int i, j, k; 121762306a36Sopenharmony_ci int r; 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci r = amdgpu_discovery_init(adev); 122062306a36Sopenharmony_ci if (r) { 122162306a36Sopenharmony_ci DRM_ERROR("amdgpu_discovery_init failed\n"); 122262306a36Sopenharmony_ci return r; 122362306a36Sopenharmony_ci } 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci adev->gfx.xcc_mask = 0; 122662306a36Sopenharmony_ci adev->sdma.sdma_mask = 0; 122762306a36Sopenharmony_ci adev->vcn.inst_mask = 0; 122862306a36Sopenharmony_ci adev->jpeg.inst_mask = 0; 122962306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 123062306a36Sopenharmony_ci ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + 123162306a36Sopenharmony_ci le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset)); 123262306a36Sopenharmony_ci num_dies = le16_to_cpu(ihdr->num_dies); 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci DRM_DEBUG("number of dies: %d\n", num_dies); 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci for (i = 0; i < num_dies; i++) { 123762306a36Sopenharmony_ci die_offset = le16_to_cpu(ihdr->die_info[i].die_offset); 123862306a36Sopenharmony_ci dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset); 123962306a36Sopenharmony_ci num_ips = le16_to_cpu(dhdr->num_ips); 124062306a36Sopenharmony_ci ip_offset = die_offset + sizeof(*dhdr); 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_ci if (le16_to_cpu(dhdr->die_id) != i) { 124362306a36Sopenharmony_ci DRM_ERROR("invalid die id %d, expected %d\n", 124462306a36Sopenharmony_ci le16_to_cpu(dhdr->die_id), i); 124562306a36Sopenharmony_ci return -EINVAL; 124662306a36Sopenharmony_ci } 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci DRM_DEBUG("number of hardware IPs on die%d: %d\n", 124962306a36Sopenharmony_ci le16_to_cpu(dhdr->die_id), num_ips); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci for (j = 0; j < num_ips; j++) { 125262306a36Sopenharmony_ci ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset); 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci if (amdgpu_discovery_validate_ip(ip)) 125562306a36Sopenharmony_ci goto next_ip; 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_ci num_base_address = ip->num_base_address; 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_ci DRM_DEBUG("%s(%d) #%d v%d.%d.%d:\n", 126062306a36Sopenharmony_ci hw_id_names[le16_to_cpu(ip->hw_id)], 126162306a36Sopenharmony_ci le16_to_cpu(ip->hw_id), 126262306a36Sopenharmony_ci ip->instance_number, 126362306a36Sopenharmony_ci ip->major, ip->minor, 126462306a36Sopenharmony_ci ip->revision); 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci if (le16_to_cpu(ip->hw_id) == VCN_HWID) { 126762306a36Sopenharmony_ci /* Bit [5:0]: original revision value 126862306a36Sopenharmony_ci * Bit [7:6]: en/decode capability: 126962306a36Sopenharmony_ci * 0b00 : VCN function normally 127062306a36Sopenharmony_ci * 0b10 : encode is disabled 127162306a36Sopenharmony_ci * 0b01 : decode is disabled 127262306a36Sopenharmony_ci */ 127362306a36Sopenharmony_ci if (adev->vcn.num_vcn_inst < 127462306a36Sopenharmony_ci AMDGPU_MAX_VCN_INSTANCES) { 127562306a36Sopenharmony_ci adev->vcn.vcn_config[adev->vcn.num_vcn_inst] = 127662306a36Sopenharmony_ci ip->revision & 0xc0; 127762306a36Sopenharmony_ci adev->vcn.num_vcn_inst++; 127862306a36Sopenharmony_ci adev->vcn.inst_mask |= 127962306a36Sopenharmony_ci (1U << ip->instance_number); 128062306a36Sopenharmony_ci adev->jpeg.inst_mask |= 128162306a36Sopenharmony_ci (1U << ip->instance_number); 128262306a36Sopenharmony_ci } else { 128362306a36Sopenharmony_ci dev_err(adev->dev, "Too many VCN instances: %d vs %d\n", 128462306a36Sopenharmony_ci adev->vcn.num_vcn_inst + 1, 128562306a36Sopenharmony_ci AMDGPU_MAX_VCN_INSTANCES); 128662306a36Sopenharmony_ci } 128762306a36Sopenharmony_ci ip->revision &= ~0xc0; 128862306a36Sopenharmony_ci } 128962306a36Sopenharmony_ci if (le16_to_cpu(ip->hw_id) == SDMA0_HWID || 129062306a36Sopenharmony_ci le16_to_cpu(ip->hw_id) == SDMA1_HWID || 129162306a36Sopenharmony_ci le16_to_cpu(ip->hw_id) == SDMA2_HWID || 129262306a36Sopenharmony_ci le16_to_cpu(ip->hw_id) == SDMA3_HWID) { 129362306a36Sopenharmony_ci if (adev->sdma.num_instances < 129462306a36Sopenharmony_ci AMDGPU_MAX_SDMA_INSTANCES) { 129562306a36Sopenharmony_ci adev->sdma.num_instances++; 129662306a36Sopenharmony_ci adev->sdma.sdma_mask |= 129762306a36Sopenharmony_ci (1U << ip->instance_number); 129862306a36Sopenharmony_ci } else { 129962306a36Sopenharmony_ci dev_err(adev->dev, "Too many SDMA instances: %d vs %d\n", 130062306a36Sopenharmony_ci adev->sdma.num_instances + 1, 130162306a36Sopenharmony_ci AMDGPU_MAX_SDMA_INSTANCES); 130262306a36Sopenharmony_ci } 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_ci if (le16_to_cpu(ip->hw_id) == UMC_HWID) { 130662306a36Sopenharmony_ci adev->gmc.num_umc++; 130762306a36Sopenharmony_ci adev->umc.node_inst_num++; 130862306a36Sopenharmony_ci } 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci if (le16_to_cpu(ip->hw_id) == GC_HWID) 131162306a36Sopenharmony_ci adev->gfx.xcc_mask |= 131262306a36Sopenharmony_ci (1U << ip->instance_number); 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci for (k = 0; k < num_base_address; k++) { 131562306a36Sopenharmony_ci /* 131662306a36Sopenharmony_ci * convert the endianness of base addresses in place, 131762306a36Sopenharmony_ci * so that we don't need to convert them when accessing adev->reg_offset. 131862306a36Sopenharmony_ci */ 131962306a36Sopenharmony_ci if (ihdr->base_addr_64_bit) 132062306a36Sopenharmony_ci /* Truncate the 64bit base address from ip discovery 132162306a36Sopenharmony_ci * and only store lower 32bit ip base in reg_offset[]. 132262306a36Sopenharmony_ci * Bits > 32 follows ASIC specific format, thus just 132362306a36Sopenharmony_ci * discard them and handle it within specific ASIC. 132462306a36Sopenharmony_ci * By this way reg_offset[] and related helpers can 132562306a36Sopenharmony_ci * stay unchanged. 132662306a36Sopenharmony_ci * The base address is in dwords, thus clear the 132762306a36Sopenharmony_ci * highest 2 bits to store. 132862306a36Sopenharmony_ci */ 132962306a36Sopenharmony_ci ip->base_address[k] = 133062306a36Sopenharmony_ci lower_32_bits(le64_to_cpu(ip->base_address_64[k])) & 0x3FFFFFFF; 133162306a36Sopenharmony_ci else 133262306a36Sopenharmony_ci ip->base_address[k] = le32_to_cpu(ip->base_address[k]); 133362306a36Sopenharmony_ci DRM_DEBUG("\t0x%08x\n", ip->base_address[k]); 133462306a36Sopenharmony_ci } 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci for (hw_ip = 0; hw_ip < MAX_HWIP; hw_ip++) { 133762306a36Sopenharmony_ci if (hw_id_map[hw_ip] == le16_to_cpu(ip->hw_id) && 133862306a36Sopenharmony_ci hw_id_map[hw_ip] != 0) { 133962306a36Sopenharmony_ci DRM_DEBUG("set register base offset for %s\n", 134062306a36Sopenharmony_ci hw_id_names[le16_to_cpu(ip->hw_id)]); 134162306a36Sopenharmony_ci adev->reg_offset[hw_ip][ip->instance_number] = 134262306a36Sopenharmony_ci ip->base_address; 134362306a36Sopenharmony_ci /* Instance support is somewhat inconsistent. 134462306a36Sopenharmony_ci * SDMA is a good example. Sienna cichlid has 4 total 134562306a36Sopenharmony_ci * SDMA instances, each enumerated separately (HWIDs 134662306a36Sopenharmony_ci * 42, 43, 68, 69). Arcturus has 8 total SDMA instances, 134762306a36Sopenharmony_ci * but they are enumerated as multiple instances of the 134862306a36Sopenharmony_ci * same HWIDs (4x HWID 42, 4x HWID 43). UMC is another 134962306a36Sopenharmony_ci * example. On most chips there are multiple instances 135062306a36Sopenharmony_ci * with the same HWID. 135162306a36Sopenharmony_ci */ 135262306a36Sopenharmony_ci adev->ip_versions[hw_ip][ip->instance_number] = 135362306a36Sopenharmony_ci IP_VERSION(ip->major, ip->minor, ip->revision); 135462306a36Sopenharmony_ci } 135562306a36Sopenharmony_ci } 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_cinext_ip: 135862306a36Sopenharmony_ci if (ihdr->base_addr_64_bit) 135962306a36Sopenharmony_ci ip_offset += struct_size(ip, base_address_64, ip->num_base_address); 136062306a36Sopenharmony_ci else 136162306a36Sopenharmony_ci ip_offset += struct_size(ip, base_address, ip->num_base_address); 136262306a36Sopenharmony_ci } 136362306a36Sopenharmony_ci } 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_ci return 0; 136662306a36Sopenharmony_ci} 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_cistatic void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev) 136962306a36Sopenharmony_ci{ 137062306a36Sopenharmony_ci int vcn_harvest_count = 0; 137162306a36Sopenharmony_ci int umc_harvest_count = 0; 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci /* 137462306a36Sopenharmony_ci * Harvest table does not fit Navi1x and legacy GPUs, 137562306a36Sopenharmony_ci * so read harvest bit per IP data structure to set 137662306a36Sopenharmony_ci * harvest configuration. 137762306a36Sopenharmony_ci */ 137862306a36Sopenharmony_ci if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 2, 0) && 137962306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 3)) { 138062306a36Sopenharmony_ci if ((adev->pdev->device == 0x731E && 138162306a36Sopenharmony_ci (adev->pdev->revision == 0xC6 || 138262306a36Sopenharmony_ci adev->pdev->revision == 0xC7)) || 138362306a36Sopenharmony_ci (adev->pdev->device == 0x7340 && 138462306a36Sopenharmony_ci adev->pdev->revision == 0xC9) || 138562306a36Sopenharmony_ci (adev->pdev->device == 0x7360 && 138662306a36Sopenharmony_ci adev->pdev->revision == 0xC7)) 138762306a36Sopenharmony_ci amdgpu_discovery_read_harvest_bit_per_ip(adev, 138862306a36Sopenharmony_ci &vcn_harvest_count); 138962306a36Sopenharmony_ci } else { 139062306a36Sopenharmony_ci amdgpu_discovery_read_from_harvest_table(adev, 139162306a36Sopenharmony_ci &vcn_harvest_count, 139262306a36Sopenharmony_ci &umc_harvest_count); 139362306a36Sopenharmony_ci } 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci amdgpu_discovery_harvest_config_quirk(adev); 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_ci if (vcn_harvest_count == adev->vcn.num_vcn_inst) { 139862306a36Sopenharmony_ci adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK; 139962306a36Sopenharmony_ci adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK; 140062306a36Sopenharmony_ci } 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci if (umc_harvest_count < adev->gmc.num_umc) { 140362306a36Sopenharmony_ci adev->gmc.num_umc -= umc_harvest_count; 140462306a36Sopenharmony_ci } 140562306a36Sopenharmony_ci} 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ciunion gc_info { 140862306a36Sopenharmony_ci struct gc_info_v1_0 v1; 140962306a36Sopenharmony_ci struct gc_info_v1_1 v1_1; 141062306a36Sopenharmony_ci struct gc_info_v1_2 v1_2; 141162306a36Sopenharmony_ci struct gc_info_v2_0 v2; 141262306a36Sopenharmony_ci struct gc_info_v2_1 v2_1; 141362306a36Sopenharmony_ci}; 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_cistatic int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev) 141662306a36Sopenharmony_ci{ 141762306a36Sopenharmony_ci struct binary_header *bhdr; 141862306a36Sopenharmony_ci union gc_info *gc_info; 141962306a36Sopenharmony_ci u16 offset; 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci if (!adev->mman.discovery_bin) { 142262306a36Sopenharmony_ci DRM_ERROR("ip discovery uninitialized\n"); 142362306a36Sopenharmony_ci return -EINVAL; 142462306a36Sopenharmony_ci } 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 142762306a36Sopenharmony_ci offset = le16_to_cpu(bhdr->table_list[GC].offset); 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_ci if (!offset) 143062306a36Sopenharmony_ci return 0; 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci gc_info = (union gc_info *)(adev->mman.discovery_bin + offset); 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci switch (le16_to_cpu(gc_info->v1.header.version_major)) { 143562306a36Sopenharmony_ci case 1: 143662306a36Sopenharmony_ci adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->v1.gc_num_se); 143762306a36Sopenharmony_ci adev->gfx.config.max_cu_per_sh = 2 * (le32_to_cpu(gc_info->v1.gc_num_wgp0_per_sa) + 143862306a36Sopenharmony_ci le32_to_cpu(gc_info->v1.gc_num_wgp1_per_sa)); 143962306a36Sopenharmony_ci adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->v1.gc_num_sa_per_se); 144062306a36Sopenharmony_ci adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->v1.gc_num_rb_per_se); 144162306a36Sopenharmony_ci adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->v1.gc_num_gl2c); 144262306a36Sopenharmony_ci adev->gfx.config.max_gprs = le32_to_cpu(gc_info->v1.gc_num_gprs); 144362306a36Sopenharmony_ci adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->v1.gc_num_max_gs_thds); 144462306a36Sopenharmony_ci adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->v1.gc_gs_table_depth); 144562306a36Sopenharmony_ci adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->v1.gc_gsprim_buff_depth); 144662306a36Sopenharmony_ci adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->v1.gc_double_offchip_lds_buffer); 144762306a36Sopenharmony_ci adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->v1.gc_wave_size); 144862306a36Sopenharmony_ci adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->v1.gc_max_waves_per_simd); 144962306a36Sopenharmony_ci adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->v1.gc_max_scratch_slots_per_cu); 145062306a36Sopenharmony_ci adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->v1.gc_lds_size); 145162306a36Sopenharmony_ci adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v1.gc_num_sc_per_se) / 145262306a36Sopenharmony_ci le32_to_cpu(gc_info->v1.gc_num_sa_per_se); 145362306a36Sopenharmony_ci adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v1.gc_num_packer_per_sc); 145462306a36Sopenharmony_ci if (gc_info->v1.header.version_minor >= 1) { 145562306a36Sopenharmony_ci adev->gfx.config.gc_num_tcp_per_sa = le32_to_cpu(gc_info->v1_1.gc_num_tcp_per_sa); 145662306a36Sopenharmony_ci adev->gfx.config.gc_num_sdp_interface = le32_to_cpu(gc_info->v1_1.gc_num_sdp_interface); 145762306a36Sopenharmony_ci adev->gfx.config.gc_num_tcps = le32_to_cpu(gc_info->v1_1.gc_num_tcps); 145862306a36Sopenharmony_ci } 145962306a36Sopenharmony_ci if (gc_info->v1.header.version_minor >= 2) { 146062306a36Sopenharmony_ci adev->gfx.config.gc_num_tcp_per_wpg = le32_to_cpu(gc_info->v1_2.gc_num_tcp_per_wpg); 146162306a36Sopenharmony_ci adev->gfx.config.gc_tcp_l1_size = le32_to_cpu(gc_info->v1_2.gc_tcp_l1_size); 146262306a36Sopenharmony_ci adev->gfx.config.gc_num_sqc_per_wgp = le32_to_cpu(gc_info->v1_2.gc_num_sqc_per_wgp); 146362306a36Sopenharmony_ci adev->gfx.config.gc_l1_instruction_cache_size_per_sqc = le32_to_cpu(gc_info->v1_2.gc_l1_instruction_cache_size_per_sqc); 146462306a36Sopenharmony_ci adev->gfx.config.gc_l1_data_cache_size_per_sqc = le32_to_cpu(gc_info->v1_2.gc_l1_data_cache_size_per_sqc); 146562306a36Sopenharmony_ci adev->gfx.config.gc_gl1c_per_sa = le32_to_cpu(gc_info->v1_2.gc_gl1c_per_sa); 146662306a36Sopenharmony_ci adev->gfx.config.gc_gl1c_size_per_instance = le32_to_cpu(gc_info->v1_2.gc_gl1c_size_per_instance); 146762306a36Sopenharmony_ci adev->gfx.config.gc_gl2c_per_gpu = le32_to_cpu(gc_info->v1_2.gc_gl2c_per_gpu); 146862306a36Sopenharmony_ci } 146962306a36Sopenharmony_ci break; 147062306a36Sopenharmony_ci case 2: 147162306a36Sopenharmony_ci adev->gfx.config.max_shader_engines = le32_to_cpu(gc_info->v2.gc_num_se); 147262306a36Sopenharmony_ci adev->gfx.config.max_cu_per_sh = le32_to_cpu(gc_info->v2.gc_num_cu_per_sh); 147362306a36Sopenharmony_ci adev->gfx.config.max_sh_per_se = le32_to_cpu(gc_info->v2.gc_num_sh_per_se); 147462306a36Sopenharmony_ci adev->gfx.config.max_backends_per_se = le32_to_cpu(gc_info->v2.gc_num_rb_per_se); 147562306a36Sopenharmony_ci adev->gfx.config.max_texture_channel_caches = le32_to_cpu(gc_info->v2.gc_num_tccs); 147662306a36Sopenharmony_ci adev->gfx.config.max_gprs = le32_to_cpu(gc_info->v2.gc_num_gprs); 147762306a36Sopenharmony_ci adev->gfx.config.max_gs_threads = le32_to_cpu(gc_info->v2.gc_num_max_gs_thds); 147862306a36Sopenharmony_ci adev->gfx.config.gs_vgt_table_depth = le32_to_cpu(gc_info->v2.gc_gs_table_depth); 147962306a36Sopenharmony_ci adev->gfx.config.gs_prim_buffer_depth = le32_to_cpu(gc_info->v2.gc_gsprim_buff_depth); 148062306a36Sopenharmony_ci adev->gfx.config.double_offchip_lds_buf = le32_to_cpu(gc_info->v2.gc_double_offchip_lds_buffer); 148162306a36Sopenharmony_ci adev->gfx.cu_info.wave_front_size = le32_to_cpu(gc_info->v2.gc_wave_size); 148262306a36Sopenharmony_ci adev->gfx.cu_info.max_waves_per_simd = le32_to_cpu(gc_info->v2.gc_max_waves_per_simd); 148362306a36Sopenharmony_ci adev->gfx.cu_info.max_scratch_slots_per_cu = le32_to_cpu(gc_info->v2.gc_max_scratch_slots_per_cu); 148462306a36Sopenharmony_ci adev->gfx.cu_info.lds_size = le32_to_cpu(gc_info->v2.gc_lds_size); 148562306a36Sopenharmony_ci adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v2.gc_num_sc_per_se) / 148662306a36Sopenharmony_ci le32_to_cpu(gc_info->v2.gc_num_sh_per_se); 148762306a36Sopenharmony_ci adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v2.gc_num_packer_per_sc); 148862306a36Sopenharmony_ci if (gc_info->v2.header.version_minor == 1) { 148962306a36Sopenharmony_ci adev->gfx.config.gc_num_tcp_per_sa = le32_to_cpu(gc_info->v2_1.gc_num_tcp_per_sh); 149062306a36Sopenharmony_ci adev->gfx.config.gc_tcp_size_per_cu = le32_to_cpu(gc_info->v2_1.gc_tcp_size_per_cu); 149162306a36Sopenharmony_ci adev->gfx.config.gc_num_sdp_interface = le32_to_cpu(gc_info->v2_1.gc_num_sdp_interface); /* per XCD */ 149262306a36Sopenharmony_ci adev->gfx.config.gc_num_cu_per_sqc = le32_to_cpu(gc_info->v2_1.gc_num_cu_per_sqc); 149362306a36Sopenharmony_ci adev->gfx.config.gc_l1_instruction_cache_size_per_sqc = le32_to_cpu(gc_info->v2_1.gc_instruction_cache_size_per_sqc); 149462306a36Sopenharmony_ci adev->gfx.config.gc_l1_data_cache_size_per_sqc = le32_to_cpu(gc_info->v2_1.gc_scalar_data_cache_size_per_sqc); 149562306a36Sopenharmony_ci adev->gfx.config.gc_tcc_size = le32_to_cpu(gc_info->v2_1.gc_tcc_size); /* per XCD */ 149662306a36Sopenharmony_ci } 149762306a36Sopenharmony_ci break; 149862306a36Sopenharmony_ci default: 149962306a36Sopenharmony_ci dev_err(adev->dev, 150062306a36Sopenharmony_ci "Unhandled GC info table %d.%d\n", 150162306a36Sopenharmony_ci le16_to_cpu(gc_info->v1.header.version_major), 150262306a36Sopenharmony_ci le16_to_cpu(gc_info->v1.header.version_minor)); 150362306a36Sopenharmony_ci return -EINVAL; 150462306a36Sopenharmony_ci } 150562306a36Sopenharmony_ci return 0; 150662306a36Sopenharmony_ci} 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_ciunion mall_info { 150962306a36Sopenharmony_ci struct mall_info_v1_0 v1; 151062306a36Sopenharmony_ci struct mall_info_v2_0 v2; 151162306a36Sopenharmony_ci}; 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_cistatic int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev) 151462306a36Sopenharmony_ci{ 151562306a36Sopenharmony_ci struct binary_header *bhdr; 151662306a36Sopenharmony_ci union mall_info *mall_info; 151762306a36Sopenharmony_ci u32 u, mall_size_per_umc, m_s_present, half_use; 151862306a36Sopenharmony_ci u64 mall_size; 151962306a36Sopenharmony_ci u16 offset; 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci if (!adev->mman.discovery_bin) { 152262306a36Sopenharmony_ci DRM_ERROR("ip discovery uninitialized\n"); 152362306a36Sopenharmony_ci return -EINVAL; 152462306a36Sopenharmony_ci } 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 152762306a36Sopenharmony_ci offset = le16_to_cpu(bhdr->table_list[MALL_INFO].offset); 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci if (!offset) 153062306a36Sopenharmony_ci return 0; 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci mall_info = (union mall_info *)(adev->mman.discovery_bin + offset); 153362306a36Sopenharmony_ci 153462306a36Sopenharmony_ci switch (le16_to_cpu(mall_info->v1.header.version_major)) { 153562306a36Sopenharmony_ci case 1: 153662306a36Sopenharmony_ci mall_size = 0; 153762306a36Sopenharmony_ci mall_size_per_umc = le32_to_cpu(mall_info->v1.mall_size_per_m); 153862306a36Sopenharmony_ci m_s_present = le32_to_cpu(mall_info->v1.m_s_present); 153962306a36Sopenharmony_ci half_use = le32_to_cpu(mall_info->v1.m_half_use); 154062306a36Sopenharmony_ci for (u = 0; u < adev->gmc.num_umc; u++) { 154162306a36Sopenharmony_ci if (m_s_present & (1 << u)) 154262306a36Sopenharmony_ci mall_size += mall_size_per_umc * 2; 154362306a36Sopenharmony_ci else if (half_use & (1 << u)) 154462306a36Sopenharmony_ci mall_size += mall_size_per_umc / 2; 154562306a36Sopenharmony_ci else 154662306a36Sopenharmony_ci mall_size += mall_size_per_umc; 154762306a36Sopenharmony_ci } 154862306a36Sopenharmony_ci adev->gmc.mall_size = mall_size; 154962306a36Sopenharmony_ci adev->gmc.m_half_use = half_use; 155062306a36Sopenharmony_ci break; 155162306a36Sopenharmony_ci case 2: 155262306a36Sopenharmony_ci mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc); 155362306a36Sopenharmony_ci adev->gmc.mall_size = mall_size_per_umc * adev->gmc.num_umc; 155462306a36Sopenharmony_ci break; 155562306a36Sopenharmony_ci default: 155662306a36Sopenharmony_ci dev_err(adev->dev, 155762306a36Sopenharmony_ci "Unhandled MALL info table %d.%d\n", 155862306a36Sopenharmony_ci le16_to_cpu(mall_info->v1.header.version_major), 155962306a36Sopenharmony_ci le16_to_cpu(mall_info->v1.header.version_minor)); 156062306a36Sopenharmony_ci return -EINVAL; 156162306a36Sopenharmony_ci } 156262306a36Sopenharmony_ci return 0; 156362306a36Sopenharmony_ci} 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ciunion vcn_info { 156662306a36Sopenharmony_ci struct vcn_info_v1_0 v1; 156762306a36Sopenharmony_ci}; 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_cistatic int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev) 157062306a36Sopenharmony_ci{ 157162306a36Sopenharmony_ci struct binary_header *bhdr; 157262306a36Sopenharmony_ci union vcn_info *vcn_info; 157362306a36Sopenharmony_ci u16 offset; 157462306a36Sopenharmony_ci int v; 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci if (!adev->mman.discovery_bin) { 157762306a36Sopenharmony_ci DRM_ERROR("ip discovery uninitialized\n"); 157862306a36Sopenharmony_ci return -EINVAL; 157962306a36Sopenharmony_ci } 158062306a36Sopenharmony_ci 158162306a36Sopenharmony_ci /* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES 158262306a36Sopenharmony_ci * which is smaller than VCN_INFO_TABLE_MAX_NUM_INSTANCES 158362306a36Sopenharmony_ci * but that may change in the future with new GPUs so keep this 158462306a36Sopenharmony_ci * check for defensive purposes. 158562306a36Sopenharmony_ci */ 158662306a36Sopenharmony_ci if (adev->vcn.num_vcn_inst > VCN_INFO_TABLE_MAX_NUM_INSTANCES) { 158762306a36Sopenharmony_ci dev_err(adev->dev, "invalid vcn instances\n"); 158862306a36Sopenharmony_ci return -EINVAL; 158962306a36Sopenharmony_ci } 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci bhdr = (struct binary_header *)adev->mman.discovery_bin; 159262306a36Sopenharmony_ci offset = le16_to_cpu(bhdr->table_list[VCN_INFO].offset); 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci if (!offset) 159562306a36Sopenharmony_ci return 0; 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci vcn_info = (union vcn_info *)(adev->mman.discovery_bin + offset); 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_ci switch (le16_to_cpu(vcn_info->v1.header.version_major)) { 160062306a36Sopenharmony_ci case 1: 160162306a36Sopenharmony_ci /* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES 160262306a36Sopenharmony_ci * so this won't overflow. 160362306a36Sopenharmony_ci */ 160462306a36Sopenharmony_ci for (v = 0; v < adev->vcn.num_vcn_inst; v++) { 160562306a36Sopenharmony_ci adev->vcn.vcn_codec_disable_mask[v] = 160662306a36Sopenharmony_ci le32_to_cpu(vcn_info->v1.instance_info[v].fuse_data.all_bits); 160762306a36Sopenharmony_ci } 160862306a36Sopenharmony_ci break; 160962306a36Sopenharmony_ci default: 161062306a36Sopenharmony_ci dev_err(adev->dev, 161162306a36Sopenharmony_ci "Unhandled VCN info table %d.%d\n", 161262306a36Sopenharmony_ci le16_to_cpu(vcn_info->v1.header.version_major), 161362306a36Sopenharmony_ci le16_to_cpu(vcn_info->v1.header.version_minor)); 161462306a36Sopenharmony_ci return -EINVAL; 161562306a36Sopenharmony_ci } 161662306a36Sopenharmony_ci return 0; 161762306a36Sopenharmony_ci} 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_cistatic int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev) 162062306a36Sopenharmony_ci{ 162162306a36Sopenharmony_ci /* what IP to use for this? */ 162262306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 162362306a36Sopenharmony_ci case IP_VERSION(9, 0, 1): 162462306a36Sopenharmony_ci case IP_VERSION(9, 1, 0): 162562306a36Sopenharmony_ci case IP_VERSION(9, 2, 1): 162662306a36Sopenharmony_ci case IP_VERSION(9, 2, 2): 162762306a36Sopenharmony_ci case IP_VERSION(9, 3, 0): 162862306a36Sopenharmony_ci case IP_VERSION(9, 4, 0): 162962306a36Sopenharmony_ci case IP_VERSION(9, 4, 1): 163062306a36Sopenharmony_ci case IP_VERSION(9, 4, 2): 163162306a36Sopenharmony_ci case IP_VERSION(9, 4, 3): 163262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); 163362306a36Sopenharmony_ci break; 163462306a36Sopenharmony_ci case IP_VERSION(10, 1, 10): 163562306a36Sopenharmony_ci case IP_VERSION(10, 1, 1): 163662306a36Sopenharmony_ci case IP_VERSION(10, 1, 2): 163762306a36Sopenharmony_ci case IP_VERSION(10, 1, 3): 163862306a36Sopenharmony_ci case IP_VERSION(10, 1, 4): 163962306a36Sopenharmony_ci case IP_VERSION(10, 3, 0): 164062306a36Sopenharmony_ci case IP_VERSION(10, 3, 1): 164162306a36Sopenharmony_ci case IP_VERSION(10, 3, 2): 164262306a36Sopenharmony_ci case IP_VERSION(10, 3, 3): 164362306a36Sopenharmony_ci case IP_VERSION(10, 3, 4): 164462306a36Sopenharmony_ci case IP_VERSION(10, 3, 5): 164562306a36Sopenharmony_ci case IP_VERSION(10, 3, 6): 164662306a36Sopenharmony_ci case IP_VERSION(10, 3, 7): 164762306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &nv_common_ip_block); 164862306a36Sopenharmony_ci break; 164962306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 165062306a36Sopenharmony_ci case IP_VERSION(11, 0, 1): 165162306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 165262306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 165362306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 165462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &soc21_common_ip_block); 165562306a36Sopenharmony_ci break; 165662306a36Sopenharmony_ci default: 165762306a36Sopenharmony_ci dev_err(adev->dev, 165862306a36Sopenharmony_ci "Failed to add common ip block(GC_HWIP:0x%x)\n", 165962306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0]); 166062306a36Sopenharmony_ci return -EINVAL; 166162306a36Sopenharmony_ci } 166262306a36Sopenharmony_ci return 0; 166362306a36Sopenharmony_ci} 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_cistatic int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev) 166662306a36Sopenharmony_ci{ 166762306a36Sopenharmony_ci /* use GC or MMHUB IP version */ 166862306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 166962306a36Sopenharmony_ci case IP_VERSION(9, 0, 1): 167062306a36Sopenharmony_ci case IP_VERSION(9, 1, 0): 167162306a36Sopenharmony_ci case IP_VERSION(9, 2, 1): 167262306a36Sopenharmony_ci case IP_VERSION(9, 2, 2): 167362306a36Sopenharmony_ci case IP_VERSION(9, 3, 0): 167462306a36Sopenharmony_ci case IP_VERSION(9, 4, 0): 167562306a36Sopenharmony_ci case IP_VERSION(9, 4, 1): 167662306a36Sopenharmony_ci case IP_VERSION(9, 4, 2): 167762306a36Sopenharmony_ci case IP_VERSION(9, 4, 3): 167862306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); 167962306a36Sopenharmony_ci break; 168062306a36Sopenharmony_ci case IP_VERSION(10, 1, 10): 168162306a36Sopenharmony_ci case IP_VERSION(10, 1, 1): 168262306a36Sopenharmony_ci case IP_VERSION(10, 1, 2): 168362306a36Sopenharmony_ci case IP_VERSION(10, 1, 3): 168462306a36Sopenharmony_ci case IP_VERSION(10, 1, 4): 168562306a36Sopenharmony_ci case IP_VERSION(10, 3, 0): 168662306a36Sopenharmony_ci case IP_VERSION(10, 3, 1): 168762306a36Sopenharmony_ci case IP_VERSION(10, 3, 2): 168862306a36Sopenharmony_ci case IP_VERSION(10, 3, 3): 168962306a36Sopenharmony_ci case IP_VERSION(10, 3, 4): 169062306a36Sopenharmony_ci case IP_VERSION(10, 3, 5): 169162306a36Sopenharmony_ci case IP_VERSION(10, 3, 6): 169262306a36Sopenharmony_ci case IP_VERSION(10, 3, 7): 169362306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); 169462306a36Sopenharmony_ci break; 169562306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 169662306a36Sopenharmony_ci case IP_VERSION(11, 0, 1): 169762306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 169862306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 169962306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 170062306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block); 170162306a36Sopenharmony_ci break; 170262306a36Sopenharmony_ci default: 170362306a36Sopenharmony_ci dev_err(adev->dev, 170462306a36Sopenharmony_ci "Failed to add gmc ip block(GC_HWIP:0x%x)\n", 170562306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0]); 170662306a36Sopenharmony_ci return -EINVAL; 170762306a36Sopenharmony_ci } 170862306a36Sopenharmony_ci return 0; 170962306a36Sopenharmony_ci} 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_cistatic int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev) 171262306a36Sopenharmony_ci{ 171362306a36Sopenharmony_ci switch (adev->ip_versions[OSSSYS_HWIP][0]) { 171462306a36Sopenharmony_ci case IP_VERSION(4, 0, 0): 171562306a36Sopenharmony_ci case IP_VERSION(4, 0, 1): 171662306a36Sopenharmony_ci case IP_VERSION(4, 1, 0): 171762306a36Sopenharmony_ci case IP_VERSION(4, 1, 1): 171862306a36Sopenharmony_ci case IP_VERSION(4, 3, 0): 171962306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); 172062306a36Sopenharmony_ci break; 172162306a36Sopenharmony_ci case IP_VERSION(4, 2, 0): 172262306a36Sopenharmony_ci case IP_VERSION(4, 2, 1): 172362306a36Sopenharmony_ci case IP_VERSION(4, 4, 0): 172462306a36Sopenharmony_ci case IP_VERSION(4, 4, 2): 172562306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); 172662306a36Sopenharmony_ci break; 172762306a36Sopenharmony_ci case IP_VERSION(5, 0, 0): 172862306a36Sopenharmony_ci case IP_VERSION(5, 0, 1): 172962306a36Sopenharmony_ci case IP_VERSION(5, 0, 2): 173062306a36Sopenharmony_ci case IP_VERSION(5, 0, 3): 173162306a36Sopenharmony_ci case IP_VERSION(5, 2, 0): 173262306a36Sopenharmony_ci case IP_VERSION(5, 2, 1): 173362306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); 173462306a36Sopenharmony_ci break; 173562306a36Sopenharmony_ci case IP_VERSION(6, 0, 0): 173662306a36Sopenharmony_ci case IP_VERSION(6, 0, 1): 173762306a36Sopenharmony_ci case IP_VERSION(6, 0, 2): 173862306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &ih_v6_0_ip_block); 173962306a36Sopenharmony_ci break; 174062306a36Sopenharmony_ci case IP_VERSION(6, 1, 0): 174162306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &ih_v6_1_ip_block); 174262306a36Sopenharmony_ci break; 174362306a36Sopenharmony_ci default: 174462306a36Sopenharmony_ci dev_err(adev->dev, 174562306a36Sopenharmony_ci "Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n", 174662306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0]); 174762306a36Sopenharmony_ci return -EINVAL; 174862306a36Sopenharmony_ci } 174962306a36Sopenharmony_ci return 0; 175062306a36Sopenharmony_ci} 175162306a36Sopenharmony_ci 175262306a36Sopenharmony_cistatic int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev) 175362306a36Sopenharmony_ci{ 175462306a36Sopenharmony_ci switch (adev->ip_versions[MP0_HWIP][0]) { 175562306a36Sopenharmony_ci case IP_VERSION(9, 0, 0): 175662306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); 175762306a36Sopenharmony_ci break; 175862306a36Sopenharmony_ci case IP_VERSION(10, 0, 0): 175962306a36Sopenharmony_ci case IP_VERSION(10, 0, 1): 176062306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block); 176162306a36Sopenharmony_ci break; 176262306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 176362306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 176462306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 176562306a36Sopenharmony_ci case IP_VERSION(11, 0, 5): 176662306a36Sopenharmony_ci case IP_VERSION(11, 0, 9): 176762306a36Sopenharmony_ci case IP_VERSION(11, 0, 7): 176862306a36Sopenharmony_ci case IP_VERSION(11, 0, 11): 176962306a36Sopenharmony_ci case IP_VERSION(11, 0, 12): 177062306a36Sopenharmony_ci case IP_VERSION(11, 0, 13): 177162306a36Sopenharmony_ci case IP_VERSION(11, 5, 0): 177262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); 177362306a36Sopenharmony_ci break; 177462306a36Sopenharmony_ci case IP_VERSION(11, 0, 8): 177562306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v11_0_8_ip_block); 177662306a36Sopenharmony_ci break; 177762306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 177862306a36Sopenharmony_ci case IP_VERSION(12, 0, 1): 177962306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block); 178062306a36Sopenharmony_ci break; 178162306a36Sopenharmony_ci case IP_VERSION(13, 0, 0): 178262306a36Sopenharmony_ci case IP_VERSION(13, 0, 1): 178362306a36Sopenharmony_ci case IP_VERSION(13, 0, 2): 178462306a36Sopenharmony_ci case IP_VERSION(13, 0, 3): 178562306a36Sopenharmony_ci case IP_VERSION(13, 0, 5): 178662306a36Sopenharmony_ci case IP_VERSION(13, 0, 6): 178762306a36Sopenharmony_ci case IP_VERSION(13, 0, 7): 178862306a36Sopenharmony_ci case IP_VERSION(13, 0, 8): 178962306a36Sopenharmony_ci case IP_VERSION(13, 0, 10): 179062306a36Sopenharmony_ci case IP_VERSION(13, 0, 11): 179162306a36Sopenharmony_ci case IP_VERSION(14, 0, 0): 179262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); 179362306a36Sopenharmony_ci break; 179462306a36Sopenharmony_ci case IP_VERSION(13, 0, 4): 179562306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v13_0_4_ip_block); 179662306a36Sopenharmony_ci break; 179762306a36Sopenharmony_ci default: 179862306a36Sopenharmony_ci dev_err(adev->dev, 179962306a36Sopenharmony_ci "Failed to add psp ip block(MP0_HWIP:0x%x)\n", 180062306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0]); 180162306a36Sopenharmony_ci return -EINVAL; 180262306a36Sopenharmony_ci } 180362306a36Sopenharmony_ci return 0; 180462306a36Sopenharmony_ci} 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_cistatic int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev) 180762306a36Sopenharmony_ci{ 180862306a36Sopenharmony_ci switch (adev->ip_versions[MP1_HWIP][0]) { 180962306a36Sopenharmony_ci case IP_VERSION(9, 0, 0): 181062306a36Sopenharmony_ci case IP_VERSION(10, 0, 0): 181162306a36Sopenharmony_ci case IP_VERSION(10, 0, 1): 181262306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 181362306a36Sopenharmony_ci if (adev->asic_type == CHIP_ARCTURUS) 181462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 181562306a36Sopenharmony_ci else 181662306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); 181762306a36Sopenharmony_ci break; 181862306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 181962306a36Sopenharmony_ci case IP_VERSION(11, 0, 5): 182062306a36Sopenharmony_ci case IP_VERSION(11, 0, 9): 182162306a36Sopenharmony_ci case IP_VERSION(11, 0, 7): 182262306a36Sopenharmony_ci case IP_VERSION(11, 0, 8): 182362306a36Sopenharmony_ci case IP_VERSION(11, 0, 11): 182462306a36Sopenharmony_ci case IP_VERSION(11, 0, 12): 182562306a36Sopenharmony_ci case IP_VERSION(11, 0, 13): 182662306a36Sopenharmony_ci case IP_VERSION(11, 5, 0): 182762306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 182862306a36Sopenharmony_ci break; 182962306a36Sopenharmony_ci case IP_VERSION(12, 0, 0): 183062306a36Sopenharmony_ci case IP_VERSION(12, 0, 1): 183162306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block); 183262306a36Sopenharmony_ci break; 183362306a36Sopenharmony_ci case IP_VERSION(13, 0, 0): 183462306a36Sopenharmony_ci case IP_VERSION(13, 0, 1): 183562306a36Sopenharmony_ci case IP_VERSION(13, 0, 2): 183662306a36Sopenharmony_ci case IP_VERSION(13, 0, 3): 183762306a36Sopenharmony_ci case IP_VERSION(13, 0, 4): 183862306a36Sopenharmony_ci case IP_VERSION(13, 0, 5): 183962306a36Sopenharmony_ci case IP_VERSION(13, 0, 6): 184062306a36Sopenharmony_ci case IP_VERSION(13, 0, 7): 184162306a36Sopenharmony_ci case IP_VERSION(13, 0, 8): 184262306a36Sopenharmony_ci case IP_VERSION(13, 0, 10): 184362306a36Sopenharmony_ci case IP_VERSION(13, 0, 11): 184462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); 184562306a36Sopenharmony_ci break; 184662306a36Sopenharmony_ci default: 184762306a36Sopenharmony_ci dev_err(adev->dev, 184862306a36Sopenharmony_ci "Failed to add smu ip block(MP1_HWIP:0x%x)\n", 184962306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0]); 185062306a36Sopenharmony_ci return -EINVAL; 185162306a36Sopenharmony_ci } 185262306a36Sopenharmony_ci return 0; 185362306a36Sopenharmony_ci} 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci#if defined(CONFIG_DRM_AMD_DC) 185662306a36Sopenharmony_cistatic void amdgpu_discovery_set_sriov_display(struct amdgpu_device *adev) 185762306a36Sopenharmony_ci{ 185862306a36Sopenharmony_ci amdgpu_device_set_sriov_virtual_display(adev); 185962306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); 186062306a36Sopenharmony_ci} 186162306a36Sopenharmony_ci#endif 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_cistatic int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev) 186462306a36Sopenharmony_ci{ 186562306a36Sopenharmony_ci if (adev->enable_virtual_display) { 186662306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); 186762306a36Sopenharmony_ci return 0; 186862306a36Sopenharmony_ci } 186962306a36Sopenharmony_ci 187062306a36Sopenharmony_ci if (!amdgpu_device_has_dc_support(adev)) 187162306a36Sopenharmony_ci return 0; 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci#if defined(CONFIG_DRM_AMD_DC) 187462306a36Sopenharmony_ci if (adev->ip_versions[DCE_HWIP][0]) { 187562306a36Sopenharmony_ci switch (adev->ip_versions[DCE_HWIP][0]) { 187662306a36Sopenharmony_ci case IP_VERSION(1, 0, 0): 187762306a36Sopenharmony_ci case IP_VERSION(1, 0, 1): 187862306a36Sopenharmony_ci case IP_VERSION(2, 0, 2): 187962306a36Sopenharmony_ci case IP_VERSION(2, 0, 0): 188062306a36Sopenharmony_ci case IP_VERSION(2, 0, 3): 188162306a36Sopenharmony_ci case IP_VERSION(2, 1, 0): 188262306a36Sopenharmony_ci case IP_VERSION(3, 0, 0): 188362306a36Sopenharmony_ci case IP_VERSION(3, 0, 2): 188462306a36Sopenharmony_ci case IP_VERSION(3, 0, 3): 188562306a36Sopenharmony_ci case IP_VERSION(3, 0, 1): 188662306a36Sopenharmony_ci case IP_VERSION(3, 1, 2): 188762306a36Sopenharmony_ci case IP_VERSION(3, 1, 3): 188862306a36Sopenharmony_ci case IP_VERSION(3, 1, 4): 188962306a36Sopenharmony_ci case IP_VERSION(3, 1, 5): 189062306a36Sopenharmony_ci case IP_VERSION(3, 1, 6): 189162306a36Sopenharmony_ci case IP_VERSION(3, 2, 0): 189262306a36Sopenharmony_ci case IP_VERSION(3, 2, 1): 189362306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 189462306a36Sopenharmony_ci amdgpu_discovery_set_sriov_display(adev); 189562306a36Sopenharmony_ci else 189662306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dm_ip_block); 189762306a36Sopenharmony_ci break; 189862306a36Sopenharmony_ci default: 189962306a36Sopenharmony_ci dev_err(adev->dev, 190062306a36Sopenharmony_ci "Failed to add dm ip block(DCE_HWIP:0x%x)\n", 190162306a36Sopenharmony_ci adev->ip_versions[DCE_HWIP][0]); 190262306a36Sopenharmony_ci return -EINVAL; 190362306a36Sopenharmony_ci } 190462306a36Sopenharmony_ci } else if (adev->ip_versions[DCI_HWIP][0]) { 190562306a36Sopenharmony_ci switch (adev->ip_versions[DCI_HWIP][0]) { 190662306a36Sopenharmony_ci case IP_VERSION(12, 0, 0): 190762306a36Sopenharmony_ci case IP_VERSION(12, 0, 1): 190862306a36Sopenharmony_ci case IP_VERSION(12, 1, 0): 190962306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 191062306a36Sopenharmony_ci amdgpu_discovery_set_sriov_display(adev); 191162306a36Sopenharmony_ci else 191262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dm_ip_block); 191362306a36Sopenharmony_ci break; 191462306a36Sopenharmony_ci default: 191562306a36Sopenharmony_ci dev_err(adev->dev, 191662306a36Sopenharmony_ci "Failed to add dm ip block(DCI_HWIP:0x%x)\n", 191762306a36Sopenharmony_ci adev->ip_versions[DCI_HWIP][0]); 191862306a36Sopenharmony_ci return -EINVAL; 191962306a36Sopenharmony_ci } 192062306a36Sopenharmony_ci } 192162306a36Sopenharmony_ci#endif 192262306a36Sopenharmony_ci return 0; 192362306a36Sopenharmony_ci} 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_cistatic int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev) 192662306a36Sopenharmony_ci{ 192762306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 192862306a36Sopenharmony_ci case IP_VERSION(9, 0, 1): 192962306a36Sopenharmony_ci case IP_VERSION(9, 1, 0): 193062306a36Sopenharmony_ci case IP_VERSION(9, 2, 1): 193162306a36Sopenharmony_ci case IP_VERSION(9, 2, 2): 193262306a36Sopenharmony_ci case IP_VERSION(9, 3, 0): 193362306a36Sopenharmony_ci case IP_VERSION(9, 4, 0): 193462306a36Sopenharmony_ci case IP_VERSION(9, 4, 1): 193562306a36Sopenharmony_ci case IP_VERSION(9, 4, 2): 193662306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); 193762306a36Sopenharmony_ci break; 193862306a36Sopenharmony_ci case IP_VERSION(9, 4, 3): 193962306a36Sopenharmony_ci if (!amdgpu_exp_hw_support) 194062306a36Sopenharmony_ci return -EINVAL; 194162306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v9_4_3_ip_block); 194262306a36Sopenharmony_ci break; 194362306a36Sopenharmony_ci case IP_VERSION(10, 1, 10): 194462306a36Sopenharmony_ci case IP_VERSION(10, 1, 2): 194562306a36Sopenharmony_ci case IP_VERSION(10, 1, 1): 194662306a36Sopenharmony_ci case IP_VERSION(10, 1, 3): 194762306a36Sopenharmony_ci case IP_VERSION(10, 1, 4): 194862306a36Sopenharmony_ci case IP_VERSION(10, 3, 0): 194962306a36Sopenharmony_ci case IP_VERSION(10, 3, 2): 195062306a36Sopenharmony_ci case IP_VERSION(10, 3, 1): 195162306a36Sopenharmony_ci case IP_VERSION(10, 3, 4): 195262306a36Sopenharmony_ci case IP_VERSION(10, 3, 5): 195362306a36Sopenharmony_ci case IP_VERSION(10, 3, 6): 195462306a36Sopenharmony_ci case IP_VERSION(10, 3, 3): 195562306a36Sopenharmony_ci case IP_VERSION(10, 3, 7): 195662306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); 195762306a36Sopenharmony_ci break; 195862306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 195962306a36Sopenharmony_ci case IP_VERSION(11, 0, 1): 196062306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 196162306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 196262306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 196362306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block); 196462306a36Sopenharmony_ci break; 196562306a36Sopenharmony_ci default: 196662306a36Sopenharmony_ci dev_err(adev->dev, 196762306a36Sopenharmony_ci "Failed to add gfx ip block(GC_HWIP:0x%x)\n", 196862306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0]); 196962306a36Sopenharmony_ci return -EINVAL; 197062306a36Sopenharmony_ci } 197162306a36Sopenharmony_ci return 0; 197262306a36Sopenharmony_ci} 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_cistatic int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev) 197562306a36Sopenharmony_ci{ 197662306a36Sopenharmony_ci switch (adev->ip_versions[SDMA0_HWIP][0]) { 197762306a36Sopenharmony_ci case IP_VERSION(4, 0, 0): 197862306a36Sopenharmony_ci case IP_VERSION(4, 0, 1): 197962306a36Sopenharmony_ci case IP_VERSION(4, 1, 0): 198062306a36Sopenharmony_ci case IP_VERSION(4, 1, 1): 198162306a36Sopenharmony_ci case IP_VERSION(4, 1, 2): 198262306a36Sopenharmony_ci case IP_VERSION(4, 2, 0): 198362306a36Sopenharmony_ci case IP_VERSION(4, 2, 2): 198462306a36Sopenharmony_ci case IP_VERSION(4, 4, 0): 198562306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); 198662306a36Sopenharmony_ci break; 198762306a36Sopenharmony_ci case IP_VERSION(4, 4, 2): 198862306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v4_4_2_ip_block); 198962306a36Sopenharmony_ci break; 199062306a36Sopenharmony_ci case IP_VERSION(5, 0, 0): 199162306a36Sopenharmony_ci case IP_VERSION(5, 0, 1): 199262306a36Sopenharmony_ci case IP_VERSION(5, 0, 2): 199362306a36Sopenharmony_ci case IP_VERSION(5, 0, 5): 199462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); 199562306a36Sopenharmony_ci break; 199662306a36Sopenharmony_ci case IP_VERSION(5, 2, 0): 199762306a36Sopenharmony_ci case IP_VERSION(5, 2, 2): 199862306a36Sopenharmony_ci case IP_VERSION(5, 2, 4): 199962306a36Sopenharmony_ci case IP_VERSION(5, 2, 5): 200062306a36Sopenharmony_ci case IP_VERSION(5, 2, 6): 200162306a36Sopenharmony_ci case IP_VERSION(5, 2, 3): 200262306a36Sopenharmony_ci case IP_VERSION(5, 2, 1): 200362306a36Sopenharmony_ci case IP_VERSION(5, 2, 7): 200462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); 200562306a36Sopenharmony_ci break; 200662306a36Sopenharmony_ci case IP_VERSION(6, 0, 0): 200762306a36Sopenharmony_ci case IP_VERSION(6, 0, 1): 200862306a36Sopenharmony_ci case IP_VERSION(6, 0, 2): 200962306a36Sopenharmony_ci case IP_VERSION(6, 0, 3): 201062306a36Sopenharmony_ci case IP_VERSION(6, 1, 0): 201162306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block); 201262306a36Sopenharmony_ci break; 201362306a36Sopenharmony_ci default: 201462306a36Sopenharmony_ci dev_err(adev->dev, 201562306a36Sopenharmony_ci "Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n", 201662306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0]); 201762306a36Sopenharmony_ci return -EINVAL; 201862306a36Sopenharmony_ci } 201962306a36Sopenharmony_ci return 0; 202062306a36Sopenharmony_ci} 202162306a36Sopenharmony_ci 202262306a36Sopenharmony_cistatic int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) 202362306a36Sopenharmony_ci{ 202462306a36Sopenharmony_ci if (adev->ip_versions[VCE_HWIP][0]) { 202562306a36Sopenharmony_ci switch (adev->ip_versions[UVD_HWIP][0]) { 202662306a36Sopenharmony_ci case IP_VERSION(7, 0, 0): 202762306a36Sopenharmony_ci case IP_VERSION(7, 2, 0): 202862306a36Sopenharmony_ci /* UVD is not supported on vega20 SR-IOV */ 202962306a36Sopenharmony_ci if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) 203062306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block); 203162306a36Sopenharmony_ci break; 203262306a36Sopenharmony_ci default: 203362306a36Sopenharmony_ci dev_err(adev->dev, 203462306a36Sopenharmony_ci "Failed to add uvd v7 ip block(UVD_HWIP:0x%x)\n", 203562306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0]); 203662306a36Sopenharmony_ci return -EINVAL; 203762306a36Sopenharmony_ci } 203862306a36Sopenharmony_ci switch (adev->ip_versions[VCE_HWIP][0]) { 203962306a36Sopenharmony_ci case IP_VERSION(4, 0, 0): 204062306a36Sopenharmony_ci case IP_VERSION(4, 1, 0): 204162306a36Sopenharmony_ci /* VCE is not supported on vega20 SR-IOV */ 204262306a36Sopenharmony_ci if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) 204362306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block); 204462306a36Sopenharmony_ci break; 204562306a36Sopenharmony_ci default: 204662306a36Sopenharmony_ci dev_err(adev->dev, 204762306a36Sopenharmony_ci "Failed to add VCE v4 ip block(VCE_HWIP:0x%x)\n", 204862306a36Sopenharmony_ci adev->ip_versions[VCE_HWIP][0]); 204962306a36Sopenharmony_ci return -EINVAL; 205062306a36Sopenharmony_ci } 205162306a36Sopenharmony_ci } else { 205262306a36Sopenharmony_ci switch (adev->ip_versions[UVD_HWIP][0]) { 205362306a36Sopenharmony_ci case IP_VERSION(1, 0, 0): 205462306a36Sopenharmony_ci case IP_VERSION(1, 0, 1): 205562306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block); 205662306a36Sopenharmony_ci break; 205762306a36Sopenharmony_ci case IP_VERSION(2, 0, 0): 205862306a36Sopenharmony_ci case IP_VERSION(2, 0, 2): 205962306a36Sopenharmony_ci case IP_VERSION(2, 2, 0): 206062306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); 206162306a36Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) 206262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); 206362306a36Sopenharmony_ci break; 206462306a36Sopenharmony_ci case IP_VERSION(2, 0, 3): 206562306a36Sopenharmony_ci break; 206662306a36Sopenharmony_ci case IP_VERSION(2, 5, 0): 206762306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block); 206862306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block); 206962306a36Sopenharmony_ci break; 207062306a36Sopenharmony_ci case IP_VERSION(2, 6, 0): 207162306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block); 207262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block); 207362306a36Sopenharmony_ci break; 207462306a36Sopenharmony_ci case IP_VERSION(3, 0, 0): 207562306a36Sopenharmony_ci case IP_VERSION(3, 0, 16): 207662306a36Sopenharmony_ci case IP_VERSION(3, 1, 1): 207762306a36Sopenharmony_ci case IP_VERSION(3, 1, 2): 207862306a36Sopenharmony_ci case IP_VERSION(3, 0, 2): 207962306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); 208062306a36Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) 208162306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); 208262306a36Sopenharmony_ci break; 208362306a36Sopenharmony_ci case IP_VERSION(3, 0, 33): 208462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); 208562306a36Sopenharmony_ci break; 208662306a36Sopenharmony_ci case IP_VERSION(4, 0, 0): 208762306a36Sopenharmony_ci case IP_VERSION(4, 0, 2): 208862306a36Sopenharmony_ci case IP_VERSION(4, 0, 4): 208962306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block); 209062306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block); 209162306a36Sopenharmony_ci break; 209262306a36Sopenharmony_ci case IP_VERSION(4, 0, 3): 209362306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v4_0_3_ip_block); 209462306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v4_0_3_ip_block); 209562306a36Sopenharmony_ci break; 209662306a36Sopenharmony_ci default: 209762306a36Sopenharmony_ci dev_err(adev->dev, 209862306a36Sopenharmony_ci "Failed to add vcn/jpeg ip block(UVD_HWIP:0x%x)\n", 209962306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0]); 210062306a36Sopenharmony_ci return -EINVAL; 210162306a36Sopenharmony_ci } 210262306a36Sopenharmony_ci } 210362306a36Sopenharmony_ci return 0; 210462306a36Sopenharmony_ci} 210562306a36Sopenharmony_ci 210662306a36Sopenharmony_cistatic int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev) 210762306a36Sopenharmony_ci{ 210862306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 210962306a36Sopenharmony_ci case IP_VERSION(10, 1, 10): 211062306a36Sopenharmony_ci case IP_VERSION(10, 1, 1): 211162306a36Sopenharmony_ci case IP_VERSION(10, 1, 2): 211262306a36Sopenharmony_ci case IP_VERSION(10, 1, 3): 211362306a36Sopenharmony_ci case IP_VERSION(10, 1, 4): 211462306a36Sopenharmony_ci case IP_VERSION(10, 3, 0): 211562306a36Sopenharmony_ci case IP_VERSION(10, 3, 1): 211662306a36Sopenharmony_ci case IP_VERSION(10, 3, 2): 211762306a36Sopenharmony_ci case IP_VERSION(10, 3, 3): 211862306a36Sopenharmony_ci case IP_VERSION(10, 3, 4): 211962306a36Sopenharmony_ci case IP_VERSION(10, 3, 5): 212062306a36Sopenharmony_ci case IP_VERSION(10, 3, 6): 212162306a36Sopenharmony_ci if (amdgpu_mes) { 212262306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block); 212362306a36Sopenharmony_ci adev->enable_mes = true; 212462306a36Sopenharmony_ci if (amdgpu_mes_kiq) 212562306a36Sopenharmony_ci adev->enable_mes_kiq = true; 212662306a36Sopenharmony_ci } 212762306a36Sopenharmony_ci break; 212862306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 212962306a36Sopenharmony_ci case IP_VERSION(11, 0, 1): 213062306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 213162306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 213262306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 213362306a36Sopenharmony_ci amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block); 213462306a36Sopenharmony_ci adev->enable_mes = true; 213562306a36Sopenharmony_ci adev->enable_mes_kiq = true; 213662306a36Sopenharmony_ci break; 213762306a36Sopenharmony_ci default: 213862306a36Sopenharmony_ci break; 213962306a36Sopenharmony_ci } 214062306a36Sopenharmony_ci return 0; 214162306a36Sopenharmony_ci} 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_cistatic void amdgpu_discovery_init_soc_config(struct amdgpu_device *adev) 214462306a36Sopenharmony_ci{ 214562306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 214662306a36Sopenharmony_ci case IP_VERSION(9, 4, 3): 214762306a36Sopenharmony_ci aqua_vanjaram_init_soc_config(adev); 214862306a36Sopenharmony_ci break; 214962306a36Sopenharmony_ci default: 215062306a36Sopenharmony_ci break; 215162306a36Sopenharmony_ci } 215262306a36Sopenharmony_ci} 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_ciint amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) 215562306a36Sopenharmony_ci{ 215662306a36Sopenharmony_ci int r; 215762306a36Sopenharmony_ci 215862306a36Sopenharmony_ci switch (adev->asic_type) { 215962306a36Sopenharmony_ci case CHIP_VEGA10: 216062306a36Sopenharmony_ci vega10_reg_base_init(adev); 216162306a36Sopenharmony_ci adev->sdma.num_instances = 2; 216262306a36Sopenharmony_ci adev->gmc.num_umc = 4; 216362306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 0, 0); 216462306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 0, 0); 216562306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 0); 216662306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 0); 216762306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 0); 216862306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 0); 216962306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0); 217062306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 1, 0); 217162306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 0, 0); 217262306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0); 217362306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0); 217462306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0); 217562306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 0); 217662306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 0, 1); 217762306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0); 217862306a36Sopenharmony_ci adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0); 217962306a36Sopenharmony_ci adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 0); 218062306a36Sopenharmony_ci break; 218162306a36Sopenharmony_ci case CHIP_VEGA12: 218262306a36Sopenharmony_ci vega10_reg_base_init(adev); 218362306a36Sopenharmony_ci adev->sdma.num_instances = 2; 218462306a36Sopenharmony_ci adev->gmc.num_umc = 4; 218562306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 3, 0); 218662306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 3, 0); 218762306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 1); 218862306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 1); 218962306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 1); 219062306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 1); 219162306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 5, 0); 219262306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 2, 0); 219362306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 0); 219462306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0); 219562306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0); 219662306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0); 219762306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 1); 219862306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 1); 219962306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0); 220062306a36Sopenharmony_ci adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0); 220162306a36Sopenharmony_ci adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 1); 220262306a36Sopenharmony_ci break; 220362306a36Sopenharmony_ci case CHIP_RAVEN: 220462306a36Sopenharmony_ci vega10_reg_base_init(adev); 220562306a36Sopenharmony_ci adev->sdma.num_instances = 1; 220662306a36Sopenharmony_ci adev->vcn.num_vcn_inst = 1; 220762306a36Sopenharmony_ci adev->gmc.num_umc = 2; 220862306a36Sopenharmony_ci if (adev->apu_flags & AMD_APU_IS_RAVEN2) { 220962306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 2, 0); 221062306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 2, 0); 221162306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 1); 221262306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 1); 221362306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 1); 221462306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 1); 221562306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 1); 221662306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 5, 0); 221762306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 1); 221862306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 1); 221962306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 1, 0); 222062306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 1); 222162306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 2); 222262306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 1); 222362306a36Sopenharmony_ci adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 1); 222462306a36Sopenharmony_ci } else { 222562306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 1, 0); 222662306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 1, 0); 222762306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 0); 222862306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 0); 222962306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 0); 223062306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0); 223162306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 0); 223262306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 0, 0); 223362306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 0); 223462306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 0); 223562306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 0, 0); 223662306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 0); 223762306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 1, 0); 223862306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 0); 223962306a36Sopenharmony_ci adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 0); 224062306a36Sopenharmony_ci } 224162306a36Sopenharmony_ci break; 224262306a36Sopenharmony_ci case CHIP_VEGA20: 224362306a36Sopenharmony_ci vega20_reg_base_init(adev); 224462306a36Sopenharmony_ci adev->sdma.num_instances = 2; 224562306a36Sopenharmony_ci adev->gmc.num_umc = 8; 224662306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 0); 224762306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 0); 224862306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 0); 224962306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 0); 225062306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 0); 225162306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 0); 225262306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 0); 225362306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 0); 225462306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 1); 225562306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 2); 225662306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2); 225762306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 2); 225862306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 2); 225962306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 0); 226062306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 2, 0); 226162306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][1] = IP_VERSION(7, 2, 0); 226262306a36Sopenharmony_ci adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 1, 0); 226362306a36Sopenharmony_ci adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 1, 0); 226462306a36Sopenharmony_ci break; 226562306a36Sopenharmony_ci case CHIP_ARCTURUS: 226662306a36Sopenharmony_ci arct_reg_base_init(adev); 226762306a36Sopenharmony_ci adev->sdma.num_instances = 8; 226862306a36Sopenharmony_ci adev->vcn.num_vcn_inst = 2; 226962306a36Sopenharmony_ci adev->gmc.num_umc = 8; 227062306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 1); 227162306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 1); 227262306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 1); 227362306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 1); 227462306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 2); 227562306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 2); 227662306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][1] = IP_VERSION(4, 2, 2); 227762306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][2] = IP_VERSION(4, 2, 2); 227862306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][3] = IP_VERSION(4, 2, 2); 227962306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][4] = IP_VERSION(4, 2, 2); 228062306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][5] = IP_VERSION(4, 2, 2); 228162306a36Sopenharmony_ci adev->ip_versions[SDMA1_HWIP][6] = IP_VERSION(4, 2, 2); 228262306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 1); 228362306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 1); 228462306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 2); 228562306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 4); 228662306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2); 228762306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 3); 228862306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 3); 228962306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 1); 229062306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 5, 0); 229162306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 5, 0); 229262306a36Sopenharmony_ci break; 229362306a36Sopenharmony_ci case CHIP_ALDEBARAN: 229462306a36Sopenharmony_ci aldebaran_reg_base_init(adev); 229562306a36Sopenharmony_ci adev->sdma.num_instances = 5; 229662306a36Sopenharmony_ci adev->vcn.num_vcn_inst = 2; 229762306a36Sopenharmony_ci adev->gmc.num_umc = 4; 229862306a36Sopenharmony_ci adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 2); 229962306a36Sopenharmony_ci adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 2); 230062306a36Sopenharmony_ci adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 4, 0); 230162306a36Sopenharmony_ci adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 4, 0); 230262306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 4, 0); 230362306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][1] = IP_VERSION(4, 4, 0); 230462306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][2] = IP_VERSION(4, 4, 0); 230562306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][3] = IP_VERSION(4, 4, 0); 230662306a36Sopenharmony_ci adev->ip_versions[SDMA0_HWIP][4] = IP_VERSION(4, 4, 0); 230762306a36Sopenharmony_ci adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 2); 230862306a36Sopenharmony_ci adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 4); 230962306a36Sopenharmony_ci adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 7, 0); 231062306a36Sopenharmony_ci adev->ip_versions[MP0_HWIP][0] = IP_VERSION(13, 0, 2); 231162306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] = IP_VERSION(13, 0, 2); 231262306a36Sopenharmony_ci adev->ip_versions[THM_HWIP][0] = IP_VERSION(13, 0, 2); 231362306a36Sopenharmony_ci adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(13, 0, 2); 231462306a36Sopenharmony_ci adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 2); 231562306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 6, 0); 231662306a36Sopenharmony_ci adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 6, 0); 231762306a36Sopenharmony_ci adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 1, 0); 231862306a36Sopenharmony_ci break; 231962306a36Sopenharmony_ci default: 232062306a36Sopenharmony_ci r = amdgpu_discovery_reg_base_init(adev); 232162306a36Sopenharmony_ci if (r) 232262306a36Sopenharmony_ci return -EINVAL; 232362306a36Sopenharmony_ci 232462306a36Sopenharmony_ci amdgpu_discovery_harvest_ip(adev); 232562306a36Sopenharmony_ci amdgpu_discovery_get_gfx_info(adev); 232662306a36Sopenharmony_ci amdgpu_discovery_get_mall_info(adev); 232762306a36Sopenharmony_ci amdgpu_discovery_get_vcn_info(adev); 232862306a36Sopenharmony_ci break; 232962306a36Sopenharmony_ci } 233062306a36Sopenharmony_ci 233162306a36Sopenharmony_ci amdgpu_discovery_init_soc_config(adev); 233262306a36Sopenharmony_ci amdgpu_discovery_sysfs_init(adev); 233362306a36Sopenharmony_ci 233462306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 233562306a36Sopenharmony_ci case IP_VERSION(9, 0, 1): 233662306a36Sopenharmony_ci case IP_VERSION(9, 2, 1): 233762306a36Sopenharmony_ci case IP_VERSION(9, 4, 0): 233862306a36Sopenharmony_ci case IP_VERSION(9, 4, 1): 233962306a36Sopenharmony_ci case IP_VERSION(9, 4, 2): 234062306a36Sopenharmony_ci case IP_VERSION(9, 4, 3): 234162306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_AI; 234262306a36Sopenharmony_ci break; 234362306a36Sopenharmony_ci case IP_VERSION(9, 1, 0): 234462306a36Sopenharmony_ci case IP_VERSION(9, 2, 2): 234562306a36Sopenharmony_ci case IP_VERSION(9, 3, 0): 234662306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_RV; 234762306a36Sopenharmony_ci break; 234862306a36Sopenharmony_ci case IP_VERSION(10, 1, 10): 234962306a36Sopenharmony_ci case IP_VERSION(10, 1, 1): 235062306a36Sopenharmony_ci case IP_VERSION(10, 1, 2): 235162306a36Sopenharmony_ci case IP_VERSION(10, 1, 3): 235262306a36Sopenharmony_ci case IP_VERSION(10, 1, 4): 235362306a36Sopenharmony_ci case IP_VERSION(10, 3, 0): 235462306a36Sopenharmony_ci case IP_VERSION(10, 3, 2): 235562306a36Sopenharmony_ci case IP_VERSION(10, 3, 4): 235662306a36Sopenharmony_ci case IP_VERSION(10, 3, 5): 235762306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_NV; 235862306a36Sopenharmony_ci break; 235962306a36Sopenharmony_ci case IP_VERSION(10, 3, 1): 236062306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_VGH; 236162306a36Sopenharmony_ci adev->apu_flags |= AMD_APU_IS_VANGOGH; 236262306a36Sopenharmony_ci break; 236362306a36Sopenharmony_ci case IP_VERSION(10, 3, 3): 236462306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_YC; 236562306a36Sopenharmony_ci break; 236662306a36Sopenharmony_ci case IP_VERSION(10, 3, 6): 236762306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_GC_10_3_6; 236862306a36Sopenharmony_ci break; 236962306a36Sopenharmony_ci case IP_VERSION(10, 3, 7): 237062306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_GC_10_3_7; 237162306a36Sopenharmony_ci break; 237262306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 237362306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 237462306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 237562306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_GC_11_0_0; 237662306a36Sopenharmony_ci break; 237762306a36Sopenharmony_ci case IP_VERSION(11, 0, 1): 237862306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 237962306a36Sopenharmony_ci adev->family = AMDGPU_FAMILY_GC_11_0_1; 238062306a36Sopenharmony_ci break; 238162306a36Sopenharmony_ci default: 238262306a36Sopenharmony_ci return -EINVAL; 238362306a36Sopenharmony_ci } 238462306a36Sopenharmony_ci 238562306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 238662306a36Sopenharmony_ci case IP_VERSION(9, 1, 0): 238762306a36Sopenharmony_ci case IP_VERSION(9, 2, 2): 238862306a36Sopenharmony_ci case IP_VERSION(9, 3, 0): 238962306a36Sopenharmony_ci case IP_VERSION(10, 1, 3): 239062306a36Sopenharmony_ci case IP_VERSION(10, 1, 4): 239162306a36Sopenharmony_ci case IP_VERSION(10, 3, 1): 239262306a36Sopenharmony_ci case IP_VERSION(10, 3, 3): 239362306a36Sopenharmony_ci case IP_VERSION(10, 3, 6): 239462306a36Sopenharmony_ci case IP_VERSION(10, 3, 7): 239562306a36Sopenharmony_ci case IP_VERSION(11, 0, 1): 239662306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 239762306a36Sopenharmony_ci adev->flags |= AMD_IS_APU; 239862306a36Sopenharmony_ci break; 239962306a36Sopenharmony_ci default: 240062306a36Sopenharmony_ci break; 240162306a36Sopenharmony_ci } 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_ci if (adev->ip_versions[XGMI_HWIP][0] == IP_VERSION(4, 8, 0)) 240462306a36Sopenharmony_ci adev->gmc.xgmi.supported = true; 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ci /* set NBIO version */ 240762306a36Sopenharmony_ci switch (adev->ip_versions[NBIO_HWIP][0]) { 240862306a36Sopenharmony_ci case IP_VERSION(6, 1, 0): 240962306a36Sopenharmony_ci case IP_VERSION(6, 2, 0): 241062306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v6_1_funcs; 241162306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg; 241262306a36Sopenharmony_ci break; 241362306a36Sopenharmony_ci case IP_VERSION(7, 0, 0): 241462306a36Sopenharmony_ci case IP_VERSION(7, 0, 1): 241562306a36Sopenharmony_ci case IP_VERSION(2, 5, 0): 241662306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v7_0_funcs; 241762306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg; 241862306a36Sopenharmony_ci break; 241962306a36Sopenharmony_ci case IP_VERSION(7, 4, 0): 242062306a36Sopenharmony_ci case IP_VERSION(7, 4, 1): 242162306a36Sopenharmony_ci case IP_VERSION(7, 4, 4): 242262306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v7_4_funcs; 242362306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg; 242462306a36Sopenharmony_ci break; 242562306a36Sopenharmony_ci case IP_VERSION(7, 9, 0): 242662306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v7_9_funcs; 242762306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v7_9_hdp_flush_reg; 242862306a36Sopenharmony_ci break; 242962306a36Sopenharmony_ci case IP_VERSION(7, 2, 0): 243062306a36Sopenharmony_ci case IP_VERSION(7, 2, 1): 243162306a36Sopenharmony_ci case IP_VERSION(7, 3, 0): 243262306a36Sopenharmony_ci case IP_VERSION(7, 5, 0): 243362306a36Sopenharmony_ci case IP_VERSION(7, 5, 1): 243462306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v7_2_funcs; 243562306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg; 243662306a36Sopenharmony_ci break; 243762306a36Sopenharmony_ci case IP_VERSION(2, 1, 1): 243862306a36Sopenharmony_ci case IP_VERSION(2, 3, 0): 243962306a36Sopenharmony_ci case IP_VERSION(2, 3, 1): 244062306a36Sopenharmony_ci case IP_VERSION(2, 3, 2): 244162306a36Sopenharmony_ci case IP_VERSION(3, 3, 0): 244262306a36Sopenharmony_ci case IP_VERSION(3, 3, 1): 244362306a36Sopenharmony_ci case IP_VERSION(3, 3, 2): 244462306a36Sopenharmony_ci case IP_VERSION(3, 3, 3): 244562306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v2_3_funcs; 244662306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; 244762306a36Sopenharmony_ci break; 244862306a36Sopenharmony_ci case IP_VERSION(4, 3, 0): 244962306a36Sopenharmony_ci case IP_VERSION(4, 3, 1): 245062306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 245162306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v4_3_sriov_funcs; 245262306a36Sopenharmony_ci else 245362306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v4_3_funcs; 245462306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg; 245562306a36Sopenharmony_ci break; 245662306a36Sopenharmony_ci case IP_VERSION(7, 7, 0): 245762306a36Sopenharmony_ci case IP_VERSION(7, 7, 1): 245862306a36Sopenharmony_ci adev->nbio.funcs = &nbio_v7_7_funcs; 245962306a36Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v7_7_hdp_flush_reg; 246062306a36Sopenharmony_ci break; 246162306a36Sopenharmony_ci default: 246262306a36Sopenharmony_ci break; 246362306a36Sopenharmony_ci } 246462306a36Sopenharmony_ci 246562306a36Sopenharmony_ci switch (adev->ip_versions[HDP_HWIP][0]) { 246662306a36Sopenharmony_ci case IP_VERSION(4, 0, 0): 246762306a36Sopenharmony_ci case IP_VERSION(4, 0, 1): 246862306a36Sopenharmony_ci case IP_VERSION(4, 1, 0): 246962306a36Sopenharmony_ci case IP_VERSION(4, 1, 1): 247062306a36Sopenharmony_ci case IP_VERSION(4, 1, 2): 247162306a36Sopenharmony_ci case IP_VERSION(4, 2, 0): 247262306a36Sopenharmony_ci case IP_VERSION(4, 2, 1): 247362306a36Sopenharmony_ci case IP_VERSION(4, 4, 0): 247462306a36Sopenharmony_ci case IP_VERSION(4, 4, 2): 247562306a36Sopenharmony_ci adev->hdp.funcs = &hdp_v4_0_funcs; 247662306a36Sopenharmony_ci break; 247762306a36Sopenharmony_ci case IP_VERSION(5, 0, 0): 247862306a36Sopenharmony_ci case IP_VERSION(5, 0, 1): 247962306a36Sopenharmony_ci case IP_VERSION(5, 0, 2): 248062306a36Sopenharmony_ci case IP_VERSION(5, 0, 3): 248162306a36Sopenharmony_ci case IP_VERSION(5, 0, 4): 248262306a36Sopenharmony_ci case IP_VERSION(5, 2, 0): 248362306a36Sopenharmony_ci adev->hdp.funcs = &hdp_v5_0_funcs; 248462306a36Sopenharmony_ci break; 248562306a36Sopenharmony_ci case IP_VERSION(5, 2, 1): 248662306a36Sopenharmony_ci adev->hdp.funcs = &hdp_v5_2_funcs; 248762306a36Sopenharmony_ci break; 248862306a36Sopenharmony_ci case IP_VERSION(6, 0, 0): 248962306a36Sopenharmony_ci case IP_VERSION(6, 0, 1): 249062306a36Sopenharmony_ci case IP_VERSION(6, 1, 0): 249162306a36Sopenharmony_ci adev->hdp.funcs = &hdp_v6_0_funcs; 249262306a36Sopenharmony_ci break; 249362306a36Sopenharmony_ci default: 249462306a36Sopenharmony_ci break; 249562306a36Sopenharmony_ci } 249662306a36Sopenharmony_ci 249762306a36Sopenharmony_ci switch (adev->ip_versions[DF_HWIP][0]) { 249862306a36Sopenharmony_ci case IP_VERSION(3, 6, 0): 249962306a36Sopenharmony_ci case IP_VERSION(3, 6, 1): 250062306a36Sopenharmony_ci case IP_VERSION(3, 6, 2): 250162306a36Sopenharmony_ci adev->df.funcs = &df_v3_6_funcs; 250262306a36Sopenharmony_ci break; 250362306a36Sopenharmony_ci case IP_VERSION(2, 1, 0): 250462306a36Sopenharmony_ci case IP_VERSION(2, 1, 1): 250562306a36Sopenharmony_ci case IP_VERSION(2, 5, 0): 250662306a36Sopenharmony_ci case IP_VERSION(3, 5, 1): 250762306a36Sopenharmony_ci case IP_VERSION(3, 5, 2): 250862306a36Sopenharmony_ci adev->df.funcs = &df_v1_7_funcs; 250962306a36Sopenharmony_ci break; 251062306a36Sopenharmony_ci case IP_VERSION(4, 3, 0): 251162306a36Sopenharmony_ci adev->df.funcs = &df_v4_3_funcs; 251262306a36Sopenharmony_ci break; 251362306a36Sopenharmony_ci default: 251462306a36Sopenharmony_ci break; 251562306a36Sopenharmony_ci } 251662306a36Sopenharmony_ci 251762306a36Sopenharmony_ci switch (adev->ip_versions[SMUIO_HWIP][0]) { 251862306a36Sopenharmony_ci case IP_VERSION(9, 0, 0): 251962306a36Sopenharmony_ci case IP_VERSION(9, 0, 1): 252062306a36Sopenharmony_ci case IP_VERSION(10, 0, 0): 252162306a36Sopenharmony_ci case IP_VERSION(10, 0, 1): 252262306a36Sopenharmony_ci case IP_VERSION(10, 0, 2): 252362306a36Sopenharmony_ci adev->smuio.funcs = &smuio_v9_0_funcs; 252462306a36Sopenharmony_ci break; 252562306a36Sopenharmony_ci case IP_VERSION(11, 0, 0): 252662306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 252762306a36Sopenharmony_ci case IP_VERSION(11, 0, 3): 252862306a36Sopenharmony_ci case IP_VERSION(11, 0, 4): 252962306a36Sopenharmony_ci case IP_VERSION(11, 0, 7): 253062306a36Sopenharmony_ci case IP_VERSION(11, 0, 8): 253162306a36Sopenharmony_ci adev->smuio.funcs = &smuio_v11_0_funcs; 253262306a36Sopenharmony_ci break; 253362306a36Sopenharmony_ci case IP_VERSION(11, 0, 6): 253462306a36Sopenharmony_ci case IP_VERSION(11, 0, 10): 253562306a36Sopenharmony_ci case IP_VERSION(11, 0, 11): 253662306a36Sopenharmony_ci case IP_VERSION(11, 5, 0): 253762306a36Sopenharmony_ci case IP_VERSION(13, 0, 1): 253862306a36Sopenharmony_ci case IP_VERSION(13, 0, 9): 253962306a36Sopenharmony_ci case IP_VERSION(13, 0, 10): 254062306a36Sopenharmony_ci adev->smuio.funcs = &smuio_v11_0_6_funcs; 254162306a36Sopenharmony_ci break; 254262306a36Sopenharmony_ci case IP_VERSION(13, 0, 2): 254362306a36Sopenharmony_ci adev->smuio.funcs = &smuio_v13_0_funcs; 254462306a36Sopenharmony_ci break; 254562306a36Sopenharmony_ci case IP_VERSION(13, 0, 3): 254662306a36Sopenharmony_ci adev->smuio.funcs = &smuio_v13_0_3_funcs; 254762306a36Sopenharmony_ci if (adev->smuio.funcs->get_pkg_type(adev) == AMDGPU_PKG_TYPE_APU) { 254862306a36Sopenharmony_ci adev->flags |= AMD_IS_APU; 254962306a36Sopenharmony_ci } 255062306a36Sopenharmony_ci break; 255162306a36Sopenharmony_ci case IP_VERSION(13, 0, 6): 255262306a36Sopenharmony_ci case IP_VERSION(13, 0, 8): 255362306a36Sopenharmony_ci case IP_VERSION(14, 0, 0): 255462306a36Sopenharmony_ci adev->smuio.funcs = &smuio_v13_0_6_funcs; 255562306a36Sopenharmony_ci break; 255662306a36Sopenharmony_ci default: 255762306a36Sopenharmony_ci break; 255862306a36Sopenharmony_ci } 255962306a36Sopenharmony_ci 256062306a36Sopenharmony_ci switch (adev->ip_versions[LSDMA_HWIP][0]) { 256162306a36Sopenharmony_ci case IP_VERSION(6, 0, 0): 256262306a36Sopenharmony_ci case IP_VERSION(6, 0, 1): 256362306a36Sopenharmony_ci case IP_VERSION(6, 0, 2): 256462306a36Sopenharmony_ci case IP_VERSION(6, 0, 3): 256562306a36Sopenharmony_ci adev->lsdma.funcs = &lsdma_v6_0_funcs; 256662306a36Sopenharmony_ci break; 256762306a36Sopenharmony_ci default: 256862306a36Sopenharmony_ci break; 256962306a36Sopenharmony_ci } 257062306a36Sopenharmony_ci 257162306a36Sopenharmony_ci r = amdgpu_discovery_set_common_ip_blocks(adev); 257262306a36Sopenharmony_ci if (r) 257362306a36Sopenharmony_ci return r; 257462306a36Sopenharmony_ci 257562306a36Sopenharmony_ci r = amdgpu_discovery_set_gmc_ip_blocks(adev); 257662306a36Sopenharmony_ci if (r) 257762306a36Sopenharmony_ci return r; 257862306a36Sopenharmony_ci 257962306a36Sopenharmony_ci /* For SR-IOV, PSP needs to be initialized before IH */ 258062306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) { 258162306a36Sopenharmony_ci r = amdgpu_discovery_set_psp_ip_blocks(adev); 258262306a36Sopenharmony_ci if (r) 258362306a36Sopenharmony_ci return r; 258462306a36Sopenharmony_ci r = amdgpu_discovery_set_ih_ip_blocks(adev); 258562306a36Sopenharmony_ci if (r) 258662306a36Sopenharmony_ci return r; 258762306a36Sopenharmony_ci } else { 258862306a36Sopenharmony_ci r = amdgpu_discovery_set_ih_ip_blocks(adev); 258962306a36Sopenharmony_ci if (r) 259062306a36Sopenharmony_ci return r; 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_ci if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { 259362306a36Sopenharmony_ci r = amdgpu_discovery_set_psp_ip_blocks(adev); 259462306a36Sopenharmony_ci if (r) 259562306a36Sopenharmony_ci return r; 259662306a36Sopenharmony_ci } 259762306a36Sopenharmony_ci } 259862306a36Sopenharmony_ci 259962306a36Sopenharmony_ci if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { 260062306a36Sopenharmony_ci r = amdgpu_discovery_set_smu_ip_blocks(adev); 260162306a36Sopenharmony_ci if (r) 260262306a36Sopenharmony_ci return r; 260362306a36Sopenharmony_ci } 260462306a36Sopenharmony_ci 260562306a36Sopenharmony_ci r = amdgpu_discovery_set_display_ip_blocks(adev); 260662306a36Sopenharmony_ci if (r) 260762306a36Sopenharmony_ci return r; 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci r = amdgpu_discovery_set_gc_ip_blocks(adev); 261062306a36Sopenharmony_ci if (r) 261162306a36Sopenharmony_ci return r; 261262306a36Sopenharmony_ci 261362306a36Sopenharmony_ci r = amdgpu_discovery_set_sdma_ip_blocks(adev); 261462306a36Sopenharmony_ci if (r) 261562306a36Sopenharmony_ci return r; 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_ci if ((adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && 261862306a36Sopenharmony_ci !amdgpu_sriov_vf(adev)) || 261962306a36Sopenharmony_ci (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO && amdgpu_dpm == 1)) { 262062306a36Sopenharmony_ci r = amdgpu_discovery_set_smu_ip_blocks(adev); 262162306a36Sopenharmony_ci if (r) 262262306a36Sopenharmony_ci return r; 262362306a36Sopenharmony_ci } 262462306a36Sopenharmony_ci 262562306a36Sopenharmony_ci r = amdgpu_discovery_set_mm_ip_blocks(adev); 262662306a36Sopenharmony_ci if (r) 262762306a36Sopenharmony_ci return r; 262862306a36Sopenharmony_ci 262962306a36Sopenharmony_ci r = amdgpu_discovery_set_mes_ip_blocks(adev); 263062306a36Sopenharmony_ci if (r) 263162306a36Sopenharmony_ci return r; 263262306a36Sopenharmony_ci 263362306a36Sopenharmony_ci return 0; 263462306a36Sopenharmony_ci} 263562306a36Sopenharmony_ci 2636