skylake: Prepare GPE for use in bootblock
Export the pmc_gpe_init() function from pmc.c to pmutil.c so it can be used in bootblock, and then call it from there to initialize any GPEs for use in firmware. BUG=chrome-os-partner:58666 TEST=test working GPE as TPM interrupt on skylake board Change-Id: I6b4f7d0aa689db42dc455075f84ab5694e8c9661 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://review.coreboot.org/17135 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
This commit is contained in:
parent
64ce1d122c
commit
f0ba2259b8
|
@ -301,6 +301,9 @@ void pch_early_init(void)
|
||||||
/* Program SMBUS_BASE_ADDRESS and Enable it */
|
/* Program SMBUS_BASE_ADDRESS and Enable it */
|
||||||
enable_smbus();
|
enable_smbus();
|
||||||
|
|
||||||
|
/* Set up GPE configuration */
|
||||||
|
pmc_gpe_init();
|
||||||
|
|
||||||
soc_config_rtc();
|
soc_config_rtc();
|
||||||
|
|
||||||
enable_heci();
|
enable_heci();
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0)
|
#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0)
|
||||||
#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func)
|
#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func)
|
||||||
|
|
||||||
#if ENV_RAMSTAGE
|
#if ENV_RAMSTAGE && !defined(__SIMPLE_DEVICE__)
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot))
|
#define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot))
|
||||||
|
|
|
@ -186,6 +186,9 @@ uint16_t smbus_tco_regs(void);
|
||||||
/* Set the DISB after DRAM init */
|
/* Set the DISB after DRAM init */
|
||||||
void pmc_set_disb(void);
|
void pmc_set_disb(void);
|
||||||
|
|
||||||
|
/* Initialize GPEs */
|
||||||
|
void pmc_gpe_init(void);
|
||||||
|
|
||||||
static inline int deep_s3_enabled(void)
|
static inline int deep_s3_enabled(void)
|
||||||
{
|
{
|
||||||
uint32_t deep_s3_pol;
|
uint32_t deep_s3_pol;
|
||||||
|
|
|
@ -129,42 +129,6 @@ static void pch_rtc_init(void)
|
||||||
cmos_init(rtc_failed);
|
cmos_init(rtc_failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmc_gpe_init(config_t *config)
|
|
||||||
{
|
|
||||||
uint8_t *pmc_regs;
|
|
||||||
uint32_t gpio_cfg;
|
|
||||||
uint32_t gpio_cfg_reg;
|
|
||||||
const uint32_t gpio_cfg_mask =
|
|
||||||
(GPE0_DWX_MASK << GPE0_DW0_SHIFT) |
|
|
||||||
(GPE0_DWX_MASK << GPE0_DW1_SHIFT) |
|
|
||||||
(GPE0_DWX_MASK << GPE0_DW2_SHIFT);
|
|
||||||
|
|
||||||
pmc_regs = pmc_mmio_regs();
|
|
||||||
gpio_cfg = 0;
|
|
||||||
|
|
||||||
/* Route the GPIOs to the GPE0 block. Determine that all values
|
|
||||||
* are different, and if they aren't use the reset values. */
|
|
||||||
if (config->gpe0_dw0 == config->gpe0_dw1 ||
|
|
||||||
config->gpe0_dw1 == config->gpe0_dw2) {
|
|
||||||
printk(BIOS_INFO, "PMC: Using default GPE route.\n");
|
|
||||||
gpio_cfg = read32(pmc_regs + GPIO_CFG);
|
|
||||||
} else {
|
|
||||||
gpio_cfg |= (uint32_t)config->gpe0_dw0 << GPE0_DW0_SHIFT;
|
|
||||||
gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT;
|
|
||||||
gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT;
|
|
||||||
}
|
|
||||||
gpio_cfg_reg = read32(pmc_regs + GPIO_CFG) & ~gpio_cfg_mask;
|
|
||||||
gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
|
|
||||||
write32(pmc_regs + GPIO_CFG, gpio_cfg_reg);
|
|
||||||
|
|
||||||
/* Set the routes in the GPIO communities as well. */
|
|
||||||
gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT);
|
|
||||||
|
|
||||||
/* Set GPE enables based on devictree. */
|
|
||||||
enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,
|
|
||||||
config->gpe0_en_3, config->gpe0_en_4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pch_power_options(void)
|
static void pch_power_options(void)
|
||||||
{
|
{
|
||||||
u16 reg16;
|
u16 reg16;
|
||||||
|
@ -172,7 +136,6 @@ static void pch_power_options(void)
|
||||||
/*PMC Controller Device 0x1F, Func 02*/
|
/*PMC Controller Device 0x1F, Func 02*/
|
||||||
device_t dev = PCH_DEV_PMC;
|
device_t dev = PCH_DEV_PMC;
|
||||||
/* Get the chip configuration */
|
/* Get the chip configuration */
|
||||||
config_t *config = dev->chip_info;
|
|
||||||
int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
|
int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -207,7 +170,7 @@ static void pch_power_options(void)
|
||||||
printk(BIOS_INFO, "Set power %s after power failure.\n", state);
|
printk(BIOS_INFO, "Set power %s after power failure.\n", state);
|
||||||
|
|
||||||
/* Set up GPE configuration. */
|
/* Set up GPE configuration. */
|
||||||
pmc_gpe_init(config);
|
pmc_gpe_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
|
static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
* and the differences between PCH variants.
|
* and the differences between PCH variants.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define __SIMPLE_DEVICE__
|
||||||
|
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/pci.h>
|
#include <device/pci.h>
|
||||||
|
@ -27,6 +29,7 @@
|
||||||
#include <halt.h>
|
#include <halt.h>
|
||||||
#include <rules.h>
|
#include <rules.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <soc/gpe.h>
|
||||||
#include <soc/gpio.h>
|
#include <soc/gpio.h>
|
||||||
#include <soc/iomap.h>
|
#include <soc/iomap.h>
|
||||||
#include <soc/lpc.h>
|
#include <soc/lpc.h>
|
||||||
|
@ -34,6 +37,7 @@
|
||||||
#include <soc/pm.h>
|
#include <soc/pm.h>
|
||||||
#include <soc/pmc.h>
|
#include <soc/pmc.h>
|
||||||
#include <soc/smbus.h>
|
#include <soc/smbus.h>
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
/* Print status bits with descriptive names */
|
/* Print status bits with descriptive names */
|
||||||
static void print_status_bits(u32 status, const char *bit_names[])
|
static void print_status_bits(u32 status, const char *bit_names[])
|
||||||
|
@ -465,3 +469,47 @@ void poweroff(void)
|
||||||
if (!ENV_SMM)
|
if (!ENV_SMM)
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pmc_gpe_init(void)
|
||||||
|
{
|
||||||
|
ROMSTAGE_CONST struct soc_intel_skylake_config *config;
|
||||||
|
ROMSTAGE_CONST struct device *dev = dev_find_slot(0, PCH_DEVFN_PMC);
|
||||||
|
uint8_t *pmc_regs;
|
||||||
|
uint32_t gpio_cfg;
|
||||||
|
uint32_t gpio_cfg_reg;
|
||||||
|
const uint32_t gpio_cfg_mask =
|
||||||
|
(GPE0_DWX_MASK << GPE0_DW0_SHIFT) |
|
||||||
|
(GPE0_DWX_MASK << GPE0_DW1_SHIFT) |
|
||||||
|
(GPE0_DWX_MASK << GPE0_DW2_SHIFT);
|
||||||
|
|
||||||
|
/* Look up the device in devicetree */
|
||||||
|
if (!dev || !dev->chip_info) {
|
||||||
|
printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config = dev->chip_info;
|
||||||
|
pmc_regs = pmc_mmio_regs();
|
||||||
|
|
||||||
|
/* Route the GPIOs to the GPE0 block. Determine that all values
|
||||||
|
* are different, and if they aren't use the reset values. */
|
||||||
|
gpio_cfg = 0;
|
||||||
|
if (config->gpe0_dw0 == config->gpe0_dw1 ||
|
||||||
|
config->gpe0_dw1 == config->gpe0_dw2) {
|
||||||
|
printk(BIOS_INFO, "PMC: Using default GPE route.\n");
|
||||||
|
gpio_cfg = read32(pmc_regs + GPIO_CFG);
|
||||||
|
} else {
|
||||||
|
gpio_cfg |= (uint32_t)config->gpe0_dw0 << GPE0_DW0_SHIFT;
|
||||||
|
gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT;
|
||||||
|
gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT;
|
||||||
|
}
|
||||||
|
gpio_cfg_reg = read32(pmc_regs + GPIO_CFG) & ~gpio_cfg_mask;
|
||||||
|
gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
|
||||||
|
write32(pmc_regs + GPIO_CFG, gpio_cfg_reg);
|
||||||
|
|
||||||
|
/* Set the routes in the GPIO communities as well. */
|
||||||
|
gpio_route_gpe(gpio_cfg_reg >> GPE0_DW0_SHIFT);
|
||||||
|
|
||||||
|
/* Set GPE enables based on devictree. */
|
||||||
|
enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,
|
||||||
|
config->gpe0_en_3, config->gpe0_en_4);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue