2021-06-03 22:20:22

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 00/12] Add new Renesas RZ/G2L SoC and Renesas RZ/G2L SMARC EVK support

Hi All,

This patch series adds initial support for Renesas RZ/G2L SoC and
Renesas RZ/G2L SMARC EVK.

Initial patches enables minimal peripherals on Renesas RZ/G2L
SMARC EVK and booted via initramfs.
* Documentation for RZ/G2{L,LC,UL} SoC variants
* SoC identification support
* CPG core support
* Minimal SoC DTSi
* Minimal DTS for SMARC EVK

Changes for v2:
* Included type-2 RZ/G2Ul SoC in binding doc
* Added single entry for SMARC EVK "renesas,smarc-evk"
* Renamed ARCH_R9A07G044L to ARCH_R9A07G044 and
dropped ARCH_R9A07G044LC config
* Dropped SoC identification changes will post them as
separate patch.
* Updated comment in sh-sci.c
* Binding documentation patch for serial driver has been
accepted so dropped the patch from this series
* Incorporated changes requested by Geert for CPG core
* Fixed dtbs_check errors
* Dropped 'clock-names'/'clocks'/'power-domains'/'resets'
properties from GIC node and will include them in a separate
patch along with arm,gic-v3.yaml binding updates
* Included ACK's from Rob

Patches are based on top of [1] master branch.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/

Cheers,
Prabhakar

Biju Das (1):
serial: sh-sci: Add support for RZ/G2L SoC

Lad Prabhakar (11):
dt-bindings: arm: renesas: Document Renesas RZ/G2UL SoC
dt-bindings: arm: renesas: Document Renesas RZ/G2{L,LC} SoC variants
dt-bindings: arm: renesas: Document SMARC EVK
soc: renesas: Add ARCH_R9A07G044 for the new RZ/G2L SoC's
arm64: defconfig: Enable ARCH_R9A07G044
clk: renesas: Define RZ/G2L CPG Clock Definitions
dt-bindings: clock: renesas: Document RZ/G2L SoC CPG driver
clk: renesas: Add CPG core wrapper for RZ/G2L SoC
clk: renesas: Add support for R9A07G044 SoC
arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's
arm64: dts: renesas: Add initial device tree for RZ/G2L SMARC EVK

.../devicetree/bindings/arm/renesas.yaml | 18 +
.../bindings/clock/renesas,rzg2l-cpg.yaml | 80 ++
arch/arm64/boot/dts/renesas/Makefile | 2 +
arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 119 +++
arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 +
.../boot/dts/renesas/r9a07g044l2-smarc.dts | 21 +
arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 27 +
arch/arm64/configs/defconfig | 1 +
drivers/clk/renesas/Kconfig | 9 +
drivers/clk/renesas/Makefile | 2 +
drivers/clk/renesas/r9a07g044-cpg.c | 372 +++++++
drivers/clk/renesas/renesas-rzg2l-cpg.c | 979 ++++++++++++++++++
drivers/clk/renesas/renesas-rzg2l-cpg.h | 217 ++++
drivers/soc/renesas/Kconfig | 5 +
drivers/tty/serial/sh-sci.c | 12 +-
drivers/tty/serial/sh-sci.h | 1 +
include/dt-bindings/clock/r9a07g044-cpg.h | 89 ++
17 files changed, 1978 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044.dtsi
create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
create mode 100644 arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
create mode 100644 drivers/clk/renesas/r9a07g044-cpg.c
create mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.c
create mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.h
create mode 100644 include/dt-bindings/clock/r9a07g044-cpg.h

--
2.17.1


2021-06-03 22:20:34

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 02/12] dt-bindings: arm: renesas: Document Renesas RZ/G2{L,LC} SoC variants

Add device tree bindings documentation for Renesas RZ/G2{L,LC}
SoC variants.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
Reviewed-by: Chris Paterson <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/arm/renesas.yaml | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/renesas.yaml b/Documentation/devicetree/bindings/arm/renesas.yaml
index 3b79108b49a0..0f99408960d7 100644
--- a/Documentation/devicetree/bindings/arm/renesas.yaml
+++ b/Documentation/devicetree/bindings/arm/renesas.yaml
@@ -309,6 +309,15 @@ properties:
- renesas,r9a07g043u12 # RZ/G2UL Type-2
- const: renesas,r9a07g043

+ - description: RZ/G2{L,LC} (R9A07G044)
+ items:
+ - enum:
+ - renesas,r9a07g044c1 # Single Cortex-A55 RZ/G2LC
+ - renesas,r9a07g044c2 # Dual Cortex-A55 RZ/G2LC
+ - renesas,r9a07g044l1 # Single Cortex-A55 RZ/G2L
+ - renesas,r9a07g044l2 # Dual Cortex-A55 RZ/G2L
+ - const: renesas,r9a07g044
+
additionalProperties: true

...
--
2.17.1

2021-06-03 22:20:41

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 03/12] dt-bindings: arm: renesas: Document SMARC EVK

Document Renesas SMARC EVK board which are based on RZ/G2L (R9A07G044)
SoC. The SMARC EVK consists of RZ/G2L SoM module and SMARC carrier board,
the SoM module sits on top of carrier board.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
Reviewed-by: Chris Paterson <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/arm/renesas.yaml | 2 ++
1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/renesas.yaml b/Documentation/devicetree/bindings/arm/renesas.yaml
index 0f99408960d7..a0cce4e25039 100644
--- a/Documentation/devicetree/bindings/arm/renesas.yaml
+++ b/Documentation/devicetree/bindings/arm/renesas.yaml
@@ -311,6 +311,8 @@ properties:

- description: RZ/G2{L,LC} (R9A07G044)
items:
+ - enum:
+ - renesas,smarc-evk # SMARC EVK
- enum:
- renesas,r9a07g044c1 # Single Cortex-A55 RZ/G2LC
- renesas,r9a07g044c2 # Dual Cortex-A55 RZ/G2LC
--
2.17.1

2021-06-03 22:20:42

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 01/12] dt-bindings: arm: renesas: Document Renesas RZ/G2UL SoC

Add device tree bindings documentation for Renesas RZ/G2UL SoC.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
Reviewed-by: Chris Paterson <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/arm/renesas.yaml | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/renesas.yaml b/Documentation/devicetree/bindings/arm/renesas.yaml
index 5fd0696a9f91..3b79108b49a0 100644
--- a/Documentation/devicetree/bindings/arm/renesas.yaml
+++ b/Documentation/devicetree/bindings/arm/renesas.yaml
@@ -302,6 +302,13 @@ properties:
- renesas,rzn1d400-db # RZN1D-DB (RZ/N1D Demo Board for the RZ/N1D 400 pins package)
- const: renesas,r9a06g032

+ - description: RZ/G2UL (R9A07G043)
+ items:
+ - enum:
+ - renesas,r9a07g043u11 # RZ/G2UL Type-1
+ - renesas,r9a07g043u12 # RZ/G2UL Type-2
+ - const: renesas,r9a07g043
+
additionalProperties: true

...
--
2.17.1

2021-06-03 22:20:58

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 05/12] arm64: defconfig: Enable ARCH_R9A07G044

Enable the Renesas RZ/G2L SoC variants in the ARM64 defconfig.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c1110fc20cdb..756fb464b107 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1044,6 +1044,7 @@ CONFIG_ARCH_R8A77980=y
CONFIG_ARCH_R8A77990=y
CONFIG_ARCH_R8A77995=y
CONFIG_ARCH_R8A779A0=y
+CONFIG_ARCH_R9A07G044=y
CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
--
2.17.1

2021-06-03 22:21:00

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 04/12] soc: renesas: Add ARCH_R9A07G044 for the new RZ/G2L SoC's

Add ARCH_R9A07G044 as a configuration symbol for the new Renesas
RZ/G2L SoC variants.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
---
drivers/soc/renesas/Kconfig | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index b70bbc38efc6..71b44c31b012 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -279,6 +279,11 @@ config ARCH_R8A774B1
help
This enables support for the Renesas RZ/G2N SoC.

+config ARCH_R9A07G044
+ bool "ARM64 Platform support for RZ/G2L"
+ help
+ This enables support for the Renesas RZ/G2L SoC variants.
+
endif # ARM64

config RST_RCAR
--
2.17.1

2021-06-03 22:21:02

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's

Add initial DTSI for RZ/G2{L,LC} SoC's.

File structure:
r9a07g044.dtsi => RZ/G2L family SoC common parts
r9a07g044l1.dtsi => Specific to RZ/G2L (R9A07G044L single cortex A55) SoC

Signed-off-by: Lad Prabhakar <[email protected]>
Signed-off-by: Biju Das <[email protected]>
---
arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 119 +++++++++++++++++++
arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 ++++
2 files changed, 144 insertions(+)
create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044.dtsi
create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
new file mode 100644
index 000000000000..b2dbf6543d98
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2L and RZ/G2LC common SoC parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r9a07g044-cpg.h>
+
+/ {
+ compatible = "renesas,r9a07g044";
+ #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>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+ };
+
+ 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";
+ };
+
+ L3_CA55: cache-controller-0 {
+ compatible = "cache";
+ cache-unified;
+ cache-size = <0x40000>;
+ };
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ scif0: serial@1004b800 {
+ compatible = "renesas,scif-r9a07g044";
+ reg = <0 0x1004b800 0 0x400>;
+ interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A07G044_CLK_SCIF0>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G044_CLK_SCIF0>;
+ status = "disabled";
+ };
+
+ cpg: clock-controller@11010000 {
+ compatible = "renesas,r9a07g044-cpg";
+ reg = <0 0x11010000 0 0x10000>;
+ clocks = <&extal_clk>;
+ clock-names = "extal";
+ #clock-cells = <2>;
+ #reset-cells = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ gic: interrupt-controller@11900000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0x11900000 0 0x40000>,
+ <0x0 0x11940000 0 0x60000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
new file mode 100644
index 000000000000..02f6da806696
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2L R9A07G044L1 common parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g044.dtsi"
+
+/ {
+ compatible = "renesas,r9a07g044l1", "renesas,r9a07g044";
+
+ cpus {
+ /delete-node/ cpu-map;
+ /delete-node/ cpu@100;
+ };
+
+ timer {
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
--
2.17.1

2021-06-03 22:21:13

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 09/12] clk: renesas: Add support for R9A07G044 SoC

Define the clock outputs supported by RZ/G2L (R9A07G044) SoC
and bind it with RZ/G2L CPG core.

Based on a patch in the BSP by Binh Nguyen
<[email protected]>.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
---
drivers/clk/renesas/Kconfig | 5 +
drivers/clk/renesas/Makefile | 1 +
drivers/clk/renesas/r9a07g044-cpg.c | 372 ++++++++++++++++++++++++
drivers/clk/renesas/renesas-rzg2l-cpg.c | 6 +
drivers/clk/renesas/renesas-rzg2l-cpg.h | 2 +
5 files changed, 386 insertions(+)
create mode 100644 drivers/clk/renesas/r9a07g044-cpg.c

diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 5a0d934f43a4..d1fc44fe755d 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -32,6 +32,7 @@ config CLK_RENESAS
select CLK_R8A77995 if ARCH_R8A77995
select CLK_R8A779A0 if ARCH_R8A779A0
select CLK_R9A06G032 if ARCH_R9A06G032
+ select CLK_R9A07G044 if ARCH_R9A07G044
select CLK_SH73A0 if ARCH_SH73A0

if CLK_RENESAS
@@ -156,6 +157,10 @@ config CLK_R9A06G032
help
This is a driver for R9A06G032 clocks

+config CLK_R9A07G044
+ bool "RZ/G2L clock support" if COMPILE_TEST
+ select CLK_RZG2L
+
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 a9c299686b4a..5c6c5c721d98 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o
obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o
obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o
obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
+obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o

# Family
diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c
new file mode 100644
index 000000000000..9a481d01cf69
--- /dev/null
+++ b/drivers/clk/renesas/r9a07g044-cpg.c
@@ -0,0 +1,372 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/G2L CPG driver
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/clock/r9a07g044-cpg.h>
+
+#include "renesas-rzg2l-cpg.h"
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R9A07G044_OSCCLK,
+
+ /* External Input Clocks */
+ CLK_XINCLK,
+
+ /* Internal Core Clocks */
+ CLK_OSC_DIV1000,
+ CLK_PLL1,
+ CLK_SEL_PLL1,
+ CLK600,
+ CLK_PLL2,
+ CLK_PLL2_1,
+ CLK_SEL_PLL2_1,
+ CLK800FIX_C,
+ CLK800FIX_CDIV2,
+ CLK200FIX_C,
+ CLK200_C,
+ CLK100FIX_C,
+ CLK_PLL2_2,
+ CLK_SEL_PLL2_2,
+ CLK533_C,
+ CLK533_CDIV2,
+ CLK533FIX_C,
+ CLK533FIX_CDIV2,
+ CLK533FIX_LPCLK,
+ CLK_PLL3,
+ CLK_PLL3_1,
+ CLK_SEL_PLL3_1,
+ CLK800FIX_CD,
+ CLK800FIX_DIV2,
+ CLK200FIX_CD,
+ CLK200_CD,
+ CLK100FIX_CD,
+ CLK100_CD,
+ CLK_PLL3_2,
+ CLK_SEL_PLL3_2,
+ CLK_PLL3_3,
+ CLK_SEL_PLL3_3,
+ CLK533_CD,
+ CLK533FIX_CD,
+ CLK_PLL4,
+ CLK_SEL_PLL4,
+ CLK_PLL5,
+ CLK_PLL5_1,
+ CLK_SEL_PLL5_1,
+ CLK_PLL5_3,
+ CLK_SEL_PLL5_3,
+ CLK_PLL5_2,
+ CLK_SEL_PLL5_2,
+ CLK_SEL_PLL5_4,
+ CLK_250,
+ CLK_PLL6,
+ CLK_PLL6_1,
+ CLK_SEL_PLL6_1,
+ CLK_SEL_G1_1,
+ CLK_SEL_G1_2,
+ CLK_SEL_G2,
+ CLK_PLL6_DIV2,
+ CLK_SEL_PLL6_2,
+
+ /* Module Clocks */
+ MOD_CLK_BASE,
+};
+
+/* Divider tables */
+static const struct clk_div_table divdsilpcl[] = {
+ {0, 16},
+ {1, 32},
+ {2, 64},
+ {3, 128},
+};
+
+static const struct clk_div_table dtable_2b[] = {
+ {0, 1},
+ {1, 2},
+ {2, 4},
+ {3, 8},
+};
+
+static const struct clk_div_table dtable_3b[] = {
+ {0, 1},
+ {1, 2},
+ {2, 4},
+ {3, 8},
+ {4, 32},
+};
+
+static const struct clk_div_table dtable_4b[] = {
+ {0, 1},
+ {1, 2},
+ {2, 3},
+ {3, 4},
+ {4, 5},
+ {5, 6},
+ {6, 7},
+ {7, 8},
+ {8, 9},
+ {9, 10},
+ {10, 11},
+ {11, 12},
+ {12, 13},
+ {13, 14},
+ {14, 15},
+ {15, 16},
+};
+
+/* MUX clock tables */
+static const char * const sel_pll1[] = { "xinclk", ".pll1" };
+static const char * const sel_pll2_1[] = { "xinclk", ".pll2_1" };
+static const char * const sel_pll2_2[] = { "xinclk", ".pll2_2" };
+static const char * const sel_pll3_1[] = { "xinclk", ".pll3_1" };
+static const char * const sel_pll3_2[] = { "xinclk", ".pll3_2" };
+static const char * const sel_pll3_3[] = { ".sel_pll3_2", ".pll3_3" };
+static const char * const sel_pll4[] = { ".osc_div1000", ".pll4" };
+static const char * const sel_pll5_1[] = { "xinclk", ".pll5_1" };
+static const char * const sel_pll5_3[] = { "xinclk", ".pll5_3" };
+static const char * const sel_pll5_4[] = { ".sel_pll5_1", ".sel_pll5_3" };
+static const char * const sel_pll5_2[] = { "xinclk", ".pll5_2" };
+static const char * const sel_pll6_1[] = { "xinclk", ".pll6" };
+static const char * const sel_g1_1[] = { ".sel_pll6_1", ".clk600" };
+static const char * const sel_g1_2[] = { ".clk533fix_cd", ".clk800fix_div2" };
+static const char * const sel_g2[] = { ".sel_g1_1", ".sel_g1_2" };
+static const char * const sel_pll6_2[] = { ".pll6_div2", ".clk250" };
+static const char * const sel_eth[] = { "xinclk", ".sel_pll6_2" };
+static const char * const sel_shdi[] = { ".clk800fix_c", ".clk533_c",
+ ".clk800fix_cdiv2", ".clk533_cdiv2" };
+
+static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_XINCLK),
+
+ /* Internal Core Clocks */
+ DEF_FIXED(".osc", R9A07G044_OSCCLK, CLK_XINCLK, 1, 1),
+ DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_XINCLK, 1, 1000),
+ DEF_PLL(".pll1", CLK_PLL1, CLK_TYPE_SAM_PLL, CLK_XINCLK,
+ PLL146_CONF(0), PLL146_STBY(0), PLL146_MON(0)),
+ DEF_PLL(".pll2", CLK_PLL2, CLK_TYPE_SI_PLL, CLK_XINCLK,
+ PLL235_CONF(0), PLL235_STBY(0), PLL235_MON(0)),
+ DEF_PLL(".pll3", CLK_PLL3, CLK_TYPE_SI_PLL, CLK_XINCLK,
+ PLL235_CONF(1), PLL235_STBY(1), PLL235_MON(1)),
+ DEF_PLL(".pll4", CLK_PLL4, CLK_TYPE_SAM_PLL, CLK_XINCLK,
+ PLL146_CONF(1), PLL146_STBY(1), PLL146_MON(1)),
+ DEF_PLL(".pll5", CLK_PLL5, CLK_TYPE_SI_PLL, CLK_XINCLK,
+ PLL235_CONF(2), PLL235_STBY(2), PLL235_MON(2)),
+ DEF_PLL(".pll6", CLK_PLL6, CLK_TYPE_SAM_PLL, CLK_XINCLK,
+ PLL146_CONF(2), PLL146_STBY(2), PLL146_MON(2)),
+ DEF_MUX(".sel_pll1", CLK_SEL_PLL1, SEL_PLL1,
+ sel_pll1, 2, CLK_MUX_READ_ONLY),
+ DEF_FIXED(".clk600", CLK600, CLK_PLL1, 1, 2),
+ DEF_FIXED(".pll2_1", CLK_PLL2_1, CLK_PLL2, 1, 2),
+ DEF_MUX(".sel_pll2_1", CLK_SEL_PLL2_1, SEL_PLL2_1,
+ sel_pll2_1, 2, CLK_MUX_READ_ONLY),
+ DEF_FIXED(".clk800fix_c", CLK800FIX_C, CLK_SEL_PLL2_1, 1, 2),
+ DEF_FIXED(".clk800fix_cdiv2", CLK800FIX_CDIV2, CLK800FIX_C, 1, 2),
+ DEF_FIXED(".clk200fix_c", CLK200FIX_C, CLK800FIX_C, 1, 4),
+ DEF_DIV(".clk200_c", CLK200_C, CLK200FIX_C,
+ DIVPL2B, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED(".clk100fix_c", CLK100FIX_C, CLK200FIX_C, 1, 2),
+ DEF_FIXED(".pll2_2", CLK_PLL2_2, CLK_PLL2, 1, 6),
+ DEF_MUX(".sel_pll2_2", CLK_SEL_PLL2_2, SEL_PLL2_2,
+ sel_pll2_2, 2, CLK_MUX_READ_ONLY),
+ DEF_DIV(".clk533_c", CLK533_C, CLK_SEL_PLL2_2,
+ DIVPL2C, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED(".clk533_cdiv2", CLK533_CDIV2, CLK533_C, 1, 2),
+ DEF_FIXED(".clk533fix_c", CLK533FIX_C, CLK_SEL_PLL2_2, 1, 1),
+ DEF_FIXED(".clk533fix_cdiv2", CLK533FIX_CDIV2, CLK533FIX_C, 1, 2),
+ DEF_FIXED(".clk533fix_lpclk", CLK533FIX_LPCLK, CLK533FIX_C, 1, 2),
+ DEF_FIXED(".pll3_1", CLK_PLL3_1, CLK_PLL3, 1, 2),
+ DEF_MUX(".sel_pll3_1", CLK_SEL_PLL3_1, SEL_PLL3_1,
+ sel_pll3_1, 2, CLK_MUX_READ_ONLY),
+ DEF_FIXED(".clk800fix_cd", CLK800FIX_CD, CLK_SEL_PLL3_1, 1, 2),
+ DEF_FIXED(".clk800fix_div2", CLK800FIX_DIV2, CLK800FIX_CD, 1, 2),
+ DEF_FIXED(".clk200fix_cd", CLK200FIX_CD, CLK800FIX_CD, 1, 4),
+ DEF_FIXED(".clk100fix_cd", CLK100FIX_CD, CLK200FIX_CD, 1, 2),
+ DEF_FIXED(".pll3_2", CLK_PLL3_2, CLK_PLL3, 1, 6),
+ DEF_MUX(".sel_pll3_2", CLK_SEL_PLL3_2, SEL_PLL3_2,
+ sel_pll3_2, 2, CLK_MUX_READ_ONLY),
+ DEF_FIXED(".pll3_3", CLK_PLL3_3, CLK_PLL3, 1, 8),
+ DEF_MUX(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3,
+ sel_pll3_3, 2, CLK_MUX_READ_ONLY),
+ DEF_DIV(".clk533_cd", CLK533_CD, CLK_SEL_PLL3_3,
+ DIVPL3C, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED(".clk533fix_cd", CLK533FIX_CD, CLK_SEL_PLL3_2, 1, 1),
+ DEF_MUX(".sel_pll4", CLK_SEL_PLL4, SEL_PLL4, sel_pll4, 2, 0),
+ DEF_FIXED(".pll5_1", CLK_PLL5_1, CLK_PLL5, 1, 1),
+ DEF_MUX(".sel_pll5_1", CLK_SEL_PLL5_1, SEL_PLL5_1,
+ sel_pll5_1, 2, CLK_MUX_READ_ONLY),
+ DEF_FIXED(".pll5_3", CLK_PLL5_3, CLK_PLL5, 1, 2),
+ DEF_MUX(".sel_pll5_3", CLK_SEL_PLL5_3, SEL_PLL5_3,
+ sel_pll5_3, 2, CLK_MUX_READ_ONLY),
+ DEF_MUX(".sel_pll5_4", CLK_SEL_PLL5_4, SEL_PLL5_4,
+ sel_pll5_4, 2, 0),
+ DEF_FIXED(".pll5_2", CLK_PLL5_2, CLK_PLL5, 1, 6),
+ DEF_MUX(".sel_pll5_2", CLK_SEL_PLL5_2, SEL_PLL5_2,
+ sel_pll5_2, 2, CLK_MUX_READ_ONLY),
+ DEF_FIXED(".clk250", CLK_250, CLK_SEL_PLL5_2, 1, 2),
+ DEF_MUX(".sel_pll6_1", CLK_SEL_PLL6_1, SEL_PLL6_1,
+ sel_pll6_1, 2, CLK_MUX_READ_ONLY),
+ DEF_MUX(".sel_g1_1", CLK_SEL_G1_1, SEL_G1_1,
+ sel_g1_1, 2, CLK_MUX_READ_ONLY),
+ DEF_MUX(".sel_g1_2", CLK_SEL_G1_2, SEL_G1_2,
+ sel_g1_2, 2, CLK_MUX_READ_ONLY),
+ DEF_MUX(".sel_g2", CLK_SEL_G2, SEL_G2, sel_g2, 2, 0),
+ DEF_FIXED(".pll6_div2", CLK_PLL6_DIV2, CLK_PLL6, 1, 2),
+ DEF_MUX(".sel_pll6_2", CLK_SEL_PLL6_2, SEL_PLL6_2,
+ sel_pll6_2, 2, CLK_MUX_HIWORD_MASK),
+
+ /* Core output clk*/
+ DEF_DIV("I", R9A07G044_CLK_I, CLK_SEL_PLL1,
+ DIVPL1, NULL, CLK_DIVIDER_POWER_OF_TWO |
+ CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("I2", R9A07G044_CLK_I2, CLK200FIX_CD,
+ DIVPL3CLK200FIX, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_G2, DIVGPU, NULL,
+ CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED("S0", R9A07G044_CLK_S0, CLK_SEL_PLL4, 1, 2),
+ DEF_FIXED("S1", R9A07G044_CLK_S0, CLK_SEL_PLL4, 1, 4),
+ DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK533_CD, 1, 2),
+ DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK533_CD, 1, 4),
+ DEF_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0,
+ sel_shdi, 4, CLK_MUX_HIWORD_MASK),
+ DEF_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1,
+ sel_shdi, 4, CLK_MUX_HIWORD_MASK),
+ DEF_FIXED("M0", R9A07G044_CLK_M0, CLK200FIX_CD, 1, 1),
+ DEF_FIXED("M1", R9A07G044_CLK_M1, CLK_SEL_PLL5_1, 1, 1),
+ DEF_FIXED("M2", R9A07G044_CLK_M2, CLK533FIX_CD, 1, 2),
+ DEF_2DIV("M3", R9A07G044_CLK_M3, CLK_SEL_PLL5_4,
+ DIVDSIA, DIVDSIB, dtable_2b, dtable_4b, 0),
+ DEF_DIV("M4", R9A07G044_CLK_M4, CLK533FIX_LPCLK, DIVDSILPCL,
+ divdsilpcl, CLK_DIVIDER_HIWORD_MASK),
+ DEF_MUX("HP", R9A07G044_CLK_HP, SEL_ETH, sel_eth, 2, CLK_MUX_HIWORD_MASK),
+ DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK800FIX_C, 1, 10),
+ DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK100FIX_CD, 1, 1),
+ DEF_DIV("P0", R9A07G044_CLK_P0, CLK100FIX_C, DIVPL2A,
+ dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("P1", R9A07G044_CLK_P1, CLK200FIX_CD,
+ DIVPL3B, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("P2", R9A07G044_CLK_P2, CLK100FIX_CD,
+ DIVPL3A, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED("AT", R9A07G044_CLK_AT, CLK800FIX_CD, 1, 2),
+};
+
+static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
+ DEF_MOD("gic", R9A07G044_CLK_GIC600,
+ R9A07G044_CLK_P1,
+ 0x514, BIT(0), (BIT(0) | BIT(1))),
+ DEF_MOD("ia55", R9A07G044_CLK_IA55,
+ R9A07G044_CLK_P1,
+ 0x518, (BIT(0) | BIT(1)), BIT(0)),
+ DEF_MOD("syc", R9A07G044_CLK_SYC,
+ CLK_XINCLK,
+ 0x528, BIT(0), BIT(0)),
+ DEF_MOD("dmac", R9A07G044_CLK_DMAC,
+ R9A07G044_CLK_P1,
+ 0x52c, (BIT(0) | BIT(1)),
+ (BIT(0) | BIT(1))),
+ DEF_MOD("sysc", R9A07G044_CLK_SYSC,
+ CLK_XINCLK,
+ 0x530, (BIT(0) | BIT(1)),
+ (BIT(0) | BIT(1) | BIT(2))),
+ DEF_MOD("ssi0", R9A07G044_CLK_SSI0,
+ R9A07G044_CLK_P0,
+ 0x570, (BIT(0) | BIT(1)), BIT(0)),
+ DEF_MOD("ssi1", R9A07G044_CLK_SSI1,
+ R9A07G044_CLK_P0,
+ 0x570, (BIT(2) | BIT(3)), BIT(1)),
+ DEF_MOD("ssi2", R9A07G044_CLK_SSI2,
+ R9A07G044_CLK_P0,
+ 0x570, (BIT(4) | BIT(5)), BIT(2)),
+ DEF_MOD("ssi3", R9A07G044_CLK_SSI3,
+ R9A07G044_CLK_P0,
+ 0x570, (BIT(6) | BIT(7)), BIT(3)),
+ DEF_MOD("src", R9A07G044_CLK_SRC,
+ R9A07G044_CLK_P0,
+ 0x574, BIT(0), BIT(0)),
+ DEF_MOD("usb0", R9A07G044_CLK_USB0,
+ R9A07G044_CLK_P1,
+ 0x578, (BIT(0) | BIT(2) | BIT(3)),
+ (BIT(0) | BIT(2) | BIT(3))),
+ DEF_MOD("usb1", R9A07G044_CLK_USB1,
+ R9A07G044_CLK_P1,
+ 0x578, (BIT(1) | BIT(3)),
+ (BIT(1) | BIT(3))),
+ DEF_MOD("eth0", R9A07G044_CLK_ETH0,
+ R9A07G044_CLK_HP,
+ 0x57c, BIT(0), BIT(0)),
+ DEF_MOD("eth1", R9A07G044_CLK_ETH1,
+ R9A07G044_CLK_HP,
+ 0x57c, BIT(1), BIT(1)),
+ DEF_MOD("i2c0", R9A07G044_CLK_I2C0,
+ R9A07G044_CLK_P0,
+ 0x580, BIT(0), BIT(0)),
+ DEF_MOD("i2c1", R9A07G044_CLK_I2C1,
+ R9A07G044_CLK_P0,
+ 0x580, BIT(1), BIT(1)),
+ DEF_MOD("i2c2", R9A07G044_CLK_I2C2,
+ R9A07G044_CLK_P0,
+ 0x580, BIT(2), BIT(2)),
+ DEF_MOD("i2c3", R9A07G044_CLK_I2C3,
+ R9A07G044_CLK_P0,
+ 0x580, BIT(3), BIT(3)),
+ DEF_MOD("scif0", R9A07G044_CLK_SCIF0,
+ R9A07G044_CLK_P0,
+ 0x584, BIT(0), BIT(0)),
+ DEF_MOD("scif1", R9A07G044_CLK_SCIF1,
+ R9A07G044_CLK_P0,
+ 0x584, BIT(1), BIT(1)),
+ DEF_MOD("scif2", R9A07G044_CLK_SCIF2,
+ R9A07G044_CLK_P0,
+ 0x584, BIT(2), BIT(2)),
+ DEF_MOD("scif3", R9A07G044_CLK_SCIF3,
+ R9A07G044_CLK_P0,
+ 0x584, BIT(3), BIT(3)),
+ DEF_MOD("scif4", R9A07G044_CLK_SCIF4,
+ R9A07G044_CLK_P0,
+ 0x584, BIT(4), BIT(4)),
+ DEF_MOD("sci0", R9A07G044_CLK_SCI0,
+ R9A07G044_CLK_P0,
+ 0x588, BIT(0), BIT(0)),
+ DEF_MOD("sci1", R9A07G044_CLK_SCI1,
+ R9A07G044_CLK_P0,
+ 0x588, BIT(1), BIT(1)),
+ DEF_MOD("canfd", R9A07G044_CLK_CANFD,
+ R9A07G044_CLK_P0,
+ 0x594, BIT(0), (BIT(0) | BIT(1))),
+ DEF_MOD("gpio", R9A07G044_CLK_GPIO,
+ CLK_XINCLK,
+ 0x598, BIT(0),
+ (BIT(0) | BIT(1) | BIT(2))),
+ DEF_MOD("adc", R9A07G044_CLK_ADC,
+ R9A07G044_CLK_TSU,
+ 0x5a8, (BIT(0) | BIT(1)), (BIT(0) | BIT(1))),
+};
+
+static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
+ MOD_CLK_BASE + R9A07G044_CLK_GIC600,
+};
+
+const struct rzg2l_cpg_info r9a07g044_cpg_info = {
+ /* Core Clocks */
+ .core_clks = r9a07g044_core_clks,
+ .num_core_clks = ARRAY_SIZE(r9a07g044_core_clks),
+ .last_dt_core_clk = LAST_DT_CORE_CLK,
+ .num_total_core_clks = MOD_CLK_BASE,
+
+ /* Critical Module Clocks */
+ .crit_mod_clks = r9a07g044_crit_mod_clks,
+ .num_crit_mod_clks = ARRAY_SIZE(r9a07g044_crit_mod_clks),
+
+ /* Module Clocks */
+ .mod_clks = r9a07g044_mod_clks,
+ .num_mod_clks = ARRAY_SIZE(r9a07g044_mod_clks),
+ .num_hw_mod_clks = R9A07G044_CLK_MIPI_DSI_PIN + 1,
+};
diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c
index f096b9d0548c..05e6d61128d6 100644
--- a/drivers/clk/renesas/renesas-rzg2l-cpg.c
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c
@@ -952,6 +952,12 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
}

static const struct of_device_id rzg2l_cpg_match[] = {
+#ifdef CONFIG_CLK_R9A07G044
+ {
+ .compatible = "renesas,r9a07g044-cpg",
+ .data = &r9a07g044_cpg_info,
+ },
+#endif
{ /* sentinel */ }
};

diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.h b/drivers/clk/renesas/renesas-rzg2l-cpg.h
index 8e7117e7f79b..de49de9b2383 100644
--- a/drivers/clk/renesas/renesas-rzg2l-cpg.h
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.h
@@ -212,4 +212,6 @@ struct rzg2l_cpg_info {
unsigned int num_crit_mod_clks;
};

+extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
+
#endif
--
2.17.1

2021-06-03 22:22:08

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 10/12] serial: sh-sci: Add support for RZ/G2L SoC

From: Biju Das <[email protected]>

Add serial support for RZ/G2L SoC with earlycon and
extended mode register support.

Signed-off-by: Biju Das <[email protected]>
Signed-off-by: Lad Prabhakar <[email protected]>
---
drivers/tty/serial/sh-sci.c | 12 +++++++++++-
drivers/tty/serial/sh-sci.h | 1 +
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ef37fdf37612..798ccd88251f 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -289,7 +289,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
},

/*
- * The "SCIFA" that is in RZ/T and RZ/A2.
+ * The "SCIFA" that is in RZ/A2, RZ/G2L and RZ/T.
* 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.
@@ -306,6 +306,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
[SCFDR] = { 0x0E, 16 },
[SCSPTR] = { 0x10, 16 },
[SCLSR] = { 0x12, 16 },
+ [SEMR] = { 0x14, 8 },
},
.fifosize = 16,
.overrun_reg = SCLSR,
@@ -2514,6 +2515,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_cflag & PARENB)
bits++;

+ if (sci_getreg(port, SEMR)->size)
+ serial_port_out(port, SEMR, 0);
+
if (best_clk >= 0) {
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
switch (srr + 1) {
@@ -3170,6 +3174,10 @@ static const struct of_device_id of_sci_match[] = {
.compatible = "renesas,scif-r7s9210",
.data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE),
},
+ {
+ .compatible = "renesas,scif-r9a07g044",
+ .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE),
+ },
/* Family-specific types */
{
.compatible = "renesas,rcar-gen1-scif",
@@ -3452,6 +3460,7 @@ static int __init rzscifa_early_console_setup(struct earlycon_device *device,
port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE;
return early_console_setup(device, PORT_SCIF);
}
+
static int __init scifa_early_console_setup(struct earlycon_device *device,
const char *opt)
{
@@ -3471,6 +3480,7 @@ static int __init hscif_early_console_setup(struct earlycon_device *device,
OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup);
OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup);
OF_EARLYCON_DECLARE(scif, "renesas,scif-r7s9210", rzscifa_early_console_setup);
+OF_EARLYCON_DECLARE(scif, "renesas,scif-r9a07g044", rzscifa_early_console_setup);
OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup);
OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup);
OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup);
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index c0dfe4382898..c0ae78632dda 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -31,6 +31,7 @@ enum {
SCCKS, /* BRG Clock Select Register */
HSRTRGR, /* Rx FIFO Data Count Trigger Register */
HSTTRGR, /* Tx FIFO Data Count Trigger Register */
+ SEMR, /* Serial extended mode register */

SCIx_NR_REGS,
};
--
2.17.1

2021-06-03 22:22:18

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 06/12] clk: renesas: Define RZ/G2L CPG Clock Definitions

Define RZ/G2L (R9A07G044) Clock Pulse Generator Core Clock
and module clock outputs, as listed in Table 8.3 ("Clock List")
of the RZ/G2L Hardware User's Manual (Rev.0.42, Feb.2021).

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
---
include/dt-bindings/clock/r9a07g044-cpg.h | 89 +++++++++++++++++++++++
1 file changed, 89 insertions(+)
create mode 100644 include/dt-bindings/clock/r9a07g044-cpg.h

diff --git a/include/dt-bindings/clock/r9a07g044-cpg.h b/include/dt-bindings/clock/r9a07g044-cpg.h
new file mode 100644
index 000000000000..1d8986563fc5
--- /dev/null
+++ b/include/dt-bindings/clock/r9a07g044-cpg.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__
+#define __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* R9A07G044 CPG Core Clocks */
+#define R9A07G044_CLK_I 0
+#define R9A07G044_CLK_I2 1
+#define R9A07G044_CLK_G 2
+#define R9A07G044_CLK_S0 3
+#define R9A07G044_CLK_S1 4
+#define R9A07G044_CLK_SPI0 5
+#define R9A07G044_CLK_SPI1 6
+#define R9A07G044_CLK_SD0 7
+#define R9A07G044_CLK_SD1 8
+#define R9A07G044_CLK_M0 9
+#define R9A07G044_CLK_M1 10
+#define R9A07G044_CLK_M2 11
+#define R9A07G044_CLK_M3 12
+#define R9A07G044_CLK_M4 13
+#define R9A07G044_CLK_HP 14
+#define R9A07G044_CLK_TSU 15
+#define R9A07G044_CLK_ZT 16
+#define R9A07G044_CLK_P0 17
+#define R9A07G044_CLK_P1 18
+#define R9A07G044_CLK_P2 19
+#define R9A07G044_CLK_AT 20
+#define R9A07G044_OSCCLK 21
+
+/* R9A07G044 Module Clocks */
+#define R9A07G044_CLK_GIC600 0
+#define R9A07G044_CLK_IA55 1
+#define R9A07G044_CLK_SYC 2
+#define R9A07G044_CLK_DMAC 3
+#define R9A07G044_CLK_SYSC 4
+#define R9A07G044_CLK_MTU 5
+#define R9A07G044_CLK_GPT 6
+#define R9A07G044_CLK_ETH0 7
+#define R9A07G044_CLK_ETH1 8
+#define R9A07G044_CLK_I2C0 9
+#define R9A07G044_CLK_I2C1 10
+#define R9A07G044_CLK_I2C2 11
+#define R9A07G044_CLK_I2C3 12
+#define R9A07G044_CLK_SCIF0 13
+#define R9A07G044_CLK_SCIF1 14
+#define R9A07G044_CLK_SCIF2 15
+#define R9A07G044_CLK_SCIF3 16
+#define R9A07G044_CLK_SCIF4 17
+#define R9A07G044_CLK_SCI0 18
+#define R9A07G044_CLK_SCI1 19
+#define R9A07G044_CLK_GPIO 20
+#define R9A07G044_CLK_SDHI0 21
+#define R9A07G044_CLK_SDHI1 22
+#define R9A07G044_CLK_USB0 23
+#define R9A07G044_CLK_USB1 24
+#define R9A07G044_CLK_CANFD 25
+#define R9A07G044_CLK_SSI0 26
+#define R9A07G044_CLK_SSI1 27
+#define R9A07G044_CLK_SSI2 28
+#define R9A07G044_CLK_SSI3 29
+#define R9A07G044_CLK_MHU 30
+#define R9A07G044_CLK_OSTM0 31
+#define R9A07G044_CLK_OSTM1 32
+#define R9A07G044_CLK_OSTM2 33
+#define R9A07G044_CLK_WDT0 34
+#define R9A07G044_CLK_WDT1 35
+#define R9A07G044_CLK_WDT2 36
+#define R9A07G044_CLK_WDT_PON 37
+#define R9A07G044_CLK_GPU 38
+#define R9A07G044_CLK_ISU 39
+#define R9A07G044_CLK_H264 40
+#define R9A07G044_CLK_CRU 41
+#define R9A07G044_CLK_MIPI_DSI 42
+#define R9A07G044_CLK_LCDC 43
+#define R9A07G044_CLK_SRC 44
+#define R9A07G044_CLK_RSPI0 45
+#define R9A07G044_CLK_RSPI1 46
+#define R9A07G044_CLK_RSPI2 47
+#define R9A07G044_CLK_ADC 48
+#define R9A07G044_CLK_TSU_PCLK 49
+#define R9A07G044_CLK_SPI 50
+#define R9A07G044_CLK_MIPI_DSI_V 51
+#define R9A07G044_CLK_MIPI_DSI_PIN 52
+
+#endif /* __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__ */
--
2.17.1

2021-06-03 22:22:32

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 07/12] dt-bindings: clock: renesas: Document RZ/G2L SoC CPG driver

Document the device tree bindings of the Renesas RZ/G2L SoC clock
driver in Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
.../bindings/clock/renesas,rzg2l-cpg.yaml | 80 +++++++++++++++++++
1 file changed, 80 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml

diff --git a/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml b/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
new file mode 100644
index 000000000000..fe32d4daac32
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/clock/renesas,rzg2l-cpg.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Renesas RZ/G2L Clock Pulse Generator / Module Standby Mode
+
+maintainers:
+ - Geert Uytterhoeven <[email protected]>
+
+description: |
+ On Renesas RZ/G2L SoC, the CPG (Clock Pulse Generator) and Module
+ Standby Mode share the same register block.
+
+ They provide the following functionalities:
+ - The CPG block generates various core clocks,
+ - The Module Standby Mode block provides two functions:
+ 1. Module Stop, providing a Clock Domain to control the clock supply
+ to individual SoC devices,
+ 2. Reset Control, to perform a software reset of individual SoC devices.
+
+properties:
+ compatible:
+ const: renesas,r9a07g044-cpg # RZ/G2{L,LC,UL}
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ const: extal
+
+ '#clock-cells':
+ description: |
+ - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
+ and a core clock reference, as defined in
+ <dt-bindings/clock/r9a07g044l-cpg.h>
+ - For module clocks, the two clock specifier cells must be "CPG_MOD" and
+ a module number, as defined in the <dt-bindings/clock/r9a07g044l-cpg.h>.
+ const: 2
+
+ '#power-domain-cells':
+ description:
+ SoC devices that are part of the CPG/Module Standby Mode Clock Domain and
+ can be power-managed through Module Stop should refer to the CPG device
+ node in their "power-domains" property, as documented by the generic PM
+ Domain bindings in Documentation/devicetree/bindings/power/power-domain.yaml.
+ const: 0
+
+ '#reset-cells':
+ description:
+ The single reset specifier cell must be the module number, as defined in
+ the <dt-bindings/clock/r9a07g044l-cpg.h>.
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#power-domain-cells'
+ - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ cpg: clock-controller@11010000 {
+ compatible = "renesas,r9a07g044-cpg";
+ reg = <0x11010000 0x10000>;
+ clocks = <&extal_clk>;
+ clock-names = "extal";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ #reset-cells = <1>;
+ };
--
2.17.1

2021-06-03 22:22:45

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 08/12] clk: renesas: Add CPG core wrapper for RZ/G2L SoC

Add CPG core wrapper for RZ/G2L family.

Based on a patch in the BSP by Binh Nguyen
<[email protected]>.

Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Biju Das <[email protected]>
---
drivers/clk/renesas/Kconfig | 4 +
drivers/clk/renesas/Makefile | 1 +
drivers/clk/renesas/renesas-rzg2l-cpg.c | 973 ++++++++++++++++++++++++
drivers/clk/renesas/renesas-rzg2l-cpg.h | 215 ++++++
4 files changed, 1193 insertions(+)
create mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.c
create mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.h

diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 607e64a17d72..5a0d934f43a4 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -182,6 +182,10 @@ config CLK_RCAR_USB2_CLOCK_SEL
help
This is a driver for R-Car USB2 clock selector

+config CLK_RZG2L
+ bool "Renesas RZ/G2L SoC clock support" if COMPILE_TEST && !ARCH_RENESAS
+ depends on ARCH_RENESAS || COMPILE_TEST
+
# Generic
config CLK_RENESAS_CPG_MSSR
bool "CPG/MSSR clock support" if COMPILE_TEST
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index ef0d2bba92bf..a9c299686b4a 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_CLK_RCAR_CPG_LIB) += rcar-cpg-lib.o
obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o
obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o
obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o
+obj-$(CONFIG_CLK_RZG2L) += renesas-rzg2l-cpg.o

