summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2016-07-12 23:39:51 -0500
committerAaron Durbin <adurbin@chromium.org>2016-07-13 21:58:22 +0200
commit1318e88352d7b20661adec82769f46308471d739 (patch)
treeb16ca346ca2f11952699befaa1ac17c14ece7457
parentc79101ab84be4ee145917b64c1e9ea23461f82c5 (diff)
soc/intel/apollolake: add initial ITSS support
The interrupt and timer subsystem (ITSS) sits between the APIC and the other logic blocks. It only supports positive polarity events, but there's a polarity inversion setting for each IRQ such that it can pass the signal on to the APIC according to the expected APIC redirection entry values. This support is needed in order for the platform/board to set the expected interrupt polarity into the APIC for gpio signals. BUG=chrome-os-partner:54955 Change-Id: I50ea1b7c4a7601e760878af515518cc0e808c0d1 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/15647 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Andrey Petrov <andrey.petrov@intel.com> Reviewed-by: Furquan Shaikh <furquan@google.com>
-rw-r--r--src/soc/intel/apollolake/Makefile.inc3
-rw-r--r--src/soc/intel/apollolake/include/soc/itss.h22
-rw-r--r--src/soc/intel/apollolake/itss.c43
3 files changed, 68 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 8dacdabbd5..c44fc464d5 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -13,6 +13,7 @@ bootblock-y += bootblock/cache_as_ram.S
bootblock-y += bootblock/bootblock.c
bootblock-y += car.c
bootblock-y += gpio.c
+bootblock-y += itss.c
bootblock-y += lpc_lib.c
bootblock-y += mmap_boot.c
bootblock-y += pmutil.c
@@ -24,6 +25,7 @@ romstage-y += car.c
romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage.c
romstage-y += gpio.c
romstage-y += i2c_early.c
+romstage-y += itss.c
romstage-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
romstage-y += lpc_lib.c
romstage-y += memmap.c
@@ -48,6 +50,7 @@ ramstage-y += dsp.c
ramstage-y += gpio.c
ramstage-y += graphics.c
ramstage-y += i2c.c
+ramstage-y += itss.c
ramstage-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
ramstage-y += lpc.c
ramstage-y += lpc_lib.c
diff --git a/src/soc/intel/apollolake/include/soc/itss.h b/src/soc/intel/apollolake/include/soc/itss.h
new file mode 100644
index 0000000000..1de722683e
--- /dev/null
+++ b/src/soc/intel/apollolake/include/soc/itss.h
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_APOLLOLAKE_ITSS_H_
+#define _SOC_APOLLOLAKE_ITSS_H_
+
+/* Set the interrupt polarity for provided IRQ to the APIC. */
+void itss_set_irq_polarity(int irq, int active_low);
+
+#endif /* _SOC_APOLLOLAKE_ITSS_H_ */
diff --git a/src/soc/intel/apollolake/itss.c b/src/soc/intel/apollolake/itss.c
new file mode 100644
index 0000000000..60d3e06406
--- /dev/null
+++ b/src/soc/intel/apollolake/itss.c
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <soc/iosf.h>
+#include <soc/itss.h>
+
+#define IOSF_ITSS_PORT_ID 0xd0
+#define ITSS_MAX_IRQ 119
+#define IPC0 0x3200
+#define IRQS_PER_IPC 32
+
+void itss_set_irq_polarity(int irq, int active_low)
+{
+ uint32_t mask;
+ uint32_t val;
+ uint16_t reg;
+ const uint16_t port = IOSF_ITSS_PORT_ID;
+
+ if (irq < 0 || irq > ITSS_MAX_IRQ)
+ return;
+
+ reg = IPC0 + sizeof(uint32_t) * (irq / IRQS_PER_IPC);
+ mask = 1 << (irq % IRQS_PER_IPC);
+
+ val = iosf_read(port, reg);
+ val &= ~mask;
+ /* Setting the bit makes the IRQ active low. */
+ val |= active_low ? mask : 0;
+ iosf_write(port, reg, val);
+}