Re: [PATCH v4 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Feb 20, 2025 at 3:06 PM Fabrizio Castro
<fabrizio.castro.jz@xxxxxxxxxxx> wrote:
>
> 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 and an ack 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 ids.
>
> Export rzv2h_icu_register_dma_req_ack() so that the DMA driver
> can register both ids in one go.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@xxxxxxxxxxx>
> Reviewed-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> ---
> v3->v4:
> * No change.
> v2->v3:
> * Replaced rzv2h_icu_register_dma_req_ack with
>   rzv2h_icu_register_dma_req_ack() in changelog.
> * Added dummy for rzv2h_icu_register_dma_req_ack().
> * Added Rb Thomas.
> v1->v2:
> * Improved macros.
> * Shared new macros for minimum values.
> ---
>  drivers/irqchip/irq-renesas-rzv2h.c       | 56 +++++++++++++++++++++++
>  include/linux/irqchip/irq-renesas-rzv2h.h | 26 +++++++++++
>  2 files changed, 82 insertions(+)
>  create mode 100644 include/linux/irqchip/irq-renesas-rzv2h.h
>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>

Cheers,
Prabhakar

> diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
> index fe2d29e91026..a8e9feda73b0 100644
> --- a/drivers/irqchip/irq-renesas-rzv2h.c
> +++ b/drivers/irqchip/irq-renesas-rzv2h.c
> @@ -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
> @@ -80,6 +83,19 @@
>  #define ICU_TINT_EXTRACT_GPIOINT(x)            FIELD_GET(GENMASK(31, 16), (x))
>  #define ICU_PB5_TINT                           0x55
>
> +/* 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))
> +
> +#define ICU_DMAC_DACK_SEL_SHIFT(field_no)      ((field_no) * 8)
> +#define ICU_DMAC_DACK_SEL_MASK(field_no)       (GENMASK(6, 0) << ICU_DMAC_DACK_SEL_SHIFT(field_no))
> +#define ICU_DMAC_PREP_DACK_SEL(sel, field_no)  ((sel) << ICU_DMAC_DACK_SEL_SHIFT(field_no))
> +
>  /**
>   * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
>   * @base:      Controller's base address
> @@ -94,6 +110,45 @@ struct rzv2h_icu_priv {
>         raw_spinlock_t                  lock;
>  };
>
> +void rzv2h_icu_register_dma_req_ack(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
> +                                   u16 req_no, u8 ack_no)
> +{
> +       struct rzv2h_icu_priv *priv = platform_get_drvdata(icu_dev);
> +       u32 icu_dmackselk, dmaack, dmaack_mask;
> +       u32 icu_dmksely, dmareq, dmareq_mask;
> +       u8 k, field_no;
> +       u8 y, upper;
> +
> +       if (req_no >= RZV2H_ICU_DMAC_REQ_NO_MIN_FIX_OUTPUT)
> +               req_no = RZV2H_ICU_DMAC_REQ_NO_DEFAULT;
> +
> +       if (ack_no >= RZV2H_ICU_DMAC_ACK_NO_MIN_FIX_OUTPUT)
> +               ack_no = RZV2H_ICU_DMAC_ACK_NO_DEFAULT;
> +
> +       y = dmac_channel / 2;
> +       upper = dmac_channel % 2;
> +
> +       dmareq = ICU_DMAC_PREP_DMAREQ(req_no, upper);
> +       dmareq_mask = ICU_DMAC_DMAREQ_MASK(upper);
> +
> +       k  = ack_no / 4;
> +       field_no = ack_no % 4;
> +
> +       dmaack_mask = ICU_DMAC_DACK_SEL_MASK(field_no);
> +       dmaack = ICU_DMAC_PREP_DACK_SEL(ack_no, field_no);
> +
> +       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));
> +
> +       icu_dmackselk = readl(priv->base + ICU_DMACKSELk(k));
> +       icu_dmackselk = (icu_dmackselk & ~dmaack_mask) | dmaack;
> +       writel(icu_dmackselk, priv->base + ICU_DMACKSELk(k));
> +}
> +EXPORT_SYMBOL_GPL(rzv2h_icu_register_dma_req_ack);
> +
>  static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
>  {
>         return data->domain->host_data;
> @@ -446,6 +501,7 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
>                 goto put_dev;
>         }
>
> +       platform_set_drvdata(pdev, rzv2h_icu_data);
>         rzv2h_icu_data->irqchip = &rzv2h_icu_chip;
>
>         rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
> diff --git a/include/linux/irqchip/irq-renesas-rzv2h.h b/include/linux/irqchip/irq-renesas-rzv2h.h
> new file mode 100644
> index 000000000000..d06e01bf969b
> --- /dev/null
> +++ b/include/linux/irqchip/irq-renesas-rzv2h.h
> @@ -0,0 +1,26 @@
> +/* 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
> +#define RZV2H_ICU_DMAC_ACK_NO_DEFAULT          0x7f
> +#define RZV2H_ICU_DMAC_REQ_NO_MIN_FIX_OUTPUT   0x1b5
> +#define RZV2H_ICU_DMAC_ACK_NO_MIN_FIX_OUTPUT   0x50
> +
> +#ifdef CONFIG_RENESAS_RZV2H_ICU
> +void rzv2h_icu_register_dma_req_ack(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
> +                                   u16 req_no, u8 ack_no);
> +#else
> +static inline void rzv2h_icu_register_dma_req_ack(struct platform_device *icu_dev, u8 dmac_index,
> +                                                 u8 dmac_channel, u16 req_no, u8 ack_no) { }
> +#endif
> +
> +#endif
> --
> 2.34.1
>
>





[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux