-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #77 from ivq/up_use_mcu_irq
Use WL sys all irq
- Loading branch information
Showing
2 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
186 changes: 186 additions & 0 deletions
186
board/pine64/ox64/patches/linux/0027-Add-irqchip-driver.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
From 1f8731ea052cf874984510e1997b2015538b4328 Mon Sep 17 00:00:00 2001 | ||
From: Samuel Holland <[email protected]> | ||
Date: Mon, 13 Mar 2023 20:57:20 -0500 | ||
Subject: [PATCH] irqchip driver | ||
|
||
Signed-off-by: Samuel Holland <[email protected]> | ||
Signed-off-by: Alexander Horner <[email protected]> | ||
--- | ||
drivers/irqchip/Makefile | 1 + | ||
drivers/irqchip/irq-bflb-mcu.c | 155 +++++++++++++++++++++++++++++++++ | ||
2 files changed, 156 insertions(+) | ||
create mode 100644 drivers/irqchip/irq-bflb-mcu.c | ||
|
||
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile | ||
index ffd945fe71aa2c..a559ec301f5f37 100644 | ||
--- a/drivers/irqchip/Makefile | ||
+++ b/drivers/irqchip/Makefile | ||
@@ -7,6 +7,7 @@ obj-$(CONFIG_ATH79) += irq-ath79-cpu.o | ||
obj-$(CONFIG_ATH79) += irq-ath79-misc.o | ||
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o | ||
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o | ||
+obj-$(CONFIG_SOC_BOUFFALOLAB) += irq-bflb-mcu.o | ||
obj-$(CONFIG_ARCH_ACTIONS) += irq-owl-sirq.o | ||
obj-$(CONFIG_DAVINCI_CP_INTC) += irq-davinci-cp-intc.o | ||
obj-$(CONFIG_EXYNOS_IRQ_COMBINER) += exynos-combiner.o | ||
diff --git a/drivers/irqchip/irq-bflb-mcu.c b/drivers/irqchip/irq-bflb-mcu.c | ||
new file mode 100644 | ||
index 00000000000000..e02458b3d6e8d6 | ||
--- /dev/null | ||
+++ b/drivers/irqchip/irq-bflb-mcu.c | ||
@@ -0,0 +1,155 @@ | ||
+// SPDX-License-Identifier: GPL-2.0 | ||
+/* | ||
+ * Hardware state machine: | ||
+ * - Set status = 1 when all of the below conditions are met: | ||
+ * a) trigger == 1 | ||
+ * b) mask == 0 | ||
+ * c) last pass trigger == 0 OR last pass mask == 1 | ||
+ * - Set status = 0 when writing clear = 1 | ||
+ * | ||
+ * This means: | ||
+ * - Mask without ack does nothing. | ||
+ * - Unmask retriggers level interrupts. | ||
+ */ | ||
+ | ||
+#include <linux/interrupt.h> | ||
+#include <linux/irq.h> | ||
+#include <linux/irqchip.h> | ||
+#include <linux/irqchip/chained_irq.h> | ||
+#include <linux/irqdomain.h> | ||
+#include <linux/of.h> | ||
+#include <linux/of_address.h> | ||
+ | ||
+#define BFLB_MCU_STATUS(n) (0x00 + 4 * (n)) | ||
+#define BFLB_MCU_MASK(n) (0x08 + 4 * (n)) | ||
+#define BFLB_MCU_CLEAR(n) (0x10 + 4 * (n)) | ||
+ | ||
+#define BFLB_MCU_NR_IRQS 64 | ||
+ | ||
+static void bflb_mcu_irq_ack(struct irq_data *d) | ||
+{ | ||
+ irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
+ void __iomem *regs = irq_data_get_irq_chip_data(d); | ||
+ void __iomem *reg = regs + BFLB_MCU_CLEAR(hwirq / 32); | ||
+ unsigned int bit = BIT(hwirq % 32); | ||
+ | ||
+ writel_relaxed(bit, reg); | ||
+} | ||
+ | ||
+static void bflb_mcu_irq_mask(struct irq_data *d) | ||
+{ | ||
+ irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
+ void __iomem *regs = irq_data_get_irq_chip_data(d); | ||
+ void __iomem *reg = regs + BFLB_MCU_MASK(hwirq / 32); | ||
+ unsigned int bit = BIT(hwirq % 32); | ||
+ | ||
+ writel_relaxed(readl_relaxed(reg) | bit, reg); | ||
+} | ||
+ | ||
+static void bflb_mcu_irq_mask_ack(struct irq_data *d) | ||
+{ | ||
+ irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
+ void __iomem *regs = irq_data_get_irq_chip_data(d); | ||
+ void __iomem *mask_reg = regs + BFLB_MCU_MASK(hwirq / 32); | ||
+ void __iomem *ack_reg = regs + BFLB_MCU_CLEAR(hwirq / 32); | ||
+ unsigned int bit = BIT(hwirq % 32); | ||
+ | ||
+ writel_relaxed(readl_relaxed(mask_reg) | bit, mask_reg); | ||
+ writel_relaxed(bit, ack_reg); | ||
+} | ||
+ | ||
+static void bflb_mcu_irq_unmask(struct irq_data *d) | ||
+{ | ||
+ irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
+ void __iomem *regs = irq_data_get_irq_chip_data(d); | ||
+ void __iomem *reg = regs + BFLB_MCU_MASK(hwirq / 32); | ||
+ unsigned int bit = BIT(hwirq % 32); | ||
+ | ||
+ writel_relaxed(readl_relaxed(reg) & ~bit, reg); | ||
+} | ||
+ | ||
+static const struct irq_chip bflb_mcu_irq_chip = { | ||
+ .name = "BFLB MCU", | ||
+ .irq_ack = bflb_mcu_irq_ack, | ||
+ .irq_mask = bflb_mcu_irq_mask, | ||
+ .irq_mask_ack = bflb_mcu_irq_mask_ack, | ||
+ .irq_unmask = bflb_mcu_irq_unmask, | ||
+ .flags = IRQCHIP_SKIP_SET_WAKE, | ||
+}; | ||
+ | ||
+static int bflb_mcu_domain_map(struct irq_domain *domain, unsigned int virq, | ||
+ irq_hw_number_t hwirq) | ||
+{ | ||
+ irq_domain_set_info(domain, virq, hwirq, &bflb_mcu_irq_chip, | ||
+ domain->host_data, handle_level_irq, NULL, NULL); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static const struct irq_domain_ops bflb_mcu_domain_ops = { | ||
+ .map = bflb_mcu_domain_map, | ||
+ .xlate = irq_domain_xlate_onecell, | ||
+}; | ||
+ | ||
+static void bflb_mcu_handle_irq(struct irq_desc *desc) | ||
+{ | ||
+ struct irq_domain *domain = irq_desc_get_handler_data(desc); | ||
+ struct irq_chip *chip = irq_desc_get_chip(desc); | ||
+ void __iomem *regs = domain->host_data; | ||
+ | ||
+ chained_irq_enter(chip, desc); | ||
+ | ||
+ for (unsigned int i = 0; i < BITS_TO_U32(BFLB_MCU_NR_IRQS); ++i) { | ||
+ unsigned long status = readl_relaxed(regs + BFLB_MCU_STATUS(i)); | ||
+ int bit; | ||
+ | ||
+ for_each_set_bit(bit, &status, 32) | ||
+ generic_handle_domain_irq(domain, 32 * i + bit); | ||
+ } | ||
+ | ||
+ chained_irq_exit(chip, desc); | ||
+} | ||
+ | ||
+static int __init bflb_mcu_init(struct device_node *node, | ||
+ struct device_node *parent) | ||
+{ | ||
+ struct irq_domain *domain; | ||
+ void __iomem *regs; | ||
+ int irq, ret; | ||
+ | ||
+ regs = of_io_request_and_map(node, 0, NULL); | ||
+ if (IS_ERR(regs)) | ||
+ return PTR_ERR(regs); | ||
+ | ||
+ irq = irq_of_parse_and_map(node, 0); | ||
+ if (irq <= 0) { | ||
+ ret = -EINVAL; | ||
+ goto out_iounmap; | ||
+ } | ||
+ | ||
+ domain = irq_domain_add_linear(node, BFLB_MCU_NR_IRQS, | ||
+ &bflb_mcu_domain_ops, regs); | ||
+ if (!domain) { | ||
+ ret = -ENOMEM; | ||
+ goto out_unmap_irq; | ||
+ } | ||
+ | ||
+ /* Mask and ack all interrupts. */ | ||
+ writel_relaxed(0xffffffff, regs + BFLB_MCU_MASK(0)); | ||
+ writel_relaxed(0xffffffff, regs + BFLB_MCU_MASK(1)); | ||
+ writel_relaxed(0xffffffff, regs + BFLB_MCU_CLEAR(0)); | ||
+ writel_relaxed(0xffffffff, regs + BFLB_MCU_CLEAR(1)); | ||
+ | ||
+ irq_set_chained_handler_and_data(irq, bflb_mcu_handle_irq, domain); | ||
+ | ||
+ return 0; | ||
+ | ||
+out_unmap_irq: | ||
+ irq_dispose_mapping(irq); | ||
+out_iounmap: | ||
+ iounmap(regs); | ||
+ | ||
+ return ret; | ||
+} | ||
+ | ||
+IRQCHIP_DECLARE(bflb_mcu, "bflb,bl808-mcu-irq", bflb_mcu_init); |
110 changes: 110 additions & 0 deletions
110
board/pine64/ox64/patches/linux/0028-dts-bl808-SDH-uses-WL-sys-all-irq.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
From 09a33399684883c8c0aef48693e00f5d0747539d Mon Sep 17 00:00:00 2001 | ||
From: qwang <[email protected]> | ||
Date: Tue, 12 Sep 2023 14:04:14 +0800 | ||
Subject: [PATCH] dts: bl808: Use WL sys all irq | ||
|
||
Signed-off-by: qwang <[email protected]> | ||
--- | ||
.../dts/bouffalolab/bl808-pine64-ox64.dts | 2 ++ | ||
.../boot/dts/bouffalolab/bl808-sipeed-m1s.dts | 2 ++ | ||
arch/riscv/boot/dts/bouffalolab/bl808.dtsi | 26 +++++++++++-------- | ||
3 files changed, 19 insertions(+), 11 deletions(-) | ||
|
||
diff --git a/arch/riscv/boot/dts/bouffalolab/bl808-pine64-ox64.dts b/arch/riscv/boot/dts/bouffalolab/bl808-pine64-ox64.dts | ||
index 0d8ba867a..e5c291471 100644 | ||
--- a/arch/riscv/boot/dts/bouffalolab/bl808-pine64-ox64.dts | ||
+++ b/arch/riscv/boot/dts/bouffalolab/bl808-pine64-ox64.dts | ||
@@ -59,6 +59,8 @@ &sdhci0 { | ||
status = "okay"; | ||
}; | ||
|
||
+/* | ||
&ipclic { | ||
status = "okay"; | ||
}; | ||
+*/ | ||
diff --git a/arch/riscv/boot/dts/bouffalolab/bl808-sipeed-m1s.dts b/arch/riscv/boot/dts/bouffalolab/bl808-sipeed-m1s.dts | ||
index 4a12e6941..f713d468c 100644 | ||
--- a/arch/riscv/boot/dts/bouffalolab/bl808-sipeed-m1s.dts | ||
+++ b/arch/riscv/boot/dts/bouffalolab/bl808-sipeed-m1s.dts | ||
@@ -69,6 +69,8 @@ &sdhci0 { | ||
status = "okay"; | ||
}; | ||
|
||
+/* | ||
&ipclic { | ||
status = "okay"; | ||
}; | ||
+*/ | ||
diff --git a/arch/riscv/boot/dts/bouffalolab/bl808.dtsi b/arch/riscv/boot/dts/bouffalolab/bl808.dtsi | ||
index 06d2453ef..091048440 100644 | ||
--- a/arch/riscv/boot/dts/bouffalolab/bl808.dtsi | ||
+++ b/arch/riscv/boot/dts/bouffalolab/bl808.dtsi | ||
@@ -75,8 +75,7 @@ pinctrl: pinctrl@0x200008C4 { | ||
|
||
interrupt-controller; | ||
#interrupt-cells = <2>; | ||
- interrupts-extended = <&ipclic BFLB_IPC_SOURCE_M0 | ||
- BFLB_IPC_DEVICE_GPIO IRQ_TYPE_EDGE_RISING>; | ||
+ interrupts-extended = <&m0ic 44>; | ||
|
||
sdh_pins: sdh-pins { | ||
pins = "GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO5"; | ||
@@ -101,10 +100,7 @@ uart0: serial@30002000 { | ||
uart1: serial@0x2000AA00 { | ||
compatible = "bflb,bl808-uart"; | ||
reg = <0x2000AA00 0x0100>; | ||
- interrupts-extended = <&ipclic BFLB_IPC_SOURCE_M0 | ||
- BFLB_IPC_DEVICE_UART2 | ||
- IRQ_TYPE_EDGE_RISING>; | ||
- mboxes = <&ipclic BFLB_IPC_SOURCE_M0 BFLB_IPC_DEVICE_UART2>; | ||
+ interrupts-extended = <&m0ic 30>; | ||
clocks = <&xtal>; | ||
status = "disabled"; | ||
}; | ||
@@ -112,14 +108,12 @@ BFLB_IPC_DEVICE_UART2 | ||
sdhci0: sdhci@20060000 { | ||
compatible = "bflb,bl808-sdhci"; | ||
reg = <0x20060000 0x100>; | ||
- interrupts-extended = <&ipclic BFLB_IPC_SOURCE_M0 | ||
- BFLB_IPC_DEVICE_SDHCI | ||
- IRQ_TYPE_EDGE_RISING>; | ||
- mboxes = <&ipclic BFLB_IPC_SOURCE_M0 BFLB_IPC_DEVICE_SDHCI>; | ||
+ interrupts-extended = <&m0ic 17>; | ||
clocks = <&sdh>; | ||
status = "disabled"; | ||
}; | ||
|
||
+ /* | ||
ipclic: mailbox@30005000 { | ||
compatible = "bflb,bl808-ipc"; | ||
reg = <0x30005000 0x20>, | ||
@@ -132,6 +126,16 @@ ipclic: mailbox@30005000 { | ||
#mbox-cells = <2>; | ||
status = "disabled"; | ||
}; | ||
+ */ | ||
+ | ||
+ m0ic: mcu-interrupt-controller@20000050 { | ||
+ compatible = "bflb,bl808-mcu-irq"; | ||
+ reg = <0x20000050 0x18>; | ||
+ interrupts = <81 IRQ_TYPE_LEVEL_HIGH>; | ||
+ interrupt-controller; | ||
+ #address-cells = <0>; | ||
+ #interrupt-cells = <1>; | ||
+ }; | ||
|
||
plic: interrupt-controller@e0000000 { | ||
compatible = "thead,c900-plic"; | ||
@@ -141,7 +145,7 @@ plic: interrupt-controller@e0000000 { | ||
interrupt-controller; | ||
#address-cells = <0>; | ||
#interrupt-cells = <2>; | ||
- riscv,ndev = <64>; | ||
+ riscv,ndev = <82>; | ||
}; | ||
|
||
clint: timer@e4000000 { | ||
-- | ||
2.42.1 | ||
|