summaryrefslogtreecommitdiff
path: root/src/soc/intel
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2016-07-12 17:32:52 -0500
committerAaron Durbin <adurbin@chromium.org>2016-07-13 21:58:37 +0200
commitb72c67b713c7a651416be28831d80a77ef1ce617 (patch)
tree05c842f4a23ec773076ca0a2f4a48faf9ca136eb /src/soc/intel
parent1318e88352d7b20661adec82769f46308471d739 (diff)
downloadcoreboot-b72c67b713c7a651416be28831d80a77ef1ce617.tar.xz
soc/intel/apollolake: set gpio interrupt polarity in ITSS
For APIC routed gpios, set the corresponding interrupt polarity for the associated IRQ based on the gpio pad's invert setting. This allows for the APIC redirection entries to match the hardware active polarity once the double inversion takes place to meet apollolake interrupt triggering constraints. BUG=chrome-os-partner:54955 Change-Id: I69c395b6f861946d4774a4206cf8f5f721c6f5f4 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/15648 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc/intel')
-rw-r--r--src/soc/intel/apollolake/gpio.c32
-rw-r--r--src/soc/intel/apollolake/include/soc/gpio_defs.h1
2 files changed, 33 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/gpio.c b/src/soc/intel/apollolake/gpio.c
index 699c8fea28..a3ffb3de0f 100644
--- a/src/soc/intel/apollolake/gpio.c
+++ b/src/soc/intel/apollolake/gpio.c
@@ -19,6 +19,7 @@
#include <gpio.h>
#include <soc/gpio.h>
#include <soc/iosf.h>
+#include <soc/itss.h>
#include <soc/pm.h>
/* This list must be in order, from highest pad numbers, to lowest pad numbers*/
@@ -53,12 +54,43 @@ static const struct pad_community *gpio_get_community(uint16_t pad)
return map;
}
+static void gpio_configure_itss(const struct pad_config *cfg,
+ uint16_t port, uint16_t pad_cfg_offset)
+{
+ int irq;
+
+ /* Set up ITSS polarity if pad is routed to APIC.
+ *
+ * The ITSS takes only active high interrupt signals. Therefore,
+ * if the pad configuration indicates an inversion assume the
+ * intent is for the ITSS polarity. Before forwarding on the
+ * request to the APIC there's an inversion setting for how the
+ * signal is forwarded to the APIC. Honor the inversion setting
+ * in the GPIO pad configuration so that a hardware active low
+ * signal looks that way to the APIC (double inversion).
+ */
+ if (!(cfg->config0 & PAD_CFG0_ROUTE_IOAPIC))
+ return;
+
+ irq = iosf_read(port, pad_cfg_offset + sizeof(uint32_t));
+ irq &= PAD_CFG1_IRQ_MASK;
+ if (!irq) {
+ printk(BIOS_ERR, "GPIO %u doesn't support APIC routing,\n",
+ cfg->pad);
+ return;
+ }
+
+ itss_set_irq_polarity(irq, !!(cfg->config0 & PAD_CFG0_RX_POL_INVERT));
+}
+
void gpio_configure_pad(const struct pad_config *cfg)
{
const struct pad_community *comm = gpio_get_community(cfg->pad);
uint16_t config_offset = PAD_CFG_OFFSET(cfg->pad - comm->first_pad);
iosf_write(comm->port, config_offset, cfg->config0);
iosf_write(comm->port, config_offset + sizeof(uint32_t), cfg->config1);
+
+ gpio_configure_itss(cfg, comm->port, config_offset);
}
void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads)
diff --git a/src/soc/intel/apollolake/include/soc/gpio_defs.h b/src/soc/intel/apollolake/include/soc/gpio_defs.h
index c6e2c3cf91..48e08e783e 100644
--- a/src/soc/intel/apollolake/include/soc/gpio_defs.h
+++ b/src/soc/intel/apollolake/include/soc/gpio_defs.h
@@ -75,6 +75,7 @@
#define PAD_CFG0_RESET_PLTRST (2 << 30)
#define PAD_CFG0_RESET_RSMRST (3 << 30)
+#define PAD_CFG1_IRQ_MASK (0xff << 0)
#define PAD_CFG1_PULL_MASK (0xf << 10)
#define PAD_CFG1_PULL_NONE (0x0 << 10)
#define PAD_CFG1_PULL_DN_5K (0x2 << 10)