]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req()
authorFabrizio Castro <fabrizio.castro.jz@renesas.com>
Wed, 23 Apr 2025 14:34:19 +0000 (15:34 +0100)
committerVinod Koul <vkoul@kernel.org>
Wed, 14 May 2025 14:30:40 +0000 (15:30 +0100)
On the Renesas RZ/V2H(P) family of SoCs, DMAC IPs are connected
to the Interrupt Control Unit (ICU).
For DMA transfers, a request number must be registered with the
ICU, which means that the DMAC driver has to be able to instruct
the ICU driver with the registration of such id.

Export rzv2h_icu_register_dma_req() so that the DMAC driver can
register the DMAC request number.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20250423143422.3747702-4-fabrizio.castro.jz@renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/irqchip/irq-renesas-rzv2h.c
include/linux/irqchip/irq-renesas-rzv2h.h [new file with mode: 0644]

index 3d5b5fdf9bde823cc4942961890a009c26e356b1..c0322bdfc69f9a364d7ae6f88afe756f60dece8e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/irqchip.h>
+#include <linux/irqchip/irq-renesas-rzv2h.h>
 #include <linux/irqdomain.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -41,6 +42,8 @@
 #define ICU_TSCLR                              0x24
 #define ICU_TITSR(k)                           (0x28 + (k) * 4)
 #define ICU_TSSR(k)                            (0x30 + (k) * 4)
+#define ICU_DMkSELy(k, y)                      (0x420 + (k) * 0x20 + (y) * 4)
+#define ICU_DMACKSELk(k)                       (0x500 + (k) * 4)
 
 /* NMI */
 #define ICU_NMI_EDGE_FALLING                   0
@@ -103,6 +106,15 @@ struct rzv2h_hw_info {
        u8              field_width;
 };
 
+/* DMAC */
+#define ICU_DMAC_DkRQ_SEL_MASK                 GENMASK(9, 0)
+
+#define ICU_DMAC_DMAREQ_SHIFT(up)              ((up) * 16)
+#define ICU_DMAC_DMAREQ_MASK(up)               (ICU_DMAC_DkRQ_SEL_MASK \
+                                                << ICU_DMAC_DMAREQ_SHIFT(up))
+#define ICU_DMAC_PREP_DMAREQ(sel, up)          (FIELD_PREP(ICU_DMAC_DkRQ_SEL_MASK, (sel)) \
+                                                << ICU_DMAC_DMAREQ_SHIFT(up))
+
 /**
  * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
  * @base:      Controller's base address
@@ -117,6 +129,27 @@ struct rzv2h_icu_priv {
        const struct rzv2h_hw_info      *info;
 };
 
+void rzv2h_icu_register_dma_req(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
+                               u16 req_no)
+{
+       struct rzv2h_icu_priv *priv = platform_get_drvdata(icu_dev);
+       u32 icu_dmksely, dmareq, dmareq_mask;
+       u8 y, upper;
+
+       y = dmac_channel / 2;
+       upper = dmac_channel % 2;
+
+       dmareq = ICU_DMAC_PREP_DMAREQ(req_no, upper);
+       dmareq_mask = ICU_DMAC_DMAREQ_MASK(upper);
+
+       guard(raw_spinlock_irqsave)(&priv->lock);
+
+       icu_dmksely = readl(priv->base + ICU_DMkSELy(dmac_index, y));
+       icu_dmksely = (icu_dmksely & ~dmareq_mask) | dmareq;
+       writel(icu_dmksely, priv->base + ICU_DMkSELy(dmac_index, y));
+}
+EXPORT_SYMBOL_GPL(rzv2h_icu_register_dma_req);
+
 static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
 {
        return data->domain->host_data;
@@ -483,6 +516,8 @@ static int rzv2h_icu_init_common(struct device_node *node, struct device_node *p
        if (!rzv2h_icu_data)
                return -ENOMEM;
 
+       platform_set_drvdata(pdev, rzv2h_icu_data);
+
        rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
        if (IS_ERR(rzv2h_icu_data->base))
                return PTR_ERR(rzv2h_icu_data->base);
diff --git a/include/linux/irqchip/irq-renesas-rzv2h.h b/include/linux/irqchip/irq-renesas-rzv2h.h
new file mode 100644 (file)
index 0000000..618a60d
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Renesas RZ/V2H(P) Interrupt Control Unit (ICU)
+ *
+ * Copyright (C) 2025 Renesas Electronics Corporation.
+ */
+
+#ifndef __LINUX_IRQ_RENESAS_RZV2H
+#define __LINUX_IRQ_RENESAS_RZV2H
+
+#include <linux/platform_device.h>
+
+#define RZV2H_ICU_DMAC_REQ_NO_DEFAULT          0x3ff
+
+#ifdef CONFIG_RENESAS_RZV2H_ICU
+void rzv2h_icu_register_dma_req(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
+                               u16 req_no);
+#else
+static inline void rzv2h_icu_register_dma_req(struct platform_device *icu_dev, u8 dmac_index,
+                                             u8 dmac_channel, u16 req_no) { }
+#endif
+
+#endif /* __LINUX_IRQ_RENESAS_RZV2H */