diff options
author | Subrata Banik <subrata.banik@intel.com> | 2018-05-17 18:40:32 +0530 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-01-10 12:18:34 +0000 |
commit | 7bc4dc5648c6ff37a847e99d7acee11e3e72a79d (patch) | |
tree | c7137be28a68c96d3711c77ef7bbd9d288d6569f /src/soc/intel/common/block | |
parent | e7184b0ad07b0d3fe3e2f58bacd5e10e3cd88a79 (diff) |
soc/intel/common/block: Move tco common functions into block/smbus
This patch cleans soc/intel/{apl/cnl/icl/skl} by moving common soc
code into common/block/smbus.
BUG=b:78109109
BRANCH=NONE
TEST=Build and boot KBL/CNL/APL/ICL platform.
Change-Id: I34b33922cafee9f31702587e0f9c03b64f0781b8
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Signed-off-by: Maulik V Vaghela <maulik.v.vaghela@intel.com>
Reviewed-on: https://review.coreboot.org/c/26166
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Diffstat (limited to 'src/soc/intel/common/block')
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/pmclib.h | 7 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/tco.h | 36 | ||||
-rw-r--r-- | src/soc/intel/common/block/pmc/pmclib.c | 3 | ||||
-rw-r--r-- | src/soc/intel/common/block/smbus/Kconfig | 11 | ||||
-rw-r--r-- | src/soc/intel/common/block/smbus/Makefile.inc | 7 | ||||
-rw-r--r-- | src/soc/intel/common/block/smbus/tco.c | 139 | ||||
-rw-r--r-- | src/soc/intel/common/block/smm/smihandler.c | 1 |
7 files changed, 196 insertions, 8 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/pmclib.h b/src/soc/intel/common/block/include/intelblocks/pmclib.h index e1c29be1ad..82eb2ae4c4 100644 --- a/src/soc/intel/common/block/include/intelblocks/pmclib.h +++ b/src/soc/intel/common/block/include/intelblocks/pmclib.h @@ -93,13 +93,6 @@ uint32_t pmc_clear_tco_status(void); */ const char *const *soc_tco_sts_array(size_t *a); -/* - * Resets the tco status registers. This function clears the tco_sts register - * and returns the sts and enable bits set. - */ -uint32_t soc_reset_tco_status(void); - - /* GPE */ /* diff --git a/src/soc/intel/common/block/include/intelblocks/tco.h b/src/soc/intel/common/block/include/intelblocks/tco.h new file mode 100644 index 0000000000..86fa33b61a --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/tco.h @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017-2018 Intel Corporation. + * + * 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_TCO_H +#define SOC_INTEL_COMMON_BLOCK_TCO_H + +#include <stdint.h> + +/* + * Enable TCO BAR using SMBUS TCO base to access TCO related register + * also disable the timer. + */ +void tco_configure(void); +/* Lockdown TCO registers before booting to OS */ +void tco_lockdown(void); +/* + * Resets the tco status registers. This function clears the tco_sts register + * and returns the status bits set. + */ +uint32_t tco_reset_status(void); +uint16_t tco_read_reg(uint16_t tco_reg); +void tco_write_reg(uint16_t tco_reg, uint16_t value); + +#endif /* SOC_INTEL_COMMON_BLOCK_TCO_H */ diff --git a/src/soc/intel/common/block/pmc/pmclib.c b/src/soc/intel/common/block/pmc/pmclib.c index 4a1da9ecb9..a4696805a1 100644 --- a/src/soc/intel/common/block/pmc/pmclib.c +++ b/src/soc/intel/common/block/pmc/pmclib.c @@ -20,6 +20,7 @@ #include <halt.h> #include <intelblocks/pmclib.h> #include <intelblocks/gpio.h> +#include <intelblocks/tco.h> #include <soc/pm.h> #include <string.h> #include <timer.h> @@ -260,7 +261,7 @@ static uint32_t print_tco_status(uint32_t tco_sts) uint32_t pmc_clear_tco_status(void) { - return print_tco_status(soc_reset_tco_status()); + return print_tco_status(tco_reset_status()); } /* GPE */ diff --git a/src/soc/intel/common/block/smbus/Kconfig b/src/soc/intel/common/block/smbus/Kconfig index 4514383364..fe940ccab0 100644 --- a/src/soc/intel/common/block/smbus/Kconfig +++ b/src/soc/intel/common/block/smbus/Kconfig @@ -2,3 +2,14 @@ config SOC_INTEL_COMMON_BLOCK_SMBUS bool help Intel Processor common SMBus support + +config SOC_INTEL_COMMON_BLOCK_TCO + bool + help + Intel Processor common TCO support + +config SOC_INTEL_COMMON_BLOCK_TCO_ENABLE_THROUGH_SMBUS + bool + depends on SOC_INTEL_COMMON_BLOCK_TCO + help + Select this config to enable TCO BAR through SMBUS diff --git a/src/soc/intel/common/block/smbus/Makefile.inc b/src/soc/intel/common/block/smbus/Makefile.inc index 1a10fd9735..309ad9a3d8 100644 --- a/src/soc/intel/common/block/smbus/Makefile.inc +++ b/src/soc/intel/common/block/smbus/Makefile.inc @@ -1,8 +1,15 @@ bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbuslib.c bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbus_early.c +bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbuslib.c romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbus_early.c +romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbuslib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS) += smbus.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c + +postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c +smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c +verstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO) += tco.c diff --git a/src/soc/intel/common/block/smbus/tco.c b/src/soc/intel/common/block/smbus/tco.c new file mode 100644 index 0000000000..14589450d2 --- /dev/null +++ b/src/soc/intel/common/block/smbus/tco.c @@ -0,0 +1,139 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * 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 <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <intelblocks/pcr.h> +#include <intelblocks/tco.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> +#include <soc/pm.h> +#include <soc/smbus.h> + +#define PCR_DMI_TCOBASE 0x2778 +/* Enable TCO I/O range decode. */ +#define TCOEN (1 << 1) + +/* SMBUS TCO base address. */ +#define TCOBASE 0x50 +#define TCOCTL 0x54 +#define TCO_BASE_EN (1 << 8) + +/* Get base address of TCO I/O registers. */ +static uint16_t tco_get_bar(void) +{ + return TCO_BASE_ADDRESS; +} + +uint16_t tco_read_reg(uint16_t tco_reg) +{ + uint16_t tcobase; + + tcobase = tco_get_bar(); + + return inw(tcobase + tco_reg); +} + +void tco_write_reg(uint16_t tco_reg, uint16_t value) +{ + uint16_t tcobase; + + tcobase = tco_get_bar(); + + outw(value, tcobase + tco_reg); +} + +void tco_lockdown(void) +{ + uint16_t tcocnt; + + /* TCO Lock down */ + tcocnt = tco_read_reg(TCO1_CNT); + tcocnt |= TCO_LOCK; + tco_write_reg(TCO1_CNT, tcocnt); +} + +uint32_t tco_reset_status(void) +{ + uint16_t tco1_sts; + uint16_t tco2_sts; + + /* TCO Status 2 register */ + tco2_sts = tco_read_reg(TCO2_STS); + tco2_sts |= TCO_STS_SECOND_TO; + tco_write_reg(TCO2_STS, tco2_sts); + + /* TCO Status 1 register */ + tco1_sts = tco_read_reg(TCO1_STS); + + return (tco2_sts << 16) | tco1_sts; +} + +/* Stop TCO timer */ +static void tco_timer_disable(void) +{ + uint16_t tcocnt; + + /* Program TCO timer halt */ + tcocnt = tco_read_reg(TCO1_CNT); + tcocnt |= TCO_TMR_HLT; + tco_write_reg(TCO1_CNT, tcocnt); +} + +/* Enable TCO BAR using SMBUS TCO base to access TCO related register */ +static void tco_enable_bar(void) +{ + uint32_t reg32; + uint16_t tcobase; +#if defined(__SIMPLE_DEVICE__) + int devfn = PCH_DEVFN_SMBUS; + pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); +#else + struct device *dev; + dev = PCH_DEV_SMBUS; +#endif + + /* Disable TCO in SMBUS Device first before changing Base Address */ + reg32 = pci_read_config32(dev, TCOCTL); + reg32 &= ~TCO_BASE_EN; + pci_write_config32(dev, TCOCTL, reg32); + + /* Program TCO Base */ + tcobase = tco_get_bar(); + pci_write_config32(dev, TCOBASE, tcobase); + + /* Enable TCO in SMBUS */ + pci_write_config32(dev, TCOCTL, reg32 | TCO_BASE_EN); + + /* + * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] + */ + pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN); +} + +/* + * Enable TCO BAR using SMBUS TCO base to access TCO related register + * also disable the timer. + */ +void tco_configure(void) +{ + if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_TCO_ENABLE_THROUGH_SMBUS)) + tco_enable_bar(); + + tco_timer_disable(); +} diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index 538028d76a..16f31b6756 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -31,6 +31,7 @@ #include <soc/pm.h> #include <soc/gpio.h> #include <soc/iomap.h> +#include <soc/smbus.h> #include <spi-generic.h> #include <stdint.h> #include <stdlib.h> |