Message ID | 20230929053915.1530607-1-claudiu.beznea@bp.renesas.com |
---|---|
Headers | show |
Series | Add new Renesas RZ/G3S SoC and RZ/G3S SMARC EVK | expand |
On Fri, Sep 29, 2023 at 08:39:06AM +0300, Claudiu wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Set additionalProperties: false. > > Suggested-by: Rob Herring <robh@kernel.org> I did? > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - this patch is new in v2 and added as suggested by Rob > > .../devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml > index 4782f96feb7e..eb726770f571 100644 > --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml > +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml > @@ -106,8 +106,7 @@ additionalProperties: > line-name: true > > - type: object > - additionalProperties: > - $ref: "#/additionalProperties/anyOf/0" > + additionalProperties: false With no properties defined, this only allows an empty node which is probably not what you want. It's the other anyOf entry that needed it, but I already sent a fix which Linus applied. Rob
On 02.10.2023 17:50, Rob Herring wrote: > On Fri, Sep 29, 2023 at 08:39:06AM +0300, Claudiu wrote: >> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> >> Set additionalProperties: false. >> >> Suggested-by: Rob Herring <robh@kernel.org> > > I did? It is what I've understood from this: https://patchwork.kernel.org/project/linux-renesas-soc/patch/20230912045157.177966-30-claudiu.beznea.uj@bp.renesas.com/ > >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> --- >> >> Changes in v2: >> - this patch is new in v2 and added as suggested by Rob >> >> .../devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 3 +-- >> 1 file changed, 1 insertion(+), 2 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml >> index 4782f96feb7e..eb726770f571 100644 >> --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml >> +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml >> @@ -106,8 +106,7 @@ additionalProperties: >> line-name: true >> >> - type: object >> - additionalProperties: >> - $ref: "#/additionalProperties/anyOf/0" >> + additionalProperties: false > > With no properties defined, this only allows an empty node which is > probably not what you want. It's the other anyOf entry that needed it, > but I already sent a fix which Linus applied. Thanks! > > Rob
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > SD MUX output (SD0) is further divided by 4 in G2{L, UL}. The divided > clock is SD0_DIV4. SD0_DIV4 is registered with CLK_SET_RATE_PARENT which > means a rate request for it is propagated to the MUX and could reach > rzg2l_cpg_sd_clk_mux_set_parent() concurrently with the users of SD0. > Add proper locking to avoid concurrent access on SD MUX set rate > registers. > > Fixes: eaff33646f4cb ("clk: renesas: rzg2l: Add SDHI clk mux support") > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - adapted delay_us to 10us > - adapted CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US to 200us; tested > with this adjustements on RZ/G3S and RZ/G2L SoCs Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-clk-for-v6.7. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > According to hardware manual of RZ/G2L (r01uh0914ej0130-rzg2l-rzg2lc.pdf) > the computation formula for PLL rate is as follows: > > Fout = ((m + k/65536) * Fin) / (p * 2^s) > > and k has values in range [-32768, 32767]. Dividing k by 65536 with > integer variables leads all the time to zero. Thus we may have slight > differences b/w what has been set vs. what is displayed. Thus, > get rid of this and decompose the formula before dividing k by 65536. > > Fixes: ef3c613ccd68a ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - used mul_u64_u32_shr() Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-clk-for-v6.7. > --- a/drivers/clk/renesas/rzg2l-cpg.c > +++ b/drivers/clk/renesas/rzg2l-cpg.c > @@ -695,18 +695,18 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, > 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; > + u64 rate; > > 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) << SDIV(val2); > > - return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); > + rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + (s16)KDIV(val1), As KDIV() is always a signed number, I will move the cast to s16 to the definition of KDIV() while applying. > + 16 + SDIV(val2)); > + > + return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1)); > } > > static const struct clk_ops rzg2l_cpg_pll_ops = { Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Add support for reading the frequency of PLL1/4/6 available on RZ/G3S. > The computation formula for PLL frequency is as follows: > Fout = (nir + nfr / 4096) * Fin / (mr * pr) > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - added GENMASK() defines for DIV_P, DIV_M, DIV_NI, DIV_NF > - used mul_u64_u32_shr() as suggested by Geert on v1 > - s/CLK_TYPE_G3S_SAM_PLL/CLK_TYPE_G3S_PLL/g Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-clk-for-v6.7. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Remove CPG_SDHI_DSEL and its bits from generic header as RZ/G3S has > different offset register and bits for this, thus avoid mixing them. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- > > Changes in v2: > - s/form/from in commit description > - removed "G2UL_" prefix from macros' names > - collected tags Thanks, will queue in renesas-clk-for-v6.7. Gr{oetje,eeting}s, Geert
Hi Claudiu, On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Add a divider clock driver for RZ/G3S. This will be used in RZ/G3S > by SDHI, SPI, OCTA, I, I2, I3, P0, P1, P2, P3 core clocks. > The divider has some limitation for SDHI and OCTA clocks: > - SD div cannot be 1 if parent rate is 800MHz > - OCTA div cannot be 1 if parent rate is 400MHz > For these clocks a notifier could be registered from platform specific > clock driver and proper actions are taken before clock rate is changed, > if needed. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - removed DIV_NOTIF macro Thanks for the update! > --- a/drivers/clk/renesas/rzg2l-cpg.c > +++ b/drivers/clk/renesas/rzg2l-cpg.c > @@ -91,6 +91,22 @@ struct sd_mux_hw_data { > > #define to_sd_mux_hw_data(_hw) container_of(_hw, struct sd_mux_hw_data, hw_data) > > +/** > + * struct div_hw_data - divider clock hardware data > + * @hw_data: clock hw data > + * @dtable: pointer to divider table > + * @invalid_rate: invalid rate for divider > + * @width: divider width > + */ > +struct div_hw_data { > + struct clk_hw_data hw_data; > + const struct clk_div_table *dtable; > + unsigned long invalid_rate; > + u32 width; > +}; > + > +#define to_div_hw_data(_hw) container_of(_hw, struct div_hw_data, hw_data) > + > struct rzg2l_pll5_param { > u32 pl5_fracin; > u8 pl5_refdiv; > @@ -200,6 +216,54 @@ int rzg2l_cpg_sd_mux_clk_notifier(struct notifier_block *nb, unsigned long event > return ret; > } > > +int rzg3s_cpg_div_clk_notifier(struct notifier_block *nb, unsigned long event, > + void *data) > +{ > + struct clk_notifier_data *cnd = data; > + struct clk_hw *hw = __clk_get_hw(cnd->clk); > + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); > + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); > + struct rzg2l_cpg_priv *priv = clk_hw_data->priv; > + u32 off = GET_REG_OFFSET(clk_hw_data->conf); > + u32 shift = GET_SHIFT(clk_hw_data->conf); > + u32 bitmask = GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); > + unsigned long flags; > + int ret = 0; > + u32 val; > + > + if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate || > + div_hw_data->invalid_rate % cnd->new_rate) > + return 0; NOTIFY_DONE for event != PRE_RATE_CHANGE NOTIFY_OK for the other cases > + > + spin_lock_irqsave(&priv->rmw_lock, flags); > + > + val = readl(priv->base + off); > + val >>= shift; > + val &= bitmask; > + > + /* > + * There are different constraints for the user of this notifiers as follows: > + * 1/ SD div cannot be 1 (val == 0) if parent rate is 800MHz > + * 2/ OCTA div cannot be 1 (val == 0) if parent rate is 400MHz > + * As SD can have only one parent having 800MHz and OCTA div can have > + * only one parent having 400MHz we took into account the parent rate > + * at the beginning of function (by checking invalid_rate % new_rate). > + * Now it is time to check the hardware divider and update it accordingly. > + */ > + if (!val) { > + writel(((bitmask << shift) << 16) | BIT(shift), priv->base + off); Haven't you exchanged the (single) write-enable bit and the (multi-bit) division ratio setting? According to the docs, the write-enable bit is at 16 + shift, while the division ratio is at shift. Also, using bitmask as the division ratio means the maximum value that fits in the bitfield, which would be a prohibited setting in case of DIV_OCTA. Now, looking at rzg3s_div_clk_set_rate() below, perhaps you just wanted to set the ratio to value to 1, but used the wrong size for bitmask? > + /* Wait for the update done. */ > + ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); > + } > + > + spin_unlock_irqrestore(&priv->rmw_lock, flags); > + > + if (ret) > + dev_err(priv->dev, "Failed to downgrade the div\n"); and return NOTIFY_BAD > + > + return ret; NOTIFY_OK > +} > + > static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core, > struct rzg2l_cpg_priv *priv) > { > @@ -217,6 +281,146 @@ static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk > return clk_notifier_register(hw->clk, nb); > } > > +static unsigned long rzg3s_div_clk_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); > + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); > + struct rzg2l_cpg_priv *priv = clk_hw_data->priv; > + u32 val; > + > + val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); > + val >>= GET_SHIFT(clk_hw_data->conf); > + val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); > + > + return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable, > + CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width); > +} > + > +static bool rzg3s_div_clk_is_rate_valid(const unsigned long invalid_rate, unsigned long rate) > +{ > + if (invalid_rate && rate >= invalid_rate) > + return false; > + > + return true; > +} > + > +static long rzg3s_div_clk_round_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long *parent_rate) > +{ > + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); > + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); > + long round_rate; > + > + round_rate = divider_round_rate(hw, rate, parent_rate, div_hw_data->dtable, > + div_hw_data->width, CLK_DIVIDER_ROUND_CLOSEST); > + > + if (!rzg3s_div_clk_is_rate_valid(div_hw_data->invalid_rate, round_rate)) > + return -EINVAL; Shouldn't this return the closest rate that is actually supported instead? > + > + return round_rate; > +} But please implement .determine_rate() instead of .round_rate() in new drivers. > + > +static int rzg3s_div_clk_set_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long parent_rate) > +{ > + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); > + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); > + struct rzg2l_cpg_priv *priv = clk_hw_data->priv; > + u32 off = GET_REG_OFFSET(clk_hw_data->conf); > + u32 shift = GET_SHIFT(clk_hw_data->conf); > + unsigned long flags; > + u32 bitmask, val; > + int ret; > + > + /* > + * Some dividers cannot support some rates: > + * - SD div cannot support 800 MHz when parent is @800MHz and div = 1 > + * - OCTA div cannot support 400 MHz when parent is @400MHz and div = 1 > + * Check these scenarios. > + */ > + if (!rzg3s_div_clk_is_rate_valid(div_hw_data->invalid_rate, rate)) > + return -EINVAL; Can this actually happen? Wouldn't the notifier have prevented us from getting here? > + > + val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width, > + CLK_DIVIDER_ROUND_CLOSEST); > + > + bitmask = (GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0) << shift) << 16; Is bitmask the (single) write-enable bit? If yes, that should be BIT(16 + shift), and the variable should be renamed to reflect that. I guess there should be a general "#define CPG_WEN BIT(16)", then you can simply use writel((CPG_WEN | val) << shift, ...); > + > + spin_lock_irqsave(&priv->rmw_lock, flags); > + writel(bitmask | (val << shift), priv->base + off); > + /* Wait for the update done. */ > + ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); > + spin_unlock_irqrestore(&priv->rmw_lock, flags); > + > + return ret; > +} > + > +static const struct clk_ops rzg3s_div_clk_ops = { > + .recalc_rate = rzg3s_div_clk_recalc_rate, > + .round_rate = rzg3s_div_clk_round_rate, > + .set_rate = rzg3s_div_clk_set_rate, > +}; > + > +static struct clk * __init > +rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct clk **clks, > + void __iomem *base, struct rzg2l_cpg_priv *priv) > +{ > + struct div_hw_data *div_hw_data; > + struct clk_init_data init = {}; > + const struct clk_div_table *clkt; > + struct clk_hw *clk_hw; > + const struct clk *parent; > + const char *parent_name; > + u32 max; > + int ret; > + > + parent = clks[core->parent & 0xffff]; > + if (IS_ERR(parent)) > + return ERR_CAST(parent); > + > + parent_name = __clk_get_name(parent); > + > + div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL); > + if (!div_hw_data) > + return ERR_PTR(-ENOMEM); > + > + init.name = core->name; > + init.flags = core->flag; > + init.ops = &rzg3s_div_clk_ops; > + init.parent_names = &parent_name; > + init.num_parents = 1; > + > + /* Get the maximum divider to retrieve div width. */ > + for (clkt = core->dtable; clkt->div; clkt++) { > + if (max < clkt->div) "max" is used uninitialized > + max = clkt->div; > + } > + > + div_hw_data->hw_data.priv = priv; > + div_hw_data->hw_data.conf = core->conf; > + div_hw_data->hw_data.sconf = core->sconf; > + div_hw_data->dtable = core->dtable; > + div_hw_data->invalid_rate = core->invalid_rate; > + div_hw_data->width = fls(max) - 1; Isn't that > + > + clk_hw = &div_hw_data->hw_data.hw; > + clk_hw->init = &init; > + > + ret = devm_clk_hw_register(priv->dev, clk_hw); > + if (ret) > + return ERR_PTR(ret); > + > + ret = rzg2l_register_notifier(clk_hw, core, priv); > + if (ret) { > + dev_err(priv->dev, "Failed to register notifier for %s\n", > + core->name); > + return ERR_PTR(ret); > + } > + > + return clk_hw->clk; > +} Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Add minimal clock and reset support for RZ/G3S SoC to be able to boot > Linux from SD Card/eMMC. This includes necessary core clocks for booting > and GIC, SCIF, GPIO, SD0 mod clocks and resets. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - used RZ/G3S specific definition for CPG_CLKDIVSTATUS register > - removed CLK_PLL3_DIV2_2, CLK_SD0_DIV, CLK_S0_DIV2 > - added space after { and before } in array initializations > - s/indexes/indices/g > - s/.osc/OSC and moved it in core output clocks section > - s/.osc2/OSC2 and moved it in core output clock section > - s/SD0_DIV4/.sd0_div4 Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > SD, PWPR power registers have different offsets b/w RZ/G2L and RZ/G3S. > Commit adds a per SoC configuration data structure that is initialized with > proper register offset for individual SoCs. The struct rzg2l_hwcfg will be > further extended in next commits. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- > > Changes in v2: > - collected tags Thanks, will queue in renesas-pinctrl-for-v6.7. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > RZ/G3S supports different drive strength values for different power sources > and pin groups (A, B, C). On each group there could be up to 4 drive > strength values per power source. Available power sources are 1v8, 2v5, > 3v3. Drive strength values are fine tuned than what was previously > available on the driver thus the necessity of having micro-amp support. > As drive strength and power source values are linked together the > hardware setup for these was moved at the end of > rzg2l_pinctrl_pinconf_set() to ensure proper validation of the new > values. > > The drive strength values are expected to be initialized though SoC > specific hardware configuration data structure. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - s/strenght/strength, s/togheter/together in commit description > - got rid of RZG2L_INVALID_IOLH_VAL macro and consider zero as invalid > value for entries in struct rzg2l_hwcfg::iolh_group[abc]_ua[] arrays > - removed spinlock in rzg2l_[sg]et_power_source() > - introduced caps_to_pwr_reg() and simplified the code in > rzg2l_[sg]et_power_source() > - changed return type of rzg2l_iolh_ua_to_val() to int and return > -EINVAL on failure cases > - s/rzg2l_ds_supported/rzg2l_ds_is_supported > - inverted the logic in rzg2l_pinctrl_pinconf_set() when applying drive > strength and power source to hardware registers and thus simplified the > code > - used devm_kcalloc() instead of devm_kzalloc() > - adderessed the rest of the review comments Thanks, will queue in renesas-pinctrl-for-v6.7, with Paul's comment addresses. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:40 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Document Renesas RZ/G3S SMARC SoM board which is based on RZ/G3S > (R9A08G045S33) SoC. > > Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org> > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - this patch is new in v2 and added as suggested by Geert Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-devel for v6.7. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:40 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Add initial DTSI for RZ/G3S SoC. Files in commit has the following > meaning: > r9a08g045.dtsi RZ/G3S family SoC common parts > r9a08g045s33.dtsi RZ/G3S R0A08G045S33 SoC specific parts > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- > > Changes in v2: > - collected tags Thanks, will queue in renesas-devel for v6.7. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:40 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Add initial device tree for RZ SMARC Carrier-II. At the moment it > contains only serial interface. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - inversed the pin naming Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-devel for v6.7. Gr{oetje,eeting}s, Geert
On Fri, Sep 29, 2023 at 7:40 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Enable config flag for Renesas RZ/G3S (R9A08G045) SoC. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- > > Changes in v2: > - collected tags Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-devel for v6.7. Gr{oetje,eeting}s, Geert
Hi, Geert, On 04.10.2023 15:30, Geert Uytterhoeven wrote: > Hi Claudiu, > > On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: >> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> >> Add a divider clock driver for RZ/G3S. This will be used in RZ/G3S >> by SDHI, SPI, OCTA, I, I2, I3, P0, P1, P2, P3 core clocks. >> The divider has some limitation for SDHI and OCTA clocks: >> - SD div cannot be 1 if parent rate is 800MHz >> - OCTA div cannot be 1 if parent rate is 400MHz >> For these clocks a notifier could be registered from platform specific >> clock driver and proper actions are taken before clock rate is changed, >> if needed. >> >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> --- >> >> Changes in v2: >> - removed DIV_NOTIF macro > > Thanks for the update! > >> --- a/drivers/clk/renesas/rzg2l-cpg.c >> +++ b/drivers/clk/renesas/rzg2l-cpg.c >> @@ -91,6 +91,22 @@ struct sd_mux_hw_data { >> >> #define to_sd_mux_hw_data(_hw) container_of(_hw, struct sd_mux_hw_data, hw_data) >> >> +/** >> + * struct div_hw_data - divider clock hardware data >> + * @hw_data: clock hw data >> + * @dtable: pointer to divider table >> + * @invalid_rate: invalid rate for divider >> + * @width: divider width >> + */ >> +struct div_hw_data { >> + struct clk_hw_data hw_data; >> + const struct clk_div_table *dtable; >> + unsigned long invalid_rate; >> + u32 width; >> +}; >> + >> +#define to_div_hw_data(_hw) container_of(_hw, struct div_hw_data, hw_data) >> + >> struct rzg2l_pll5_param { >> u32 pl5_fracin; >> u8 pl5_refdiv; >> @@ -200,6 +216,54 @@ int rzg2l_cpg_sd_mux_clk_notifier(struct notifier_block *nb, unsigned long event >> return ret; >> } >> >> +int rzg3s_cpg_div_clk_notifier(struct notifier_block *nb, unsigned long event, >> + void *data) >> +{ >> + struct clk_notifier_data *cnd = data; >> + struct clk_hw *hw = __clk_get_hw(cnd->clk); >> + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); >> + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); >> + struct rzg2l_cpg_priv *priv = clk_hw_data->priv; >> + u32 off = GET_REG_OFFSET(clk_hw_data->conf); >> + u32 shift = GET_SHIFT(clk_hw_data->conf); >> + u32 bitmask = GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); >> + unsigned long flags; >> + int ret = 0; >> + u32 val; >> + >> + if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate || >> + div_hw_data->invalid_rate % cnd->new_rate) >> + return 0; > > NOTIFY_DONE for event != PRE_RATE_CHANGE > NOTIFY_OK for the other cases Sure! > >> + >> + spin_lock_irqsave(&priv->rmw_lock, flags); >> + >> + val = readl(priv->base + off); >> + val >>= shift; >> + val &= bitmask; >> + >> + /* >> + * There are different constraints for the user of this notifiers as follows: >> + * 1/ SD div cannot be 1 (val == 0) if parent rate is 800MHz >> + * 2/ OCTA div cannot be 1 (val == 0) if parent rate is 400MHz >> + * As SD can have only one parent having 800MHz and OCTA div can have >> + * only one parent having 400MHz we took into account the parent rate >> + * at the beginning of function (by checking invalid_rate % new_rate). >> + * Now it is time to check the hardware divider and update it accordingly. >> + */ >> + if (!val) { >> + writel(((bitmask << shift) << 16) | BIT(shift), priv->base + off); > > Haven't you exchanged the (single) write-enable bit and the (multi-bit) > division ratio setting? According to the docs, the write-enable bit > is at 16 + shift, while the division ratio is at shift. Indeed, I messed this up. Though, I've tested quite some use cases and they all worked... I'll review this anyway, thanks for pointing it up. > > Also, using bitmask as the division ratio means the maximum value > that fits in the bitfield, which would be a prohibited setting in case > of DIV_OCTA. > > Now, looking at rzg3s_div_clk_set_rate() below, perhaps you just wanted > to set the ratio to value to 1, but used the wrong size for bitmask? Yes, the idea was to set a safe divider. > >> + /* Wait for the update done. */ >> + ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); >> + } >> + >> + spin_unlock_irqrestore(&priv->rmw_lock, flags); >> + >> + if (ret) >> + dev_err(priv->dev, "Failed to downgrade the div\n"); > > and return NOTIFY_BAD Sure! > >> + >> + return ret; > > NOTIFY_OK Sure! > >> +} >> + >> static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core, >> struct rzg2l_cpg_priv *priv) >> { >> @@ -217,6 +281,146 @@ static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk >> return clk_notifier_register(hw->clk, nb); >> } >> >> +static unsigned long rzg3s_div_clk_recalc_rate(struct clk_hw *hw, >> + unsigned long parent_rate) >> +{ >> + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); >> + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); >> + struct rzg2l_cpg_priv *priv = clk_hw_data->priv; >> + u32 val; >> + >> + val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); >> + val >>= GET_SHIFT(clk_hw_data->conf); >> + val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); >> + >> + return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable, >> + CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width); >> +} >> + >> +static bool rzg3s_div_clk_is_rate_valid(const unsigned long invalid_rate, unsigned long rate) >> +{ >> + if (invalid_rate && rate >= invalid_rate) >> + return false; >> + >> + return true; >> +} >> + >> +static long rzg3s_div_clk_round_rate(struct clk_hw *hw, unsigned long rate, >> + unsigned long *parent_rate) >> +{ >> + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); >> + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); >> + long round_rate; >> + >> + round_rate = divider_round_rate(hw, rate, parent_rate, div_hw_data->dtable, >> + div_hw_data->width, CLK_DIVIDER_ROUND_CLOSEST); >> + >> + if (!rzg3s_div_clk_is_rate_valid(div_hw_data->invalid_rate, round_rate)) >> + return -EINVAL; > > Shouldn't this return the closest rate that is actually supported instead? The divider_round_rate() already choose it as the closest rate that it is actually not supported, thus I chose to just return -EINVAL. I chose it this way to use divider_round_rate(). Don't know if there is way around this using divider_round_rate() I'll have a look. > >> + >> + return round_rate; >> +} > > But please implement .determine_rate() instead of .round_rate() in > new drivers. Indeed, I missed this one. > >> + >> +static int rzg3s_div_clk_set_rate(struct clk_hw *hw, unsigned long rate, >> + unsigned long parent_rate) >> +{ >> + struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw); >> + struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data); >> + struct rzg2l_cpg_priv *priv = clk_hw_data->priv; >> + u32 off = GET_REG_OFFSET(clk_hw_data->conf); >> + u32 shift = GET_SHIFT(clk_hw_data->conf); >> + unsigned long flags; >> + u32 bitmask, val; >> + int ret; >> + >> + /* >> + * Some dividers cannot support some rates: >> + * - SD div cannot support 800 MHz when parent is @800MHz and div = 1 >> + * - OCTA div cannot support 400 MHz when parent is @400MHz and div = 1 >> + * Check these scenarios. >> + */ >> + if (!rzg3s_div_clk_is_rate_valid(div_hw_data->invalid_rate, rate)) >> + return -EINVAL; > > Can this actually happen? Wouldn't the notifier have prevented us from > getting here? I remember I added it here as a result of testing. I'll double check it. > >> + >> + val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width, >> + CLK_DIVIDER_ROUND_CLOSEST); >> + >> + bitmask = (GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0) << shift) << 16; > > Is bitmask the (single) write-enable bit? > > If yes, that should be BIT(16 + shift), and the variable should be > renamed to reflect that. > > I guess there should be a general "#define CPG_WEN BIT(16)", then you > can simply use > > writel((CPG_WEN | val) << shift, ...); OK. > >> + >> + spin_lock_irqsave(&priv->rmw_lock, flags); >> + writel(bitmask | (val << shift), priv->base + off); >> + /* Wait for the update done. */ >> + ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); >> + spin_unlock_irqrestore(&priv->rmw_lock, flags); >> + >> + return ret; >> +} >> + >> +static const struct clk_ops rzg3s_div_clk_ops = { >> + .recalc_rate = rzg3s_div_clk_recalc_rate, >> + .round_rate = rzg3s_div_clk_round_rate, >> + .set_rate = rzg3s_div_clk_set_rate, >> +}; >> + >> +static struct clk * __init >> +rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct clk **clks, >> + void __iomem *base, struct rzg2l_cpg_priv *priv) >> +{ >> + struct div_hw_data *div_hw_data; >> + struct clk_init_data init = {}; >> + const struct clk_div_table *clkt; >> + struct clk_hw *clk_hw; >> + const struct clk *parent; >> + const char *parent_name; >> + u32 max; >> + int ret; >> + >> + parent = clks[core->parent & 0xffff]; >> + if (IS_ERR(parent)) >> + return ERR_CAST(parent); >> + >> + parent_name = __clk_get_name(parent); >> + >> + div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL); >> + if (!div_hw_data) >> + return ERR_PTR(-ENOMEM); >> + >> + init.name = core->name; >> + init.flags = core->flag; >> + init.ops = &rzg3s_div_clk_ops; >> + init.parent_names = &parent_name; >> + init.num_parents = 1; >> + >> + /* Get the maximum divider to retrieve div width. */ >> + for (clkt = core->dtable; clkt->div; clkt++) { >> + if (max < clkt->div) > > "max" is used uninitialized Yes, you're right. Thank you for your review, Claudiu Beznea > >> + max = clkt->div; >> + } >> + >> + div_hw_data->hw_data.priv = priv; >> + div_hw_data->hw_data.conf = core->conf; >> + div_hw_data->hw_data.sconf = core->sconf; >> + div_hw_data->dtable = core->dtable; >> + div_hw_data->invalid_rate = core->invalid_rate; >> + div_hw_data->width = fls(max) - 1; > > Isn't that >> + >> + clk_hw = &div_hw_data->hw_data.hw; >> + clk_hw->init = &init; >> + >> + ret = devm_clk_hw_register(priv->dev, clk_hw); >> + if (ret) >> + return ERR_PTR(ret); >> + >> + ret = rzg2l_register_notifier(clk_hw, core, priv); >> + if (ret) { >> + dev_err(priv->dev, "Failed to register notifier for %s\n", >> + core->name); >> + return ERR_PTR(ret); >> + } >> + >> + return clk_hw->clk; >> +} > > Gr{oetje,eeting}s, > > Geert >
On 04.10.2023 16:17, Geert Uytterhoeven wrote: > On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: >> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> >> RZ/G3S supports different drive strength values for different power sources >> and pin groups (A, B, C). On each group there could be up to 4 drive >> strength values per power source. Available power sources are 1v8, 2v5, >> 3v3. Drive strength values are fine tuned than what was previously >> available on the driver thus the necessity of having micro-amp support. >> As drive strength and power source values are linked together the >> hardware setup for these was moved at the end of >> rzg2l_pinctrl_pinconf_set() to ensure proper validation of the new >> values. >> >> The drive strength values are expected to be initialized though SoC >> specific hardware configuration data structure. >> >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> --- >> >> Changes in v2: >> - s/strenght/strength, s/togheter/together in commit description >> - got rid of RZG2L_INVALID_IOLH_VAL macro and consider zero as invalid >> value for entries in struct rzg2l_hwcfg::iolh_group[abc]_ua[] arrays >> - removed spinlock in rzg2l_[sg]et_power_source() >> - introduced caps_to_pwr_reg() and simplified the code in >> rzg2l_[sg]et_power_source() >> - changed return type of rzg2l_iolh_ua_to_val() to int and return >> -EINVAL on failure cases >> - s/rzg2l_ds_supported/rzg2l_ds_is_supported >> - inverted the logic in rzg2l_pinctrl_pinconf_set() when applying drive >> strength and power source to hardware registers and thus simplified the >> code >> - used devm_kcalloc() instead of devm_kzalloc() >> - adderessed the rest of the review comments > > Thanks, will queue in renesas-pinctrl-for-v6.7, with Paul's comment > addresses. Thank you Geert and Paul! > > Gr{oetje,eeting}s, > > Geert >
On Wed, Oct 4, 2023 at 3:17 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote: > On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > > > RZ/G3S supports different drive strength values for different power sources > > and pin groups (A, B, C). On each group there could be up to 4 drive > > strength values per power source. Available power sources are 1v8, 2v5, > > 3v3. Drive strength values are fine tuned than what was previously > > available on the driver thus the necessity of having micro-amp support. > > As drive strength and power source values are linked together the > > hardware setup for these was moved at the end of > > rzg2l_pinctrl_pinconf_set() to ensure proper validation of the new > > values. > > > > The drive strength values are expected to be initialized though SoC > > specific hardware configuration data structure. > > > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > --- > > > > Changes in v2: > > - s/strenght/strength, s/togheter/together in commit description > > - got rid of RZG2L_INVALID_IOLH_VAL macro and consider zero as invalid > > value for entries in struct rzg2l_hwcfg::iolh_group[abc]_ua[] arrays > > - removed spinlock in rzg2l_[sg]et_power_source() > > - introduced caps_to_pwr_reg() and simplified the code in > > rzg2l_[sg]et_power_source() > > - changed return type of rzg2l_iolh_ua_to_val() to int and return > > -EINVAL on failure cases > > - s/rzg2l_ds_supported/rzg2l_ds_is_supported > > - inverted the logic in rzg2l_pinctrl_pinconf_set() when applying drive > > strength and power source to hardware registers and thus simplified the > > code > > - used devm_kcalloc() instead of devm_kzalloc() > > - adderessed the rest of the review comments Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > Thanks, will queue in renesas-pinctrl-for-v6.7, with Paul's comment > addresses. Gr{oetje,eeting}s, Geert
Hi Claudiu, On Wed, Oct 4, 2023 at 2:30 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote: > On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > > > Add a divider clock driver for RZ/G3S. This will be used in RZ/G3S > > by SDHI, SPI, OCTA, I, I2, I3, P0, P1, P2, P3 core clocks. > > The divider has some limitation for SDHI and OCTA clocks: > > - SD div cannot be 1 if parent rate is 800MHz > > - OCTA div cannot be 1 if parent rate is 400MHz > > For these clocks a notifier could be registered from platform specific > > clock driver and proper actions are taken before clock rate is changed, > > if needed. > > > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > --- > > > > Changes in v2: > > - removed DIV_NOTIF macro > > --- a/drivers/clk/renesas/rzg2l-cpg.c > > +++ b/drivers/clk/renesas/rzg2l-cpg.c > > +static struct clk * __init > > +rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct clk **clks, > > + void __iomem *base, struct rzg2l_cpg_priv *priv) > > +{ > > + struct div_hw_data *div_hw_data; > > + struct clk_init_data init = {}; > > + const struct clk_div_table *clkt; > > + struct clk_hw *clk_hw; > > + const struct clk *parent; > > + const char *parent_name; > > + u32 max; > > + int ret; > > + > > + parent = clks[core->parent & 0xffff]; > > + if (IS_ERR(parent)) > > + return ERR_CAST(parent); > > + > > + parent_name = __clk_get_name(parent); > > + > > + div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL); > > + if (!div_hw_data) > > + return ERR_PTR(-ENOMEM); > > + > > + init.name = core->name; > > + init.flags = core->flag; > > + init.ops = &rzg3s_div_clk_ops; > > + init.parent_names = &parent_name; > > + init.num_parents = 1; > > + > > + /* Get the maximum divider to retrieve div width. */ > > + for (clkt = core->dtable; clkt->div; clkt++) { > > + if (max < clkt->div) > > "max" is used uninitialized > > > + max = clkt->div; > > + } > > + > > + div_hw_data->hw_data.priv = priv; > > + div_hw_data->hw_data.conf = core->conf; > > + div_hw_data->hw_data.sconf = core->sconf; > > + div_hw_data->dtable = core->dtable; > > + div_hw_data->invalid_rate = core->invalid_rate; > > + div_hw_data->width = fls(max) - 1; > > Isn't that My apologies for not finishing my sentence; I wanted to write "Isn't that identical to __fls(max)?". But as the latter generates slightly worse code, it's not worth making that change. Gr{oetje,eeting}s, Geert
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Hi, This patch series adds initial support for The Renesas RZ/G3S (R9A08G045{S33}) SoC. The RZ/G3S device is a general-purpose microprocessor with a single-core Arm® Cortex®-A55 (1.1GHz) and a dual-core Arm® Cortex®-M33 (250MHz), perfect for an IOT gateway controller. This includes: - SoC identification; - clocks (core clocks, pin controller clock, serial interface, SD ch0 clock) and corresponding resets; - minimal device tree for SoM and carrier boards. With this series Linux can boot from eMMC or SD card. The eMMC and uSD interface are multiplexed on the SoM; selection is made using a hardware switch. Patches are gouped as follows: - 01 documents scif support; - 02-05 contain fixes on clock drivers identified while adding RZ/G3S support - 06 clock cleanups identifies while adding support for RZ/G3S - 07-13 clock changes needed by RZ/G3S - 14-21 pinctrl changes needed by RZ/G3S - 22-28 device tree support for RZ/G3S Changes in v2: - addressed review comments - collected tags - removed from series patches that were already integrated - added patches: - [PATCH v2 19/28] dt-bindings: pinctrl: renesas: set additionalProperties: false - [PATCH v2 23/28] dt-bindings: arm: renesas: document RZ/G3S SMARC SoM - [PATCH v2 26/28] dt-bindings: arm: renesas: document SMARC Carrier-II EVK - please see individual patches for detailed changes Claudiu Beznea (28): dt-bindings: serial: renesas,scif: document r9a08g045 support clk: renesas: rzg2l: wait for status bit of SD mux before continuing clk: renesas: rzg2l: lock around writes to mux register clk: renesas: rzg2l: trust value returned by hardware clk: renesas: rzg2l: fix computation formula clk: renesas: rzg2l: remove critical area clk: renesas: rzg2l: add support for RZ/G3S PLL clk: renesas: rzg2l: add struct clk_hw_data clk: renesas: rzg2l: remove CPG_SDHI_DSEL from generic header clk: renesas: rzg2l: refactor sd mux driver clk: renesas: rzg2l: add a divider clock for RZ/G3S dt-bindings: clock: renesas,rzg2l-cpg: document RZ/G3S SoC clk: renesas: add minimal boot support for RZ/G3S SoC pinctrl: renesas: rzg2l: index all registers based on port offset pinctrl: renesas: rzg2l: adapt for different SD/PWPR register offsets pinctrl: renesas: rzg2l: adapt function number for RZ/G3S pinctrl: renesas: rzg2l: move ds and oi to SoC specific configuration pinctrl: renesas: rzg2l: add support for different ds values on different groups dt-bindings: pinctrl: renesas: set additionalProperties: false dt-bindings: pinctrl: renesas: document RZ/G3S SoC pinctrl: renesas: rzg2l: add support for RZ/G3S SoC arm64: dts: renesas: add initial DTSI for RZ/G3S SoC dt-bindings: arm: renesas: document RZ/G3S SMARC SoM arm64: dts: renesas: rzg3l-smarc-som: add initial support for RZ/G3S SMARC SoM arm64: dts: renesas: rzg3s-smarc: add initial device tree for RZ SMARC Carrier-II Board dt-bindings: arm: renesas: document SMARC Carrier-II EVK arm64: dts: renesas: r9a08g045s33-smarc: add initial device tree for RZ/G3S SMARC EVK board arm64: defconfig: enable RZ/G3S (R9A08G045) SoC .../bindings/clock/renesas,rzg2l-cpg.yaml | 1 + .../pinctrl/renesas,rzg2l-pinctrl.yaml | 23 +- .../bindings/serial/renesas,scif.yaml | 1 + .../bindings/soc/renesas/renesas.yaml | 13 + arch/arm64/boot/dts/renesas/Makefile | 2 + arch/arm64/boot/dts/renesas/r9a08g045.dtsi | 139 ++++ .../boot/dts/renesas/r9a08g045s33-smarc.dts | 17 + arch/arm64/boot/dts/renesas/r9a08g045s33.dtsi | 14 + .../boot/dts/renesas/rzg3s-smarc-som.dtsi | 142 ++++ arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi | 28 + arch/arm64/configs/defconfig | 1 + drivers/clk/renesas/Kconfig | 7 +- drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r9a07g043-cpg.c | 19 +- drivers/clk/renesas/r9a07g044-cpg.c | 19 +- drivers/clk/renesas/r9a08g045-cpg.c | 213 ++++++ drivers/clk/renesas/rzg2l-cpg.c | 478 ++++++++++-- drivers/clk/renesas/rzg2l-cpg.h | 33 +- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 705 ++++++++++++++---- include/dt-bindings/clock/r9a08g045-cpg.h | 242 ++++++ 20 files changed, 1860 insertions(+), 238 deletions(-) create mode 100644 arch/arm64/boot/dts/renesas/r9a08g045.dtsi create mode 100644 arch/arm64/boot/dts/renesas/r9a08g045s33-smarc.dts create mode 100644 arch/arm64/boot/dts/renesas/r9a08g045s33.dtsi create mode 100644 arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi create mode 100644 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi create mode 100644 drivers/clk/renesas/r9a08g045-cpg.c create mode 100644 include/dt-bindings/clock/r9a08g045-cpg.h