# Generic
obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o
diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c
new file mode 100644
index 000000000000..f096b9d0548c
--- /dev/null
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c
@@ -0,0 +1,973 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/G2L Clock Pulse Generator
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ * Based on renesas-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ * Copyright (C) 2013 Ideas On Board SPRL
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/renesas.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+#include "renesas-rzg2l-cpg.h"
+
+#ifdef DEBUG
+#define WARN_DEBUG(x) WARN_ON(x)
+#else
+#define WARN_DEBUG(x) do { } while (0)
+#endif
+
+#define DIV_RSMASK(v, s, m) ((v >> s) & m)
+#define GET_REG(val) ((val >> 20) & 0xfff)
+#define GET_SHIFT(val) ((val >> 12) & 0xff)
+#define GET_WIDTH(val) ((val >> 8) & 0xf)
+
+#define KDIV(val) DIV_RSMASK(val, 16, 0xffff)
+#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff)
+#define PDIV(val) DIV_RSMASK(val, 0, 0x3f)
+#define SDIV(val) DIV_RSMASK(val, 0, 0x7)
+#define REFDIV(val) DIV_RSMASK(val, 8, 0x3f)
+#define POSTDIV1(val) DIV_RSMASK(val, 0, 0x7)
+#define POSTDIV2(val) DIV_RSMASK(val, 4, 0x7)
+#define FRACIN(val) DIV_RSMASK(val, 8, 0xffffff)
+#define INITIN(val) DIV_RSMASK(val, 16, 0xfff)
+
+#define CLK_ON_R(reg) (reg)
+#define CLK_MON_R(reg) (0x680 - 0x500 + (reg))
+#define CLK_RST_R(reg) (0x800 - 0x500 + (reg))
+#define CLK_MRST_R(reg) (0x980 - 0x500 + (reg))
+
+#define GET_REG1(val) ((val >> 22) & 0x3ff)
+#define GET_REG2(val) ((val >> 12) & 0x3ff)
+#define GET_REG3(val) (val & 0x3ff)
+
+/**
+ * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
+ *
+ * @rcdev: Optional reset controller entity
+ * @dev: CPG device
+ * @base: CPG register block base address
+ * @rmw_lock: protects RMW register accesses
+ * @clks: Array containing all Core and Module Clocks
+ * @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
+ * @info: Pointer to platform data
+ */
+struct rzg2l_cpg_priv {
+#ifdef CONFIG_RESET_CONTROLLER
+ struct reset_controller_dev rcdev;
+#endif
+ struct device *dev;
+ void __iomem *base;
+ spinlock_t rmw_lock;
+
+ struct clk **clks;
+ unsigned int num_core_clks;
+ unsigned int num_mod_clks;
+ unsigned int last_dt_core_clk;
+
+ struct raw_notifier_head notifiers;
+ const struct rzg2l_cpg_info *info;
+};
+
+static void rzg2l_cpg_del_clk_provider(void *data)
+{
+ of_clk_del_provider(data);
+}
+
+static struct clk * __init
+rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
+ struct clk **clks,
+ void __iomem *base,
+ struct rzg2l_cpg_priv *priv)
+{
+ struct device *dev = priv->dev;
+ const struct clk *parent;
+ const char *parent_name;
+ struct clk_hw *clk_hw;
+
+ parent = clks[core->parent & 0xffff];
+ 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(core->conf),
+ GET_SHIFT(core->conf),
+ GET_WIDTH(core->conf),
+ core->flag,
+ core->dtable,
+ &priv->rmw_lock);
+ else
+ clk_hw = clk_hw_register_divider(dev, core->name,
+ parent_name, 0,
+ base + GET_REG(core->conf),
+ GET_SHIFT(core->conf),
+ GET_WIDTH(core->conf),
+ core->flag, &priv->rmw_lock);
+
+ if (IS_ERR(clk_hw))
+ return NULL;
+
+ return clk_hw->clk;
+}
+
+static struct clk * __init
+rzg2l_cpg_sell_clk_register(const struct cpg_core_clk *core,
+ void __iomem *base, struct rzg2l_cpg_priv *priv)
+{
+ const struct clk_hw *clk_hw;
+
+ clk_hw = clk_hw_register_mux(priv->dev, core->name,
+ core->parent_names,
+ core->num_parents,
+ core->flag == CLK_MUX_READ_ONLY ?
+ CLK_SET_RATE_PARENT : 0,
+ base + GET_REG(core->conf),
+ GET_SHIFT(core->conf),
+ GET_WIDTH(core->conf),
+ core->flag, &priv->rmw_lock);
+
+ if (IS_ERR(clk_hw))
+ return NULL;
+
+ return clk_hw->clk;
+}
+
+struct div2_clk {
+ struct clk_hw hw;
+ unsigned int conf;
+ unsigned int confs;
+ const struct clk_div_table *dtable;
+ const struct clk_div_table *dtables;
+ void __iomem *base;
+ struct rzg2l_cpg_priv *priv;
+};
+
+#define to_d2clk(_hw) container_of(_hw, struct div2_clk, hw)
+
+static unsigned int div2_clock_get_div(unsigned int val,
+ const struct clk_div_table *t,
+ unsigned int length)
+{
+ unsigned int i;
+
+ for (i = 0; i <= length; i++)
+ if (val == t[i].val)
+ return t[i].div;
+
+ /* return div=1 if failed */
+ return 1;
+}
+
+static unsigned long
+rzg2l_cpg_div2_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct div2_clk *d2clk = to_d2clk(hw);
+ u32 div, divs, val, vals;
+
+ val = readl(d2clk->base + GET_REG(d2clk->conf));
+ div = DIV_RSMASK(val, GET_SHIFT(d2clk->conf),
+ (BIT(GET_WIDTH(d2clk->conf)) - 1));
+ div = div2_clock_get_div(div, d2clk->dtable,
+ (BIT(GET_WIDTH(d2clk->conf)) - 1));
+
+ vals = readl(d2clk->base + GET_REG(d2clk->confs));
+ divs = DIV_RSMASK(val, GET_SHIFT(d2clk->confs),
+ (BIT(GET_WIDTH(d2clk->confs)) - 1));
+ divs = div2_clock_get_div(divs, d2clk->dtables,
+ (BIT(GET_WIDTH(d2clk->confs)) - 1));
+
+ div = div * divs;
+
+ return DIV_ROUND_CLOSEST_ULL((u64)parent_rate, div);
+}
+
+static int rzg2l_cpg_div2_clk_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ unsigned long best_diff = (unsigned long)-1;
+ unsigned int best_div, best_divs, div, divs;
+ struct div2_clk *d2clk = to_d2clk(hw);
+ unsigned int i, j, n, ns;
+ unsigned long diff;
+
+ n = BIT(GET_WIDTH(d2clk->conf)) - 1;
+ ns = BIT(GET_WIDTH(d2clk->confs)) - 1;
+ for (i = 0; i <= n; i++) {
+ for (j = 0; j <= ns; j++) {
+ div = div2_clock_get_div(i, d2clk->dtable, n);
+ divs = div2_clock_get_div(j, d2clk->dtables, ns);
+ diff = abs(req->best_parent_rate - (req->rate * div * divs));
+ if (best_diff > diff) {
+ best_diff = diff;
+ best_div = div;
+ best_divs = divs;
+ }
+ }
+ }
+
+ req->rate = DIV_ROUND_CLOSEST_ULL((u64)req->best_parent_rate, best_div * best_divs);
+ return 0;
+}
+
+static int rzg2l_cpg_div2_clk_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ unsigned long best_diff = (unsigned long)-1;
+ struct div2_clk *d2clk = to_d2clk(hw);
+ struct rzg2l_cpg_priv *priv = d2clk->priv;
+ unsigned int div, divs, val, vals, n, ns;
+ unsigned long diff, flags;
+ unsigned int i, j;
+
+ n = BIT(GET_WIDTH(d2clk->conf)) - 1;
+ ns = BIT(GET_WIDTH(d2clk->confs)) - 1;
+ for (i = 0; i <= n; i++) {
+ for (j = 0; j <= ns; j++) {
+ div = div2_clock_get_div(i, d2clk->dtable, n);
+ divs = div2_clock_get_div(j, d2clk->dtables, ns);
+ diff = abs(parent_rate - (rate * div * divs));
+ if (best_diff > diff) {
+ best_diff = diff;
+ val = i;
+ vals = j;
+ }
+ }
+ }
+
+ spin_lock_irqsave(&priv->rmw_lock, flags);
+
+ val = (val << GET_SHIFT(d2clk->conf)) |
+ (0x1 << (GET_SHIFT(d2clk->conf) + 16));
+ writel(val, d2clk->base + GET_REG(d2clk->conf));
+
+ vals = (vals << GET_SHIFT(d2clk->confs)) |
+ (0x1 << (GET_SHIFT(d2clk->confs) + 16));
+ writel(vals, d2clk->base + GET_REG(d2clk->confs));
+
+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops rzg2l_cpg_div2_ops = {
+ .recalc_rate = rzg2l_cpg_div2_clk_recalc_rate,
+ .determine_rate = rzg2l_cpg_div2_clk_determine_rate,
+ .set_rate = rzg2l_cpg_div2_clk_set_rate,
+};
+
+static struct clk * __init
+rzg2l_cpg_div2_clk_register(const struct cpg_core_clk *core,
+ struct clk **clks,
+ void __iomem *base,
+ struct rzg2l_cpg_priv *priv)
+{
+ const struct clk *parent;
+ struct clk_init_data init;
+ struct div2_clk *d2clk;
+ struct device *dev = priv->dev;
+ struct clk *clk;
+ const char *parent_name;
+
+ parent = clks[core->parent & 0xffff];
+ if (IS_ERR(parent))
+ return ERR_CAST(parent);
+
+ d2clk = devm_kzalloc(dev, sizeof(*d2clk), GFP_KERNEL);
+ if (!d2clk) {
+ clk = ERR_PTR(-ENOMEM);
+ return NULL;
+ }
+
+ parent_name = __clk_get_name(parent);
+ init.name = core->name;
+ init.ops = &rzg2l_cpg_div2_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ d2clk->hw.init = &init;
+ d2clk->conf = core->conf;
+ d2clk->confs = core->confs;
+ d2clk->dtable = core->dtable;
+ d2clk->dtables = core->dtables;
+ d2clk->base = base;
+ d2clk->priv = priv;
+
+ clk = clk_register(NULL, &d2clk->hw);
+ if (IS_ERR(clk))
+ kfree(d2clk);
+
+ return clk;
+}
+
+struct pll_clk {
+ struct clk_hw hw;
+ unsigned int stby_conf;
+ unsigned int mon_conf;
+ unsigned int conf;
+ unsigned int type;
+ void __iomem *base;
+ struct rzg2l_cpg_priv *priv;
+};
+
+#define to_pll(_hw) container_of(_hw, struct pll_clk, hw)
+
+static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct pll_clk *pll_clk = to_pll(hw);
+ struct rzg2l_cpg_priv *priv = pll_clk->priv;
+ unsigned int val1, val2, val3;
+ unsigned int mult = 1;
+ unsigned int div = 1;
+
+ if (pll_clk->type == CLK_TYPE_SAM_PLL) {
+ val1 = readl(priv->base + GET_REG1(pll_clk->conf));
+ val2 = readl(priv->base + GET_REG2(pll_clk->conf));
+ mult = MDIV(val1) + KDIV(val1) / 65536;
+ div = PDIV(val1) * (1 << SDIV(val2));
+ } else if (pll_clk->type == CLK_TYPE_SI_PLL) {
+ val1 = readl(priv->base + GET_REG1(pll_clk->conf));
+ val2 = readl(priv->base + GET_REG2(pll_clk->conf));
+ val3 = readl(priv->base + GET_REG3(pll_clk->conf));
+
+ mult = INITIN(val3) + FRACIN(val2) / (0x1 << 24);
+ div = POSTDIV1(val1) * POSTDIV2(val1) * REFDIV(val1);
+ } else {
+ return 0;
+ }
+
+ return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div);
+}
+
+static const struct clk_ops rzg2l_cpg_pll_ops = {
+ .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate,
+};
+
+static struct clk * __init
+rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
+ struct clk **clks,
+ void __iomem *base,
+ struct rzg2l_cpg_priv *priv)
+{
+ struct device *dev = priv->dev;
+ const struct clk *parent;
+ struct clk_init_data init;
+ const char *parent_name;
+ struct pll_clk *pll_clk;
+ struct clk *clk;
+
+ parent = clks[core->parent & 0xffff];
+ if (IS_ERR(parent))
+ return ERR_CAST(parent);
+
+ pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
+ if (!pll_clk) {
+ clk = ERR_PTR(-ENOMEM);
+ return NULL;
+ }
+
+ parent_name = __clk_get_name(parent);
+ init.name = core->name;
+ init.ops = &rzg2l_cpg_pll_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll_clk->hw.init = &init;
+ pll_clk->stby_conf = core->stby_conf;
+ pll_clk->mon_conf = core->mon_conf;
+ pll_clk->conf = core->conf;
+ pll_clk->base = base;
+ pll_clk->priv = priv;
+ pll_clk->type = core->type;
+
+ clk = clk_register(NULL, &pll_clk->hw);
+ if (IS_ERR(clk))
+ kfree(pll_clk);
+
+ return clk;
+}
+
+static struct clk
+*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
+ void *data)
+{
+ unsigned int clkidx = clkspec->args[1];
+ struct rzg2l_cpg_priv *priv = data;
+ struct device *dev = priv->dev;
+ const char *type;
+ struct clk *clk;
+
+ switch (clkspec->args[0]) {
+ case CPG_CORE:
+ type = "core";
+ if (clkidx > priv->last_dt_core_clk) {
+ dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
+ return ERR_PTR(-EINVAL);
+ }
+ clk = priv->clks[clkidx];
+ break;
+
+ case CPG_MOD:
+ type = "module";
+ if (clkidx > priv->num_core_clks + priv->num_mod_clks) {
+ dev_err(dev, "Invalid %s clock index %u\n", type,
+ clkidx);
+ return ERR_PTR(-EINVAL);
+ }
+ clk = priv->clks[priv->num_core_clks + clkidx];
+ break;
+
+ default:
+ dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (IS_ERR(clk))
+ dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
+ PTR_ERR(clk));
+ else
+ dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
+ clkspec->args[0], clkspec->args[1], clk,
+ clk_get_rate(clk));
+ return clk;
+}
+
+static void __init
+rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
+ const struct rzg2l_cpg_info *info,
+ struct rzg2l_cpg_priv *priv)
+{
+ struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent;
+ struct device *dev = priv->dev;
+ unsigned int id = core->id, div = core->div;
+ const char *parent_name;
+
+ WARN_DEBUG(id >= priv->num_core_clks);
+ WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
+
+ if (!core->name) {
+ /* Skip NULLified clock */
+ return;
+ }
+
+ switch (core->type) {
+ case CLK_TYPE_IN:
+ clk = of_clk_get_by_name(priv->dev->of_node, core->name);
+ break;
+ case CLK_TYPE_FF:
+ WARN_DEBUG(core->parent >= priv->num_core_clks);
+ parent = priv->clks[core->parent];
+ if (IS_ERR(parent)) {
+ clk = parent;
+ goto fail;
+ }
+
+ parent_name = __clk_get_name(parent);
+ clk = clk_register_fixed_factor(NULL, core->name,
+ parent_name, CLK_SET_RATE_PARENT,
+ core->mult, div);
+ break;
+ case CLK_TYPE_SAM_PLL:
+ case CLK_TYPE_SI_PLL:
+ clk = rzg2l_cpg_pll_clk_register(core, priv->clks,
+ priv->base, priv);
+ break;
+ case CLK_TYPE_DIV:
+ clk = rzg2l_cpg_div_clk_register(core, priv->clks,
+ priv->base, priv);
+ break;
+ case CLK_TYPE_2DIV:
+ clk = rzg2l_cpg_div2_clk_register(core, priv->clks,
+ priv->base, priv);
+ break;
+ case CLK_TYPE_MUX:
+ clk = rzg2l_cpg_sell_clk_register(core, priv->base, priv);
+ break;
+ default:
+ goto fail;
+ };
+
+ if (IS_ERR_OR_NULL(clk))
+ goto fail;
+
+ dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
+ priv->clks[id] = clk;
+ return;
+
+fail:
+ dev_err(dev, "Failed to register %s clock %s: %ld\n", "core",
+ core->name, PTR_ERR(clk));
+}
+
+/**
+ * struct mstp_clock - MSTP gating clock
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ * @off: register offset
+ * @onoff: ON/MON bits
+ * @reset: reset bits
+ * @priv: CPG/MSTP private data
+ */
+struct mstp_clock {
+ struct clk_hw hw;
+ u16 off;
+ u8 onoff;
+ u8 reset;
+ struct rzg2l_cpg_priv *priv;
+};
+
+#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+
+static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
+{
+ struct mstp_clock *clock = to_mod_clock(hw);
+ struct rzg2l_cpg_priv *priv = clock->priv;
+ unsigned int reg = clock->off;
+ struct device *dev = priv->dev;
+ unsigned long flags;
+ unsigned int i;
+ u32 value;
+
+ if (!clock->off) {
+ dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk);
+ return 0;
+ }
+
+ dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk,
+ enable ? "ON" : "OFF");
+ spin_lock_irqsave(&priv->rmw_lock, flags);
+
+ if (enable)
+ value = (clock->onoff << 16) | clock->onoff;
+ else
+ value = clock->onoff << 16;
+ writel(value, priv->base + CLK_ON_R(reg));
+
+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
+
+ if (!enable)
+ return 0;
+
+ for (i = 1000; i > 0; --i) {
+ if (((readl(priv->base + CLK_MON_R(reg))) & clock->onoff))
+ break;
+ cpu_relax();
+ }
+
+ if (!i) {
+ dev_err(dev, "Failed to enable CLK_ON %p\n",
+ priv->base + CLK_ON_R(reg));
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int rzg2l_mod_clock_enable(struct clk_hw *hw)
+{
+ return rzg2l_mod_clock_endisable(hw, true);
+}
+
+static void rzg2l_mod_clock_disable(struct clk_hw *hw)
+{
+ rzg2l_mod_clock_endisable(hw, false);
+}
+
+static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
+{
+ struct mstp_clock *clock = to_mod_clock(hw);
+ struct rzg2l_cpg_priv *priv = clock->priv;
+ u32 value;
+
+ if (!clock->off) {
+ dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk);
+ return 1;
+ }
+
+ value = readl(priv->base + CLK_MON_R(clock->off));
+
+ return !(value & clock->onoff);
+}
+
+static const struct clk_ops rzg2l_mod_clock_ops = {
+ .enable = rzg2l_mod_clock_enable,
+ .disable = rzg2l_mod_clock_disable,
+ .is_enabled = rzg2l_mod_clock_is_enabled,
+};
+
+static void __init
+rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
+ const struct rzg2l_cpg_info *info,
+ struct rzg2l_cpg_priv *priv)
+{
+ struct mstp_clock *clock = NULL;
+ struct device *dev = priv->dev;
+ unsigned int id = mod->id;
+ struct clk_init_data init;
+ struct clk *parent, *clk;
+ const char *parent_name;
+ unsigned int i;
+
+ 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);
+
+ if (!mod->name) {
+ /* Skip NULLified clock */
+ return;
+ }
+
+ parent = priv->clks[mod->parent];
+ if (IS_ERR(parent)) {
+ clk = parent;
+ goto fail;
+ }
+
+ clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
+ if (!clock) {
+ clk = ERR_PTR(-ENOMEM);
+ goto fail;
+ }
+
+ init.name = mod->name;
+ init.ops = &rzg2l_mod_clock_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ for (i = 0; i < info->num_crit_mod_clks; i++)
+ if (id == info->crit_mod_clks[i]) {
+ dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n",
+ mod->name);
+ init.flags |= CLK_IS_CRITICAL;
+ break;
+ }
+
+ parent_name = __clk_get_name(parent);
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ clock->off = mod->off;
+ clock->onoff = mod->onoff;
+ clock->reset = mod->reset;
+ clock->priv = priv;
+ clock->hw.init = &init;
+
+ clk = clk_register(NULL, &clock->hw);
+ if (IS_ERR(clk))
+ goto fail;
+
+ dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
+ priv->clks[id] = clk;
+ return;
+
+fail:
+ dev_err(dev, "Failed to register %s clock %s: %ld\n", "module",
+ mod->name, PTR_ERR(clk));
+ kfree(clock);
+}
+
+#ifdef CONFIG_RESET_CONTROLLER
+
+#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev)
+
+static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+ const struct rzg2l_cpg_info *info = priv->info;
+ unsigned int reg = info->mod_clks[id].off;
+ u32 dis = info->mod_clks[id].reset;
+ u32 we = dis << 16;
+
+ dev_dbg(rcdev->dev, "reset name:%s id:%ld offset:0x%x\n",
+ info->mod_clks[id].name, id, CLK_RST_R(reg));
+
+ /* Reset module */
+ writel(we, priv->base + CLK_RST_R(reg));
+
+ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
+ udelay(35);
+
+ /* Release module from reset state */
+ writel(we | dis, priv->base + CLK_RST_R(reg));
+
+ return 0;
+}
+
+static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+ const struct rzg2l_cpg_info *info = priv->info;
+ unsigned int reg = info->mod_clks[id].off;
+ u32 value = info->mod_clks[id].reset << 16;
+
+ dev_dbg(rcdev->dev, "assert name:%s id:%ld offset:0x%x\n",
+ info->mod_clks[id].name, id, CLK_RST_R(reg));
+
+ writel(value, priv->base + CLK_RST_R(reg));
+ return 0;
+}
+
+static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+ const struct rzg2l_cpg_info *info = priv->info;
+ unsigned int reg = info->mod_clks[id].off;
+ u32 dis = info->mod_clks[id].reset;
+ u32 value = (dis << 16) | dis;
+
+ dev_dbg(rcdev->dev, "deassert name:%s id:%ld offset:0x%x\n",
+ info->mod_clks[id].name, id, CLK_RST_R(reg));
+
+ writel(value, priv->base + CLK_RST_R(reg));
+ return 0;
+}
+
+static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+ const struct rzg2l_cpg_info *info = priv->info;
+ unsigned int reg = info->mod_clks[id].off;
+ u32 bitmask = info->mod_clks[id].reset;
+
+ return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
+}
+
+static const struct reset_control_ops rzg2l_cpg_reset_ops = {
+ .reset = rzg2l_cpg_reset,
+ .assert = rzg2l_cpg_assert,
+ .deassert = rzg2l_cpg_deassert,
+ .status = rzg2l_cpg_status,
+};
+
+static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ unsigned int id = reset_spec->args[0];
+
+ if (id >= rcdev->nr_resets) {
+ dev_err(rcdev->dev, "Invalid reset index %u\n", id);
+ return -EINVAL;
+ }
+
+ return id;
+}
+
+static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
+{
+ priv->rcdev.ops = &rzg2l_cpg_reset_ops;
+ priv->rcdev.of_node = priv->dev->of_node;
+ priv->rcdev.dev = priv->dev;
+ priv->rcdev.of_reset_n_cells = 1;
+ priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate;
+ priv->rcdev.nr_resets = priv->num_mod_clks;
+
+ return devm_reset_controller_register(priv->dev, &priv->rcdev);
+}
+
+#else /* !CONFIG_RESET_CONTROLLER */
+static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
+{
+ return 0;
+}
+#endif /* !CONFIG_RESET_CONTROLLER */
+
+static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec)
+{
+ if (clkspec->args_count != 2)
+ return false;
+
+ switch (clkspec->args[0]) {
+ case CPG_MOD:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct of_phandle_args clkspec;
+ struct clk *clk;
+ int error;
+ int i = 0;
+
+ while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
+ &clkspec)) {
+ if (rzg2l_cpg_is_pm_clk(&clkspec))
+ goto found;
+
+ of_node_put(clkspec.np);
+ i++;
+ }
+
+ return 0;
+
+found:
+ clk = of_clk_get_from_provider(&clkspec);
+ of_node_put(clkspec.np);
+
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ error = pm_clk_create(dev);
+ if (error)
+ goto fail_put;
+
+ error = pm_clk_add_clk(dev, clk);
+ if (error)
+ goto fail_destroy;
+
+ return 0;
+
+fail_destroy:
+ pm_clk_destroy(dev);
+fail_put:
+ clk_put(clk);
+ return error;
+}
+
+static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev)
+{
+ if (!pm_clk_no_clocks(dev))
+ pm_clk_destroy(dev);
+}
+
+static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct generic_pm_domain *genpd;
+
+ genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL);
+ if (!genpd)
+ return -ENOMEM;
+
+ genpd->name = np->name;
+ genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+ GENPD_FLAG_ACTIVE_WAKEUP;
+ genpd->attach_dev = rzg2l_cpg_attach_dev;
+ genpd->detach_dev = rzg2l_cpg_detach_dev;
+ pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
+
+ of_genpd_add_provider_simple(np, genpd);
+ return 0;
+}
+
+static int __init rzg2l_cpg_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ const struct rzg2l_cpg_info *info;
+ struct rzg2l_cpg_priv *priv;
+ unsigned int nclks, i;
+ struct clk **clks;
+ int error;
+
+ info = of_device_get_match_data(dev);
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+ priv->info = info;
+ spin_lock_init(&priv->rmw_lock);
+
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ nclks = info->num_total_core_clks + info->num_hw_mod_clks;
+ clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);
+ if (!clks)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, priv);
+ priv->clks = clks;
+ 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;
+
+ for (i = 0; i < nclks; i++)
+ clks[i] = ERR_PTR(-ENOENT);
+
+ for (i = 0; i < info->num_core_clks; i++)
+ rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv);
+
+ for (i = 0; i < info->num_mod_clks; i++)
+ rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv);
+
+ error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv);
+ if (error)
+ return error;
+
+ error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np);
+ if (error)
+ return error;
+
+ error = rzg2l_cpg_add_clk_domain(dev);
+ if (error)
+ return error;
+
+ error = rzg2l_cpg_reset_controller_register(priv);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static const struct of_device_id rzg2l_cpg_match[] = {
+ { /* sentinel */ }
+};
+
+static struct platform_driver rzg2l_cpg_driver = {
+ .driver = {
+ .name = "rzg2l-cpg",
+ .of_match_table = rzg2l_cpg_match,
+ },
+};
+
+static int __init rzg2l_cpg_init(void)
+{
+ return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe);
+}
+
+subsys_initcall(rzg2l_cpg_init);
+
+MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.h b/drivers/clk/renesas/renesas-rzg2l-cpg.h
new file mode 100644
index 000000000000..8e7117e7f79b
--- /dev/null
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.h
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * RZ/G2L Clock Pulse Generator
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ */
+
+#ifndef __RENESAS_RZG2L_CPG_H__
+#define __RENESAS_RZG2L_CPG_H__
+
+/* Register offset */
+/* n : 0, 1, 2 : PLL1, PLL4, PLL6 */
+#define PLL146_CLK1_R(n) (0x04 + (16 * n))
+#define PLL146_CLK2_R(n) (0x08 + (16 * n))
+#define PLL146_MON_R(n) (0x0C + (16 * n))
+#define PLL146_STBY_R(n) (0x00 + (16 * n))
+
+/* n : 0, 1, 2 : PLL2, PLL3, PLL5 */
+#define PLL235_CLK1_R(n) (0x104 + (32 * n))
+#define PLL235_CLK3_R(n) (0x10c + (32 * n))
+#define PLL235_CLK4_R(n) (0x110 + (32 * n))
+#define PLL235_MON_R(n) (0x11C + (32 * n))
+#define PLL235_STBY_R(n) (0x100 + (32 * n))
+
+#define PLL1_DIV_R (0x200)
+#define PLL2_DIV_R (0x204)
+#define PLL3A_DIV_R (0x208)
+#define PLL3B_DIV_R (0x20c)
+#define PLL6_DIV_R (0x210)
+#define PL2SDHI_SEL_R (0x218)
+#define CLK_STATUS_R (0x280)
+#define CA55_SSEL_R (0x400)
+#define PL2_SSEL_R (0x404)
+#define PL3_SSEL_R (0x408)
+#define PL4_DSEL_R (0x21C)
+#define PL5_SSEL_R (0x410)
+#define PL6_SSEL_R (0x414)
+#define PL6_ETH_SSEL_R (0x418)
+#define PL5_SDIV_R (0x420)
+#define OTHERFUNC1_R (0xBE8)
+
+#define SEL_PLL1 (CA55_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL2_1 (PL2_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL2_2 (PL2_SSEL_R << 20 | 4 << 12 | 1 << 8)
+#define SEL_PLL3_1 (PL3_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL3_2 (PL3_SSEL_R << 20 | 4 << 12 | 1 << 8)
+#define SEL_PLL3_3 (PL3_SSEL_R << 20 | 8 << 12 | 1 << 8)
+#define SEL_PLL4 (PL4_DSEL_R << 20 | 8 << 12 | 1 << 8)
+#define SEL_PLL5_1 (PL5_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL5_2 (PL5_SSEL_R << 20 | 4 << 12 | 1 << 8)
+#define SEL_PLL5_3 (PL5_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL5_4 (OTHERFUNC1_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL6_1 (PL6_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_PLL6_2 (PL6_ETH_SSEL_R << 20 | 0 << 12 | 1 << 8)
+#define SEL_ETH (PL6_ETH_SSEL_R << 20 | 4 << 12 | 1 << 8)
+#define SEL_G1_1 (PL6_SSEL_R << 20 | 4 << 12 | 1 << 8)
+#define SEL_G1_2 (PL6_SSEL_R << 20 | 8 << 12 | 1 << 8)
+#define SEL_G2 (PL6_SSEL_R << 20 | 12 << 12 | 1 << 8)
+#define SEL_SDHI0 (PL2SDHI_SEL_R << 20 | 0 << 12 | 2 << 8)
+#define SEL_SDHI1 (PL2SDHI_SEL_R << 20 | 4 << 12 | 2 << 8)
+#define DIVPL1 (PLL1_DIV_R << 20 | 0 << 12 | 2 << 8)
+#define DIVPL2A (PLL2_DIV_R << 20 | 0 << 12 | 3 << 8)
+#define DIVPL2B (PLL2_DIV_R << 20 | 4 << 12 | 3 << 8)
+#define DIVPL2C (PLL2_DIV_R << 20 | 8 << 12 | 3 << 8)
+#define DIVDSILPCL (PLL2_DIV_R << 20 | 12 << 12 | 2 << 8)
+#define DIVPL3A (PLL3A_DIV_R << 20 | 0 << 12 | 3 << 8)
+#define DIVPL3B (PLL3A_DIV_R << 20 | 4 << 12 | 3 << 8)
+#define DIVPL3C (PLL3A_DIV_R << 20 | 8 << 12 | 3 << 8)
+#define DIVPL3CLK200FIX (PLL3B_DIV_R << 20 | 0 << 12 | 3 << 8)
+#define DIVGPU (PLL6_DIV_R << 20 | 0 << 12 | 2 << 8)
+#define DIVDSIB (PL5_SDIV_R << 20 | 8 << 12 | 4 << 8)
+#define DIVDSIA (PL5_SDIV_R << 20 | 0 << 12 | 2 << 8)
+
+#define PLL146_STBY(n) (PLL146_STBY_R(n) << 20 | 2 << 16 | 0 << 12)
+#define PLL146_MON(n) (PLL146_MON_R(n) << 20 | 4 << 16 | 0 << 12)
+#define PLL235_STBY(n) (PLL235_STBY_R(n) << 20 | 2 << 16 | 0 << 12)
+#define PLL235_MON(n) (PLL235_MON_R(n) << 20 | 4 << 16 | 0 << 12)
+
+#define PLL146_CONF(n) (PLL146_CLK1_R(n) << 22 | PLL146_CLK2_R(n) << 12 | 0)
+#define PLL235_CONF(n) (PLL235_CLK1_R(n) << 22 | PLL235_CLK3_R(n) << 12 | PLL235_CLK4_R(n))
+
+/**
+ * Definitions of CPG Core Clocks
+ *
+ * These include:
+ * - Clock outputs exported to DT
+ * - External input clocks
+ * - Internal CPG clocks
+ */
+struct cpg_core_clk {
+ const char *name;
+ unsigned int id;
+ unsigned int parent;
+ unsigned int div;
+ unsigned int mult;
+ unsigned int type;
+ unsigned int conf;
+ const struct clk_div_table *dtable;
+ int flag;
+ const char * const *parent_names;
+ int num_parents;
+
+ /* used for clocks with two configs */
+ unsigned int confs;
+ const struct clk_div_table *dtables;
+ unsigned int stby_conf;
+ unsigned int mon_conf;
+};
+
+enum clk_types {
+ /* Generic */
+ CLK_TYPE_IN, /* External Clock Input */
+ CLK_TYPE_FF, /* Fixed Factor Clock */
+ CLK_TYPE_SAM_PLL,
+ CLK_TYPE_SI_PLL,
+
+ /* Clock with divider */
+ CLK_TYPE_DIV,
+ CLK_TYPE_2DIV,
+
+ /* Clock with selector */
+ CLK_TYPE_MUX,
+
+ /* Custom definitions start here */
+ CLK_TYPE_CUSTOM,
+};
+
+#define DEF_TYPE(_name, _id, _type...) \
+ { .name = _name, .id = _id, .type = _type }
+#define DEF_BASE(_name, _id, _type, _parent...) \
+ DEF_TYPE(_name, _id, _type, .parent = _parent)
+#define DEF_PLL(_name, _id, _type, _parent, _conf, _stby_conf, _mon_conf) \
+ DEF_TYPE(_name, _id, _type, .parent = _parent, .conf = _conf, \
+ .stby_conf = _stby_conf, .mon_conf = _mon_conf)
+#define DEF_INPUT(_name, _id) \
+ DEF_TYPE(_name, _id, CLK_TYPE_IN)
+#define DEF_FIXED(_name, _id, _parent, _mult, _div) \
+ DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
+#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \
+ DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
+ .parent = _parent, .dtable = _dtable, .flag = _flag)
+#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag) \
+ DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
+ .parent_names = _parent_names, \
+ .num_parents = _num_parents, .flag = _flag)
+/* Clock with two dividers */
+#define DEF_2DIV(_name, _id, _parent, _conf, _confs, _dtable, _dtables, _flag) \
+ DEF_TYPE(_name, _id, CLK_TYPE_2DIV, .parent = _parent, \
+ .conf = _conf, .confs = _confs, \
+ .dtable = _dtable, .dtables = _dtables, .flag = _flag)
+
+/**
+ * struct rzg2l_mod_clk - Module Clocks definitions
+ *
+ * @name: handle between common and hardware-specific interfaces
+ * @id: clock index in array containing all Core and Module Clocks
+ * @parent: id of parent clock
+ * @off: register offset
+ * @onoff: ON/MON bits
+ * @reset: reset bits
+ */
+struct rzg2l_mod_clk {
+ const char *name;
+ unsigned int id;
+ unsigned int parent;
+ u16 off;
+ u8 onoff;
+ u8 reset;
+};
+
+#define DEF_MOD(_name, _id, _parent, _off, _onoff, _reset) \
+ [_id] = { \
+ .name = _name, \
+ .id = MOD_CLK_BASE + _id, \
+ .parent = (_parent), \
+ .off = (_off), \
+ .onoff = (_onoff), \
+ .reset = (_reset) \
+ }
+
+/**
+ * struct rzg2l_cpg_info - SoC-specific CPG Description
+ *
+ * @core_clks: Array of Core Clock definitions
+ * @num_core_clks: Number of entries in core_clks[]
+ * @last_dt_core_clk: ID of the last Core Clock exported to DT
+ * @num_total_core_clks: Total number of Core Clocks (exported + internal)
+ *
+ * @mod_clks: Array of Module Clock definitions
+ * @num_mod_clks: Number of entries in mod_clks[]
+ * @num_hw_mod_clks: Number of Module Clocks supported by the hardware
+ *
+ * @crit_mod_clks: Array with Module Clock IDs of critical clocks that
+ * should not be disabled without a knowledgeable driver
+ * @num_crit_mod_clks: Number of entries in crit_mod_clks[]
+ */
+struct rzg2l_cpg_info {
+ /* Core Clocks */
+ const struct cpg_core_clk *core_clks;
+ unsigned int num_core_clks;
+ unsigned int last_dt_core_clk;
+ unsigned int num_total_core_clks;
+
+ /* Module Clocks */
+ const struct rzg2l_mod_clk *mod_clks;
+ unsigned int num_mod_clks;
+ unsigned int num_hw_mod_clks;
+
+ /* Critical Module Clocks that should not be disabled */
+ const unsigned int *crit_mod_clks;
+ unsigned int num_crit_mod_clks;
+};
+
+#endif
--
2.17.1

