summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/common/block/include/intelblocks/thermal.h27
-rw-r--r--src/soc/intel/common/block/thermal/Kconfig7
-rw-r--r--src/soc/intel/common/block/thermal/Makefile.inc1
-rw-r--r--src/soc/intel/common/block/thermal/thermal_pmc.c91
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);
+}