[coreboot-gerrit] Patch set updated for coreboot: soc/intel/apollolake: Add GPE routing code

Shaunak Saha (shaunak.saha@intel.com) gerrit at coreboot.org
Wed Jun 29 11:24:54 CEST 2016


Shaunak Saha (shaunak.saha at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15324

-gerrit

commit 854215e75ef14fff23b5bbc4fcc885e124e1bd26
Author: Shaunak Saha <shaunak.saha at intel.com>
Date:   Tue Jun 7 02:06:28 2016 -0700

    soc/intel/apollolake: Add GPE routing code
    
    This patch adds the basic framework for SCI to GPE routing code.
    
    BUG = chrome-os-partner:53438
    TEST = Toogle pch_sci_l from ec console using gpioset command and
    	see that the sci counter increases in /sys/firmware/acpi/interrupt
    	and also 9 in /proc/interrupts.
    
    Change-Id: I3b3198276530bf6513d94e9bea02ab9751212adf
    Signed-off-by: Shaunak Saha <shaunak.saha at intel.com>
---
 src/soc/intel/apollolake/chip.c                  |  6 +-
 src/soc/intel/apollolake/chip.h                  |  6 ++
 src/soc/intel/apollolake/gpio.c                  | 79 ++++++++++++++++++++++++
 src/soc/intel/apollolake/include/soc/gpio.h      | 13 ++++
 src/soc/intel/apollolake/include/soc/gpio_defs.h | 21 +++++++
 src/soc/intel/apollolake/include/soc/pm.h        |  8 ++-
 6 files changed, 130 insertions(+), 3 deletions(-)

diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index af3310e..02875b0 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -33,6 +33,7 @@
 #include <soc/pci_devs.h>
 #include <spi-generic.h>
 #include <soc/pm.h>
+#include <soc/gpio.h>
 
 #include "chip.h"
 
@@ -275,7 +276,6 @@ struct chip_operations soc_intel_apollolake_ops = {
 
 static void fsp_notify_dummy(void *arg)
 {
-
 	enum fsp_notify_phase ph = (enum fsp_notify_phase) arg;
 	enum fsp_status ret;
 
@@ -285,8 +285,10 @@ static void fsp_notify_dummy(void *arg)
 			fsp_handle_reset(ret);
 	}
 	/* Call END_OF_FIRMWARE Notify after READY_TO_BOOT Notify */
-	if (ph == READY_TO_BOOT)
+	if (ph == READY_TO_BOOT) {
+		pmc_gpe_init();
 		fsp_notify_dummy((void *)END_OF_FIRMWARE);
+	}
 }
 
 BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_EXIT, fsp_notify_dummy,
diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h
index ef82c53..4446ac5 100644
--- a/src/soc/intel/apollolake/chip.h
+++ b/src/soc/intel/apollolake/chip.h
@@ -18,6 +18,8 @@
 #ifndef _SOC_APOLLOLAKE_CHIP_H_
 #define _SOC_APOLLOLAKE_CHIP_H_
 
+#include <soc/gpio_defs.h>
+
 #define CLKREQ_DISABLED		0xf
 
 /* Serial IRQ control. SERIRQ_QUIET is the default (0). */
@@ -79,6 +81,10 @@ struct soc_intel_apollolake_config {
 
 	/* Integrated Sensor Hub */
 	uint8_t integrated_sensor_hub_enable;
+
+	uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
+	uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
+	uint8_t gpe0_dw3; /* GPE0_127_96 STS/EN */
 };
 
 #endif	/* _SOC_APOLLOLAKE_CHIP_H_ */
diff --git a/src/soc/intel/apollolake/gpio.c b/src/soc/intel/apollolake/gpio.c
index d0ef648..ce32592 100644
--- a/src/soc/intel/apollolake/gpio.c
+++ b/src/soc/intel/apollolake/gpio.c
@@ -19,6 +19,9 @@
 #include <gpio.h>
 #include <soc/gpio.h>
 #include <soc/iosf.h>
+#include <soc/pm.h>
+#include <soc/pci_devs.h>
+#include "chip.h"
 
 /* This list must be in order, from highest pad numbers, to lowest pad numbers*/
 static const struct pad_community {
@@ -132,3 +135,79 @@ const char *gpio_acpi_path(gpio_t gpio_num)
 
 	return NULL;
 }
+
+#if ENV_RAMSTAGE
+
+void pmc_gpe_init(void)
+{
+        uint32_t gpio_cfg = 0;
+        uint32_t gpio_cfg_reg;
+	struct soc_intel_apollolake_config *config;
+
+	struct device *dev = NB_DEV_ROOT;
+	if (!dev || !dev->chip_info) {
+		printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
+		return;
+	}
+	config = dev->chip_info;
+
+	uintptr_t pmc_bar = get_pmc_mmio_bar();
+
+	const uint32_t gpio_cfg_mask =
+		(GPE0_DWX_MASK << GPE0_DW1_SHIFT) |
+		(GPE0_DWX_MASK << GPE0_DW2_SHIFT) |
+		(GPE0_DWX_MASK << GPE0_DW3_SHIFT);
+
+	/* Route the GPIOs to the GPE0 block. Determine that all values
+	 * are different, and if they aren't use the reset values.
+	 * DW0 is reserved/unused */
+	if (config->gpe0_dw1 == config->gpe0_dw2 ||
+		config->gpe0_dw2 == config->gpe0_dw3) {
+		printk(BIOS_INFO, "PMC: Using default GPE route.\n");
+		gpio_cfg = read32((void *)pmc_bar + GPIO_GPE_CFG);
+	} else {
+		gpio_cfg |= (uint32_t)config->gpe0_dw1 << GPE0_DW1_SHIFT;
+		gpio_cfg |= (uint32_t)config->gpe0_dw2 << GPE0_DW2_SHIFT;
+		gpio_cfg |= (uint32_t)config->gpe0_dw3 << GPE0_DW3_SHIFT;
+	}
+
+	gpio_cfg_reg = read32((void *)pmc_bar + GPIO_GPE_CFG) & ~gpio_cfg_mask;
+	gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
+
+	write32((void *)pmc_bar + GPIO_GPE_CFG, gpio_cfg_reg);
+
+	/* Set the routes in the GPIO communities as well. */
+	gpio_route_gpe();
+}
+
+void gpio_route_gpe(void)
+{
+	int i;
+	uint32_t misccfg_mask;
+	uint32_t misccfg_value;
+	uint32_t misccfg_gpe0_dw0; /* ACPI GPE0[31:0] */
+	uint32_t misccfg_gpe0_dw1; /* ACPI GPE0[63:32] */
+	uint32_t misccfg_gpe0_dw2; /* ACPI GPE0[95:64] */
+
+	/* Set the group here for community specific MISCCFG register */
+	misccfg_gpe0_dw0 = GPP_7; /* GPE0b */
+	misccfg_gpe0_dw1 = GPP_0; /* GPE0c */
+	misccfg_gpe0_dw2 = GPP_0; /* GPE0d */
+
+	/* Program GPIO_MISCCFG */
+	misccfg_mask = (uint32_t) ~(MISCCFG_GPE0_DW2_MASK |
+			MISCCFG_GPE0_DW1_MASK |
+			MISCCFG_GPE0_DW0_MASK);
+	misccfg_value  = (uint32_t)((misccfg_gpe0_dw2 << MISCCFG_GPE0_DW2_SHIFT)
+		| (misccfg_gpe0_dw1 << MISCCFG_GPE0_DW1_SHIFT)
+		| (misccfg_gpe0_dw0 << MISCCFG_GPE0_DW0_SHIFT));
+
+	for (i = 0; i < ARRAY_SIZE(gpio_communities); i++) {
+		const struct pad_community *comm = &gpio_communities[i];
+
+		iosf_write(comm->port, GPIO_MISCCFG, ((iosf_read(comm->port,
+				GPIO_MISCCFG) & misccfg_mask) | misccfg_value));
+	}
+}
+
+#endif
diff --git a/src/soc/intel/apollolake/include/soc/gpio.h b/src/soc/intel/apollolake/include/soc/gpio.h
index c9d32cc..487dd93 100644
--- a/src/soc/intel/apollolake/include/soc/gpio.h
+++ b/src/soc/intel/apollolake/include/soc/gpio.h
@@ -99,5 +99,18 @@ struct pad_config {
 void gpio_configure_pad(const struct pad_config *cfg);
 void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads);
 
+void pmc_gpe_init(void);
+
+/*
+ * Set the GPIO groups for the GPE blocks. The gpe0_route is interpreted
+ * as the packed configuration for GPE0_DW[2:0]. This basically sets the
+ * MISCCFG register bits:
+ *  dw0 = gpe0_route[11:8]
+ *  dw1 = gpe0_route[15:12]
+ *  dw2 = gpe0_route[19:16].
+ */
+void gpio_route_gpe(void);
+
 #endif /* __ACPI__ */
+
 #endif /* _SOC_APOLLOLAKE_GPIO_H_ */
diff --git a/src/soc/intel/apollolake/include/soc/gpio_defs.h b/src/soc/intel/apollolake/include/soc/gpio_defs.h
index 30c4bdb..d0372ea 100644
--- a/src/soc/intel/apollolake/include/soc/gpio_defs.h
+++ b/src/soc/intel/apollolake/include/soc/gpio_defs.h
@@ -23,6 +23,27 @@
 #ifndef _SOC_APOLLOLAKE_GPIO_DEFS_H_
 #define _SOC_APOLLOLAKE_GPIO_DEFS_H_
 
+/*
+ * There are 8 GPIO groups. GPP_0 -> GPP_8 (Group 3 is not present)
+ */
+#define GPP_0  0 /* SOUTHWEST GPIO #  0 ~ 31 belong to GROUP0 */
+#define GPP_1  1 /* SOUTHWEST GPIO # 32 ~ 42 belong to GROUP1 */
+#define GPP_2  2 /* WEST      GPIO #  0 ~ 25 belong to GROUP2 */
+#define GPP_4  4 /* NORTHWEST GPIO #  0 ~ 17 belong to GROUP4 */
+#define GPP_5  5 /* NORTHWEST GPIO # 32 ~ 63 belong to GROUP5, except # 52 and 60 */
+#define GPP_6  6 /* NORTHWEST GPIO # 64 ~ 76 belong to GROUP6 */
+#define GPP_7  7 /* NORTH     GPIO #  0 ~ 31 belong to GROUP7 */
+#define GPP_8  8 /* NORTH     GPIO # 32 ~ 61 belong to GROUP8 */
+
+#define GPIO_MISCCFG	0x10         /* Miscellaneous Configuration */
+
+#define MISCCFG_GPE0_DW0_SHIFT 8
+#define MISCCFG_GPE0_DW0_MASK (0xf << MISCCFG_GPE0_DW0_SHIFT)
+#define MISCCFG_GPE0_DW1_SHIFT 12
+#define MISCCFG_GPE0_DW1_MASK (0xf << MISCCFG_GPE0_DW1_SHIFT)
+#define MISCCFG_GPE0_DW2_SHIFT 16
+#define MISCCFG_GPE0_DW2_MASK (0xf << MISCCFG_GPE0_DW2_SHIFT)
+
 #define PAD_CFG0_TX_STATE		(1 << 0)
 #define PAD_CFG0_RX_STATE		(1 << 1)
 #define PAD_CFG0_TX_DISABLE		(1 << 8)
diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h
index 3da7dd0..0f1e36a 100644
--- a/src/soc/intel/apollolake/include/soc/pm.h
+++ b/src/soc/intel/apollolake/include/soc/pm.h
@@ -129,10 +129,16 @@
 #       define RPS		(1 <<  2)
 #define GEN_PMCON3		0x1028
 #define ETR			0x1048
+#define GPIO_GPE_CFG		0x1050
+
+#define  GPE0_DWX_MASK          0xf
+#define  GPE0_DW1_SHIFT         4
+#define  GPE0_DW2_SHIFT         8
+#define  GPE0_DW3_SHIFT         12
+
 #	define CF9_LOCK		(1 << 31)
 #	define CF9_GLB_RST	(1 << 20)
 
-
 /* Generic sleep state types */
 #define SLEEP_STATE_S0		0
 #define SLEEP_STATE_S3		3



More information about the coreboot-gerrit mailing list