diff --git a/board/pine64/ox64/patches/linux/0027-Add-irqchip-driver.patch b/board/pine64/ox64/patches/linux/0027-Add-irqchip-driver.patch new file mode 100644 index 0000000..4fc2fc4 --- /dev/null +++ b/board/pine64/ox64/patches/linux/0027-Add-irqchip-driver.patch @@ -0,0 +1,186 @@ +From 1f8731ea052cf874984510e1997b2015538b4328 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Mon, 13 Mar 2023 20:57:20 -0500 +Subject: [PATCH] irqchip driver + +Signed-off-by: Samuel Holland +Signed-off-by: Alexander Horner +--- + 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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); diff --git a/board/pine64/ox64/patches/linux/0028-dts-bl808-SDH-uses-WL-sys-all-irq.patch b/board/pine64/ox64/patches/linux/0028-dts-bl808-SDH-uses-WL-sys-all-irq.patch new file mode 100644 index 0000000..016887d --- /dev/null +++ b/board/pine64/ox64/patches/linux/0028-dts-bl808-SDH-uses-WL-sys-all-irq.patch @@ -0,0 +1,110 @@ +From 09a33399684883c8c0aef48693e00f5d0747539d Mon Sep 17 00:00:00 2001 +From: qwang +Date: Tue, 12 Sep 2023 14:04:14 +0800 +Subject: [PATCH] dts: bl808: Use WL sys all irq + +Signed-off-by: qwang +--- + .../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 +