[coreboot-gerrit] New patch to review for coreboot: soc/intel/apollolake: GPE routing code

Shaunak Saha (shaunak.saha@intel.com) gerrit at coreboot.org
Thu Jun 23 00:45: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 b78361716857fa0d6304c5e10013e69a90037eb2
Author: Shaunak Saha <shaunak.saha at intel.com>
Date:   Tue Jun 7 02:06:28 2016 -0700

    soc/intel/apollolake: GPE routing code
    
    This patch adds the basic framework for SCI to GPE routing code.
    
    Change-Id: I3b3198276530bf6513d94e9bea02ab9751212adf
    Signed-off-by: Shaunak Saha <shaunak.saha at intel.com>
---
 src/soc/intel/apollolake/chip.c                  |   8 +-
 src/soc/intel/apollolake/chip.h                  |   7 +
 src/soc/intel/apollolake/gpio.c                  | 126 +++++++++++
 src/soc/intel/apollolake/include/soc/gpio.h      |  13 ++
 src/soc/intel/apollolake/include/soc/gpio_defs.h | 255 +++++++++++++++++++++++
 src/soc/intel/apollolake/include/soc/pm.h        |   2 +
 6 files changed, 410 insertions(+), 1 deletion(-)

diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index dd4a0a5..7d0dd33 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -32,6 +32,7 @@
 #include <soc/nvs.h>
 #include <soc/pci_devs.h>
 #include <spi-generic.h>
+#include <soc/gpio.h>
 
 #include "chip.h"
 
@@ -152,7 +153,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;
 
 	if (fsp_notify(ph) != FSP_SUCCESS)
@@ -160,6 +160,12 @@ static void fsp_notify_dummy(void *arg)
 	/* Call END_OF_FIRMWARE Notify after READY_TO_BOOT Notify */
 	if (ph == READY_TO_BOOT)
 		fsp_notify_dummy((void *)END_OF_FIRMWARE);
+
+	if(ph == READY_TO_BOOT)
+	{
+		pmc_gpe_init();
+        }
+
 }
 
 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..7599d4e 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,11 @@ struct soc_intel_apollolake_config {
 
 	/* Integrated Sensor Hub */
 	uint8_t integrated_sensor_hub_enable;
+
+	uint8_t gpe0_dw0; /* GPE0_31_0 STS/EN */
+	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..21e9357 100644
--- a/src/soc/intel/apollolake/gpio.c
+++ b/src/soc/intel/apollolake/gpio.c
@@ -19,6 +19,47 @@
 #include <gpio.h>
 #include <soc/gpio.h>
 #include <soc/iosf.h>
+#include <soc/pm.h>
+#include <soc/iomap.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <soc/pci_devs.h>
+#include <reg_script.h>
+#include <device/pci.h>
+#include "chip.h"
+
+
+/* There are 4 communities with 8 GPIO groups (GPP_[0:8] there is no group 3) */
+struct gpio_community {
+        int port_id;
+        /* Inclusive pads within the community. */
+        gpio_t min;
+        gpio_t max;
+};
+
+/* This is ordered to match ACPI and OS driver. */
+static const struct gpio_community communities[] = {
+        {
+                .port_id = GPIO_SOUTHWEST,
+                .min = GPP_0_0,
+                .max = GPP_1_10,
+        },
+        {
+                .port_id = GPIO_WEST,
+                .min = GPP_2_0,
+                .max = GPP_2_25,
+        },
+        {
+                .port_id = GPIO_NORTHWEST,
+                .min = GPP_4_0,
+                .max = GPP_6_12,
+        },
+        {
+                .port_id = GPIO_NORTH,
+                .min = GPP_7_0,
+                .max = GPP_8_29,
+        },
+};
 
 /* This list must be in order, from highest pad numbers, to lowest pad numbers*/
 static const struct pad_community {
@@ -132,3 +173,88 @@ const char *gpio_acpi_path(gpio_t gpio_num)
 
 	return NULL;
 }
+
+#if ENV_RAMSTAGE
+
+static const struct reg_script pch_pmc_misc_init_script[] = {
+        /* Enable SCI */
+        REG_IO_WRITE32(ACPI_PMIO_BASE + PM1_CNT, SCI_EN),
+        REG_SCRIPT_END
+};
+
+
+void pmc_gpe_init(void)
+{
+        uint32_t gpio_cfg = 0;
+        uint32_t gpio_cfg_reg;
+	struct soc_intel_apollolake_config *config;
+
+	struct device *dev = dev_find_slot(NB_BUS, NB_DEVFN);
+	if (!dev || !dev->chip_info) {
+		printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
+		return;
+	}
+	config = dev->chip_info;
+	reg_script_run_on_dev(dev, pch_pmc_misc_init_script);
+
+	struct device *dev_pmc = dev_find_slot(0, PCI_DEVFN(0xd, 1));
+	uint32_t pmc_bar = pci_read_config32(dev_pmc, PCI_BASE_ADDRESS_0);
+	pmc_bar = pmc_bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
+
+	const uint32_t gpio_cfg_mask =
+		(GPE0_DWX_MASK << GPE0_DW0_SHIFT) |
+		(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_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_CFG) & ~gpio_cfg_mask;
+	gpio_cfg_reg |= gpio_cfg & gpio_cfg_mask;
+
+	write32((void *)pmc_bar + GPIO_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 Data32And;
+	uint32_t Data32Or;
+	uint32_t gpe0_dw1;
+	uint32_t gpe0_dw2;
+	uint32_t gpe0_dw3;
+
+	/* Set the group here for community specific MISCCFG register */
+	gpe0_dw1 = GPP_7; /* GPE0b */
+	gpe0_dw2 = GPP_0; /* GPE0c */
+	gpe0_dw3 = GPP_0; /* GPE0d */
+
+	/*Program GPIO_MISCCFG */
+	Data32And = (uint32_t) ~(GPIO_MISCCFG_GPE0_DW2 | GPIO_MISCCFG_GPE0_DW1 | GPIO_MISCCFG_GPE0_DW0);
+	Data32Or  = (uint32_t)((gpe0_dw3 << N_GPIO_MISCCFG_GPE0_DW2) |
+		(gpe0_dw2 << N_GPIO_MISCCFG_GPE0_DW1) |
+		(gpe0_dw1 << N_GPIO_MISCCFG_GPE0_DW0));
+
+	for (i = 0; i < ARRAY_SIZE(communities); i++) {
+		const struct gpio_community *comm = &communities[i];
+
+	iosf_write( comm->port_id,GPIO_MISCCFG,((iosf_read(GPIO_WEST ,GPIO_MISCCFG) & Data32And) | Data32Or));
+	}
+}
+
+#endif
diff --git a/src/soc/intel/apollolake/include/soc/gpio.h b/src/soc/intel/apollolake/include/soc/gpio.h
index c9d32cc..b813467 100644
--- a/src/soc/intel/apollolake/include/soc/gpio.h
+++ b/src/soc/intel/apollolake/include/soc/gpio.h
@@ -100,4 +100,17 @@ void gpio_configure_pad(const struct pad_config *cfg);
 void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads);
 
 #endif /* __ACPI__ */
+
+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 /* _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..9d7d604 100644
--- a/src/soc/intel/apollolake/include/soc/gpio_defs.h
+++ b/src/soc/intel/apollolake/include/soc/gpio_defs.h
@@ -23,6 +23,261 @@
 #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 */
+
+/*
+ * GPIOs are ordered monotonically increasing to match ACPI/OS driver.
+ */
+
+/* SOUTHWEST */
+/* Group 0 */
+#define GPP_0_0			0
+#define GPP_0_1			1
+#define GPP_0_2			2
+#define GPP_0_3			3
+#define GPP_0_4			4
+#define GPP_0_5			5
+#define GPP_0_6			6
+#define GPP_0_7			7
+#define GPP_0_8			8
+#define GPP_0_9			9
+#define GPP_0_10		10
+#define GPP_0_11		11
+#define GPP_0_12		12
+#define GPP_0_13		13
+#define GPP_0_14		14
+#define GPP_0_15		15
+#define GPP_0_16		16
+#define GPP_0_17		17
+#define GPP_0_18		18
+#define GPP_0_19		19
+#define GPP_0_20		20
+#define GPP_0_21		21
+#define GPP_0_22		22
+#define GPP_0_23		23
+#define GPP_0_24		24
+#define GPP_0_25		25
+#define GPP_0_26		26
+#define GPP_0_27		27
+#define GPP_0_28		28
+#define GPP_0_29		29
+#define GPP_0_30		30
+#define GPP_0_31		31
+
+/* Group 1 */
+#define GPP_1_0			32
+#define GPP_1_1			33
+#define GPP_1_2			34
+#define GPP_1_3			35
+#define GPP_1_4			36
+#define GPP_1_5			37
+#define GPP_1_6			38
+#define GPP_1_7			39
+#define GPP_1_8			40
+#define GPP_1_9			41
+#define GPP_1_10		42
+
+/* WEST */
+/* Group 2 */
+#define GPP_2_0			0
+#define GPP_2_1			1
+#define GPP_2_2			2
+#define GPP_2_3			3
+#define GPP_2_4			4
+#define GPP_2_5			5
+#define GPP_2_6			6
+#define GPP_2_7			7
+#define GPP_2_8			8
+#define GPP_2_9			9
+#define GPP_2_10		10
+#define GPP_2_11		11
+#define GPP_2_12		12
+#define GPP_2_13		13
+#define GPP_2_14		14
+#define GPP_2_15		15
+#define GPP_2_16		16
+#define GPP_2_17		17
+#define GPP_2_18		18
+#define GPP_2_19		19
+#define GPP_2_20		20
+#define GPP_2_21		21
+#define GPP_2_22		22
+#define GPP_2_23		23
+#define GPP_2_24		24
+#define GPP_2_25		25
+
+/* NORTHWEST */
+/* Group 4 */
+#define GPP_4_0			0
+#define GPP_4_1			1
+#define GPP_4_2			2
+#define GPP_4_3			3
+#define GPP_4_4			4
+#define GPP_4_5			5
+#define GPP_4_6			6
+#define GPP_4_7			7
+#define GPP_4_8			8
+#define GPP_4_9			9
+#define GPP_4_10		10
+#define GPP_4_11		11
+#define GPP_4_12		12
+#define GPP_4_13		13
+#define GPP_4_14		14
+#define GPP_4_15		15
+#define GPP_4_16		16
+#define GPP_4_17		17
+
+/* Group 5 */
+#define GPP_5_0			33
+#define GPP_5_1			34
+#define GPP_5_2			35
+#define GPP_5_3			36
+#define GPP_5_4			37
+#define GPP_5_5			38
+#define GPP_5_6			39
+#define GPP_5_7			40
+#define GPP_5_8			41
+#define GPP_5_9			42
+#define GPP_5_10		43
+#define GPP_5_11		44
+#define GPP_5_12		45
+#define GPP_5_13		46
+#define GPP_5_14		47
+#define GPP_5_15		48
+#define GPP_5_16		49
+#define GPP_5_17		50
+#define GPP_5_18		51
+#define GPP_5_19		53
+#define GPP_5_20		54
+#define GPP_5_21		55
+#define GPP_5_22		56
+#define GPP_5_23		57
+#define GPP_5_24		58
+#define GPP_5_25		59
+#define GPP_5_26		61
+#define GPP_5_27		62
+#define GPP_5_28		63
+
+/* Group 6 */
+#define GPP_6_0			64
+#define GPP_6_1			65
+#define GPP_6_2			66
+#define GPP_6_3			67
+#define GPP_6_4			68
+#define GPP_6_5			69
+#define GPP_6_6			70
+#define GPP_6_7			71
+#define GPP_6_8			72
+#define GPP_6_9			73
+#define GPP_6_10		74
+#define GPP_6_11		75
+#define GPP_6_12		76
+
+/* NORTH */
+/* Group 7 */
+#define GPP_7_0			0
+#define GPP_7_1			1
+#define GPP_7_2			2
+#define GPP_7_3			3
+#define GPP_7_4			4
+#define GPP_7_5			5
+#define GPP_7_6			6
+#define GPP_7_7			7
+#define GPP_7_8			8
+#define GPP_7_9			9
+#define GPP_7_10		10
+#define GPP_7_11		11
+#define GPP_7_12		12
+#define GPP_7_13		13
+#define GPP_7_14		14
+#define GPP_7_15		15
+#define GPP_7_16		16
+#define GPP_7_17		17
+#define GPP_7_18		18
+#define GPP_7_19		19
+#define GPP_7_20		20
+#define GPP_7_21		21
+#define GPP_7_22		22
+#define GPP_7_23		23
+#define GPP_7_24		24
+#define GPP_7_25		25
+#define GPP_7_26		26
+#define GPP_7_27		27
+#define GPP_7_28		28
+#define GPP_7_29		29
+#define GPP_7_30		30
+#define GPP_7_31		31
+
+/* Group 8 */
+#define GPP_8_0			32
+#define GPP_8_1			33
+#define GPP_8_2			34
+#define GPP_8_3			35
+#define GPP_8_4			36
+#define GPP_8_5			37
+#define GPP_8_6			38
+#define GPP_8_7			39
+#define GPP_8_8			40
+#define GPP_8_9			41
+#define GPP_8_10		42
+#define GPP_8_11		43
+#define GPP_8_12		44
+#define GPP_8_13		45
+#define GPP_8_14		46
+#define GPP_8_15		47
+#define GPP_8_16		48
+#define GPP_8_17		49
+#define GPP_8_18		50
+#define GPP_8_19		51
+#define GPP_8_20		52
+#define GPP_8_21		53
+#define GPP_8_22		54
+#define GPP_8_23		55
+#define GPP_8_24		56
+#define GPP_8_25		57
+#define GPP_8_26		58
+#define GPP_8_27		59
+#define GPP_8_28		60
+#define GPP_8_29		61
+
+
+/* GPIO_22*/
+#define GPE_EC_WAKE	54
+
+#define GPIO_MISCCFG	0x10         ///< Miscellaneous Configuration
+#define GPIO_MISCCFG_GPE0_DW2 (BIT(19) | BIT(18) | BIT(17) | BIT(16))
+#define N_GPIO_MISCCFG_GPE0_DW2	16
+#define GPIO_MISCCFG_GPE0_DW1 (BIT(15) | BIT(14) | BIT(13) | BIT(12))
+#define N_GPIO_MISCCFG_GPE0_DW1	12
+#define GPIO_MISCCFG_GPE0_DW0 (BIT(11) | BIT(10) | BIT(9) | BIT(8))
+#define N_GPIO_MISCCFG_GPE0_DW0	8
+
+#define  GPE0_DWX_MASK		0xf
+#define  GPE0_DW0_SHIFT		0
+#define  GPE0_DW1_SHIFT		4
+#define  GPE0_DW2_SHIFT		8
+#define  GPE0_DW3_SHIFT		12
+
+/* GPI General Purpose Event Status */
+#define GPI_GPE_STS_0	0x120
+#define GPI_GPE_STS_1	0x124
+#define GPI_GPE_STS_2	0x128
+
+/* GPI General Purpose Events Enable */
+#define GPI_GPE_EN_0	0x130
+#define GPI_GPE_EN_1	0x134
+#define GPI_GPE_EN_2	0x138
+
 #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 856872e..ba37fc5 100644
--- a/src/soc/intel/apollolake/include/soc/pm.h
+++ b/src/soc/intel/apollolake/include/soc/pm.h
@@ -134,6 +134,8 @@
 #define SLEEP_STATE_S3		3
 #define SLEEP_STATE_S5		5
 
+#define  GPIO_CFG		0x1050
+
 /* Track power state from reset to log events. */
 struct chipset_power_state {
         uint16_t pm1_sts;



More information about the coreboot-gerrit mailing list