diff options
Diffstat (limited to 'src/soc/intel/common/block/thermal/thermal.c')
-rw-r--r-- | src/soc/intel/common/block/thermal/thermal.c | 89 |
1 files changed, 89 insertions, 0 deletions
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); +} |