
On 03/10/2023 13:56, Marek Vasut wrote:
On 9/20/23 14:42, Paul Barker wrote:
This driver provides clock and reset control for the Renesas RZ/G2L (R9A07G044) SoC. It consists of two parts:
driver code which is applicable to all SoCs in the RZ/G2L family
static data describing the clocks and resets which are specific to the R9A07G044 SoC.
clk_set_rate() and clk_get_rate() are implemented only for the clocks that are actually used in u-boot.
The CPG driver is marked with DM_FLAG_PRE_RELOC to ensure that its bind function is called before the SCIF (serial port) driver is probed. This is required so that we can de-assert the relevant reset signal during the serial driver probe function.
This patch is based on the corresponding Linux v6.5 driver.
Same thing as 02/16..04/16 applies here.
Signed-off-by: Paul Barker paul.barker.ct@bp.renesas.com Reviewed-by: Biju Das biju.das.jz@bp.renesas.com Reviewed-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
arch/arm/mach-rmobile/Kconfig | 1 + arch/arm/mach-rmobile/Kconfig.rzg2l | 1 + drivers/clk/renesas/Kconfig | 9 + drivers/clk/renesas/Makefile | 2 + drivers/clk/renesas/r9a07g044-cpg.c | 384 +++++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.c | 502 ++++++++++++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.h | 318 ++++++++++++++++++ 7 files changed, 1217 insertions(+) create mode 100644 drivers/clk/renesas/r9a07g044-cpg.c create mode 100644 drivers/clk/renesas/rzg2l-cpg.c create mode 100644 drivers/clk/renesas/rzg2l-cpg.h
diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig index fd240832d83d..fc37f6c79e50 100644 --- a/arch/arm/mach-rmobile/Kconfig +++ b/arch/arm/mach-rmobile/Kconfig @@ -74,6 +74,7 @@ config RZG2L imply MULTI_DTB_FIT_USER_DEFINED_AREA imply SYS_MALLOC_F imply RENESAS_SDHI
- imply CLK_RZG2L
Keep the list sorted
help Enable support for the Renesas RZ/G2L family of SoCs, including the the RZ/G2L itself (based on the R9A07G044 SoC). diff --git a/arch/arm/mach-rmobile/Kconfig.rzg2l b/arch/arm/mach-rmobile/Kconfig.rzg2l index 266f82c18085..7d268e8c366a 100644 --- a/arch/arm/mach-rmobile/Kconfig.rzg2l +++ b/arch/arm/mach-rmobile/Kconfig.rzg2l @@ -5,6 +5,7 @@ if RZG2L
config R9A07G044L bool "Renesas R9A07G044L SoC"
- imply CLK_R9A07G044
Why not CLK_R9A07G044L (with L at the end) ?
The driver will also support the RZ/G2LC (R9A07G044C) when support for that SoC is added in a later patch series.
help Enable support for the R9A07G044L SoC used in the RZ/G2L.
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 437a82cd48be..927d62cf99a3 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -156,3 +156,12 @@ config CLK_R9A06G032 depends on CLK_RENESAS help Enable this to support the clocks on Renesas R9A06G032 SoC.
+config CLK_RZG2L
- bool "Renesas RZ/G2L family clock support"
- depends on CLK_RENESAS
- select DM_RESET
+config CLK_R9A07G044
- bool "RZ/G2L (R9A07G044L) clock support"
- depends on CLK_RZG2L
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 48373e61b901..df7e225e9ca4 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -23,3 +23,5 @@ 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_R9A06G032) += r9a06g032-clocks.o +obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o +obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c new file mode 100644 index 000000000000..e215db7caf15 --- /dev/null +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- RZ/G2L CPG driver
- Copyright (C) 2021-2023 Renesas Electronics Corp.
- */
+#include <common.h> +#include <dm/device.h> +#include <dt-bindings/clock/r9a07g044-cpg.h> +#include <linux/clk-provider.h>
+#include "rzg2l-cpg.h"
+/* Divider tables */ +static const struct clk_div_table dtable_1_8[] = {
- {0, 1},
- {1, 2},
- {2, 4},
- {3, 8},
- {0, 0},
+};
+static const struct clk_div_table dtable_1_32[] = {
- {0, 1},
- {1, 2},
- {2, 4},
- {3, 8},
- {4, 32},
- {0, 0},
+};
+static const struct clk_div_table dtable_16_128[] = {
- {0, 16},
- {1, 32},
- {2, 64},
- {3, 128},
- {0, 0},
+};
+/* Mux clock tables */ +static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" }; +static const char * const sel_pll5_4[] = { ".pll5_foutpostdiv", ".pll5_fout1ph0" }; +static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
Is this mixed tabs and spaces here ?
(please fix this in Linux too)
I've tried to minimize changes between the u-boot and Linux drivers, so this mixed tabs/spaces issue, parenthesis around numbers in defines, etc, is an exact copy of what was accepted into the mainline kernel. The hope is that we can more easily port fixes from Linux to u-boot if the code remains as similar as possible.
+static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" }; +static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
[...]
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
[...]
+static int rzg2l_cpg_clk_set(struct clk *clk, bool enable) +{
- struct rzg2l_cpg_data *data =
(struct rzg2l_cpg_data *)dev_get_driver_data(clk->dev);
- unsigned int cpg_clk_id = CPG_CLK_ID(clk->id);
- const struct rzg2l_mod_clk *mod_clk = NULL;
- u32 value;
- unsigned int i;
- dev_dbg(clk->dev, "%s %s clock %u\n", enable ? "enable" : "disable",
is_mod_clk(clk->id) ? "module" : "core", cpg_clk_id);
- if (!is_mod_clk(clk->id)) {
dev_err(clk->dev, "ID %lu is not a module clock\n", clk->id);
return -EINVAL;
- }
- for (i = 0; i < data->info->num_mod_clks; i++) {
if (data->info->mod_clks[i].id == cpg_clk_id) {
mod_clk = &data->info->mod_clks[i];
break;
}
- }
- if (!mod_clk) {
dev_err(clk->dev, "Module clock %u not found\n", cpg_clk_id);
return -ENODEV;
- }
- value = (BIT(mod_clk->bit) << 16);
Parenthesis not needed around this statement.
This one is my mistake - I forgot to remove the brackets when I simplified this expression. Will fix in v2.
- if (enable)
value |= BIT(mod_clk->bit);
- writel(value, data->base + mod_clk->off);
- if (enable && readl_poll_timeout(data->base + CLK_MON_R(mod_clk->off),
value, (value & BIT(mod_clk->bit)),
10)) {
dev_err(clk->dev, "Timeout\n");
return -ETIMEDOUT;
- }
- return 0;
+}
+static int rzg2l_cpg_clk_enable(struct clk *clk) +{
- return rzg2l_cpg_clk_set(clk, true);
+}
+static int rzg2l_cpg_clk_disable(struct clk *clk) +{
- return rzg2l_cpg_clk_set(clk, false);
+}
+static int rzg2l_cpg_clk_of_xlate(struct clk *clk,
struct ofnode_phandle_args *args)
+{
- struct rzg2l_cpg_data *data =
(struct rzg2l_cpg_data *)dev_get_driver_data(clk->dev);
- u32 cpg_clk_type, cpg_clk_id;
- bool found = false;
- unsigned int i;
- if (args->args_count != 2) {
dev_dbg(clk->dev, "Invalid args_count: %d\n", args->args_count);
return -EINVAL;
- }
- cpg_clk_type = args->args[0];
- cpg_clk_id = args->args[1];
- switch (cpg_clk_type) {
- case CPG_CORE:
Is this copied from RCAR clock driver ?
Can this be deduplicated someohw ?
This isn't copied from the RCAR driver. In Linux the RZ/G2L family CPG drivers are separate to the RCAR clock drivers as there are too many differences to easily combine them.
Thanks, Paul