linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC
@ 2025-04-03 21:29 Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
                   ` (12 more replies)
  0 siblings, 13 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel; +Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel

This patchset brings basic support for Renesas RZ/T2H SoC and
its evaluation board. The 4 CPUs are enabled, only the serial 
console is available and the board must boot on a ramdisk. 
earlycon is supported, though.

The RZ/T2H serial controller (SCI) is quite different from the 
other RZ SoCs, one of the big differences (but not the only) being
the 32 bits registers. In order to not modify the existing sh-sci 
driver too much, a new set of 'ops' function pointer is introduced,
allowing to code the specifics of RZ/T2H in a separate file.
Termios setting is not supported yet, the default 115200 baudrate
being kept by default.

Clock support for RZ/T2H is added to the existing renesas-cpg-mssr
driver, with some little modifications so that more parameters are
passed to the device-specific registration callback. 
At this stage, the assumption is made that most of the initialization 
is done earlier by the bootloader. Module clock enable/disable is 
not supported, because quite hard to test when the only available 
peripheral is the serial console, and will come in a future patchset.

This patch series applies to linux-next

Changes v6->v7
* [PATCH 2/13]
  - Add description for reg property
* [PATCH 3/13]
  - Moved all rsci in a separate file
  - Added example
* [PATCH 10/13]
  - Renamed compatible string to r9a09g077-rsci
* [PATCH 11/13]
  - Renamed compatible string to r9a09g077-rsci
* [PATCH 12/13]
  - lands in arm64 directory instead of arm

Changes v5->v6
* [PATCH 1/13]
  - Rebased on top of next-20250331
* [PATCH 2/13]
  - Set clock minItem constraint
  - Moved additionalProperties after 'allOf' section
* [PATCH 10/13]
  - Rename SERIAL_RZ_SCI_T2 to CONFIG_SERIAL_RSCI
  - Rename rz-sci-t2.{c,h} to rsci.{c,h}
  - Rename port type to PORT_RSCI
  - Rename sci_r9a09g077_data to of_sci_r9a09g077_data for consistency
* [PATCH 12/13]
  - Rebased on top of next-20250331
* [PATCH 13/13]
  - Renamed CONFIG_SERIAL_RZ_SCI_T2 to CONFIG_SERIAL_RSCI

Changes v4->v5
* [PATCH 2/13]:
  - Set reg minItems and maxItems defaults at top level
* [PATCH 8/13]:
   - sci_shutdown is no longer static (systemd needs it)
* [PATCH 10/13]:
  - Rename SERIAL_RZ_SCI to SERIAL_RZ_SCI_T2
  - Rename rzsci.{c,h} to rz-sci-t2.{c,h}
  - Rename port type to PORT_RZ_SCI_T2
  - Set sci_shutdown ops pointer (needed by systemd for having a console)
* [PATCH 13/13]:
   - Renamed CONFIG_SERIAL_RZ_SCI to CONFIG_SERIAL_RZ_SCI_T2

Changes v3->v4
* Remove all unwanted 'Reviewed by:' tags coming from internal patchwork.
* [PATCH 2/13]: 
  - Handle maxItems and clocks names properly in schema.
* [PATCH 3/13]: 
  - Add more details in commit description about why renesas,sci 
    does not apply.
  - Remove uart-has-rtscts for !rzsci.
* [PATCH 4/13] & [PATCH 13/13] 
  - Sets ARCH_R9A09G077 to Y by default.
* [PATCH 6/13] 
   - Add missing #include <bitfield.h> (reported by bot)
   - Add missing __iomem address space in cpg_rzt2h_addr_from_offset and
     return type (reported by bot)
   - fixed clocks: inverted 'mult' and 'div' parameters when using 
     the DEF_FIXED macro
* [PATCH 8/13]
   - Add missing #include <bitfield.h>
   - Remove sci_poll_get_char sci_poll_put_char from sh-sci-common.h (both 
     function are not used by rzsci yet).
   - Add missing #ifdef around .poll_put_char pointer initialization.
* [PATCH 9/13] 
  - Fix the bot compilation error on superh in sci_probe_earlyprink()
* [PATCH 10/13]
  - Add missing #include <bitfield.h>
  - Fix christmas tree code style in rzsci_transmit_chars.
* [PATCH 13/13]
  - Change the commit title.
  - Remove CONFIG_ARCH_R9A09G077=y.

Changes v2->v3
* Amend [PATCH v2 05/13] with Signed-off-by, added comment about
  moved parameters of priv data.
* bindings:
  - sci: own section for RZ/T2H sci, resets no required at this stage
  - sci: 'uart-has-rtscts' is conditional to RZ/T2H.
  - renesas: 'renesas,r9a09g077' is the fallback.
  - cpg: renamed 'r9a09g077-cpg-mssr.h to 'renesas,r9a09g077-cpg-mssr.h'.
  - cpg: update renesas,cpg-mssr.yaml (added loco clock, maxItems for registers is 2),
    update commit description
* rz/sci: 
  - rebase the patchset on v6.14-rc3.
  - removed unused register bits definitions in rzsci.c
  - rzsci: replace the busy loop in rzsci_poll_put_char by 
    readl_relaxed_poll_timeout_atomic
  - change 'struct sci_suspend_regs' to opaque pointer in sci_port, 
    kzalloc it with size returned from the added 'suspend_regs_size()' 
    to specific ops.
  - renamed 'sh-sci_common.h' to 'sh-sci-common.h'
  - add Geert's fixes for SH crash
  - do not use SCI_OF_DATA macro to avoid code duplication by compiler
  - revert some global functions to static
* clk:
  - fixed Kconfig for selecting CLK_RENESAS_CPG_MSSR.
  - code style.
  - use macros for MSTPCR block selection.
  - fixed erroneous offset in mstpcr_for_rzt2h array.
  - fixed the forgotten rcar-gen2-cpg.c in [PATCH v2 05/13]
 * defconfig;
  - added commit description and SoB
  - update cover letter about SoC options

Changes v1->v2
* CPG based on renesas-cpg-mssr (no more new CPG driver), updated cover letter
  for that.
* bindings: 
  - passed dt_binding_check and added missing compatible strings, 
  - document SoC + evaluation board in a single commit
  - rzsci added to sci documentation
  - fixed dependencies
  - renamed the evaluation board to r9a9g077m44-rzt2h-evk
  - removed clock module numbers & resets from binding header
  - compatibles: renamed r9a09g077-rzt2h-evk to rzt2h-evk
* rz/sci:
  - added Renesas copyright
  - fixed rzsci_receive_chars following Geert's advice, and comment
    that 9-bits data is not supported
  - fixed the regression (ops init) on non-DT legacy boards, sci_probe_regmap
    called moved in the non-DT case.
  - moved struct sci_of_data introduction in the appropriate commit
* dts
  - applied conventions (nodes alphabetical order & node names)
  - added missing compatibles to r9a09g077m44.dtsi and r9a09g077m44-rzt2h-evk.dts
 


Thierry Bultel (13):
  dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC
  dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
  dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci
  soc: renesas: Add RZ/T2H (R9A09G077) config option
  clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register
  clk: renesas: Add support for R9A09G077 SoC
  serial: sh-sci: Fix a comment about SCIFA
  serial: sh-sci: Introduced function pointers
  serial: sh-sci: Introduced sci_of_data
  serial: sh-sci: Add support for RZ/T2H SCI
  arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC
  arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board
  arm64: defconfig: Enable Renesas RZ/T2H serial SCI

 .../bindings/clock/renesas,cpg-mssr.yaml      |  61 +-
 .../bindings/serial/renesas,rsci.yaml         |  78 +++
 .../bindings/soc/renesas/renesas.yaml         |  10 +
 arch/arm64/boot/dts/renesas/Makefile          |   1 +
 arch/arm64/boot/dts/renesas/r9a09g077.dtsi    | 129 ++++
 .../dts/renesas/r9a09g077m44-rzt2h-evk.dts    |  35 +
 arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi |  13 +
 arch/arm64/configs/defconfig                  |   1 +
 drivers/clk/renesas/Kconfig                   |   5 +
 drivers/clk/renesas/Makefile                  |   1 +
 drivers/clk/renesas/r7s9210-cpg-mssr.c        |   7 +-
 drivers/clk/renesas/r8a77970-cpg-mssr.c       |  11 +-
 drivers/clk/renesas/r9a09g077-cpg-mssr.c      | 238 +++++++
 drivers/clk/renesas/rcar-gen2-cpg.c           |   5 +-
 drivers/clk/renesas/rcar-gen2-cpg.h           |   3 +-
 drivers/clk/renesas/rcar-gen3-cpg.c           |   6 +-
 drivers/clk/renesas/rcar-gen3-cpg.h           |   6 +-
 drivers/clk/renesas/rcar-gen4-cpg.c           |   8 +-
 drivers/clk/renesas/rcar-gen4-cpg.h           |   3 +-
 drivers/clk/renesas/renesas-cpg-mssr.c        | 153 ++--
 drivers/clk/renesas/renesas-cpg-mssr.h        |  43 +-
 drivers/soc/renesas/Kconfig                   |   6 +
 drivers/tty/serial/Kconfig                    |   7 +
 drivers/tty/serial/Makefile                   |   1 +
 drivers/tty/serial/rsci.c                     | 467 +++++++++++++
 drivers/tty/serial/rsci.h                     |  12 +
 drivers/tty/serial/sh-sci-common.h            | 167 +++++
 drivers/tty/serial/sh-sci.c                   | 651 ++++++++++--------
 drivers/tty/serial/sh-sci.h                   |   2 -
 .../clock/renesas,r9a09g077-cpg-mssr.h        |  49 ++
 include/linux/serial_sci.h                    |   3 +-
 include/uapi/linux/serial_core.h              |   3 +
 32 files changed, 1818 insertions(+), 367 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/serial/renesas,rsci.yaml
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi
 create mode 100644 drivers/clk/renesas/r9a09g077-cpg-mssr.c
 create mode 100644 drivers/tty/serial/rsci.c
 create mode 100644 drivers/tty/serial/rsci.h
 create mode 100644 drivers/tty/serial/sh-sci-common.h
 create mode 100644 include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h

-- 
2.43.0


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-17 13:39   ` Geert Uytterhoeven
  2025-04-03 21:29 ` [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Rob Herring, Geert Uytterhoeven, devicetree, linux-kernel

Add RZ/T2H (R9A09G077), its variants, and the rt2h-evk evaluation board in
documentation.

Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: rebased on next-20250331
Changes v4->v5: none
Changes v3->v4: none
---
 .../devicetree/bindings/soc/renesas/renesas.yaml       | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index 51a4c48eea6d..6874f425bf1f 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -570,6 +570,16 @@ properties:
           - const: renesas,r9a09g057h48
           - const: renesas,r9a09g057
 
+      - description: RZ/T2H (R9A09G077)
+        items:
+          - enum:
+              - renesas,rzt2h-evk # RZ/T2H Evaluation Board
+          - enum:
+              - renesas,r9a09g077m04 # RZ/T2H with Single Cortex-A55 + Dual Cortex-R52 - no security
+              - renesas,r9a09g077m24 # RZ/T2H with Dual Cortex-A55 + Dual Cortex-R52 - no security
+              - renesas,r9a09g077m44 # RZ/T2H with Quad Cortex-A55 + Dual Cortex-R52 - no security
+          - const: renesas,r9a09g077
+
 additionalProperties: true
 
 ...
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-04 19:37   ` Rob Herring (Arm)
  2025-04-17 13:41   ` Geert Uytterhoeven
  2025-04-03 21:29 ` [PATCH v7 03/13] dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci Thierry Bultel
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Geert Uytterhoeven, linux-clk, devicetree, linux-kernel

Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding.

Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7:
  - Add description for reg property
Changes v5->v6:
  - Set clock minItem constraint
  - Moved additionalProperties after 'allOf' section
Changes v4->v5:
  - Set reg minItems and maxItems defaults at top level
Changes v3->v4:
  - Handle maxItems and clocks names properly in schema. 
---
 .../bindings/clock/renesas,cpg-mssr.yaml      | 61 ++++++++++++++-----
 .../clock/renesas,r9a09g077-cpg-mssr.h        | 49 +++++++++++++++
 2 files changed, 94 insertions(+), 16 deletions(-)
 create mode 100644 include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
index 77ce3615c65a..483440ad0e3f 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
@@ -52,9 +52,15 @@ properties:
       - renesas,r8a779f0-cpg-mssr # R-Car S4-8
       - renesas,r8a779g0-cpg-mssr # R-Car V4H
       - renesas,r8a779h0-cpg-mssr # R-Car V4M
+      - renesas,r9a09g077-cpg-mssr # RZ/T2H
 
   reg:
-    maxItems: 1
+    minItems: 1
+    items:
+      - description: base address of register block 0
+      - description: base address of register block 1
+    description: base addresses of clock controller. Some controllers
+      (like r9a09g077) use two blocks instead of a single one).
 
   clocks:
     minItems: 1
@@ -63,11 +69,6 @@ properties:
   clock-names:
     minItems: 1
     maxItems: 2
-    items:
-      enum:
-        - extal     # All
-        - extalr    # Most R-Car Gen3 and RZ/G2
-        - usb_extal # Most R-Car Gen2 and RZ/G1
 
   '#clock-cells':
     description: |
@@ -92,16 +93,6 @@ properties:
       the datasheet.
     const: 1
 
-if:
-  not:
-    properties:
-      compatible:
-        items:
-          enum:
-            - renesas,r7s9210-cpg-mssr
-then:
-  required:
-    - '#reset-cells'
 
 required:
   - compatible
@@ -111,6 +102,44 @@ required:
   - '#clock-cells'
   - '#power-domain-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,r9a09g077-cpg-mssr
+    then:
+      properties:
+        reg:
+          minItems: 2
+        clocks:
+          minItems: 2
+        clock-names:
+          items:
+            - const: extal
+            - const: loco
+    else:
+      properties:
+        reg:
+          maxItems: 1
+        clock-names:
+          items:
+            enum:
+              - extal     # All
+              - extalr    # Most R-Car Gen3 and RZ/G2
+              - usb_extal # Most R-Car Gen2 and RZ/G1
+
+  - if:
+      not:
+        properties:
+          compatible:
+            items:
+              enum:
+                - renesas,r7s9210-cpg-mssr
+    then:
+      required:
+        - '#reset-cells'
+
 additionalProperties: false
 
 examples:
