drivers: interrupt_controller: add LiteX interrupt controller driver
Add LiteX interrupt controller driver and bindings for this device.
Signed-off-by: Filip Kokosinski <fkokosinski@internships.antmicro.com>
Signed-off-by: Mateusz Holenko <mholenko@antmicro.com>
diff --git a/CODEOWNERS b/CODEOWNERS
index 69d6d27..5f6f38b 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -122,6 +122,7 @@
/drivers/i2s/i2s_ll_stm32* @avisconti
/drivers/ieee802154/ @jukkar @tbursztyka
/drivers/interrupt_controller/ @andrewboie
+/drivers/*/vexriscv_litex.c @mateusz-holenko @kgugala @pgielda
/drivers/led/ @Mani-Sadhasivam
/drivers/led_strip/ @mbolivar
/drivers/modem/ @mike-scott
@@ -174,6 +175,7 @@
/dts/bindings/sensor/ams* @alexanderwachter
/dts/bindings/*/sifive* @mateusz-holenko @kgugala @pgielda @nategraff-sifive
/dts/bindings/*/litex* @mateusz-holenko @kgugala @pgielda
+/dts/bindings/*/vexriscv* @mateusz-holenko @kgugala @pgielda
/ext/fs/ @nashif @wentongwu
/ext/hal/atmel/asf/sam/include/same70*/ @aurel32
/ext/hal/atmel/asf/sam0/include/samr21/ @benpicco
diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt
index 93cc8d6..2ee8dea 100644
--- a/drivers/interrupt_controller/CMakeLists.txt
+++ b/drivers/interrupt_controller/CMakeLists.txt
@@ -13,3 +13,4 @@
zephyr_sources_ifdef(CONFIG_DW_ICTL dw_ictl.c)
zephyr_sources_ifdef(CONFIG_RV32M1_INTMUX rv32m1_intmux.c)
zephyr_sources_ifdef(CONFIG_SAM0_EIC sam0_eic.c)
+zephyr_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ vexriscv_litex.c)
diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig
index 3266561..80201e8 100644
--- a/drivers/interrupt_controller/Kconfig
+++ b/drivers/interrupt_controller/Kconfig
@@ -119,6 +119,12 @@
Platform Level Interrupt Controller provides support
for external interrupt lines defined by the RISC-V SoC;
+config VEXRISCV_LITEX_IRQ
+ bool "VexRiscv LiteX Interrupt controller"
+ depends on SOC_RISCV32_LITEX_VEXRISCV
+ help
+ IRQ implementation for LiteX VexRiscv
+
config DW_ICTL
bool "Designware Interrupt Controller"
depends on MULTI_LEVEL_INTERRUPTS
diff --git a/drivers/interrupt_controller/vexriscv_litex.c b/drivers/interrupt_controller/vexriscv_litex.c
new file mode 100644
index 0000000..a94cf13
--- /dev/null
+++ b/drivers/interrupt_controller/vexriscv_litex.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <kernel.h>
+#include <arch/cpu.h>
+#include <init.h>
+#include <irq.h>
+#include <device.h>
+#include <zephyr.h>
+#include <zephyr/types.h>
+
+#define IRQ_MASK DT_VEXRISCV_INTC0_0_IRQ_MASK_BASE_ADDRESS
+#define IRQ_PENDING DT_VEXRISCV_INTC0_0_IRQ_PENDING_BASE_ADDRESS
+
+#define TIMER0_IRQ DT_LITEX_TIMER0_E0002800_IRQ_0
+#define UART0_IRQ DT_LITEX_UART0_E0001800_IRQ_0
+static inline void vexriscv_litex_irq_setmask(u32_t mask)
+{
+ __asm__ volatile ("csrw %0, %1" :: "i"(IRQ_MASK), "r"(mask));
+}
+
+static inline u32_t vexriscv_litex_irq_getmask(void)
+{
+ u32_t mask;
+
+ __asm__ volatile ("csrr %0, %1" : "=r"(mask) : "i"(IRQ_MASK));
+ return mask;
+}
+
+static inline u32_t vexriscv_litex_irq_pending(void)
+{
+ u32_t pending;
+
+ __asm__ volatile ("csrr %0, %1" : "=r"(pending) : "i"(IRQ_PENDING));
+ return pending;
+}
+
+static inline void vexriscv_litex_irq_setie(u32_t ie)
+{
+ if (ie) {
+ __asm__ volatile ("csrrs x0, mstatus, %0"
+ :: "r"(SOC_MSTATUS_IEN));
+ } else {
+ __asm__ volatile ("csrrc x0, mstatus, %0"
+ :: "r"(SOC_MSTATUS_IEN));
+ }
+}
+
+static void vexriscv_litex_irq_handler(void *device)
+{
+ struct _isr_table_entry *ite;
+ u32_t pending, mask, irqs;
+
+ pending = vexriscv_litex_irq_pending();
+ mask = vexriscv_litex_irq_getmask();
+ irqs = pending & mask;
+
+#ifdef CONFIG_LITEX_TIMER
+ if (irqs & (1 << TIMER0_IRQ)) {
+ ite = &_sw_isr_table[TIMER0_IRQ];
+ ite->isr(ite->arg);
+ }
+#endif
+
+#ifdef CONFIG_UART_INTERRUPT_DRIVEN
+ if (irqs & (1 << UART0_IRQ)) {
+ ite = &_sw_isr_table[UART0_IRQ];
+ ite->isr(ite->arg);
+ }
+#endif
+}
+
+void z_arch_irq_enable(unsigned int irq)
+{
+ vexriscv_litex_irq_setmask(vexriscv_litex_irq_getmask() | (1 << irq));
+}
+
+void z_arch_irq_disable(unsigned int irq)
+{
+ vexriscv_litex_irq_setmask(vexriscv_litex_irq_getmask() & ~(1 << irq));
+}
+
+int z_arch_irq_is_enabled(unsigned int irq)
+{
+ return vexriscv_litex_irq_getmask() & (1 << irq);
+}
+
+static int vexriscv_litex_irq_init(struct device *dev)
+{
+ ARG_UNUSED(dev);
+ __asm__ volatile ("csrrs x0, mie, %0"
+ :: "r"((1 << RISCV_MACHINE_TIMER_IRQ)
+ | (1 << RISCV_MACHINE_EXT_IRQ)));
+ vexriscv_litex_irq_setie(1);
+ IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, 0, vexriscv_litex_irq_handler,
+ NULL, 0);
+
+ return 0;
+}
+
+SYS_INIT(vexriscv_litex_irq_init, PRE_KERNEL_2,
+ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
diff --git a/dts/bindings/interrupt-controller/vexriscv,intc0.yaml b/dts/bindings/interrupt-controller/vexriscv,intc0.yaml
new file mode 100644
index 0000000..331a196
--- /dev/null
+++ b/dts/bindings/interrupt-controller/vexriscv,intc0.yaml
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+---
+title: LiteX VexRiscV Interrupt Controller
+version: 0.1
+
+description: >
+ This binding describes LiteX VexRiscV Interrupt Controller
+
+properties:
+ compatible:
+ category: required
+ type: string
+ description: compatible strings
+ constraint: "vexriscv,intc0"
+ generation: define
+
+ reg:
+ category: required
+ type: int
+ description: mmio register space
+ generation: define
+
+ riscv,max-priority:
+ type: int
+ description: maximum interrupt priority
+ category: required
+ generation: define
+
+"#cells":
+ - irq
+ - priority
+...