aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/skylake/pmc.c
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2015-08-07 22:29:42 -0500
committerAaron Durbin <adurbin@chromium.org>2015-08-14 15:20:10 +0200
commit9a8dc37cdd9486926c6b5416dd48f4f075b2612d (patch)
tree9ffb787910a9361d1024397c99ec7654a99a91af /src/soc/intel/skylake/pmc.c
parent799bf781fdc71baa2332fc75f2a382c15f2ce321 (diff)
skylake: provide GPE0 routing devicetree configuration
On skylake the GPE0 routing can be dynamically changed to a particular GPIO group. Provide the ability for the mainboard to set the route accordingly. If any of the values in the devicetree are the same the current setting in the PMC register is used. The GPIO communities need to have matching configuration for the plumbing to work properly. BUG=chrome-os-partner:43778 BRANCH=None TEST=Built and booted glados w/ and w/o devicetree changes. Fields are set accordingly. Original-Change-Id: I263d648c8ea8a70b21570f01b333d05a5fa2a4e3 Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/291930 Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Change-Id: I966d38bc197dbb52a2ba50927c06e243e169afbe Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/11203 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/soc/intel/skylake/pmc.c')
-rw-r--r--src/soc/intel/skylake/pmc.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c
index 2c794cabea..b6c35ebb4f 100644
--- a/src/soc/intel/skylake/pmc.c
+++ b/src/soc/intel/skylake/pmc.c
@@ -27,6 +27,7 @@
#include <pc80/mc146818rtc.h>
#include <reg_script.h>
#include <string.h>
+#include <soc/gpio.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <soc/pmc.h>
@@ -147,6 +148,42 @@ static void pch_rtc_init(void)
#endif
}
+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;
@@ -187,9 +224,9 @@ static void pch_power_options(void)
}
pci_write_config16(dev, GEN_PMCON_B, reg16);
printk(BIOS_INFO, "Set power %s after power failure.\n", state);
- /* GPE setup based on device tree configuration */
- enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,
- config->gpe0_en_3, config->gpe0_en_4);
+
+ /* Set up GPE configuration. */
+ pmc_gpe_init(config);
/* SMI setup based on device tree configuration */
enable_alt_smi(config->ec_smi_gpio, config->alt_gp_smi_en);