2021-06-03 22:23:12

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v2 12/12] arm64: dts: renesas: Add initial device tree for RZ/G2L SMARC EVK

Add basic support for RZ/G2L SMARC EVK (based on R9A07G044L2):
- memory
- External input clock
- SCIF

Signed-off-by: Lad Prabhakar <[email protected]>
Signed-off-by: Biju Das <[email protected]>
---
arch/arm64/boot/dts/renesas/Makefile | 2 ++
.../boot/dts/renesas/r9a07g044l2-smarc.dts | 21 +++++++++++++++
arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 27 +++++++++++++++++++
3 files changed, 50 insertions(+)
create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
create mode 100644 arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index f2de2fa0c8b8..68e30e26564b 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -62,3 +62,5 @@ dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu.dtb
dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb

dtb-$(CONFIG_ARCH_R8A779A0) += r8a779a0-falcon.dtb
+
+dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts b/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
new file mode 100644
index 000000000000..de2b86cac577
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2L SMARC EVK board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g044.dtsi"
+#include "rzg2l-smarc.dtsi"
+
+/ {
+ model = "Renesas SMARC EVK based on r9a07g044l2";
+ compatible = "renesas,smarc-evk", "renesas,r9a07g044l2", "renesas,r9a07g044";
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x78000000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
new file mode 100644
index 000000000000..adcd4f50519e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2L SMARC EVK common parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel";
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&extal_clk {
+ clock-frequency = <24000000>;
+};
+
+&scif0 {
+ status = "okay";
+};
--
2.17.1

2021-06-04 13:56:42

by Biju Das

[permalink] [raw]
Subject: RE: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's

Hi Prabhakar,

Thanks for the patch.

> Subject: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for
> RZ/G2{L,LC} SoC's
>
> Add initial DTSI for RZ/G2{L,LC} SoC's.
>
> File structure:
> r9a07g044.dtsi => RZ/G2L family SoC common parts r9a07g044l1.dtsi =>
> Specific to RZ/G2L (R9A07G044L single cortex A55) SoC
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Signed-off-by: Biju Das <[email protected]>
> ---
> arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 119 +++++++++++++++++++
> arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 ++++
> 2 files changed, 144 insertions(+)
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
>
> diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> new file mode 100644
> index 000000000000..b2dbf6543d98
> --- /dev/null
> +++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> @@ -0,0 +1,119 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Device Tree Source for the RZ/G2L and RZ/G2LC common SoC parts
> + *
> + * Copyright (C) 2021 Renesas Electronics Corp.
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/r9a07g044-cpg.h>
> +
> +/ {
> + compatible = "renesas,r9a07g044";
> + #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>;
> + };
> +
> + psci {
> + compatible = "arm,psci-1.0", "arm,psci-0.2";
> + method = "smc";
> + };
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cpu-map {
> + cluster0 {
> + core0 {
> + cpu = <&cpu0>;
> + };
> + core1 {
> + cpu = <&cpu1>;
> + };
> + };
> + };
> +
> + 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";
> + };
> +
> + L3_CA55: cache-controller-0 {
> + compatible = "cache";
> + cache-unified;
> + cache-size = <0x40000>;
> + };
> + };
> +
> + soc: soc {
> + compatible = "simple-bus";
> + interrupt-parent = <&gic>;
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + scif0: serial@1004b800 {
> + compatible = "renesas,scif-r9a07g044";
> + reg = <0 0x1004b800 0 0x400>;
> + interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "eri", "rxi", "txi",
> + "bri", "dri", "tei";
> + clocks = <&cpg CPG_MOD R9A07G044_CLK_SCIF0>;
> + clock-names = "fck";
> + power-domains = <&cpg>;
> + resets = <&cpg R9A07G044_CLK_SCIF0>;
> + status = "disabled";
> + };
> +
> + cpg: clock-controller@11010000 {
> + compatible = "renesas,r9a07g044-cpg";
> + reg = <0 0x11010000 0 0x10000>;

What about WDTOVF_RST(0xB10) and WDTRST_SEL(0xB14) registers, this registers to be handled by WDT driver.
Unfortunately it is in CPG block.

So do we need to map the entire CPG registers or up to 0xB00?

Geert, Prabhakar: Any thoughts?

Cheers,
Biju

> + clocks = <&extal_clk>;
> + clock-names = "extal";
> + #clock-cells = <2>;
> + #reset-cells = <1>;
> + #power-domain-cells = <0>;
> + };
> +
> + gic: interrupt-controller@11900000 {
> + compatible = "arm,gic-v3";
> + #interrupt-cells = <3>;
> + #address-cells = <0>;
> + interrupt-controller;
> + reg = <0x0 0x11900000 0 0x40000>,
> + <0x0 0x11940000 0 0x60000>;
> + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
> + };
> + };
> +
> + timer {
> + compatible = "arm,armv8-timer";
> + interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2)
> | IRQ_TYPE_LEVEL_LOW)>,
> + <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
> IRQ_TYPE_LEVEL_LOW)>,
> + <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
> IRQ_TYPE_LEVEL_LOW)>,
> + <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
> IRQ_TYPE_LEVEL_LOW)>;
> + };
> +};
> diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
> b/arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
> new file mode 100644
> index 000000000000..02f6da806696
> --- /dev/null
> +++ b/arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Device Tree Source for the RZ/G2L R9A07G044L1 common parts
> + *
> + * Copyright (C) 2021 Renesas Electronics Corp.
> + */
> +
> +/dts-v1/;
> +#include "r9a07g044.dtsi"
> +
> +/ {
> + compatible = "renesas,r9a07g044l1", "renesas,r9a07g044";
> +
> + cpus {
> + /delete-node/ cpu-map;
> + /delete-node/ cpu@100;
> + };
> +
> + timer {
> + interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1)
> | IRQ_TYPE_LEVEL_LOW)>,
> + <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
> IRQ_TYPE_LEVEL_LOW)>,
> + <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
> IRQ_TYPE_LEVEL_LOW)>,
> + <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
> IRQ_TYPE_LEVEL_LOW)>;
> + };
> +};
> --
> 2.17.1

