* [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H
@ 2026-03-09 15:06 Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 01/17] spi: dt-bindings: Document the RZ/V2H(P) RSPI Cosmin Tanislav
` (18 more replies)
0 siblings, 19 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
This series adds RSPI support for the Renesas RZ/T2H (R9A09G077) and
RZ/N2H (R9A09G087) SoCs.
RZ/T2H and RZ/N2H support is implemented as part of the RZ/V2H RSPI
driver, and, as such, the RZ/V2H RSPI driver had to be backported.
Patches were cherry-picked from upstream kernel.
This series applies on top of my previously submitted series [1] (to
avoid a conflict in drivers/clk/renesas/r9a09g077-cpg.c mainly).
[1]: https://patchwork.kernel.org/project/cip-dev/cover/20260303165351.914437-1-cosmin-gabriel.tanislav.xa@renesas.com/
V3:
* describe changes made to apply on top of CIP
V2:
* remove internal Reviewed-by tags
Cosmin Tanislav (14):
clk: renesas: r9a09g077: Add SPI module clocks
spi: rzv2h-rspi: make resets optional
spi: rzv2h-rspi: make FIFO size chip-specific
spi: rzv2h-rspi: make clocks chip-specific
spi: rzv2h-rspi: move register writes out of rzv2h_rspi_setup_clock()
spi: rzv2h-rspi: avoid recomputing transfer frequency
spi: rzv2h-rspi: make transfer clock rate finding chip-specific
spi: rzv2h-rspi: add support for using PCLK for transfer clock
spi: rzv2h-rspi: add support for variable transfer clock
spi: rzv2h-rspi: add support for loopback mode
spi: rzv2h-rspi: add support for RZ/T2H and RZ/N2H
spi: dt-bindings: renesas,rzv2h-rspi: document RZ/T2H and RZ/N2H
arm64: dts: renesas: r9a09g077: Add SPI nodes
arm64: dts: renesas: r9a09g087: Add SPI nodes
Fabrizio Castro (3):
spi: dt-bindings: Document the RZ/V2H(P) RSPI
spi: Add driver for the RZ/V2H(P) RSPI IP
arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
.../bindings/spi/renesas,rzv2h-rspi.yaml | 138 ++++
arch/arm64/boot/dts/renesas/r9a09g077.dtsi | 72 ++
arch/arm64/boot/dts/renesas/r9a09g087.dtsi | 72 ++
arch/arm64/configs/defconfig | 1 +
drivers/clk/renesas/r9a09g077-cpg.c | 22 +-
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-rzv2h-rspi.c | 687 ++++++++++++++++++
8 files changed, 1000 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
create mode 100644 drivers/spi/spi-rzv2h-rspi.c
--
2.53.0
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 01/17] spi: dt-bindings: Document the RZ/V2H(P) RSPI
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 02/17] spi: Add driver for the RZ/V2H(P) RSPI IP Cosmin Tanislav
` (17 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
commit 44b91d61c505863b8ae90b7094aee5ca0dce808f upstream.
Add dt-bindings for the RSPI IP found inside the Renesas RZ/V2H(P)
SoC.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20250704162036.468765-2-fabrizio.castro.jz@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
.../bindings/spi/renesas,rzv2h-rspi.yaml | 96 +++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
diff --git a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
new file mode 100644
index 000000000000..ab27fefc3c3a
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/renesas,rzv2h-rspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2H(P) Renesas Serial Peripheral Interface (RSPI)
+
+maintainers:
+ - Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+
+allOf:
+ - $ref: spi-controller.yaml#
+
+properties:
+ compatible:
+ const: renesas,r9a09g057-rspi # RZ/V2H(P)
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ items:
+ - description: Idle Interrupt
+ - description: Error Interrupt
+ - description: Communication End Interrupt
+ - description: Receive Buffer Full Interrupt
+ - description: Transmit Buffer Empty Interrupt
+
+ interrupt-names:
+ items:
+ - const: idle
+ - const: error
+ - const: end
+ - const: rx
+ - const: tx
+
+ clocks:
+ maxItems: 3
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: pclk_sfr
+ - const: tclk
+
+ resets:
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: presetn
+ - const: tresetn
+
+ power-domains:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-names
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - power-domains
+ - '#address-cells'
+ - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/renesas-cpg-mssr.h>
+ spi@12800800 {
+ compatible = "renesas,r9a09g057-rspi";
+
+ reg = <0x12800800 0x400>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 504 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 505 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_MOD 0x5a>,
+ <&cpg CPG_MOD 0x5b>,
+ <&cpg CPG_MOD 0x5c>;
+ clock-names = "pclk", "pclk_sfr", "tclk";
+ resets = <&cpg 0x7f>, <&cpg 0x80>;
+ reset-names = "presetn", "tresetn";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 02/17] spi: Add driver for the RZ/V2H(P) RSPI IP
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 01/17] spi: dt-bindings: Document the RZ/V2H(P) RSPI Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-13 10:17 ` [cip-dev] " Pavel Machek
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 03/17] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Cosmin Tanislav
` (16 subsequent siblings)
18 siblings, 1 reply; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
commit 8b61c8919dff080d83415523cd68f2fef03ccfc7 upstream.
The Renesas RZ/V2H(P) RSPI IP supports 4-wire and 3-wire
serial communications in both host role and target role.
It can use a DMA, but the I/O can also be driven by the
processor.
RX-only, TX-only, and RX-TX operations are available in
DMA mode, while in processor I/O mode it only RX-TX
operations are supported.
Add a driver to support 4-wire serial communications as
host role in processor I/O mode.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Link: https://patch.msgid.link/20250704162036.468765-3-fabrizio.castro.jz@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-rzv2h-rspi.c | 466 +++++++++++++++++++++++++++++++++++
3 files changed, 475 insertions(+)
create mode 100644 drivers/spi/spi-rzv2h-rspi.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 06c740442fa7..9ea2f3ebc0ed 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -885,6 +885,14 @@ config SPI_RSPI
help
SPI driver for Renesas RSPI and QSPI blocks.
+config SPI_RZV2H_RSPI
+ tristate "Renesas RZ/V2H RSPI controller"
+ depends on ARCH_RENESAS || COMPILE_TEST
+ help
+ RSPI driver for the Renesas RZ/V2H Serial Peripheral Interface (RSPI).
+ RSPI supports both SPI host and SPI target roles. This option only
+ enables the SPI host role.
+
config SPI_RZV2M_CSI
tristate "Renesas RZ/V2M CSI controller"
depends on ARCH_RENESAS || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index a9b1bc259b68..969e98237655 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+obj-$(CONFIG_SPI_RZV2H_RSPI) += spi-rzv2h-rspi.o
obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
new file mode 100644
index 000000000000..dcc431ba60a9
--- /dev/null
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Renesas RZ/V2H Renesas Serial Peripheral Interface (RSPI)
+ *
+ * Copyright (C) 2025 Renesas Electronics Corporation
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/limits.h>
+#include <linux/log2.h>
+#include <linux/math.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+#include <linux/wait.h>
+
+/* Registers */
+#define RSPI_SPDR 0x00
+#define RSPI_SPCR 0x08
+#define RSPI_SSLP 0x10
+#define RSPI_SPBR 0x11
+#define RSPI_SPSCR 0x13
+#define RSPI_SPCMD 0x14
+#define RSPI_SPDCR2 0x44
+#define RSPI_SPSR 0x52
+#define RSPI_SPSRC 0x6a
+#define RSPI_SPFCR 0x6c
+
+/* Register SPCR */
+#define RSPI_SPCR_MSTR BIT(30)
+#define RSPI_SPCR_SPRIE BIT(17)
+#define RSPI_SPCR_SCKASE BIT(12)
+#define RSPI_SPCR_SPE BIT(0)
+
+/* Register SPBR */
+#define RSPI_SPBR_SPR_MIN 0
+#define RSPI_SPBR_SPR_MAX 255
+
+/* Register SPCMD */
+#define RSPI_SPCMD_SSLA GENMASK(25, 24)
+#define RSPI_SPCMD_SPB GENMASK(20, 16)
+#define RSPI_SPCMD_LSBF BIT(12)
+#define RSPI_SPCMD_SSLKP BIT(7)
+#define RSPI_SPCMD_BRDV GENMASK(3, 2)
+#define RSPI_SPCMD_CPOL BIT(1)
+#define RSPI_SPCMD_CPHA BIT(0)
+
+#define RSPI_SPCMD_BRDV_MIN 0
+#define RSPI_SPCMD_BRDV_MAX 3
+
+/* Register SPDCR2 */
+#define RSPI_SPDCR2_TTRG GENMASK(11, 8)
+#define RSPI_SPDCR2_RTRG GENMASK(3, 0)
+#define RSPI_FIFO_SIZE 16
+
+/* Register SPSR */
+#define RSPI_SPSR_SPRF BIT(15)
+
+/* Register RSPI_SPSRC */
+#define RSPI_SPSRC_CLEAR 0xfd80
+
+#define RSPI_RESET_NUM 2
+#define RSPI_CLK_NUM 3
+
+struct rzv2h_rspi_priv {
+ struct reset_control_bulk_data resets[RSPI_RESET_NUM];
+ struct spi_controller *controller;
+ void __iomem *base;
+ struct clk *tclk;
+ wait_queue_head_t wait;
+ unsigned int bytes_per_word;
+ u32 freq;
+ u16 status;
+};
+
+#define RZV2H_RSPI_TX(func, type) \
+static inline void rzv2h_rspi_tx_##type(struct rzv2h_rspi_priv *rspi, \
+ const void *txbuf, \
+ unsigned int index) { \
+ type buf = 0; \
+ \
+ if (txbuf) \
+ buf = ((type *)txbuf)[index]; \
+ \
+ func(buf, rspi->base + RSPI_SPDR); \
+}
+
+#define RZV2H_RSPI_RX(func, type) \
+static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
+ void *rxbuf, \
+ unsigned int index) { \
+ type buf = func(rspi->base + RSPI_SPDR); \
+ \
+ if (rxbuf) \
+ ((type *)rxbuf)[index] = buf; \
+}
+
+RZV2H_RSPI_TX(writel, u32)
+RZV2H_RSPI_TX(writew, u16)
+RZV2H_RSPI_TX(writeb, u8)
+RZV2H_RSPI_RX(readl, u32)
+RZV2H_RSPI_RX(readw, u16)
+RZV2H_RSPI_RX(readl, u8)
+
+static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
+ int reg_offs, u32 bit_mask, u32 value)
+{
+ u32 tmp;
+
+ value <<= __ffs(bit_mask);
+ tmp = (readl(rspi->base + reg_offs) & ~bit_mask) | value;
+ writel(tmp, rspi->base + reg_offs);
+}
+
+static inline void rzv2h_rspi_spe_disable(const struct rzv2h_rspi_priv *rspi)
+{
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 0);
+}
+
+static inline void rzv2h_rspi_spe_enable(const struct rzv2h_rspi_priv *rspi)
+{
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 1);
+}
+
+static inline void rzv2h_rspi_clear_fifos(const struct rzv2h_rspi_priv *rspi)
+{
+ writeb(1, rspi->base + RSPI_SPFCR);
+}
+
+static inline void rzv2h_rspi_clear_all_irqs(struct rzv2h_rspi_priv *rspi)
+{
+ writew(RSPI_SPSRC_CLEAR, rspi->base + RSPI_SPSRC);
+ rspi->status = 0;
+}
+
+static irqreturn_t rzv2h_rx_irq_handler(int irq, void *data)
+{
+ struct rzv2h_rspi_priv *rspi = data;
+
+ rspi->status = readw(rspi->base + RSPI_SPSR);
+ wake_up(&rspi->wait);
+
+ return IRQ_HANDLED;
+}
+
+static inline int rzv2h_rspi_wait_for_interrupt(struct rzv2h_rspi_priv *rspi,
+ u32 wait_mask)
+{
+ return wait_event_timeout(rspi->wait, (rspi->status & wait_mask),
+ HZ) == 0 ? -ETIMEDOUT : 0;
+}
+
+static void rzv2h_rspi_send(struct rzv2h_rspi_priv *rspi, const void *txbuf,
+ unsigned int index)
+{
+ switch (rspi->bytes_per_word) {
+ case 4:
+ rzv2h_rspi_tx_u32(rspi, txbuf, index);
+ break;
+ case 2:
+ rzv2h_rspi_tx_u16(rspi, txbuf, index);
+ break;
+ default:
+ rzv2h_rspi_tx_u8(rspi, txbuf, index);
+ }
+}
+
+static int rzv2h_rspi_receive(struct rzv2h_rspi_priv *rspi, void *rxbuf,
+ unsigned int index)
+{
+ int ret;
+
+ ret = rzv2h_rspi_wait_for_interrupt(rspi, RSPI_SPSR_SPRF);
+ if (ret)
+ return ret;
+
+ switch (rspi->bytes_per_word) {
+ case 4:
+ rzv2h_rspi_rx_u32(rspi, rxbuf, index);
+ break;
+ case 2:
+ rzv2h_rspi_rx_u16(rspi, rxbuf, index);
+ break;
+ default:
+ rzv2h_rspi_rx_u8(rspi, rxbuf, index);
+ }
+
+ return 0;
+}
+
+static int rzv2h_rspi_transfer_one(struct spi_controller *controller,
+ struct spi_device *spi,
+ struct spi_transfer *transfer)
+{
+ struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(controller);
+ unsigned int words_to_transfer, i;
+ int ret = 0;
+
+ transfer->effective_speed_hz = rspi->freq;
+ words_to_transfer = transfer->len / rspi->bytes_per_word;
+
+ for (i = 0; i < words_to_transfer; i++) {
+ rzv2h_rspi_clear_all_irqs(rspi);
+
+ rzv2h_rspi_send(rspi, transfer->tx_buf, i);
+
+ ret = rzv2h_rspi_receive(rspi, transfer->rx_buf, i);
+ if (ret)
+ break;
+ }
+
+ rzv2h_rspi_clear_all_irqs(rspi);
+
+ if (ret)
+ transfer->error = SPI_TRANS_FAIL_IO;
+
+ spi_finalize_current_transfer(controller);
+
+ return ret;
+}
+
+static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
+ u8 brdv)
+{
+ return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv)));
+}
+
+static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
+{
+ unsigned long tclk_rate;
+ int spr;
+ u8 brdv;
+
+ /*
+ * From the manual:
+ * Bit rate = f(RSPI_n_TCLK)/(2*(n+1)*2^(N))
+ *
+ * Where:
+ * * RSPI_n_TCLK is fixed to 200MHz on V2H
+ * * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
+ * * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
+ */
+ tclk_rate = clk_get_rate(rspi->tclk);
+ for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
+ spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
+ spr--;
+ if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
+ goto clock_found;
+ }
+
+ return 0;
+
+clock_found:
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv);
+ writeb(spr, rspi->base + RSPI_SPBR);
+
+ return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
+}
+
+static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
+ struct spi_message *message)
+{
+ struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
+ const struct spi_device *spi = message->spi;
+ struct spi_transfer *xfer;
+ u32 speed_hz = U32_MAX;
+ u8 bits_per_word;
+ u32 conf32;
+ u16 conf16;
+
+ /* Make sure SPCR.SPE is 0 before amending the configuration */
+ rzv2h_rspi_spe_disable(rspi);
+
+ /* Configure the device to work in "host" mode */
+ conf32 = RSPI_SPCR_MSTR;
+
+ /* Auto-stop function */
+ conf32 |= RSPI_SPCR_SCKASE;
+
+ /* SPI receive buffer full interrupt enable */
+ conf32 |= RSPI_SPCR_SPRIE;
+
+ writel(conf32, rspi->base + RSPI_SPCR);
+
+ /* Use SPCMD0 only */
+ writeb(0x0, rspi->base + RSPI_SPSCR);
+
+ /* Setup mode */
+ conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_SSLKP, 1);
+ conf32 |= FIELD_PREP(RSPI_SPCMD_SSLA, spi_get_chipselect(spi, 0));
+ writel(conf32, rspi->base + RSPI_SPCMD);
+ if (spi->mode & SPI_CS_HIGH)
+ writeb(BIT(spi_get_chipselect(spi, 0)), rspi->base + RSPI_SSLP);
+ else
+ writeb(0, rspi->base + RSPI_SSLP);
+
+ /* Setup FIFO thresholds */
+ conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1);
+ conf16 |= FIELD_PREP(RSPI_SPDCR2_RTRG, 0);
+ writew(conf16, rspi->base + RSPI_SPDCR2);
+
+ rzv2h_rspi_clear_fifos(rspi);
+
+ list_for_each_entry(xfer, &message->transfers, transfer_list) {
+ if (!xfer->speed_hz)
+ continue;
+
+ speed_hz = min(xfer->speed_hz, speed_hz);
+ bits_per_word = xfer->bits_per_word;
+ }
+
+ if (speed_hz == U32_MAX)
+ return -EINVAL;
+
+ rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
+ rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word - 1);
+
+ rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
+ if (!rspi->freq)
+ return -EINVAL;
+
+ rzv2h_rspi_spe_enable(rspi);
+
+ return 0;
+}
+
+static int rzv2h_rspi_unprepare_message(struct spi_controller *ctlr,
+ struct spi_message *message)
+{
+ struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr);
+
+ rzv2h_rspi_spe_disable(rspi);
+
+ return 0;
+}
+
+static int rzv2h_rspi_probe(struct platform_device *pdev)
+{
+ struct spi_controller *controller;
+ struct device *dev = &pdev->dev;
+ struct rzv2h_rspi_priv *rspi;
+ struct clk_bulk_data *clks;
+ unsigned long tclk_rate;
+ int irq_rx, ret, i;
+
+ controller = devm_spi_alloc_host(dev, sizeof(*rspi));
+ if (!controller)
+ return -ENOMEM;
+
+ rspi = spi_controller_get_devdata(controller);
+ platform_set_drvdata(pdev, rspi);
+
+ rspi->controller = controller;
+
+ rspi->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rspi->base))
+ return PTR_ERR(rspi->base);
+
+ ret = devm_clk_bulk_get_all_enabled(dev, &clks);
+ if (ret != RSPI_CLK_NUM)
+ return dev_err_probe(dev, ret >= 0 ? -EINVAL : ret,
+ "cannot get clocks\n");
+ for (i = 0; i < RSPI_CLK_NUM; i++) {
+ if (!strcmp(clks[i].id, "tclk")) {
+ rspi->tclk = clks[i].clk;
+ break;
+ }
+ }
+
+ if (!rspi->tclk)
+ return dev_err_probe(dev, -EINVAL, "Failed to get tclk\n");
+
+ tclk_rate = clk_get_rate(rspi->tclk);
+
+ rspi->resets[0].id = "presetn";
+ rspi->resets[1].id = "tresetn";
+ ret = devm_reset_control_bulk_get_exclusive(dev, RSPI_RESET_NUM,
+ rspi->resets);
+ if (ret)
+ return dev_err_probe(dev, ret, "cannot get resets\n");
+
+ irq_rx = platform_get_irq_byname(pdev, "rx");
+ if (irq_rx < 0)
+ return dev_err_probe(dev, irq_rx, "cannot get IRQ 'rx'\n");
+
+ ret = reset_control_bulk_deassert(RSPI_RESET_NUM, rspi->resets);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to deassert resets\n");
+
+ init_waitqueue_head(&rspi->wait);
+
+ ret = devm_request_irq(dev, irq_rx, rzv2h_rx_irq_handler, 0,
+ dev_name(dev), rspi);
+ if (ret) {
+ dev_err(dev, "cannot request `rx` IRQ\n");
+ goto quit_resets;
+ }
+
+ controller->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
+ SPI_LSB_FIRST;
+ controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+ controller->prepare_message = rzv2h_rspi_prepare_message;
+ controller->unprepare_message = rzv2h_rspi_unprepare_message;
+ controller->num_chipselect = 4;
+ controller->transfer_one = rzv2h_rspi_transfer_one;
+ controller->min_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
+ RSPI_SPBR_SPR_MAX,
+ RSPI_SPCMD_BRDV_MAX);
+ controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
+ RSPI_SPBR_SPR_MIN,
+ RSPI_SPCMD_BRDV_MIN);
+
+ device_set_node(&controller->dev, dev_fwnode(dev));
+
+ ret = spi_register_controller(controller);
+ if (ret) {
+ dev_err(dev, "register controller failed\n");
+ goto quit_resets;
+ }
+
+ return 0;
+
+quit_resets:
+ reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets);
+
+ return ret;
+}
+
+static void rzv2h_rspi_remove(struct platform_device *pdev)
+{
+ struct rzv2h_rspi_priv *rspi = platform_get_drvdata(pdev);
+
+ spi_unregister_controller(rspi->controller);
+
+ reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets);
+}
+
+static const struct of_device_id rzv2h_rspi_match[] = {
+ { .compatible = "renesas,r9a09g057-rspi" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzv2h_rspi_match);
+
+static struct platform_driver rzv2h_rspi_drv = {
+ .probe = rzv2h_rspi_probe,
+ .remove = rzv2h_rspi_remove,
+ .driver = {
+ .name = "rzv2h_rspi",
+ .of_match_table = rzv2h_rspi_match,
+ },
+};
+module_platform_driver(rzv2h_rspi_drv);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/V2H(P) Serial Peripheral Interface Driver");
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 03/17] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 01/17] spi: dt-bindings: Document the RZ/V2H(P) RSPI Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 02/17] spi: Add driver for the RZ/V2H(P) RSPI IP Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 04/17] clk: renesas: r9a09g077: Add SPI module clocks Cosmin Tanislav
` (15 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
commit abd7c0293816a5fa5766710d2e7b576384fdec4d upstream.
Enable the Renesas RZ/V2H(P) RSPI driver for the benefit of
RZ/V2H(P) based platforms.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/20250624192304.338979-6-fabrizio.castro.jz@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index efa6efe31a9b..43ddc37d8015 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -566,6 +566,7 @@ CONFIG_SPI_ROCKCHIP=y
CONFIG_SPI_ROCKCHIP_SFC=m
CONFIG_SPI_RPCIF=m
CONFIG_SPI_RSPI=m
+CONFIG_SPI_RZV2H_RSPI=m
CONFIG_SPI_RZV2M_CSI=m
CONFIG_SPI_QCOM_QSPI=m
CONFIG_SPI_QUP=y
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 04/17] clk: renesas: r9a09g077: Add SPI module clocks
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (2 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 03/17] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 05/17] spi: rzv2h-rspi: make resets optional Cosmin Tanislav
` (14 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 5fb2f67341bd4b7c482f2bbda6b78244a51c3923 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have four SPI
peripherals, each with their own clock divider, which divides PLL4 by
either 24, 25, 30 or 32, similar to the SCI peripheral.
The dividers feed into the usual module clocks.
Add them all.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20251105104151.1489281-2-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
[cosmin.tanislav: resolve merge conflict]
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* describe changes made to apply on top of CIP
V2:
* remove internal Reviewed-by tags
drivers/clk/renesas/r9a09g077-cpg.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c
index af49565a544e..a1d420254ca6 100644
--- a/drivers/clk/renesas/r9a09g077-cpg.c
+++ b/drivers/clk/renesas/r9a09g077-cpg.c
@@ -46,12 +46,15 @@
#define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1)
#define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1)
#define DIVCA55S CONF_PACK(SCKCR2, 12, 1)
+#define DIVSPI3ASYNC CONF_PACK(SCKCR2, 16, 2)
+#define DIVSPI0ASYNC CONF_PACK(SCKCR3, 0, 2)
+#define DIVSPI1ASYNC CONF_PACK(SCKCR3, 2, 2)
+#define DIVSPI2ASYNC CONF_PACK(SCKCR3, 4, 2)
#define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 2)
#define SEL_PLL CONF_PACK(SCKCR, 22, 1)
-
enum rzt2h_clk_types {
CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */
CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */
@@ -84,6 +87,10 @@ enum clk_ids {
CLK_SEL_CLK_PLL4,
CLK_PLL4D1,
CLK_SCI0ASYNC,
+ CLK_SPI0ASYNC,
+ CLK_SPI1ASYNC,
+ CLK_SPI2ASYNC,
+ CLK_SPI3ASYNC,
/* Module Clocks */
MOD_CLK_BASE,
@@ -134,6 +141,15 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC,
dtable_24_25_30_32),
+ DEF_DIV(".spi0async", CLK_SPI0ASYNC, CLK_PLL4D1, DIVSPI0ASYNC,
+ dtable_24_25_30_32),
+ DEF_DIV(".spi1async", CLK_SPI1ASYNC, CLK_PLL4D1, DIVSPI1ASYNC,
+ dtable_24_25_30_32),
+ DEF_DIV(".spi2async", CLK_SPI2ASYNC, CLK_PLL4D1, DIVSPI2ASYNC,
+ dtable_24_25_30_32),
+ DEF_DIV(".spi3async", CLK_SPI3ASYNC, CLK_PLL4D1, DIVSPI3ASYNC,
+ dtable_24_25_30_32),
+
/* Core output clk */
DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0,
dtable_1_2),
@@ -156,10 +172,14 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
DEF_MOD("sci0fck", 8, CLK_SCI0ASYNC),
DEF_MOD("iic0", 100, R9A09G077_CLK_PCLKL),
DEF_MOD("iic1", 101, R9A09G077_CLK_PCLKL),
+ DEF_MOD("spi0", 104, CLK_SPI0ASYNC),
+ DEF_MOD("spi1", 105, CLK_SPI1ASYNC),
+ DEF_MOD("spi2", 106, CLK_SPI2ASYNC),
DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH),
DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH),
DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM),
DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL),
+ DEF_MOD("spi3", 602, CLK_SPI3ASYNC),
DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM),
DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM),
};
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 05/17] spi: rzv2h-rspi: make resets optional
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (3 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 04/17] clk: renesas: r9a09g077: Add SPI module clocks Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 06/17] spi: rzv2h-rspi: make FIFO size chip-specific Cosmin Tanislav
` (13 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit aead5ae91e4cbadac817d15737eca3b531237448 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs don't have
reset lines for the SPI peripheral, make them optional to prepare for
adding support for them.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-2-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index dcc431ba60a9..09b9362e9b1f 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -384,8 +384,8 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
rspi->resets[0].id = "presetn";
rspi->resets[1].id = "tresetn";
- ret = devm_reset_control_bulk_get_exclusive(dev, RSPI_RESET_NUM,
- rspi->resets);
+ ret = devm_reset_control_bulk_get_optional_exclusive(dev, RSPI_RESET_NUM,
+ rspi->resets);
if (ret)
return dev_err_probe(dev, ret, "cannot get resets\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 06/17] spi: rzv2h-rspi: make FIFO size chip-specific
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (4 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 05/17] spi: rzv2h-rspi: make resets optional Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 07/17] spi: rzv2h-rspi: make clocks chip-specific Cosmin Tanislav
` (12 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 8e89ee6cd2b928a8431bef61e8b851ce5df1ecb0 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a
different FIFO size compared to RZ/V2H. Add a chip-specific structure,
and set the FIFO size inside it, to prepare for adding support for them.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-3-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index 09b9362e9b1f..7a7a576c17dd 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -58,7 +58,6 @@
/* Register SPDCR2 */
#define RSPI_SPDCR2_TTRG GENMASK(11, 8)
#define RSPI_SPDCR2_RTRG GENMASK(3, 0)
-#define RSPI_FIFO_SIZE 16
/* Register SPSR */
#define RSPI_SPSR_SPRF BIT(15)
@@ -69,9 +68,14 @@
#define RSPI_RESET_NUM 2
#define RSPI_CLK_NUM 3
+struct rzv2h_rspi_info {
+ unsigned int fifo_size;
+};
+
struct rzv2h_rspi_priv {
struct reset_control_bulk_data resets[RSPI_RESET_NUM];
struct spi_controller *controller;
+ const struct rzv2h_rspi_info *info;
void __iomem *base;
struct clk *tclk;
wait_queue_head_t wait;
@@ -305,7 +309,7 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
writeb(0, rspi->base + RSPI_SSLP);
/* Setup FIFO thresholds */
- conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1);
+ conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, rspi->info->fifo_size - 1);
conf16 |= FIELD_PREP(RSPI_SPDCR2_RTRG, 0);
writew(conf16, rspi->base + RSPI_SPDCR2);
@@ -362,6 +366,8 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
rspi->controller = controller;
+ rspi->info = device_get_match_data(dev);
+
rspi->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rspi->base))
return PTR_ERR(rspi->base);
@@ -445,8 +451,12 @@ static void rzv2h_rspi_remove(struct platform_device *pdev)
reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets);
}
+static const struct rzv2h_rspi_info rzv2h_info = {
+ .fifo_size = 16,
+};
+
static const struct of_device_id rzv2h_rspi_match[] = {
- { .compatible = "renesas,r9a09g057-rspi" },
+ { .compatible = "renesas,r9a09g057-rspi", &rzv2h_info },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzv2h_rspi_match);
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 07/17] spi: rzv2h-rspi: make clocks chip-specific
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (5 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 06/17] spi: rzv2h-rspi: make FIFO size chip-specific Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 08/17] spi: rzv2h-rspi: move register writes out of rzv2h_rspi_setup_clock() Cosmin Tanislav
` (11 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit ebd7d6ae0dc7d65e21460c928519f40ccf95f3b9 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have
different clocks compared to RZ/V2H. Set the number of clocks and the
name of the transfer clock in the chip-specific structure to prepare for
adding support for them.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-4-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index 7a7a576c17dd..a1f17ec8727b 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -66,10 +66,11 @@
#define RSPI_SPSRC_CLEAR 0xfd80
#define RSPI_RESET_NUM 2
-#define RSPI_CLK_NUM 3
struct rzv2h_rspi_info {
+ const char *tclk_name;
unsigned int fifo_size;
+ unsigned int num_clks;
};
struct rzv2h_rspi_priv {
@@ -373,11 +374,11 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
return PTR_ERR(rspi->base);
ret = devm_clk_bulk_get_all_enabled(dev, &clks);
- if (ret != RSPI_CLK_NUM)
+ if (ret != rspi->info->num_clks)
return dev_err_probe(dev, ret >= 0 ? -EINVAL : ret,
"cannot get clocks\n");
- for (i = 0; i < RSPI_CLK_NUM; i++) {
- if (!strcmp(clks[i].id, "tclk")) {
+ for (i = 0; i < rspi->info->num_clks; i++) {
+ if (!strcmp(clks[i].id, rspi->info->tclk_name)) {
rspi->tclk = clks[i].clk;
break;
}
@@ -452,7 +453,9 @@ static void rzv2h_rspi_remove(struct platform_device *pdev)
}
static const struct rzv2h_rspi_info rzv2h_info = {
+ .tclk_name = "tclk",
.fifo_size = 16,
+ .num_clks = 3,
};
static const struct of_device_id rzv2h_rspi_match[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 08/17] spi: rzv2h-rspi: move register writes out of rzv2h_rspi_setup_clock()
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (6 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 07/17] spi: rzv2h-rspi: make clocks chip-specific Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 09/17] spi: rzv2h-rspi: avoid recomputing transfer frequency Cosmin Tanislav
` (10 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 1b7ce968ab2579702ea9dbc2fb599e540bbd8c88 upstream.
In preparation for caching the last requested transfer frequency, move
register writes outside of rzv2h_rspi_setup_clock().
The transfer list is iterated to determine the speed of the transfer
and the bits per word.
The speed of the transfer is used to compute SPR and BRDV inside
rzv2h_rspi_setup_clock().
BRDV and SPB are stored in the SPCMD register.
Move the transfer iteration earlier, move the SPR and BRDV writing out
of rzv2h_rspi_setup_clock(), consolidate writing BRDV and SPB into the
initial write to the SPCMD register.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-5-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 45 ++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index a1f17ec8727b..f02f25b98ec6 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -83,6 +83,8 @@ struct rzv2h_rspi_priv {
unsigned int bytes_per_word;
u32 freq;
u16 status;
+ u8 spr;
+ u8 brdv;
};
#define RZV2H_RSPI_TX(func, type) \
@@ -263,8 +265,8 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
return 0;
clock_found:
- rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv);
- writeb(spr, rspi->base + RSPI_SPBR);
+ rspi->spr = spr;
+ rspi->brdv = brdv;
return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
}
@@ -283,6 +285,25 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
/* Make sure SPCR.SPE is 0 before amending the configuration */
rzv2h_rspi_spe_disable(rspi);
+ list_for_each_entry(xfer, &message->transfers, transfer_list) {
+ if (!xfer->speed_hz)
+ continue;
+
+ speed_hz = min(xfer->speed_hz, speed_hz);
+ bits_per_word = xfer->bits_per_word;
+ }
+
+ if (speed_hz == U32_MAX)
+ return -EINVAL;
+
+ rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
+
+ rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
+ if (!rspi->freq)
+ return -EINVAL;
+
+ writeb(rspi->spr, rspi->base + RSPI_SPBR);
+
/* Configure the device to work in "host" mode */
conf32 = RSPI_SPCR_MSTR;
@@ -301,6 +322,8 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST));
+ conf32 |= FIELD_PREP(RSPI_SPCMD_SPB, bits_per_word - 1);
+ conf32 |= FIELD_PREP(RSPI_SPCMD_BRDV, rspi->brdv);
conf32 |= FIELD_PREP(RSPI_SPCMD_SSLKP, 1);
conf32 |= FIELD_PREP(RSPI_SPCMD_SSLA, spi_get_chipselect(spi, 0));
writel(conf32, rspi->base + RSPI_SPCMD);
@@ -316,24 +339,6 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
rzv2h_rspi_clear_fifos(rspi);
- list_for_each_entry(xfer, &message->transfers, transfer_list) {
- if (!xfer->speed_hz)
- continue;
-
- speed_hz = min(xfer->speed_hz, speed_hz);
- bits_per_word = xfer->bits_per_word;
- }
-
- if (speed_hz == U32_MAX)
- return -EINVAL;
-
- rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
- rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word - 1);
-
- rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
- if (!rspi->freq)
- return -EINVAL;
-
rzv2h_rspi_spe_enable(rspi);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 09/17] spi: rzv2h-rspi: avoid recomputing transfer frequency
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (7 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 08/17] spi: rzv2h-rspi: move register writes out of rzv2h_rspi_setup_clock() Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 10/17] spi: rzv2h-rspi: make transfer clock rate finding chip-specific Cosmin Tanislav
` (9 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 88782493204512fcf4e020e2385bca3e3c5bd4c0 upstream.
Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a more
complicated algorithm for calculating the optimal SPI transfer frequency
compared to RZ/V2H, as the clock from which the SPI frequency is
generated supports multiple dividers.
Cache the requested transfer frequency and skip calling
rzv2h_rspi_setup_clock() if it matches the last used one to prepare for
adding support for variable clock frequency handling.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-6-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index f02f25b98ec6..d7719f3c7b13 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -81,6 +81,7 @@ struct rzv2h_rspi_priv {
struct clk *tclk;
wait_queue_head_t wait;
unsigned int bytes_per_word;
+ u32 last_speed_hz;
u32 freq;
u16 status;
u8 spr;
@@ -298,9 +299,13 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word));
- rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
- if (!rspi->freq)
- return -EINVAL;
+ if (speed_hz != rspi->last_speed_hz) {
+ rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz);
+ if (!rspi->freq)
+ return -EINVAL;
+
+ rspi->last_speed_hz = speed_hz;
+ }
writeb(rspi->spr, rspi->base + RSPI_SPBR);
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 10/17] spi: rzv2h-rspi: make transfer clock rate finding chip-specific
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (8 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 09/17] spi: rzv2h-rspi: avoid recomputing transfer frequency Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-13 10:25 ` Pavel Machek
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock Cosmin Tanislav
` (8 subsequent siblings)
18 siblings, 1 reply; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 77d931584dd38916b66c65320c80a65cbef4b122 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a more
complicated clocking setup for the SPI transfer clock than RZ/V2H, as
the clock from which it is generated supports multiple dividers.
To prepare for adding support for these SoCs, split out the logic for
finding the SPR and BRDV for a fixed clock into
rzv2h_rspi_find_rate_fixed(), and add and use a .find_tclk_rate()
callback into the chip-specific structure.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-7-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 62 ++++++++++++++++++++++++++++++------
1 file changed, 53 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index d7719f3c7b13..f59bcadf5e38 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -67,7 +67,18 @@
#define RSPI_RESET_NUM 2
+struct rzv2h_rspi_best_clock {
+ struct clk *clk;
+ unsigned long clk_rate;
+ unsigned long error;
+ u32 actual_hz;
+ u8 brdv;
+ u8 spr;
+};
+
struct rzv2h_rspi_info {
+ void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
+ struct rzv2h_rspi_best_clock *best_clk);
const char *tclk_name;
unsigned int fifo_size;
unsigned int num_clks;
@@ -240,9 +251,13 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv)));
}
-static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
+static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
+ u8 spr_min, u8 spr_max,
+ struct rzv2h_rspi_best_clock *best)
{
- unsigned long tclk_rate;
+ unsigned long clk_rate;
+ unsigned long error;
+ u32 actual_hz;
int spr;
u8 brdv;
@@ -255,21 +270,49 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
* * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
* * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
*/
- tclk_rate = clk_get_rate(rspi->tclk);
+ clk_rate = clk_get_rate(clk);
for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
- spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
+ spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1)));
spr--;
- if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
+ if (spr >= spr_min && spr <= spr_max)
goto clock_found;
}
- return 0;
+ return;
clock_found:
- rspi->spr = spr;
- rspi->brdv = brdv;
+ actual_hz = rzv2h_rspi_calc_bitrate(clk_rate, spr, brdv);
+ error = abs((long)hz - (long)actual_hz);
- return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
+ if (error >= best->error)
+ return;
+
+ *best = (struct rzv2h_rspi_best_clock) {
+ .clk = clk,
+ .clk_rate = clk_rate,
+ .error = error,
+ .actual_hz = actual_hz,
+ .brdv = brdv,
+ .spr = spr,
+ };
+}
+
+static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
+{
+ struct rzv2h_rspi_best_clock best_clock = {
+ .error = ULONG_MAX,
+ };
+
+ rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
+ RSPI_SPBR_SPR_MAX, &best_clock);
+
+ if (!best_clock.clk_rate)
+ return -EINVAL;
+
+ rspi->spr = best_clock.spr;
+ rspi->brdv = best_clock.brdv;
+
+ return best_clock.actual_hz;
}
static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
@@ -463,6 +506,7 @@ static void rzv2h_rspi_remove(struct platform_device *pdev)
}
static const struct rzv2h_rspi_info rzv2h_info = {
+ .find_tclk_rate = rzv2h_rspi_find_rate_fixed,
.tclk_name = "tclk",
.fifo_size = 16,
.num_clks = 3,
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (9 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 10/17] spi: rzv2h-rspi: make transfer clock rate finding chip-specific Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-12 3:22 ` nobuhiro.iwamatsu.x90
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 12/17] spi: rzv2h-rspi: add support for variable " Cosmin Tanislav
` (7 subsequent siblings)
18 siblings, 1 reply; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 1ce3e8adc7d0038e59a7c9f5c9e5f399ba0db5d6 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs support
generating the SPI transfer clock from PCLK, with the quirk that SPR 0
is not supported, causing the highest achievable SPI transfer frequency
to be 31.25MHz.
Add support for generating the SPI transfer clock from PCLK.
Renesas RZ/V2H (R9A09G057) also has the BPEN bit used to enable this
option in the datasheet, but it is not explicitly documented and there's
no details about its limitations as there are on RZ/T2H.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-8-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index f59bcadf5e38..e9d8ee919261 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -34,6 +34,7 @@
#define RSPI_SPFCR 0x6c
/* Register SPCR */
+#define RSPI_SPCR_BPEN BIT(31)
#define RSPI_SPCR_MSTR BIT(30)
#define RSPI_SPCR_SPRIE BIT(17)
#define RSPI_SPCR_SCKASE BIT(12)
@@ -41,6 +42,7 @@
/* Register SPBR */
#define RSPI_SPBR_SPR_MIN 0
+#define RSPI_SPBR_SPR_PCLK_MIN 1
#define RSPI_SPBR_SPR_MAX 255
/* Register SPCMD */
@@ -79,6 +81,8 @@ struct rzv2h_rspi_best_clock {
struct rzv2h_rspi_info {
void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
struct rzv2h_rspi_best_clock *best_clk);
+ void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high,
+ struct rzv2h_rspi_best_clock *best_clk);
const char *tclk_name;
unsigned int fifo_size;
unsigned int num_clks;
@@ -90,6 +94,7 @@ struct rzv2h_rspi_priv {
const struct rzv2h_rspi_info *info;
void __iomem *base;
struct clk *tclk;
+ struct clk *pclk;
wait_queue_head_t wait;
unsigned int bytes_per_word;
u32 last_speed_hz;
@@ -97,6 +102,7 @@ struct rzv2h_rspi_priv {
u16 status;
u8 spr;
u8 brdv;
+ bool use_pclk;
};
#define RZV2H_RSPI_TX(func, type) \
@@ -306,9 +312,18 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
RSPI_SPBR_SPR_MAX, &best_clock);
+ /*
+ * T2H and N2H can also use PCLK as a source, which is 125MHz, but not
+ * when both SPR and BRDV are 0.
+ */
+ if (best_clock.error && rspi->info->find_pclk_rate)
+ rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN,
+ RSPI_SPBR_SPR_MAX, &best_clock);
+
if (!best_clock.clk_rate)
return -EINVAL;
+ rspi->use_pclk = best_clock.clk == rspi->pclk;
rspi->spr = best_clock.spr;
rspi->brdv = best_clock.brdv;
@@ -361,6 +376,9 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
/* SPI receive buffer full interrupt enable */
conf32 |= RSPI_SPCR_SPRIE;
+ /* Bypass synchronization circuit */
+ conf32 |= FIELD_PREP(RSPI_SPCR_BPEN, rspi->use_pclk);
+
writel(conf32, rspi->base + RSPI_SPCR);
/* Use SPCMD0 only */
@@ -433,7 +451,9 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
for (i = 0; i < rspi->info->num_clks; i++) {
if (!strcmp(clks[i].id, rspi->info->tclk_name)) {
rspi->tclk = clks[i].clk;
- break;
+ } else if (rspi->info->find_pclk_rate &&
+ !strcmp(clks[i].id, "pclk")) {
+ rspi->pclk = clks[i].clk;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 12/17] spi: rzv2h-rspi: add support for variable transfer clock
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (10 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 13/17] spi: rzv2h-rspi: add support for loopback mode Cosmin Tanislav
` (6 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 9c9bf4fdc5e5d09d5f4280ed2c582df6e1f837d9 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a more
complicated clocking setup for the SPI transfer clock than RZ/V2H, as
the clock from which it is generated supports multiple dividers.
To prepare for adding support for these SoCs, do the following changes.
Use the minimum frequency of SPI clock to calculate the SPI
controller's min_speed_hz, and the maximum frequency to calculate
max_speed_hz.
Apply the clock rate found by the .find_tclk_rate() to the found clock.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-9-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index e9d8ee919261..be45269e8853 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -308,6 +308,7 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
struct rzv2h_rspi_best_clock best_clock = {
.error = ULONG_MAX,
};
+ int ret;
rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
RSPI_SPBR_SPR_MAX, &best_clock);
@@ -323,6 +324,10 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
if (!best_clock.clk_rate)
return -EINVAL;
+ ret = clk_set_rate(best_clock.clk, best_clock.clk_rate);
+ if (ret)
+ return 0;
+
rspi->use_pclk = best_clock.clk == rspi->pclk;
rspi->spr = best_clock.spr;
rspi->brdv = best_clock.brdv;
@@ -426,8 +431,8 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct rzv2h_rspi_priv *rspi;
struct clk_bulk_data *clks;
- unsigned long tclk_rate;
int irq_rx, ret, i;
+ long tclk_rate;
controller = devm_spi_alloc_host(dev, sizeof(*rspi));
if (!controller)
@@ -460,8 +465,6 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
if (!rspi->tclk)
return dev_err_probe(dev, -EINVAL, "Failed to get tclk\n");
- tclk_rate = clk_get_rate(rspi->tclk);
-
rspi->resets[0].id = "presetn";
rspi->resets[1].id = "tresetn";
ret = devm_reset_control_bulk_get_optional_exclusive(dev, RSPI_RESET_NUM,
@@ -493,9 +496,23 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
controller->unprepare_message = rzv2h_rspi_unprepare_message;
controller->num_chipselect = 4;
controller->transfer_one = rzv2h_rspi_transfer_one;
+
+ tclk_rate = clk_round_rate(rspi->tclk, 0);
+ if (tclk_rate < 0) {
+ ret = tclk_rate;
+ goto quit_resets;
+ }
+
controller->min_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
RSPI_SPBR_SPR_MAX,
RSPI_SPCMD_BRDV_MAX);
+
+ tclk_rate = clk_round_rate(rspi->tclk, ULONG_MAX);
+ if (tclk_rate < 0) {
+ ret = tclk_rate;
+ goto quit_resets;
+ }
+
controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
RSPI_SPBR_SPR_MIN,
RSPI_SPCMD_BRDV_MIN);
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 13/17] spi: rzv2h-rspi: add support for loopback mode
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (11 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 12/17] spi: rzv2h-rspi: add support for variable " Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 14/17] spi: rzv2h-rspi: add support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (5 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit bc4f0b1e39035b9bb3d5d9692074702110f5e2b1 uptream.
Add support for loopback mode for debugging purposes, allowing us to
test the SPI controller at the maximum SPI transfer clock without being
limited by external wiring.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-10-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index be45269e8853..da110efba971 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -24,6 +24,7 @@
/* Registers */
#define RSPI_SPDR 0x00
#define RSPI_SPCR 0x08
+#define RSPI_SPPCR 0x0e
#define RSPI_SSLP 0x10
#define RSPI_SPBR 0x11
#define RSPI_SPSCR 0x13
@@ -40,6 +41,9 @@
#define RSPI_SPCR_SCKASE BIT(12)
#define RSPI_SPCR_SPE BIT(0)
+/* Register SPPCR */
+#define RSPI_SPPCR_SPLP2 BIT(1)
+
/* Register SPBR */
#define RSPI_SPBR_SPR_MIN 0
#define RSPI_SPBR_SPR_PCLK_MIN 1
@@ -345,6 +349,7 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
u8 bits_per_word;
u32 conf32;
u16 conf16;
+ u8 conf8;
/* Make sure SPCR.SPE is 0 before amending the configuration */
rzv2h_rspi_spe_disable(rspi);
@@ -389,6 +394,10 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
/* Use SPCMD0 only */
writeb(0x0, rspi->base + RSPI_SPSCR);
+ /* Setup loopback */
+ conf8 = FIELD_PREP(RSPI_SPPCR_SPLP2, !!(spi->mode & SPI_LOOP));
+ writeb(conf8, rspi->base + RSPI_SPPCR);
+
/* Setup mode */
conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL));
conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA));
@@ -490,7 +499,7 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
}
controller->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
- SPI_LSB_FIRST;
+ SPI_LSB_FIRST | SPI_LOOP;
controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
controller->prepare_message = rzv2h_rspi_prepare_message;
controller->unprepare_message = rzv2h_rspi_unprepare_message;
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 14/17] spi: rzv2h-rspi: add support for RZ/T2H and RZ/N2H
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (12 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 13/17] spi: rzv2h-rspi: add support for loopback mode Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 15/17] spi: dt-bindings: renesas,rzv2h-rspi: document " Cosmin Tanislav
` (4 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 0cc8cd824b9fb7fb087a2ec6b0c80d812cc4fde7 upstream.
Compared to the previously supported RZ/V2H, the Renesas RZ/T2H
(R9A09G077) and RZ/N2H (R9A09G087) SoCs have a smaller FIFO, no resets,
and only two clocks: PCLKSPIn and PCLK. PCLKSPIn, being the clock from
which the SPI transfer clock is generated, is the equivalent of the TCLK
clock from RZ/V2H. They also support generating the SPI transfer clock
from PCLK.
PCLKSPIn supports multiple dividers, generating multiple possible
frequencies from its parent. To handle this, do the following changes.
Use the minimum frequency of SPI clock to calculate the SPI controller's
min_speed_hz, and the maximum frequency to calculate max_speed_hz.
Add a new function, rzv2h_rspi_find_rate_variable(), which is used for
the .find_tclk_rate() callback, and which supports handling clocks with
a variable rate, with the following overall logic.
Iterate through all possible BRDV values.
For each BRDV, calculate two different SPRs, one for the clock's minimum
frequency, and one for the maxmimum, and iterate through each SPR
between them.
If the minimum SPR is higher than the upper SPR limit, the minimum rate
is too high to achieve the requested SPI frequency, skip to the next
BRDV.
For each SPR, calculate a rate and let the clock framework round it to
the closest supported rate of the clock.
The rate and SPR that generate a transfer frequency closest to the
requested SPI transfer frequency will be picked.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Link: https://patch.msgid.link/20251119161434.595677-12-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
drivers/spi/spi-rzv2h-rspi.c | 108 +++++++++++++++++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index da110efba971..1db7e4e5d64e 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -261,6 +261,105 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv)));
}
+static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
+ u8 spr_min, u8 spr_max,
+ struct rzv2h_rspi_best_clock *best)
+{
+ long clk_rate, clk_min_rate, clk_max_rate;
+ int min_rate_spr, max_rate_spr;
+ unsigned long error;
+ u32 actual_hz;
+ u8 brdv;
+ int spr;
+
+ /*
+ * On T2H / N2H, the source for the SPI clock is PCLKSPIn, which is a
+ * 1/32, 1/30, 1/25 or 1/24 divider of PLL4, which is 2400MHz,
+ * resulting in either 75MHz, 80MHz, 96MHz or 100MHz.
+ */
+ clk_min_rate = clk_round_rate(clk, 0);
+ if (clk_min_rate < 0)
+ return;
+
+ clk_max_rate = clk_round_rate(clk, ULONG_MAX);
+ if (clk_max_rate < 0)
+ return;
+
+ /*
+ * From the manual:
+ * Bit rate = f(PCLKSPIn) / (2 * (n + 1) * 2^N)
+ *
+ * If we adapt it to the current context, we get the following:
+ * hz = rate / ((spr + 1) * (1 << (brdv + 1)))
+ *
+ * This can be written in multiple forms depending on what we want to
+ * determine.
+ *
+ * To find the rate, having hz, spr and brdv:
+ * rate = hz * (spr + 1) * (1 << (brdv + 1)
+ *
+ * To find the spr, having rate, hz, and spr:
+ * spr = rate / (hz * (1 << (brdv + 1)) - 1
+ */
+
+ for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
+ /* Calculate the divisor needed to find the SPR from a rate. */
+ u32 rate_div = hz * (1 << (brdv + 1));
+
+ /*
+ * If the SPR for the minimum rate is greater than the maximum
+ * allowed value skip this BRDV. The divisor increases with each
+ * BRDV iteration, so the following BRDV might result in a
+ * minimum SPR that is in the valid range.
+ */
+ min_rate_spr = DIV_ROUND_CLOSEST(clk_min_rate, rate_div) - 1;
+ if (min_rate_spr > spr_max)
+ continue;
+
+ /*
+ * If the SPR for the maximum rate is less than the minimum
+ * allowed value, exit. The divisor only increases with each
+ * BRDV iteration, so the following BRDV cannot result in a
+ * maximum SPR that is in the valid range.
+ */
+ max_rate_spr = DIV_ROUND_CLOSEST(clk_max_rate, rate_div) - 1;
+ if (max_rate_spr < spr_min)
+ break;
+
+ if (min_rate_spr < spr_min)
+ min_rate_spr = spr_min;
+
+ if (max_rate_spr > spr_max)
+ max_rate_spr = spr_max;
+
+ for (spr = min_rate_spr; spr <= max_rate_spr; spr++) {
+ clk_rate = (spr + 1) * rate_div;
+
+ clk_rate = clk_round_rate(clk, clk_rate);
+ if (clk_rate <= 0)
+ continue;
+
+ actual_hz = rzv2h_rspi_calc_bitrate(clk_rate, spr, brdv);
+ error = abs((long)hz - (long)actual_hz);
+
+ if (error >= best->error)
+ continue;
+
+ *best = (struct rzv2h_rspi_best_clock) {
+ .clk = clk,
+ .clk_rate = clk_rate,
+ .error = error,
+ .actual_hz = actual_hz,
+ .brdv = brdv,
+ .spr = spr,
+ };
+
+ if (!error)
+ return;
+ }
+ }
+}
+
static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
u8 spr_min, u8 spr_max,
struct rzv2h_rspi_best_clock *best)
@@ -558,8 +657,17 @@ static const struct rzv2h_rspi_info rzv2h_info = {
.num_clks = 3,
};
+static const struct rzv2h_rspi_info rzt2h_info = {
+ .find_tclk_rate = rzv2h_rspi_find_rate_variable,
+ .find_pclk_rate = rzv2h_rspi_find_rate_fixed,
+ .tclk_name = "pclkspi",
+ .fifo_size = 4,
+ .num_clks = 2,
+};
+
static const struct of_device_id rzv2h_rspi_match[] = {
{ .compatible = "renesas,r9a09g057-rspi", &rzv2h_info },
+ { .compatible = "renesas,r9a09g077-rspi", &rzt2h_info },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzv2h_rspi_match);
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 15/17] spi: dt-bindings: renesas,rzv2h-rspi: document RZ/T2H and RZ/N2H
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (13 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 14/17] spi: rzv2h-rspi: add support for RZ/T2H and RZ/N2H Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 16/17] arm64: dts: renesas: r9a09g077: Add SPI nodes Cosmin Tanislav
` (3 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit e93d7b2d8b349f659fa9456048ee86e10eb422f9 upstream.
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have four SPI
peripherals.
Compared to the previously supported RZ/V2H, these SoCs have a smaller
FIFO, no resets, and only two clocks: PCLKSPIn and PCLK. PCLKSPIn,
being the clock from which the SPI transfer clock is generated, is the
equivalent of the TCLK from V2H.
Document them, and use RZ/T2H as a fallback for RZ/N2H as the SPIs are
entirely compatible.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://patch.msgid.link/20251119161434.595677-11-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* no changes
V2:
* remove internal Reviewed-by tags
.../bindings/spi/renesas,rzv2h-rspi.yaml | 62 ++++++++++++++++---
1 file changed, 52 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
index ab27fefc3c3a..4331df3e3d47 100644
--- a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
+++ b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
@@ -9,12 +9,15 @@ title: Renesas RZ/V2H(P) Renesas Serial Peripheral Interface (RSPI)
maintainers:
- Fabrizio Castro <fabrizio.castro.jz@renesas.com>
-allOf:
- - $ref: spi-controller.yaml#
-
properties:
compatible:
- const: renesas,r9a09g057-rspi # RZ/V2H(P)
+ oneOf:
+ - enum:
+ - renesas,r9a09g057-rspi # RZ/V2H(P)
+ - renesas,r9a09g077-rspi # RZ/T2H
+ - items:
+ - const: renesas,r9a09g087-rspi # RZ/N2H
+ - const: renesas,r9a09g077-rspi # RZ/T2H
reg:
maxItems: 1
@@ -36,13 +39,12 @@ properties:
- const: tx
clocks:
+ minItems: 2
maxItems: 3
clock-names:
- items:
- - const: pclk
- - const: pclk_sfr
- - const: tclk
+ minItems: 2
+ maxItems: 3
resets:
maxItems: 2
@@ -62,12 +64,52 @@ required:
- interrupt-names
- clocks
- clock-names
- - resets
- - reset-names
- power-domains
- '#address-cells'
- '#size-cells'
+allOf:
+ - $ref: spi-controller.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - renesas,r9a09g057-rspi
+ then:
+ properties:
+ clocks:
+ minItems: 3
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: pclk_sfr
+ - const: tclk
+
+ required:
+ - resets
+ - reset-names
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - renesas,r9a09g077-rspi
+ then:
+ properties:
+ clocks:
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: pclkspi
+
+ resets: false
+ reset-names: false
+
unevaluatedProperties: false
examples:
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 16/17] arm64: dts: renesas: r9a09g077: Add SPI nodes
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (14 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 15/17] spi: dt-bindings: renesas,rzv2h-rspi: document " Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 17/17] arm64: dts: renesas: r9a09g087: " Cosmin Tanislav
` (2 subsequent siblings)
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit fb8f11c7975ad6096437e6a6757c98c9c9475551 upstream.
Add support for the four SPI controllers on the Renesas RZ/T2H Soc.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20251119161434.595677-13-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
[cosmin.tanislav: resolve merge conflict]
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* describe changes made to apply on top of CIP
V2:
* remove internal Reviewed-by tags
arch/arm64/boot/dts/renesas/r9a09g077.dtsi | 72 ++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
index 342e1470928a..78436a486ffe 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
@@ -90,6 +90,78 @@ sci0: serial@80005000 {
status = "disabled";
};
+ rspi0: spi@80007000 {
+ compatible = "renesas,r9a09g077-rspi";
+ reg = <0x0 0x80007000 0x0 0x400>;
+ interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 638 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 634 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 635 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKM>,
+ <&cpg CPG_MOD 104>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi1: spi@80007400 {
+ compatible = "renesas,r9a09g077-rspi";
+ reg = <0x0 0x80007400 0x0 0x400>;
+ interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 643 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 639 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKM>,
+ <&cpg CPG_MOD 105>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi2: spi@80007800 {
+ compatible = "renesas,r9a09g077-rspi";
+ reg = <0x0 0x80007800 0x0 0x400>;
+ interrupts = <GIC_SPI 646 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 647 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 648 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 644 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 645 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKM>,
+ <&cpg CPG_MOD 106>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi3: spi@81007000 {
+ compatible = "renesas,r9a09g077-rspi";
+ reg = <0x0 0x81007000 0x0 0x400>;
+ interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 653 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 649 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 650 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKM>,
+ <&cpg CPG_MOD 602>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
wdt0: watchdog@80082000 {
compatible = "renesas,r9a09g077-wdt";
reg = <0 0x80082000 0 0x400>,
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6.12.y-cip v3 17/17] arm64: dts: renesas: r9a09g087: Add SPI nodes
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (15 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 16/17] arm64: dts: renesas: r9a09g077: Add SPI nodes Cosmin Tanislav
@ 2026-03-09 15:06 ` Cosmin Tanislav
2026-03-12 3:28 ` [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H nobuhiro.iwamatsu.x90
2026-03-13 10:31 ` [cip-dev] " Pavel Machek
18 siblings, 0 replies; 25+ messages in thread
From: Cosmin Tanislav @ 2026-03-09 15:06 UTC (permalink / raw)
To: cip-dev, pavel, nobuhiro.iwamatsu.x90
commit 3c77f58d108c80c464a0676aeaa3dbf791883f19 upstream.
Add support for the four SPI controllers on the Renesas RZ/N2H Soc.
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20251119161434.595677-14-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
[cosmin.tanislav: resolve merge conflict]
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---
V3:
* describe changes made to apply on top of CIP
V2:
* remove internal Reviewed-by tags
arch/arm64/boot/dts/renesas/r9a09g087.dtsi | 72 ++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi
index 9e2ad080215a..c056c476e0d7 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi
@@ -90,6 +90,78 @@ sci0: serial@80005000 {
status = "disabled";
};
+ rspi0: spi@80007000 {
+ compatible = "renesas,r9a09g087-rspi", "renesas,r9a09g077-rspi";
+ reg = <0x0 0x80007000 0x0 0x400>;
+ interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 638 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 634 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 635 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKM>,
+ <&cpg CPG_MOD 104>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi1: spi@80007400 {
+ compatible = "renesas,r9a09g087-rspi", "renesas,r9a09g077-rspi";
+ reg = <0x0 0x80007400 0x0 0x400>;
+ interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 643 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 639 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKM>,
+ <&cpg CPG_MOD 105>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi2: spi@80007800 {
+ compatible = "renesas,r9a09g087-rspi", "renesas,r9a09g077-rspi";
+ reg = <0x0 0x80007800 0x0 0x400>;
+ interrupts = <GIC_SPI 646 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 647 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 648 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 644 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 645 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKM>,
+ <&cpg CPG_MOD 106>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rspi3: spi@81007000 {
+ compatible = "renesas,r9a09g087-rspi", "renesas,r9a09g077-rspi";
+ reg = <0x0 0x81007000 0x0 0x400>;
+ interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 653 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 649 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 650 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "idle", "error", "end", "rx", "tx";
+ clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKM>,
+ <&cpg CPG_MOD 602>;
+ clock-names = "pclk", "pclkspi";
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
wdt0: watchdog@80082000 {
compatible = "renesas,r9a09g087-wdt", "renesas,r9a09g077-wdt";
reg = <0 0x80082000 0 0x400>,
--
2.53.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* RE: [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock Cosmin Tanislav
@ 2026-03-12 3:22 ` nobuhiro.iwamatsu.x90
2026-03-12 7:56 ` Cosmin-Gabriel Tanislav
0 siblings, 1 reply; 25+ messages in thread
From: nobuhiro.iwamatsu.x90 @ 2026-03-12 3:22 UTC (permalink / raw)
To: cosmin-gabriel.tanislav.xa, cip-dev, pavel
Hi,
> -----Original Message-----
> From: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> Sent: Tuesday, March 10, 2026 12:06 AM
> To: cip-dev@lists.cip-project.org; pavel@nabladev.com; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Subject: [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock
>
> commit 1ce3e8adc7d0038e59a7c9f5c9e5f399ba0db5d6 upstream.
>
> The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs support generating the SPI transfer clock from PCLK,
> with the quirk that SPR 0 is not supported, causing the highest achievable SPI transfer frequency to be 31.25MHz.
>
> Add support for generating the SPI transfer clock from PCLK.
>
> Renesas RZ/V2H (R9A09G057) also has the BPEN bit used to enable this option in the datasheet, but it is not explicitly
> documented and there's no details about its limitations as there are on RZ/T2H.
>
> Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> Link: https://patch.msgid.link/20251119161434.595677-8-cosmin-gabriel.tanislav.xa@renesas.com
> Signed-off-by: Mark Brown <broonie@kernel.org>
> Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> ---
>
> V3:
> * no changes
>
> V2:
> * remove internal Reviewed-by tags
>
> drivers/spi/spi-rzv2h-rspi.c | 22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c index f59bcadf5e38..e9d8ee919261 100644
> --- a/drivers/spi/spi-rzv2h-rspi.c
> +++ b/drivers/spi/spi-rzv2h-rspi.c
> @@ -34,6 +34,7 @@
> #define RSPI_SPFCR 0x6c
>
> /* Register SPCR */
> +#define RSPI_SPCR_BPEN BIT(31)
> #define RSPI_SPCR_MSTR BIT(30)
> #define RSPI_SPCR_SPRIE BIT(17)
> #define RSPI_SPCR_SCKASE BIT(12)
> @@ -41,6 +42,7 @@
>
> /* Register SPBR */
> #define RSPI_SPBR_SPR_MIN 0
> +#define RSPI_SPBR_SPR_PCLK_MIN 1
> #define RSPI_SPBR_SPR_MAX 255
>
> /* Register SPCMD */
> @@ -79,6 +81,8 @@ struct rzv2h_rspi_best_clock { struct rzv2h_rspi_info {
> void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
> struct rzv2h_rspi_best_clock *best_clk);
> + void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high,
> + struct rzv2h_rspi_best_clock *best_clk);
> const char *tclk_name;
> unsigned int fifo_size;
> unsigned int num_clks;
> @@ -90,6 +94,7 @@ struct rzv2h_rspi_priv {
> const struct rzv2h_rspi_info *info;
> void __iomem *base;
> struct clk *tclk;
> + struct clk *pclk;
> wait_queue_head_t wait;
> unsigned int bytes_per_word;
> u32 last_speed_hz;
> @@ -97,6 +102,7 @@ struct rzv2h_rspi_priv {
> u16 status;
> u8 spr;
> u8 brdv;
> + bool use_pclk;
> };
>
> #define RZV2H_RSPI_TX(func, type) \
> @@ -306,9 +312,18 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
> rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
> RSPI_SPBR_SPR_MAX, &best_clock);
>
> + /*
> + * T2H and N2H can also use PCLK as a source, which is 125MHz, but not
> + * when both SPR and BRDV are 0.
> + */
> + if (best_clock.error && rspi->info->find_pclk_rate)
> + rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN,
> + RSPI_SPBR_SPR_MAX, &best_clock);
> +
> if (!best_clock.clk_rate)
> return -EINVAL;
>
> + rspi->use_pclk = best_clock.clk == rspi->pclk;
> rspi->spr = best_clock.spr;
> rspi->brdv = best_clock.brdv;
>
> @@ -361,6 +376,9 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
> /* SPI receive buffer full interrupt enable */
> conf32 |= RSPI_SPCR_SPRIE;
>
> + /* Bypass synchronization circuit */
> + conf32 |= FIELD_PREP(RSPI_SPCR_BPEN, rspi->use_pclk);
> +
> writel(conf32, rspi->base + RSPI_SPCR);
>
> /* Use SPCMD0 only */
> @@ -433,7 +451,9 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
> for (i = 0; i < rspi->info->num_clks; i++) {
> if (!strcmp(clks[i].id, rspi->info->tclk_name)) {
> rspi->tclk = clks[i].clk;
> - break;
> + } else if (rspi->info->find_pclk_rate &&
> + !strcmp(clks[i].id, "pclk")) {
I think strncmp is better than strcmp.
> + rspi->pclk = clks[i].clk;
> }
> }
>
> --
> 2.53.0
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (16 preceding siblings ...)
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 17/17] arm64: dts: renesas: r9a09g087: " Cosmin Tanislav
@ 2026-03-12 3:28 ` nobuhiro.iwamatsu.x90
2026-03-13 10:31 ` [cip-dev] " Pavel Machek
18 siblings, 0 replies; 25+ messages in thread
From: nobuhiro.iwamatsu.x90 @ 2026-03-12 3:28 UTC (permalink / raw)
To: cosmin-gabriel.tanislav.xa, cip-dev, pavel
Hi all,
> -----Original Message-----
> From: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> Sent: Tuesday, March 10, 2026 12:06 AM
> To: cip-dev@lists.cip-project.org; pavel@nabladev.com; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Subject: [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H
>
> This series adds RSPI support for the Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs.
>
> RZ/T2H and RZ/N2H support is implemented as part of the RZ/V2H RSPI driver, and, as such, the RZ/V2H RSPI driver had
> to be backported.
>
> Patches were cherry-picked from upstream kernel.
>
> This series applies on top of my previously submitted series [1] (to avoid a conflict in
> drivers/clk/renesas/r9a09g077-cpg.c mainly).
>
> [1]:
> https://patchwork.kernel.org/project/cip-dev/cover/20260303165351.914437-1-cosmin-gabriel.tanislav.xa@renesas.co
> m/
>
> V3:
> * describe changes made to apply on top of CIP
>
> V2:
> * remove internal Reviewed-by tags
>
> Cosmin Tanislav (14):
> clk: renesas: r9a09g077: Add SPI module clocks
> spi: rzv2h-rspi: make resets optional
> spi: rzv2h-rspi: make FIFO size chip-specific
> spi: rzv2h-rspi: make clocks chip-specific
> spi: rzv2h-rspi: move register writes out of rzv2h_rspi_setup_clock()
> spi: rzv2h-rspi: avoid recomputing transfer frequency
> spi: rzv2h-rspi: make transfer clock rate finding chip-specific
> spi: rzv2h-rspi: add support for using PCLK for transfer clock
> spi: rzv2h-rspi: add support for variable transfer clock
> spi: rzv2h-rspi: add support for loopback mode
> spi: rzv2h-rspi: add support for RZ/T2H and RZ/N2H
> spi: dt-bindings: renesas,rzv2h-rspi: document RZ/T2H and RZ/N2H
> arm64: dts: renesas: r9a09g077: Add SPI nodes
> arm64: dts: renesas: r9a09g087: Add SPI nodes
>
> Fabrizio Castro (3):
> spi: dt-bindings: Document the RZ/V2H(P) RSPI
> spi: Add driver for the RZ/V2H(P) RSPI IP
> arm64: defconfig: Enable the RZ/V2H(P) RSPI driver
>
> .../bindings/spi/renesas,rzv2h-rspi.yaml | 138 ++++
> arch/arm64/boot/dts/renesas/r9a09g077.dtsi | 72 ++
> arch/arm64/boot/dts/renesas/r9a09g087.dtsi | 72 ++
> arch/arm64/configs/defconfig | 1 +
> drivers/clk/renesas/r9a09g077-cpg.c | 22 +-
> drivers/spi/Kconfig | 8 +
> drivers/spi/Makefile | 1 +
> drivers/spi/spi-rzv2h-rspi.c | 687 ++++++++++++++++++
> 8 files changed, 1000 insertions(+), 1 deletion(-) create mode 100644
> Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
> create mode 100644 drivers/spi/spi-rzv2h-rspi.c
>
I reviewed this series, looks good to me.
I can apply if tests are OK and there are no other comments.
https://gitlab.com/cip-project/cip-kernel/linux-cip/-/pipelines/2380006614
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.x90@mail.toshiba>
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock
2026-03-12 3:22 ` nobuhiro.iwamatsu.x90
@ 2026-03-12 7:56 ` Cosmin-Gabriel Tanislav
0 siblings, 0 replies; 25+ messages in thread
From: Cosmin-Gabriel Tanislav @ 2026-03-12 7:56 UTC (permalink / raw)
To: nobuhiro.iwamatsu.x90@mail.toshiba, cip-dev@lists.cip-project.org,
pavel@nabladev.com
> From: nobuhiro.iwamatsu.x90@mail.toshiba <nobuhiro.iwamatsu.x90@mail.toshiba>
> Sent: Thursday, March 12, 2026 5:23 AM
> clock
>
> Hi,
>
> > -----Original Message-----
> > From: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> > Sent: Tuesday, March 10, 2026 12:06 AM
> > To: cip-dev@lists.cip-project.org; pavel@nabladev.com; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> > <nobuhiro.iwamatsu.x90@mail.toshiba>
> > Subject: [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock
> >
> > commit 1ce3e8adc7d0038e59a7c9f5c9e5f399ba0db5d6 upstream.
> >
> > The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs support generating the SPI transfer clock
> from PCLK,
> > with the quirk that SPR 0 is not supported, causing the highest achievable SPI transfer frequency to
> be 31.25MHz.
> >
> > Add support for generating the SPI transfer clock from PCLK.
> >
> > Renesas RZ/V2H (R9A09G057) also has the BPEN bit used to enable this option in the datasheet, but it
> is not explicitly
> > documented and there's no details about its limitations as there are on RZ/T2H.
> >
> > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> > Link: https://patch.msgid.link/20251119161434.595677-8-cosmin-gabriel.tanislav.xa@renesas.com
> > Signed-off-by: Mark Brown <broonie@kernel.org>
> > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
> > ---
> >
> > V3:
> > * no changes
> >
> > V2:
> > * remove internal Reviewed-by tags
> >
> > drivers/spi/spi-rzv2h-rspi.c | 22 +++++++++++++++++++++-
> > 1 file changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c index
> f59bcadf5e38..e9d8ee919261 100644
> > --- a/drivers/spi/spi-rzv2h-rspi.c
> > +++ b/drivers/spi/spi-rzv2h-rspi.c
> > @@ -34,6 +34,7 @@
> > #define RSPI_SPFCR 0x6c
> >
> > /* Register SPCR */
> > +#define RSPI_SPCR_BPEN BIT(31)
> > #define RSPI_SPCR_MSTR BIT(30)
> > #define RSPI_SPCR_SPRIE BIT(17)
> > #define RSPI_SPCR_SCKASE BIT(12)
> > @@ -41,6 +42,7 @@
> >
> > /* Register SPBR */
> > #define RSPI_SPBR_SPR_MIN 0
> > +#define RSPI_SPBR_SPR_PCLK_MIN 1
> > #define RSPI_SPBR_SPR_MAX 255
> >
> > /* Register SPCMD */
> > @@ -79,6 +81,8 @@ struct rzv2h_rspi_best_clock { struct rzv2h_rspi_info {
> > void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
> > struct rzv2h_rspi_best_clock *best_clk);
> > + void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high,
> > + struct rzv2h_rspi_best_clock *best_clk);
> > const char *tclk_name;
> > unsigned int fifo_size;
> > unsigned int num_clks;
> > @@ -90,6 +94,7 @@ struct rzv2h_rspi_priv {
> > const struct rzv2h_rspi_info *info;
> > void __iomem *base;
> > struct clk *tclk;
> > + struct clk *pclk;
> > wait_queue_head_t wait;
> > unsigned int bytes_per_word;
> > u32 last_speed_hz;
> > @@ -97,6 +102,7 @@ struct rzv2h_rspi_priv {
> > u16 status;
> > u8 spr;
> > u8 brdv;
> > + bool use_pclk;
> > };
> >
> > #define RZV2H_RSPI_TX(func, type) \
> > @@ -306,9 +312,18 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
> > rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
> > RSPI_SPBR_SPR_MAX, &best_clock);
> >
> > + /*
> > + * T2H and N2H can also use PCLK as a source, which is 125MHz, but not
> > + * when both SPR and BRDV are 0.
> > + */
> > + if (best_clock.error && rspi->info->find_pclk_rate)
> > + rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN,
> > + RSPI_SPBR_SPR_MAX, &best_clock);
> > +
> > if (!best_clock.clk_rate)
> > return -EINVAL;
> >
> > + rspi->use_pclk = best_clock.clk == rspi->pclk;
> > rspi->spr = best_clock.spr;
> > rspi->brdv = best_clock.brdv;
> >
> > @@ -361,6 +376,9 @@ static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
> > /* SPI receive buffer full interrupt enable */
> > conf32 |= RSPI_SPCR_SPRIE;
> >
> > + /* Bypass synchronization circuit */
> > + conf32 |= FIELD_PREP(RSPI_SPCR_BPEN, rspi->use_pclk);
> > +
> > writel(conf32, rspi->base + RSPI_SPCR);
> >
> > /* Use SPCMD0 only */
> > @@ -433,7 +451,9 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
> > for (i = 0; i < rspi->info->num_clks; i++) {
> > if (!strcmp(clks[i].id, rspi->info->tclk_name)) {
> > rspi->tclk = clks[i].clk;
> > - break;
> > + } else if (rspi->info->find_pclk_rate &&
> > + !strcmp(clks[i].id, "pclk")) {
>
> I think strncmp is better than strcmp.
>
How would strncmp look when applied to this case, if you do not mind me
asking? I only see the following possibilities:
strncmp(clks[i].id, "pclk", strlen("pclk")) -> prefix match, not ok,
as it would return 0 for "pclk2" for example
strncmp(clks[i].id, "pclk", strlen("pclk") + 1) -> equivalent to strcmp
Am I missing something?
> > + rspi->pclk = clks[i].clk;
> > }
> > }
> >
> > --
> > 2.53.0
>
> Best regards,
> Nobuhiro
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [cip-dev] [PATCH 6.12.y-cip v3 02/17] spi: Add driver for the RZ/V2H(P) RSPI IP
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 02/17] spi: Add driver for the RZ/V2H(P) RSPI IP Cosmin Tanislav
@ 2026-03-13 10:17 ` Pavel Machek
0 siblings, 0 replies; 25+ messages in thread
From: Pavel Machek @ 2026-03-13 10:17 UTC (permalink / raw)
To: cosmin-gabriel.tanislav.xa; +Cc: cip-dev, pavel, nobuhiro.iwamatsu.x90
[-- Attachment #1: Type: text/plain, Size: 1605 bytes --]
Hi!
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
>
> commit 8b61c8919dff080d83415523cd68f2fef03ccfc7 upstream.
>
> The Renesas RZ/V2H(P) RSPI IP supports 4-wire and 3-wire
> serial communications in both host role and target role.
> It can use a DMA, but the I/O can also be driven by the
> processor.
Normally we format this to 70 columns or so.
> @@ -885,6 +885,14 @@ config SPI_RSPI
> help
> SPI driver for Renesas RSPI and QSPI blocks.
>
> +config SPI_RZV2H_RSPI
> + tristate "Renesas RZ/V2H RSPI controller"
> + depends on ARCH_RENESAS || COMPILE_TEST
> + help
> + RSPI driver for the Renesas RZ/V2H Serial Peripheral Interface (RSPI).
> + RSPI supports both SPI host and SPI target roles. This option only
> + enables the SPI host role.
"Module will be called xyz" is normally in the help text.
> +static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
> +{
> + unsigned long tclk_rate;
> + int spr;
> + u8 brdv;
...
> + tclk_rate = clk_get_rate(rspi->tclk);
> + for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
> + spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
> + spr--;
> + if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
> + goto clock_found;
> + }
> +
> + return 0;
> +
> +clock_found:
> + rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv);
> + writeb(spr, rspi->base + RSPI_SPBR);
> +
> + return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
> +}
I believe code would be better without the goto here.
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 6.12.y-cip v3 10/17] spi: rzv2h-rspi: make transfer clock rate finding chip-specific
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 10/17] spi: rzv2h-rspi: make transfer clock rate finding chip-specific Cosmin Tanislav
@ 2026-03-13 10:25 ` Pavel Machek
0 siblings, 0 replies; 25+ messages in thread
From: Pavel Machek @ 2026-03-13 10:25 UTC (permalink / raw)
To: Cosmin Tanislav; +Cc: cip-dev, pavel, nobuhiro.iwamatsu.x90
[-- Attachment #1: Type: text/plain, Size: 1900 bytes --]
Hi!
> commit 77d931584dd38916b66c65320c80a65cbef4b122 upstream.
>
> The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a more
> complicated clocking setup for the SPI transfer clock than RZ/V2H, as
> the clock from which it is generated supports multiple dividers.
>
> To prepare for adding support for these SoCs, split out the logic for
> finding the SPR and BRDV for a fixed clock into
> rzv2h_rspi_find_rate_fixed(), and add and use a .find_tclk_rate()
> callback into the chip-specific structure.
> @@ -255,21 +270,49 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
> * * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
> * * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
> */
> - tclk_rate = clk_get_rate(rspi->tclk);
> + clk_rate = clk_get_rate(clk);
> for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
> - spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
> + spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1)));
> spr--;
> - if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
> + if (spr >= spr_min && spr <= spr_max)
> goto clock_found;
> }
>
> - return 0;
> + return;
>
> clock_found:
> - rspi->spr = spr;
> - rspi->brdv = brdv;
> + actual_hz = rzv2h_rspi_calc_bitrate(clk_rate, spr, brdv);
> + error = abs((long)hz - (long)actual_hz);
>
> - return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
> + if (error >= best->error)
> + return;
> +
> + *best = (struct rzv2h_rspi_best_clock) {
> + .clk = clk,
> + .clk_rate = clk_rate,
> + .error = error,
> + .actual_hz = actual_hz,
> + .brdv = brdv,
> + .spr = spr,
> + };
> +}
This is really quite strange code... looks like Rust more than C.
Filling clk, error, actual_hz, .... into temporary variable and then
just assiging it may be better.
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [cip-dev] [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
` (17 preceding siblings ...)
2026-03-12 3:28 ` [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H nobuhiro.iwamatsu.x90
@ 2026-03-13 10:31 ` Pavel Machek
2026-03-18 5:31 ` nobuhiro.iwamatsu.x90
18 siblings, 1 reply; 25+ messages in thread
From: Pavel Machek @ 2026-03-13 10:31 UTC (permalink / raw)
To: cosmin-gabriel.tanislav.xa; +Cc: cip-dev, pavel, nobuhiro.iwamatsu.x90
[-- Attachment #1: Type: text/plain, Size: 645 bytes --]
Hi!
> This series adds RSPI support for the Renesas RZ/T2H (R9A09G077) and
> RZ/N2H (R9A09G087) SoCs.
>
> RZ/T2H and RZ/N2H support is implemented as part of the RZ/V2H RSPI
> driver, and, as such, the RZ/V2H RSPI driver had to be backported.
>
> Patches were cherry-picked from upstream kernel.
I had some minor comments here, but those should be fixed in mainline,
first, so they should not block the merge.
Reviewed-by: Pavel Machek <pavel@nabladev.com>
I can apply the series if it passes testing and there are no other
comments.
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [cip-dev] [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H
2026-03-13 10:31 ` [cip-dev] " Pavel Machek
@ 2026-03-18 5:31 ` nobuhiro.iwamatsu.x90
0 siblings, 0 replies; 25+ messages in thread
From: nobuhiro.iwamatsu.x90 @ 2026-03-18 5:31 UTC (permalink / raw)
To: pavel, cosmin-gabriel.tanislav.xa; +Cc: cip-dev
Hi all,
> -----Original Message-----
> From: Pavel Machek <pavel@nabladev.com>
> Sent: Friday, March 13, 2026 7:31 PM
> To: cosmin-gabriel.tanislav.xa@renesas.com
> Cc: cip-dev@lists.cip-project.org; pavel@nabladev.com; iwamatsu nobuhiro(岩松 信洋 □DITC○CPT)
> <nobuhiro.iwamatsu.x90@mail.toshiba>
> Subject: Re: [cip-dev] [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H
>
> Hi!
>
> > This series adds RSPI support for the Renesas RZ/T2H (R9A09G077) and
> > RZ/N2H (R9A09G087) SoCs.
> >
> > RZ/T2H and RZ/N2H support is implemented as part of the RZ/V2H RSPI
> > driver, and, as such, the RZ/V2H RSPI driver had to be backported.
> >
> > Patches were cherry-picked from upstream kernel.
>
> I had some minor comments here, but those should be fixed in mainline, first, so they should not block the merge.
>
> Reviewed-by: Pavel Machek <pavel@nabladev.com>
>
> I can apply the series if it passes testing and there are no other comments.
>
I applied and pushed this series, thanks.
> Best regards,
> Pavel
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-03-18 5:31 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-09 15:06 [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 01/17] spi: dt-bindings: Document the RZ/V2H(P) RSPI Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 02/17] spi: Add driver for the RZ/V2H(P) RSPI IP Cosmin Tanislav
2026-03-13 10:17 ` [cip-dev] " Pavel Machek
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 03/17] arm64: defconfig: Enable the RZ/V2H(P) RSPI driver Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 04/17] clk: renesas: r9a09g077: Add SPI module clocks Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 05/17] spi: rzv2h-rspi: make resets optional Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 06/17] spi: rzv2h-rspi: make FIFO size chip-specific Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 07/17] spi: rzv2h-rspi: make clocks chip-specific Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 08/17] spi: rzv2h-rspi: move register writes out of rzv2h_rspi_setup_clock() Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 09/17] spi: rzv2h-rspi: avoid recomputing transfer frequency Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 10/17] spi: rzv2h-rspi: make transfer clock rate finding chip-specific Cosmin Tanislav
2026-03-13 10:25 ` Pavel Machek
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 11/17] spi: rzv2h-rspi: add support for using PCLK for transfer clock Cosmin Tanislav
2026-03-12 3:22 ` nobuhiro.iwamatsu.x90
2026-03-12 7:56 ` Cosmin-Gabriel Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 12/17] spi: rzv2h-rspi: add support for variable " Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 13/17] spi: rzv2h-rspi: add support for loopback mode Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 14/17] spi: rzv2h-rspi: add support for RZ/T2H and RZ/N2H Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 15/17] spi: dt-bindings: renesas,rzv2h-rspi: document " Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 16/17] arm64: dts: renesas: r9a09g077: Add SPI nodes Cosmin Tanislav
2026-03-09 15:06 ` [PATCH 6.12.y-cip v3 17/17] arm64: dts: renesas: r9a09g087: " Cosmin Tanislav
2026-03-12 3:28 ` [PATCH 6.12.y-cip v3 00/17] Add RSPI support for RZ/T2H and RZ/N2H nobuhiro.iwamatsu.x90
2026-03-13 10:31 ` [cip-dev] " Pavel Machek
2026-03-18 5:31 ` nobuhiro.iwamatsu.x90
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox