Shaunak Saha (shaunak.saha@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15324
-gerrit
commit 98261fd94a77023fb6becc5f8187b69338e7bcb8 Author: Shaunak Saha shaunak.saha@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@intel.com --- src/soc/intel/apollolake/chip.c | 6 +- src/soc/intel/apollolake/chip.h | 7 + src/soc/intel/apollolake/gpio.c | 85 ++++++++ src/soc/intel/apollolake/include/soc/gpio.h | 14 ++ src/soc/intel/apollolake/include/soc/gpio_defs.h | 236 +++++++++++++++++++++++ src/soc/intel/apollolake/include/soc/pm.h | 9 +- 6 files changed, 354 insertions(+), 3 deletions(-)
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index 821570b..fc0025a 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"
@@ -274,7 +275,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;
@@ -284,8 +284,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..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..0571e51 100644 --- a/src/soc/intel/apollolake/gpio.c +++ b/src/soc/intel/apollolake/gpio.c @@ -19,6 +19,14 @@ #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 <device/pci.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 +140,80 @@ 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 = 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; + + uintptr_t pmc_bar = get_pmc_mmio_bar(); + + 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_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 gpe0_dw0; + uint32_t gpe0_dw1; + uint32_t gpe0_dw2; + + /* Set the group here for community specific MISCCFG register */ + gpe0_dw0 = GPP_7; /* GPE0b */ + gpe0_dw1 = GPP_0; /* GPE0c */ + 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)((gpe0_dw2 << MISCCFG_GPE0_DW2_SHIFT) | + (gpe0_dw1 << MISCCFG_GPE0_DW1_SHIFT) | + (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..9bed198 100644 --- a/src/soc/intel/apollolake/include/soc/gpio.h +++ b/src/soc/intel/apollolake/include/soc/gpio.h @@ -22,6 +22,7 @@ /* __ACPI__ guard is needed to ignore below code in ACPI/ASL compilation */ #ifndef __ACPI__ #include <types.h> +#include <soc/gpio_defs.h>
typedef uint32_t gpio_t;
@@ -99,5 +100,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..d96ffba 100644 --- a/src/soc/intel/apollolake/include/soc/gpio_defs.h +++ b/src/soc/intel/apollolake/include/soc/gpio_defs.h @@ -23,6 +23,242 @@ #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 + +#define GPIO_MISCCFG 0x10 ///< Miscellaneous Configuration + +#define MISCCFG_GPE0_DW0_SHIFT 8 +#define MISCCFG_GPE0_DW0_MASK (0xf << MISCCFG_GPE0_DW1_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_DW1_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..a3ed3b1 100644 --- a/src/soc/intel/apollolake/include/soc/pm.h +++ b/src/soc/intel/apollolake/include/soc/pm.h @@ -128,11 +128,18 @@ #define GEN_PMCON2 0x1024 # define RPS (1 << 2) #define GEN_PMCON3 0x1028 +#define GPIO_GPE_CFG 0x1050 + +#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 + #define ETR 0x1048 # 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