diff --git a/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
new file mode 100644
index 000000000000..27c9cdcdf7c8
--- /dev/null
+++ b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
+#define __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* R9A09G077 CPG Core Clocks */
+#define R9A09G077_CA55C0		0
+#define R9A09G077_CA55C1		1
+#define R9A09G077_CA55C2		2
+#define R9A09G077_CA55C3		3
+#define R9A09G077_SDHIHS		4
+#define R9A09G077_CLK_PLL1_ETH_PHY	5
+#define R9A09G077_CLK_OSC_ETH_PHY	6
+#define R9A09G077_CLK_ETHPHY		7
+#define R9A09G077_PCLKAH		8
+#define R9A09G077_PCLKAM		9
+#define R9A09G077_PCLKAL		10
+#define R9A09G077_CLK_SEL_ETH_PHY	11
+#define R9A09G077_DFI			12
+#define R9A09G077_PCLKH			13
+#define R9A09G077_PCLKM			14
+#define R9A09G077_PCLKL			15
+#define R9A09G077_PCLKGPTL		16
+#define R9A09G077_PCLKSHOST		17
+#define R9A09G077_PCLKRTC		18
+#define R9A09G077_USB			19
+#define R9A09G077_SPI0			20
+#define R9A09G077_SPI1			21
+#define R9A09G077_SPI2			22
+#define R9A09G077_SPI3			23
+#define R9A09G077_ETCLKA		24
+#define R9A09G077_ETCLKB		25
+#define R9A09G077_ETCLKC		26
+#define R9A09G077_ETCLKD		27
+#define R9A09G077_ETCLKE		28
+#define R9A09G077_ETHCLKE		29
+#define R9A09G077_ETHCLK_EXTAL		30
+#define R9A09G077_ETH_REFCLK		31
+#define R9A09G077_LCDC_CLKA		32
+#define R9A09G077_LCDC_CLKP		33
+#define R9A09G077_CA55			34
+#define R9A09G077_LCDC_CLKD		35
+
+#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 03/13] dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-17 14:04   ` Geert Uytterhoeven
  2025-04-03 21:29 ` [PATCH v7 04/13] soc: renesas: Add RZ/T2H (R9A09G077) config option Thierry Bultel
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Rob Herring, Geert Uytterhoeven, linux-kernel, linux-serial,
	devicetree

RSCI of RZ/T2H SoC (a.k.a r9a09g077), as a lot
of similarities with SCI in other Renesas SoC like G2L, G3S, V2L;
However, it has a different set of registers, and in addition to serial,
this IP also supports SCIe (encoder), SmartCard, i2c and spi.
This is why the 'renesas,sci' fallback for generic SCI does not apply for it.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: 
  - Moved all rsci in a separate file
  - Added example
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4:
  - Added more details in commit description about why renesas,sci 
    does not apply.
  - Removed uart-has-rtscts for !rzsci.
----
 .../bindings/serial/renesas,rsci.yaml         | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serial/renesas,rsci.yaml

diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
new file mode 100644
index 000000000000..ea879db5f485
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/renesas,rsci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RSCI Serial Communication Interface
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+  - Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
+
+allOf:
+  - $ref: serial.yaml#
+
+properties:
+  compatible:
+    const: renesas,r9a09g077-rsci      # RZ/T2H
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Error interrupt
+      - description: Receive buffer full interrupt
+      - description: Transmit buffer empty interrupt
+      - description: Transmit end interrupt
+
+  interrupt-names:
+    items:
+      - const: eri
+      - const: rxi
+      - const: txi
+      - const: tei
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: fck # UART functional clock
+
+  power-domains:
+    maxItems: 1
+
+  uart-has-rtscts: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - power-domains
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+    aliases {
+        serial0 = &sci0;
+    };
+
+    sci0: serial@80005000 {
+        compatible = "renesas,r9a09g077-rsci";
+        reg = <0x80005000 0x400>;
+        interrupts = <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 591 IRQ_TYPE_EDGE_RISING>,
+                     <GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
+                     <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "eri", "rxi", "txi", "tei";
+        clocks = <&cpg CPG_MOD 108>;
+        clock-names = "fck";
+        power-domains = <&cpg>;
+    };
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 04/13] soc: renesas: Add RZ/T2H (R9A09G077) config option
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (2 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 03/13] dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Geert Uytterhoeven, linux-kernel

Add a configuration option for the RZ/T2H SoC.

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4:
  - Sets ARCH_R9A09G077 to Y by default.
---
 drivers/soc/renesas/Kconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 49648cf28bd2..5ce646afa008 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -359,6 +359,12 @@ config ARCH_R9A09G057
 	help
 	  This enables support for the Renesas RZ/V2H(P) SoC variants.
 
+config ARCH_R9A09G077
+	bool "ARM64 Platform support for RZ/T2H"
+	default y if ARCH_RENESAS
+	help
+	  This enables support for the Renesas RZ/T2H SoC variants.
+
 endif # ARM64
 
 if RISCV
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (3 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 04/13] soc: renesas: Add RZ/T2H (R9A09G077) config option Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-17 14:15   ` Geert Uytterhoeven
  2025-04-03 21:29 ` [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	linux-clk, linux-kernel

In a subsequent patch, the registration callback will need more parameters
from cpg_mssr_priv (like another base address with clock controllers
with double register block, and also, notifiers and rmw_lock).
Instead of adding more parameters, move the needed parameters to a public
sub-struct.
Instead moving clks to this structure, which would have implied to add
an allocation (and cleanup) for it, keep the way the allocation is done
and just have a copy of the pointer in the public structure.

Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4: none
---
 drivers/clk/renesas/r7s9210-cpg-mssr.c  |  7 +-
 drivers/clk/renesas/r8a77970-cpg-mssr.c | 11 +--
 drivers/clk/renesas/rcar-gen2-cpg.c     |  5 +-
 drivers/clk/renesas/rcar-gen2-cpg.h     |  3 +-
 drivers/clk/renesas/rcar-gen3-cpg.c     |  6 +-
 drivers/clk/renesas/rcar-gen3-cpg.h     |  6 +-
 drivers/clk/renesas/rcar-gen4-cpg.c     |  8 +-
 drivers/clk/renesas/rcar-gen4-cpg.h     |  3 +-
 drivers/clk/renesas/renesas-cpg-mssr.c  | 97 ++++++++++++-------------
 drivers/clk/renesas/renesas-cpg-mssr.h  | 20 ++++-
 10 files changed, 93 insertions(+), 73 deletions(-)

diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c
index e1812867a6da..a8ed87c11ba1 100644
--- a/drivers/clk/renesas/r7s9210-cpg-mssr.c
+++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c
@@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk,
 
 static struct clk * __init rza2_cpg_clk_register(struct device *dev,
 	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers)
+	struct cpg_mssr_pub *pub)
 {
-	struct clk *parent;
+	void __iomem *base = pub->base0;
+	struct clk **clks = pub->clks;
 	unsigned int mult = 1;
 	unsigned int div = 1;
+	struct clk *parent;
 
 	parent = clks[core->parent];
 	if (IS_ERR(parent))
diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
index 3cec0f501b94..c50aa1a49196 100644
--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
@@ -218,11 +218,13 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
 }
 
 static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
-	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers)
+	const struct cpg_core_clk *core,
+	const struct cpg_mssr_info *info,
+	struct cpg_mssr_pub *pub)
 {
 	const struct clk_div_table *table;
+	void __iomem *base = pub->base0;
+	struct clk **clks = pub->clks;
 	const struct clk *parent;
 	unsigned int shift;
 
@@ -236,8 +238,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
 		shift = 4;
 		break;
 	default:
-		return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
-						  notifiers);
+		return rcar_gen3_cpg_clk_register(dev, core, info, pub);
 	}
 
 	parent = clks[core->parent];
diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c
index 4c3764972bad..ab34bb8c3e07 100644
--- a/drivers/clk/renesas/rcar-gen2-cpg.c
+++ b/drivers/clk/renesas/rcar-gen2-cpg.c
@@ -274,10 +274,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
 
 struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev,
 	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers)
+	struct cpg_mssr_pub *pub)
 {
 	const struct clk_div_table *table = NULL;
+	void __iomem *base = pub->base0;
+	struct clk **clks = pub->clks;
 	const struct clk *parent;
 	const char *parent_name;
 	unsigned int mult = 1;
diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h
index bdcd4a38d48d..3d4b127fdeaf 100644
--- a/drivers/clk/renesas/rcar-gen2-cpg.h
+++ b/drivers/clk/renesas/rcar-gen2-cpg.h
@@ -32,8 +32,7 @@ struct rcar_gen2_cpg_pll_config {
 
 struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
 	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers);
+	struct cpg_mssr_pub *pub);
 int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config,
 		       unsigned int pll0_div, u32 mode);
 
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index 027100e84ee4..10ae20489df9 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -345,9 +345,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
 
 struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
 	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers)
+	struct cpg_mssr_pub *pub)
 {
+	struct raw_notifier_head *notifiers = &pub->notifiers;
+	void __iomem *base = pub->base0;
+	struct clk **clks = pub->clks;
 	const struct clk *parent;
 	unsigned int mult = 1;
 	unsigned int div = 1;
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index bfdc649bdf12..6ad560fca01b 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -80,9 +80,9 @@ struct rcar_gen3_cpg_pll_config {
 #define CPG_RCKCR	0x240
 
 struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
-	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers);
+	const struct cpg_core_clk *core,
+	const struct cpg_mssr_info *info,
+	struct cpg_mssr_pub *pub);
 int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
 		       unsigned int clk_extalr, u32 mode);
 
diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c
index 31aa790fd003..877626bbe7e1 100644
--- a/drivers/clk/renesas/rcar-gen4-cpg.c
+++ b/drivers/clk/renesas/rcar-gen4-cpg.c
@@ -418,9 +418,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = {
 
 struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
 	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers)
+	struct cpg_mssr_pub *pub)
 {
+	struct raw_notifier_head *notifiers = &pub->notifiers;
+	void __iomem *base = pub->base0;
+	struct clk **clks = pub->clks;
 	const struct clk *parent;
 	unsigned int mult = 1;
 	unsigned int div = 1;
@@ -517,7 +519,7 @@ struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
 
 	case CLK_TYPE_GEN4_RPC:
 		return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR,
-					    __clk_get_name(parent), notifiers);
+					    __clk_get_name(parent), &pub->notifiers);
 
 	case CLK_TYPE_GEN4_RPCD2:
 		return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR,
diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h
index 717fd148464f..6c8280b37c37 100644
--- a/drivers/clk/renesas/rcar-gen4-cpg.h
+++ b/drivers/clk/renesas/rcar-gen4-cpg.h
@@ -78,8 +78,7 @@ struct rcar_gen4_cpg_pll_config {
 
 struct clk *rcar_gen4_cpg_clk_register(struct device *dev,
 	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-	struct clk **clks, void __iomem *base,
-	struct raw_notifier_head *notifiers);
+	struct cpg_mssr_pub *pub);
 int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config,
 		       unsigned int clk_extalr, u32 mode);
 
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index da021ee446ec..4bdfa4f65ab4 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -127,14 +127,12 @@ static const u16 srstclr_for_gen4[] = {
  *
  * @rcdev: Optional reset controller entity
  * @dev: CPG/MSSR device
- * @base: CPG/MSSR register block base address
  * @reg_layout: CPG/MSSR register layout
  * @rmw_lock: protects RMW register accesses
  * @np: Device node in DT for this CPG/MSSR module
  * @num_core_clks: Number of Core Clocks in clks[]
  * @num_mod_clks: Number of Module Clocks in clks[]
  * @last_dt_core_clk: ID of the last Core Clock exported to DT
- * @notifiers: Notifier chain to save/restore clock state for system resume
  * @status_regs: Pointer to status registers array
  * @control_regs: Pointer to control registers array
  * @reset_regs: Pointer to reset registers array
@@ -143,6 +141,7 @@ static const u16 srstclr_for_gen4[] = {
  *                 [].val: Saved values of SMSTPCR[]
  * @reserved_ids: Temporary used, reserved id list
  * @num_reserved_ids: Temporary used, number of reserved id list
+ * @pub: Data passed to clock registration callback
  * @clks: Array containing all Core and Module Clocks
  */
 struct cpg_mssr_priv {
@@ -150,16 +149,13 @@ struct cpg_mssr_priv {
 	struct reset_controller_dev rcdev;
 #endif
 	struct device *dev;
-	void __iomem *base;
 	enum clk_reg_layout reg_layout;
-	spinlock_t rmw_lock;
 	struct device_node *np;
 
 	unsigned int num_core_clks;
 	unsigned int num_mod_clks;
 	unsigned int last_dt_core_clk;
 
-	struct raw_notifier_head notifiers;
 	const u16 *status_regs;
 	const u16 *control_regs;
 	const u16 *reset_regs;
@@ -172,6 +168,7 @@ struct cpg_mssr_priv {
 	unsigned int *reserved_ids;
 	unsigned int num_reserved_ids;
 
+	struct cpg_mssr_pub pub;
 	struct clk *clks[];
 };
 
@@ -205,38 +202,39 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
 
 	dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
 		enable ? "ON" : "OFF");
-	spin_lock_irqsave(&priv->rmw_lock, flags);
+	spin_lock_irqsave(&priv->pub.rmw_lock, flags);
 
 	if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
-		value = readb(priv->base + priv->control_regs[reg]);
+		value = readb(priv->pub.base0 + priv->control_regs[reg]);
 		if (enable)
 			value &= ~bitmask;
 		else
 			value |= bitmask;
-		writeb(value, priv->base + priv->control_regs[reg]);
+		writeb(value, priv->pub.base0 + priv->control_regs[reg]);
 
 		/* dummy read to ensure write has completed */
-		readb(priv->base + priv->control_regs[reg]);
-		barrier_data(priv->base + priv->control_regs[reg]);
+		readb(priv->pub.base0 + priv->control_regs[reg]);
+		barrier_data(priv->pub.base0 + priv->control_regs[reg]);
+
 	} else {
-		value = readl(priv->base + priv->control_regs[reg]);
+		value = readl(priv->pub.base0 + priv->control_regs[reg]);
 		if (enable)
 			value &= ~bitmask;
 		else
 			value |= bitmask;
-		writel(value, priv->base + priv->control_regs[reg]);
+		writel(value, priv->pub.base0 + priv->control_regs[reg]);
 	}
 
-	spin_unlock_irqrestore(&priv->rmw_lock, flags);
+	spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
 
 	if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
 		return 0;
 
-	error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
+	error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
 					  value, !(value & bitmask), 0, 10);
 	if (error)
 		dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
-			priv->base + priv->control_regs[reg], bit);
+			priv->pub.base0 + priv->control_regs[reg], bit);
 
 	return error;
 }
@@ -255,12 +253,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
 {
 	struct mstp_clock *clock = to_mstp_clock(hw);
 	struct cpg_mssr_priv *priv = clock->priv;
+	unsigned int reg = clock->index / 32;
 	u32 value;
 
 	if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
-		value = readb(priv->base + priv->control_regs[clock->index / 32]);
+		value = readb(priv->pub.base0 + priv->control_regs[reg]);
 	else
-		value = readl(priv->base + priv->status_regs[clock->index / 32]);
+		value = readl(priv->pub.base0 + priv->status_regs[reg]);
 
 	return !(value & BIT(clock->index % 32));
 }
@@ -347,7 +346,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 	case CLK_TYPE_DIV6P1:
 	case CLK_TYPE_DIV6_RO:
 		WARN_DEBUG(core->parent >= priv->num_core_clks);
-		parent = priv->clks[core->parent];
+		parent = priv->pub.clks[core->parent];
 		if (IS_ERR(parent)) {
 			clk = parent;
 			goto fail;
@@ -357,12 +356,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 
 		if (core->type == CLK_TYPE_DIV6_RO)
 			/* Multiply with the DIV6 register value */
-			div *= (readl(priv->base + core->offset) & 0x3f) + 1;
+			div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1;
 
 		if (core->type == CLK_TYPE_DIV6P1) {
 			clk = cpg_div6_register(core->name, 1, &parent_name,
-						priv->base + core->offset,
-						&priv->notifiers);
+						priv->pub.base0 + core->offset,
+						&priv->pub.notifiers);
 		} else {
 			clk = clk_register_fixed_factor(NULL, core->name,
 							parent_name, 0,
@@ -378,8 +377,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 	default:
 		if (info->cpg_clk_register)
 			clk = info->cpg_clk_register(dev, core, info,
-						     priv->clks, priv->base,
-						     &priv->notifiers);
+						     &priv->pub);
 		else
 			dev_err(dev, "%s has unsupported core clock type %u\n",
 				core->name, core->type);
@@ -390,7 +388,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 		goto fail;
 
 	dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
-	priv->clks[id] = clk;
+	priv->pub.clks[id] = clk;
 	return;
 
 fail:
@@ -413,14 +411,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
 	WARN_DEBUG(id < priv->num_core_clks);
 	WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
 	WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
-	WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
+	WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT);
 
 	if (!mod->name) {
 		/* Skip NULLified clock */
 		return;
 	}
 
-	parent = priv->clks[mod->parent];
+	parent = priv->pub.clks[mod->parent];
 	if (IS_ERR(parent)) {
 		clk = parent;
 		goto fail;
@@ -622,13 +620,13 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
 	dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
 
 	/* Reset module */
-	writel(bitmask, priv->base + priv->reset_regs[reg]);
+	writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
 
 	/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
 	udelay(35);
 
 	/* Release module from reset state */
-	writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
+	writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
 
 	return 0;
 }
@@ -642,7 +640,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
 
 	dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
 
-	writel(bitmask, priv->base + priv->reset_regs[reg]);
+	writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
 	return 0;
 }
 
@@ -656,7 +654,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
 
 	dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
 
-	writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
+	writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
 	return 0;
 }
 
@@ -668,7 +666,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev,
 	unsigned int bit = id % 32;
 	u32 bitmask = BIT(bit);
 
-	return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
+	return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask);
 }
 
 static const struct reset_control_ops cpg_mssr_reset_ops = {
@@ -894,12 +892,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
 		if (priv->smstpcr_saved[reg].mask)
 			priv->smstpcr_saved[reg].val =
 				priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
-				readb(priv->base + priv->control_regs[reg]) :
-				readl(priv->base + priv->control_regs[reg]);
+				readb(priv->pub.base0 + priv->control_regs[reg]) :
+				readl(priv->pub.base0 + priv->control_regs[reg]);
 	}
 
 	/* Save core clocks */
-	raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL);
+	raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL);
 
 	return 0;
 }
@@ -916,7 +914,7 @@ static int cpg_mssr_resume_noirq(struct device *dev)
 		return 0;
 
 	/* Restore core clocks */
-	raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL);
+	raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL);
 
 	/* Restore module clocks */
 	for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
@@ -925,29 +923,29 @@ static int cpg_mssr_resume_noirq(struct device *dev)
 			continue;
 
 		if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
-			oldval = readb(priv->base + priv->control_regs[reg]);
+			oldval = readb(priv->pub.base0 + priv->control_regs[reg]);
 		else
-			oldval = readl(priv->base + priv->control_regs[reg]);
+			oldval = readl(priv->pub.base0 + priv->control_regs[reg]);
 		newval = oldval & ~mask;
 		newval |= priv->smstpcr_saved[reg].val & mask;
 		if (newval == oldval)
 			continue;
 
 		if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
-			writeb(newval, priv->base + priv->control_regs[reg]);
+			writeb(newval, priv->pub.base0 + priv->control_regs[reg]);
 			/* dummy read to ensure write has completed */
-			readb(priv->base + priv->control_regs[reg]);
-			barrier_data(priv->base + priv->control_regs[reg]);
+			readb(priv->pub.base0 + priv->control_regs[reg]);
+			barrier_data(priv->pub.base0 + priv->control_regs[reg]);
 			continue;
 		} else
-			writel(newval, priv->base + priv->control_regs[reg]);
+			writel(newval, priv->pub.base0 + priv->control_regs[reg]);
 
 		/* Wait until enabled clocks are really enabled */
 		mask &= ~priv->smstpcr_saved[reg].val;
 		if (!mask)
 			continue;
 
-		error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
+		error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
 						oldval, !(oldval & mask), 0, 10);
 		if (error)
 			dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg,
@@ -1057,12 +1055,13 @@ static int __init cpg_mssr_common_init(struct device *dev,
 	if (!priv)
 		return -ENOMEM;
 
+	priv->pub.clks = priv->clks;
 	priv->np = np;
 	priv->dev = dev;
-	spin_lock_init(&priv->rmw_lock);
+	spin_lock_init(&priv->pub.rmw_lock);
 
-	priv->base = of_iomap(np, 0);
-	if (!priv->base) {
+	priv->pub.base0 = of_iomap(np, 0);
+	if (!priv->pub.base0) {
 		error = -ENOMEM;
 		goto out_err;
 	}
@@ -1070,7 +1069,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
 	priv->num_core_clks = info->num_total_core_clks;
 	priv->num_mod_clks = info->num_hw_mod_clks;
 	priv->last_dt_core_clk = info->last_dt_core_clk;
-	RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
+	RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers);
 	priv->reg_layout = info->reg_layout;
 	if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
 		priv->status_regs = mstpsr;
@@ -1090,7 +1089,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
 	}
 
 	for (i = 0; i < nclks; i++)
-		priv->clks[i] = ERR_PTR(-ENOENT);
+		priv->pub.clks[i] = ERR_PTR(-ENOENT);
 
 	error = cpg_mssr_reserved_init(priv, info);
 	if (error)
@@ -1107,8 +1106,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
 reserve_err:
 	cpg_mssr_reserved_exit(priv);
 out_err:
-	if (priv->base)
-		iounmap(priv->base);
+	if (priv->pub.base0)
+		iounmap(priv->pub.base0);
 	kfree(priv);
 
 	return error;
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index a1d6e0cbcff9..16337c5ed23e 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -8,6 +8,8 @@
 #ifndef __CLK_RENESAS_CPG_MSSR_H__
 #define __CLK_RENESAS_CPG_MSSR_H__
 
+#include <linux/notifier.h>
+
     /*
      * Definitions of CPG Core Clocks
      *
@@ -27,6 +29,21 @@ struct cpg_core_clk {
 	unsigned int div;
 	unsigned int mult;
 	unsigned int offset;
+
+/**
+ * struct cpg_mssr_pub - Private data shared with
+ * device-specific clk registration code
+ *
+ * @base0: CPG/MSSR register block base0 address
+ * @rmw_lock: protects RMW register accesses
+ * @notifiers: Notifier chain to save/restore clock state for system resume
+ * @clks: pointer to clocks
+ */
+struct cpg_mssr_pub {
+	void __iomem *base0;
+	struct raw_notifier_head notifiers;
+	spinlock_t rmw_lock;
+	struct clk **clks;
 };
 
 enum clk_types {
@@ -153,8 +170,7 @@ struct cpg_mssr_info {
 	struct clk *(*cpg_clk_register)(struct device *dev,
 					const struct cpg_core_clk *core,
 					const struct cpg_mssr_info *info,
-					struct clk **clks, void __iomem *base,
-					struct raw_notifier_head *notifiers);
+					struct cpg_mssr_pub *pub);
 };
 
 extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (4 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-17 18:45   ` Geert Uytterhoeven
  2025-04-03 21:29 ` [PATCH v7 07/13] serial: sh-sci: Fix a comment about SCIFA Thierry Bultel
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	linux-kernel, linux-clk

RZ/T2H has 2 registers blocks at different addresses.

The clock tree has configurable dividers and mux selectors.
Add these new clock types, new register layout type, and
registration code for mux and div in registration callback.

Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4:
   - Add missing #include <bitfield.h> (reported by bot)
   - Add missing __iomem address space in cpg_rzt2h_addr_from_offset and
     return type (reported by bot)
   - fixed clocks: inverted 'mult' and 'div' parameters when using 
     the DEF_FIXED macro
---
 drivers/clk/renesas/Kconfig              |   5 +
 drivers/clk/renesas/Makefile             |   1 +
 drivers/clk/renesas/r9a09g077-cpg-mssr.c | 238 +++++++++++++++++++++++
 drivers/clk/renesas/renesas-cpg-mssr.c   |  56 +++++-
 drivers/clk/renesas/renesas-cpg-mssr.h   |  23 +++
 5 files changed, 322 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/renesas/r9a09g077-cpg-mssr.c

diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 5a4bc3f94d49..3f9c4deb4c25 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -42,6 +42,7 @@ config CLK_RENESAS
 	select CLK_R9A09G011 if ARCH_R9A09G011
 	select CLK_R9A09G047 if ARCH_R9A09G047
 	select CLK_R9A09G057 if ARCH_R9A09G057
+	select CLK_R9A09G077 if ARCH_R9A09G077
 	select CLK_SH73A0 if ARCH_SH73A0
 
 if CLK_RENESAS
@@ -203,6 +204,10 @@ config CLK_R9A09G057
        bool "RZ/V2H(P) clock support" if COMPILE_TEST
        select CLK_RZV2H
 
+config CLK_R9A09G077
+	bool "RZ/T2H clock support" if COMPILE_TEST
+	select CLK_RENESAS_CPG_MSSR
+
 config CLK_SH73A0
 	bool "SH-Mobile AG5 clock support" if COMPILE_TEST
 	select CLK_RENESAS_CPG_MSTP
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index 2d6e746939c4..3989515dfec3 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_R8A779A0)		+= r8a779a0-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A779F0)		+= r8a779f0-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A779G0)		+= r8a779g0-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A779H0)		+= r8a779h0-cpg-mssr.o
+obj-$(CONFIG_CLK_R9A09G077)		+= r9a09g077-cpg-mssr.o
 obj-$(CONFIG_CLK_R9A06G032)		+= r9a06g032-clocks.o
 obj-$(CONFIG_CLK_R9A07G043)		+= r9a07g043-cpg.o
 obj-$(CONFIG_CLK_R9A07G044)		+= r9a07g044-cpg.o
diff --git a/drivers/clk/renesas/r9a09g077-cpg-mssr.c b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
new file mode 100644
index 000000000000..b67dbf5d59d8
--- /dev/null
+++ b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r9a09g077 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ *
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
+#include "renesas-cpg-mssr.h"
+
+#define SCKCR		0x00
+#define SCKCR2		0x04
+#define SCKCR3		0x08
+#define SCKCR4		0x0C
+#define PMSEL		0x10
+#define PMSEL_PLL0	BIT(0)
+#define PMSEL_PLL2	BIT(2)
+#define PMSEL_PLL3	BIT(3)
+#define PLL0EN		BIT(0)
+#define PLL2EN		BIT(0)
+#define PLL3EN		BIT(0)
+#define PLL0MON		0x20
+#define PLL0EN_REG	0x30
+#define PLL0_SSC_CTR	0x34
+#define PLL1MON		0x40
+#define LOCOCR		0x70
+#define HIZCTRLEN	0x80
+#define PLL2MON		0x90
+#define PLL2EN_REG	0xA0
+#define PLL2_SSC_CTR	0xAC
+#define PLL3MON		0xB0
+#define PLL3EN_REG	0xC0
+#define PLL3_VCO_CTR0	0xC4
+#define PLL3_VCO_CTR1	0xC8
+#define PLL4MON		0xD0
+#define PHYSEL		BIT(21)
+
+#define MRCTLA		0x240
+#define MRCTLE		0x250
+#define MRCTLI		0x260
+#define MRCTLM		0x270
+
+#define DDIV_PACK(offset, bitpos, size) \
+		(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
+
+#define DIVCA55		DDIV_PACK(SCKCR2, 8, 4)
+#define DIVCA55S	DDIV_PACK(SCKCR2, 12, 1)
+#define DIVCR520	DDIV_PACK(SCKCR2, 2, 2)
+#define DIVCR521	DDIV_PACK(SCKCR2, 0, 2)
+#define DIVLCDC		DDIV_PACK(SCKCR3, 20, 3)
+#define DIVCKIO		DDIV_PACK(SCKCR, 16, 3)
+#define DIVETHPHY	DDIV_PACK(SCKCR, 21, 1)
+#define DIVCANFD	DDIV_PACK(SCKCR, 20, 1)
+#define DIVSPI0		DDIV_PACK(SCKCR3, 0, 2)
+#define DIVSPI1		DDIV_PACK(SCKCR3, 2, 2)
+#define DIVSPI2		DDIV_PACK(SCKCR3, 4, 2)
+#define DIVSPI3		DDIV_PACK(SCKCR2, 16, 2)
+
+#define SEL_PLL_PACK(offset, bitpos, size) \
+	(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
+
+#define SEL_PLL		SEL_PLL_PACK(SCKCR, 22, 1)
+
+#define GET_SHIFT(val)		FIELD_GET(GENMASK(19, 12), val)
+#define GET_WIDTH(val)		FIELD_GET(GENMASK(11, 8), val)
+#define GET_REG_OFFSET(val)	FIELD_GET(GENMASK(31, 20), val)
+
+enum clk_ids {
+	/* Core Clock Outputs exported to DT */
+	LAST_DT_CORE_CLK = R9A09G077_LCDC_CLKD,
+
+	/* External Input Clocks */
+	CLK_EXTAL,
+	CLK_LOCO,
+
+	/* Internal Core Clocks */
+	CLK_PLL0,
+	CLK_PLL1,
+	CLK_PLL2,
+	CLK_PLL3,
+	CLK_PLL4,
+	CLK_SEL_PLL0,
+	CLK_SEL_CLK_PLL0,
+	CLK_SEL_PLL1,
+	CLK_SEL_CLK_PLL1,
+	CLK_SEL_PLL2,
+	CLK_SEL_CLK_PLL2,
+	CLK_SEL_PLL4,
+	CLK_SEL_CLK_PLL4,
+	CLK_SEL_CLK_SRC,
+	CLK_SEL_EXTAL,
+	CLK_SEL_LOCO,
+	CLK_PLL3_INPUT,
+
+	/* Module Clocks */
+	MOD_CLK_BASE,
+};
+
+static const struct clk_div_table dtable_1_2[] = {
+	{0, 2},
+	{15, 1},
+	{0, 0},
+};
+
+/* Mux clock tables */
+static const char * const sel_clk_pll0[] = { ".sel_loco", ".sel_pll0" };
+static const char * const sel_clk_pll1[] = { ".sel_loco", ".sel_pll1" };
+static const char * const sel_clk_pll4[] = { ".sel_loco", ".sel_pll4" };
+
+static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
+	/* External Clock Inputs */
+	DEF_INPUT("extal", CLK_EXTAL),
+	DEF_INPUT("loco", CLK_LOCO),
+
+	/* Internal Core Clocks */
+	DEF_FIXED(".pll0", CLK_PLL0, CLK_EXTAL, 1, 48),
+	DEF_FIXED(".pll1", CLK_PLL1, CLK_EXTAL, 1, 40),
+	DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 1, 96),
+	DEF_FIXED(".sel_pll0", CLK_SEL_PLL0, CLK_PLL0, 1, 1),
+	DEF_MUX(".sel_clk_pll0", CLK_SEL_CLK_PLL0, SEL_PLL,
+		sel_clk_pll0, ARRAY_SIZE(sel_clk_pll0), 0, CLK_MUX_READ_ONLY),
+	DEF_FIXED(".sel_pll1", CLK_SEL_PLL1, CLK_PLL1, 1, 1),
+	DEF_MUX(".sel_clk_pll1", CLK_SEL_CLK_PLL1, SEL_PLL,
+		sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), 0, CLK_MUX_READ_ONLY),
+	DEF_FIXED(".sel_pll4", CLK_SEL_PLL4, CLK_PLL4, 1, 1),
+	DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL,
+		sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), 0, CLK_MUX_READ_ONLY),
+
+	/* Core output clk */
+	DEF_DIV("CA55", R9A09G077_CA55, CLK_SEL_CLK_PLL0, DIVCA55,
+		dtable_1_2, CLK_DIVIDER_HIWORD_MASK, 1),
+	DEF_FIXED("PCLKM", R9A09G077_PCLKM, CLK_SEL_CLK_PLL1, 8, 1),
+	DEF_FIXED("PCLKGPTL", R9A09G077_PCLKGPTL, CLK_SEL_CLK_PLL1, 2, 1),
+};
+
+static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
+	DEF_MOD("sci0", 108, R9A09G077_PCLKM),
+};
+
+static struct clk * __init
+r9a09g077_cpg_div_clk_register(struct device *dev,
+			       const struct cpg_core_clk *core,
+			       void __iomem *base,
+			       struct cpg_mssr_pub *pub)
+{
+	const struct clk *parent;
+	const char *parent_name;
+	struct clk_hw *clk_hw;
+
+	parent = pub->clks[core->parent];
+
+	if (IS_ERR(parent))
+		return ERR_CAST(parent);
+
+	parent_name = __clk_get_name(parent);
+
+	if (core->dtable)
+		clk_hw = clk_hw_register_divider_table(dev, core->name,
+						       parent_name, 0,
+						       base + GET_REG_OFFSET(core->conf),
+						       GET_SHIFT(core->conf),
+						       GET_WIDTH(core->conf),
+						       core->flag,
+						       core->dtable,
+						       &pub->rmw_lock);
+	else
+		clk_hw = clk_hw_register_divider(dev, core->name,
+						 parent_name, 0,
+						 base + GET_REG_OFFSET(core->conf),
+						 GET_SHIFT(core->conf),
+						 GET_WIDTH(core->conf),
+						 core->flag, &pub->rmw_lock);
+
+	if (IS_ERR(clk_hw))
+		return ERR_CAST(clk_hw);
+
+	return clk_hw->clk;
+
+}
+
+static struct clk * __init
+r9a09g077_cpg_mux_clk_register(struct device *dev,
+			       const struct cpg_core_clk *core,
+			       void __iomem *base,
+			       struct cpg_mssr_pub *pub)
+{
+	struct clk_hw *clk_hw;
+
+	clk_hw = devm_clk_hw_register_mux(dev, core->name,
+					  core->parent_names, core->num_parents,
+					  core->flag,
+					  base + GET_REG_OFFSET(core->conf),
+					  GET_SHIFT(core->conf),
+					  GET_WIDTH(core->conf),
+					  core->mux_flags, &pub->rmw_lock);
+	return clk_hw->clk;
+}
+
+static struct clk * __init
+r9a09g077_cpg_clk_register(struct device *dev,
+			   const struct cpg_core_clk *core,
+			   const struct cpg_mssr_info *info,
+			   struct cpg_mssr_pub *pub)
+{
+	void __iomem *base = core->sel_base ? pub->base1 : pub->base0;
+
+	switch (core->type) {
+	case CLK_TYPE_DIV:
+		return r9a09g077_cpg_div_clk_register(dev, core, base, pub);
+	case CLK_TYPE_MUX:
+		return r9a09g077_cpg_mux_clk_register(dev, core, base, pub);
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+}
+
+const struct cpg_mssr_info r9a09g077_cpg_mssr_info = {
+	/* Core Clocks */
+	.core_clks = r9a09g077_core_clks,
+	.num_core_clks = ARRAY_SIZE(r9a09g077_core_clks),
+	.last_dt_core_clk = LAST_DT_CORE_CLK,
+	.num_total_core_clks = MOD_CLK_BASE,
+
+	/* Module Clocks */
+	.mod_clks = r9a09g077_mod_clks,
+	.num_mod_clks = ARRAY_SIZE(r9a09g077_mod_clks),
+	.num_hw_mod_clks = 12 * 32,
+
+	.reg_layout = CLK_REG_LAYOUT_RZ_T2H,
+	.cpg_clk_register = r9a09g077_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 4bdfa4f65ab4..123bc1558e53 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -79,6 +79,27 @@ static const u16 mstpcr_for_gen4[] = {
 	0x2D60, 0x2D64, 0x2D68, 0x2D6C, 0x2D70, 0x2D74,
 };
 
+/*
+ * Module Stop Control Register (RZ/T2H)
+ * RZ/T2H has 2 registers blocks,
+ * Bit 12 is used to differentiate them
+ */
+
+#define RZT2H_MSTPCR_BLOCK_SHIFT	12
+#define RZT2H_MSTPCR_OFFSET_MASK	GENMASK(11, 0)
+#define RZT2H_MSTPCR(block, offset)	(((block) << RZT2H_MSTPCR_BLOCK_SHIFT) & \
+					((offset) & RZT2H_MSTPCR_OFFSET_MASK))
+
+#define RZT2H_MSTPCR_BLOCK(x)		((x) >> RZT2H_MSTPCR_BLOCK_SHIFT)
+#define RZT2H_MSTPCR_OFFSET(x)		((x) & RZT2H_MSTPCR_OFFSET_MASK)
+
+static const u16 mstpcr_for_rzt2h[] = {
+	RZT2H_MSTPCR(0, 0x300), RZT2H_MSTPCR(0, 0x304), RZT2H_MSTPCR(0, 0x308),
+	RZT2H_MSTPCR(0, 0x30c),	RZT2H_MSTPCR(0, 0x310), RZT2H_MSTPCR(1, 0x318),
+	RZT2H_MSTPCR(1, 0x320), RZT2H_MSTPCR(0, 0x324), RZT2H_MSTPCR(0, 0x328),
+	RZT2H_MSTPCR(0, 0x32c), RZT2H_MSTPCR(0, 0x330), RZT2H_MSTPCR(1, 0x334),
+};
+
 /*
  * Standby Control Register offsets (RZ/A)
  * Base address is FRQCR register
@@ -188,6 +209,15 @@ struct mstp_clock {
 
 #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
 
+static void __iomem *cpg_rzt2h_addr_from_offset(struct clk_hw *hw, u16 offset)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct cpg_mssr_priv *priv = clock->priv;
+	void __iomem *base = RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0;
+
+	return base + RZT2H_MSTPCR_OFFSET(offset);
+}
+
 static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
 {
 	struct mstp_clock *clock = to_mstp_clock(hw);
@@ -227,7 +257,8 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
 
 	spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
 
-	if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
+	if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
+		priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
 		return 0;
 
 	error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
@@ -258,6 +289,12 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
 
 	if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
 		value = readb(priv->pub.base0 + priv->control_regs[reg]);
+	else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
+		void __iomem *addr =
+			cpg_rzt2h_addr_from_offset(hw,
+						   priv->control_regs[reg]);
+		value = readw(addr);
+	}
 	else
 		value = readl(priv->pub.base0 + priv->status_regs[reg]);
 
@@ -868,6 +905,12 @@ static const struct of_device_id cpg_mssr_match[] = {
 		.compatible = "renesas,r8a779h0-cpg-mssr",
 		.data = &r8a779h0_cpg_mssr_info,
 	},
+#endif
+#ifdef CONFIG_CLK_R9A09G077
+	{
+		.compatible = "renesas,r9a09g077-cpg-mssr",
+		.data = &r9a09g077_cpg_mssr_info,
+	},
 #endif
 	{ /* sentinel */ }
 };
@@ -1065,6 +1108,13 @@ static int __init cpg_mssr_common_init(struct device *dev,
 		error = -ENOMEM;
 		goto out_err;
 	}
+	if (info->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
+		priv->pub.base1 = of_iomap(np, 1);
+		if (!priv->pub.base1) {
+			error = -ENOMEM;
+			goto out_err;
+		}
+	}
 
 	priv->num_core_clks = info->num_total_core_clks;
 	priv->num_mod_clks = info->num_hw_mod_clks;
@@ -1078,6 +1128,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
 		priv->reset_clear_regs = srstclr;
 	} else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
 		priv->control_regs = stbcr;
+	} else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
+		priv->control_regs = mstpcr_for_rzt2h;
 	} else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
 		priv->status_regs = mstpsr_for_gen4;
 		priv->control_regs = mstpcr_for_gen4;
@@ -1108,6 +1160,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
 out_err:
 	if (priv->pub.base0)
 		iounmap(priv->pub.base0);
+	if (priv->pub.base1)
+		iounmap(priv->pub.base1);
 	kfree(priv);
 
 	return error;
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index 16337c5ed23e..ccab4c1b216a 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -22,6 +22,8 @@
 struct cpg_core_clk {
 	/* Common */
 	const char *name;
+	const char * const *parent_names;
+	const struct clk_div_table *dtable;
 	unsigned int id;
 	unsigned int type;
 	/* Depending on type */
@@ -29,18 +31,26 @@ struct cpg_core_clk {
 	unsigned int div;
 	unsigned int mult;
 	unsigned int offset;
+	unsigned int conf;
+	int flag;
+	int mux_flags;
+	int num_parents;
+	int sel_base;
+};
 
 /**
  * struct cpg_mssr_pub - Private data shared with
  * device-specific clk registration code
  *
  * @base0: CPG/MSSR register block base0 address
+ * @base1: CPG/MSSR register block base1 address
  * @rmw_lock: protects RMW register accesses
  * @notifiers: Notifier chain to save/restore clock state for system resume
  * @clks: pointer to clocks
  */
 struct cpg_mssr_pub {
 	void __iomem *base0;
+	void __iomem *base1;
 	struct raw_notifier_head notifiers;
 	spinlock_t rmw_lock;
 	struct clk **clks;
@@ -53,6 +63,8 @@ enum clk_types {
 	CLK_TYPE_DIV6P1,	/* DIV6 Clock with 1 parent clock */
 	CLK_TYPE_DIV6_RO,	/* DIV6 Clock read only with extra divisor */
 	CLK_TYPE_FR,		/* Fixed Rate Clock */
+	CLK_TYPE_DIV,		/* Clock with divider */
+	CLK_TYPE_MUX,		/* Clock with clock source selector */
 
 	/* Custom definitions start here */
 	CLK_TYPE_CUSTOM,
@@ -73,6 +85,15 @@ enum clk_types {
 	DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
 #define DEF_RATE(_name, _id, _rate)	\
 	DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate)
+#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag, _sel_base) \
+	DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
+		 .parent = _parent, .dtable = _dtable, .flag = _flag, .sel_base = _sel_base)
+#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \
+		_mux_flags) \
+	DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
+		 .parent_names = _parent_names, .num_parents = _num_parents, \
+		 .flag = _flag, .mux_flags = _mux_flags)
+
 
     /*
      * Definitions of Module Clocks
@@ -106,6 +127,7 @@ enum clk_reg_layout {
 	CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
 	CLK_REG_LAYOUT_RZ_A,
 	CLK_REG_LAYOUT_RCAR_GEN4,
+	CLK_REG_LAYOUT_RZ_T2H,
 };
 
     /**
@@ -197,6 +219,7 @@ extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a779f0_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a779g0_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a779h0_cpg_mssr_info;
+extern const struct cpg_mssr_info r9a09g077_cpg_mssr_info;
 
 void __init cpg_mssr_early_init(struct device_node *np,
 				const struct cpg_mssr_info *info);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 07/13] serial: sh-sci: Fix a comment about SCIFA
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (5 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 08/13] serial: sh-sci: Introduced function pointers Thierry Bultel
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Wolfram Sang, Geert Uytterhoeven, linux-kernel, linux-serial

The comment was correct when it was added, at that time RZ/T1 was
the only SoC in the RZ/T line. Since then, further SoCs have been
added with RZ/T names which do not use the same SCIFA register
layout and so the comment is now misleading.

So we update the comment to explicitly reference only RZ/T1 SoCs.

Reviewed-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4: none
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1c8480d0338e..d7a060033a89 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -310,7 +310,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 	},
 
 	/*
-	 * The "SCIFA" that is in RZ/A2, RZ/G2L and RZ/T.
+	 * The "SCIFA" that is in RZ/A2, RZ/G2L and RZ/T1.
 	 * It looks like a normal SCIF with FIFO data, but with a
 	 * compressed address space. Also, the break out of interrupts
 	 * are different: ERI/BRI, RXI, TXI, TEI, DRI.
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 08/13] serial: sh-sci: Introduced function pointers
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (6 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 07/13] serial: sh-sci: Fix a comment about SCIFA Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 09/13] serial: sh-sci: Introduced sci_of_data Thierry Bultel
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Geert Uytterhoeven, Wolfram Sang, linux-kernel, linux-serial

The aim here is to prepare support for new sci controllers like
the T2H/RSCI whose registers are too much different for being
handled in common code.

This named serial controller also has 32 bits register,
so some return types had to be changed.

The needed generic functions are no longer static, with prototypes
defined in sh-sci-common.h so that they can be used from specific
implementation in a separate file, to keep this driver as little
changed as possible.

For doing so, a set of 'ops' is added to struct sci_port.

Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: 
   - sci_shutdown is no longer static (systemd needs it)
Changes v3->v4:
   - Add missing #include <bitfield.h>
   - Remove sci_poll_get_char sci_poll_put_char from sh-sci-common.h (both 
     function are not used by rzsci yet).
   - Add missing #ifdef around .poll_put_char pointer initialization.
   - More registers to save & restore due to rebase on tty-next
---
 drivers/tty/serial/sh-sci-common.h | 159 ++++++++++
 drivers/tty/serial/sh-sci.c        | 484 +++++++++++++++--------------
 drivers/tty/serial/sh-sci.h        |   2 -
 3 files changed, 407 insertions(+), 238 deletions(-)
 create mode 100644 drivers/tty/serial/sh-sci-common.h

diff --git a/drivers/tty/serial/sh-sci-common.h b/drivers/tty/serial/sh-sci-common.h
new file mode 100644
index 000000000000..2ed742bca83f
--- /dev/null
+++ b/drivers/tty/serial/sh-sci-common.h
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __SH_SCI_COMMON_H__
+#define __SH_SCI_COMMON_H__
+
+#include <linux/serial_core.h>
+
+enum SCI_CLKS {
+	SCI_FCK,		/* Functional Clock */
+	SCI_SCK,		/* Optional External Clock */
+	SCI_BRG_INT,		/* Optional BRG Internal Clock Source */
+	SCI_SCIF_CLK,		/* Optional BRG External Clock Source */
+	SCI_NUM_CLKS
+};
+
+/* Offsets into the sci_port->irqs array */
+enum {
+	SCIx_ERI_IRQ,
+	SCIx_RXI_IRQ,
+	SCIx_TXI_IRQ,
+	SCIx_BRI_IRQ,
+	SCIx_DRI_IRQ,
+	SCIx_TEI_IRQ,
+	SCIx_NR_IRQS,
+
+	SCIx_MUX_IRQ = SCIx_NR_IRQS,	/* special case */
+};
+
+/* Bit x set means sampling rate x + 1 is supported */
+#define SCI_SR(x)		BIT((x) - 1)
+#define SCI_SR_RANGE(x, y)	GENMASK((y) - 1, (x) - 1)
+
+void sci_release_port(struct uart_port *port);
+int sci_request_port(struct uart_port *port);
+void sci_config_port(struct uart_port *port, int flags);
+int sci_verify_port(struct uart_port *port, struct serial_struct *ser);
+void sci_pm(struct uart_port *port, unsigned int state,
+		   unsigned int oldstate);
+
+struct plat_sci_reg {
+	u8 offset;
+	u8 size;
+};
+
+struct sci_port_params_bits {
+	unsigned int rxtx_enable;
+	unsigned int te_clear;
+	unsigned int poll_sent_bits;
+};
+
+struct sci_common_regs {
+	unsigned int status;
+	unsigned int control;
+};
+
+/* The actual number of needed registers. This is used by sci only */
+#define SCI_NR_REGS 20
+
+struct sci_port_params {
+	const struct plat_sci_reg regs[SCI_NR_REGS];
+	const struct sci_common_regs *common_regs;
+	const struct sci_port_params_bits *param_bits;
+	unsigned int fifosize;
+	unsigned int overrun_reg;
+	unsigned int overrun_mask;
+	unsigned int sampling_rate_mask;
+	unsigned int error_mask;
+	unsigned int error_clear;
+};
+
+struct sci_port_ops {
+	u32 (*read_reg)(struct uart_port *port, int reg);
+	void (*write_reg)(struct uart_port *port, int reg, int value);
+	void (*clear_SCxSR)(struct uart_port *port, unsigned int mask);
+
+	void (*transmit_chars)(struct uart_port *port);
+	void (*receive_chars)(struct uart_port *port);
+
+	void (*poll_put_char)(struct uart_port *port, unsigned char c);
+
+	int (*set_rtrg)(struct uart_port *port, int rx_trig);
+	int (*rtrg_enabled)(struct uart_port *port);
+
+	void (*shutdown_complete)(struct uart_port *port);
+
+	void (*prepare_console_write)(struct uart_port *port, u32 ctrl);
+	void (*console_save)(struct uart_port *port);
+	void (*console_restore)(struct uart_port *port);
+	size_t (*suspend_regs_size)(void);
+};
+
+struct sci_port {
+	struct uart_port	port;
+
+	/* Platform configuration */
+	const struct sci_port_params *params;
+	const struct plat_sci_port *cfg;
+
+	unsigned int		sampling_rate_mask;
+	resource_size_t		reg_size;
+	struct mctrl_gpios	*gpios;
+
+	/* Clocks */
+	struct clk		*clks[SCI_NUM_CLKS];
+	unsigned long		clk_rates[SCI_NUM_CLKS];
+
+	int			irqs[SCIx_NR_IRQS];
+	char			*irqstr[SCIx_NR_IRQS];
+
+	struct dma_chan			*chan_tx;
+	struct dma_chan			*chan_rx;
+
+	struct reset_control		*rstc;
+	struct sci_suspend_regs		*suspend_regs;
+
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+	struct dma_chan			*chan_tx_saved;
+	struct dma_chan			*chan_rx_saved;
+	dma_cookie_t			cookie_tx;
+	dma_cookie_t			cookie_rx[2];
+	dma_cookie_t			active_rx;
+	dma_addr_t			tx_dma_addr;
+	unsigned int			tx_dma_len;
+	struct scatterlist		sg_rx[2];
+	void				*rx_buf[2];
+	size_t				buf_len_rx;
+	struct work_struct		work_tx;
+	struct hrtimer			rx_timer;
+	unsigned int			rx_timeout;	/* microseconds */
+#endif
+	unsigned int			rx_frame;
+	int				rx_trigger;
+	struct timer_list		rx_fifo_timer;
+	int				rx_fifo_timeout;
+	u16				hscif_tot;
+
+	const struct sci_port_ops *ops;
+
+	bool has_rtscts;
+	bool autorts;
+	bool tx_occurred;
+};
+
+#define to_sci_port(uart) container_of((uart), struct sci_port, port)
+
+void sci_port_disable(struct sci_port *sci_port);
+void sci_port_enable(struct sci_port *sci_port);
+
+int sci_startup(struct uart_port *port);
+void sci_shutdown(struct uart_port *port);
+
+#define min_sr(_port)		ffs((_port)->sampling_rate_mask)
+#define max_sr(_port)		fls((_port)->sampling_rate_mask)
+
+#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
+int __init scix_early_console_setup(struct earlycon_device *device, int);
+#endif
+
+#endif /* __SH_SCI_COMMON_H__ */
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index d7a060033a89..54a484b04a97 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -56,19 +56,7 @@
 
 #include "serial_mctrl_gpio.h"
 #include "sh-sci.h"
-
-/* Offsets into the sci_port->irqs array */
-enum {
-	SCIx_ERI_IRQ,
-	SCIx_RXI_IRQ,
-	SCIx_TXI_IRQ,
-	SCIx_BRI_IRQ,
-	SCIx_DRI_IRQ,
-	SCIx_TEI_IRQ,
-	SCIx_NR_IRQS,
-
-	SCIx_MUX_IRQ = SCIx_NR_IRQS,	/* special case */
-};
+#include "sh-sci-common.h"
 
 #define SCIx_IRQ_IS_MUXED(port)			\
 	((port)->irqs[SCIx_ERI_IRQ] ==	\
@@ -76,32 +64,38 @@ enum {
 	((port)->irqs[SCIx_ERI_IRQ] &&	\
 	 ((port)->irqs[SCIx_RXI_IRQ] < 0))
 
-enum SCI_CLKS {
-	SCI_FCK,		/* Functional Clock */
-	SCI_SCK,		/* Optional External Clock */
-	SCI_BRG_INT,		/* Optional BRG Internal Clock Source */
-	SCI_SCIF_CLK,		/* Optional BRG External Clock Source */
-	SCI_NUM_CLKS
-};
-
-/* Bit x set means sampling rate x + 1 is supported */
-#define SCI_SR(x)		BIT((x) - 1)
-#define SCI_SR_RANGE(x, y)	GENMASK((y) - 1, (x) - 1)
-
 #define SCI_SR_SCIFAB		SCI_SR(5) | SCI_SR(7) | SCI_SR(11) | \
 				SCI_SR(13) | SCI_SR(16) | SCI_SR(17) | \
 				SCI_SR(19) | SCI_SR(27)
 
-#define min_sr(_port)		ffs((_port)->sampling_rate_mask)
-#define max_sr(_port)		fls((_port)->sampling_rate_mask)
-
 /* Iterate over all supported sampling rates, from high to low */
 #define for_each_sr(_sr, _port)						\
 	for ((_sr) = max_sr(_port); (_sr) >= min_sr(_port); (_sr)--)	\
 		if ((_port)->sampling_rate_mask & SCI_SR((_sr)))
 
-struct plat_sci_reg {
-	u8 offset, size;
+#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
+
+static struct sci_port sci_ports[SCI_NPORTS];
+static unsigned long sci_ports_in_use;
+static struct uart_driver sci_uart_driver;
+static bool sci_uart_earlycon;
+static bool sci_uart_earlycon_dev_probing;
+
+static const struct sci_port_params_bits sci_sci_port_params_bits = {
+	.rxtx_enable = SCSCR_RE | SCSCR_TE,
+	.te_clear = SCSCR_TE | SCSCR_TEIE,
+	.poll_sent_bits = SCI_TDRE | SCI_TEND
+};
+
+static const struct sci_port_params_bits sci_scif_port_params_bits = {
+	.rxtx_enable = SCSCR_RE | SCSCR_TE,
+	.te_clear = SCSCR_TE | SCSCR_TEIE,
+	.poll_sent_bits = SCIF_TDFE | SCIF_TEND
+};
+
+static const struct sci_common_regs sci_common_regs = {
+	.status = SCxSR,
+	.control = SCSCR,
 };
 
 struct sci_suspend_regs {
@@ -118,77 +112,9 @@ struct sci_suspend_regs {
 	u8 semr;
 };
 
-struct sci_port_params {
-	const struct plat_sci_reg regs[SCIx_NR_REGS];
-	unsigned int fifosize;
-	unsigned int overrun_reg;
-	unsigned int overrun_mask;
-	unsigned int sampling_rate_mask;
-	unsigned int error_mask;
-	unsigned int error_clear;
-};
-
-struct sci_port {
-	struct uart_port	port;
-
-	/* Platform configuration */
-	const struct sci_port_params *params;
-	const struct plat_sci_port *cfg;
-	unsigned int		sampling_rate_mask;
-	resource_size_t		reg_size;
-	struct mctrl_gpios	*gpios;
-
-	/* Clocks */
-	struct clk		*clks[SCI_NUM_CLKS];
-	unsigned long		clk_rates[SCI_NUM_CLKS];
-
-	int			irqs[SCIx_NR_IRQS];
-	char			*irqstr[SCIx_NR_IRQS];
-
-	struct dma_chan			*chan_tx;
-	struct dma_chan			*chan_rx;
-
-	struct reset_control		*rstc;
-
-#ifdef CONFIG_SERIAL_SH_SCI_DMA
-	struct dma_chan			*chan_tx_saved;
-	struct dma_chan			*chan_rx_saved;
-	dma_cookie_t			cookie_tx;
-	dma_cookie_t			cookie_rx[2];
-	dma_cookie_t			active_rx;
-	dma_addr_t			tx_dma_addr;
-	unsigned int			tx_dma_len;
-	struct scatterlist		sg_rx[2];
-	void				*rx_buf[2];
-	size_t				buf_len_rx;
-	struct work_struct		work_tx;
-	struct hrtimer			rx_timer;
-	unsigned int			rx_timeout;	/* microseconds */
-#endif
-	unsigned int			rx_frame;
-	int				rx_trigger;
-	struct timer_list		rx_fifo_timer;
-	int				rx_fifo_timeout;
-	struct sci_suspend_regs		suspend_regs;
-	u16				hscif_tot;
-
-	bool has_rtscts;
-	bool autorts;
-	bool tx_occurred;
-};
-
-#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
-
-static struct sci_port sci_ports[SCI_NPORTS];
-static unsigned long sci_ports_in_use;
-static struct uart_driver sci_uart_driver;
-static bool sci_uart_earlycon;
-static bool sci_uart_earlycon_dev_probing;
-
-static inline struct sci_port *
-to_sci_port(struct uart_port *uart)
+static size_t sci_suspend_regs_size(void)
 {
-	return container_of(uart, struct sci_port, port);
+	return sizeof(struct sci_suspend_regs);
 }
 
 static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
@@ -211,6 +137,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCI_DEFAULT_ERROR_MASK | SCI_ORER,
 		.error_clear = SCI_ERROR_CLEAR & ~SCI_ORER,
+		.param_bits = &sci_sci_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -233,6 +161,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCI_DEFAULT_ERROR_MASK | SCI_ORER,
 		.error_clear = SCI_ERROR_CLEAR & ~SCI_ORER,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -257,6 +187,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR_SCIFAB,
 		.error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER,
 		.error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -282,6 +214,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR_SCIFAB,
 		.error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER,
 		.error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -307,6 +241,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -335,6 +271,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -366,6 +304,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -388,6 +328,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -412,6 +354,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -439,6 +383,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -468,6 +414,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR_RANGE(8, 32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -492,6 +440,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -519,6 +469,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(32),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK,
 		.error_clear = SCIF_ERROR_CLEAR,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 
 	/*
@@ -542,6 +494,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 		.sampling_rate_mask = SCI_SR(16),
 		.error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER,
 		.error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER,
+		.param_bits = &sci_scif_port_params_bits,
+		.common_regs = &sci_common_regs,
 	},
 };
 
@@ -579,7 +533,7 @@ static void sci_serial_out(struct uart_port *p, int offset, int value)
 		WARN(1, "Invalid register access\n");
 }
 
-static void sci_port_enable(struct sci_port *sci_port)
+void sci_port_enable(struct sci_port *sci_port)
 {
 	unsigned int i;
 
@@ -595,7 +549,7 @@ static void sci_port_enable(struct sci_port *sci_port)
 	sci_port->port.uartclk = sci_port->clk_rates[SCI_FCK];
 }
 
-static void sci_port_disable(struct sci_port *sci_port)
+void sci_port_disable(struct sci_port *sci_port)
 {
 	unsigned int i;
 
@@ -735,12 +689,13 @@ static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask)
 static int sci_poll_get_char(struct uart_port *port)
 {
 	unsigned short status;
+	struct sci_port *s = to_sci_port(port);
 	int c;
 
 	do {
 		status = sci_serial_in(port, SCxSR);
 		if (status & SCxSR_ERRORS(port)) {
-			sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
+			s->ops->clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 			continue;
 		}
 		break;
@@ -753,7 +708,7 @@ static int sci_poll_get_char(struct uart_port *port)
 
 	/* Dummy read */
 	sci_serial_in(port, SCxSR);
-	sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
+	s->ops->clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 
 	return c;
 }
@@ -761,14 +716,16 @@ static int sci_poll_get_char(struct uart_port *port)
 
 static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 {
-	unsigned short status;
+	struct sci_port *s = to_sci_port(port);
+	const struct sci_common_regs *regs = s->params->common_regs;
+	unsigned int status;
 
 	do {
-		status = sci_serial_in(port, SCxSR);
+		status = s->ops->read_reg(port, regs->status);
 	} while (!(status & SCxSR_TDxE(port)));
 
 	sci_serial_out(port, SCxTDR, c);
-	sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
+	s->ops->clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
 }
 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE ||
 	  CONFIG_SERIAL_SH_SCI_EARLYCON */
@@ -911,7 +868,7 @@ static void sci_transmit_chars(struct uart_port *port)
 		port->icount.tx++;
 	} while (--count > 0);
 
-	sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
+	s->ops->clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
 
 	if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
@@ -930,6 +887,7 @@ static void sci_transmit_chars(struct uart_port *port)
 static void sci_receive_chars(struct uart_port *port)
 {
 	struct tty_port *tport = &port->state->port;
+	struct sci_port *s = to_sci_port(port);
 	int i, count, copied = 0;
 	unsigned short status;
 	unsigned char flag;
@@ -984,7 +942,7 @@ static void sci_receive_chars(struct uart_port *port)
 		}
 
 		sci_serial_in(port, SCxSR); /* dummy read */
-		sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
+		s->ops->clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 
 		copied += count;
 		port->icount.rx += count;
@@ -997,16 +955,17 @@ static void sci_receive_chars(struct uart_port *port)
 		/* TTY buffers full; read from RX reg to prevent lockup */
 		sci_serial_in(port, SCxRDR);
 		sci_serial_in(port, SCxSR); /* dummy read */
-		sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
+		s->ops->clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 	}
 }
 
 static int sci_handle_errors(struct uart_port *port)
 {
 	int copied = 0;
-	unsigned short status = sci_serial_in(port, SCxSR);
-	struct tty_port *tport = &port->state->port;
 	struct sci_port *s = to_sci_port(port);
+	const struct sci_common_regs *regs = s->params->common_regs;
+	unsigned int status = s->ops->read_reg(port, regs->status);
+	struct tty_port *tport = &port->state->port;
 
 	/* Handle overruns */
 	if (status & s->params->overrun_mask) {
@@ -1165,7 +1124,7 @@ static void rx_fifo_timer_fn(struct timer_list *t)
 	struct uart_port *port = &s->port;
 
 	dev_dbg(port->dev, "Rx timed out\n");
-	scif_set_rtrg(port, 1);
+	s->ops->set_rtrg(port, 1);
 }
 
 static ssize_t rx_fifo_trigger_show(struct device *dev,
@@ -1190,9 +1149,9 @@ static ssize_t rx_fifo_trigger_store(struct device *dev,
 	if (ret)
 		return ret;
 
-	sci->rx_trigger = scif_set_rtrg(port, r);
+	sci->rx_trigger = sci->ops->set_rtrg(port, r);
 	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
-		scif_set_rtrg(port, 1);
+		sci->ops->set_rtrg(port, 1);
 
 	return count;
 }
@@ -1235,7 +1194,7 @@ static ssize_t rx_fifo_timeout_store(struct device *dev,
 		sci->hscif_tot = r << HSSCR_TOT_SHIFT;
 	} else {
 		sci->rx_fifo_timeout = r;
-		scif_set_rtrg(port, 1);
+		sci->ops->set_rtrg(port, 1);
 		if (r > 0)
 			timer_setup(&sci->rx_fifo_timer, rx_fifo_timer_fn, 0);
 	}
@@ -1360,7 +1319,7 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
 	    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
 		enable_irq(s->irqs[SCIx_RXI_IRQ]);
 		if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
-			scif_set_rtrg(port, s->rx_trigger);
+			s->ops->set_rtrg(port, s->rx_trigger);
 		else
 			scr &= ~SCSCR_RDRQE;
 	}
@@ -1798,7 +1757,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 		    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
 			disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
 			if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
-				scif_set_rtrg(port, 1);
+				s->ops->set_rtrg(port, 1);
 				scr |= SCSCR_RIE;
 			} else {
 				scr |= SCSCR_RDRQE;
@@ -1824,8 +1783,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 #endif
 
 	if (s->rx_trigger > 1 && s->rx_fifo_timeout > 0) {
-		if (!scif_rtrg_enabled(port))
-			scif_set_rtrg(port, s->rx_trigger);
+		if (!s->ops->rtrg_enabled(port))
+			s->ops->set_rtrg(port, s->rx_trigger);
 
 		mod_timer(&s->rx_fifo_timer, jiffies + DIV_ROUND_UP(
 			  s->rx_frame * HZ * s->rx_fifo_timeout, 1000000));
@@ -1835,7 +1794,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 	 * of whether the I_IXOFF is set, otherwise, how is the interrupt
 	 * to be disabled?
 	 */
-	sci_receive_chars(port);
+	s->ops->receive_chars(port);
 
 	return IRQ_HANDLED;
 }
@@ -1844,9 +1803,10 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
 	unsigned long flags;
+	struct sci_port *s = to_sci_port(port);
 
 	uart_port_lock_irqsave(port, &flags);
-	sci_transmit_chars(port);
+	s->ops->transmit_chars(port);
 	uart_port_unlock_irqrestore(port, flags);
 
 	return IRQ_HANDLED;
@@ -1855,16 +1815,18 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
+	struct sci_port *s = to_sci_port(port);
+	const struct sci_common_regs *regs = s->params->common_regs;
 	unsigned long flags;
-	unsigned short ctrl;
+	u32 ctrl;
 
 	if (port->type != PORT_SCI)
 		return sci_tx_interrupt(irq, ptr);
 
 	uart_port_lock_irqsave(port, &flags);
-	ctrl = sci_serial_in(port, SCSCR);
-	ctrl &= ~(SCSCR_TE | SCSCR_TEIE);
-	sci_serial_out(port, SCSCR, ctrl);
+	ctrl = s->ops->read_reg(port, regs->control) &
+		~(s->params->param_bits->te_clear);
+	s->ops->write_reg(port, regs->control, ctrl);
 	uart_port_unlock_irqrestore(port, flags);
 
 	return IRQ_HANDLED;
@@ -1873,6 +1835,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
 static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
+	struct sci_port *s = to_sci_port(port);
 
 	/* Handle BREAKs */
 	sci_handle_breaks(port);
@@ -1880,7 +1843,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 	/* drop invalid character received before break was detected */
 	sci_serial_in(port, SCxRDR);
 
-	sci_clear_SCxSR(port, SCxSR_BREAK_CLEAR(port));
+	s->ops->clear_SCxSR(port, SCxSR_BREAK_CLEAR(port));
 
 	return IRQ_HANDLED;
 }
@@ -1908,15 +1871,15 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 		if (sci_handle_errors(port)) {
 			/* discard character in rx buffer */
 			sci_serial_in(port, SCxSR);
-			sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
+			s->ops->clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 		}
 	} else {
 		sci_handle_fifo_overrun(port);
 		if (!s->chan_rx)
-			sci_receive_chars(port);
+			s->ops->receive_chars(port);
 	}
 
-	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
+	s->ops->clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 
 	/* Kick the transmission */
 	if (!s->chan_tx)
@@ -2286,7 +2249,17 @@ static void sci_break_ctl(struct uart_port *port, int break_state)
 	uart_port_unlock_irqrestore(port, flags);
 }
 
-static int sci_startup(struct uart_port *port)
+static void sci_shutdown_complete(struct uart_port *port)
+{
+	struct sci_port *s = to_sci_port(port);
+	u16 scr;
+
+	scr = sci_serial_in(port, SCSCR);
+	sci_serial_out(port, SCSCR,
+		       scr & (SCSCR_CKE1 | SCSCR_CKE0 | s->hscif_tot));
+}
+
+int sci_startup(struct uart_port *port)
 {
 	struct sci_port *s = to_sci_port(port);
 	int ret;
@@ -2305,11 +2278,10 @@ static int sci_startup(struct uart_port *port)
 	return 0;
 }
 
-static void sci_shutdown(struct uart_port *port)
+void sci_shutdown(struct uart_port *port)
 {
 	struct sci_port *s = to_sci_port(port);
 	unsigned long flags;
-	u16 scr;
 
 	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
 
@@ -2319,13 +2291,7 @@ static void sci_shutdown(struct uart_port *port)
 	uart_port_lock_irqsave(port, &flags);
 	sci_stop_rx(port);
 	sci_stop_tx(port);
-	/*
-	 * Stop RX and TX, disable related interrupts, keep clock source
-	 * and HSCIF TOT bits
-	 */
-	scr = sci_serial_in(port, SCSCR);
-	sci_serial_out(port, SCSCR,
-		       scr & (SCSCR_CKE1 | SCSCR_CKE0 | s->hscif_tot));
+	s->ops->shutdown_complete(port);
 	uart_port_unlock_irqrestore(port, flags);
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
@@ -2402,8 +2368,8 @@ static int sci_brg_calc(struct sci_port *s, unsigned int bps,
 
 /* calculate sample rate, BRR, and clock select */
 static int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
-			  unsigned int *brr, unsigned int *srr,
-			  unsigned int *cks)
+		   unsigned int *brr, unsigned int *srr,
+		   unsigned int *cks)
 {
 	unsigned long freq = s->clk_rates[SCI_FCK];
 	unsigned int sr, br, prediv, scrate, c;
@@ -2480,9 +2446,9 @@ static void sci_reset(struct uart_port *port)
 	if (reg->size)
 		sci_serial_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
 
-	sci_clear_SCxSR(port,
-			SCxSR_RDxF_CLEAR(port) & SCxSR_ERROR_CLEAR(port) &
-			SCxSR_BREAK_CLEAR(port));
+	s->ops->clear_SCxSR(port,
+			    SCxSR_RDxF_CLEAR(port) & SCxSR_ERROR_CLEAR(port) &
+			    SCxSR_BREAK_CLEAR(port));
 	if (sci_getreg(port, SCLSR)->size) {
 		status = sci_serial_in(port, SCLSR);
 		status &= ~(SCLSR_TO | SCLSR_ORER);
@@ -2491,14 +2457,14 @@ static void sci_reset(struct uart_port *port)
 
 	if (s->rx_trigger > 1) {
 		if (s->rx_fifo_timeout) {
-			scif_set_rtrg(port, 1);
+			s->ops->set_rtrg(port, 1);
 			timer_setup(&s->rx_fifo_timer, rx_fifo_timer_fn, 0);
 		} else {
 			if (port->type == PORT_SCIFA ||
 			    port->type == PORT_SCIFB)
-				scif_set_rtrg(port, 1);
+				s->ops->set_rtrg(port, 1);
 			else
-				scif_set_rtrg(port, s->rx_trigger);
+				s->ops->set_rtrg(port, s->rx_trigger);
 		}
 	}
 }
@@ -2758,7 +2724,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 		sci_enable_ms(port);
 }
 
-static void sci_pm(struct uart_port *port, unsigned int state,
+void sci_pm(struct uart_port *port, unsigned int state,
 		   unsigned int oldstate)
 {
 	struct sci_port *sci_port = to_sci_port(port);
@@ -2821,7 +2787,7 @@ static int sci_remap_port(struct uart_port *port)
 	return 0;
 }
 
-static void sci_release_port(struct uart_port *port)
+void sci_release_port(struct uart_port *port)
 {
 	struct sci_port *sport = to_sci_port(port);
 
@@ -2833,7 +2799,7 @@ static void sci_release_port(struct uart_port *port)
 	release_mem_region(port->mapbase, sport->reg_size);
 }
 
-static int sci_request_port(struct uart_port *port)
+int sci_request_port(struct uart_port *port)
 {
 	struct resource *res;
 	struct sci_port *sport = to_sci_port(port);
@@ -2855,7 +2821,7 @@ static int sci_request_port(struct uart_port *port)
 	return 0;
 }
 
-static void sci_config_port(struct uart_port *port, int flags)
+void sci_config_port(struct uart_port *port, int flags)
 {
 	if (flags & UART_CONFIG_TYPE) {
 		struct sci_port *sport = to_sci_port(port);
@@ -2865,7 +2831,7 @@ static void sci_config_port(struct uart_port *port, int flags)
 	}
 }
 
-static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
+int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
 	if (ser->baud_base < 2400)
 		/* No paper tape reader for Mitch.. */
@@ -2874,6 +2840,75 @@ static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
 	return 0;
 }
 
+static void sci_prepare_console_write(struct uart_port *port, u32 ctrl)
+{
+	struct sci_port *s = to_sci_port(port);
+	u32 ctrl_temp =
+		s->params->param_bits->rxtx_enable |
+		(s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) |
+		(ctrl & (SCSCR_CKE1 | SCSCR_CKE0)) |
+		s->hscif_tot;
+	sci_serial_out(port, SCSCR, ctrl_temp);
+}
+
+static void sci_console_save(struct uart_port *port)
+{
+	struct sci_port *s = to_sci_port(port);
+	struct sci_suspend_regs *regs = s->suspend_regs;
+
+	if (sci_getreg(port, SCDL)->size)
+		regs->scdl = sci_serial_in(port, SCDL);
+	if (sci_getreg(port, SCCKS)->size)
+		regs->sccks = sci_serial_in(port, SCCKS);
+	if (sci_getreg(port, SCSMR)->size)
+		regs->scsmr = sci_serial_in(port, SCSMR);
+	if (sci_getreg(port, SCSCR)->size)
+		regs->scscr = sci_serial_in(port, SCSCR);
+	if (sci_getreg(port, SCFCR)->size)
+		regs->scfcr = sci_serial_in(port, SCFCR);
+	if (sci_getreg(port, SCSPTR)->size)
+		regs->scsptr = sci_serial_in(port, SCSPTR);
+	if (sci_getreg(port, SCBRR)->size)
+		regs->scbrr = sci_serial_in(port, SCBRR);
+	if (sci_getreg(port, HSSRR)->size)
+		regs->hssrr = sci_serial_in(port, HSSRR);
+	if (sci_getreg(port, SCPCR)->size)
+		regs->scpcr = sci_serial_in(port, SCPCR);
+	if (sci_getreg(port, SCPDR)->size)
+		regs->scpdr = sci_serial_in(port, SCPDR);
+	if (sci_getreg(port, SEMR)->size)
+		regs->semr = sci_serial_in(port, SEMR);
+}
+
+static void sci_console_restore(struct uart_port *port)
+{
+	struct sci_port *s = to_sci_port(port);
+	struct sci_suspend_regs *regs = s->suspend_regs;
+
+	if (sci_getreg(port, SCDL)->size)
+		sci_serial_out(port, SCDL, regs->scdl);
+	if (sci_getreg(port, SCCKS)->size)
+		sci_serial_out(port, SCCKS, regs->sccks);
+	if (sci_getreg(port, SCSMR)->size)
+		sci_serial_out(port, SCSMR, regs->scsmr);
+	if (sci_getreg(port, SCSCR)->size)
+		sci_serial_out(port, SCSCR, regs->scscr);
+	if (sci_getreg(port, SCFCR)->size)
+		sci_serial_out(port, SCFCR, regs->scfcr);
+	if (sci_getreg(port, SCSPTR)->size)
+		sci_serial_out(port, SCSPTR, regs->scsptr);
+	if (sci_getreg(port, SCBRR)->size)
+		sci_serial_out(port, SCBRR, regs->scbrr);
+	if (sci_getreg(port, HSSRR)->size)
+		sci_serial_out(port, HSSRR, regs->hssrr);
+	if (sci_getreg(port, SCPCR)->size)
+		sci_serial_out(port, SCPCR, regs->scpcr);
+	if (sci_getreg(port, SCPDR)->size)
+		sci_serial_out(port, SCPDR, regs->scpdr);
+	if (sci_getreg(port, SEMR)->size)
+		sci_serial_out(port, SEMR, regs->semr);
+}
+
 static const struct uart_ops sci_uart_ops = {
 	.tx_empty	= sci_tx_empty,
 	.set_mctrl	= sci_set_mctrl,
@@ -2899,6 +2934,25 @@ static const struct uart_ops sci_uart_ops = {
 #endif
 };
 
+static const struct sci_port_ops sci_port_ops = {
+	.read_reg		= sci_serial_in,
+	.write_reg		= sci_serial_out,
+	.clear_SCxSR		= sci_clear_SCxSR,
+	.transmit_chars		= sci_transmit_chars,
+	.receive_chars		= sci_receive_chars,
+#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || \
+    defined(CONFIG_SERIAL_SH_SCI_EARLYCON)
+	.poll_put_char		= sci_poll_put_char,
+#endif
+	.set_rtrg		= scif_set_rtrg,
+	.rtrg_enabled		= scif_rtrg_enabled,
+	.shutdown_complete	= sci_shutdown_complete,
+	.prepare_console_write	= sci_prepare_console_write,
+	.console_save		= sci_console_save,
+	.console_restore	= sci_console_restore,
+	.suspend_regs_size	= sci_suspend_regs_size,
+};
+
 static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
 {
 	const char *clk_names[] = {
@@ -2992,6 +3046,7 @@ static int sci_init_single(struct platform_device *dev,
 	int ret;
 
 	sci_port->cfg	= p;
+	sci_port->ops	= &sci_port_ops;
 
 	port->ops	= &sci_uart_ops;
 	port->iotype	= UPIO_MEM;
@@ -3104,7 +3159,7 @@ static int sci_init_single(struct platform_device *dev,
     defined(CONFIG_SERIAL_SH_SCI_EARLYCON)
 static void serial_console_putchar(struct uart_port *port, unsigned char ch)
 {
-	sci_poll_put_char(port, ch);
+	to_sci_port(port)->ops->poll_put_char(port, ch);
 }
 
 /*
@@ -3116,7 +3171,9 @@ static void serial_console_write(struct console *co, const char *s,
 {
 	struct sci_port *sci_port = &sci_ports[co->index];
 	struct uart_port *port = &sci_port->port;
-	unsigned short bits, ctrl, ctrl_temp;
+	const struct sci_common_regs *regs = sci_port->params->common_regs;
+	unsigned int bits;
+	u32 ctrl;
 	unsigned long flags;
 	int locked = 1;
 
@@ -3128,21 +3185,21 @@ static void serial_console_write(struct console *co, const char *s,
 		uart_port_lock_irqsave(port, &flags);
 
 	/* first save SCSCR then disable interrupts, keep clock source */
-	ctrl = sci_serial_in(port, SCSCR);
-	ctrl_temp = SCSCR_RE | SCSCR_TE |
-		    (sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) |
-		    (ctrl & (SCSCR_CKE1 | SCSCR_CKE0));
-	sci_serial_out(port, SCSCR, ctrl_temp | sci_port->hscif_tot);
+
+	ctrl = sci_port->ops->read_reg(port, regs->control);
+	sci_port->ops->prepare_console_write(port, ctrl);
 
 	uart_console_write(port, s, count, serial_console_putchar);
 
 	/* wait until fifo is empty and last bit has been transmitted */
-	bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
-	while ((sci_serial_in(port, SCxSR) & bits) != bits)
+
+	bits = sci_port->params->param_bits->poll_sent_bits;
+
+	while ((sci_port->ops->read_reg(port, regs->status) & bits) != bits)
 		cpu_relax();
 
 	/* restore the SCSCR */
-	sci_serial_out(port, SCSCR, ctrl);
+	sci_port->ops->write_reg(port, regs->control, ctrl);
 
 	if (locked)
 		uart_port_unlock_irqrestore(port, flags);
@@ -3275,7 +3332,6 @@ static void sci_remove(struct platform_device *dev)
 		device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout);
 }
 
-
 #define SCI_OF_DATA(type, regtype)	(void *)((type) << 16 | (regtype))
 #define SCI_OF_TYPE(data)		((unsigned long)(data) >> 16)
 #define SCI_OF_REGTYPE(data)		((unsigned long)(data) & 0xffff)
@@ -3512,6 +3568,11 @@ static int sci_probe(struct platform_device *dev)
 	}
 
 	sp = &sci_ports[dev_id];
+	sp->suspend_regs = devm_kzalloc(&dev->dev,
+					sp->ops->suspend_regs_size(),
+					GFP_KERNEL);
+	if (!sp->suspend_regs)
+		return -ENOMEM;
 
 	/*
 	 * In case:
@@ -3563,64 +3624,6 @@ static int sci_probe(struct platform_device *dev)
 	return 0;
 }
 
-static void sci_console_save(struct sci_port *s)
-{
-	struct sci_suspend_regs *regs = &s->suspend_regs;
-	struct uart_port *port = &s->port;
-
-	if (sci_getreg(port, SCDL)->size)
-		regs->scdl = sci_serial_in(port, SCDL);
-	if (sci_getreg(port, SCCKS)->size)
-		regs->sccks = sci_serial_in(port, SCCKS);
-	if (sci_getreg(port, SCSMR)->size)
-		regs->scsmr = sci_serial_in(port, SCSMR);
-	if (sci_getreg(port, SCSCR)->size)
-		regs->scscr = sci_serial_in(port, SCSCR);
-	if (sci_getreg(port, SCFCR)->size)
-		regs->scfcr = sci_serial_in(port, SCFCR);
-	if (sci_getreg(port, SCSPTR)->size)
-		regs->scsptr = sci_serial_in(port, SCSPTR);
-	if (sci_getreg(port, SCBRR)->size)
-		regs->scbrr = sci_serial_in(port, SCBRR);
-	if (sci_getreg(port, HSSRR)->size)
-		regs->hssrr = sci_serial_in(port, HSSRR);
-	if (sci_getreg(port, SCPCR)->size)
-		regs->scpcr = sci_serial_in(port, SCPCR);
-	if (sci_getreg(port, SCPDR)->size)
-		regs->scpdr = sci_serial_in(port, SCPDR);
-	if (sci_getreg(port, SEMR)->size)
-		regs->semr = sci_serial_in(port, SEMR);
-}
-
-static void sci_console_restore(struct sci_port *s)
-{
-	struct sci_suspend_regs *regs = &s->suspend_regs;
-	struct uart_port *port = &s->port;
-
-	if (sci_getreg(port, SCDL)->size)
-		sci_serial_out(port, SCDL, regs->scdl);
-	if (sci_getreg(port, SCCKS)->size)
-		sci_serial_out(port, SCCKS, regs->sccks);
-	if (sci_getreg(port, SCSMR)->size)
-		sci_serial_out(port, SCSMR, regs->scsmr);
-	if (sci_getreg(port, SCSCR)->size)
-		sci_serial_out(port, SCSCR, regs->scscr);
-	if (sci_getreg(port, SCFCR)->size)
-		sci_serial_out(port, SCFCR, regs->scfcr);
-	if (sci_getreg(port, SCSPTR)->size)
-		sci_serial_out(port, SCSPTR, regs->scsptr);
-	if (sci_getreg(port, SCBRR)->size)
-		sci_serial_out(port, SCBRR, regs->scbrr);
-	if (sci_getreg(port, HSSRR)->size)
-		sci_serial_out(port, HSSRR, regs->hssrr);
-	if (sci_getreg(port, SCPCR)->size)
-		sci_serial_out(port, SCPCR, regs->scpcr);
-	if (sci_getreg(port, SCPDR)->size)
-		sci_serial_out(port, SCPDR, regs->scpdr);
-	if (sci_getreg(port, SEMR)->size)
-		sci_serial_out(port, SEMR, regs->semr);
-}
-
 static __maybe_unused int sci_suspend(struct device *dev)
 {
 	struct sci_port *sport = dev_get_drvdata(dev);
@@ -3628,8 +3631,10 @@ static __maybe_unused int sci_suspend(struct device *dev)
 	if (sport) {
 		uart_suspend_port(&sci_uart_driver, &sport->port);
 
-		if (!console_suspend_enabled && uart_console(&sport->port))
-			sci_console_save(sport);
+		if (!console_suspend_enabled && uart_console(&sport->port)) {
+			if (sport->ops->console_save)
+				sport->ops->console_save(&sport->port);
+		}
 		else
 			return reset_control_assert(sport->rstc);
 	}
@@ -3643,7 +3648,8 @@ static __maybe_unused int sci_resume(struct device *dev)
 
 	if (sport) {
 		if (!console_suspend_enabled && uart_console(&sport->port)) {
-			sci_console_restore(sport);
+			if (sport->ops->console_restore)
+				sport->ops->console_restore(&sport->port);
 		} else {
 			int ret = reset_control_deassert(sport->rstc);
 
@@ -3707,9 +3713,11 @@ static int early_console_exit(struct console *co)
 	return 0;
 }
 
-static int __init early_console_setup(struct earlycon_device *device,
+int __init scix_early_console_setup(struct earlycon_device *device,
 				      int type)
 {
+	const struct sci_common_regs *regs;
+
 	if (!device->port.membase)
 		return -ENODEV;
 
@@ -3717,11 +3725,15 @@ static int __init early_console_setup(struct earlycon_device *device,
 	sci_ports[0].port = device->port;
 	port_cfg.type = type;
 	sci_ports[0].cfg = &port_cfg;
+	sci_ports[0].ops = &sci_port_ops;
 	sci_ports[0].params = sci_probe_regmap(&port_cfg);
 	sci_uart_earlycon = true;
-	port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR);
-	sci_serial_out(&sci_ports[0].port, SCSCR,
-		       SCSCR_RE | SCSCR_TE | port_cfg.scscr);
+	regs = sci_ports[0].params->common_regs;
+
+	port_cfg.scscr = sci_ports[0].ops->read_reg(&sci_ports[0].port, regs->control);
+	sci_ports[0].ops->write_reg(&sci_ports[0].port,
+				    regs->control,
+				    sci_ports[0].params->param_bits->rxtx_enable | port_cfg.scscr);
 
 	device->con->write = serial_console_write;
 	device->con->exit = early_console_exit;
@@ -3731,41 +3743,41 @@ static int __init early_console_setup(struct earlycon_device *device,
 static int __init sci_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return early_console_setup(device, PORT_SCI);
+	return scix_early_console_setup(device, PORT_SCI);
 }
 static int __init scif_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return early_console_setup(device, PORT_SCIF);
+	return scix_early_console_setup(device, PORT_SCIF);
 }
 static int __init rzscifa_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
 	port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE;
-	return early_console_setup(device, PORT_SCIF);
+	return scix_early_console_setup(device, PORT_SCIF);
 }
 
 static int __init rzv2hscif_early_console_setup(struct earlycon_device *device,
 						const char *opt)
 {
 	port_cfg.regtype = SCIx_RZV2H_SCIF_REGTYPE;
-	return early_console_setup(device, PORT_SCIF);
+	return scix_early_console_setup(device, PORT_SCIF);
 }
 
 static int __init scifa_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return early_console_setup(device, PORT_SCIFA);
+	return scix_early_console_setup(device, PORT_SCIFA);
 }
 static int __init scifb_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return early_console_setup(device, PORT_SCIFB);
+	return scix_early_console_setup(device, PORT_SCIFB);
 }
 static int __init hscif_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return early_console_setup(device, PORT_HSCIF);
+	return scix_early_console_setup(device, PORT_HSCIF);
 }
 
 OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup);
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 0b65563c4e9e..951681aba586 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -32,8 +32,6 @@ enum {
 	HSRTRGR,			/* Rx FIFO Data Count Trigger Register */
 	HSTTRGR,			/* Tx FIFO Data Count Trigger Register */
 	SEMR,				/* Serial extended mode register */
-
-	SCIx_NR_REGS,
 };
 
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 09/13] serial: sh-sci: Introduced sci_of_data
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (7 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 08/13] serial: sh-sci: Introduced function pointers Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Wolfram Sang, Geert Uytterhoeven, linux-kernel, linux-serial

The aim here is to provide an easier support to more different SCI
controllers, like the RZ/T2H one.

The existing .data field of_sci_match is changed to a structure containing
all what that can be statically initialized, and avoid a call to
'sci_probe_regmap', in both 'sci_init_single', and 'early_console_setup'.

'sci_probe_regmap' is now assumed to be called in the only case where the
device description is from a board file instead of a dts.

In this way, there is no need to patch 'sci_probe_regmap' for adding new
SCI type, and also, the specific sci_port_params for a new SCI type can be
provided by an external file.

Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4:
   - Fix the bot compilation error on superh in sci_probe_earlyprink()
---
 drivers/tty/serial/sh-sci-common.h |  10 +-
 drivers/tty/serial/sh-sci.c        | 164 +++++++++++++++++++++--------
 2 files changed, 131 insertions(+), 43 deletions(-)

diff --git a/drivers/tty/serial/sh-sci-common.h b/drivers/tty/serial/sh-sci-common.h
index 2ed742bca83f..bd9d9cfac1c8 100644
--- a/drivers/tty/serial/sh-sci-common.h
+++ b/drivers/tty/serial/sh-sci-common.h
@@ -89,6 +89,14 @@ struct sci_port_ops {
 	size_t (*suspend_regs_size)(void);
 };
 
+struct sci_of_data {
+	const struct sci_port_params *params;
+	const struct uart_ops *uart_ops;
+	const struct sci_port_ops *ops;
+	unsigned short regtype;
+	unsigned short type;
+};
+
 struct sci_port {
 	struct uart_port	port;
 
@@ -153,7 +161,7 @@ void sci_shutdown(struct uart_port *port);
 #define max_sr(_port)		fls((_port)->sampling_rate_mask)
 
 #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
-int __init scix_early_console_setup(struct earlycon_device *device, int);
+int __init scix_early_console_setup(struct earlycon_device *device, const struct sci_of_data *data);
 #endif
 
 #endif /* __SH_SCI_COMMON_H__ */
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 54a484b04a97..0ddf178a72f5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2996,10 +2996,13 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
 }
 
 static const struct sci_port_params *
-sci_probe_regmap(const struct plat_sci_port *cfg)
+sci_probe_regmap(const struct plat_sci_port *cfg, struct sci_port *sci_port)
 {
 	unsigned int regtype;
 
+	sci_port->ops = &sci_port_ops;
+	sci_port->port.ops = &sci_uart_ops;
+
 	if (cfg->regtype != SCIx_PROBE_REGTYPE)
 		return &sci_port_params[cfg->regtype];
 
@@ -3046,9 +3049,7 @@ static int sci_init_single(struct platform_device *dev,
 	int ret;
 
 	sci_port->cfg	= p;
-	sci_port->ops	= &sci_port_ops;
 
-	port->ops	= &sci_uart_ops;
 	port->iotype	= UPIO_MEM;
 	port->line	= index;
 	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_SH_SCI_CONSOLE);
@@ -3088,10 +3089,6 @@ static int sci_init_single(struct platform_device *dev,
 		for (i = 1; i < ARRAY_SIZE(sci_port->irqs); i++)
 			sci_port->irqs[i] = sci_port->irqs[0];
 
-	sci_port->params = sci_probe_regmap(p);
-	if (unlikely(sci_port->params == NULL))
-		return -EINVAL;
-
 	switch (p->type) {
 	case PORT_SCIFB:
 		sci_port->rx_trigger = 48;
@@ -3277,13 +3274,18 @@ static struct console early_serial_console = {
 static int sci_probe_earlyprintk(struct platform_device *pdev)
 {
 	const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev);
+	struct sci_port *sp = &sci_ports[pdev->id];
 
 	if (early_serial_console.data)
 		return -EEXIST;
 
 	early_serial_console.index = pdev->id;
 
-	sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true);
+	sp->params = sci_probe_regmap(cfg, sp);
+	if (!sp->params)
+		return -ENODEV;
+
+	sci_init_single(pdev, sp, pdev->id, cfg, true);
 
 	if (!strstr(early_serial_buf, "keep"))
 		early_serial_console.flags |= CON_BOOT;
@@ -3332,58 +3334,126 @@ static void sci_remove(struct platform_device *dev)
 		device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout);
 }
 
-#define SCI_OF_DATA(type, regtype)	(void *)((type) << 16 | (regtype))
-#define SCI_OF_TYPE(data)		((unsigned long)(data) >> 16)
-#define SCI_OF_REGTYPE(data)		((unsigned long)(data) & 0xffff)
+static const struct sci_of_data of_sci_scif_sh2 = {
+	.type = PORT_SCIF,
+	.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_SH2_SCIF_FIFODATA_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_scif_rz_scifa = {
+	.type = PORT_SCIF,
+	.regtype = SCIx_RZ_SCIFA_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_RZ_SCIFA_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_scif_rzv2h = {
+	.type = PORT_SCIF,
+	.regtype = SCIx_RZV2H_SCIF_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_RZV2H_SCIF_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_rcar_scif = {
+	.type = PORT_SCIF,
+	.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_SH4_SCIF_BRG_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_scif_sh4 = {
+	.type = PORT_SCIF,
+	.regtype = SCIx_SH4_SCIF_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_SH4_SCIF_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_scifa = {
+	.type = PORT_SCIFA,
+	.regtype = SCIx_SCIFA_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_SCIFA_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_scifb = {
+	.type = PORT_SCIFB,
+	.regtype = SCIx_SCIFB_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_SCIFB_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_hscif = {
+	.type = PORT_HSCIF,
+	.regtype = SCIx_HSCIF_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_HSCIF_REGTYPE],
+};
+
+static const struct sci_of_data of_sci_sci = {
+	.type = PORT_SCI,
+	.regtype = SCIx_SCI_REGTYPE,
+	.ops = &sci_port_ops,
+	.uart_ops = &sci_uart_ops,
+	.params = &sci_port_params[SCIx_SCI_REGTYPE],
+};
 
 static const struct of_device_id of_sci_match[] __maybe_unused = {
 	/* SoC-specific types */
 	{
 		.compatible = "renesas,scif-r7s72100",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_SH2_SCIF_FIFODATA_REGTYPE),
+		.data = &of_sci_scif_sh2,
 	},
 	{
 		.compatible = "renesas,scif-r7s9210",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE),
+		.data = &of_sci_scif_rz_scifa,
 	},
 	{
 		.compatible = "renesas,scif-r9a07g044",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE),
+		.data = &of_sci_scif_rz_scifa,
 	},
 	{
 		.compatible = "renesas,scif-r9a09g057",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_RZV2H_SCIF_REGTYPE),
+		.data = &of_sci_scif_rzv2h,
 	},
 	/* Family-specific types */
 	{
 		.compatible = "renesas,rcar-gen1-scif",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE),
+		.data = &of_sci_rcar_scif,
 	}, {
 		.compatible = "renesas,rcar-gen2-scif",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE),
+		.data = &of_sci_rcar_scif,
 	}, {
 		.compatible = "renesas,rcar-gen3-scif",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE),
+		.data = &of_sci_rcar_scif
 	}, {
 		.compatible = "renesas,rcar-gen4-scif",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_BRG_REGTYPE),
+		.data = &of_sci_rcar_scif
 	},
 	/* Generic types */
 	{
 		.compatible = "renesas,scif",
-		.data = SCI_OF_DATA(PORT_SCIF, SCIx_SH4_SCIF_REGTYPE),
+		.data = &of_sci_scif_sh4,
 	}, {
 		.compatible = "renesas,scifa",
-		.data = SCI_OF_DATA(PORT_SCIFA, SCIx_SCIFA_REGTYPE),
+		.data = &of_sci_scifa,
 	}, {
 		.compatible = "renesas,scifb",
-		.data = SCI_OF_DATA(PORT_SCIFB, SCIx_SCIFB_REGTYPE),
+		.data = &of_sci_scifb,
 	}, {
 		.compatible = "renesas,hscif",
-		.data = SCI_OF_DATA(PORT_HSCIF, SCIx_HSCIF_REGTYPE),
+		.data = &of_sci_hscif,
 	}, {
 		.compatible = "renesas,sci",
-		.data = SCI_OF_DATA(PORT_SCI, SCIx_SCI_REGTYPE),
+		.data = &of_sci_sci,
 	}, {
 		/* Terminator */
 	},
@@ -3402,7 +3472,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
 	struct reset_control *rstc;
 	struct plat_sci_port *p;
 	struct sci_port *sp;
-	const void *data;
+	const struct sci_of_data *data;
 	int id, ret;
 
 	if (!IS_ENABLED(CONFIG_OF) || !np)
@@ -3449,8 +3519,12 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
 	sp->rstc = rstc;
 	*dev_id = id;
 
-	p->type = SCI_OF_TYPE(data);
-	p->regtype = SCI_OF_REGTYPE(data);
+	p->type = data->type;
+	p->regtype = data->regtype;
+
+	sp->ops = data->ops;
+	sp->port.ops = data->uart_ops;
+	sp->params = data->params;
 
 	sp->has_rtscts = of_property_read_bool(np, "uart-has-rtscts");
 
@@ -3557,6 +3631,7 @@ static int sci_probe(struct platform_device *dev)
 		p = sci_parse_dt(dev, &dev_id);
 		if (IS_ERR(p))
 			return PTR_ERR(p);
+		sp = &sci_ports[dev_id];
 	} else {
 		p = dev->dev.platform_data;
 		if (p == NULL) {
@@ -3565,9 +3640,12 @@ static int sci_probe(struct platform_device *dev)
 		}
 
 		dev_id = dev->id;
+		sp = &sci_ports[dev_id];
+		sp->params = sci_probe_regmap(p, sp);
+		if (!sp->params)
+			return -ENODEV;
 	}
 
-	sp = &sci_ports[dev_id];
 	sp->suspend_regs = devm_kzalloc(&dev->dev,
 					sp->ops->suspend_regs_size(),
 					GFP_KERNEL);
@@ -3714,19 +3792,23 @@ static int early_console_exit(struct console *co)
 }
 
 int __init scix_early_console_setup(struct earlycon_device *device,
-				      int type)
+				    const struct sci_of_data *data)
 {
 	const struct sci_common_regs *regs;
 
 	if (!device->port.membase)
 		return -ENODEV;
 
-	device->port.type = type;
+	device->port.type = data->type;
 	sci_ports[0].port = device->port;
-	port_cfg.type = type;
+
+	port_cfg.type = data->type;
+	port_cfg.regtype = data->regtype;
+
 	sci_ports[0].cfg = &port_cfg;
-	sci_ports[0].ops = &sci_port_ops;
-	sci_ports[0].params = sci_probe_regmap(&port_cfg);
+	sci_ports[0].params = data->params;
+	sci_ports[0].ops = data->ops;
+	sci_ports[0].port.ops = data->uart_ops;
 	sci_uart_earlycon = true;
 	regs = sci_ports[0].params->common_regs;
 
@@ -3743,41 +3825,39 @@ int __init scix_early_console_setup(struct earlycon_device *device,
 static int __init sci_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return scix_early_console_setup(device, PORT_SCI);
+	return scix_early_console_setup(device, &of_sci_sci);
 }
 static int __init scif_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return scix_early_console_setup(device, PORT_SCIF);
+	return scix_early_console_setup(device, &of_sci_scif_sh4);
 }
 static int __init rzscifa_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE;
-	return scix_early_console_setup(device, PORT_SCIF);
+	return scix_early_console_setup(device, &of_sci_scif_rz_scifa);
 }
 
 static int __init rzv2hscif_early_console_setup(struct earlycon_device *device,
 						const char *opt)
 {
-	port_cfg.regtype = SCIx_RZV2H_SCIF_REGTYPE;
-	return scix_early_console_setup(device, PORT_SCIF);
+	return scix_early_console_setup(device, &of_sci_scif_rzv2h);
 }
 
 static int __init scifa_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return scix_early_console_setup(device, PORT_SCIFA);
+	return scix_early_console_setup(device, &of_sci_scifa);
 }
 static int __init scifb_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return scix_early_console_setup(device, PORT_SCIFB);
+	return scix_early_console_setup(device, &of_sci_scifb);
 }
 static int __init hscif_early_console_setup(struct earlycon_device *device,
 					  const char *opt)
 {
-	return scix_early_console_setup(device, PORT_HSCIF);
+	return scix_early_console_setup(device, &of_sci_hscif);
 }
 
 OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (8 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 09/13] serial: sh-sci: Introduced sci_of_data Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-11 14:57   ` Greg KH
  2025-04-17 12:53   ` Geert Uytterhoeven
  2025-04-03 21:29 ` [PATCH v7 11/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
                   ` (2 subsequent siblings)
  12 siblings, 2 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Wolfram Sang, linux-kernel, linux-serial

Define a new RSCI port type, and the RSCI 32 bits registers set.
The RZ/T2H SCI has a a fifo, and a quite different set of registers
from the orginal SH SCI ones.
DMA is not supported yet.

Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7:
  - Renamed compatible string to r9a09g077-rsci
Changes v5->v6:
  - Rename SERIAL_RZ_SCI_T2 to CONFIG_SERIAL_RSCI
  - Rename rz-sci-t2.{c,h} to rsci.{c,h}
  - Rename port type to PORT_RSCI
  - Rename sci_r9a09g077_data to of_sci_r9a09g077_data for consistency
Changes v4->v5:
  - Rename SERIAL_RZ_SCI to SERIAL_RZ_SCI_T2
  - Rename rzsci.{c,h} to rz-sci-t2.{c,h}
  - Rename port type to PORT_RZ_SCI_T2
  - Set sci_shutdown ops pointer (needed by systemd for having a console)
Changes v3->v4:
  - Added missing #include <bitfield.h>
  - Fix christmas tree code style in rzsci_transmit_chars.
---
 drivers/tty/serial/Kconfig       |   7 +
 drivers/tty/serial/Makefile      |   1 +
 drivers/tty/serial/rsci.c        | 467 +++++++++++++++++++++++++++++++
 drivers/tty/serial/rsci.h        |  12 +
 drivers/tty/serial/sh-sci.c      |  21 +-
 include/linux/serial_sci.h       |   3 +-
 include/uapi/linux/serial_core.h |   3 +
 7 files changed, 508 insertions(+), 6 deletions(-)
 create mode 100644 drivers/tty/serial/rsci.c
 create mode 100644 drivers/tty/serial/rsci.h

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 79a8186d3361..44427415a80d 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -675,6 +675,13 @@ config SERIAL_SH_SCI_DMA
 	depends on SERIAL_SH_SCI && DMA_ENGINE
 	default ARCH_RENESAS
 
+config SERIAL_RSCI
+	tristate "Support for Renesas RZ/T2H SCI variant"
+	depends on SERIAL_SH_SCI
+	help
+	  Support for the RZ/T2H SCI variant with fifo.
+	  Say Y if you want to be able to use the RZ/T2H SCI serial port.
+
 config SERIAL_HS_LPC32XX
 	tristate "LPC32XX high speed serial port support"
 	depends on ARCH_LPC32XX || COMPILE_TEST
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index d58d9f719889..a2ccbc508ec5 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_SERIAL_QCOM_GENI)		+= qcom_geni_serial.o
 obj-$(CONFIG_SERIAL_QE)			+= ucc_uart.o
 obj-$(CONFIG_SERIAL_RDA)		+= rda-uart.o
 obj-$(CONFIG_SERIAL_RP2)		+= rp2.o
+obj-$(CONFIG_SERIAL_RSCI)		+= rsci.o
 obj-$(CONFIG_SERIAL_SA1100)		+= sa1100.o
 obj-$(CONFIG_SERIAL_SAMSUNG)		+= samsung_tty.o
 obj-$(CONFIG_SERIAL_SB1250_DUART)	+= sb1250-duart.o
diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c
new file mode 100644
index 000000000000..91fa1167adcb
--- /dev/null
+++ b/drivers/tty/serial/rsci.c
@@ -0,0 +1,467 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/serial_core.h>
+#include <linux/serial_sci.h>
+#include <linux/tty_flip.h>
+#include "rsci.h"
+
+/* RSCI registers */
+#define RDR	0x00
+#define TDR	0x04
+#define CCR0	0x08
+#define CCR1	0x0C
+#define CCR2	0x10
+#define CCR3	0x14
+#define CCR4	0x18
+#define FCR	0x24
+#define DCR	0x30
+#define CSR	0x48
+#define FRSR	0x50
+#define FTSR	0x54
+#define CFCLR	0x68
+#define FFCLR	0x70
+
+/* RDR (Receive Data Register) */
+#define RDR_FFER		BIT(12) /* FIFO Framing Error */
+#define RDR_FPER		BIT(11) /* FIFO Parity Error */
+#define RDR_RDAT_MSK		GENMASK(8, 0)
+
+/* TDR (Transmit Data Register) */
+#define TDR_MPBT		BIT(9)	/* Multiprocessor Transfer */
+#define TDR_TDAT_9BIT_LSHIFT	0
+#define TDR_TDAT_9BIT_VAL	0x1FF
+#define TDR_TDAT_9BIT_MSK	(TDR_TDAT_9BIT_VAL << TDR_TDAT_9BIT_LSHIFT)
+
+/* CCR0 (Common Control Register 0) */
+#define CCR0_SSE		BIT(24)	/* SSn# Pin Function Enable */
+#define CCR0_TEIE		BIT(21)	/* Transmit End Interrupt Enable */
+#define CCR0_TIE		BIT(20)	/* Transmit Interrupt Enable */
+#define CCR0_RIE		BIT(16)	/* Receive Interrupt Enable */
+#define CCR0_IDSEL		BIT(10)	/* ID Frame Select */
+#define CCR0_DCME		BIT(9)	/* Data Compare Match Enable */
+#define CCR0_MPIE		BIT(8)	/* Multiprocessor Interrupt Enable */
+#define CCR0_TE			BIT(4)	/* Transmit Enable */
+#define CCR0_RE			BIT(0)	/* Receive Enable */
+
+/* CCR1 (Common Control Register 1) */
+#define CCR1_NFEN		BIT(28)	/* Digital Noise Filter Function */
+#define CCR1_SHARPS		BIT(20)	/* Half -duplex Communication Select */
+#define CCR1_SPLP		BIT(16)	/* Loopback Control */
+#define CCR1_RINV		BIT(13)	/* RxD invert */
+#define CCR1_TINV		BIT(12)	/* TxD invert */
+#define CCR1_PM			BIT(9)	/* Parity Mode */
+#define CCR1_PE			BIT(8)	/* Parity Enable */
+#define CCR1_SPB2IO		BIT(5)	/* Serial Port Break I/O */
+#define CCR1_SPB2DT		BIT(4)	/* Serial Port Break Data Select */
+#define CCR1_CTSPEN		BIT(1)	/* CTS External Pin Enable */
+#define CCR1_CTSE		BIT(0)	/* CTS Enable */
+
+/* FCR (FIFO Control Register) */
+#define FCR_RFRST		BIT(23)	/* Receive FIFO Data Register Reset */
+#define FCR_TFRST		BIT(15)	/* Transmit FIFO Data Register Reset */
+#define FCR_DRES		BIT(0)	/* Incoming Data Ready Error Select */
+#define FCR_RTRG4_0		GENMASK(20, 16)
+#define FCR_TTRG		GENMASK(12, 8)
+
+/* CSR (Common Status Register) */
+#define CSR_RDRF		BIT(31)	/* Receive Data Full */
+#define CSR_TEND		BIT(30)	/* Transmit End Flag */
+#define CSR_TDRE		BIT(29)	/* Transmit Data Empty */
+#define CSR_FER			BIT(28)	/* Framing Error */
+#define CSR_PER			BIT(27)	/* Parity Error */
+#define CSR_MFF			BIT(26)	/* Mode Fault Error */
+#define CSR_ORER		BIT(24)	/* Overrun Error */
+#define CSR_DFER		BIT(18)	/* Data Compare Match Framing Error */
+#define CSR_DPER		BIT(17)	/* Data Compare Match Parity Error */
+#define CSR_DCMF		BIT(16)	/* Data Compare Match */
+#define CSR_RXDMON		BIT(15)	/* Serial Input Data Monitor */
+#define CSR_ERS			BIT(4)	/* Error Signal Status */
+
+#define SCxSR_ERRORS(port)	(to_sci_port(port)->params->error_mask)
+#define SCxSR_ERROR_CLEAR(port)	(to_sci_port(port)->params->error_clear)
+
+#define RSCI_DEFAULT_ERROR_MASK	(CSR_PER | CSR_FER)
+
+#define RSCI_RDxF_CLEAR		(CFCLR_RDRFC)
+#define RSCI_ERROR_CLEAR	(CFCLR_PERC | CFCLR_FERC)
+#define RSCI_TDxE_CLEAR		(CFCLR_TDREC)
+#define RSCI_BREAK_CLEAR	(CFCLR_PERC | CFCLR_FERC | CFCLR_ORERC)
+
+/* FRSR (FIFO Receive Status Register) */
+#define FRSR_R5_0		GENMASK(13, 8)	/* Receive FIFO Data Count */
+#define FRSR_DR			BIT(0)	/* Receive Data Ready */
+
+/* CFCLR (Common Flag CLear Register) */
+#define CFCLR_RDRFC		BIT(31)	/* RDRF Clear */
+#define CFCLR_TDREC		BIT(29)	/* TDRE Clear */
+#define CFCLR_FERC		BIT(28)	/* FER Clear */
+#define CFCLR_PERC		BIT(27)	/* PER Clear */
+#define CFCLR_MFFC		BIT(26)	/* MFF Clear */
+#define CFCLR_ORERC		BIT(24)	/* ORER Clear */
+#define CFCLR_DFERC		BIT(18)	/* DFER Clear */
+#define CFCLR_DPERC		BIT(17)	/* DPER Clear */
+#define CFCLR_DCMFC		BIT(16)	/* DCMF Clear */
+#define CFCLR_ERSC		BIT(4)	/* ERS Clear */
+#define CFCLR_CLRFLAG		(CFCLR_RDRFC | CFCLR_FERC | CFCLR_PERC | \
+				 CFCLR_MFFC | CFCLR_ORERC | CFCLR_DFERC | \
+				 CFCLR_DPERC | CFCLR_DCMFC | CFCLR_ERSC)
+
+/* FFCLR (FIFO Flag CLear Register) */
+#define FFCLR_DRC		BIT(0)	/* DR Clear */
+
+#define DCR_DEPOL		BIT(0)
+
+static u32 rzsci_serial_in(struct uart_port *p, int offset)
+{
+	return readl(p->membase + offset);
+}
+
+static void rzsci_serial_out(struct uart_port *p, int offset, int value)
+{
+	writel(value, p->membase + offset);
+}
+
+static void rzsci_clear_DRxC(struct uart_port *port)
+{
+	rzsci_serial_out(port, CFCLR, CFCLR_RDRFC);
+	rzsci_serial_out(port, FFCLR, FFCLR_DRC);
+}
+
+static void rzsci_clear_SCxSR(struct uart_port *port, unsigned int mask)
+{
+	rzsci_serial_out(port, CFCLR, mask);
+}
+
+static void rzsci_start_rx(struct uart_port *port)
+{
+	unsigned int ctrl;
+
+	ctrl = rzsci_serial_in(port, CCR0);
+	ctrl |= CCR0_RIE;
+	rzsci_serial_out(port, CCR0, ctrl);
+}
+
+static void rzsci_set_termios(struct uart_port *port, struct ktermios *termios,
+			      const struct ktermios *old)
+{
+	struct sci_port *s = to_sci_port(port);
+	unsigned long flags;
+
+	sci_port_enable(s);
+	uart_port_lock_irqsave(port, &flags);
+
+	/* For now, only RX enabling is supported */
+	if (termios->c_cflag & CREAD)
+		rzsci_start_rx(port);
+
+	uart_port_unlock_irqrestore(port, flags);
+	sci_port_disable(s);
+}
+
+static int rzsci_txfill(struct uart_port *port)
+{
+	return rzsci_serial_in(port, FTSR);
+}
+
+static int rzsci_rxfill(struct uart_port *port)
+{
+	u32 val = rzsci_serial_in(port, FRSR);
+
+	return FIELD_GET(FRSR_R5_0, val);
+}
+
+static unsigned int rzsci_tx_empty(struct uart_port *port)
+{
+	unsigned int status = rzsci_serial_in(port, CSR);
+	unsigned int in_tx_fifo = rzsci_txfill(port);
+
+	return (status & CSR_TEND) && !in_tx_fifo ? TIOCSER_TEMT : 0;
+}
+
+static void rzsci_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	/* Not supported yet */
+}
+
+static unsigned int rzsci_get_mctrl(struct uart_port *port)
+{
+	/* Not supported yet */
+	return 0;
+}
+
+static void rzsci_clear_CFC(struct uart_port *port, unsigned int mask)
+{
+	rzsci_serial_out(port, CFCLR, mask);
+}
+
+static void rzsci_start_tx(struct uart_port *port)
+{
+	struct sci_port *sp = to_sci_port(port);
+	u32 ctrl;
+
+	if (sp->chan_tx)
+		return;
+
+	/*
+	 * TE (Transmit Enable) must be set after setting TIE
+	 * (Transmit Interrupt Enable) or in the same instruction
+	 * to start the transmit process.
+	 */
+	ctrl = rzsci_serial_in(port, CCR0);
+	ctrl |= CCR0_TIE | CCR0_TE;
+	rzsci_serial_out(port, CCR0, ctrl);
+}
+
+static void rzsci_stop_tx(struct uart_port *port)
+{
+	u32 ctrl;
+
+	ctrl = rzsci_serial_in(port, CCR0);
+	ctrl &= ~CCR0_TIE;
+	rzsci_serial_out(port, CCR0, ctrl);
+}
+
+static void rzsci_stop_rx(struct uart_port *port)
+{
+	u32 ctrl;
+
+	ctrl = rzsci_serial_in(port, CCR0);
+	ctrl &= ~CCR0_RIE;
+	rzsci_serial_out(port, CCR0, ctrl);
+}
+
+static int rzsci_txroom(struct uart_port *port)
+{
+	return port->fifosize - rzsci_txfill(port);
+}
+
+static void rzsci_transmit_chars(struct uart_port *port)
+{
+	unsigned int stopped = uart_tx_stopped(port);
+	struct tty_port *tport = &port->state->port;
+	u32 status, ctrl;
+	int count;
+
+	status = rzsci_serial_in(port, CSR);
+	if (!(status & CSR_TDRE)) {
+		ctrl = rzsci_serial_in(port, CCR0);
+		if (kfifo_is_empty(&tport->xmit_fifo))
+			ctrl &= ~CCR0_TIE;
+		else
+			ctrl |= CCR0_TIE;
+		rzsci_serial_out(port, CCR0, ctrl);
+		return;
+	}
+
+	count = rzsci_txroom(port);
+
+	do {
+		unsigned char c;
+
+		if (port->x_char) {
+			c = port->x_char;
+			port->x_char = 0;
+		} else if (stopped || !kfifo_get(&tport->xmit_fifo, &c)) {
+			break;
+		}
+
+		rzsci_clear_CFC(port, CFCLR_TDREC);
+		rzsci_serial_out(port, TDR, c);
+
+		port->icount.tx++;
+	} while (--count > 0);
+
+	if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (kfifo_is_empty(&tport->xmit_fifo)) {
+		ctrl = rzsci_serial_in(port, CCR0);
+		ctrl &= ~CCR0_TIE;
+		ctrl |= CCR0_TEIE;
+		rzsci_serial_out(port, CCR0, ctrl);
+	}
+}
+
+static void rzsci_receive_chars(struct uart_port *port)
+{
+	struct tty_port *tport = &port->state->port;
+	u32 rdat, status, frsr_status = 0;
+	int i, count, copied = 0;
+	unsigned char flag;
+
+	status = rzsci_serial_in(port, CSR);
+	frsr_status = rzsci_serial_in(port, FRSR);
+
+	if (!(status & CSR_RDRF) && !(frsr_status & FRSR_DR))
+		return;
+
+	while (1) {
+		/* Don't copy more bytes than there is room for in the buffer */
+		count = tty_buffer_request_room(tport, rzsci_rxfill(port));
+
+		/* If for any reason we can't copy more data, we're done! */
+		if (count == 0)
+			break;
+
+		for (i = 0; i < count; i++) {
+			char c;
+
+			rdat = rzsci_serial_in(port, RDR);
+			/* 9-bits data is not supported yet */
+			c = rdat & RDR_RDAT_MSK;
+
+			if (uart_handle_sysrq_char(port, c)) {
+				count--;
+				i--;
+				continue;
+			}
+
+			/* Store data and status.
+			 * Non FIFO mode is not supported
+			 */
+			if (rdat & RDR_FFER) {
+				flag = TTY_FRAME;
+				port->icount.frame++;
+			} else if (rdat & RDR_FPER) {
+				flag = TTY_PARITY;
+				port->icount.parity++;
+			} else {
+				flag = TTY_NORMAL;
+			}
+
+			tty_insert_flip_char(tport, c, flag);
+		}
+
+		rzsci_serial_in(port, CSR); /* dummy read */
+		rzsci_clear_DRxC(port);
+
+		copied += count;
+		port->icount.rx += count;
+	}
+
+	if (copied) {
+		/* Tell the rest of the system the news. New characters! */
+		tty_flip_buffer_push(tport);
+	} else {
+		/* TTY buffers full; read from RX reg to prevent lockup */
+		rzsci_serial_in(port, RDR);
+		rzsci_serial_in(port, CSR); /* dummy read */
+		rzsci_clear_DRxC(port);
+	}
+}
+
+static void rzsci_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	u32 status;
+	int ret;
+
+	ret = readl_relaxed_poll_timeout_atomic(port->membase + CSR, status,
+						(status & CSR_TDRE), 100,
+						USEC_PER_SEC);
+	if (ret != 0) {
+		dev_err(port->dev,
+			"Error while sending data in UART TX : %d\n", ret);
+		goto done;
+	}
+	rzsci_serial_out(port, TDR, c);
+done:
+	rzsci_clear_SCxSR(port, CFCLR_TDREC);
+}
+
+static void rzsci_prepare_console_write(struct uart_port *port, u32 ctrl)
+{
+	struct sci_port *s = to_sci_port(port);
+	u32 ctrl_temp =
+		s->params->param_bits->rxtx_enable |
+		CCR0_TIE |
+		s->hscif_tot;
+	rzsci_serial_out(port, CCR0, ctrl_temp);
+}
+
+static const char *rzsci_type(struct uart_port *port)
+{
+	return "rzsci";
+}
+
+static size_t rzsci_suspend_regs_size(void)
+{
+	return 0;
+}
+
+static const struct sci_common_regs rzsci_common_regs = {
+	.status = CSR,
+	.control = CCR0,
+};
+
+static const struct sci_port_params_bits rzsci_port_param_bits = {
+	.rxtx_enable = CCR0_RE | CCR0_TE,
+	.te_clear = CCR0_TE | CCR0_TEIE,
+	.poll_sent_bits = CSR_TDRE | CSR_TEND,
+};
+
+static const struct sci_port_params rzsci_port_params = {
+	.fifosize = 16,
+	.overrun_reg = CSR,
+	.overrun_mask = CSR_ORER,
+	.sampling_rate_mask = SCI_SR(32),
+	.error_mask = RSCI_DEFAULT_ERROR_MASK,
+	.error_clear = RSCI_ERROR_CLEAR,
+	.param_bits = &rzsci_port_param_bits,
+	.common_regs = &rzsci_common_regs,
+};
+
+static const struct uart_ops rzt2_sci_uart_ops = {
+	.tx_empty	= rzsci_tx_empty,
+	.set_mctrl	= rzsci_set_mctrl,
+	.get_mctrl	= rzsci_get_mctrl,
+	.start_tx	= rzsci_start_tx,
+	.stop_tx	= rzsci_stop_tx,
+	.stop_rx	= rzsci_stop_rx,
+	.startup	= sci_startup,
+	.shutdown	= sci_shutdown,
+	.set_termios	= rzsci_set_termios,
+	.pm		= sci_pm,
+	.type		= rzsci_type,
+	.release_port	= sci_release_port,
+	.request_port	= sci_request_port,
+	.config_port	= sci_config_port,
+	.verify_port	= sci_verify_port,
+};
+
+static const struct sci_port_ops rzsci_port_ops = {
+	.read_reg		= rzsci_serial_in,
+	.write_reg		= rzsci_serial_out,
+	.clear_SCxSR		= rzsci_clear_SCxSR,
+	.transmit_chars		= rzsci_transmit_chars,
+	.receive_chars		= rzsci_receive_chars,
+	.poll_put_char		= rzsci_poll_put_char,
+	.prepare_console_write	= rzsci_prepare_console_write,
+	.suspend_regs_size	= rzsci_suspend_regs_size,
+};
+
+struct sci_of_data of_sci_r9a09g077_data = {
+	.type = PORT_RSCI,
+	.regtype = SCIx_RZT2H_SCI_REGTYPE,
+	.ops = &rzsci_port_ops,
+	.uart_ops = &rzt2_sci_uart_ops,
+	.params = &rzsci_port_params,
+};
+
+#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
+
+static int __init rzt2hsci_early_console_setup(struct earlycon_device *device,
+					       const char *opt)
+{
+	return scix_early_console_setup(device, &of_sci_r9a09g077_data);
+}
+
+OF_EARLYCON_DECLARE(rzsci, "renesas,r9a09g077-rsci", rzt2hsci_early_console_setup);
+
+#endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */
diff --git a/drivers/tty/serial/rsci.h b/drivers/tty/serial/rsci.h
new file mode 100644
index 000000000000..0a037af26267
--- /dev/null
+++ b/drivers/tty/serial/rsci.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __RSCI_H__
+#define __RSCI_H__
+
+#include "sh-sci-common.h"
+
+#ifdef CONFIG_SERIAL_RSCI
+extern struct sci_of_data of_sci_r9a09g077_data;
+#endif
+
+#endif /* __RSCI_H__ */
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 0ddf178a72f5..1a82c316c6eb 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -54,6 +54,7 @@
 #include <asm/platform_early.h>
 #endif
 
+#include "rsci.h"
 #include "serial_mctrl_gpio.h"
 #include "sh-sci.h"
 #include "sh-sci-common.h"
@@ -1820,7 +1821,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
 	unsigned long flags;
 	u32 ctrl;
 
-	if (port->type != PORT_SCI)
+	if (port->type != PORT_SCI && port->type != PORT_RSCI)
 		return sci_tx_interrupt(irq, ptr);
 
 	uart_port_lock_irqsave(port, &flags);
@@ -3069,10 +3070,10 @@ static int sci_init_single(struct platform_device *dev,
 	}
 
 	/*
-	 * The fourth interrupt on SCI port is transmit end interrupt, so
+	 * The fourth interrupt on SCI and RZSCI port is transmit end interrupt, so
 	 * shuffle the interrupts.
 	 */
-	if (p->type == PORT_SCI)
+	if (p->type == PORT_SCI || p->type == PORT_RSCI)
 		swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]);
 
 	/* The SCI generates several interrupts. They can be muxed together or
@@ -3106,6 +3107,9 @@ static int sci_init_single(struct platform_device *dev,
 		else
 			sci_port->rx_trigger = 8;
 		break;
+	case PORT_RSCI:
+		sci_port->rx_trigger = 15;
+		break;
 	default:
 		sci_port->rx_trigger = 1;
 		break;
@@ -3330,7 +3334,8 @@ static void sci_remove(struct platform_device *dev)
 
 	if (port->port.fifosize > 1)
 		device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger);
-	if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF)
+	if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF ||
+	    type == PORT_RSCI)
 		device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout);
 }
 
@@ -3424,6 +3429,12 @@ static const struct of_device_id of_sci_match[] __maybe_unused = {
 		.compatible = "renesas,scif-r9a09g057",
 		.data = &of_sci_scif_rzv2h,
 	},
+#ifdef CONFIG_SERIAL_RSCI
+	{
+		.compatible = "renesas,r9a09g077-rsci",
+		.data = &of_sci_r9a09g077_data,
+	},
+#endif	/* CONFIG_SERIAL_RSCI */
 	/* Family-specific types */
 	{
 		.compatible = "renesas,rcar-gen1-scif",
@@ -3683,7 +3694,7 @@ static int sci_probe(struct platform_device *dev)
 			return ret;
 	}
 	if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB ||
-	    sp->port.type == PORT_HSCIF) {
+	    sp->port.type == PORT_HSCIF || sp->port.type == PORT_RSCI) {
 		ret = device_create_file(&dev->dev, &dev_attr_rx_fifo_timeout);
 		if (ret) {
 			if (sp->port.fifosize > 1) {
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 0f2f50b8d28e..787fd9a96711 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -38,6 +38,7 @@ enum {
 	SCIx_HSCIF_REGTYPE,
 	SCIx_RZ_SCIFA_REGTYPE,
 	SCIx_RZV2H_SCIF_REGTYPE,
+	SCIx_RZT2H_SCI_REGTYPE,
 
 	SCIx_NR_REGTYPES,
 };
@@ -50,7 +51,7 @@ struct plat_sci_port_ops {
  * Platform device specific platform_data struct
  */
 struct plat_sci_port {
-	unsigned int	type;			/* SCI / SCIF / IRDA / HSCIF */
+	unsigned int	type;			/* SCI / SCIF / IRDA / HSCIF / RZSCI */
 	upf_t		flags;			/* UPF_* flags */
 
 	unsigned int	sampling_rate;
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 9c007a106330..c15011e96d16 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -231,6 +231,9 @@
 /* Sunplus UART */
 #define PORT_SUNPLUS	123
 
+/* SH-SCI */
+#define PORT_RSCI	124
+
 /* Generic type identifier for ports which type is not important to userspace. */
 #define PORT_GENERIC	(-1)
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 11/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (9 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 12/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 13/13] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	devicetree, linux-kernel

Add the initial dtsi for the RZ/T2H Soc:

- gic
- armv8-timer
- cpg clock
- sci0 uart

also add arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi, that keeps
all 4 CPUs enabled, for consistency with later support of -m24
and -m04 SoC revisions, that only have 2 and 1 Cortex-A55, respectively,
and that will use /delete-node/ to disable the missing CPUs.

Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7:
  - Renamed compatible string to r9a09g077-rsci
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4: none
---
 arch/arm64/boot/dts/renesas/r9a09g077.dtsi    | 129 ++++++++++++++++++
 arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi |  13 ++
 2 files changed, 142 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
new file mode 100644
index 000000000000..746bb93fdeb6
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/T2H SoC
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "renesas,r9a09g077";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	extal_clk: extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		l3_ca55: cache-controller-0 {
+			compatible = "cache";
+			cache-unified;
+			cache-size = <0x100000>;
+			cache-level = <3>;
+		};
+
+		cpu0: cpu@0 {
+			compatible = "arm,cortex-a55";
+			reg = <0>;
+			device_type = "cpu";
+			next-level-cache = <&l3_ca55>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu@100 {
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			device_type = "cpu";
+			next-level-cache = <&l3_ca55>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu@200 {
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			device_type = "cpu";
+			next-level-cache = <&l3_ca55>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu@300 {
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			device_type = "cpu";
+			next-level-cache = <&l3_ca55>;
+			enable-method = "psci";
+		};
+	};
+
+	loco_clk: loco {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board */
+		clock-frequency = <0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	soc: soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		sci0: serial@80005000 {
+			compatible = "renesas,r9a09g077-rsci";
+			reg = <0 0x80005000 0 0x400>;
+			interrupts = <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 591 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "eri", "rxi", "txi", "tei";
+			clocks = <&cpg CPG_MOD 108>;
+			clock-names = "fck";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		cpg: clock-controller@80280000 {
+			compatible = "renesas,r9a09g077-cpg-mssr";
+			reg = <0 0x80280000 0 0x1000>,
+			      <0 0x81280000 0 0x9000>;
+			clocks = <&extal_clk>, <&loco_clk>;
+			clock-names = "extal", "loco";
+			#clock-cells = <2>;
+			#reset-cells = <1>;
+			#power-domain-cells = <0>;
+		};
+
+		gic: interrupt-controller@83000000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x83000000 0 0x40000>,
+			      <0x0 0x83040000 0 0x160000>;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+				      <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi
new file mode 100644
index 000000000000..6f4a11b39d12
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/T2H 4-core SoC
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a09g077.dtsi"
+
+/ {
+	compatible = "renesas,r9a09g077m44", "renesas,r9a09g077";
+};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 12/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (10 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 11/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  2025-04-03 21:29 ` [PATCH v7 13/13] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	devicetree, linux-kernel

Add the initial device tree for the RZ/T2H evaluation board.

Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7:
  - lands in arm64 directory instead of arm
Changes v5->v6: rebased on next-20250331
Changes v4->v5: none
Changes v3->v4: none
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 .../dts/renesas/r9a09g077m44-rzt2h-evk.dts    | 35 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index d25e665ee4bf..14e2b41b6e13 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -152,6 +152,7 @@ dtb-$(CONFIG_ARCH_R9A09G011) += r9a09g011-v2mevk2.dtb
 
 dtb-$(CONFIG_ARCH_R9A09G047) += r9a09g047e57-smarc.dtb
 
+dtb-$(CONFIG_ARCH_R9A09G077) += r9a09g077m44-rzt2h-evk.dtb
 dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h44-rzv2h-evk.dtb
 dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h48-kakip.dtb
 
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
new file mode 100644
index 000000000000..c87b95468023
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+* Device Tree Source for the RZ/T2H Development EVK board
+*
+* Copyright (C) 2025 Renesas Electronics Corp.
+*/
+
+/dts-v1/;
+
+#include "r9a09g077m44.dtsi"
+
+/ {
+	model = "Renesas Development EVK based on r9a09g077m44";
+	compatible = "renesas,rzt2h-evk", "renesas,r9a09g077m44", "renesas,r9a09g077";
+
+	aliases {
+		serial0 = &sci0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&extal_clk {
+	clock-frequency = <25000000>;
+};
+
+&loco_clk {
+	clock-frequency = <1000000>;
+};
+
+&sci0 {
+	status = "okay";
+};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v7 13/13] arm64: defconfig: Enable Renesas RZ/T2H serial SCI
  2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
                   ` (11 preceding siblings ...)
  2025-04-03 21:29 ` [PATCH v7 12/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
@ 2025-04-03 21:29 ` Thierry Bultel
  12 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-03 21:29 UTC (permalink / raw)
  To: thierry.bultel
  Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
	Wolfram Sang, linux-arm-kernel, linux-kernel

Selects RZ/T2H (aka r9a09g077) SCI (serial) specific code.

Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v6->v7: none
Changes v5->v6:
   - Renamed CONFIG_SERIAL_RZ_SCI_T2 to CONFIG_SERIAL_RSCI
Changes v4->v5:
   - Renamed CONFIG_SERIAL_RZ_SCI to CONFIG_SERIAL_RZ_SCI_T2
Changes v3->v4:
   - Remove CONFIG_ARCH_R9A09G077=y
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 5bb8f09422a2..fcfc7b2e5819 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -494,6 +494,7 @@ CONFIG_SERIAL_TEGRA_TCU=y
 CONFIG_SERIAL_IMX=y
 CONFIG_SERIAL_IMX_CONSOLE=y
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_RSCI=y
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_QCOM_GENI=y
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
  2025-04-03 21:29 ` [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-04 19:37   ` Rob Herring (Arm)
  2025-04-17 13:41   ` Geert Uytterhoeven
  1 sibling, 0 replies; 35+ messages in thread
From: Rob Herring (Arm) @ 2025-04-04 19:37 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: linux-kernel, Geert Uytterhoeven, thierry.bultel,
	linux-renesas-soc, geert, paul.barker.ct, linux-clk, devicetree


On Thu, 03 Apr 2025 23:29:04 +0200, Thierry Bultel wrote:
> Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding.
> 
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v6->v7:
>   - Add description for reg property
> Changes v5->v6:
>   - Set clock minItem constraint
>   - Moved additionalProperties after 'allOf' section
> Changes v4->v5:
>   - Set reg minItems and maxItems defaults at top level
> Changes v3->v4:
>   - Handle maxItems and clocks names properly in schema.
> ---
>  .../bindings/clock/renesas,cpg-mssr.yaml      | 61 ++++++++++++++-----
>  .../clock/renesas,r9a09g077-cpg-mssr.h        | 49 +++++++++++++++
>  2 files changed, 94 insertions(+), 16 deletions(-)
>  create mode 100644 include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-03 21:29 ` [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
@ 2025-04-11 14:57   ` Greg KH
  2025-04-14  7:54     ` Thierry Bultel
  2025-04-17 12:53   ` Geert Uytterhoeven
  1 sibling, 1 reply; 35+ messages in thread
From: Greg KH @ 2025-04-11 14:57 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, geert, paul.barker.ct,
	Wolfram Sang, linux-kernel, linux-serial

On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
> --- a/include/uapi/linux/serial_core.h
> +++ b/include/uapi/linux/serial_core.h
> @@ -231,6 +231,9 @@
>  /* Sunplus UART */
>  #define PORT_SUNPLUS	123
>  
> +/* SH-SCI */
> +#define PORT_RSCI	124

Why do you need to tell userspace about this specific port?  Is that a
hard requirement that your userspace tools require?  If not, please
don't export this here.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-11 14:57   ` Greg KH
@ 2025-04-14  7:54     ` Thierry Bultel
  2025-04-14  8:58       ` Greg KH
  0 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-14  7:54 UTC (permalink / raw)
  To: Greg KH
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	geert@linux-m68k.org, Paul Barker, Wolfram Sang,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org

Hi Greg,

> -----Original Message-----
> From: Greg KH <gregkh@linuxfoundation.org>
> Sent: vendredi 11 avril 2025 16:57
> To: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> Cc: thierry.bultel@linatsea.fr; linux-renesas-soc@vger.kernel.org;
> geert@linux-m68k.org; Paul Barker <paul.barker.ct@bp.renesas.com>; Wolfram
> Sang <wsa+renesas@sang-engineering.com>; linux-kernel@vger.kernel.org;
> linux-serial@vger.kernel.org
> Subject: Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
> 
> On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
> > --- a/include/uapi/linux/serial_core.h
> > +++ b/include/uapi/linux/serial_core.h
> > @@ -231,6 +231,9 @@
> >  /* Sunplus UART */
> >  #define PORT_SUNPLUS	123
> >
> > +/* SH-SCI */
> > +#define PORT_RSCI	124
> 
> Why do you need to tell userspace about this specific port?  Is that a
> hard requirement that your userspace tools require?  If not, please don't
> export this here.

This point has been discussed with Geert and Wolfram.
We cannot use PORT_GENERIC for this IP, and adding the new type
is just keeping consistent with the sh-sci driver.

Thanks
Thierry

> 
> thanks,
> 
> greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-14  7:54     ` Thierry Bultel
@ 2025-04-14  8:58       ` Greg KH
  2025-04-14  9:23         ` Thierry Bultel
  0 siblings, 1 reply; 35+ messages in thread
From: Greg KH @ 2025-04-14  8:58 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	geert@linux-m68k.org, Paul Barker, Wolfram Sang,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org

On Mon, Apr 14, 2025 at 07:54:12AM +0000, Thierry Bultel wrote:
> Hi Greg,
> 
> > -----Original Message-----
> > From: Greg KH <gregkh@linuxfoundation.org>
> > Sent: vendredi 11 avril 2025 16:57
> > To: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> > Cc: thierry.bultel@linatsea.fr; linux-renesas-soc@vger.kernel.org;
> > geert@linux-m68k.org; Paul Barker <paul.barker.ct@bp.renesas.com>; Wolfram
> > Sang <wsa+renesas@sang-engineering.com>; linux-kernel@vger.kernel.org;
> > linux-serial@vger.kernel.org
> > Subject: Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
> > 
> > On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
> > > --- a/include/uapi/linux/serial_core.h
> > > +++ b/include/uapi/linux/serial_core.h
> > > @@ -231,6 +231,9 @@
> > >  /* Sunplus UART */
> > >  #define PORT_SUNPLUS	123
> > >
> > > +/* SH-SCI */
> > > +#define PORT_RSCI	124
> > 
> > Why do you need to tell userspace about this specific port?  Is that a
> > hard requirement that your userspace tools require?  If not, please don't
> > export this here.
> 
> This point has been discussed with Geert and Wolfram.
> We cannot use PORT_GENERIC for this IP, and adding the new type
> is just keeping consistent with the sh-sci driver.

But, why does userspace need to know this number?  And why doesn't
PORT_GENERIC work?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-14  8:58       ` Greg KH
@ 2025-04-14  9:23         ` Thierry Bultel
  2025-04-14  9:32           ` Greg KH
  0 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-14  9:23 UTC (permalink / raw)
  To: Greg KH, Thierry Bultel
  Cc: linux-renesas-soc@vger.kernel.org, geert@linux-m68k.org,
	Paul Barker, Wolfram Sang, linux-kernel@vger.kernel.org,
	linux-serial@vger.kernel.org



Le 14/04/2025 à 10:58, Greg KH a écrit :
> On Mon, Apr 14, 2025 at 07:54:12AM +0000, Thierry Bultel wrote:
>> Hi Greg,
>>
>>> -----Original Message-----
>>> From: Greg KH <gregkh@linuxfoundation.org>
>>> Sent: vendredi 11 avril 2025 16:57
>>> To: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
>>> Cc: thierry.bultel@linatsea.fr; linux-renesas-soc@vger.kernel.org;
>>> geert@linux-m68k.org; Paul Barker <paul.barker.ct@bp.renesas.com>; Wolfram
>>> Sang <wsa+renesas@sang-engineering.com>; linux-kernel@vger.kernel.org;
>>> linux-serial@vger.kernel.org
>>> Subject: Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
>>>
>>> On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
>>>> --- a/include/uapi/linux/serial_core.h
>>>> +++ b/include/uapi/linux/serial_core.h
>>>> @@ -231,6 +231,9 @@
>>>>   /* Sunplus UART */
>>>>   #define PORT_SUNPLUS	123
>>>>
>>>> +/* SH-SCI */
>>>> +#define PORT_RSCI	124
>>> Why do you need to tell userspace about this specific port?  Is that a
>>> hard requirement that your userspace tools require?  If not, please don't
>>> export this here.
>> This point has been discussed with Geert and Wolfram.
>> We cannot use PORT_GENERIC for this IP, and adding the new type
>> is just keeping consistent with the sh-sci driver.
> But, why does userspace need to know this number?  And why doesn't
> PORT_GENERIC work?

The reason is that the sh-sci driver discriminates internally between 
port types.
There are number of locations when it checks for PORT_SCI, PORT_SCIF, 
PORT_SCIFA...
T2H SCI needs special handling, too, that is the reason why PORT_GENERIC 
cannot work. I just therefore added this new type.

>
> thanks,
>
> greg k-h


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-14  9:23         ` Thierry Bultel
@ 2025-04-14  9:32           ` Greg KH
  2025-04-14 14:07             ` Geert Uytterhoeven
  0 siblings, 1 reply; 35+ messages in thread
From: Greg KH @ 2025-04-14  9:32 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: Thierry Bultel, linux-renesas-soc@vger.kernel.org,
	geert@linux-m68k.org, Paul Barker, Wolfram Sang,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org

On Mon, Apr 14, 2025 at 11:23:34AM +0200, Thierry Bultel wrote:
> 
> 
> Le 14/04/2025 à 10:58, Greg KH a écrit :
> > On Mon, Apr 14, 2025 at 07:54:12AM +0000, Thierry Bultel wrote:
> > > Hi Greg,
> > > 
> > > > -----Original Message-----
> > > > From: Greg KH <gregkh@linuxfoundation.org>
> > > > Sent: vendredi 11 avril 2025 16:57
> > > > To: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> > > > Cc: thierry.bultel@linatsea.fr; linux-renesas-soc@vger.kernel.org;
> > > > geert@linux-m68k.org; Paul Barker <paul.barker.ct@bp.renesas.com>; Wolfram
> > > > Sang <wsa+renesas@sang-engineering.com>; linux-kernel@vger.kernel.org;
> > > > linux-serial@vger.kernel.org
> > > > Subject: Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
> > > > 
> > > > On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
> > > > > --- a/include/uapi/linux/serial_core.h
> > > > > +++ b/include/uapi/linux/serial_core.h
> > > > > @@ -231,6 +231,9 @@
> > > > >   /* Sunplus UART */
> > > > >   #define PORT_SUNPLUS	123
> > > > > 
> > > > > +/* SH-SCI */
> > > > > +#define PORT_RSCI	124
> > > > Why do you need to tell userspace about this specific port?  Is that a
> > > > hard requirement that your userspace tools require?  If not, please don't
> > > > export this here.
> > > This point has been discussed with Geert and Wolfram.
> > > We cannot use PORT_GENERIC for this IP, and adding the new type
> > > is just keeping consistent with the sh-sci driver.
> > But, why does userspace need to know this number?  And why doesn't
> > PORT_GENERIC work?
> 
> The reason is that the sh-sci driver discriminates internally between port
> types.
> There are number of locations when it checks for PORT_SCI, PORT_SCIF,
> PORT_SCIFA...

That is internal to the kernel, not external, right?

> T2H SCI needs special handling, too, that is the reason why PORT_GENERIC
> cannot work. I just therefore added this new type.

Again, why does userspace need to know this?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-14  9:32           ` Greg KH
@ 2025-04-14 14:07             ` Geert Uytterhoeven
  2025-04-15 12:35               ` Greg KH
  0 siblings, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-14 14:07 UTC (permalink / raw)
  To: Greg KH
  Cc: Thierry Bultel, Thierry Bultel, linux-renesas-soc@vger.kernel.org,
	Paul Barker, Wolfram Sang, linux-kernel@vger.kernel.org,
	linux-serial@vger.kernel.org

Hi Greg,

On Mon, 14 Apr 2025 at 11:32, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Mon, Apr 14, 2025 at 11:23:34AM +0200, Thierry Bultel wrote:
> > Le 14/04/2025 à 10:58, Greg KH a écrit :
> > > On Mon, Apr 14, 2025 at 07:54:12AM +0000, Thierry Bultel wrote:
> > > > > From: Greg KH <gregkh@linuxfoundation.org>
 > > > > On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
> > > > > > --- a/include/uapi/linux/serial_core.h
> > > > > > +++ b/include/uapi/linux/serial_core.h
> > > > > > @@ -231,6 +231,9 @@
> > > > > >   /* Sunplus UART */
> > > > > >   #define PORT_SUNPLUS        123
> > > > > >
> > > > > > +/* SH-SCI */
> > > > > > +#define PORT_RSCI    124
> > > > > Why do you need to tell userspace about this specific port?  Is that a
> > > > > hard requirement that your userspace tools require?  If not, please don't
> > > > > export this here.
> > > > This point has been discussed with Geert and Wolfram.
> > > > We cannot use PORT_GENERIC for this IP, and adding the new type
> > > > is just keeping consistent with the sh-sci driver.
> > > But, why does userspace need to know this number?  And why doesn't
> > > PORT_GENERIC work?
> >
> > The reason is that the sh-sci driver discriminates internally between port
> > types.
> > There are number of locations when it checks for PORT_SCI, PORT_SCIF,
> > PORT_SCIFA...
>
> That is internal to the kernel, not external, right?

Indeed.

> > T2H SCI needs special handling, too, that is the reason why PORT_GENERIC
> > cannot work. I just therefore added this new type.
>
> Again, why does userspace need to know this?

I guess userspace does not need to know about this (does userspace
actually care about any of these values, except for PORT_8250 and
friends?).

However, traditionally PORT_* has been used as the differentiator
for serial port types in most drivers in the kernel (incl. sh-sci.c)
as well.  Just two drivers use PORT_GENERIC, and these are the ones
that came with the introduction of PORT_GENERIC.  Since the rsci driver
is not a new driver, but a sub-driver of the existing sh-sci driver,
I think it warrants keeping on using the type field, like before. Else
it will have to become even more complex than it already is.

Note I am fine with using a non-uapi value. Is there a PORT_* number
range meant for internal (non-uapi) use?
Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-14 14:07             ` Geert Uytterhoeven
@ 2025-04-15 12:35               ` Greg KH
  0 siblings, 0 replies; 35+ messages in thread
From: Greg KH @ 2025-04-15 12:35 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Thierry Bultel, Thierry Bultel, linux-renesas-soc@vger.kernel.org,
	Paul Barker, Wolfram Sang, linux-kernel@vger.kernel.org,
	linux-serial@vger.kernel.org

On Mon, Apr 14, 2025 at 04:07:23PM +0200, Geert Uytterhoeven wrote:
> Hi Greg,
> 
> On Mon, 14 Apr 2025 at 11:32, Greg KH <gregkh@linuxfoundation.org> wrote:
> > On Mon, Apr 14, 2025 at 11:23:34AM +0200, Thierry Bultel wrote:
> > > Le 14/04/2025 à 10:58, Greg KH a écrit :
> > > > On Mon, Apr 14, 2025 at 07:54:12AM +0000, Thierry Bultel wrote:
> > > > > > From: Greg KH <gregkh@linuxfoundation.org>
>  > > > > On Thu, Apr 03, 2025 at 11:29:12PM +0200, Thierry Bultel wrote:
> > > > > > > --- a/include/uapi/linux/serial_core.h
> > > > > > > +++ b/include/uapi/linux/serial_core.h
> > > > > > > @@ -231,6 +231,9 @@
> > > > > > >   /* Sunplus UART */
> > > > > > >   #define PORT_SUNPLUS        123
> > > > > > >
> > > > > > > +/* SH-SCI */
> > > > > > > +#define PORT_RSCI    124
> > > > > > Why do you need to tell userspace about this specific port?  Is that a
> > > > > > hard requirement that your userspace tools require?  If not, please don't
> > > > > > export this here.
> > > > > This point has been discussed with Geert and Wolfram.
> > > > > We cannot use PORT_GENERIC for this IP, and adding the new type
> > > > > is just keeping consistent with the sh-sci driver.
> > > > But, why does userspace need to know this number?  And why doesn't
> > > > PORT_GENERIC work?
> > >
> > > The reason is that the sh-sci driver discriminates internally between port
> > > types.
> > > There are number of locations when it checks for PORT_SCI, PORT_SCIF,
> > > PORT_SCIFA...
> >
> > That is internal to the kernel, not external, right?
> 
> Indeed.
> 
> > > T2H SCI needs special handling, too, that is the reason why PORT_GENERIC
> > > cannot work. I just therefore added this new type.
> >
> > Again, why does userspace need to know this?
> 
> I guess userspace does not need to know about this (does userspace
> actually care about any of these values, except for PORT_8250 and
> friends?).
> 
> However, traditionally PORT_* has been used as the differentiator
> for serial port types in most drivers in the kernel (incl. sh-sci.c)
> as well.  Just two drivers use PORT_GENERIC, and these are the ones
> that came with the introduction of PORT_GENERIC.  Since the rsci driver
> is not a new driver, but a sub-driver of the existing sh-sci driver,
> I think it warrants keeping on using the type field, like before. Else
> it will have to become even more complex than it already is.
> 
> Note I am fine with using a non-uapi value. Is there a PORT_* number
> range meant for internal (non-uapi) use?

We can just start putting them in a non-uapi file so that we don't have
to keep adding things to userspace that never needs it.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI
  2025-04-03 21:29 ` [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
  2025-04-11 14:57   ` Greg KH
@ 2025-04-17 12:53   ` Geert Uytterhoeven
  1 sibling, 0 replies; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-17 12:53 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, Wolfram Sang,
	linux-kernel, linux-serial

Hi Thierry,

On Thu, 3 Apr 2025 at 23:30, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Define a new RSCI port type, and the RSCI 32 bits registers set.
> The RZ/T2H SCI has a a fifo, and a quite different set of registers
> from the orginal SH SCI ones.
> DMA is not supported yet.
>
> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v6->v7:
>   - Renamed compatible string to r9a09g077-rsci

Thanks for the update!

Just some cosmetic comments...

> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -675,6 +675,13 @@ config SERIAL_SH_SCI_DMA
>         depends on SERIAL_SH_SCI && DMA_ENGINE
>         default ARCH_RENESAS
>
> +config SERIAL_RSCI
> +       tristate "Support for Renesas RZ/T2H SCI variant"
> +       depends on SERIAL_SH_SCI
> +       help
> +         Support for the RZ/T2H SCI variant with fifo.

FIFO

> +         Say Y if you want to be able to use the RZ/T2H SCI serial port.
> +
>  config SERIAL_HS_LPC32XX
>         tristate "LPC32XX high speed serial port support"
>         depends on ARCH_LPC32XX || COMPILE_TEST

> --- /dev/null
> +++ b/drivers/tty/serial/rsci.c

> +static u32 rzsci_serial_in(struct uart_port *p, int offset)

rsci_* (everywhere)

> +{
> +       return readl(p->membase + offset);
> +}

> +static void rzsci_prepare_console_write(struct uart_port *port, u32 ctrl)
> +{
> +       struct sci_port *s = to_sci_port(port);
> +       u32 ctrl_temp =
> +               s->params->param_bits->rxtx_enable |
> +               CCR0_TIE |
> +               s->hscif_tot;

        u32 ctrl_temp = s->params->param_bits->rxtx_enable | CCR0_TIE |
                        s->hscif_tot;

> +       rzsci_serial_out(port, CCR0, ctrl_temp);
> +}

> +static const struct uart_ops rzt2_sci_uart_ops = {

rsci_uart_ops

> +       .tx_empty       = rzsci_tx_empty,
> +       .set_mctrl      = rzsci_set_mctrl,
> +       .get_mctrl      = rzsci_get_mctrl,
> +       .start_tx       = rzsci_start_tx,
> +       .stop_tx        = rzsci_stop_tx,
> +       .stop_rx        = rzsci_stop_rx,
> +       .startup        = sci_startup,
> +       .shutdown       = sci_shutdown,
> +       .set_termios    = rzsci_set_termios,
> +       .pm             = sci_pm,
> +       .type           = rzsci_type,
> +       .release_port   = sci_release_port,
> +       .request_port   = sci_request_port,
> +       .config_port    = sci_config_port,
> +       .verify_port    = sci_verify_port,
> +};
> +
> +static const struct sci_port_ops rzsci_port_ops = {

rsci_port_ops

> +       .read_reg               = rzsci_serial_in,
> +       .write_reg              = rzsci_serial_out,
> +       .clear_SCxSR            = rzsci_clear_SCxSR,
> +       .transmit_chars         = rzsci_transmit_chars,
> +       .receive_chars          = rzsci_receive_chars,
> +       .poll_put_char          = rzsci_poll_put_char,
> +       .prepare_console_write  = rzsci_prepare_console_write,
> +       .suspend_regs_size      = rzsci_suspend_regs_size,
> +};
> +
> +struct sci_of_data of_sci_r9a09g077_data = {

of_sci_rsci_data

> +       .type = PORT_RSCI,
> +       .regtype = SCIx_RZT2H_SCI_REGTYPE,
> +       .ops = &rzsci_port_ops,
> +       .uart_ops = &rzt2_sci_uart_ops,
> +       .params = &rzsci_port_params,
> +};
> +
> +#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
> +
> +static int __init rzt2hsci_early_console_setup(struct earlycon_device *device,
> +                                              const char *opt)

rsci_early_console_setup

> +{
> +       return scix_early_console_setup(device, &of_sci_r9a09g077_data);
> +}
> +
> +OF_EARLYCON_DECLARE(rzsci, "renesas,r9a09g077-rsci", rzt2hsci_early_console_setup);
> +
> +#endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */

> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> --- a/include/linux/serial_sci.h
> +++ b/include/linux/serial_sci.h
> @@ -38,6 +38,7 @@ enum {
>         SCIx_HSCIF_REGTYPE,
>         SCIx_RZ_SCIFA_REGTYPE,
>         SCIx_RZV2H_SCIF_REGTYPE,
> +       SCIx_RZT2H_SCI_REGTYPE,

SCIx_RSCI_REGTYPE?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC
  2025-04-03 21:29 ` [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
@ 2025-04-17 13:39   ` Geert Uytterhoeven
  0 siblings, 0 replies; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-17 13:39 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, Rob Herring,
	devicetree, linux-kernel

On Thu, 3 Apr 2025 at 23:29, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Add RZ/T2H (R9A09G077), its variants, and the rt2h-evk evaluation board in
> documentation.
>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in renesas-devel for v6.16.

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
  2025-04-03 21:29 ` [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
  2025-04-04 19:37   ` Rob Herring (Arm)
@ 2025-04-17 13:41   ` Geert Uytterhoeven
  2025-04-18  9:29     ` Thierry Bultel
  1 sibling, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-17 13:41 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-clk,
	devicetree, linux-kernel

Hi Thierry,

On Thu, 3 Apr 2025 at 23:29, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>

Thanks for your patch!

> --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
> +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
> @@ -52,9 +52,15 @@ properties:
>        - renesas,r8a779f0-cpg-mssr # R-Car S4-8
>        - renesas,r8a779g0-cpg-mssr # R-Car V4H
>        - renesas,r8a779h0-cpg-mssr # R-Car V4M
> +      - renesas,r9a09g077-cpg-mssr # RZ/T2H
>
>    reg:
> -    maxItems: 1
> +    minItems: 1
> +    items:
> +      - description: base address of register block 0
> +      - description: base address of register block 1
> +    description: base addresses of clock controller. Some controllers
> +      (like r9a09g077) use two blocks instead of a single one).

Non-matching closing parenthesis at the end of the line.

> @@ -111,6 +102,44 @@ required:
>    - '#clock-cells'
>    - '#power-domain-cells'
>
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: renesas,r9a09g077-cpg-mssr
> +    then:
> +      properties:
> +        reg:
> +          minItems: 2
> +        clocks:
> +          minItems: 2
> +        clock-names:
> +          items:
> +            - const: extal

There are actually two external clock inputs:
  1. Crystal resonator between XTAL and EXTAL pins,
  2. Clock signal input to the EXTCLKIN pin.
Given they are mutually-exclusive, and the choice is made by an
external input signal (XTALSEL) which cannot be read from software,
I think it is fine to model this as a single "extal" input clock.

> +            - const: loco

LOCO is the Low-Speed On-Chip Oscillator, i.e. on-chip, and thus
not an external clock input.

> +    else:
> +      properties:
> +        reg:
> +          maxItems: 1
> +        clock-names:
> +          items:
> +            enum:
> +              - extal     # All
> +              - extalr    # Most R-Car Gen3 and RZ/G2
> +              - usb_extal # Most R-Car Gen2 and RZ/G1
> +
> +  - if:
> +      not:
> +        properties:
> +          compatible:
> +            items:
> +              enum:
> +                - renesas,r7s9210-cpg-mssr
> +    then:
> +      required:
> +        - '#reset-cells'
> +
>  additionalProperties: false
>
>  examples:

> --- /dev/null
> +++ b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
> @@ -0,0 +1,49 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> + *
> + * Copyright (C) 2025 Renesas Electronics Corp.
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
> +#define __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
> +
> +#include <dt-bindings/clock/renesas-cpg-mssr.h>
> +
> +/* R9A09G077 CPG Core Clocks */
> +#define R9A09G077_CA55C0               0
> +#define R9A09G077_CA55C1               1
> +#define R9A09G077_CA55C2               2
> +#define R9A09G077_CA55C3               3
> +#define R9A09G077_SDHIHS               4
> +#define R9A09G077_CLK_PLL1_ETH_PHY     5
> +#define R9A09G077_CLK_OSC_ETH_PHY      6
> +#define R9A09G077_CLK_ETHPHY           7

I can't find these 3 clocks?

Table 7.2 "Specifications of Clock Generation Circuit (internal clock)"
Figure 7.1" Block diagram of clock generation circuit"

> +#define R9A09G077_PCLKAH               8
> +#define R9A09G077_PCLKAM               9
> +#define R9A09G077_PCLKAL               10
> +#define R9A09G077_CLK_SEL_ETH_PHY      11

I can't find this clock?

> +#define R9A09G077_DFI                  12
> +#define R9A09G077_PCLKH                        13
> +#define R9A09G077_PCLKM                        14
> +#define R9A09G077_PCLKL                        15
> +#define R9A09G077_PCLKGPTL             16
> +#define R9A09G077_PCLKSHOST            17
> +#define R9A09G077_PCLKRTC              18
> +#define R9A09G077_USB                  19
> +#define R9A09G077_SPI0                 20
> +#define R9A09G077_SPI1                 21
> +#define R9A09G077_SPI2                 22
> +#define R9A09G077_SPI3                 23

R9A09G077_XSPI[0-3]?

> +#define R9A09G077_ETCLKA               24
> +#define R9A09G077_ETCLKB               25
> +#define R9A09G077_ETCLKC               26
> +#define R9A09G077_ETCLKD               27
> +#define R9A09G077_ETCLKE               28
> +#define R9A09G077_ETHCLKE              29

I can't find this clock?

> +#define R9A09G077_ETHCLK_EXTAL         30
> +#define R9A09G077_ETH_REFCLK           31

There are four of these? R9A09G077_ETH[0-3]_REFCLK?

> +#define R9A09G077_LCDC_CLKA            32
> +#define R9A09G077_LCDC_CLKP            33

I can't find these 2 clocks?

> +#define R9A09G077_CA55                 34

R9A09G077_CA55S?

> +#define R9A09G077_LCDC_CLKD            35

Some clocks seem to be missing, but you can always add them later
(this file is an ABI, i.e. append-only).

> +
> +#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 03/13] dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci
  2025-04-03 21:29 ` [PATCH v7 03/13] dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci Thierry Bultel
@ 2025-04-17 14:04   ` Geert Uytterhoeven
  0 siblings, 0 replies; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-17 14:04 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, Rob Herring,
	Geert Uytterhoeven, linux-kernel, linux-serial, devicetree

Hi Thierry,

On Thu, 3 Apr 2025 at 23:29, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> RSCI of RZ/T2H SoC (a.k.a r9a09g077), as a lot
> of similarities with SCI in other Renesas SoC like G2L, G3S, V2L;
> However, it has a different set of registers, and in addition to serial,
> this IP also supports SCIe (encoder), SmartCard, i2c and spi.
> This is why the 'renesas,sci' fallback for generic SCI does not apply for it.
>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v6->v7:
>   - Moved all rsci in a separate file
>   - Added example

Thanks for your patch, which is now commit 25422e8f46c1fd14
("dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci")
in tty/tty-next.

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml

> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/renesas-cpg-mssr.h>
> +
> +    aliases {
> +        serial0 = &sci0;
> +    };

Aliases are not really needed in examples; the DT janitors may send
a patch to remove this ;-).

> +
> +    sci0: serial@80005000 {
> +        compatible = "renesas,r9a09g077-rsci";
> +        reg = <0x80005000 0x400>;
> +        interrupts = <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 591 IRQ_TYPE_EDGE_RISING>,
> +                     <GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
> +                     <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "eri", "rxi", "txi", "tei";
> +        clocks = <&cpg CPG_MOD 108>;

Shouldn't that be 8 instead of 108?
Doesn't matter much, as this file is just an example...

> +        clock-names = "fck";
> +        power-domains = <&cpg>;
> +    };

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register
  2025-04-03 21:29 ` [PATCH v7 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
@ 2025-04-17 14:15   ` Geert Uytterhoeven
  0 siblings, 0 replies; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-17 14:15 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-clk,
	linux-kernel

Hi Thierry,

On Thu, 3 Apr 2025 at 23:30, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> In a subsequent patch, the registration callback will need more parameters
> from cpg_mssr_priv (like another base address with clock controllers
> with double register block, and also, notifiers and rmw_lock).
> Instead of adding more parameters, move the needed parameters to a public
> sub-struct.
> Instead moving clks to this structure, which would have implied to add
> an allocation (and cleanup) for it, keep the way the allocation is done
> and just have a copy of the pointer in the public structure.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>

Thanks for your patch!

> --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
> +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
> @@ -218,11 +218,13 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
>  }
>
>  static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
> -       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
> -       struct clk **clks, void __iomem *base,
> -       struct raw_notifier_head *notifiers)
> +       const struct cpg_core_clk *core,
> +       const struct cpg_mssr_info *info,

These two still fit on a single line, like before.

> +       struct cpg_mssr_pub *pub)
>  {
>         const struct clk_div_table *table;
> +       void __iomem *base = pub->base0;
> +       struct clk **clks = pub->clks;
>         const struct clk *parent;
>         unsigned int shift;
>

> --- a/drivers/clk/renesas/rcar-gen3-cpg.h
> +++ b/drivers/clk/renesas/rcar-gen3-cpg.h
> @@ -80,9 +80,9 @@ struct rcar_gen3_cpg_pll_config {
>  #define CPG_RCKCR      0x240
>
>  struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
> -       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
> -       struct clk **clks, void __iomem *base,
> -       struct raw_notifier_head *notifiers);
> +       const struct cpg_core_clk *core,
> +       const struct cpg_mssr_info *info,

Likewise.

> +       struct cpg_mssr_pub *pub);
>  int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
>                        unsigned int clk_extalr, u32 mode);
>

> --- a/drivers/clk/renesas/rcar-gen4-cpg.c
> +++ b/drivers/clk/renesas/rcar-gen4-cpg.c
> @@ -418,9 +418,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = {
>
>  struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
>         const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
> -       struct clk **clks, void __iomem *base,
> -       struct raw_notifier_head *notifiers)
> +       struct cpg_mssr_pub *pub)
>  {
> +       struct raw_notifier_head *notifiers = &pub->notifiers;
> +       void __iomem *base = pub->base0;
> +       struct clk **clks = pub->clks;
>         const struct clk *parent;
>         unsigned int mult = 1;
>         unsigned int div = 1;
> @@ -517,7 +519,7 @@ struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
>
>         case CLK_TYPE_GEN4_RPC:
>                 return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR,
> -                                           __clk_get_name(parent), notifiers);
> +                                           __clk_get_name(parent), &pub->notifiers);

Please drop this unneeded change.

>
>         case CLK_TYPE_GEN4_RPCD2:
>                 return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR,

> --- a/drivers/clk/renesas/renesas-cpg-mssr.c
> +++ b/drivers/clk/renesas/renesas-cpg-mssr.c
> @@ -127,14 +127,12 @@ static const u16 srstclr_for_gen4[] = {
>   *
>   * @rcdev: Optional reset controller entity
>   * @dev: CPG/MSSR device
> - * @base: CPG/MSSR register block base address
>   * @reg_layout: CPG/MSSR register layout
>   * @rmw_lock: protects RMW register accesses

rmw_lock is removed below.

>   * @np: Device node in DT for this CPG/MSSR module
>   * @num_core_clks: Number of Core Clocks in clks[]
>   * @num_mod_clks: Number of Module Clocks in clks[]
>   * @last_dt_core_clk: ID of the last Core Clock exported to DT
> - * @notifiers: Notifier chain to save/restore clock state for system resume
>   * @status_regs: Pointer to status registers array
>   * @control_regs: Pointer to control registers array
>   * @reset_regs: Pointer to reset registers array
> @@ -143,6 +141,7 @@ static const u16 srstclr_for_gen4[] = {
>   *                 [].val: Saved values of SMSTPCR[]
>   * @reserved_ids: Temporary used, reserved id list
>   * @num_reserved_ids: Temporary used, number of reserved id list
> + * @pub: Data passed to clock registration callback
>   * @clks: Array containing all Core and Module Clocks
>   */
>  struct cpg_mssr_priv {
> @@ -150,16 +149,13 @@ struct cpg_mssr_priv {
>         struct reset_controller_dev rcdev;
>  #endif
>         struct device *dev;
> -       void __iomem *base;
>         enum clk_reg_layout reg_layout;
> -       spinlock_t rmw_lock;
>         struct device_node *np;
>
>         unsigned int num_core_clks;
>         unsigned int num_mod_clks;
>         unsigned int last_dt_core_clk;
>
> -       struct raw_notifier_head notifiers;
>         const u16 *status_regs;
>         const u16 *control_regs;
>         const u16 *reset_regs;
> @@ -172,6 +168,7 @@ struct cpg_mssr_priv {
>         unsigned int *reserved_ids;
>         unsigned int num_reserved_ids;
>
> +       struct cpg_mssr_pub pub;

Perhaps insert this at the top of the structure, so &priv->pub needs
no calculation?

>         struct clk *clks[];
>  };

> --- a/drivers/clk/renesas/renesas-cpg-mssr.h
> +++ b/drivers/clk/renesas/renesas-cpg-mssr.h

> @@ -27,6 +29,21 @@ struct cpg_core_clk {
>         unsigned int div;
>         unsigned int mult;
>         unsigned int offset;
> +
> +/**
> + * struct cpg_mssr_pub - Private data shared with

The "private" sounds a bit weird here, so please just drop it.

> + * device-specific clk registration code
> + *
> + * @base0: CPG/MSSR register block base0 address
> + * @rmw_lock: protects RMW register accesses
> + * @notifiers: Notifier chain to save/restore clock state for system resume

These two lines should be exchanged, to match the declaration order
below.

> + * @clks: pointer to clocks
> + */
> +struct cpg_mssr_pub {
> +       void __iomem *base0;
> +       struct raw_notifier_head notifiers;
> +       spinlock_t rmw_lock;
> +       struct clk **clks;
>  };
>
>  enum clk_types {

The rest LGTM.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-03 21:29 ` [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
@ 2025-04-17 18:45   ` Geert Uytterhoeven
  2025-04-18 21:22     ` Thierry Bultel
  0 siblings, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-17 18:45 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-kernel,
	linux-clk

Hi Thierry,

Thanks for your patch!

On Thu, 3 Apr 2025 at 23:30, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> RZ/T2H has 2 registers blocks at different addresses.

register

> The clock tree has configurable dividers and mux selectors.
> Add these new clock types, new register layout type, and
> registration code for mux and div in registration callback.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>

> --- a/drivers/clk/renesas/Makefile
> +++ b/drivers/clk/renesas/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_R8A779A0)            += r8a779a0-cpg-mssr.o
>  obj-$(CONFIG_CLK_R8A779F0)             += r8a779f0-cpg-mssr.o
>  obj-$(CONFIG_CLK_R8A779G0)             += r8a779g0-cpg-mssr.o
>  obj-$(CONFIG_CLK_R8A779H0)             += r8a779h0-cpg-mssr.o
> +obj-$(CONFIG_CLK_R9A09G077)            += r9a09g077-cpg-mssr.o

Please keep the list sorted.

>  obj-$(CONFIG_CLK_R9A06G032)            += r9a06g032-clocks.o
>  obj-$(CONFIG_CLK_R9A07G043)            += r9a07g043-cpg.o
>  obj-$(CONFIG_CLK_R9A07G044)            += r9a07g044-cpg.o
> diff --git a/drivers/clk/renesas/r9a09g077-cpg-mssr.c b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
> new file mode 100644
> index 000000000000..b67dbf5d59d8
> --- /dev/null
> +++ b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
> @@ -0,0 +1,238 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * r9a09g077 Clock Pulse Generator / Module Standby and Software Reset
> + *
> + * Copyright (C) 2025 Renesas Electronics Corp.
> + *
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +
> +#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
> +#include "renesas-cpg-mssr.h"
> +
> +#define SCKCR          0x00
> +#define SCKCR2         0x04

Please add comments to indicate whether an offset is against base0
(e.g. SCKCR) or base1 (e.g. SCKCR2).

Perhaps encode it in a high-bit, like for the MSTPCRx registers, instead
of storing it separately in .sel_base, which is more error-prone?

> +#define SCKCR3         0x08
> +#define SCKCR4         0x0C
> +#define PMSEL          0x10
> +#define PMSEL_PLL0     BIT(0)
> +#define PMSEL_PLL2     BIT(2)
> +#define PMSEL_PLL3     BIT(3)
> +#define PLL0EN         BIT(0)
> +#define PLL2EN         BIT(0)
> +#define PLL3EN         BIT(0)

These 6 bit definitions don't match the documentation (and are unused?)

> +#define PLL0MON                0x20
> +#define PLL0EN_REG     0x30

Why the "_REG"-suffix? Unused, anyway.

> +#define PLL0_SSC_CTR   0x34
> +#define PLL1MON                0x40
> +#define LOCOCR         0x70
> +#define HIZCTRLEN      0x80
> +#define PLL2MON                0x90
> +#define PLL2EN_REG     0xA0
> +#define PLL2_SSC_CTR   0xAC
> +#define PLL3MON                0xB0
> +#define PLL3EN_REG     0xC0
> +#define PLL3_VCO_CTR0  0xC4
> +#define PLL3_VCO_CTR1  0xC8
> +#define PLL4MON                0xD0
> +#define PHYSEL         BIT(21)

SCKCR_PHYSEL? So it would belong under SCKCR.
But is unused, as you have the DIVETHPHY macro.

> +
> +#define MRCTLA         0x240
> +#define MRCTLE         0x250
> +#define MRCTLI         0x260
> +#define MRCTLM         0x270

Unused, these should end up in srcr_for_rzt2h[] in renesas-cpg-mssr.c
when adding reset controller support for RZ/T2H.

Until then, the call to cpg_mssr_reset_controller_register()
in cpg_mssr_probe() should be skipped when priv->reg_layout ==
CLK_REG_LAYOUT_RZ_T2H.

> +
> +#define DDIV_PACK(offset, bitpos, size) \
> +               (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))

Indented by 2 TABs...

> +
> +#define DIVCA55                DDIV_PACK(SCKCR2, 8, 4)

This is not correct: these 4 bits are not a single bit mask, but 4
individual bits, one for each CPU core.
Oh, due to dtable_1_2[] just having values "0" and "15", all 4 CPU
cores are always clocked at the same rate. Hmm.....

> +#define DIVCA55S       DDIV_PACK(SCKCR2, 12, 1)
> +#define DIVCR520       DDIV_PACK(SCKCR2, 2, 2)
> +#define DIVCR521       DDIV_PACK(SCKCR2, 0, 2)

Surprisingly, you do handle the 2 CR52 cores individually ;-)
Unused, anyway...

> +#define DIVLCDC                DDIV_PACK(SCKCR3, 20, 3)

Should be "4" instead of "3".

> +#define DIVCKIO                DDIV_PACK(SCKCR, 16, 3)
> +#define DIVETHPHY      DDIV_PACK(SCKCR, 21, 1)
> +#define DIVCANFD       DDIV_PACK(SCKCR, 20, 1)
> +#define DIVSPI0                DDIV_PACK(SCKCR3, 0, 2)
> +#define DIVSPI1                DDIV_PACK(SCKCR3, 2, 2)
> +#define DIVSPI2                DDIV_PACK(SCKCR3, 4, 2)
> +#define DIVSPI3                DDIV_PACK(SCKCR2, 16, 2)

Perhaps sort these definitions by SCKCR* register?

> +
> +#define SEL_PLL_PACK(offset, bitpos, size) \
> +       (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))

... indented by 1 TAB.  Please match them.

> +
> +#define SEL_PLL                SEL_PLL_PACK(SCKCR, 22, 1)
> +
> +#define GET_SHIFT(val)         FIELD_GET(GENMASK(19, 12), val)
> +#define GET_WIDTH(val)         FIELD_GET(GENMASK(11, 8), val)
> +#define GET_REG_OFFSET(val)    FIELD_GET(GENMASK(31, 20), val)

Please use consistent naming:
    SHIFT ~ bitpos
    WIDTH ~ size
    REG_OFFSET ~ offset

If you would use FIELD_*() helpers for both, you could write the above as e.g.

    #define OFFSET_MASK GENMASK(31, 20)
    #define SHIFT_MASK  GENMASK(19, 12)
    #define WIDTH_MASK  GENMASK(11, 8)

   #define SEL_PLL_PACK(offset, shift, width)  \
            (FIELD_PREP_CONST(OFFSET_MASK, (offset)) | \
             FIELD_PREP_CONST(SHIFT_MASK, (shift)) | \
             FIELD_PREP_CONST(WIDTH_MASK, (width))) \

    #define GET_SHIFT(val)         FIELD_GET(SHIFT_MASK, val)
    #define GET_WIDTH(val)         FIELD_GET(WIDTH_MASK val)
    #define GET_REG_OFFSET(val)    FIELD_GET(OFFSET_MASK, val)

> +
> +enum clk_ids {
> +       /* Core Clock Outputs exported to DT */
> +       LAST_DT_CORE_CLK = R9A09G077_LCDC_CLKD,
> +
> +       /* External Input Clocks */
> +       CLK_EXTAL,
> +       CLK_LOCO,

This is an internally-generated clock.

> +
> +       /* Internal Core Clocks */
> +       CLK_PLL0,
> +       CLK_PLL1,
> +       CLK_PLL2,
> +       CLK_PLL3,
> +       CLK_PLL4,
> +       CLK_SEL_PLL0,
> +       CLK_SEL_CLK_PLL0,
> +       CLK_SEL_PLL1,
> +       CLK_SEL_CLK_PLL1,
> +       CLK_SEL_PLL2,
> +       CLK_SEL_CLK_PLL2,
> +       CLK_SEL_PLL4,
> +       CLK_SEL_CLK_PLL4,
> +       CLK_SEL_CLK_SRC,
> +       CLK_SEL_EXTAL,
> +       CLK_SEL_LOCO,
> +       CLK_PLL3_INPUT,
> +
> +       /* Module Clocks */
> +       MOD_CLK_BASE,
> +};
> +
> +static const struct clk_div_table dtable_1_2[] = {
> +       {0, 2},
> +       {15, 1},
> +       {0, 0},
> +};
> +
> +/* Mux clock tables */
> +static const char * const sel_clk_pll0[] = { ".sel_loco", ".sel_pll0" };
> +static const char * const sel_clk_pll1[] = { ".sel_loco", ".sel_pll1" };
> +static const char * const sel_clk_pll4[] = { ".sel_loco", ".sel_pll4" };
> +
> +static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
> +       /* External Clock Inputs */
> +       DEF_INPUT("extal", CLK_EXTAL),
> +       DEF_INPUT("loco", CLK_LOCO),

DEF_RATE(), as this is an internally-generated clock.

> +
> +       /* Internal Core Clocks */
> +       DEF_FIXED(".pll0", CLK_PLL0, CLK_EXTAL, 1, 48),
> +       DEF_FIXED(".pll1", CLK_PLL1, CLK_EXTAL, 1, 40),
> +       DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 1, 96),
> +       DEF_FIXED(".sel_pll0", CLK_SEL_PLL0, CLK_PLL0, 1, 1),

This is the unimplemented selector to bypass the PLL, right?

> +       DEF_MUX(".sel_clk_pll0", CLK_SEL_CLK_PLL0, SEL_PLL,
> +               sel_clk_pll0, ARRAY_SIZE(sel_clk_pll0), 0, CLK_MUX_READ_ONLY),
> +       DEF_FIXED(".sel_pll1", CLK_SEL_PLL1, CLK_PLL1, 1, 1),
> +       DEF_MUX(".sel_clk_pll1", CLK_SEL_CLK_PLL1, SEL_PLL,
> +               sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), 0, CLK_MUX_READ_ONLY),
> +       DEF_FIXED(".sel_pll4", CLK_SEL_PLL4, CLK_PLL4, 1, 1),
> +       DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL,
> +               sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), 0, CLK_MUX_READ_ONLY),
> +
> +       /* Core output clk */
> +       DEF_DIV("CA55", R9A09G077_CA55, CLK_SEL_CLK_PLL0, DIVCA55,
> +               dtable_1_2, CLK_DIVIDER_HIWORD_MASK, 1),
> +       DEF_FIXED("PCLKM", R9A09G077_PCLKM, CLK_SEL_CLK_PLL1, 8, 1),
> +       DEF_FIXED("PCLKGPTL", R9A09G077_PCLKGPTL, CLK_SEL_CLK_PLL1, 2, 1),

Please sort these two alphabetically.

> +};
> +
> +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
> +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),

Shouldn't that be 8 instead of 108?
Using R9A09G077_PCLKM as the parent is a temporary simplification,
right?

> +};
> +
> +static struct clk * __init
> +r9a09g077_cpg_div_clk_register(struct device *dev,
> +                              const struct cpg_core_clk *core,
> +                              void __iomem *base,
> +                              struct cpg_mssr_pub *pub)

Fits on one line less when wrapped.

> +{
> +       const struct clk *parent;
> +       const char *parent_name;
> +       struct clk_hw *clk_hw;
> +
> +       parent = pub->clks[core->parent];
> +
> +       if (IS_ERR(parent))
> +               return ERR_CAST(parent);
> +
> +       parent_name = __clk_get_name(parent);
> +
> +       if (core->dtable)
> +               clk_hw = clk_hw_register_divider_table(dev, core->name,
> +                                                      parent_name, 0,
> +                                                      base + GET_REG_OFFSET(core->conf),
> +                                                      GET_SHIFT(core->conf),
> +                                                      GET_WIDTH(core->conf),
> +                                                      core->flag,
> +                                                      core->dtable,
> +                                                      &pub->rmw_lock);
> +       else
> +               clk_hw = clk_hw_register_divider(dev, core->name,
> +                                                parent_name, 0,
> +                                                base + GET_REG_OFFSET(core->conf),
> +                                                GET_SHIFT(core->conf),
> +                                                GET_WIDTH(core->conf),
> +                                                core->flag, &pub->rmw_lock);
> +
> +       if (IS_ERR(clk_hw))
> +               return ERR_CAST(clk_hw);
> +
> +       return clk_hw->clk;
> +
> +}
> +
> +static struct clk * __init
> +r9a09g077_cpg_mux_clk_register(struct device *dev,
> +                              const struct cpg_core_clk *core,
> +                              void __iomem *base,
> +                              struct cpg_mssr_pub *pub)

