2021-06-09 16:24:34

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 00/11] 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 v3:
* Updated tag from Rob for CPG binding doc
* Included RB tags from Geert
* Added description for clock-names property in CPG binding doc
* Dropped serial driver patch (already merged)
* Fixed CPG core issues for USB/ADC IP
* Added r9a07g044l2.dtsi

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

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 | 83 ++
arch/arm64/boot/dts/renesas/Makefile | 2 +
arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 120 +++
arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 +
.../boot/dts/renesas/r9a07g044l2-smarc.dts | 21 +
arch/arm64/boot/dts/renesas/r9a07g044l2.dtsi | 13 +
arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 27 +
arch/arm64/configs/defconfig | 1 +
drivers/clk/renesas/Kconfig | 10 +
drivers/clk/renesas/Makefile | 2 +
drivers/clk/renesas/r9a07g044-cpg.c | 127 +++
drivers/clk/renesas/renesas-rzg2l-cpg.c | 750 ++++++++++++++++++
drivers/clk/renesas/renesas-rzg2l-cpg.h | 136 ++++
drivers/soc/renesas/Kconfig | 5 +
include/dt-bindings/clock/r9a07g044-cpg.h | 89 +++
16 files changed, 1429 insertions(+)
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/r9a07g044l2.dtsi
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-09 16:24:43

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 01/11] 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]>
Reviewed-by: Geert Uytterhoeven <[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-09 16:25:57

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 06/11] 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-09 16:26:26

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 08/11] 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 | 5 +
drivers/clk/renesas/Makefile | 1 +
drivers/clk/renesas/renesas-rzg2l-cpg.c | 744 ++++++++++++++++++++++++
drivers/clk/renesas/renesas-rzg2l-cpg.h | 134 +++++
4 files changed, 884 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..a067428cb7af 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -182,6 +182,11 @@ 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
+ select RESET_CONTROLLER
+
# 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..9e860d55c916
--- /dev/null
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c
@@ -0,0 +1,744 @@
+// 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_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 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_REG_OFFSET(val) ((val >> 20) & 0xfff)
+#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)
+#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)
+
+/**
+ * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
+ *
+ * @rcdev: Reset controller entity
+ * @dev: CPG device
+ * @base: CPG register block base address
+ * @rmw_lock: protects 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 {
+ struct reset_controller_dev rcdev;
+ 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_OFFSET(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_OFFSET(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 pll_clk {
+ struct clk_hw hw;
+ 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;
+ unsigned int mult = 1;
+ unsigned int div = 1;
+
+ if (pll_clk->type != CLK_TYPE_SAM_PLL)
+ return parent_rate;
+
+ val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
+ val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
+ mult = MDIV(val1) + KDIV(val1) / 65536;
+ div = PDIV(val1) * (1 << SDIV(val2));
+
+ 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->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:
+ 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;
+ 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);
+}
+
+#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);
+}
+
+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..8ff0047ffeb9
--- /dev/null
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.h
@@ -0,0 +1,134 @@
+/* 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__
+
+#define CPG_PL2_DDIV (0x204)
+#define CPG_PL3A_DDIV (0x208)
+
+/* n = 0/1/2 for PLL1/4/6 */
+#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
+#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n))
+
+#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12)
+
+#define DDIV_PACK(offset, bitpos, size) \
+ (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
+#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3)
+#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3)
+
+/**
+ * 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;
+ const char * const *parent_names;
+ int flag;
+ int num_parents;
+};
+
+enum clk_types {
+ /* Generic */
+ CLK_TYPE_IN, /* External Clock Input */
+ CLK_TYPE_FF, /* Fixed Factor Clock */
+ CLK_TYPE_SAM_PLL,
+
+ /* Clock with divider */
+ CLK_TYPE_DIV,
+};
+
+#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_SAMPLL(_name, _id, _parent, _conf) \
+ DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _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)
+
+/**
+ * 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-09 16:26:59

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 11/11] 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]>
Reviewed-by: Geert Uytterhoeven <[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..d3f72ec62f03
--- /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 "r9a07g044l2.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-09 16:27:00

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 10/11] 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 => RZ/G2L R9A07G044L1 SoC specific parts
r9a07g044l2.dtsi => RZ/G2L R9A07G044L2 SoC specific parts

Signed-off-by: Lad Prabhakar <[email protected]>
Signed-off-by: Biju Das <[email protected]>
---
arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 120 +++++++++++++++++++
arch/arm64/boot/dts/renesas/r9a07g044l1.dtsi | 25 ++++
arch/arm64/boot/dts/renesas/r9a07g044l2.dtsi | 13 ++
3 files changed, 158 insertions(+)
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.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..6a103a62eccb
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
@@ -0,0 +1,120 @@
+// 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>;
+
+ /* clock can be either from exclk or crystal oscillator (XIN/XOUT) */
+ 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..9d89d4590358
--- /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 SoC specific 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)>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l2.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044l2.dtsi
new file mode 100644
index 000000000000..91dc10b2cdbb
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044l2.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2L R9A07G044L2 SoC specific parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g044.dtsi"
+
+/ {
+ compatible = "renesas,r9a07g044l2", "renesas,r9a07g044";
+};
--
2.17.1

