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:
		| @@ -301,6 +301,9 @@ void pch_early_init(void) | ||||
| 	/* Program SMBUS_BASE_ADDRESS and Enable it */ | ||||
| 	enable_smbus(); | ||||
|  | ||||
| 	/* Set up GPE configuration */ | ||||
| 	pmc_gpe_init(); | ||||
|  | ||||
| 	soc_config_rtc(); | ||||
|  | ||||
| 	enable_heci(); | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
| #define _SA_DEVFN(slot)		PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0) | ||||
| #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/pci_def.h> | ||||
| #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 */ | ||||
| void pmc_set_disb(void); | ||||
|  | ||||
| /* Initialize GPEs */ | ||||
| void pmc_gpe_init(void); | ||||
|  | ||||
| static inline int deep_s3_enabled(void) | ||||
| { | ||||
| 	uint32_t deep_s3_pol; | ||||
|   | ||||
| @@ -129,42 +129,6 @@ static void pch_rtc_init(void) | ||||
| 		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) | ||||
| { | ||||
| 	u16 reg16; | ||||
| @@ -172,7 +136,6 @@ static void pch_power_options(void) | ||||
| 	/*PMC Controller Device 0x1F, Func 02*/ | ||||
| 	device_t dev = PCH_DEV_PMC; | ||||
| 	/* Get the chip configuration */ | ||||
| 	config_t *config = dev->chip_info; | ||||
| 	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); | ||||
|  | ||||
| 	/* 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) | ||||
|   | ||||
| @@ -19,6 +19,8 @@ | ||||
|  * and the differences between PCH variants. | ||||
|  */ | ||||
|  | ||||
| #define __SIMPLE_DEVICE__ | ||||
|  | ||||
| #include <arch/io.h> | ||||
| #include <device/device.h> | ||||
| #include <device/pci.h> | ||||
| @@ -27,6 +29,7 @@ | ||||
| #include <halt.h> | ||||
| #include <rules.h> | ||||
| #include <stdlib.h> | ||||
| #include <soc/gpe.h> | ||||
| #include <soc/gpio.h> | ||||
| #include <soc/iomap.h> | ||||
| #include <soc/lpc.h> | ||||
| @@ -34,6 +37,7 @@ | ||||
| #include <soc/pm.h> | ||||
| #include <soc/pmc.h> | ||||
| #include <soc/smbus.h> | ||||
| #include "chip.h" | ||||
|  | ||||
| /* Print status bits with descriptive names */ | ||||
| static void print_status_bits(u32 status, const char *bit_names[]) | ||||
| @@ -465,3 +469,47 @@ void poweroff(void) | ||||
| 	if (!ENV_SMM) | ||||
| 		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); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user