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 29/09/2023 06:39, Claudiu 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 Should this be "are more fine tuned" or "are less fine tuned"? > 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> Thanks, Paul
On Fri, Sep 29, 2023 at 7:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Hardware user manual of RZ/G2L (r01uh0914ej0130-rzg2l-rzg2lc.pdf, > chapter 7.4.7 Procedure for Switching Clocks by the Dynamic Switching > Frequency Selectors) specifies that we need to check CPG_PL2SDHI_DSEL for > SD clock switching status. > > Fixes: eaff33646f4cb ("clk: renesas: rzg2l: Add SDHI clk mux support") > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - initialized msk 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> > > 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> > > Initial value of CPG_PL2SDHI_DSEL bits 0..1 or 4..6 is 01b. Hardware user's > manual (r01uh0914ej0130-rzg2l-rzg2lc.pdf) specifies that setting 0 is > prohibited. The rzg2l_cpg_sd_clk_mux_get_parent() should just read > CPG_PL2SDHI_DSEL, trust the value and return the proper clock parent index > based on the read value. Do this. > > Fixes: eaff33646f4cb ("clk: renesas: rzg2l: Add SDHI clk mux support") > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - Used "return val ? val - 1 : 0;" 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> > > spinlock in rzg2l_mod_clock_endisable() is intended to protect the accesses > to hardware register. There is no need to protect the instructions that set > temporary variable which will be then written to register. With this only > one write to one clock register is executed thus locking/unlocking rmw_lock > is removed. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - removed also the spinlock > - s/reduce/remove in patch title 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> > > 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> > > Add clk_hw_data struct that keeps the core part of a clock data. The > sd_hw_data embeds a member of type struct clk_hw_data along with other > members (in the next commits). This commit prepares the field for > refactoring the SD MUX clock driver. > > 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-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> > > Refactor SD MUX driver to be able to reuse the same code on RZ/G3S. > RZ/G2{L, UL} has a limitation with regards to switching the clock source > for SD MUX (MUX clock source has to be switched to 266MHz before switching > b/w 533MHz and 400MHz). This limitation has been introduced as a clock > notifier that is registered on platform based initialization data thus the > SD MUX code could be reused on RZ/G3S. > > As both RZ/G2{L, UL} and RZ/G3S has specific bits in specific registers > to check if the clock switching has been done, this configuration (register > offset, register bits and bits width) is now passed though > struct cpg_core_clk::sconf (status configuration) from platform specific > initialization code. > > Along with struct cpg_core_clk::sconf the mux table indices are also > passed from platform specific initialization code. > > Also, mux flags are now passed to DEF_SD_MUX() as they will be later > used by RZ/G3S. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - s/indexes/indices in commit description > - mentioned in commit description that mux flags can now be passed to > driver though DEF_SD_MUX() macro > - removed SoC specific names from macros' names > - added spaces after { and before } when initializing arrays > - preserved the order of .[gs]set_parent() API definitions for simpler > diff b/w versions > - removed SD_MUX_NOTIF macro Thanks for the update! > --- a/drivers/clk/renesas/rzg2l-cpg.c > +++ b/drivers/clk/renesas/rzg2l-cpg.c > @@ -142,6 +146,77 @@ static void rzg2l_cpg_del_clk_provider(void *data) > of_clk_del_provider(data); > } > > +/* Must be called in atomic context. */ > +static int rzg2l_cpg_wait_clk_update_done(void __iomem *base, u32 conf) > +{ > + u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf); > + u32 off = GET_REG_OFFSET(conf); > + u32 val; > + > + return readl_poll_timeout_atomic(base + off, val, !(val & bitmask), 10, 200); > +} > + > +int rzg2l_cpg_sd_mux_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 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); > + const u32 clk_src_266 = 3; > + unsigned long flags; > + u32 bitmask; > + int ret; > + > + if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266)) > + return 0; include/linux/clk.h: * PRE_RATE_CHANGE - called immediately before the clk rate is changed, * to indicate that the rate change will proceed. Drivers must * immediately terminate any operations that will be affected by the * rate change. Callbacks may either return NOTIFY_DONE, NOTIFY_OK, * NOTIFY_STOP or NOTIFY_BAD. > + > + spin_lock_irqsave(&priv->rmw_lock, flags); > + > + /* > + * As per the HW manual, we should not directly switch from 533 MHz to > + * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz) > + * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first, > + * and then switch to the target setting (2’b01 (533 MHz) or 2’b10 > + * (400 MHz)). > + * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock > + * switching register is prohibited. > + * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and > + * the index to value mapping is done by adding 1 to the index. > + */ > + bitmask = (GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0) << shift) << 16; > + writel(bitmask | (clk_src_266 << 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); > + > + if (ret) > + dev_err(priv->dev, "failed to switch to safe clk source\n"); > + > + return ret; Likewise. > +} > > static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = { > .determine_rate = __clk_mux_determine_rate_closest, > - .set_parent = rzg2l_cpg_sd_clk_mux_set_parent, > - .get_parent = rzg2l_cpg_sd_clk_mux_get_parent, > + .set_parent = rzg2l_cpg_sd_mux_clk_set_parent, > + .get_parent = rzg2l_cpg_sd_mux_clk_get_parent, Please keep the old names, for consistency with __clk_mux_determine_rate_closest() and drivers/clk/clk-mux.c, and to reduce the diff. Any existing inconsistent use of "clk_mux" vs. "mux_clk" can be resolved later with a separate patch, if anyone cares. > --- a/drivers/clk/renesas/rzg2l-cpg.h > +++ b/drivers/clk/renesas/rzg2l-cpg.h > @@ -272,4 +276,6 @@ extern const struct rzg2l_cpg_info r9a07g044_cpg_info; > extern const struct rzg2l_cpg_info r9a07g054_cpg_info; > extern const struct rzg2l_cpg_info r9a09g011_cpg_info; > > +int rzg2l_cpg_sd_mux_clk_notifier(struct notifier_block *nb, unsigned long event, void *data); rzg2l_cpg_sd_clk_mux_notifier()? > + > #endif The rest LGTM. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org 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
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
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> > > To get address that needs to be read/write for specific port > functionalities the P(), PM(), PMC(), PFC(), PIN(), IOLH() IEN(), ISEL() > macros are used. Some of these macros received as argument the hardware > port identifier, some hardware port offset address (e.g. ISEL() received > port identifier, IOLH() received port offset address). This makes hard to > extend the current driver for SoCs were port identifiers are not continuous > in memory map of pin controller. This is the case for RZ/G3S pin controller > were ports are mapped as follows: > > port offset port identifier > ----------- --------------- > 0x20 P0 > 0x21 P5 > 0x22 P6 > 0x23 P11 > 0x24 P12 > 0x25 P13 > 0x26 P14 > 0x27 P15 > 0x28 P16 > 0x29 P17 > 0x2a P18 > 0x30 P1 > 0x31 P2 > 0x32 P3 > 0x33 P4 > 0x34 P7 > 0x35 P8 > 0x36 P8 > 0x37 P10 > > To make this achievable change all the above macros used to get the address > of a port register for specific port functionality based on port hardware > address. Shortly, all the above macros will get as argument the port > offset address listed in the above table. > > With this RZG2L_SINGLE_PIN_GET_PORT_OFFSET(), RZG2L_PIN_ID_TO_PORT_OFFSET() > and RZG2L_GPIO_PORT_GET_INDEX() were replaced by > RZG2L_PIN_CFG_TO_PORT_OFFSET(), RZG2L_SINGLE_PIN_GET_CFGS() and > RZG2L_GPIO_PORT_GET_CFGS() were replaced by RZG2L_PIN_CFG_TO_CAPS(). > > Also rzg2l_pinctrl_set_pfc_mode() don't need port argument anymore. > Also rzg2l_gpio_direction_input() and rzg2l_gpio_direction_output() don't > need to translate port and bit locally as this can be done by > rzg2l_gpio_set_direction(). > > To use the same naming for port, bit/pin and register offset the > port_offset variable names in different places was replaced by variable > named off and there is no need to initialize anymore cfg and bit in > different code places. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > --- > > Changes in v2: > - mentioned in commit description about the replacement of > RZG2L_GPIO_PORT_GET_INDEX() with RZG2L_PIN_CFG_TO_PORT_OFFSET() > - moved variable declaration inside for() > - got rid of local variable and used directly RZG2L_PIN_ID_TO_PORT() in > debug message from rzg2l_pinctrl_set_mux() function > - collected tags Thanks for the update! Sill queue in renesas-pinctrl-for-v6.7. > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c > @@ -202,9 +202,11 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev, > unsigned int group_selector) > { > struct rzg2l_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); > + const struct pinctrl_pin_desc *pin_desc; > + unsigned int *psel_val, *pin_data; > struct function_desc *func; > - unsigned int i, *psel_val; > struct group_desc *group; > + u32 pin, off; > int *pins; > > func = pinmux_generic_get_function(pctldev, func_selector); > @@ -217,12 +219,17 @@ static int rzg2l_pinctrl_set_mux(struct pinctrl_dev *pctldev, > psel_val = func->data; > pins = group->pins; > > - for (i = 0; i < group->num_pins; i++) { > - dev_dbg(pctrl->dev, "port:%u pin: %u PSEL:%u\n", > - RZG2L_PIN_ID_TO_PORT(pins[i]), RZG2L_PIN_ID_TO_PIN(pins[i]), > - psel_val[i]); > - rzg2l_pinctrl_set_pfc_mode(pctrl, RZG2L_PIN_ID_TO_PORT(pins[i]), > - RZG2L_PIN_ID_TO_PIN(pins[i]), psel_val[i]); > + for (unsigned int i = 0; i < group->num_pins; i++) { > + pin_desc = &pctrl->desc.pins[pins[i]]; > + pin_data = pin_desc->drv_data; > + > + pin = RZG2L_PIN_ID_TO_PIN(pins[i]); > + off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); In my comments on v1, I actually meant to combine these assignments to variables with the variable declarations. I will handle that while applying. > + > + dev_dbg(pctrl->dev, "port:%u pin: %u off:%x PSEL:%u\n", > + RZG2L_PIN_ID_TO_PORT(pins[i]), pin, off, psel_val[i]); > + > + rzg2l_pinctrl_set_pfc_mode(pctrl, pin, off, psel_val[i]); > } > > return 0; 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> > > On RZ/G3S PFC register allow setting 8 functions for individual ports > (function1 to function8). For function1 register need to be configured > with 0, for function8 register need to be configured with 7. > We cannot use zero based addressing when requesting functions from > different code places as documentation (RZG3S_pinfunction_List_r1.0.xlsx) > states explicitly that function0 is GPIO. > > For this add a new member to struct rzg2l_hwcfg that will keep the > offset that need to be substracted before applying a value to PFC register. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- > > Changes in v2: > - in commit description mentioned that function0 is GPIO > - 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:39 AM Claudiu <claudiu.beznea@tuxon.dev> wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > Move drive strength and output impedance values to SoC specific > configuration data structure (struct rzg2l_hwcfg). This allows extending > the drive strength support for RZ/G3S. Along with this the DS values > were converted to uA for simple integration with RZ/G3S support. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > --- > > Changes in v2: > - s/indexes/indices in code documentation > - s/micro amps/uA in code documentation > - added RZG2L_IOLH_MAX_DS_ENTRIES for "+ 4" statements in code > - changed struct rzg2l_hwcfg::iolh_groupb_oi[] size to 4 to avoid > oversize it in next commits when RZG2L_IOLH_IDX_MAX will be increased > and thus avoiding issues when executing > "if (index == ARRAY_SIZE(hwcfg->iolh_groupb_oi))" in > rzg2l_pinctrl_pinconf_set() > - collected tags Thanks, will queue in renesas-pinctrl-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 basic support for RZ/G3S to be able to boot from SD card, have a > running console port and use GPIOs. RZ/G3S has 82 general-purpose IO > ports. Support for the remaining pin functions (e.g. Ethernet, XSPI) > will be added along with controller specific support. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - dropped [RZG2L_IOLH_IDX_2V5 ... RZG2L_IOLH_IDX_3V3 - 1] = > RZG2L_INVALID_IOLH_VAL initializations from v1 as these are not needed > anymore with the new code adjustements > - added BUILD_BUG_ON() for r9a08g045_gpio_configs[] in > rzg2l_pinctrl_probe() Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> i.e. will queue in renesas-pinctrl-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 support for RZ/G3S SMARC SoM. The following devices available > on SoM were added to this initial device tree: > > - RZ/G3S SoC: Renesas R9A08G045S33GBG > - Clock Generator (only 24MHz output): Renesas 5L35023B > - 1GiB LPDDR4 SDRAM: Micron MT53D512M16D1DS-046 > - 64GB eMMC Flash (though SD ch0): Micron MTFC64GBCAQTC > > SD channel 0 of RZ/G3S is connected to an uSD card interface > and an eMMC. The selection b/w them is done though a hardware switch. > The DT will select b/w uSD and eMMC though SW_SD0_DEV_SEL build flag. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - s/Carrier-II SoM/SoM in patch title > - listed in commit description only devices addressed by this initial dtsi > - s/8G LPDDR4/1GiB LPDDR4 in commit description > - removed sd0-pwr-en-hog node and use specific GPIO in vcc_sdhi0 regulator > - added SoM compatible: > compatible = "renesas,rzg3s-smarcm", "renesas,r9a08g045s33", "renesas,r9a08g045"; 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 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> > > Add initial device tree for RZ/G3S SMARC EVK board. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > --- > > Changes in v2: > - modified compatible > - @Geert: I haven't added you Rb tag as I've added > "renesas,rzg3s-smarcm" to the compatible list 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 14: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> >> >> Refactor SD MUX driver to be able to reuse the same code on RZ/G3S. >> RZ/G2{L, UL} has a limitation with regards to switching the clock source >> for SD MUX (MUX clock source has to be switched to 266MHz before switching >> b/w 533MHz and 400MHz). This limitation has been introduced as a clock >> notifier that is registered on platform based initialization data thus the >> SD MUX code could be reused on RZ/G3S. >> >> As both RZ/G2{L, UL} and RZ/G3S has specific bits in specific registers >> to check if the clock switching has been done, this configuration (register >> offset, register bits and bits width) is now passed though >> struct cpg_core_clk::sconf (status configuration) from platform specific >> initialization code. >> >> Along with struct cpg_core_clk::sconf the mux table indices are also >> passed from platform specific initialization code. >> >> Also, mux flags are now passed to DEF_SD_MUX() as they will be later >> used by RZ/G3S. >> >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> >> --- >> >> Changes in v2: >> - s/indexes/indices in commit description >> - mentioned in commit description that mux flags can now be passed to >> driver though DEF_SD_MUX() macro >> - removed SoC specific names from macros' names >> - added spaces after { and before } when initializing arrays >> - preserved the order of .[gs]set_parent() API definitions for simpler >> diff b/w versions >> - removed SD_MUX_NOTIF macro > > Thanks for the update! > >> --- a/drivers/clk/renesas/rzg2l-cpg.c >> +++ b/drivers/clk/renesas/rzg2l-cpg.c > >> @@ -142,6 +146,77 @@ static void rzg2l_cpg_del_clk_provider(void *data) >> of_clk_del_provider(data); >> } >> >> +/* Must be called in atomic context. */ >> +static int rzg2l_cpg_wait_clk_update_done(void __iomem *base, u32 conf) >> +{ >> + u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf); >> + u32 off = GET_REG_OFFSET(conf); >> + u32 val; >> + >> + return readl_poll_timeout_atomic(base + off, val, !(val & bitmask), 10, 200); >> +} >> + >> +int rzg2l_cpg_sd_mux_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 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); >> + const u32 clk_src_266 = 3; >> + unsigned long flags; >> + u32 bitmask; >> + int ret; >> + >> + if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266)) >> + return 0; > > include/linux/clk.h: > > * PRE_RATE_CHANGE - called immediately before the clk rate is changed, > * to indicate that the rate change will proceed. Drivers must > * immediately terminate any operations that will be affected by the > * rate change. Callbacks may either return NOTIFY_DONE, NOTIFY_OK, > * NOTIFY_STOP or NOTIFY_BAD. Indeed I missed these. > >> + >> + spin_lock_irqsave(&priv->rmw_lock, flags); >> + >> + /* >> + * As per the HW manual, we should not directly switch from 533 MHz to >> + * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz) >> + * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first, >> + * and then switch to the target setting (2’b01 (533 MHz) or 2’b10 >> + * (400 MHz)). >> + * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock >> + * switching register is prohibited. >> + * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and >> + * the index to value mapping is done by adding 1 to the index. >> + */ >> + bitmask = (GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0) << shift) << 16; >> + writel(bitmask | (clk_src_266 << 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); >> + >> + if (ret) >> + dev_err(priv->dev, "failed to switch to safe clk source\n"); >> + >> + return ret; > > Likewise. > >> +} > >> >> static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = { >> .determine_rate = __clk_mux_determine_rate_closest, >> - .set_parent = rzg2l_cpg_sd_clk_mux_set_parent, >> - .get_parent = rzg2l_cpg_sd_clk_mux_get_parent, >> + .set_parent = rzg2l_cpg_sd_mux_clk_set_parent, >> + .get_parent = rzg2l_cpg_sd_mux_clk_get_parent, > > Please keep the old names, for consistency with > __clk_mux_determine_rate_closest() and drivers/clk/clk-mux.c, and to > reduce the diff. > > Any existing inconsistent use of "clk_mux" vs. "mux_clk" can be resolved > later with a separate patch, if anyone cares. ok > >> --- a/drivers/clk/renesas/rzg2l-cpg.h >> +++ b/drivers/clk/renesas/rzg2l-cpg.h > >> @@ -272,4 +276,6 @@ extern const struct rzg2l_cpg_info r9a07g044_cpg_info; >> extern const struct rzg2l_cpg_info r9a07g054_cpg_info; >> extern const struct rzg2l_cpg_info r9a09g011_cpg_info; >> >> +int rzg2l_cpg_sd_mux_clk_notifier(struct notifier_block *nb, unsigned long event, void *data); > > rzg2l_cpg_sd_clk_mux_notifier()? ok > >> + >> #endif > > The rest LGTM. > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > 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
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