2021-06-07 11:04:12

by Lad, Prabhakar

[permalink] [raw]
Subject: Re: [PATCH v2 00/12] Add new Renesas RZ/G2L SoC and Renesas RZ/G2L SMARC EVK support

Hi Geert,

On Thu, Jun 3, 2021 at 11:18 PM Lad Prabhakar
<[email protected]> wrote:
>
> Hi All,
>
> This patch series adds initial support for Renesas RZ/G2L SoC and
> Renesas RZ/G2L SMARC EVK.
>
> Initial patches enables minimal peripherals on Renesas RZ/G2L
> SMARC EVK and booted via initramfs.
> * Documentation for RZ/G2{L,LC,UL} SoC variants
> * SoC identification support
> * CPG core support
> * Minimal SoC DTSi
> * Minimal DTS for SMARC EVK
>
> Changes for v2:
> * Included type-2 RZ/G2Ul SoC in binding doc
> * Added single entry for SMARC EVK "renesas,smarc-evk"
> * Renamed ARCH_R9A07G044L to ARCH_R9A07G044 and
> dropped ARCH_R9A07G044LC config
> * Dropped SoC identification changes will post them as
> separate patch.
> * Updated comment in sh-sci.c
> * Binding documentation patch for serial driver has been
> accepted so dropped the patch from this series
> * Incorporated changes requested by Geert for CPG core
> * Fixed dtbs_check errors
> * Dropped 'clock-names'/'clocks'/'power-domains'/'resets'
> properties from GIC node and will include them in a separate
> patch along with arm,gic-v3.yaml binding updates
> * Included ACK's from Rob
>
> Patches are based on top of [1] master branch.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/
>
> Cheers,
> Prabhakar
>
> Biju Das (1):
> serial: sh-sci: Add support for RZ/G2L SoC
>
> Lad Prabhakar (11):
> dt-bindings: arm: renesas: Document Renesas RZ/G2UL SoC
> dt-bindings: arm: renesas: Document Renesas RZ/G2{L,LC} SoC variants
> dt-bindings: arm: renesas: Document SMARC EVK
> soc: renesas: Add ARCH_R9A07G044 for the new RZ/G2L SoC's
> arm64: defconfig: Enable ARCH_R9A07G044
> clk: renesas: Define RZ/G2L CPG Clock Definitions
> dt-bindings: clock: renesas: Document RZ/G2L SoC CPG driver
> clk: renesas: Add CPG core wrapper for RZ/G2L SoC
> clk: renesas: Add support for R9A07G044 SoC
> arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's
> arm64: dts: renesas: Add initial device tree for RZ/G2L SMARC EVK
>
Biju pointed out USB/ADC isn't working with the current implementation
on upstream kernel, I'll have to re-structure to accommodate this
use-case. I'll send a v3 fixing the issue.

