diff options
-rw-r--r-- | src/soc/intel/tigerlake/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/tigerlake/fsp_params.c | 50 | ||||
-rw-r--r-- | src/soc/intel/tigerlake/include/soc/lpm.h | 10 | ||||
-rw-r--r-- | src/soc/intel/tigerlake/lpm.c | 58 |
4 files changed, 71 insertions, 48 deletions
diff --git a/src/soc/intel/tigerlake/Makefile.inc b/src/soc/intel/tigerlake/Makefile.inc index 0ec8e843f0..91464b3f50 100644 --- a/src/soc/intel/tigerlake/Makefile.inc +++ b/src/soc/intel/tigerlake/Makefile.inc @@ -32,6 +32,7 @@ ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += lockdown.c +ramstage-y += lpm.c ramstage-y += me.c ramstage-y += p2sb.c ramstage-y += pmc.c diff --git a/src/soc/intel/tigerlake/fsp_params.c b/src/soc/intel/tigerlake/fsp_params.c index 15ba280b92..bb100df633 100644 --- a/src/soc/intel/tigerlake/fsp_params.c +++ b/src/soc/intel/tigerlake/fsp_params.c @@ -22,6 +22,7 @@ #include <security/vboot/vboot_common.h> #include <soc/gpio.h> #include <soc/intel/common/vbt.h> +#include <soc/lpm.h> #include <soc/pci_devs.h> #include <soc/ramstage.h> #include <soc/soc_chip.h> @@ -69,53 +70,6 @@ static int get_l1_substate_control(enum L1_substates_control ctl) return ctl - 1; } -/* Function returns true if the platform is TGL-UP3 */ -static bool platform_is_up3(void) -{ - const struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); - u32 cpu_id = cpu_get_cpuid(); - uint16_t mchid = pci_read_config16(dev, PCI_DEVICE_ID); - - if ((cpu_id != CPUID_TIGERLAKE_A0) && (cpu_id != CPUID_TIGERLAKE_B0)) - return false; - - return ((mchid == PCI_DEVICE_ID_INTEL_TGL_ID_U_2_2) || - (mchid == PCI_DEVICE_ID_INTEL_TGL_ID_U_4_2)); -} - -static int get_disable_mask(struct soc_intel_tigerlake_config *config) -{ - int disable_mask; - - /* Disable any sub-states requested by mainboard */ - disable_mask = config->LpmStateDisableMask; - - /* UP3 does not support S0i2.2/S0i3.3/S0i3.4 */ - if (platform_is_up3()) - disable_mask |= LPM_S0i3_3 | LPM_S0i3_4 | LPM_S0i2_2; - - /* If external bypass is not used, S0i3 isn't recommended. */ - if (config->external_bypass == false) - disable_mask |= LPM_S0i3_0 | LPM_S0i3_1 | LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4; - - /* If external clock gating is not implemented, S0i3.4 isn't recommended. */ - if (config->external_clk_gated == false) - disable_mask |= LPM_S0i3_4; - - /* - * If external phy gating is not implemented, - * S0i3.3/S0i3.4/S0i2.2 are not recommended. - */ - if (config->external_phy_gated == false) - disable_mask |= LPM_S0i3_3 | LPM_S0i3_4 | LPM_S0i2_2; - - /* If CNVi or ISH is used, S0i3.2/S0i3.3/S0i3.4 cannot be achieved. */ - if (is_devfn_enabled(PCH_DEVFN_CNVI_WIFI) || is_devfn_enabled(PCH_DEVFN_ISH)) - disable_mask |= LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4; - - return disable_mask; -} - static void parse_devicetree(FSP_S_CONFIG *params) { const struct soc_intel_tigerlake_config *config; @@ -483,7 +437,7 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) * LPM0-s0i2.0, LPM1-s0i2.1, LPM2-s0i2.2, LPM3-s0i3.0, * LPM4-s0i3.1, LPM5-s0i3.2, LPM6-s0i3.3, LPM7-s0i3.4 */ - params->PmcLpmS0ixSubStateEnableMask = LPM_S0iX_ALL & ~get_disable_mask(config); + params->PmcLpmS0ixSubStateEnableMask = get_supported_lpm_mask(config); /* * Power Optimizer for DMI and SATA. diff --git a/src/soc/intel/tigerlake/include/soc/lpm.h b/src/soc/intel/tigerlake/include/soc/lpm.h new file mode 100644 index 0000000000..4f58e83684 --- /dev/null +++ b/src/soc/intel/tigerlake/include/soc/lpm.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_LPM_H_ +#define _SOC_LPM_H_ + +#include <soc/soc_chip.h> + +int get_supported_lpm_mask(struct soc_intel_tigerlake_config *config); + +#endif /* _SOC_LPM_H_ */ diff --git a/src/soc/intel/tigerlake/lpm.c b/src/soc/intel/tigerlake/lpm.c new file mode 100644 index 0000000000..92279d682b --- /dev/null +++ b/src/soc/intel/tigerlake/lpm.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <arch/cpu.h> +#include <device/device.h> +#include <device/pci_ops.h> +#include <device/pci_ids.h> +#include <cpu/intel/cpu_ids.h> +#include <soc/lpm.h> +#include <soc/pci_devs.h> +#include <soc/soc_chip.h> +#include <types.h> + +/* Function returns true if the platform is TGL-UP3 */ +static bool platform_is_up3(void) +{ + const struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); + u32 cpu_id = cpu_get_cpuid(); + uint16_t mchid = pci_read_config16(dev, PCI_DEVICE_ID); + + if ((cpu_id != CPUID_TIGERLAKE_A0) && (cpu_id != CPUID_TIGERLAKE_B0)) + return false; + + return ((mchid == PCI_DEVICE_ID_INTEL_TGL_ID_U_2_2) || + (mchid == PCI_DEVICE_ID_INTEL_TGL_ID_U_4_2)); +} + +int get_supported_lpm_mask(struct soc_intel_tigerlake_config *config) +{ + int disable_mask; + + /* Disable any sub-states requested by mainboard */ + disable_mask = config->LpmStateDisableMask; + + /* UP3 does not support S0i2.2/S0i3.3/S0i3.4 */ + if (platform_is_up3()) + disable_mask |= LPM_S0i3_3 | LPM_S0i3_4 | LPM_S0i2_2; + + /* If external bypass is not used, S0i3 isn't recommended. */ + if (config->external_bypass == false) + disable_mask |= LPM_S0i3_0 | LPM_S0i3_1 | LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4; + + /* If external clock gating is not implemented, S0i3.4 isn't recommended. */ + if (config->external_clk_gated == false) + disable_mask |= LPM_S0i3_4; + + /* + * If external phy gating is not implemented, + * S0i3.3/S0i3.4/S0i2.2 are not recommended. + */ + if (config->external_phy_gated == false) + disable_mask |= LPM_S0i3_3 | LPM_S0i3_4 | LPM_S0i2_2; + + /* If CNVi or ISH is used, S0i3.2/S0i3.3/S0i3.4 cannot be achieved. */ + if (is_devfn_enabled(PCH_DEVFN_CNVI_WIFI) || is_devfn_enabled(PCH_DEVFN_ISH)) + disable_mask |= LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4; + + return LPM_S0iX_ALL & ~disable_mask; +} |