soc/intel/common/thermal: Allow thermal configuration over PMC

Thermal configuration has evolved over PCH generations where
latest PCH has provided an option to allow thermal configuration
using PMC PWRMBASE registers.

This patch adds an option for impacted SoC to select the Kconfig
for allowing thermal configuration using PMC PCH MMIO space.

BUG=b:193774296
TEST=Able to build and boot hatch and adlrvp platform.

Change-Id: I0c6ae72610da39fc18ff252c440d006e83c570a0
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59209
Reviewed-by:  Felix Singer <felixsinger@posteo.net>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: EricR Lai <ericr_lai@compal.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2021-11-19 13:49:21 +05:30
parent d7375b3fdd
commit 2ee30add35
4 changed files with 126 additions and 0 deletions

View File

@ -3,6 +3,33 @@
#ifndef _SOC_INTEL_COMMON_BLOCK_THERMAL_H_
#define _SOC_INTEL_COMMON_BLOCK_THERMAL_H_
/* Catastrophic Trip Point Enable */
#define PMC_PWRM_THERMAL_CTEN 0x150c
/* Policy Lock-Down Bit */
#define PMC_PWRM_THERMAL_CTEN_CTENLOCK (1 << 31)
/* Catastrophic Power-Down Enable */
#define PMC_PWRM_THERMAL_CTEN_CPDEN (1 << 0)
/* EC Thermal Sensor Reporting Enable */
#define PMC_PWRM_THERMAL_ECRPTEN 0x1510
/* Lock-Down Bit */
#define PMC_PWRM_THERMAL_ECRPTEN_ECRPTENLOCK (1 << 31)
/* Enable PMC to EC Temp Reporting */
#define PMC_PWRM_THERMAL_ECRPTEN_EN_RPT (1 << 0)
/* Throttle Levels */
#define PMC_PWRM_THERMAL_TL 0x1520
/* TL LOCK */
#define PMC_PWRM_THERMAL_TL_TLLOCK (1 << 31)
/* TT Enable */
#define PMC_PWRM_THERMAL_TL_TTEN (1 << 29)
/* Throttle Levels Enable */
#define PMC_PWRM_THERMAL_TLEN 0x1528
/* TLENLOCK */
#define PMC_PWRM_THERMAL_TLEN_TLENLOCK (1 << 31)
/* PCH Hot Level Control */
#define PMC_PWRM_THERMAL_PHLC 0x1540
/* PHL Lock */
#define PMC_PWRM_THERMAL_PHLC_PHLCLOCK (1 << 31)
/* Enable thermal sensor power management */
void pch_thermal_configuration(void);

View File

@ -3,3 +3,10 @@ config SOC_INTEL_COMMON_BLOCK_THERMAL
default n
help
This option allows to configure PCH thermal registers for supported PCH.
config SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC
bool
default n
help
This option allows to configure PCH thermal registers using PMC PWRMBASE
for chipsets since Tiger Lake PCH.

View File

@ -1,2 +1,3 @@
romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL) += thermal.c
romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC) += thermal_pmc.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL) += thermal.c

View File

@ -0,0 +1,91 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <device/mmio.h>
#include <intelblocks/cfg.h>
#include <intelblocks/pmclib.h>
#include <intelblocks/thermal.h>
#define MAX_TRIP_TEMP 205
/* This is the safest default Trip Temp value */
#define DEFAULT_TRIP_TEMP 50
/*
* Trip Point = T2L | T1L | T0L where T2L > T1L > T0L
* T2L = Bit 28:20
* T1L = Bit 18:10
* T0L = Bit 8:0
*/
#define GET_LTT_VALUE(x) ((x + 10) << 20 | (x + 5) << 10 | x)
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 uint32_t pch_get_ltt_value(void)
{
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!");
return GET_LTT_VALUE(thermal_config);
}
/*
* Thermal configuration has evolved over time. With older platform the
* thermal device is sitting over PCI and allow to configure its configuration
* register by accessing the PCI configuration space or MMIO space.
*
* Since Tiger Lake, thermal registers are being moved behind the PMC PCI device
* hence, accessing thermal configuration registers would need making access
* to PWRMBASE. In this case SoC Kconfig to select
* SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC to allow thermal configuration.
*/
void pch_thermal_configuration(void)
{
uintptr_t pmc_bar = soc_read_pmc_base();
struct pmc_thermal_config {
uint16_t offset;
uint32_t mask;
uint32_t value;
} config[] = {
{
.offset = PMC_PWRM_THERMAL_CTEN,
.value = PMC_PWRM_THERMAL_CTEN_CPDEN | PMC_PWRM_THERMAL_CTEN_CTENLOCK,
},
{
.offset = PMC_PWRM_THERMAL_ECRPTEN,
.value = PMC_PWRM_THERMAL_ECRPTEN_EN_RPT
| PMC_PWRM_THERMAL_ECRPTEN_ECRPTENLOCK,
},
{
.offset = PMC_PWRM_THERMAL_TL,
.mask = ~0,
.value = pch_get_ltt_value() | PMC_PWRM_THERMAL_TL_TTEN
| PMC_PWRM_THERMAL_TL_TLLOCK,
},
{
.offset = PMC_PWRM_THERMAL_PHLC,
.value = PMC_PWRM_THERMAL_PHLC_PHLCLOCK,
},
{
.offset = PMC_PWRM_THERMAL_TLEN,
.value = PMC_PWRM_THERMAL_TLEN_TLENLOCK,
},
};
for (int i = 0; i < ARRAY_SIZE(config); i++)
clrsetbits32((void *)(pmc_bar + config[i].offset), config[i].mask,
config[i].value);
}