2021-06-09 16:29:44

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 09/11] 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 | 127 ++++++++++++++++++++++++
drivers/clk/renesas/renesas-rzg2l-cpg.c | 6 ++
drivers/clk/renesas/renesas-rzg2l-cpg.h | 2 +
5 files changed, 141 insertions(+)
create mode 100644 drivers/clk/renesas/r9a07g044-cpg.c

diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index a067428cb7af..916c7d227e25 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..50b5269586a4
--- /dev/null
+++ b/drivers/clk/renesas/r9a07g044-cpg.c
@@ -0,0 +1,127 @@
+// 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_EXTAL,
+
+ /* Internal Core Clocks */
+ CLK_OSC_DIV1000,
+ CLK_PLL1,
+ CLK_PLL2,
+ CLK_PLL2_DIV2,
+ CLK_PLL2_DIV16,
+ CLK_PLL2_DIV20,
+ CLK_PLL3,
+ CLK_PLL3_DIV2,
+ CLK_PLL3_DIV4,
+ CLK_PLL3_DIV8,
+ CLK_PLL4,
+ CLK_PLL5,
+ CLK_PLL5_DIV2,
+ CLK_PLL6,
+
+ /* Module Clocks */
+ MOD_CLK_BASE,
+};
+
+/* Divider tables */
+static const struct clk_div_table dtable_3b[] = {
+ {0, 1},
+ {1, 2},
+ {2, 4},
+ {3, 8},
+ {4, 32},
+};
+
+static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+
+ /* Internal Core Clocks */
+ DEF_FIXED(".osc", R9A07G044_OSCCLK, CLK_EXTAL, 1, 1),
+ DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
+ DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)),
+ DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2),
+ DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2),
+
+ DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
+ DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16),
+ DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
+
+ DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
+ DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4),
+ DEF_FIXED(".pll3_div8", CLK_PLL3_DIV8, CLK_PLL3, 1, 8),
+
+ /* Core output clk */
+ DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
+ DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
+ dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1),
+ DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV8,
+ DIVPL3B, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+};
+
+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("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)),
+};
+
+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 9e860d55c916..ef308cb2368f 100644
--- a/drivers/clk/renesas/renesas-rzg2l-cpg.c
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c
@@ -723,6 +723,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 8ff0047ffeb9..3948bdd8afc9 100644
--- a/drivers/clk/renesas/renesas-rzg2l-cpg.h
+++ b/drivers/clk/renesas/renesas-rzg2l-cpg.h
@@ -131,4 +131,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-09 18:05:52

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 02/11] 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]>
Reviewed-by: Geert Uytterhoeven <[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-09 18:05:53

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 04/11] 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]>
Reviewed-by: Geert Uytterhoeven <[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-09 18:05:53

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 03/11] 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]>
Reviewed-by: Geert Uytterhoeven <[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-09 18:47:21

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 05/11] 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]>
Reviewed-by: Geert Uytterhoeven <[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-09 18:47:30

by Prabhakar Mahadev Lad

[permalink] [raw]
Subject: [PATCH v3 07/11] 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]>
Reviewed-by: Rob Herring <[email protected]>
---
.../bindings/clock/renesas,rzg2l-cpg.yaml | 83 +++++++++++++++++++
1 file changed, 83 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..30b2e3d0d25d
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml
@@ -0,0 +1,83 @@
+# 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 Standby, 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}
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ description:
+ Clock source to CPG can be either from external clock input (EXCLK) or
+ crystal oscillator (XIN/XOUT).
+ 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/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/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 Standby 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/r9a07g044-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-10 12:33:05