Fits on one line less when wrapped.

> +{
> +       struct clk_hw *clk_hw;
> +
> +       clk_hw = devm_clk_hw_register_mux(dev, core->name,
> +                                         core->parent_names, core->num_parents,
> +                                         core->flag,
> +                                         base + GET_REG_OFFSET(core->conf),
> +                                         GET_SHIFT(core->conf),
> +                                         GET_WIDTH(core->conf),
> +                                         core->mux_flags, &pub->rmw_lock);

Missing error check for clk_hw.

> +       return clk_hw->clk;
> +}
> +
> +static struct clk * __init
> +r9a09g077_cpg_clk_register(struct device *dev,
> +                          const struct cpg_core_clk *core,
> +                          const struct cpg_mssr_info *info,
> +                          struct cpg_mssr_pub *pub)

Fits on one line less when wrapped.

> +{
> +       void __iomem *base = core->sel_base ? pub->base1 : pub->base0;
> +
> +       switch (core->type) {
> +       case CLK_TYPE_DIV:
> +               return r9a09g077_cpg_div_clk_register(dev, core, base, pub);
> +       case CLK_TYPE_MUX:
> +               return r9a09g077_cpg_mux_clk_register(dev, core, base, pub);
> +       default:
> +               return ERR_PTR(-EINVAL);
> +       }
> +}
> +
> +const struct cpg_mssr_info r9a09g077_cpg_mssr_info = {
> +       /* Core Clocks */
> +       .core_clks = r9a09g077_core_clks,
> +       .num_core_clks = ARRAY_SIZE(r9a09g077_core_clks),
> +       .last_dt_core_clk = LAST_DT_CORE_CLK,
> +       .num_total_core_clks = MOD_CLK_BASE,
> +
> +       /* Module Clocks */
> +       .mod_clks = r9a09g077_mod_clks,
> +       .num_mod_clks = ARRAY_SIZE(r9a09g077_mod_clks),
> +       .num_hw_mod_clks = 12 * 32,

"14 * 32", to account for the two gaps in the MSTPCRx registers?

> +
> +       .reg_layout = CLK_REG_LAYOUT_RZ_T2H,
> +       .cpg_clk_register = r9a09g077_cpg_clk_register,
> +};
> diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
> index 4bdfa4f65ab4..123bc1558e53 100644
> --- a/drivers/clk/renesas/renesas-cpg-mssr.c
> +++ b/drivers/clk/renesas/renesas-cpg-mssr.c
> @@ -79,6 +79,27 @@ static const u16 mstpcr_for_gen4[] = {
>         0x2D60, 0x2D64, 0x2D68, 0x2D6C, 0x2D70, 0x2D74,
>  };
>
> +/*
> + * Module Stop Control Register (RZ/T2H)
> + * RZ/T2H has 2 registers blocks,
> + * Bit 12 is used to differentiate them
> + */
> +
> +#define RZT2H_MSTPCR_BLOCK_SHIFT       12
> +#define RZT2H_MSTPCR_OFFSET_MASK       GENMASK(11, 0)
> +#define RZT2H_MSTPCR(block, offset)    (((block) << RZT2H_MSTPCR_BLOCK_SHIFT) & \

"|" instead of "&"

> +                                       ((offset) & RZT2H_MSTPCR_OFFSET_MASK))
> +
> +#define RZT2H_MSTPCR_BLOCK(x)          ((x) >> RZT2H_MSTPCR_BLOCK_SHIFT)
> +#define RZT2H_MSTPCR_OFFSET(x)         ((x) & RZT2H_MSTPCR_OFFSET_MASK)
> +
> +static const u16 mstpcr_for_rzt2h[] = {
> +       RZT2H_MSTPCR(0, 0x300), RZT2H_MSTPCR(0, 0x304), RZT2H_MSTPCR(0, 0x308),
> +       RZT2H_MSTPCR(0, 0x30c), RZT2H_MSTPCR(0, 0x310), RZT2H_MSTPCR(1, 0x318),
> +       RZT2H_MSTPCR(1, 0x320), RZT2H_MSTPCR(0, 0x324), RZT2H_MSTPCR(0, 0x328),
> +       RZT2H_MSTPCR(0, 0x32c), RZT2H_MSTPCR(0, 0x330), RZT2H_MSTPCR(1, 0x334),

Missing holes for non-existent MSTPCRF (0x314) and MSTPCRH (0x31c).

> +};
> +
>  /*
>   * Standby Control Register offsets (RZ/A)
>   * Base address is FRQCR register

> @@ -227,7 +257,8 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
>
>         spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
>
> -       if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
> +       if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
> +               priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)

Please align the continuation of the if-condition with the start of
the condition above.

>                 return 0;
>
>         error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
> @@ -258,6 +289,12 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
>
>         if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
>                 value = readb(priv->pub.base0 + priv->control_regs[reg]);
> +       else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {

Please use curly braces in all branches if you need them in at least
one branch...

> +               void __iomem *addr =
> +                       cpg_rzt2h_addr_from_offset(hw,
> +                                                  priv->control_regs[reg]);
> +               value = readw(addr);

Aren't the MSTPCR* registers 32-bit wide?

... however, you can avoid the curly braces by moving the register
read into the helper function.

> +       }
>         else
>                 value = readl(priv->pub.base0 + priv->status_regs[reg]);
>

> --- a/drivers/clk/renesas/renesas-cpg-mssr.h
> +++ b/drivers/clk/renesas/renesas-cpg-mssr.h
> @@ -22,6 +22,8 @@
>  struct cpg_core_clk {
>         /* Common */
>         const char *name;
> +       const char * const *parent_names;
> +       const struct clk_div_table *dtable;

