blob: f88699531e854785b738d463feacc93c405e4d00 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Sumeet Pawnikar047cac72019-05-29 23:38:15 +05302
3#include <console/console.h>
4#include <device/mmio.h>
Kyösti Mälkki32d47eb2019-09-28 00:00:30 +03005#include <intelblocks/cfg.h>
Sumeet Pawnikar047cac72019-05-29 23:38:15 +05306#include <intelblocks/thermal.h>
7#include <soc/pci_devs.h>
8
9#define THERMAL_SENSOR_POWER_MANAGEMENT 0x1c
10#define CATASTROPHIC_TRIP_POINT_MASK 0x1ff
11#define MAX_TRIP_TEMP 205
12/* This is the safest default Trip Temp value */
13#define DEFAULT_TRIP_TEMP 50
14#define GET_LTT_VALUE(x) (((x) + 50) * (2))
15
16static uint8_t get_thermal_trip_temp(void)
17{
18 const struct soc_intel_common_config *common_config;
19 common_config = chip_get_common_soc_structure();
20
21 return common_config->pch_thermal_trip;
22}
23
24/* PCH Low Temp Threshold (LTT) */
25static uint16_t pch_get_ltt_value(struct device *dev)
26{
27 uint16_t ltt_value;
28 uint8_t thermal_config;
29
30 thermal_config = get_thermal_trip_temp();
31 if (!thermal_config)
32 thermal_config = DEFAULT_TRIP_TEMP;
33
34 if (thermal_config > MAX_TRIP_TEMP)
35 die("Input PCH temp trip is higher than allowed range!");
36
37 /* Trip Point Temp = (LTT / 2 - 50 degree C) */
38 ltt_value = GET_LTT_VALUE(thermal_config);
39
40 return ltt_value;
41}
42
43/* Enable thermal sensor power management */
44void pch_thermal_configuration(void)
45{
46 uint16_t reg16;
47 uintptr_t thermalbar;
48 uintptr_t thermalbar_pm;
49 struct device *dev;
50 struct resource *res;
51
52 dev = pcidev_path_on_root(PCH_DEVFN_THERMAL);
53 if (!dev) {
54 printk(BIOS_ERR, "ERROR: PCH_DEVFN_THERMAL device not found!\n");
55 return;
56 }
57
Angel Ponsc1bfbe02021-11-03 13:18:53 +010058 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
Sumeet Pawnikar047cac72019-05-29 23:38:15 +053059 if (!res) {
60 printk(BIOS_ERR, "ERROR: PCH thermal device not found!\n");
61 return;
62 }
63
64 /* Get the base address of the resource */
65 thermalbar = res->base;
66
67 /* Get the required thermal address to write the register value */
68 thermalbar_pm = thermalbar + THERMAL_SENSOR_POWER_MANAGEMENT;
69
70 /* Set Low Temp Threshold (LTT) at TSPM offset 0x1c[8:0] */
71 reg16 = read16((uint16_t *)thermalbar_pm);
72 reg16 &= ~CATASTROPHIC_TRIP_POINT_MASK;
73 /* Low Temp Threshold (LTT) */
74 reg16 |= pch_get_ltt_value(dev);
75 write16((uint16_t *)thermalbar_pm, reg16);
76}