diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/intel/skylake/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/skylake/chip.h | 3 | ||||
-rw-r--r-- | src/soc/intel/skylake/finalize.c | 10 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/iomap.h | 2 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/thermal.h | 24 | ||||
-rw-r--r-- | src/soc/intel/skylake/thermal.c | 100 |
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); +} |