From 88656a46dfa3ecd0c878a0dc6916a1f399818334 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 5 Aug 2026 17:20:49 +0200 Subject: [PATCH 1/2] dt-bindings: clock: Document Renesas R-Car X5H Clock Pulse Generator Document support for the Renesas R-Car X5H Clock Pulse Generator, and add binding definitions for a limited initial set of clocks. Signed-off-by: Geert Uytterhoeven Reviewed-by: Marek Vasut Tested-by: Marek Vasut Acked-by: Conor Dooley Link: https://patch.msgid.link/7a33c99816c850faeec5c17532811faf78959a1d.1785941595.git.geert+renesas@glider.be --- .../bindings/clock/renesas,r8a78000-cpg.yaml | 55 +++++++++++++++++++ .../dt-bindings/clock/renesas,r8a78000-cpg.h | 14 +++++ 2 files changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml create mode 100644 include/dt-bindings/clock/renesas,r8a78000-cpg.h diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml b/Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml new file mode 100644 index 000000000000..4e23bba33438 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,r8a78000-cpg.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/renesas,r8a78000-cpg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R-Car X5H Clock Pulse Generator + +maintainers: + - Geert Uytterhoeven + +description: + The R-Car X5H Clock Pulse Generator (CLK CONTROL) consists of oscillators, + PLL circuits, clock dividers and clock control circuits. It provides various + clocks for other modules. + +properties: + compatible: + const: renesas,r8a78000-cpg + + reg: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: extal + - const: extalr + + '#clock-cells': + description: + The single clock specifier cell must be the clock number, as defined in + . + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + clock-controller@c1320000 { + compatible = "renesas,r8a78000-cpg"; + reg = <0xc1320000 0x10000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <1>; + }; diff --git a/include/dt-bindings/clock/renesas,r8a78000-cpg.h b/include/dt-bindings/clock/renesas,r8a78000-cpg.h new file mode 100644 index 000000000000..7fd09a3fb353 --- /dev/null +++ b/include/dt-bindings/clock/renesas,r8a78000-cpg.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Glider bv + */ +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ +#define __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ + +/* R-Car X5H Clock Pulse Generator Clocks */ + +#define R8A78000_CPG_SGASYNCD4_PERW_BUS 0 +#define R8A78000_CPG_SGASYNCD8_PERW_BUS 1 +#define R8A78000_CPG_SGASYNCD16_PERW_BUS 2 + +#endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ */ From 0fb9083a6e56f688aeeccfc7ef7eeba586e57dc6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 5 Aug 2026 17:20:51 +0200 Subject: [PATCH 2/2] clk: renesas: Add R-Car X5H CPG driver Add a minimal Clock Pulse Generator driver for the R-Car X5H (R8A78000) SoC. For now this supports just the few fixed-rate clocks that are needed by the current minimal DTS. Signed-off-by: Geert Uytterhoeven Reviewed-by: Marek Vasut Link: https://patch.msgid.link/3f981753722de1ba871667be63460e89d299d635.1785941595.git.geert+renesas@glider.be --- drivers/clk/renesas/Kconfig | 4 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a78000-cpg.c | 166 +++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 drivers/clk/renesas/r8a78000-cpg.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 5c0238e878b7..17b95a2e96fb 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -34,6 +34,7 @@ config CLK_RENESAS select CLK_R8A779F0 if ARCH_R8A779F0 select CLK_R8A779G0 if ARCH_R8A779G0 select CLK_R8A779H0 if ARCH_R8A779H0 + select CLK_R8A78000 if ARCH_R8A78000 select CLK_R9A06G032 if ARCH_R9A06G032 select CLK_R9A07G043 if ARCH_R9A07G043 select CLK_R9A07G044 if ARCH_R9A07G044 @@ -176,6 +177,9 @@ config CLK_R8A779H0 bool "R-Car V4M clock support" if COMPILE_TEST select CLK_RCAR_GEN4_CPG +config CLK_R8A78000 + bool "R-Car X5H clock support" if COMPILE_TEST + config CLK_R9A06G032 bool "RZ/N1D clock support" if COMPILE_TEST diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index ac790e56034b..658f8aac5127 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779F0) += r8a779f0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779G0) += r8a779g0-cpg-mssr.o obj-$(CONFIG_CLK_R8A779H0) += r8a779h0-cpg-mssr.o +obj-$(CONFIG_CLK_R8A78000) += r8a78000-cpg.o obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o diff --git a/drivers/clk/renesas/r8a78000-cpg.c b/drivers/clk/renesas/r8a78000-cpg.c new file mode 100644 index 000000000000..7946f9d0b423 --- /dev/null +++ b/drivers/clk/renesas/r8a78000-cpg.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car X5H Clock Pulse Generator + * + * Copyright (C) 2026 Glider bv + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct clk_map { + int dt_id; /* DT binding clock ID or -1 sentinel */ + u32 fw_id; /* FIXED_CLK() ID */ +}; + +enum fixed_clk { + FIXED_CLK_66M, + FIXED_CLK_266M, + NUM_FIXED_CLKS +}; + +static const unsigned long fixed_clk_rates[NUM_FIXED_CLKS] = { + [FIXED_CLK_66M] = 66666000, + [FIXED_CLK_266M] = 266660000, +}; + +#define FIXED_CLK(rate) FIXED_CLK_ ## rate + +/** + * struct r8a78000_cpg_priv - Clock Pulse Generator Private Data + * + * @dev: CPG device + * @map: Mapping from DT clock IDs to fixed-rate clocks + * @fixed_hws: Fixed rate clocks + */ +struct r8a78000_cpg_priv { + struct device *dev; + const struct clk_map *map; + struct clk_hw *fixed_hws[NUM_FIXED_CLKS]; +}; + +static const struct clk_map *clk_map_find(const struct clk_map *map, u32 id) +{ + if (!map) + return NULL; + + for (; map->dt_id >= 0; map++) { + if (map->dt_id == id) + return map; + } + + return NULL; +} + +static struct clk_hw *r8a78000_clk_get(struct of_phandle_args *spec, + void *data) +{ + struct r8a78000_cpg_priv *priv = data; + struct device *dev = priv->dev; + const struct clk_map *map; + struct clk_hw *hw; + u32 id; + + if (spec->args_count != 1) + return ERR_PTR(-EINVAL); + + id = spec->args[0]; + + map = clk_map_find(priv->map, id); + if (!map) { + dev_err(dev, "Unknown clock %u\n", id); + return ERR_PTR(-ENOENT); + } + + dev_dbg(dev, "Mapping DT clock %u to fixed clock %u\n", id, map->fw_id); + + hw = priv->fixed_hws[map->fw_id]; + + dev_dbg(dev, "clock %u is %s at %lu Hz\n", id, clk_hw_get_name(hw), + clk_hw_get_rate(hw)); + + return hw; +} + +static int register_fixed_clks(struct r8a78000_cpg_priv *priv) +{ + struct device *dev = priv->dev; + unsigned long rate; + struct clk_hw *hw; + const char *name; + + for (unsigned int i = 0; i < ARRAY_SIZE(fixed_clk_rates); i++) { + rate = fixed_clk_rates[i]; + name = devm_kasprintf(dev, GFP_KERNEL, "cpg-%lu", rate); + if (!name) + return -ENOMEM; + + hw = devm_clk_hw_register_fixed_rate(dev, name, NULL, 0, rate); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + priv->fixed_hws[i] = hw; + } + + return 0; +} + +static int r8a78000_cpg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct r8a78000_cpg_priv *priv; + const struct clk_map *map; + int ret; + + map = of_device_get_match_data(dev); + if (!map) + return -ENODEV; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->map = map; + + ret = register_fixed_clks(priv); + if (ret) + return ret; + + return devm_of_clk_add_hw_provider(dev, r8a78000_clk_get, priv); +} + +static const struct clk_map r8a78000_cpg_default[] = { + { R8A78000_CPG_SGASYNCD4_PERW_BUS, FIXED_CLK(266M) }, + { R8A78000_CPG_SGASYNCD16_PERW_BUS, FIXED_CLK(66M) }, + { -1 } +}; + +static const struct of_device_id r8a78000_cpg_match[] = { + { + .compatible = "renesas,r8a78000-cpg", + .data = &r8a78000_cpg_default, + }, + { /* sentinel */ } +}; + +static struct platform_driver r8a78000_cpg_driver = { + .probe = r8a78000_cpg_probe, + .driver = { + .name = "r8a78000-cpg", + .of_match_table = r8a78000_cpg_match, + .suppress_bind_attrs = true, + }, +}; + +builtin_platform_driver(r8a78000_cpg_driver) + +MODULE_DESCRIPTION("R-Car X5H CPG Driver");