diff options
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/thermal.h | 27 | ||||
-rw-r--r-- | src/soc/intel/common/block/thermal/Kconfig | 7 | ||||
-rw-r--r-- | src/soc/intel/common/block/thermal/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/thermal/thermal_pmc.c | 91 |
4 files changed, 126 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/thermal.h b/src/soc/intel/common/block/include/intelblocks/thermal.h index 377b2f94dc..aa3318c7c4 100644 --- a/src/soc/intel/common/block/include/intelblocks/thermal.h +++ b/src/soc/intel/common/block/include/intelblocks/thermal.h @@ -3,6 +3,33 @@ #ifndef _SOC_INTEL_COMMON_BLOCK_THERMAL_H_ #define _SOC_INTEL_COMMON_BLOCK_THERMAL_H_ +/* Catastrophic Trip Point Enable */ +#define PMC_PWRM_THERMAL_CTEN 0x150c +/* Policy Lock-Down Bit */ +#define PMC_PWRM_THERMAL_CTEN_CTENLOCK (1 << 31) +/* Catastrophic Power-Down Enable */ +#define PMC_PWRM_THERMAL_CTEN_CPDEN (1 << 0) +/* EC Thermal Sensor Reporting Enable */ +#define PMC_PWRM_THERMAL_ECRPTEN 0x1510 +/* Lock-Down Bit */ +#define PMC_PWRM_THERMAL_ECRPTEN_ECRPTENLOCK (1 << 31) +/* Enable PMC to EC Temp Reporting */ +#define PMC_PWRM_THERMAL_ECRPTEN_EN_RPT (1 << 0) +/* Throttle Levels */ +#define PMC_PWRM_THERMAL_TL 0x1520 +/* TL LOCK */ +#define PMC_PWRM_THERMAL_TL_TLLOCK (1 << 31) +/* TT Enable */ +#define PMC_PWRM_THERMAL_TL_TTEN (1 << 29) +/* Throttle Levels Enable */ +#define PMC_PWRM_THERMAL_TLEN 0x1528 +/* TLENLOCK */ +#define PMC_PWRM_THERMAL_TLEN_TLENLOCK (1 << 31) +/* PCH Hot Level Control */ +#define PMC_PWRM_THERMAL_PHLC 0x1540 +/* PHL Lock */ +#define PMC_PWRM_THERMAL_PHLC_PHLCLOCK (1 << 31) + /* Enable thermal sensor power management */ void pch_thermal_configuration(void); diff --git a/src/soc/intel/common/block/thermal/Kconfig b/src/soc/intel/common/block/thermal/Kconfig index 060517656e..b39c74ca0f 100644 --- a/src/soc/intel/common/block/thermal/Kconfig +++ b/src/soc/intel/common/block/thermal/Kconfig @@ -3,3 +3,10 @@ config SOC_INTEL_COMMON_BLOCK_THERMAL default n help This option allows to configure PCH thermal registers for supported PCH. + +config SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC + bool + default n + help + This option allows to configure PCH thermal registers using PMC PWRMBASE + for chipsets since Tiger Lake PCH. diff --git a/src/soc/intel/common/block/thermal/Makefile.inc b/src/soc/intel/common/block/thermal/Makefile.inc index 951065cd11..2a652192fc 100644 --- a/src/soc/intel/common/block/thermal/Makefile.inc +++ b/src/soc/intel/common/block/thermal/Makefile.inc @@ -1,2 +1,3 @@ romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL) += thermal.c +romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC) += thermal_pmc.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL) += thermal.c diff --git a/src/soc/intel/common/block/thermal/thermal_pmc.c b/src/soc/intel/common/block/thermal/thermal_pmc.c new file mode 100644 index 0000000000..d233e9d56b --- /dev/null +++ b/src/soc/intel/common/block/thermal/thermal_pmc.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/mmio.h> +#include <intelblocks/cfg.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/thermal.h> + +#define MAX_TRIP_TEMP 205 +/* This is the safest default Trip Temp value */ +#define DEFAULT_TRIP_TEMP 50 + +/* + * Trip Point = T2L | T1L | T0L where T2L > T1L > T0L + * T2L = Bit 28:20 + * T1L = Bit 18:10 + * T0L = Bit 8:0 + */ +#define GET_LTT_VALUE(x) ((x + 10) << 20 | (x + 5) << 10 | x) + +static uint8_t get_thermal_trip_temp(void) +{ + const struct soc_intel_common_config *common_config; + common_config = chip_get_common_soc_structure(); + + return common_config->pch_thermal_trip; +} + +/* PCH Low Temp Threshold (LTT) */ +static uint32_t pch_get_ltt_value(void) +{ + uint8_t thermal_config; + + thermal_config = get_thermal_trip_temp(); + if (!thermal_config) + thermal_config = DEFAULT_TRIP_TEMP; + + if (thermal_config > MAX_TRIP_TEMP) + die("Input PCH temp trip is higher than allowed range!"); + + return GET_LTT_VALUE(thermal_config); +} + +/* + * Thermal configuration has evolved over time. With older platform the + * thermal device is sitting over PCI and allow to configure its configuration + * register by accessing the PCI configuration space or MMIO space. + * + * Since Tiger Lake, thermal registers are being moved behind the PMC PCI device + * hence, accessing thermal configuration registers would need making access + * to PWRMBASE. In this case SoC Kconfig to select + * SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC to allow thermal configuration. + */ +void pch_thermal_configuration(void) +{ + uintptr_t pmc_bar = soc_read_pmc_base(); + + struct pmc_thermal_config { + uint16_t offset; + uint32_t mask; + uint32_t value; + } config[] = { + { + .offset = PMC_PWRM_THERMAL_CTEN, + .value = PMC_PWRM_THERMAL_CTEN_CPDEN | PMC_PWRM_THERMAL_CTEN_CTENLOCK, + }, + { + .offset = PMC_PWRM_THERMAL_ECRPTEN, + .value = PMC_PWRM_THERMAL_ECRPTEN_EN_RPT + | PMC_PWRM_THERMAL_ECRPTEN_ECRPTENLOCK, + }, + { + .offset = PMC_PWRM_THERMAL_TL, + .mask = ~0, + .value = pch_get_ltt_value() | PMC_PWRM_THERMAL_TL_TTEN + | PMC_PWRM_THERMAL_TL_TLLOCK, + }, + { + .offset = PMC_PWRM_THERMAL_PHLC, + .value = PMC_PWRM_THERMAL_PHLC_PHLCLOCK, + }, + { + .offset = PMC_PWRM_THERMAL_TLEN, + .value = PMC_PWRM_THERMAL_TLEN_TLENLOCK, + }, + }; + + for (int i = 0; i < ARRAY_SIZE(config); i++) + clrsetbits32((void *)(pmc_bar + config[i].offset), config[i].mask, + config[i].value); +} |