[PATCH 07/16] clk: renesas: Add RZ/G2L CPG driver

Paul Barker paul.barker.ct at bp.renesas.com
Wed Oct 4 10:15:43 CEST 2023


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 at bp.renesas.com>
>> Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
>> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x27F4B3459F002257.asc
Type: application/pgp-keys
Size: 3520 bytes
Desc: OpenPGP public key
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20231004/f595bd97/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 236 bytes
Desc: OpenPGP digital signature
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20231004/f595bd97/attachment.sig>


More information about the U-Boot mailing list