1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 #include <cpu/cpu.h> 4 #include <cpu/intel/cpu_ids.h> 5 #include <device/device.h> 6 #include <device/pci_ids.h> 7 #include <device/pci_ops.h> 8 #include <soc/lpm.h> 9 #include <soc/pci_devs.h> 10 #include <soc/soc_chip.h> 11 #include <types.h> 12 13 /* Function returns true if the platform is TGL-UP3 */ platform_is_up3(void)14static bool platform_is_up3(void) 15 { 16 const struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); 17 u32 cpu_id = cpu_get_cpuid(); 18 uint16_t mchid = pci_read_config16(dev, PCI_DEVICE_ID); 19 20 if ((cpu_id != CPUID_TIGERLAKE_A0) && (cpu_id != CPUID_TIGERLAKE_B0)) 21 return false; 22 23 return ((mchid == PCI_DID_INTEL_TGL_ID_U_2_2) || 24 (mchid == PCI_DID_INTEL_TGL_ID_U_4_2)); 25 } 26 get_supported_lpm_mask(struct soc_intel_tigerlake_config * config)27int get_supported_lpm_mask(struct soc_intel_tigerlake_config *config) 28 { 29 int disable_mask; 30 31 /* Disable any sub-states requested by mainboard */ 32 disable_mask = config->LpmStateDisableMask; 33 34 /* UP3 does not support S0i2.2/S0i3.3/S0i3.4 */ 35 if (platform_is_up3()) 36 disable_mask |= LPM_S0i3_3 | LPM_S0i3_4 | LPM_S0i2_2; 37 38 /* If external bypass is not used, S0i3 isn't recommended. */ 39 if (config->external_bypass == false) 40 disable_mask |= LPM_S0i3_0 | LPM_S0i3_1 | LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4; 41 42 /* If external clock gating is not implemented, S0i3.4 isn't recommended. */ 43 if (config->external_clk_gated == false) 44 disable_mask |= LPM_S0i3_4; 45 46 /* 47 * If external phy gating is not implemented, 48 * S0i3.3/S0i3.4/S0i2.2 are not recommended. 49 */ 50 if (config->external_phy_gated == false) 51 disable_mask |= LPM_S0i3_3 | LPM_S0i3_4 | LPM_S0i2_2; 52 53 /* If CNVi or ISH is used, S0i3.2/S0i3.3/S0i3.4 cannot be achieved. */ 54 if (is_devfn_enabled(PCH_DEVFN_CNVI_WIFI) || is_devfn_enabled(PCH_DEVFN_ISH)) 55 disable_mask |= LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4; 56 57 return LPM_S0iX_ALL & ~disable_mask; 58 } 59