From 771d611f9ea6aa9b6dbf0ea0fffa5fb48e059351 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 29 Nov 2017 16:17:13 +0530 Subject: soc/intel/skylake: Set low maximum temperature threshold for Thermal Device PMC logic shuts down the thermal sensor when CPU is in a C-state and DTS Temp <= Low Temp Threshold in case Dynamic Thermal Shutdown in S0ix is enabled. BUG=b:69110373 BRANCH=none TEST=Ensure Thermal Device(B0: D20: F2) TSPM offset 0x1c[LTT (8:0)] value is 0xFA. Change-Id: I94d09a28bf1ea07a53cfa04c54752358bafca610 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/22419 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin Reviewed-by: Sumeet R Pawnikar Reviewed-by: Furquan Shaikh --- src/soc/intel/skylake/thermal.c | 100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/soc/intel/skylake/thermal.c (limited to 'src/soc/intel/skylake/thermal.c') 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 +#include +#include +#include +#include +#include +#include +#include + +#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); +} -- cgit v1.2.3