diff options
Diffstat (limited to 'src/soc/intel/common/block')
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/chip.h | 2 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/thermal.h | 22 | ||||
-rw-r--r-- | src/soc/intel/common/block/thermal/Kconfig | 5 | ||||
-rw-r--r-- | src/soc/intel/common/block/thermal/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/thermal/thermal.c | 89 |
5 files changed, 119 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/chip.h b/src/soc/intel/common/block/include/intelblocks/chip.h index 555bdaa893..9fe165e5b1 100644 --- a/src/soc/intel/common/block/include/intelblocks/chip.h +++ b/src/soc/intel/common/block/include/intelblocks/chip.h @@ -33,6 +33,8 @@ struct soc_intel_common_config { int chipset_lockdown; struct gspi_cfg gspi[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX]; struct dw_i2c_bus_config i2c[CONFIG_SOC_INTEL_I2C_DEV_MAX]; + /* PCH Thermal Trip Temperature in deg C */ + uint8_t pch_thermal_trip; }; /* This function to retrieve soc config structure required by common code */ diff --git a/src/soc/intel/common/block/include/intelblocks/thermal.h b/src/soc/intel/common/block/include/intelblocks/thermal.h new file mode 100644 index 0000000000..ab18eb6d1d --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/thermal.h @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 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_INTEL_COMMON_BLOCK_THERMAL_H_ +#define _SOC_INTEL_COMMON_BLOCK_THERMAL_H_ + +/* Enable thermal sensor power management */ +void pch_thermal_configuration(void); + +#endif diff --git a/src/soc/intel/common/block/thermal/Kconfig b/src/soc/intel/common/block/thermal/Kconfig new file mode 100644 index 0000000000..060517656e --- /dev/null +++ b/src/soc/intel/common/block/thermal/Kconfig @@ -0,0 +1,5 @@ +config SOC_INTEL_COMMON_BLOCK_THERMAL + bool + default n + help + This option allows to configure PCH thermal registers for supported PCH. diff --git a/src/soc/intel/common/block/thermal/Makefile.inc b/src/soc/intel/common/block/thermal/Makefile.inc new file mode 100644 index 0000000000..6f216b3f33 --- /dev/null +++ b/src/soc/intel/common/block/thermal/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL) += thermal.c diff --git a/src/soc/intel/common/block/thermal/thermal.c b/src/soc/intel/common/block/thermal/thermal.c new file mode 100644 index 0000000000..39a98a41d8 --- /dev/null +++ b/src/soc/intel/common/block/thermal/thermal.c @@ -0,0 +1,89 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 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 <console/console.h> +#include <device/mmio.h> +#include <intelblocks/chip.h> +#include <intelblocks/thermal.h> +#include <soc/pci_devs.h> + +#define THERMAL_SENSOR_POWER_MANAGEMENT 0x1c +#define CATASTROPHIC_TRIP_POINT_MASK 0x1ff +#define MAX_TRIP_TEMP 205 +/* This is the safest default Trip Temp value */ +#define DEFAULT_TRIP_TEMP 50 +#define GET_LTT_VALUE(x) (((x) + 50) * (2)) + +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 uint16_t pch_get_ltt_value(struct device *dev) +{ + uint16_t ltt_value; + 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!"); + + /* Trip Point Temp = (LTT / 2 - 50 degree C) */ + ltt_value = GET_LTT_VALUE(thermal_config); + + return ltt_value; +} + +/* Enable thermal sensor power management */ +void pch_thermal_configuration(void) +{ + uint16_t reg16; + uintptr_t thermalbar; + uintptr_t thermalbar_pm; + struct device *dev; + struct resource *res; + + dev = pcidev_path_on_root(PCH_DEVFN_THERMAL); + if (!dev) { + printk(BIOS_ERR, "ERROR: PCH_DEVFN_THERMAL device not found!\n"); + return; + } + + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (!res) { + printk(BIOS_ERR, "ERROR: PCH thermal device not found!\n"); + return; + } + + /* Get the base address of the resource */ + thermalbar = res->base; + + /* Get the required thermal address to write the register value */ + thermalbar_pm = thermalbar + THERMAL_SENSOR_POWER_MANAGEMENT; + + /* Set Low Temp Threshold (LTT) at TSPM offset 0x1c[8:0] */ + reg16 = read16((uint16_t *)thermalbar_pm); + reg16 &= ~CATASTROPHIC_TRIP_POINT_MASK; + /* Low Temp Threshold (LTT) */ + reg16 |= pch_get_ltt_value(dev); + write16((uint16_t *)thermalbar_pm, reg16); +} |