Please move them below, as they are type-specific.
I think they are never used together, so you can reduce kernel size
by combining them into an anonymous union.

>         unsigned int id;
>         unsigned int type;
>         /* Depending on type */
> @@ -29,18 +31,26 @@ struct cpg_core_clk {
>         unsigned int div;
>         unsigned int mult;
>         unsigned int offset;
> +       unsigned int conf;

u32

> +       int flag;

u8? (or u16, cfr. clk_divider.flags? see below)

> +       int mux_flags;

u8 (cfr. clk_mux.flags)

> +       int num_parents;

u8?

> +       int sel_base;

bool?

> +};

FTR, your additions as-is would have increased the size of each core
clock on arm64 by 32 bytes.

Note to self: use unions for every core clock type.

>  /**
>   * struct cpg_mssr_pub - Private data shared with
>   * device-specific clk registration code
>   *
>   * @base0: CPG/MSSR register block base0 address
> + * @base1: CPG/MSSR register block base1 address
>   * @rmw_lock: protects RMW register accesses
>   * @notifiers: Notifier chain to save/restore clock state for system resume
>   * @clks: pointer to clocks
>   */
>  struct cpg_mssr_pub {
>         void __iomem *base0;
> +       void __iomem *base1;
>         struct raw_notifier_head notifiers;
>         spinlock_t rmw_lock;
>         struct clk **clks;
> @@ -53,6 +63,8 @@ enum clk_types {
>         CLK_TYPE_DIV6P1,        /* DIV6 Clock with 1 parent clock */
>         CLK_TYPE_DIV6_RO,       /* DIV6 Clock read only with extra divisor */
>         CLK_TYPE_FR,            /* Fixed Rate Clock */
> +       CLK_TYPE_DIV,           /* Clock with divider */
> +       CLK_TYPE_MUX,           /* Clock with clock source selector */

Please move these into a new enum in r9a09g077-cpg-mssr.c, starting
from CLK_TYPE_CUSTOM, as they are specific to RZ/T2H.

>
>         /* Custom definitions start here */
>         CLK_TYPE_CUSTOM,
> @@ -73,6 +85,15 @@ enum clk_types {
>         DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
>  #define DEF_RATE(_name, _id, _rate)    \
>         DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate)
> +#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag, _sel_base) \
> +       DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
> +                .parent = _parent, .dtable = _dtable, .flag = _flag, .sel_base = _sel_base)
> +#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \
> +               _mux_flags) \
> +       DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
> +                .parent_names = _parent_names, .num_parents = _num_parents, \
> +                .flag = _flag, .mux_flags = _mux_flags)

