diff options
author | Hannah Williams <hannah.williams@intel.com> | 2017-04-06 20:54:11 -0700 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2017-10-02 22:32:33 +0000 |
commit | 1760cd3eb44ad123b6d3e3e295cdbf43f9465db1 (patch) | |
tree | 25d37433765d4824d41075b39bb7396e9f0a504b /src/soc/intel | |
parent | a05fdcb2695a9d7c553c23ef6c35c37d7cd7b795 (diff) | |
download | coreboot-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/Kconfig | 3 | ||||
-rw-r--r-- | src/soc/intel/skylake/acpi/gpio.asl | 13 | ||||
-rw-r--r-- | src/soc/intel/skylake/acpi/pch.asl | 2 | ||||
-rw-r--r-- | src/soc/intel/skylake/chip.h | 2 | ||||
-rw-r--r-- | src/soc/intel/skylake/gpio.c | 492 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/gpio.h | 180 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/gpio_defs.h | 145 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/gpio_pch_h_defs.h | 12 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/gpio_soc_defs.h | 12 | ||||
-rw-r--r-- | src/soc/intel/skylake/pmutil.c | 4 |
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 *)®s[GPI_SMI_STS_OFFSET]; - gpi_en_reg = (void *)®s[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 ®s[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 = ®s[HOSTSW_OWN_REG_OFFSET]; - return ®s[(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 *)®s[GPI_SMI_STS_OFFSET]; - gpi_en_reg = (void *)®s[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, |