Sorry for the inconvenience.

Cheers,
Prabhakar

> .../devicetree/bindings/arm/renesas.yaml | 18 +
> .../bindings/clock/renesas,rzg2l-cpg.yaml | 80 ++
> arch/arm64/boot/dts/renesas/Makefile | 2 +
> arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 119 +++
> arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 +
> .../boot/dts/renesas/r9a07g044l2-smarc.dts | 21 +
> arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 27 +
> arch/arm64/configs/defconfig | 1 +
> drivers/clk/renesas/Kconfig | 9 +
> drivers/clk/renesas/Makefile | 2 +
> drivers/clk/renesas/r9a07g044-cpg.c | 372 +++++++
> drivers/clk/renesas/renesas-rzg2l-cpg.c | 979 ++++++++++++++++++
> drivers/clk/renesas/renesas-rzg2l-cpg.h | 217 ++++
> drivers/soc/renesas/Kconfig | 5 +
> drivers/tty/serial/sh-sci.c | 12 +-
> drivers/tty/serial/sh-sci.h | 1 +
> include/dt-bindings/clock/r9a07g044-cpg.h | 89 ++
> 17 files changed, 1978 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
> create mode 100644 arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
> create mode 100644 drivers/clk/renesas/r9a07g044-cpg.c
> create mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.c
> create mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.h
> create mode 100644 include/dt-bindings/clock/r9a07g044-cpg.h
>
> --
> 2.17.1
>

2021-06-08 15:12:29

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 07/12] dt-bindings: clock: renesas: Document RZ/G2L SoC CPG driver

Hi Prabhakar,

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Document the device tree bindings of the Renesas RZ/G2L SoC clock
> driver in Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>
> Acked-by: Rob Herring <[email protected]>

IIRC, Rob gave his R-b, not his A-b.

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
> @@ -0,0 +1,80 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/clock/renesas,rzg2l-cpg.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Renesas RZ/G2L Clock Pulse Generator / Module Standby Mode
> +
> +maintainers:
> + - Geert Uytterhoeven <[email protected]>
> +
> +description: |
> + On Renesas RZ/G2L SoC, the CPG (Clock Pulse Generator) and Module
> + Standby Mode share the same register block.
> +
> + They provide the following functionalities:
> + - The CPG block generates various core clocks,
> + - The Module Standby Mode block provides two functions:
> + 1. Module Stop, providing a Clock Domain to control the clock supply
> + to individual SoC devices,
> + 2. Reset Control, to perform a software reset of individual SoC devices.
> +
> +properties:
> + compatible:
> + const: renesas,r9a07g044-cpg # RZ/G2{L,LC,UL}

Shouldn't RZ/G2UL use renesas,r9a07g043-cpg?

> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + clock-names:
> + const: extal
> +
> + '#clock-cells':
> + description: |
> + - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
> + and a core clock reference, as defined in
> + <dt-bindings/clock/r9a07g044l-cpg.h>

r9a07g044-cpg.h

> + - For module clocks, the two clock specifier cells must be "CPG_MOD" and
> + a module number, as defined in the <dt-bindings/clock/r9a07g044l-cpg.h>.

r9a07g044-cpg.h

> + const: 2
> +
> + '#power-domain-cells':
> + description:
> + SoC devices that are part of the CPG/Module Standby Mode Clock Domain and
> + can be power-managed through Module Stop should refer to the CPG device

Module Standby

> + node in their "power-domains" property, as documented by the generic PM
> + Domain bindings in Documentation/devicetree/bindings/power/power-domain.yaml.
> + const: 0
> +
> + '#reset-cells':
> + description:
> + The single reset specifier cell must be the module number, as defined in
> + the <dt-bindings/clock/r9a07g044l-cpg.h>.

r9a07g044-cpg.h

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-08 15:26:08

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 02/12] dt-bindings: arm: renesas: Document Renesas RZ/G2{L,LC} SoC variants

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Add device tree bindings documentation for Renesas RZ/G2{L,LC}
> SoC variants.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>
> Reviewed-by: Chris Paterson <[email protected]>
> Acked-by: Rob Herring <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-08 15:28:05

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 04/12] soc: renesas: Add ARCH_R9A07G044 for the new RZ/G2L SoC's

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Add ARCH_R9A07G044 as a configuration symbol for the new Renesas
> RZ/G2L SoC variants.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-08 15:28:25

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 05/12] arm64: defconfig: Enable ARCH_R9A07G044

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Enable the Renesas RZ/G2L SoC variants in the ARM64 defconfig.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-08 15:28:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 06/12] clk: renesas: Define RZ/G2L CPG Clock Definitions

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Define RZ/G2L (R9A07G044) Clock Pulse Generator Core Clock
> and module clock outputs, as listed in Table 8.3 ("Clock List")
> of the RZ/G2L Hardware User's Manual (Rev.0.42, Feb.2021).
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>

LGTM.

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 03:56:36

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 10/12] serial: sh-sci: Add support for RZ/G2L SoC

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> From: Biju Das <[email protected]>
>
> Add serial support for RZ/G2L SoC with earlycon and
> extended mode register support.
>
> Signed-off-by: Biju Das <[email protected]>
> Signed-off-by: Lad Prabhakar <[email protected]>

FTR,
Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 04:15:07

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 01/12] dt-bindings: arm: renesas: Document Renesas RZ/G2UL SoC

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Add device tree bindings documentation for Renesas RZ/G2UL SoC.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>
> Reviewed-by: Chris Paterson <[email protected]>
> Acked-by: Rob Herring <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 04:17:43

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 03/12] dt-bindings: arm: renesas: Document SMARC EVK

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Document Renesas SMARC EVK board which are based on RZ/G2L (R9A07G044)
> SoC. The SMARC EVK consists of RZ/G2L SoM module and SMARC carrier board,
> the SoM module sits on top of carrier board.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Biju Das <[email protected]>
> Reviewed-by: Chris Paterson <[email protected]>
> Acked-by: Rob Herring <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 13:20:57

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's

Hi Prabhakar,

On Fri, Jun 4, 2021 at 12:18 AM Lad Prabhakar
<[email protected]> wrote:
> Add initial DTSI for RZ/G2{L,LC} SoC's.
>
> File structure:
> r9a07g044.dtsi => RZ/G2L family SoC common parts
> r9a07g044l1.dtsi => Specific to RZ/G2L (R9A07G044L single cortex A55) SoC
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Signed-off-by: Biju Das <[email protected]>

Thanks for your patch!

> ---
> arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 119 +++++++++++++++++++
> arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 ++++
> 2 files changed, 144 insertions(+)
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044.dtsi
> create mode 100644 arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi

Don't you still want an r9a07g044l2.dtsi, for symmetry, and to add the
"renesas,r9a07g044l2" root compatible value?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 13:25:38

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's

Hi Biju,

On Fri, Jun 4, 2021 at 3:55 PM Biju Das <[email protected]> wrote:
> > Subject: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for
> > RZ/G2{L,LC} SoC's
> >
> > Add initial DTSI for RZ/G2{L,LC} SoC's.
> >
> > File structure:
> > r9a07g044.dtsi => RZ/G2L family SoC common parts r9a07g044l1.dtsi =>
> > Specific to RZ/G2L (R9A07G044L single cortex A55) SoC
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > Signed-off-by: Biju Das <[email protected]>

> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi

> > + cpg: clock-controller@11010000 {
> > + compatible = "renesas,r9a07g044-cpg";
> > + reg = <0 0x11010000 0 0x10000>;
>
> What about WDTOVF_RST(0xB10) and WDTRST_SEL(0xB14) registers, this registers to be handled by WDT driver.
> Unfortunately it is in CPG block.
>
> So do we need to map the entire CPG registers or up to 0xB00?
>
> Geert, Prabhakar: Any thoughts?

As the registers are part of the CPG block, I think they should be
covered by the CPG node. You can handle them in the CPG driver, through
functions called from the WDT driver (cfr. rcar_rst_read_mode_pins()).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 17:10:19

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v2 12/12] arm64: dts: renesas: Add initial device tree for RZ/G2L SMARC EVK

Hi Prabhakar,

On Fri, Jun 4, 2021 at 12:19 AM Lad Prabhakar
<[email protected]> wrote:
> Add basic support for RZ/G2L SMARC EVK (based on R9A07G044L2):
> - memory
> - External input clock
> - SCIF
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Signed-off-by: Biju Das <[email protected]>

Thanks for your patch!

> --- /dev/null
> +++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Device Tree Source for the RZ/G2L SMARC EVK board
> + *
> + * Copyright (C) 2021 Renesas Electronics Corp.
> + */
> +
> +/dts-v1/;
> +#include "r9a07g044.dtsi"

So this should include r9a07g044l2.dtsi.

The rest looks fine, so
Reviewed-by: Geert Uytterhoeven <[email protected]>

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2021-06-09 17:10:51

by Biju Das

[permalink] [raw]
Subject: RE: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's

Hi Geert,

Thanks for the feedback.

> Subject: Re: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for
> RZ/G2{L,LC} SoC's
>
> Hi Biju,
>
> On Fri, Jun 4, 2021 at 3:55 PM Biju Das <[email protected]>
> wrote:
> > > Subject: [PATCH v2 11/12] arm64: dts: renesas: Add initial DTSI for
> > > RZ/G2{L,LC} SoC's
> > >
> > > Add initial DTSI for RZ/G2{L,LC} SoC's.
> > >
> > > File structure:
> > > r9a07g044.dtsi => RZ/G2L family SoC common parts r9a07g044l1.dtsi
> > > => Specific to RZ/G2L (R9A07G044L single cortex A55) SoC
> > >
> > > Signed-off-by: Lad Prabhakar
> > > <[email protected]>
> > > Signed-off-by: Biju Das <[email protected]>
>
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
>
> > > + cpg: clock-controller@11010000 {
> > > + compatible = "renesas,r9a07g044-cpg";
> > > + reg = <0 0x11010000 0 0x10000>;
> >
> > What about WDTOVF_RST(0xB10) and WDTRST_SEL(0xB14) registers, this
> registers to be handled by WDT driver.
> > Unfortunately it is in CPG block.
> >
> > So do we need to map the entire CPG registers or up to 0xB00?
> >
> > Geert, Prabhakar: Any thoughts?
>
> As the registers are part of the CPG block, I think they should be covered
> by the CPG node. You can handle them in the CPG driver, through functions
> called from the WDT driver (cfr. rcar_rst_read_mode_pins()).

Got it. Similar case for WDTCTRL register to stop watchdog. This register is in SYSC block. So
we need to handle this register in SYSC driver.

Cheers,
Biju


>
> 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

2021-06-09 17:13:08

by Lad, Prabhakar

[permalink] [raw]
Subject: Re: [PATCH v2 12/12] arm64: dts: renesas: Add initial device tree for RZ/G2L SMARC EVK

Hi Geert,

Thank you for the review.

On Wed, Jun 9, 2021 at 8:18 AM Geert Uytterhoeven <[email protected]> wrote:
>
> Hi Prabhakar,
>
> On Fri, Jun 4, 2021 at 12:19 AM Lad Prabhakar
> <[email protected]> wrote:
> > Add basic support for RZ/G2L SMARC EVK (based on R9A07G044L2):
> > - memory
> > - External input clock
> > - SCIF
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > Signed-off-by: Biju Das <[email protected]>
>
> Thanks for your patch!
>
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
> > @@ -0,0 +1,21 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +/*
> > + * Device Tree Source for the RZ/G2L SMARC EVK board
> > + *
> > + * Copyright (C) 2021 Renesas Electronics Corp.
> > + */
> > +
> > +/dts-v1/;
> > +#include "r9a07g044.dtsi"
>
> So this should include r9a07g044l2.dtsi.
>
Good point I'll create an empty r9a07g044l2.dtsi file including
"r9a07g044.dtsi '' along with the compatible value and include it
here.

Cheers,
Prabhakar

> The rest looks fine, so
> Reviewed-by: Geert Uytterhoeven <[email protected]>
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
>
> 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