The passed _flag parameter is always 0?
So when non-zero, cpg_core_clk.flag is always clk_divider.flags.

Please move both definitions to r9a09g077-cpg-mssr.c, as they are
specific to RZ/T2H.

> +
>
>      /*
>       * Definitions of Module Clocks

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
  2025-04-17 13:41   ` Geert Uytterhoeven
@ 2025-04-18  9:29     ` Thierry Bultel
  0 siblings, 0 replies; 35+ messages in thread
From: Thierry Bultel @ 2025-04-18  9:29 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org

Hi Geert,

> -----Original Message-----
[snip]
> 
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
> > @@ -0,0 +1,49 @@
> > +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > + *
> > + * Copyright (C) 2025 Renesas Electronics Corp.
> > + */
> > +
> > +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
> > +#define __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
> > +
> > +#include <dt-bindings/clock/renesas-cpg-mssr.h>
> > +
> > +/* R9A09G077 CPG Core Clocks */
> > +#define R9A09G077_CA55C0               0
> > +#define R9A09G077_CA55C1               1
> > +#define R9A09G077_CA55C2               2
> > +#define R9A09G077_CA55C3               3
> > +#define R9A09G077_SDHIHS               4
> > +#define R9A09G077_CLK_PLL1_ETH_PHY     5
> > +#define R9A09G077_CLK_OSC_ETH_PHY      6
> > +#define R9A09G077_CLK_ETHPHY           7
> 
> I can't find these 3 clocks?

