1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <cpu/intel/cpu_ids.h>
5 #include <device/device.h>
6 #include <device/pci_ids.h>
7 #include <device/pci_ops.h>
9 #include <soc/pci_devs.h>
10 #include <soc/soc_chip.h>
13 /* Function returns true if the platform is TGL-UP3 */
14 static bool platform_is_up3(void)
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
);
20 if ((cpu_id
!= CPUID_TIGERLAKE_A0
) && (cpu_id
!= CPUID_TIGERLAKE_B0
))
23 return ((mchid
== PCI_DID_INTEL_TGL_ID_U_2_2
) ||
24 (mchid
== PCI_DID_INTEL_TGL_ID_U_4_2
));
27 int get_supported_lpm_mask(struct soc_intel_tigerlake_config
*config
)
31 /* Disable any sub-states requested by mainboard */
32 disable_mask
= config
->LpmStateDisableMask
;
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
;
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
;
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
;
47 * If external phy gating is not implemented,
48 * S0i3.3/S0i3.4/S0i2.2 are not recommended.
50 if (config
->external_phy_gated
== false)
51 disable_mask
|= LPM_S0i3_3
| LPM_S0i3_4
| LPM_S0i2_2
;
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
;
57 return LPM_S0iX_ALL
& ~disable_mask
;