summaryrefslogtreecommitdiff
path: root/src/soc/intel
diff options
context:
space:
mode:
authorHannah Williams <hannah.williams@intel.com>2017-04-06 20:54:11 -0700
committerAaron Durbin <adurbin@chromium.org>2017-10-02 22:32:33 +0000
commit1760cd3eb44ad123b6d3e3e295cdbf43f9465db1 (patch)
tree25d37433765d4824d41075b39bb7396e9f0a504b /src/soc/intel
parenta05fdcb2695a9d7c553c23ef6c35c37d7cd7b795 (diff)
downloadcoreboot-1760cd3eb44ad123b6d3e3e295cdbf43f9465db1.tar.xz
soc/intel/skylake: Use common/block/gpio
Other than switch to use common gpio implementation for skylake based platform, also apply the needed changes for purism board. Change-Id: I06e06dbcb6d0d6fe277dfad57b82aca51f94b099 Signed-off-by: Hannah Williams <hannah.williams@intel.com> Signed-off-by: Lijian Zhao <lijian.zhao@intel.com> Reviewed-on: https://review.coreboot.org/19201 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Youness Alaoui <snifikino@gmail.com> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel')
-rw-r--r--src/soc/intel/skylake/Kconfig3
-rw-r--r--src/soc/intel/skylake/acpi/gpio.asl13
-rw-r--r--src/soc/intel/skylake/acpi/pch.asl2
-rw-r--r--src/soc/intel/skylake/chip.h2
-rw-r--r--src/soc/intel/skylake/gpio.c492
-rw-r--r--src/soc/intel/skylake/include/soc/gpio.h180
-rw-r--r--src/soc/intel/skylake/include/soc/gpio_defs.h145
-rw-r--r--src/soc/intel/skylake/include/soc/gpio_pch_h_defs.h12
-rw-r--r--src/soc/intel/skylake/include/soc/gpio_soc_defs.h12
-rw-r--r--src/soc/intel/skylake/pmutil.c4
10 files changed, 163 insertions, 702 deletions
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index 53a8b5157c..6deadd86a3 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -56,6 +56,9 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT
select SOC_INTEL_COMMON_BLOCK_EBDA
select SOC_INTEL_COMMON_BLOCK_FAST_SPI
+ select SOC_INTEL_COMMON_BLOCK_GPIO
+ select SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL
+ select SOC_INTEL_COMMON_BLOCK_GPIO_LEGACY_MACROS
select SOC_INTEL_COMMON_BLOCK_GSPI
select SOC_INTEL_COMMON_BLOCK_ITSS
select SOC_INTEL_COMMON_BLOCK_I2C
diff --git a/src/soc/intel/skylake/acpi/gpio.asl b/src/soc/intel/skylake/acpi/gpio.asl
index fb220959d5..ebf4289218 100644
--- a/src/soc/intel/skylake/acpi/gpio.asl
+++ b/src/soc/intel/skylake/acpi/gpio.asl
@@ -13,7 +13,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-#include <soc/gpio_defs.h>
+#include <soc/gpio.h>
+
+#define GPIOTXSTATE_MASK 0x1
+#define GPIORXSTATE_MASK 0x1
Device (GPIO)
{
@@ -51,7 +54,7 @@ Device (GPIO)
Store (GPIO_BASE_SIZE, LEN3)
CreateDWordField (^RBUF, ^GIRQ._INT, IRQN)
- And (^^PCRR (PID_GPIOCOM0, MISCCFG_OFFSET),
+ And (^^PCRR (PID_GPIOCOM0, GPIO_MISCCFG),
GPIO_DRIVER_IRQ_ROUTE_MASK, Local0)
If (LEqual (Local0, GPIO_DRIVER_IRQ_ROUTE_IRQ14)) {
@@ -115,7 +118,7 @@ Method (GADD, 1, NotSerialized)
}
#endif /* CONFIG_SKYLAKE_SOC_PCH_H */
Store (PCRB (Local0), Local2)
- Add (Local2, PAD_CFG_DW_OFFSET, Local2)
+ Add (Local2, PAD_CFG_BASE, Local2)
Return (Add (Local2, Multiply (Local1, 8)))
}
@@ -130,7 +133,7 @@ Method (GRXS, 1, Serialized)
{
VAL0, 32
}
- And (GPIORXSTATE_MASK, ShiftRight (VAL0, GPIORXSTATE_SHIFT), Local0)
+ And (GPIORXSTATE_MASK, ShiftRight (VAL0, PAD_CFG0_RX_STATE_BIT), Local0)
Return (Local0)
}
@@ -146,7 +149,7 @@ Method (GTXS, 1, Serialized)
{
VAL0, 32
}
- And (GPIOTXSTATE_MASK, ShiftRight (VAL0, GPIOTXSTATE_SHIFT), Local0)
+ And (GPIOTXSTATE_MASK, ShiftRight (VAL0, PAD_CFG0_TX_STATE_BIT), Local0)
Return (Local0)
}
diff --git a/src/soc/intel/skylake/acpi/pch.asl b/src/soc/intel/skylake/acpi/pch.asl
index 74cdb9ce8d..03c2570a44 100644
--- a/src/soc/intel/skylake/acpi/pch.asl
+++ b/src/soc/intel/skylake/acpi/pch.asl
@@ -19,7 +19,7 @@
#include <intelblocks/pcr.h>
#include <soc/iomap.h>
#include <soc/irq.h>
-#include <soc/gpio_defs.h>
+#include <soc/itss.h>
#include <soc/gpe.h>
#include <soc/pcr_ids.h>
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index 606078b4a1..0ade01cd1e 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -24,8 +24,8 @@
#include <intelblocks/gspi.h>
#include <intelblocks/lpss_i2c.h>
#include <stdint.h>
-#include <soc/gpio_defs.h>
#include <soc/gpe.h>
+#include <soc/gpio.h>
#include <soc/irq.h>
#include <soc/pci_devs.h>
#include <soc/pmc.h>
diff --git a/src/soc/intel/skylake/gpio.c b/src/soc/intel/skylake/gpio.c
index afd65fc007..9c9d041e4f 100644
--- a/src/soc/intel/skylake/gpio.c
+++ b/src/soc/intel/skylake/gpio.c
@@ -2,7 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Google Inc.
- * Copyright (C) 2015 Intel Corporation.
+ * Copyright (C) 2015 - 2017 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,422 +14,116 @@
* GNU General Public License for more details.
*/
-#include <stdint.h>
-#include <string.h>
-#include <arch/io.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <gpio.h>
+#include <assert.h>
+#include <intelblocks/gpio.h>
#include <intelblocks/pcr.h>
#include <soc/pcr_ids.h>
-#include <soc/iomap.h>
#include <soc/pm.h>
-static const int gpio_debug = 0;
+static const struct reset_mapping rst_map[] = {
+ { .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 0U << 30},
+ { .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30},
+ { .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30},
+};
-/* There are 4 communities with 8 GPIO groups (GPP_[A:G] and GPD) */
-struct gpio_community {
- int port_id;
- /* Inclusive pads within the community. */
- gpio_t min;
- gpio_t max;
+static const struct reset_mapping rst_map_com2[] = {
+ { .logical = PAD_CFG0_LOGICAL_RESET_PWROK, .chipset = 0U << 30},
+ { .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30},
+ { .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30},
+ { .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 3U << 30},
};
-/* This is ordered to match ACPI and OS driver. */
-static const struct gpio_community communities[] = {
- {
- .port_id = PID_GPIOCOM0,
- .min = GPP_A0,
- .max = GPP_B23,
- },
+static const struct pad_community skl_gpio_communities[] = {
{
- .port_id = PID_GPIOCOM1,
- .min = GPP_C0,
+ .port = PID_GPIOCOM0,
+ .first_pad = GPP_A0,
+ .last_pad = GPP_B23,
+ .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS,
+ .pad_cfg_base = PAD_CFG_BASE,
+ .host_own_reg_0 = HOSTSW_OWN_REG_0,
+ .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
+ .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .name = "GPIO_COM0",
+ .acpi_path = "\\_SB.PCI0.GPIO",
+ .reset_map = rst_map,
+ .num_reset_vals = ARRAY_SIZE(rst_map),
+ }, {
+ .port = PID_GPIOCOM1,
+ .first_pad = GPP_C0,
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
- .max = GPP_H23,
+ .last_pad = GPP_H23,
#else
- .max = GPP_E23,
+ .last_pad = GPP_E23,
#endif
- },
- {
- .port_id = PID_GPIOCOM3,
+ .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS,
+ .pad_cfg_base = PAD_CFG_BASE,
+ .host_own_reg_0 = HOSTSW_OWN_REG_0,
+ .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
+ .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .name = "GPIO_COM1",
+ .acpi_path = "\\_SB.PCI0.GPIO",
+ .reset_map = rst_map,
+ .num_reset_vals = ARRAY_SIZE(rst_map),
+ }, {
+ .port = PID_GPIOCOM3,
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
- .min = GPP_I0,
- .max = GPP_I10,
+ .first_pad = GPP_I0,
+ .last_pad = GPP_I10,
#else
- .min = GPP_F0,
- .max = GPP_G7,
+ .first_pad = GPP_F0,
+ .last_pad = GPP_G7,
#endif
- },
- {
- .port_id = PID_GPIOCOM2,
- .min = GPD0,
- .max = GPD11,
- },
-};
-
-static const char *gpio_group_names[GPIO_NUM_GROUPS] = {
- "GPP_A",
- "GPP_B",
- "GPP_C",
- "GPP_D",
- "GPP_E",
- "GPP_F",
- "GPP_G",
-#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
- "GPP_H",
- "GPP_I",
-#endif
- "GPD",
-};
-
-static inline void *gpio_community_regs(int port_id)
-{
- return pcr_reg_address(port_id, 0);
-}
-
-static inline size_t gpios_in_community(const struct gpio_community *comm)
-{
- /* max is inclusive */
- return comm->max - comm->min + 1;
-}
-
-static inline size_t groups_in_community(const struct gpio_community *comm)
-{
- size_t n = gpios_in_community(comm) + GPIO_MAX_NUM_PER_GROUP - 1;
- return n / GPIO_MAX_NUM_PER_GROUP;
-}
-
-static inline int gpio_index_gpd(gpio_t gpio)
-{
- if (gpio >= GPD0 && gpio <= GPD11)
- return 1;
- return 0;
-}
-
-static const struct gpio_community *gpio_get_community(gpio_t pad)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(communities); i++) {
- const struct gpio_community *c = &communities[i];
-
- if (pad >= c->min && pad <= c->max)
- return c;
+ .num_gpi_regs = NUM_GPIO_COM3_GPI_REGS,
+ .pad_cfg_base = PAD_CFG_BASE,
+ .host_own_reg_0 = HOSTSW_OWN_REG_0,
+ .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
+ .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .name = "GPIO_COM3",
+ .acpi_path = "\\_SB.PCI0.GPIO",
+ .reset_map = rst_map,
+ .num_reset_vals = ARRAY_SIZE(rst_map),
+ }, {
+ .port = PID_GPIOCOM2,
+ .first_pad = GPD0,
+ .last_pad = GPD11,
+ .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS,
+ .pad_cfg_base = PAD_CFG_BASE,
+ .host_own_reg_0 = HOSTSW_OWN_REG_0,
+ .gpi_smi_sts_reg_0 = GPI_SMI_STS_0,
+ .gpi_smi_en_reg_0 = GPI_SMI_EN_0,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .name = "GPIO_COM2",
+ .acpi_path = "\\_SB.PCI0.GPIO",
+ .reset_map = rst_map_com2,
+ .num_reset_vals = ARRAY_SIZE(rst_map_com2),
}
+};
- return NULL;
-}
-
-static size_t community_clr_get_smi_sts(const struct gpio_community *comm,
- uint32_t *sts)
-{
- uint8_t *regs;
- size_t i;
- uint32_t *gpi_status_reg;
- uint32_t *gpi_en_reg;
- const size_t num_grps = groups_in_community(comm);
-
- /* Not all groups can be routed to SMI. However, the registers
- * read as 0. In order to simplify the logic read everything from
- * each community. */
- regs = gpio_community_regs(comm->port_id);
- gpi_status_reg = (void *)&regs[GPI_SMI_STS_OFFSET];
- gpi_en_reg = (void *)&regs[GPI_SMI_EN_OFFSET];
- for (i = 0; i < num_grps; i++) {
- sts[i] = read32(gpi_status_reg + i) & read32(gpi_en_reg + i);
- /* Clear the enabled and set status bits. */
- write32(gpi_status_reg + i, sts[i]);
- }
-
- return num_grps;
-}
-
-static void print_gpi_status(uint32_t status, const char *grp_name)
-{
- int i;
-
- if (!status)
- return;
-
- for (i = 31; i >= 0; i--) {
- if (status & (1 << i))
- printk(BIOS_DEBUG, "%s%d ", grp_name, i);
- }
-}
-
-void gpi_clear_get_smi_status(struct gpi_status *sts)
-{
- int i;
- int do_print;
- size_t sts_index = 0;
-
- for (i = 0; i < ARRAY_SIZE(communities); i++) {
- const struct gpio_community *comm = &communities[i];
- sts_index += community_clr_get_smi_sts(comm,
- &sts->grp[sts_index]);
- }
-
- do_print = 0;
- for (i = 0; i < ARRAY_SIZE(sts->grp); i++) {
- if (sts->grp[i] == 0)
- continue;
- do_print = 1;
- break;
- }
-
- if (!do_print)
- return;
-
- printk(BIOS_DEBUG, "GPI_SMI_STS: ");
- for (i = 0; i < ARRAY_SIZE(sts->grp); i++)
- print_gpi_status(sts->grp[i], gpio_group_names[i]);
- printk(BIOS_DEBUG, "\n");
-}
-
-int gpi_status_get(const struct gpi_status *sts, gpio_t gpi)
-{
- const uint32_t *gpi_sts;
-
- /* Check if valid gpi */
- if (gpio_get_community(gpi) == NULL)
- return 0;
-
- /* If not in GPD group the index is a linear function based on
- * GPI number and GPIO_MAX_NUM_PER_GROUP. */
- if (gpio_index_gpd(gpi))
- gpi_sts = &sts->grp[GPD];
- else
- gpi_sts = &sts->grp[gpi / GPIO_MAX_NUM_PER_GROUP];
-
- return !!(*gpi_sts & (1 << (gpi % GPIO_MAX_NUM_PER_GROUP)));
-}
-
-void gpio_route_gpe(uint16_t gpe0_route)
-{
- int i;
- uint32_t misc_cfg;
- const uint32_t misc_cfg_reg_mask = GPE_DW_MASK;
-
- misc_cfg = (uint32_t)gpe0_route << GPE_DW_SHIFT;
- misc_cfg &= misc_cfg_reg_mask;
-
- for (i = 0; i < ARRAY_SIZE(communities); i++) {
- uint8_t *regs;
- uint32_t reg;
- const struct gpio_community *comm = &communities[i];
-
- regs = gpio_community_regs(comm->port_id);
-
- reg = read32(regs + MISCCFG_OFFSET);
- reg &= ~misc_cfg_reg_mask;
- reg |= misc_cfg;
- write32(regs + MISCCFG_OFFSET, reg);
- }
-}
-
-static void *gpio_dw_regs(gpio_t pad)
-{
- const struct gpio_community *comm;
- uint8_t *regs;
- size_t pad_relative;
-
- comm = gpio_get_community(pad);
-
- if (comm == NULL)
- return NULL;
-
- regs = gpio_community_regs(comm->port_id);
-
- pad_relative = pad - comm->min;
-
- /* DW0 and DW1 regs are 4 bytes each. */
- return &regs[PAD_CFG_DW_OFFSET + pad_relative *
- GPIO_DWx_SIZE(GPIO_DWx_COUNT)];
-}
-
-static void *gpio_hostsw_reg(gpio_t pad, size_t *bit)
-{
- const struct gpio_community *comm;
- uint8_t *regs;
- size_t pad_relative;
-
- comm = gpio_get_community(pad);
-
- if (comm == NULL)
- return NULL;
-
- regs = gpio_community_regs(comm->port_id);
-
- pad_relative = pad - comm->min;
-
- /* Update the bit for this pad. */
- *bit = (pad_relative % HOSTSW_OWN_PADS_PER);
-
- /* HostSw regs are 4 bytes each. */
- regs = &regs[HOSTSW_OWN_REG_OFFSET];
- return &regs[(pad_relative / HOSTSW_OWN_PADS_PER) * 4];
-}
-
-static void gpio_handle_pad_mode(const struct pad_config *cfg)
-{
- size_t bit;
- uint32_t *hostsw_own_reg;
- uint32_t reg;
-
- bit = 0;
- hostsw_own_reg = gpio_hostsw_reg(cfg->pad, &bit);
-
- if (hostsw_own_reg == NULL)
- return;
-
- reg = read32(hostsw_own_reg);
- reg &= ~(1U << bit);
-
- if ((cfg->attrs & PAD_FIELD(HOSTSW, GPIO)) == PAD_FIELD(HOSTSW, GPIO))
- reg |= (HOSTSW_GPIO << bit);
- else
- reg |= (HOSTSW_ACPI << bit);
-
- write32(hostsw_own_reg, reg);
-}
-
-static void gpi_enable_smi(gpio_t pad)
-{
- const struct gpio_community *comm;
- uint8_t *regs;
- uint32_t *gpi_status_reg;
- uint32_t *gpi_en_reg;
- size_t group_offset;
- uint32_t pad_mask;
-
- comm = gpio_get_community(pad);
- if (comm == NULL)
- return;
- regs = gpio_community_regs(comm->port_id);
- gpi_status_reg = (void *)&regs[GPI_SMI_STS_OFFSET];
- gpi_en_reg = (void *)&regs[GPI_SMI_EN_OFFSET];
-
- /* Offset of SMI STS/EN for this pad's group within the community. */
- group_offset = (pad - comm->min) / GPIO_MAX_NUM_PER_GROUP;
-
- /* Clear status then set enable. */
- pad_mask = 1 << ((pad - comm->min) % GPIO_MAX_NUM_PER_GROUP);
- write32(&gpi_status_reg[group_offset], pad_mask);
- write32(&gpi_en_reg[group_offset],
- read32(&gpi_en_reg[group_offset]) | pad_mask);
-}
-
-static void gpio_configure_pad(const struct pad_config *cfg)
-{
- uint32_t *dw_regs;
- uint32_t reg;
- uint32_t dw0;
- uint32_t mask;
-
- dw_regs = gpio_dw_regs(cfg->pad);
-
- if (dw_regs == NULL)
- return;
-
- dw0 = cfg->dw0;
-
- write32(&dw_regs[0], dw0);
- reg = read32(&dw_regs[1]);
-
- /* Apply termination field */
- mask = PAD_TERM_MASK << PAD_TERM_SHIFT;
- reg &= ~mask;
- reg |= cfg->attrs & mask;
-
- /* Apply voltage tolerance field */
- mask = PAD_TOL_MASK << PAD_TOL_SHIFT;
- reg &= ~mask;
- reg |= cfg->attrs & mask;
- write32(&dw_regs[1], reg);
-
- gpio_handle_pad_mode(cfg);
-
- if ((dw0 & PAD_FIELD(GPIROUTSMI, MASK)) == PAD_FIELD(GPIROUTSMI, YES))
- gpi_enable_smi(cfg->pad);
-
- if (gpio_debug)
- printk(BIOS_DEBUG,
- "Write Pad: Base(%p) - conf0 = %x conf1= %x pad # = %d\n",
- &dw_regs[0], dw0, reg, cfg->pad);
-}
-
-void gpio_configure_pads(const struct pad_config *cfgs, size_t num)
-{
- size_t i;
-
- for (i = 0; i < num; i++)
- gpio_configure_pad(&cfgs[i]);
-}
-
-void gpio_input_pulldown(gpio_t gpio)
-{
- struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PD, DEEP);
- gpio_configure_pad(&cfg);
-}
-
-void gpio_input_pullup(gpio_t gpio)
-{
- struct pad_config cfg = PAD_CFG_GPI(gpio, 5K_PU, DEEP);
- gpio_configure_pad(&cfg);
-}
-
-void gpio_input(gpio_t gpio)
-{
- struct pad_config cfg = PAD_CFG_GPI(gpio, NONE, DEEP);
- gpio_configure_pad(&cfg);
-}
-
-void gpio_output(gpio_t gpio, int value)
-{
- struct pad_config cfg = PAD_CFG_GPO(gpio, value, DEEP);
- gpio_configure_pad(&cfg);
-}
-
-int gpio_get(gpio_t gpio_num)
-{
- uint32_t *dw_regs;
- uint32_t reg;
-
- dw_regs = gpio_dw_regs(gpio_num);
-
- if (dw_regs == NULL)
- return -1;
-
- reg = read32(&dw_regs[0]);
-
- return (reg >> GPIORXSTATE_SHIFT) & GPIORXSTATE_MASK;
-}
-
-void gpio_set(gpio_t gpio_num, int value)
-{
- uint32_t *dw_regs;
- uint32_t reg;
-
- dw_regs = gpio_dw_regs(gpio_num);
-
- if (dw_regs == NULL)
- return;
-
- reg = read32(&dw_regs[0]);
- reg &= ~PAD_FIELD(GPIOTXSTATE, MASK);
- reg |= PAD_FIELD_VAL(GPIOTXSTATE, value);
- write32(&dw_regs[0], reg);
- /* GPIO port ids support posted write semantics. */
-}
-
-const char *gpio_acpi_path(gpio_t gpio_num)
+const struct pad_community *soc_gpio_get_community(size_t *num_communities)
{
- return "\\_SB.PCI0.GPIO";
+ *num_communities = ARRAY_SIZE(skl_gpio_communities);
+ return skl_gpio_communities;
}
-uint16_t gpio_acpi_pin(gpio_t gpio_num)
+const struct pmc_to_gpio_route *soc_pmc_gpio_routes(size_t *num)
{
- return gpio_num;
+ static const struct pmc_to_gpio_route routes[] = {
+ { GPP_A, GPP_A},
+ { GPP_B, GPP_B},
+ { GPP_C, GPP_C},
+ { GPP_D, GPP_D},
+ { GPP_E, GPP_E},
+ { GPP_F, GPP_F},
+ { GPP_G, GPP_G},
+#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
+ { GPP_H, GPP_H},
+ { GPP_I, GPP_I},
+#endif
+ { GPD, GPD},
+ };
+ *num = ARRAY_SIZE(routes);
+ return routes;
}
diff --git a/src/soc/intel/skylake/include/soc/gpio.h b/src/soc/intel/skylake/include/soc/gpio.h
index 4f809cf480..13a0a7ab62 100644
--- a/src/soc/intel/skylake/include/soc/gpio.h
+++ b/src/soc/intel/skylake/include/soc/gpio.h
@@ -18,184 +18,8 @@
#define _SOC_GPIO_H_
#include <soc/gpio_defs.h>
-
-#define GPIO_DWx_SIZE(x) (sizeof(uint32_t) * (x))
+#include <intelblocks/gpio.h> /* intelblocks/gpio.h depends on definitions in
+ soc/gpio_defs.h */
#define CROS_GPIO_DEVICE_NAME "INT344B:00"
-
-#ifndef __ACPI__
-#include <stdint.h>
-#include <stddef.h>
-
-typedef uint32_t gpio_t;
-
-/* Structure to represent GPI status for GPE and SMI. Use helper
- * functions for interrogating particular GPIs. */
-struct gpi_status {
- uint32_t grp[GPIO_NUM_GROUPS];
-};
-
-/*
- * Clear GPI SMI status and fill in the structure representing enabled
- * and set status.
- */
-void gpi_clear_get_smi_status(struct gpi_status *sts);
-
-/* Return 1 if gpio is set in the gpi_status struct. Otherwise 0. */
-int gpi_status_get(const struct gpi_status *sts, gpio_t gpi);
-
-/*
- * Set the GPIO groups for the GPE blocks. The gpe0_route is interpreted
- * as the packed configuration for GPE0_DW[2:0]:
- * dw0 = gpe0_route[3:0]
- * dw1 = gpe0_route[7:4]
- * dw2 = gpe0_route[11:8].
- */
-void gpio_route_gpe(uint16_t gpe0_route);
-
-/* Configure the pads according to the pad_config array. */
-struct pad_config;
-void gpio_configure_pads(const struct pad_config *cfgs, size_t num);
-
-#define PAD_FIELD_VAL(field_, val_) \
- (((val_) & field_ ## _MASK) << field_ ## _SHIFT)
-
-#define PAD_FIELD(field_, setting_) \
- PAD_FIELD_VAL(field_, field_ ## _ ## setting_)
-
-/*
- * This encodes all the fields found within the dw0 register for each
- * pad. It directly follows the register specification:
- * rst - reset type when pad configuration is reset
- * rxst - native function routing: raw buffer or internal buffer
- * rxraw1 - drive fixed '1' for Rx buffer
- * rxev - event filtering for pad value: level, edge, drive '0'
- * rxgf - glitch filter enable
- * rxinv - invert the internal pad state
- * gpiioapic - route to IOxAPIC
- * gpisci - route for SCI
- * gpismi - route for SMI
- * gpinmi - route for NMI
- * mode - GPIO vs native function
- * rxdis - disable Rx buffer
- * txdis - disable Tx buffer
- */
-#define _DW0_VALS(rst, rxst, rxraw1, rxev, rxgf, rxinv, gpiioapic, gpisci, \
- gpismi, gpinmi, mode, rxdis, txdis) \
- (PAD_FIELD(PADRSTCFG, rst) | \
- PAD_FIELD(RXPADSTSEL, rxst) | \
- PAD_FIELD(RXRAW1, rxraw1) | \
- PAD_FIELD(RXEVCFG, rxev) | \
- PAD_FIELD(PREGFRXSEL, rxgf) | \
- PAD_FIELD(RXINV, rxinv) | \
- PAD_FIELD(GPIROUTIOXAPIC, gpiioapic) | \
- PAD_FIELD(GPIROUTSCI, gpisci) | \
- PAD_FIELD(GPIROUTSMI, gpismi) | \
- PAD_FIELD(GPIROUTNMI, gpinmi) | \
- PAD_FIELD(PMODE, mode) | \
- PAD_FIELD(GPIORXDIS, rxdis) | \
- PAD_FIELD(GPIOTXDIS, txdis))
-
-#define _PAD_CFG_ATTRS(pad_, term_, dw0_, attrs_) \
- { \
- .pad = pad_, \
- .attrs = PAD_FIELD(PAD_TERM, term_) | attrs_, \
- .dw0 = dw0_, \
- }
-
-/* Default to ACPI owned. Ownership only matters for GPI pads. */
-#define _PAD_CFG(pad_, term_, dw0_) \
- _PAD_CFG_ATTRS(pad_, term_, dw0_, PAD_FIELD(HOSTSW, ACPI))
-
-/* Native Function - No Rx buffer manipulation */
-#define PAD_CFG_NF(pad_, term_, rst_, func_) \
- _PAD_CFG(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, func_, NO, NO))
-
-/* Native 1.8V tolerant pad, only applies to some pads like I2C/I2S. */
-#define PAD_CFG_NF_1V8(pad_, term_, rst_, func_) \
- _PAD_CFG_ATTRS(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, \
- NO, NO, NO, NO, func_, NO, NO), PAD_FIELD(PAD_TOL, 1V8))
-
-/* Unused PINS will be controlled by GPIO controller (PMODE = GPIO) and
- GPIO TX/RX will be disabled. */
-#define PAD_CFG_NC(pad_) \
- _PAD_CFG(pad_, NONE, \
- _DW0_VALS(DEEP, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, YES))
-
-/* General purpose output with termination. */
-#define PAD_CFG_TERM_GPO(pad_, val_, term_, rst_) \
- _PAD_CFG(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, NO) \
- | PAD_FIELD_VAL(GPIOTXSTATE, val_))
-
-/* General purpose output. By default no termination. */
-#define PAD_CFG_GPO(pad_, val_, rst_) \
- PAD_CFG_TERM_GPO(pad_, val_, NONE, rst_)
-
-/* General purpose input with no special IRQ routing. */
-#define PAD_CFG_GPI(pad_, term_, rst_) \
- _PAD_CFG_ATTRS(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, NO, YES),\
- PAD_FIELD(HOSTSW, GPIO))
-
-/* General purpose input passed through to GPIO interrupt */
-#define PAD_CFG_GPI_INT(pad_, term_, rst_, trig_) \
- _PAD_CFG_ATTRS(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, trig_, NO, NO, NO, NO, NO, NO, GPIO, NO, YES),\
- PAD_FIELD(HOSTSW, GPIO))
-
-/* General purpose input passed through to IOxAPIC. Assume APIC logic can
- * handle polarity/edge/level constraints. */
-#define PAD_CFG_GPI_APIC(pad_, term_, rst_) \
- _PAD_CFG(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
-
-/* General purpose input passed through to IOxAPIC as inverted input. */
-#define PAD_CFG_GPI_APIC_INVERT(pad_, term_, rst_) \
- _PAD_CFG(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, YES, YES, NO, NO, NO, GPIO, NO, \
- YES))
-
-/* General purpose input passed through to IOxAPIC. This assumes edge
- * triggered events. */
-#define PAD_CFG_GPI_APIC_EDGE(pad_, term_, rst_) \
- _PAD_CFG(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, EDGE, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
-
-/* General purpose input routed to SCI. This assumes edge triggered events. */
-#define PAD_CFG_GPI_ACPI_SCI(pad_, term_, rst_, inv_) \
- _PAD_CFG_ATTRS(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
- NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
-
-#define PAD_CFG_GPI_ACPI_SCI_LEVEL(pad_, term_, rst_, inv_) \
- _PAD_CFG_ATTRS(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, LEVEL, NO, inv_, \
- NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
-
-/* General purpose input routed to SMI. This assumes edge triggered events. */
-#define PAD_CFG_GPI_ACPI_SMI(pad_, term_, rst_, inv_) \
- _PAD_CFG_ATTRS(pad_, term_, \
- _DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
- NO, NO, YES, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
-
-/*
- * The 'attrs' field carries the termination in bits 13:10 and tolerance in bit
- * 25 to match up with thd DW1 pad configuration register. Additionally, other
- * attributes can be applied such as the ones below. Bit allocation matters.
- */
-#define HOSTSW_SHIFT 0
-#define HOSTSW_MASK 1
-#define HOSTSW_ACPI HOSTSW_OWN_ACPI
-#define HOSTSW_GPIO HOSTSW_OWN_GPIO
-
-struct pad_config {
- uint16_t pad;
- uint32_t attrs;
- uint32_t dw0;
-};
-
-#endif /* __ACPI__ */
#endif
diff --git a/src/soc/intel/skylake/include/soc/gpio_defs.h b/src/soc/intel/skylake/include/soc/gpio_defs.h
index 34461f2061..137b37e613 100644
--- a/src/soc/intel/skylake/include/soc/gpio_defs.h
+++ b/src/soc/intel/skylake/include/soc/gpio_defs.h
@@ -15,13 +15,31 @@
#ifndef _SOC_GPIO_DEFS_H_
#define _SOC_GPIO_DEFS_H_
-
+#ifndef __ACPI__
+#include <stddef.h>
+#endif
#if IS_ENABLED(CONFIG_SKYLAKE_SOC_PCH_H)
# include <soc/gpio_pch_h_defs.h>
#else
# include <soc/gpio_soc_defs.h>
#endif
+#define GPIO_NUM_PAD_CFG_REGS 2 /* DW0, DW1 */
+
+#define NUM_GPIO_COMx_GPI_REGS(n) \
+ (ALIGN_UP((n), GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define NUM_GPIO_COM0_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM0_PADS)
+#define NUM_GPIO_COM1_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM1_PADS)
+#define NUM_GPIO_COM2_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM2_PADS)
+#define NUM_GPIO_COM3_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM3_PADS)
+
+#define NUM_GPI_STATUS_REGS \
+ ((NUM_GPIO_COM0_GPI_REGS) +\
+ (NUM_GPIO_COM1_GPI_REGS) +\
+ (NUM_GPIO_COM3_GPI_REGS) +\
+ (NUM_GPIO_COM2_GPI_REGS))
+
/*
* IOxAPIC IRQs for the GPIOs
*/
@@ -76,6 +94,7 @@
#define GPP_B21_IRQ 0x45
#define GPP_B22_IRQ 0x46
#define GPP_B23_IRQ 0x47
+
/* Group C */
#define GPP_C0_IRQ 0x48
#define GPP_C1_IRQ 0x49
@@ -200,121 +219,13 @@
#define GPD11_IRQ 0x5b
/* Register defines. */
-#define MISCCFG_OFFSET 0x10
-#define GPIO_DRIVER_IRQ_ROUTE_MASK 8
-#define GPIO_DRIVER_IRQ_ROUTE_IRQ14 0
-#define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8
-#define GPE_DW_SHIFT 8
-#define GPE_DW_MASK 0xfff00
-#define PAD_OWN_REG_OFFSET 0x20
-#define PAD_OWN_PADS_PER 8
-#define PAD_OWN_WIDTH_PER 4
-#define PAD_OWN_MASK 0x03
-#define PAD_OWN_HOST 0x00
-#define PAD_OWN_ME 0x01
-#define PAD_OWN_ISH 0x02
-#define HOSTSW_OWN_REG_OFFSET 0xd0
-#define HOSTSW_OWN_PADS_PER 24
-#define HOSTSW_OWN_ACPI 0
-#define HOSTSW_OWN_GPIO 1
-#define PAD_CFG_DW_OFFSET 0x400
- /* PADRSTCFG - when to reset the pad config */
-#define PADRSTCFG_SHIFT 30
-#define PADRSTCFG_MASK 0x3
-#define PADRSTCFG_DSW_PWROK 0
-#define PADRSTCFG_DEEP 1
-#define PADRSTCFG_PLTRST 2
-#define PADRSTCFG_RSMRST 3
- /* RXPADSTSEL - raw signal or internal state */
-#define RXPADSTSEL_SHIFT 29
-#define RXPADSTSEL_MASK 0x1
-#define RXPADSTSEL_RAW 0
-#define RXPADSTSEL_INTERNAL 1
- /* RXRAW1 - drive 1 instead instead of pad value */
-#define RXRAW1_SHIFT 28
-#define RXRAW1_MASK 0x1
-#define RXRAW1_NO 0
-#define RXRAW1_YES 1
- /* RXEVCFG - Interrupt and wake types */
-#define RXEVCFG_SHIFT 25
-#define RXEVCFG_MASK 0x3
-#define RXEVCFG_LEVEL 0
-#define RXEVCFG_EDGE 1
-#define RXEVCFG_DRIVE0 2
- /* PREGFRXSEL - use filtering on Rx pad */
-#define PREGFRXSEL_SHIFT 24
-#define PREGFRXSEL_MASK 0x1
-#define PREGFRXSEL_NO 0
-#define PREGFRXSEL_YES 1
- /* RXINV - invert signal to SMI, SCI, NMI, or IRQ routing. */
-#define RXINV_SHIFT 23
-#define RXINV_MASK 0x1
-#define RXINV_NO 0
-#define RXINV_YES 1
- /* GPIROUTIOXAPIC - route to io-xapic or not */
-#define GPIROUTIOXAPIC_SHIFT 20
-#define GPIROUTIOXAPIC_MASK 0x1
-#define GPIROUTIOXAPIC_NO 0
-#define GPIROUTIOXAPIC_YES 1
- /* GPIROUTSCI - route to SCI */
-#define GPIROUTSCI_SHIFT 19
-#define GPIROUTSCI_MASK 0x1
-#define GPIROUTSCI_NO 0
-#define GPIROUTSCI_YES 1
- /* GPIROUTSMI - route to SMI */
-#define GPIROUTSMI_SHIFT 18
-#define GPIROUTSMI_MASK 0x1
-#define GPIROUTSMI_NO 0
-#define GPIROUTSMI_YES 1
- /* GPIROUTNMI - route to NMI */
-#define GPIROUTNMI_SHIFT 17
-#define GPIROUTNMI_MASK 0x1
-#define GPIROUTNMI_NO 0
-#define GPIROUTNMI_YES 1
- /* PMODE - mode of pad */
-#define PMODE_SHIFT 10
-#define PMODE_MASK 0x3
-#define PMODE_GPIO 0
-#define PMODE_NF1 1
-#define PMODE_NF2 2
-#define PMODE_NF3 3
- /* GPIORXDIS - Disable Rx */
-#define GPIORXDIS_SHIFT 9
-#define GPIORXDIS_MASK 0x1
-#define GPIORXDIS_NO 0
-#define GPIORXDIS_YES 1
- /* GPIOTXDIS - Disable Tx */
-#define GPIOTXDIS_SHIFT 8
-#define GPIOTXDIS_MASK 0x1
-#define GPIOTXDIS_NO 0
-#define GPIOTXDIS_YES 1
- /* GPIORXSTATE - Internal state after glitch filter */
-#define GPIORXSTATE_SHIFT 1
-#define GPIORXSTATE_MASK 0x1
- /* GPIOTXSTATE - Drive value onto pad */
-#define GPIOTXSTATE_SHIFT 0
-#define GPIOTXSTATE_MASK 0x1
- /* TERM - termination control */
-#define PAD_TERM_SHIFT 10
-#define PAD_TERM_MASK 0xf
-#define PAD_TERM_NONE 0
-#define PAD_TERM_5K_PD 2
-#define PAD_TERM_20K_PD 4
-#define PAD_TERM_1K_PU 9
-#define PAD_TERM_2K_PU 11
-#define PAD_TERM_5K_PU 10
-#define PAD_TERM_20K_PU 12
-#define PAD_TERM_667_PU 13
-#define PAD_TERM_NATIVE 15
- /* TOL - voltage tolerance */
-#define PAD_TOL_SHIFT 25
-#define PAD_TOL_MASK 0x1
-#define PAD_TOL_3V3 0 /* 3.3V default */
-#define PAD_TOL_1V8 1 /* 1.8V tolerant */
-
-#define GPI_GPE_STS_OFFSET 0x140
-#define GPI_GPE_EN_OFFSET 0x160
-#define GPI_SMI_STS_OFFSET 0x180
-#define GPI_SMI_EN_OFFSET 0x1a0
+#define GPIO_MISCCFG 0x10
+#define GPIO_DRIVER_IRQ_ROUTE_MASK 8
+#define GPIO_DRIVER_IRQ_ROUTE_IRQ14 0
+#define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8
+#define HOSTSW_OWN_REG_0 0xd0
+#define PAD_CFG_BASE 0x400
+#define GPI_SMI_STS_0 0x180
+#define GPI_SMI_EN_0 0x1a0
#endif /* _SOC_GPIO_DEFS_H_ */
diff --git a/src/soc/intel/skylake/include/soc/gpio_pch_h_defs.h b/src/soc/intel/skylake/include/soc/gpio_pch_h_defs.h
index e1be6f0641..c6a23db0a7 100644
--- a/src/soc/intel/skylake/include/soc/gpio_pch_h_defs.h
+++ b/src/soc/intel/skylake/include/soc/gpio_pch_h_defs.h
@@ -90,6 +90,9 @@
#define GPP_B21 45
#define GPP_B22 46
#define GPP_B23 47
+
+#define NUM_GPIO_COM0_PADS (GPP_B23 - GPP_A0 + 1)
+
/* Group C */
#define GPP_C0 48
#define GPP_C1 49
@@ -229,6 +232,9 @@
#define GPP_H21 178
#define GPP_H22 179
#define GPP_H23 180
+
+#define NUM_GPIO_COM1_PADS (GPP_H23 - GPP_C0 + 1)
+
/* Group I */
#define GPP_I0 181
#define GPP_I1 182
@@ -241,6 +247,9 @@
#define GPP_I8 189
#define GPP_I9 190
#define GPP_I10 191
+
+#define NUM_GPIO_COM3_PADS (GPP_I10 - GPP_I0 + 1)
+
/* Group GPD */
#define GPD0 192
#define GPD1 193
@@ -254,4 +263,7 @@
#define GPD9 201
#define GPD10 202
#define GPD11 203
+
+#define NUM_GPIO_COM2_PADS (GPD11 - GPD0 + 1)
+
#endif /* _SOC_GPIO_PCH_H_DEFS_H_ */
diff --git a/src/soc/intel/skylake/include/soc/gpio_soc_defs.h b/src/soc/intel/skylake/include/soc/gpio_soc_defs.h
index 9ed61c7fa3..f5633e4ec6 100644
--- a/src/soc/intel/skylake/include/soc/gpio_soc_defs.h
+++ b/src/soc/intel/skylake/include/soc/gpio_soc_defs.h
@@ -88,6 +88,9 @@
#define GPP_B21 45
#define GPP_B22 46
#define GPP_B23 47
+
+#define NUM_GPIO_COM0_PADS (GPP_B23 - GPP_A0 + 1)
+
/* Group C */
#define GPP_C0 48
#define GPP_C1 49
@@ -163,6 +166,9 @@
#define GPP_E21 117
#define GPP_E22 118
#define GPP_E23 119
+
+#define NUM_GPIO_COM1_PADS (GPP_E23 - GPP_C0 + 1)
+
/* Group F */
#define GPP_F0 120
#define GPP_F1 121
@@ -197,6 +203,9 @@
#define GPP_G5 149
#define GPP_G6 150
#define GPP_G7 151
+
+#define NUM_GPIO_COM3_PADS (GPP_G7 - GPP_F0 + 1)
+
/* Group GPD */
#define GPD0 152
#define GPD1 153
@@ -211,4 +220,7 @@
#define GPD10 162
#define GPD11 163
+#define NUM_GPIO_COM2_PADS (GPD11 - GPD0 + 1)
+
+
#endif /* _SOC_GPIO_SOC_DEFS_H_ */
diff --git a/src/soc/intel/skylake/pmutil.c b/src/soc/intel/skylake/pmutil.c
index 2a677fda74..36e4784a10 100644
--- a/src/soc/intel/skylake/pmutil.c
+++ b/src/soc/intel/skylake/pmutil.c
@@ -536,7 +536,9 @@ void pmc_gpe_init(void)
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);
+ gpio_route_gpe((gpio_cfg_reg >> GPE0_DW0_SHIFT) & GPE0_DWX_MASK,
+ (gpio_cfg_reg >> GPE0_DW1_SHIFT) & GPE0_DWX_MASK,
+ (gpio_cfg_reg >> GPE0_DW2_SHIFT) & GPE0_DWX_MASK);
/* Set GPE enables based on devictree. */
enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2,