Tim Wawrzynczak | 90f9cbb | 2021-07-19 16:07:42 -0600 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | |
Elyes Haouas | def74aa | 2022-10-31 13:44:40 +0100 | [diff] [blame] | 3 | #include <cpu/cpu.h> |
Tim Wawrzynczak | 90f9cbb | 2021-07-19 16:07:42 -0600 | [diff] [blame] | 4 | #include <cpu/intel/cpu_ids.h> |
Elyes Haouas | def74aa | 2022-10-31 13:44:40 +0100 | [diff] [blame] | 5 | #include <device/device.h> |
| 6 | #include <device/pci_ids.h> |
| 7 | #include <device/pci_ops.h> |
Tim Wawrzynczak | 90f9cbb | 2021-07-19 16:07:42 -0600 | [diff] [blame] | 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 */ |
| 14 | static 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 | |
Felix Singer | 43b7f41 | 2022-03-07 04:34:52 +0100 | [diff] [blame] | 23 | return ((mchid == PCI_DID_INTEL_TGL_ID_U_2_2) || |
| 24 | (mchid == PCI_DID_INTEL_TGL_ID_U_4_2)); |
Tim Wawrzynczak | 90f9cbb | 2021-07-19 16:07:42 -0600 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | int 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 | } |