I am rewriting the definitions entirely to match the names on the documentation,
and define all the existing clocks (and not more).

Thanks for having deep checked this !

Thierry


^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-17 18:45   ` Geert Uytterhoeven
@ 2025-04-18 21:22     ` Thierry Bultel
  2025-04-23  7:18       ` Geert Uytterhoeven
  0 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-18 21:22 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org

Hi Geert,

[snip]

> > +};
> > +
> > +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
> > +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),
> 
> Shouldn't that be 8 instead of 108?
> Using R9A09G077_PCLKM as the parent is a temporary simplification, right?
> 

I am probably missing something, isn’t PCKML actually the parent clock ?

Thierry

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-18 21:22     ` Thierry Bultel
@ 2025-04-23  7:18       ` Geert Uytterhoeven
  2025-04-23  7:36         ` Thierry Bultel
  0 siblings, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-23  7:18 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org

Hi Thierry,

On Fri, 18 Apr 2025 at 23:22, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
 > +};
> > > +
> > > +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
> > > +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),
> >
> > Shouldn't that be 8 instead of 108?
> > Using R9A09G077_PCLKM as the parent is a temporary simplification, right?
>
> I am probably missing something, isn’t PCKML actually the parent clock ?

According to Figure 7.1 ("Block diagram of clock generation circuit"),
it is PCLKSCI0, which can be switched to PCLKM.  I guess that is the
default, hence my "temporary simplification" question.

As the actual switching is controlled through the SCI's CCR3 register,
the SCI block should have two clock inputs in DT (PCLKM and PCLKSCIn),
and thus the DT bindings should be amended.  See also Figure 33.1
("SCI block diagram").

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-23  7:18       ` Geert Uytterhoeven
@ 2025-04-23  7:36         ` Thierry Bultel
  2025-04-23  8:52           ` Geert Uytterhoeven
  0 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-23  7:36 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org



> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: mercredi 23 avril 2025 09:19
> To: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> Cc: thierry.bultel@linatsea.fr; linux-renesas-soc@vger.kernel.org; Paul
> Barker <paul.barker.ct@bp.renesas.com>; linux-kernel@vger.kernel.org;
> linux-clk@vger.kernel.org
> Subject: Re: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
> 
> Hi Thierry,


Hi Geert,
> 
> On Fri, 18 Apr 2025 at 23:22, Thierry Bultel
> <thierry.bultel.yh@bp.renesas.com> wrote:
>  > +};
> > > > +
> > > > +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst =
> {
> > > > +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),
> > >
> > > Shouldn't that be 8 instead of 108?
> > > Using R9A09G077_PCLKM as the parent is a temporary simplification,
> right?
> >
> > I am probably missing something, isn’t PCKML actually the parent clock ?
> 
> According to Figure 7.1 ("Block diagram of clock generation circuit"), it
> is PCLKSCI0, which can be switched to PCLKM.  I guess that is the default,
> hence my "temporary simplification" question.
> 
> As the actual switching is controlled through the SCI's CCR3 register, the
> SCI block should have two clock inputs in DT (PCLKM and PCLKSCIn), and
> thus the DT bindings should be amended.  See also Figure 33.1 ("SCI block
> diagram").
> 

Thanks for clarifying.
Indeed, this is the default setting (and the one we have at this stage).
I think that support for PCLKSCIn can be added at the time we support
baudrate setting.

Thierry

> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker.
> But when I'm talking to journalists I just say "programmer" or something
> like that.
>                                 -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-23  7:36         ` Thierry Bultel
@ 2025-04-23  8:52           ` Geert Uytterhoeven
  2025-04-24  7:53             ` Thierry Bultel
  0 siblings, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-23  8:52 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org

Hi Thierry,

On Wed, 23 Apr 2025 at 09:36, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> > From: Geert Uytterhoeven <geert@linux-m68k.org>
> > On Fri, 18 Apr 2025 at 23:22, Thierry Bultel
> > <thierry.bultel.yh@bp.renesas.com> wrote:
> >  > +};
> > > > > +
> > > > > +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst =
> > {
> > > > > +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),
> > > >
> > > > Shouldn't that be 8 instead of 108?
> > > > Using R9A09G077_PCLKM as the parent is a temporary simplification,
> > right?
> > >
> > > I am probably missing something, isn’t PCKML actually the parent clock ?
> >
> > According to Figure 7.1 ("Block diagram of clock generation circuit"), it
> > is PCLKSCI0, which can be switched to PCLKM.  I guess that is the default,
> > hence my "temporary simplification" question.
> >
> > As the actual switching is controlled through the SCI's CCR3 register, the
> > SCI block should have two clock inputs in DT (PCLKM and PCLKSCIn), and
> > thus the DT bindings should be amended.  See also Figure 33.1 ("SCI block
> > diagram").
> >
>
> Thanks for clarifying.
> Indeed, this is the default setting (and the one we have at this stage).
> I think that support for PCLKSCIn can be added at the time we support
> baudrate setting.

I am not sure we can do that in a clean backwards-compatible way.
Currently the DT bindings describe a single clock:

  clock-names:
    const: fck # UART functional clock

The documentation calls the two clocks:
  - Bus clock (PCLKM),
  - Operation clock (PCLKSCIn).

Which one is the functional clock? I'd say the latter...
Currently, DT says:

        clocks = <&cpg CPG_MOD 8>;
        clock-names = "fck";

and the clock driver uses PCLKM as the module's parent clock,
I think you will have a very hard time to synchronize all of the clock
driver, sci driver, and DTS when transitioning to something like:

        clocks = <&cpg CPG_MOD 8>, <&cpgR9A09G077_PCLKM>;
        clock-names = "fck", "bus";

where the modulo clock has to become PCLKSCIn (actually SCInASYNC,
as seen from the CPG).

Does that make sense, or am I missing something?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-23  8:52           ` Geert Uytterhoeven
@ 2025-04-24  7:53             ` Thierry Bultel
  2025-04-24  8:24               ` Geert Uytterhoeven
  0 siblings, 1 reply; 35+ messages in thread
From: Thierry Bultel @ 2025-04-24  7:53 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org

Hi Geert,

> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: mercredi 23 avril 2025 10:52
> To: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> Cc: thierry.bultel@linatsea.fr; linux-renesas-soc@vger.kernel.org; Paul
> Barker <paul.barker.ct@bp.renesas.com>; linux-kernel@vger.kernel.org;
> linux-clk@vger.kernel.org
> Subject: Re: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
> 
> Hi Thierry,
> 
> On Wed, 23 Apr 2025 at 09:36, Thierry Bultel
> <thierry.bultel.yh@bp.renesas.com> wrote:
> > > From: Geert Uytterhoeven <geert@linux-m68k.org> On Fri, 18 Apr 2025
> > > at 23:22, Thierry Bultel <thierry.bultel.yh@bp.renesas.com> wrote:
> > >  > +};
> > > > > > +
> > > > > > +static const struct mssr_mod_clk r9a09g077_mod_clks[]
> > > > > > +__initconst =
> > > {
> > > > > > +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),
> > > > >
> > > > > Shouldn't that be 8 instead of 108?
> > > > > Using R9A09G077_PCLKM as the parent is a temporary
> > > > > simplification,
> > > right?
> > > >
> > > > I am probably missing something, isn’t PCKML actually the parent
> clock ?
> > >
> > > According to Figure 7.1 ("Block diagram of clock generation
> > > circuit"), it is PCLKSCI0, which can be switched to PCLKM.  I guess
> > > that is the default, hence my "temporary simplification" question.
> > >
> > > As the actual switching is controlled through the SCI's CCR3
> > > register, the SCI block should have two clock inputs in DT (PCLKM
> > > and PCLKSCIn), and thus the DT bindings should be amended.  See also
> > > Figure 33.1 ("SCI block diagram").
> > >
> >
> > Thanks for clarifying.
> > Indeed, this is the default setting (and the one we have at this stage).
> > I think that support for PCLKSCIn can be added at the time we support
> > baudrate setting.
> 
> I am not sure we can do that in a clean backwards-compatible way.
> Currently the DT bindings describe a single clock:
> 
>   clock-names:
>     const: fck # UART functional clock
> 
> The documentation calls the two clocks:
>   - Bus clock (PCLKM),
>   - Operation clock (PCLKSCIn).
> 
> Which one is the functional clock? I'd say the latter...
> Currently, DT says:
> 
>         clocks = <&cpg CPG_MOD 8>;
>         clock-names = "fck";
> 
> and the clock driver uses PCLKM as the module's parent clock, I think you
> will have a very hard time to synchronize all of the clock driver, sci
> driver, and DTS when transitioning to something like:
> 
>         clocks = <&cpg CPG_MOD 8>, <&cpgR9A09G077_PCLKM>;
>         clock-names = "fck", "bus";
> 
> where the modulo clock has to become PCLKSCIn (actually SCInASYNC, as seen
> from the CPG).
> 
> Does that make sense, or am I missing something?

You are right, I completely understand how hard it would be to have backward compatibility.
However, doing so:

		clocks = <&cpg CPG_MOD R9A09G077_PCLK_SCI0>, <&cpg CPG_CORE R9A09G077_CLK_PCLKM>;
		clock-names = "fck", "bus";

without modifying the sh-sci driver (yet) would lead to this bogus clk_summary:

  clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id
---------------------------------------------------------------------------------------------------------------------------------------------
 loco                                0       0        0        1000000     0          0     50000      Y   deviceless                      no_connection_id         
 extal                               1       1        0        25000000    0          0     50000      Y   clock-controller@80280000       extal                    
                                                                                                           deviceless                      no_connection_id         
    .pll4                            1       1        0        2400000000  0          0     50000      Y      deviceless                      no_connection_id         
       .sel_pll4                     1       1        0        2400000000  0          0     50000      Y         deviceless                      no_connection_id         
          .sel_clk_pll4              1       1        0        2400000000  0          0     50000      Y            deviceless                      no_connection_id         
             .pll4d1                 1       1        0        2400000000  0          0     50000      Y               deviceless                      no_connection_id         
                .sci0async           1       1        0        100000000   0          0     50000      Y                  deviceless                      no_connection_id         
                   sci0              2       2        0        100000000   0          0     50000      Y                     80005000.serial                 fck                      
                                                                                                                             deviceless                      of_clk_get_from_provider 
                                                                                                                             deviceless                      no_connection_id   

it is wrong because the actual default state is that PCKLM is used, not sci0async. 
Having PCKML consumed by sci0 is an obvious fix in sci_init_clocks, but it won't show up that only one clock is used at a time.

Couldn't it be better be solved by introducing an extra mux clock ? (the one controlled by BPEN) ?

Thanks !
Thierry

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker.
> But when I'm talking to journalists I just say "programmer" or something
> like that.
>                                 -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC
  2025-04-24  7:53             ` Thierry Bultel
@ 2025-04-24  8:24               ` Geert Uytterhoeven
  0 siblings, 0 replies; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-04-24  8:24 UTC (permalink / raw)
  To: Thierry Bultel
  Cc: thierry.bultel@linatsea.fr, linux-renesas-soc@vger.kernel.org,
	Paul Barker, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org

Hi Thierry,

On Thu, 24 Apr 2025 at 09:53, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> > From: Geert Uytterhoeven <geert@linux-m68k.org>
> > On Wed, 23 Apr 2025 at 09:36, Thierry Bultel
> > <thierry.bultel.yh@bp.renesas.com> wrote:
> > > > From: Geert Uytterhoeven <geert@linux-m68k.org> On Fri, 18 Apr 2025
> > > > at 23:22, Thierry Bultel <thierry.bultel.yh@bp.renesas.com> wrote:
> > > >  > +};
> > > > > > > +
> > > > > > > +static const struct mssr_mod_clk r9a09g077_mod_clks[]
> > > > > > > +__initconst =
> > > > {
> > > > > > > +       DEF_MOD("sci0", 108, R9A09G077_PCLKM),
> > > > > >
> > > > > > Shouldn't that be 8 instead of 108?
> > > > > > Using R9A09G077_PCLKM as the parent is a temporary
> > > > > > simplification,
> > > > right?
> > > > >
> > > > > I am probably missing something, isn’t PCKML actually the parent
> > clock ?
> > > >
> > > > According to Figure 7.1 ("Block diagram of clock generation
> > > > circuit"), it is PCLKSCI0, which can be switched to PCLKM.  I guess
> > > > that is the default, hence my "temporary simplification" question.
> > > >
> > > > As the actual switching is controlled through the SCI's CCR3
> > > > register, the SCI block should have two clock inputs in DT (PCLKM
> > > > and PCLKSCIn), and thus the DT bindings should be amended.  See also
> > > > Figure 33.1 ("SCI block diagram").
> > > >
> > >
> > > Thanks for clarifying.
> > > Indeed, this is the default setting (and the one we have at this stage).
> > > I think that support for PCLKSCIn can be added at the time we support
> > > baudrate setting.
> >
> > I am not sure we can do that in a clean backwards-compatible way.
> > Currently the DT bindings describe a single clock:
> >
> >   clock-names:
> >     const: fck # UART functional clock
> >
> > The documentation calls the two clocks:
> >   - Bus clock (PCLKM),
> >   - Operation clock (PCLKSCIn).
> >
> > Which one is the functional clock? I'd say the latter...
> > Currently, DT says:
> >
> >         clocks = <&cpg CPG_MOD 8>;
> >         clock-names = "fck";
> >
> > and the clock driver uses PCLKM as the module's parent clock, I think you
> > will have a very hard time to synchronize all of the clock driver, sci
> > driver, and DTS when transitioning to something like:
> >
> >         clocks = <&cpg CPG_MOD 8>, <&cpgR9A09G077_PCLKM>;
> >         clock-names = "fck", "bus";
> >
> > where the modulo clock has to become PCLKSCIn (actually SCInASYNC, as seen
> > from the CPG).
> >
> > Does that make sense, or am I missing something?
>
> You are right, I completely understand how hard it would be to have backward compatibility.
> However, doing so:
>
>                 clocks = <&cpg CPG_MOD R9A09G077_PCLK_SCI0>, <&cpg CPG_CORE R9A09G077_CLK_PCLKM>;
>                 clock-names = "fck", "bus";
>
> without modifying the sh-sci driver (yet) would lead to this bogus clk_summary:
>
>   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id
> ---------------------------------------------------------------------------------------------------------------------------------------------
>  loco                                0       0        0        1000000     0          0     50000      Y   deviceless                      no_connection_id
>  extal                               1       1        0        25000000    0          0     50000      Y   clock-controller@80280000       extal
>                                                                                                            deviceless                      no_connection_id
>     .pll4                            1       1        0        2400000000  0          0     50000      Y      deviceless                      no_connection_id
>        .sel_pll4                     1       1        0        2400000000  0          0     50000      Y         deviceless                      no_connection_id
>           .sel_clk_pll4              1       1        0        2400000000  0          0     50000      Y            deviceless                      no_connection_id
>              .pll4d1                 1       1        0        2400000000  0          0     50000      Y               deviceless                      no_connection_id
>                 .sci0async           1       1        0        100000000   0          0     50000      Y                  deviceless                      no_connection_id
>                    sci0              2       2        0        100000000   0          0     50000      Y                     80005000.serial                 fck
>                                                                                                                              deviceless                      of_clk_get_from_provider
>                                                                                                                              deviceless                      no_connection_id
>
> it is wrong because the actual default state is that PCKLM is used, not sci0async.
> Having PCKML consumed by sci0 is an obvious fix in sci_init_clocks, but it won't show up that only one clock is used at a time.

So your rsci patch should modify the sh-sci driver to handle this correctly...

> Couldn't it be better be solved by introducing an extra mux clock ? (the one controlled by BPEN) ?

I don't think that will simplify anything:  as the BPEN bit is located
inside the RSCI register space, that mux clock must be handled by the
sh-sci/rsci driver itself, so you cannot just refer to it in the clocks
property in DT.
In theory, several other control bits (e.g. BGDM (Baud Rate Generator
Double-Speed Mode Select), ABCS (Asynchronous Mode Base Clock Select),
and ABCSE (Asynchronous Mode Extended Base Clock Select) in CCR2)
could also be modelled using the common clock framework, but that
wouldn't simplify the serial driver...

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2025-04-24  8:24 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-03 21:29 [PATCH v7 00/13] Add initial support for Renesas RZ/T2H SoC Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 01/13] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
2025-04-17 13:39   ` Geert Uytterhoeven
2025-04-03 21:29 ` [PATCH v7 02/13] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
2025-04-04 19:37   ` Rob Herring (Arm)
2025-04-17 13:41   ` Geert Uytterhoeven
2025-04-18  9:29     ` Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 03/13] dt-bindings: serial: Add compatible for Renesas RZ/T2H SoC in sci Thierry Bultel
2025-04-17 14:04   ` Geert Uytterhoeven
2025-04-03 21:29 ` [PATCH v7 04/13] soc: renesas: Add RZ/T2H (R9A09G077) config option Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 05/13] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
2025-04-17 14:15   ` Geert Uytterhoeven
2025-04-03 21:29 ` [PATCH v7 06/13] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
2025-04-17 18:45   ` Geert Uytterhoeven
2025-04-18 21:22     ` Thierry Bultel
2025-04-23  7:18       ` Geert Uytterhoeven
2025-04-23  7:36         ` Thierry Bultel
2025-04-23  8:52           ` Geert Uytterhoeven
2025-04-24  7:53             ` Thierry Bultel
2025-04-24  8:24               ` Geert Uytterhoeven
2025-04-03 21:29 ` [PATCH v7 07/13] serial: sh-sci: Fix a comment about SCIFA Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 08/13] serial: sh-sci: Introduced function pointers Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 09/13] serial: sh-sci: Introduced sci_of_data Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 10/13] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
2025-04-11 14:57   ` Greg KH
2025-04-14  7:54     ` Thierry Bultel
2025-04-14  8:58       ` Greg KH
2025-04-14  9:23         ` Thierry Bultel
2025-04-14  9:32           ` Greg KH
2025-04-14 14:07             ` Geert Uytterhoeven
2025-04-15 12:35               ` Greg KH
2025-04-17 12:53   ` Geert Uytterhoeven
2025-04-03 21:29 ` [PATCH v7 11/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 12/13] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
2025-04-03 21:29 ` [PATCH v7 13/13] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).