summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/skylake/Makefile.inc1
-rw-r--r--src/soc/intel/skylake/chip.h3
-rw-r--r--src/soc/intel/skylake/finalize.c10
-rw-r--r--src/soc/intel/skylake/include/soc/iomap.h2
-rw-r--r--src/soc/intel/skylake/include/soc/thermal.h24
-rw-r--r--src/soc/intel/skylake/thermal.c100
6 files changed, 140 insertions, 0 deletions
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index 3a6dd2d1dd..b5fae3de8d 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -67,6 +67,7 @@ ramstage-y += smi.c
ramstage-y += smmrelocate.c
ramstage-y += spi.c
ramstage-y += systemagent.c
+ramstage-y += thermal.c
ramstage-y += uart.c
ramstage-$(CONFIG_UART_DEBUG) += uart_debug.c
ramstage-y += vr_config.c
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index 2c282bc17f..e539019ca0 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -527,6 +527,9 @@ struct soc_intel_skylake_config {
* 2 - VR mailbox command sent for IA/GT/SA rails.
*/
u8 IslVrCmd;
+
+ /* PCH Trip Temperature */
+ u8 pch_trip_temp;
};
typedef struct soc_intel_skylake_config config_t;
diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c
index bcaa283598..25b7484eca 100644
--- a/src/soc/intel/skylake/finalize.c
+++ b/src/soc/intel/skylake/finalize.c
@@ -32,6 +32,7 @@
#include <soc/pm.h>
#include <soc/smbus.h>
#include <soc/systemagent.h>
+#include <soc/thermal.h>
#include <stdlib.h>
#define PSF_BASE_ADDRESS 0xA00
@@ -116,6 +117,15 @@ static void pch_finalize_script(void)
config = dev->chip_info;
/*
+ * Set low maximum temp value used for dynamic thermal sensor
+ * shutdown consideration.
+ *
+ * If Dynamic Thermal Shutdown is enabled then PMC logic shuts down the
+ * thermal sensor when CPU is in a C-state and DTS Temp <= LTT.
+ */
+ pch_thermal_configuration();
+
+ /*
* Disable ACPI PM timer based on dt policy
*
* Disabling ACPI PM timer is necessary for XTAL OSC shutdown.
diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h
index 7e99d9984c..0a573acb38 100644
--- a/src/soc/intel/skylake/include/soc/iomap.h
+++ b/src/soc/intel/skylake/include/soc/iomap.h
@@ -64,6 +64,8 @@
#define HECI1_BASE_ADDRESS 0xfed1a000
+#define THERMAL_BASE_ADDRESS 0xfe600000
+
/* CPU Trace reserved memory size */
#define GDXC_MOT_MEMORY_SIZE (96*MiB)
#define GDXC_IOT_MEMORY_SIZE (32*MiB)
diff --git a/src/soc/intel/skylake/include/soc/thermal.h b/src/soc/intel/skylake/include/soc/thermal.h
new file mode 100644
index 0000000000..31c47c6361
--- /dev/null
+++ b/src/soc/intel/skylake/include/soc/thermal.h
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_THERMAL_H_
+#define _SOC_THERMAL_H_
+
+#define THERMAL_SENSOR_POWER_MANAGEMENT 0x1c
+
+/* Enable thermal sensor power management */
+void pch_thermal_configuration(void);
+
+#endif
diff --git a/src/soc/intel/skylake/thermal.c b/src/soc/intel/skylake/thermal.c
new file mode 100644
index 0000000000..01a4f26259
--- /dev/null
+++ b/src/soc/intel/skylake/thermal.c
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/thermal.h>
+
+#define MAX_TRIP_TEMP 205
+#define DEFAULT_TRIP_TEMP 50
+
+static void *pch_thermal_get_bar(struct device *dev)
+{
+ uintptr_t bar;
+
+ bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+ /*
+ * Bits [31:12] are the base address as per EDS for Thermal Device,
+ * Don't care about [11:0] bits
+ */
+ return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
+}
+
+static void pch_thermal_set_bar(struct device *dev, uintptr_t tempbar)
+{
+ uint8_t pcireg;
+
+ /* Assign Resources to Thermal Device */
+ /* Clear BIT 1-2 of Command Register */
+ pcireg = pci_read_config8(dev, PCI_COMMAND);
+ pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+ pci_write_config8(dev, PCI_COMMAND, pcireg);
+
+ /* Program Temporary BAR for Thermal Device */
+ pci_write_config32(dev, PCI_BASE_ADDRESS_0, tempbar);
+ pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0x0);
+
+ /* Enable Bus Master and MMIO Space */
+ pcireg = pci_read_config8(dev, PCI_COMMAND);
+ pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config8(dev, PCI_COMMAND, pcireg);
+}
+
+/* PCH Low Temp Threshold (LTT) */
+static uint16_t pch_get_ltt_value(struct device *dev)
+{
+ static struct soc_intel_skylake_config *config;
+ uint16_t ltt_value;
+ uint16_t trip_temp = DEFAULT_TRIP_TEMP;
+
+ config = dev->chip_info;
+
+ if (config->pch_trip_temp)
+ trip_temp = config->pch_trip_temp;
+
+ if (trip_temp > MAX_TRIP_TEMP)
+ die("Input PCH temp trip is higher than allowed range!");
+
+ /* Trip Point Temp = (LTT / 2 - 50 degree C) */
+ ltt_value = (trip_temp + 50) * 2;
+
+ return ltt_value;
+}
+
+/* Enable thermal sensor power management */
+void pch_thermal_configuration(void)
+{
+ uint16_t reg16;
+ struct device *dev = PCH_DEV_THERMAL;
+ void *thermalbar = pch_thermal_get_bar(dev);
+
+ /* Use default pre-ram bar */
+ if (!thermalbar) {
+ pch_thermal_set_bar(dev, THERMAL_BASE_ADDRESS);
+ thermalbar = (void *)THERMAL_BASE_ADDRESS;
+ }
+
+ /* Set Low Temp Threshold (LTT) at TSPM offset 0x1c[8:0] */
+ reg16 = read16(thermalbar + THERMAL_SENSOR_POWER_MANAGEMENT);
+ reg16 &= ~0x1ff;
+ /* Low Temp Threshold (LTT) */
+ reg16 |= pch_get_ltt_value(dev);
+ write16(thermalbar + THERMAL_SENSOR_POWER_MANAGEMENT, reg16);
+}