by Geert Uytterhoeven

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

On Wed, Jun 9, 2021 at 5:33 PM 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]>

Reviewed-by: Geert Uytterhoeven <[email protected]>
i.e. will queue in renesas-clk-for-v5.14.

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-10 12:33:37

by Geert Uytterhoeven

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

On Thu, Jun 10, 2021 at 2:30 PM Geert Uytterhoeven <[email protected]> wrote:
> On Wed, Jun 9, 2021 at 5:33 PM 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]>
> > Reviewed-by: Rob Herring <[email protected]>
>
> Reviewed-by: Geert Uytterhoeven <[email protected]>
> i.e. will queue in renesas-devel for v5.14.

renesas-clk-for-v5.14, of course

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-10 12:34:36

by Geert Uytterhoeven

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

On Wed, Jun 9, 2021 at 5:33 PM 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]>
> Reviewed-by: Rob Herring <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>
i.e. will queue in renesas-devel for v5.14.

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-10 12:36:21

by Geert Uytterhoeven

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

On Wed, Jun 9, 2021 at 5:33 PM 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 => RZ/G2L R9A07G044L1 SoC specific parts
> r9a07g044l2.dtsi => RZ/G2L R9A07G044L2 SoC specific parts
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Signed-off-by: Biju Das <[email protected]>

Reviewed-by: Geert Uytterhoeven <[email protected]>
i.e. will queue in renesas-devel for v5.14.

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-10 13:05:56

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v3 08/11] clk: renesas: Add CPG core wrapper for RZ/G2L SoC

Hi Prabhakar,

On Wed, Jun 9, 2021 at 5:33 PM Lad Prabhakar
<[email protected]> wrote:
> 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]>

Thanks for your patch!

> --- a/drivers/clk/renesas/Kconfig
> +++ b/drivers/clk/renesas/Kconfig
> @@ -182,6 +182,11 @@ 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

s/SoC/family/?

I think "if COMPILE_TEST", as all other entries are using, is sufficient.

> + depends on ARCH_RENESAS || COMPILE_TEST

I think this can be dropped.

> + select RESET_CONTROLLER
> +
> # Generic

> --- /dev/null
> +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c

> +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) {

The range of module clocks in DT specifiers starts at zero, so

if (clkidx > 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;
> +}

With the above fixed:
Reviewed-by: Geert Uytterhoeven <[email protected]>

I can fix these while applying.

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-10 13:08:05

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] clk: renesas: Add support for R9A07G044 SoC

On Wed, Jun 9, 2021 at 5:33 PM Lad Prabhakar
<[email protected]> wrote:
> 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]>

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-10 14:10:49

by Lad, Prabhakar

[permalink] [raw]
Subject: Re: [PATCH v3 08/11] clk: renesas: Add CPG core wrapper for RZ/G2L SoC

Hi Geert,

Thank you for the review.

On Thu, Jun 10, 2021 at 2:04 PM Geert Uytterhoeven <[email protected]> wrote:
>
> Hi Prabhakar,
>
> On Wed, Jun 9, 2021 at 5:33 PM Lad Prabhakar
> <[email protected]> wrote:
> > 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]>
>
> Thanks for your patch!
>
> > --- a/drivers/clk/renesas/Kconfig
> > +++ b/drivers/clk/renesas/Kconfig
> > @@ -182,6 +182,11 @@ 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
>
> s/SoC/family/?
>
Agreed.

> I think "if COMPILE_TEST", as all other entries are using, is sufficient.
>
> > + depends on ARCH_RENESAS || COMPILE_TEST
>
> I think this can be dropped.
>
Agreed.

> > + select RESET_CONTROLLER
> > +
> > # Generic
>
> > --- /dev/null
> > +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c
>
> > +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) {
>
> The range of module clocks in DT specifiers starts at zero, so
>
> if (clkidx > priv->num_mod_clks) {
>
Thanks for the catch, yes the above check should be good.

>
> > + 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;
> > +}
>
> With the above fixed:
> Reviewed-by: Geert Uytterhoeven <[email protected]>
>
> I can fix these while applying.
>
Thank you.

Cheers,
Prabhakar