All of lore.kernel.org
 help / color / mirror / Atom feed
From: Conor Dooley <conor@kernel.org>
To: Hal Feng <hal.feng@starfivetech.com>
Cc: linux-riscv@lists.infradead.org, devicetree@vger.kernel.org,
	linux-clk@vger.kernel.org, Palmer Dabbelt <palmer@dabbelt.com>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Stephen Boyd <sboyd@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Emil Renner Berthing <emil.renner.berthing@canonical.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 01/11] clk: starfive: Factor out common JH7100 and JH7110 code
Date: Tue, 20 Dec 2022 21:54:26 +0000	[thread overview]
Message-ID: <Y6IvEnm1Wm9KM5KO@spud> (raw)
In-Reply-To: <20221220005054.34518-2-hal.feng@starfivetech.com>

[-- Attachment #1: Type: text/plain, Size: 26289 bytes --]

On Tue, Dec 20, 2022 at 08:50:44AM +0800, Hal Feng wrote:
> From: Emil Renner Berthing <kernel@esmil.dk>
> 
> The clock control registers on the StarFive JH7100 and JH7110 work
> identically, so factor out the code then drivers for the two SoCs
> can share it without depending on each other. No functional change.
> 
> Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
> Signed-off-by: Hal Feng <hal.feng@starfivetech.com>

The movement does in fact appear to be just a movement..
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Thanks,
Conor.

> ---
>  MAINTAINERS                                |   4 +-
>  drivers/clk/starfive/Kconfig               |   5 +
>  drivers/clk/starfive/Makefile              |   3 +-
>  drivers/clk/starfive/clk-starfive-jh7100.c | 325 --------------------
>  drivers/clk/starfive/clk-starfive-jh7100.h |   2 +
>  drivers/clk/starfive/clk-starfive-jh71x0.c | 333 +++++++++++++++++++++
>  6 files changed, 344 insertions(+), 328 deletions(-)
>  create mode 100644 drivers/clk/starfive/clk-starfive-jh71x0.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 886d3f69ee64..fd90403c33bd 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19632,11 +19632,11 @@ M:	Emil Renner Berthing <kernel@esmil.dk>
>  S:	Maintained
>  F:	arch/riscv/boot/dts/starfive/
>  
> -STARFIVE JH7100 CLOCK DRIVERS
> +STARFIVE JH71X0 CLOCK DRIVERS
>  M:	Emil Renner Berthing <kernel@esmil.dk>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
> -F:	drivers/clk/starfive/clk-starfive-jh7100*
> +F:	drivers/clk/starfive/clk-starfive-jh71*
>  F:	include/dt-bindings/clock/starfive-jh7100*.h
>  
>  STARFIVE JH7100 PINCTRL DRIVER
> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> index 003bd2d56ce7..594d516dcb38 100644
> --- a/drivers/clk/starfive/Kconfig
> +++ b/drivers/clk/starfive/Kconfig
> @@ -1,8 +1,12 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
> +config CLK_STARFIVE_JH71X0
> +	bool
> +
>  config CLK_STARFIVE_JH7100
>  	bool "StarFive JH7100 clock support"
>  	depends on SOC_STARFIVE || COMPILE_TEST
> +	select CLK_STARFIVE_JH71X0
>  	default SOC_STARFIVE
>  	help
>  	  Say yes here to support the clock controller on the StarFive JH7100
> @@ -11,6 +15,7 @@ config CLK_STARFIVE_JH7100
>  config CLK_STARFIVE_JH7100_AUDIO
>  	tristate "StarFive JH7100 audio clock support"
>  	depends on CLK_STARFIVE_JH7100
> +	select CLK_STARFIVE_JH71X0
>  	default m if SOC_STARFIVE
>  	help
>  	  Say Y or M here to support the audio clocks on the StarFive JH7100
> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> index 0fa8ecb9ec1c..82edfa9f9cb8 100644
> --- a/drivers/clk/starfive/Makefile
> +++ b/drivers/clk/starfive/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
> -# StarFive Clock
> +obj-$(CONFIG_CLK_STARFIVE_JH71X0)	+= clk-starfive-jh71x0.o
> +
>  obj-$(CONFIG_CLK_STARFIVE_JH7100)	+= clk-starfive-jh7100.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)	+= clk-starfive-jh7100-audio.o
> diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
> index 691aeebc7092..eea52f16af0d 100644
> --- a/drivers/clk/starfive/clk-starfive-jh7100.c
> +++ b/drivers/clk/starfive/clk-starfive-jh7100.c
> @@ -7,15 +7,10 @@
>   * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
>   */
>  
> -#include <linux/bits.h>
>  #include <linux/clk-provider.h>
> -#include <linux/debugfs.h>
>  #include <linux/device.h>
>  #include <linux/init.h>
> -#include <linux/io.h>
> -#include <linux/kernel.h>
>  #include <linux/mod_devicetable.h>
> -#include <linux/module.h>
>  #include <linux/platform_device.h>
>  
>  #include <dt-bindings/clock/starfive-jh7100.h>
> @@ -269,326 +264,6 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
>  	JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
>  };
>  
> -static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
> -{
> -	return container_of(hw, struct jh7100_clk, hw);
> -}
> -
> -static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
> -{
> -	return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
> -}
> -
> -static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
> -{
> -	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> -	void __iomem *reg = priv->base + 4 * clk->idx;
> -
> -	return readl_relaxed(reg);
> -}
> -
> -static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
> -{
> -	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> -	void __iomem *reg = priv->base + 4 * clk->idx;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&priv->rmw_lock, flags);
> -	value |= readl_relaxed(reg) & ~mask;
> -	writel_relaxed(value, reg);
> -	spin_unlock_irqrestore(&priv->rmw_lock, flags);
> -}
> -
> -static int jh7100_clk_enable(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
> -	return 0;
> -}
> -
> -static void jh7100_clk_disable(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
> -}
> -
> -static int jh7100_clk_is_enabled(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -
> -	return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
> -}
> -
> -static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
> -					    unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
> -
> -	return div ? parent_rate / div : 0;
> -}
> -
> -static int jh7100_clk_determine_rate(struct clk_hw *hw,
> -				     struct clk_rate_request *req)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	unsigned long parent = req->best_parent_rate;
> -	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> -	unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
> -	unsigned long result = parent / div;
> -
> -	/*
> -	 * we want the result clamped by min_rate and max_rate if possible:
> -	 * case 1: div hits the max divider value, which means it's less than
> -	 * parent / rate, so the result is greater than rate and min_rate in
> -	 * particular. we can't do anything about result > max_rate because the
> -	 * divider doesn't go any further.
> -	 * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
> -	 * always lower or equal to rate and max_rate. however the result may
> -	 * turn out lower than min_rate, but then the next higher rate is fine:
> -	 *   div - 1 = ceil(parent / rate) - 1 < parent / rate
> -	 * and thus
> -	 *   min_rate <= rate < parent / (div - 1)
> -	 */
> -	if (result < req->min_rate && div > 1)
> -		result = parent / (div - 1);
> -
> -	req->rate = result;
> -	return 0;
> -}
> -
> -static int jh7100_clk_set_rate(struct clk_hw *hw,
> -			       unsigned long rate,
> -			       unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
> -				  1UL, (unsigned long)clk->max_div);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
> -	return 0;
> -}
> -
> -static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
> -						 unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 reg = jh7100_clk_reg_get(clk);
> -	unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
> -			       ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
> -
> -	return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
> -}
> -
> -static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
> -					  struct clk_rate_request *req)
> -{
> -	unsigned long parent100 = 100 * req->best_parent_rate;
> -	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> -	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
> -				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> -	unsigned long result = parent100 / div100;
> -
> -	/* clamp the result as in jh7100_clk_determine_rate() above */
> -	if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
> -		result = parent100 / (div100 + 1);
> -	if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
> -		result = parent100 / (div100 - 1);
> -
> -	req->rate = result;
> -	return 0;
> -}
> -
> -static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
> -				    unsigned long rate,
> -				    unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
> -				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> -	u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
> -	return 0;
> -}
> -
> -static u8 jh7100_clk_get_parent(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value = jh7100_clk_reg_get(clk);
> -
> -	return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
> -}
> -
> -static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
> -	return 0;
> -}
> -
> -static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
> -					 struct clk_rate_request *req)
> -{
> -	return clk_mux_determine_rate_flags(hw, req, 0);
> -}
> -
> -static int jh7100_clk_get_phase(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value = jh7100_clk_reg_get(clk);
> -
> -	return (value & JH7100_CLK_INVERT) ? 180 : 0;
> -}
> -
> -static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value;
> -
> -	if (degrees == 0)
> -		value = 0;
> -	else if (degrees == 180)
> -		value = JH7100_CLK_INVERT;
> -	else
> -		return -EINVAL;
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
> -	return 0;
> -}
> -
> -#ifdef CONFIG_DEBUG_FS
> -static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
> -{
> -	static const struct debugfs_reg32 jh7100_clk_reg = {
> -		.name = "CTRL",
> -		.offset = 0,
> -	};
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> -	struct debugfs_regset32 *regset;
> -
> -	regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
> -	if (!regset)
> -		return;
> -
> -	regset->regs = &jh7100_clk_reg;
> -	regset->nregs = 1;
> -	regset->base = priv->base + 4 * clk->idx;
> -
> -	debugfs_create_regset32("registers", 0400, dentry, regset);
> -}
> -#else
> -#define jh7100_clk_debug_init NULL
> -#endif
> -
> -static const struct clk_ops jh7100_clk_gate_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_div_ops = {
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_fdiv_ops = {
> -	.recalc_rate = jh7100_clk_frac_recalc_rate,
> -	.determine_rate = jh7100_clk_frac_determine_rate,
> -	.set_rate = jh7100_clk_frac_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_gdiv_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_mux_ops = {
> -	.determine_rate = jh7100_clk_mux_determine_rate,
> -	.set_parent = jh7100_clk_set_parent,
> -	.get_parent = jh7100_clk_get_parent,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_gmux_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.determine_rate = jh7100_clk_mux_determine_rate,
> -	.set_parent = jh7100_clk_set_parent,
> -	.get_parent = jh7100_clk_get_parent,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_mdiv_ops = {
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.get_parent = jh7100_clk_get_parent,
> -	.set_parent = jh7100_clk_set_parent,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_gmd_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.get_parent = jh7100_clk_get_parent,
> -	.set_parent = jh7100_clk_set_parent,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_inv_ops = {
> -	.get_phase = jh7100_clk_get_phase,
> -	.set_phase = jh7100_clk_set_phase,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
> -{
> -	if (max & JH7100_CLK_DIV_MASK) {
> -		if (max & JH7100_CLK_MUX_MASK) {
> -			if (max & JH7100_CLK_ENABLE)
> -				return &jh7100_clk_gmd_ops;
> -			return &jh7100_clk_mdiv_ops;
> -		}
> -		if (max & JH7100_CLK_ENABLE)
> -			return &jh7100_clk_gdiv_ops;
> -		if (max == JH7100_CLK_FRAC_MAX)
> -			return &jh7100_clk_fdiv_ops;
> -		return &jh7100_clk_div_ops;
> -	}
> -
> -	if (max & JH7100_CLK_MUX_MASK) {
> -		if (max & JH7100_CLK_ENABLE)
> -			return &jh7100_clk_gmux_ops;
> -		return &jh7100_clk_mux_ops;
> -	}
> -
> -	if (max & JH7100_CLK_ENABLE)
> -		return &jh7100_clk_gate_ops;
> -
> -	return &jh7100_clk_inv_ops;
> -}
> -EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
> -
>  static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
>  {
>  	struct jh7100_clk_priv *priv = data;
> diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh7100.h
> index f116be5740a5..a8ba6e25b5ce 100644
> --- a/drivers/clk/starfive/clk-starfive-jh7100.h
> +++ b/drivers/clk/starfive/clk-starfive-jh7100.h
> @@ -4,6 +4,8 @@
>  
>  #include <linux/bits.h>
>  #include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/spinlock.h>
>  
>  /* register fields */
>  #define JH7100_CLK_ENABLE	BIT(31)
> diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
> new file mode 100644
> index 000000000000..6c07b61b4a32
> --- /dev/null
> +++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * StarFive JH7100 Clock Generator Driver
> + *
> + * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/debugfs.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +
> +#include "clk-starfive-jh7100.h"
> +
> +static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
> +{
> +	return container_of(hw, struct jh7100_clk, hw);
> +}
> +
> +static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
> +{
> +	return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
> +}
> +
> +static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
> +{
> +	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> +	void __iomem *reg = priv->base + 4 * clk->idx;
> +
> +	return readl_relaxed(reg);
> +}
> +
> +static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
> +{
> +	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> +	void __iomem *reg = priv->base + 4 * clk->idx;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&priv->rmw_lock, flags);
> +	value |= readl_relaxed(reg) & ~mask;
> +	writel_relaxed(value, reg);
> +	spin_unlock_irqrestore(&priv->rmw_lock, flags);
> +}
> +
> +static int jh7100_clk_enable(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
> +	return 0;
> +}
> +
> +static void jh7100_clk_disable(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
> +}
> +
> +static int jh7100_clk_is_enabled(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +
> +	return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
> +}
> +
> +static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
> +					    unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
> +
> +	return div ? parent_rate / div : 0;
> +}
> +
> +static int jh7100_clk_determine_rate(struct clk_hw *hw,
> +				     struct clk_rate_request *req)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	unsigned long parent = req->best_parent_rate;
> +	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> +	unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
> +	unsigned long result = parent / div;
> +
> +	/*
> +	 * we want the result clamped by min_rate and max_rate if possible:
> +	 * case 1: div hits the max divider value, which means it's less than
> +	 * parent / rate, so the result is greater than rate and min_rate in
> +	 * particular. we can't do anything about result > max_rate because the
> +	 * divider doesn't go any further.
> +	 * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
> +	 * always lower or equal to rate and max_rate. however the result may
> +	 * turn out lower than min_rate, but then the next higher rate is fine:
> +	 *   div - 1 = ceil(parent / rate) - 1 < parent / rate
> +	 * and thus
> +	 *   min_rate <= rate < parent / (div - 1)
> +	 */
> +	if (result < req->min_rate && div > 1)
> +		result = parent / (div - 1);
> +
> +	req->rate = result;
> +	return 0;
> +}
> +
> +static int jh7100_clk_set_rate(struct clk_hw *hw,
> +			       unsigned long rate,
> +			       unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
> +				  1UL, (unsigned long)clk->max_div);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
> +	return 0;
> +}
> +
> +static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
> +						 unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 reg = jh7100_clk_reg_get(clk);
> +	unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
> +			       ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
> +
> +	return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
> +}
> +
> +static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
> +					  struct clk_rate_request *req)
> +{
> +	unsigned long parent100 = 100 * req->best_parent_rate;
> +	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> +	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
> +				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> +	unsigned long result = parent100 / div100;
> +
> +	/* clamp the result as in jh7100_clk_determine_rate() above */
> +	if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
> +		result = parent100 / (div100 + 1);
> +	if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
> +		result = parent100 / (div100 - 1);
> +
> +	req->rate = result;
> +	return 0;
> +}
> +
> +static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
> +				    unsigned long rate,
> +				    unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
> +				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> +	u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
> +	return 0;
> +}
> +
> +static u8 jh7100_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value = jh7100_clk_reg_get(clk);
> +
> +	return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
> +}
> +
> +static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
> +	return 0;
> +}
> +
> +static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
> +					 struct clk_rate_request *req)
> +{
> +	return clk_mux_determine_rate_flags(hw, req, 0);
> +}
> +
> +static int jh7100_clk_get_phase(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value = jh7100_clk_reg_get(clk);
> +
> +	return (value & JH7100_CLK_INVERT) ? 180 : 0;
> +}
> +
> +static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value;
> +
> +	if (degrees == 0)
> +		value = 0;
> +	else if (degrees == 180)
> +		value = JH7100_CLK_INVERT;
> +	else
> +		return -EINVAL;
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
> +{
> +	static const struct debugfs_reg32 jh7100_clk_reg = {
> +		.name = "CTRL",
> +		.offset = 0,
> +	};
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> +	struct debugfs_regset32 *regset;
> +
> +	regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
> +	if (!regset)
> +		return;
> +
> +	regset->regs = &jh7100_clk_reg;
> +	regset->nregs = 1;
> +	regset->base = priv->base + 4 * clk->idx;
> +
> +	debugfs_create_regset32("registers", 0400, dentry, regset);
> +}
> +#else
> +#define jh7100_clk_debug_init NULL
> +#endif
> +
> +static const struct clk_ops jh7100_clk_gate_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_div_ops = {
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_fdiv_ops = {
> +	.recalc_rate = jh7100_clk_frac_recalc_rate,
> +	.determine_rate = jh7100_clk_frac_determine_rate,
> +	.set_rate = jh7100_clk_frac_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_gdiv_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_mux_ops = {
> +	.determine_rate = jh7100_clk_mux_determine_rate,
> +	.set_parent = jh7100_clk_set_parent,
> +	.get_parent = jh7100_clk_get_parent,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_gmux_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.determine_rate = jh7100_clk_mux_determine_rate,
> +	.set_parent = jh7100_clk_set_parent,
> +	.get_parent = jh7100_clk_get_parent,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_mdiv_ops = {
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.get_parent = jh7100_clk_get_parent,
> +	.set_parent = jh7100_clk_set_parent,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_gmd_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.get_parent = jh7100_clk_get_parent,
> +	.set_parent = jh7100_clk_set_parent,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_inv_ops = {
> +	.get_phase = jh7100_clk_get_phase,
> +	.set_phase = jh7100_clk_set_phase,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
> +{
> +	if (max & JH7100_CLK_DIV_MASK) {
> +		if (max & JH7100_CLK_MUX_MASK) {
> +			if (max & JH7100_CLK_ENABLE)
> +				return &jh7100_clk_gmd_ops;
> +			return &jh7100_clk_mdiv_ops;
> +		}
> +		if (max & JH7100_CLK_ENABLE)
> +			return &jh7100_clk_gdiv_ops;
> +		if (max == JH7100_CLK_FRAC_MAX)
> +			return &jh7100_clk_fdiv_ops;
> +		return &jh7100_clk_div_ops;
> +	}
> +
> +	if (max & JH7100_CLK_MUX_MASK) {
> +		if (max & JH7100_CLK_ENABLE)
> +			return &jh7100_clk_gmux_ops;
> +		return &jh7100_clk_mux_ops;
> +	}
> +
> +	if (max & JH7100_CLK_ENABLE)
> +		return &jh7100_clk_gate_ops;
> +
> +	return &jh7100_clk_inv_ops;
> +}
> +EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
> -- 
> 2.38.1
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Conor Dooley <conor@kernel.org>
To: Hal Feng <hal.feng@starfivetech.com>
Cc: linux-riscv@lists.infradead.org, devicetree@vger.kernel.org,
	linux-clk@vger.kernel.org, Palmer Dabbelt <palmer@dabbelt.com>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Stephen Boyd <sboyd@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Emil Renner Berthing <emil.renner.berthing@canonical.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 01/11] clk: starfive: Factor out common JH7100 and JH7110 code
Date: Tue, 20 Dec 2022 21:54:26 +0000	[thread overview]
Message-ID: <Y6IvEnm1Wm9KM5KO@spud> (raw)
In-Reply-To: <20221220005054.34518-2-hal.feng@starfivetech.com>


[-- Attachment #1.1: Type: text/plain, Size: 26289 bytes --]

On Tue, Dec 20, 2022 at 08:50:44AM +0800, Hal Feng wrote:
> From: Emil Renner Berthing <kernel@esmil.dk>
> 
> The clock control registers on the StarFive JH7100 and JH7110 work
> identically, so factor out the code then drivers for the two SoCs
> can share it without depending on each other. No functional change.
> 
> Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
> Signed-off-by: Hal Feng <hal.feng@starfivetech.com>

The movement does in fact appear to be just a movement..
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Thanks,
Conor.

> ---
>  MAINTAINERS                                |   4 +-
>  drivers/clk/starfive/Kconfig               |   5 +
>  drivers/clk/starfive/Makefile              |   3 +-
>  drivers/clk/starfive/clk-starfive-jh7100.c | 325 --------------------
>  drivers/clk/starfive/clk-starfive-jh7100.h |   2 +
>  drivers/clk/starfive/clk-starfive-jh71x0.c | 333 +++++++++++++++++++++
>  6 files changed, 344 insertions(+), 328 deletions(-)
>  create mode 100644 drivers/clk/starfive/clk-starfive-jh71x0.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 886d3f69ee64..fd90403c33bd 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19632,11 +19632,11 @@ M:	Emil Renner Berthing <kernel@esmil.dk>
>  S:	Maintained
>  F:	arch/riscv/boot/dts/starfive/
>  
> -STARFIVE JH7100 CLOCK DRIVERS
> +STARFIVE JH71X0 CLOCK DRIVERS
>  M:	Emil Renner Berthing <kernel@esmil.dk>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
> -F:	drivers/clk/starfive/clk-starfive-jh7100*
> +F:	drivers/clk/starfive/clk-starfive-jh71*
>  F:	include/dt-bindings/clock/starfive-jh7100*.h
>  
>  STARFIVE JH7100 PINCTRL DRIVER
> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> index 003bd2d56ce7..594d516dcb38 100644
> --- a/drivers/clk/starfive/Kconfig
> +++ b/drivers/clk/starfive/Kconfig
> @@ -1,8 +1,12 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
> +config CLK_STARFIVE_JH71X0
> +	bool
> +
>  config CLK_STARFIVE_JH7100
>  	bool "StarFive JH7100 clock support"
>  	depends on SOC_STARFIVE || COMPILE_TEST
> +	select CLK_STARFIVE_JH71X0
>  	default SOC_STARFIVE
>  	help
>  	  Say yes here to support the clock controller on the StarFive JH7100
> @@ -11,6 +15,7 @@ config CLK_STARFIVE_JH7100
>  config CLK_STARFIVE_JH7100_AUDIO
>  	tristate "StarFive JH7100 audio clock support"
>  	depends on CLK_STARFIVE_JH7100
> +	select CLK_STARFIVE_JH71X0
>  	default m if SOC_STARFIVE
>  	help
>  	  Say Y or M here to support the audio clocks on the StarFive JH7100
> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> index 0fa8ecb9ec1c..82edfa9f9cb8 100644
> --- a/drivers/clk/starfive/Makefile
> +++ b/drivers/clk/starfive/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
> -# StarFive Clock
> +obj-$(CONFIG_CLK_STARFIVE_JH71X0)	+= clk-starfive-jh71x0.o
> +
>  obj-$(CONFIG_CLK_STARFIVE_JH7100)	+= clk-starfive-jh7100.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)	+= clk-starfive-jh7100-audio.o
> diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
> index 691aeebc7092..eea52f16af0d 100644
> --- a/drivers/clk/starfive/clk-starfive-jh7100.c
> +++ b/drivers/clk/starfive/clk-starfive-jh7100.c
> @@ -7,15 +7,10 @@
>   * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
>   */
>  
> -#include <linux/bits.h>
>  #include <linux/clk-provider.h>
> -#include <linux/debugfs.h>
>  #include <linux/device.h>
>  #include <linux/init.h>
> -#include <linux/io.h>
> -#include <linux/kernel.h>
>  #include <linux/mod_devicetable.h>
> -#include <linux/module.h>
>  #include <linux/platform_device.h>
>  
>  #include <dt-bindings/clock/starfive-jh7100.h>
> @@ -269,326 +264,6 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
>  	JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
>  };
>  
> -static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
> -{
> -	return container_of(hw, struct jh7100_clk, hw);
> -}
> -
> -static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
> -{
> -	return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
> -}
> -
> -static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
> -{
> -	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> -	void __iomem *reg = priv->base + 4 * clk->idx;
> -
> -	return readl_relaxed(reg);
> -}
> -
> -static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
> -{
> -	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> -	void __iomem *reg = priv->base + 4 * clk->idx;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&priv->rmw_lock, flags);
> -	value |= readl_relaxed(reg) & ~mask;
> -	writel_relaxed(value, reg);
> -	spin_unlock_irqrestore(&priv->rmw_lock, flags);
> -}
> -
> -static int jh7100_clk_enable(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
> -	return 0;
> -}
> -
> -static void jh7100_clk_disable(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
> -}
> -
> -static int jh7100_clk_is_enabled(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -
> -	return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
> -}
> -
> -static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
> -					    unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
> -
> -	return div ? parent_rate / div : 0;
> -}
> -
> -static int jh7100_clk_determine_rate(struct clk_hw *hw,
> -				     struct clk_rate_request *req)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	unsigned long parent = req->best_parent_rate;
> -	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> -	unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
> -	unsigned long result = parent / div;
> -
> -	/*
> -	 * we want the result clamped by min_rate and max_rate if possible:
> -	 * case 1: div hits the max divider value, which means it's less than
> -	 * parent / rate, so the result is greater than rate and min_rate in
> -	 * particular. we can't do anything about result > max_rate because the
> -	 * divider doesn't go any further.
> -	 * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
> -	 * always lower or equal to rate and max_rate. however the result may
> -	 * turn out lower than min_rate, but then the next higher rate is fine:
> -	 *   div - 1 = ceil(parent / rate) - 1 < parent / rate
> -	 * and thus
> -	 *   min_rate <= rate < parent / (div - 1)
> -	 */
> -	if (result < req->min_rate && div > 1)
> -		result = parent / (div - 1);
> -
> -	req->rate = result;
> -	return 0;
> -}
> -
> -static int jh7100_clk_set_rate(struct clk_hw *hw,
> -			       unsigned long rate,
> -			       unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
> -				  1UL, (unsigned long)clk->max_div);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
> -	return 0;
> -}
> -
> -static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
> -						 unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 reg = jh7100_clk_reg_get(clk);
> -	unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
> -			       ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
> -
> -	return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
> -}
> -
> -static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
> -					  struct clk_rate_request *req)
> -{
> -	unsigned long parent100 = 100 * req->best_parent_rate;
> -	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> -	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
> -				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> -	unsigned long result = parent100 / div100;
> -
> -	/* clamp the result as in jh7100_clk_determine_rate() above */
> -	if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
> -		result = parent100 / (div100 + 1);
> -	if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
> -		result = parent100 / (div100 - 1);
> -
> -	req->rate = result;
> -	return 0;
> -}
> -
> -static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
> -				    unsigned long rate,
> -				    unsigned long parent_rate)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
> -				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> -	u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
> -	return 0;
> -}
> -
> -static u8 jh7100_clk_get_parent(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value = jh7100_clk_reg_get(clk);
> -
> -	return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
> -}
> -
> -static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
> -	return 0;
> -}
> -
> -static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
> -					 struct clk_rate_request *req)
> -{
> -	return clk_mux_determine_rate_flags(hw, req, 0);
> -}
> -
> -static int jh7100_clk_get_phase(struct clk_hw *hw)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value = jh7100_clk_reg_get(clk);
> -
> -	return (value & JH7100_CLK_INVERT) ? 180 : 0;
> -}
> -
> -static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
> -{
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	u32 value;
> -
> -	if (degrees == 0)
> -		value = 0;
> -	else if (degrees == 180)
> -		value = JH7100_CLK_INVERT;
> -	else
> -		return -EINVAL;
> -
> -	jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
> -	return 0;
> -}
> -
> -#ifdef CONFIG_DEBUG_FS
> -static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
> -{
> -	static const struct debugfs_reg32 jh7100_clk_reg = {
> -		.name = "CTRL",
> -		.offset = 0,
> -	};
> -	struct jh7100_clk *clk = jh7100_clk_from(hw);
> -	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> -	struct debugfs_regset32 *regset;
> -
> -	regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
> -	if (!regset)
> -		return;
> -
> -	regset->regs = &jh7100_clk_reg;
> -	regset->nregs = 1;
> -	regset->base = priv->base + 4 * clk->idx;
> -
> -	debugfs_create_regset32("registers", 0400, dentry, regset);
> -}
> -#else
> -#define jh7100_clk_debug_init NULL
> -#endif
> -
> -static const struct clk_ops jh7100_clk_gate_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_div_ops = {
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_fdiv_ops = {
> -	.recalc_rate = jh7100_clk_frac_recalc_rate,
> -	.determine_rate = jh7100_clk_frac_determine_rate,
> -	.set_rate = jh7100_clk_frac_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_gdiv_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_mux_ops = {
> -	.determine_rate = jh7100_clk_mux_determine_rate,
> -	.set_parent = jh7100_clk_set_parent,
> -	.get_parent = jh7100_clk_get_parent,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_gmux_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.determine_rate = jh7100_clk_mux_determine_rate,
> -	.set_parent = jh7100_clk_set_parent,
> -	.get_parent = jh7100_clk_get_parent,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_mdiv_ops = {
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.get_parent = jh7100_clk_get_parent,
> -	.set_parent = jh7100_clk_set_parent,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_gmd_ops = {
> -	.enable = jh7100_clk_enable,
> -	.disable = jh7100_clk_disable,
> -	.is_enabled = jh7100_clk_is_enabled,
> -	.recalc_rate = jh7100_clk_recalc_rate,
> -	.determine_rate = jh7100_clk_determine_rate,
> -	.get_parent = jh7100_clk_get_parent,
> -	.set_parent = jh7100_clk_set_parent,
> -	.set_rate = jh7100_clk_set_rate,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -static const struct clk_ops jh7100_clk_inv_ops = {
> -	.get_phase = jh7100_clk_get_phase,
> -	.set_phase = jh7100_clk_set_phase,
> -	.debug_init = jh7100_clk_debug_init,
> -};
> -
> -const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
> -{
> -	if (max & JH7100_CLK_DIV_MASK) {
> -		if (max & JH7100_CLK_MUX_MASK) {
> -			if (max & JH7100_CLK_ENABLE)
> -				return &jh7100_clk_gmd_ops;
> -			return &jh7100_clk_mdiv_ops;
> -		}
> -		if (max & JH7100_CLK_ENABLE)
> -			return &jh7100_clk_gdiv_ops;
> -		if (max == JH7100_CLK_FRAC_MAX)
> -			return &jh7100_clk_fdiv_ops;
> -		return &jh7100_clk_div_ops;
> -	}
> -
> -	if (max & JH7100_CLK_MUX_MASK) {
> -		if (max & JH7100_CLK_ENABLE)
> -			return &jh7100_clk_gmux_ops;
> -		return &jh7100_clk_mux_ops;
> -	}
> -
> -	if (max & JH7100_CLK_ENABLE)
> -		return &jh7100_clk_gate_ops;
> -
> -	return &jh7100_clk_inv_ops;
> -}
> -EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
> -
>  static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
>  {
>  	struct jh7100_clk_priv *priv = data;
> diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh7100.h
> index f116be5740a5..a8ba6e25b5ce 100644
> --- a/drivers/clk/starfive/clk-starfive-jh7100.h
> +++ b/drivers/clk/starfive/clk-starfive-jh7100.h
> @@ -4,6 +4,8 @@
>  
>  #include <linux/bits.h>
>  #include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/spinlock.h>
>  
>  /* register fields */
>  #define JH7100_CLK_ENABLE	BIT(31)
> diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
> new file mode 100644
> index 000000000000..6c07b61b4a32
> --- /dev/null
> +++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * StarFive JH7100 Clock Generator Driver
> + *
> + * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/debugfs.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +
> +#include "clk-starfive-jh7100.h"
> +
> +static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
> +{
> +	return container_of(hw, struct jh7100_clk, hw);
> +}
> +
> +static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
> +{
> +	return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
> +}
> +
> +static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
> +{
> +	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> +	void __iomem *reg = priv->base + 4 * clk->idx;
> +
> +	return readl_relaxed(reg);
> +}
> +
> +static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
> +{
> +	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> +	void __iomem *reg = priv->base + 4 * clk->idx;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&priv->rmw_lock, flags);
> +	value |= readl_relaxed(reg) & ~mask;
> +	writel_relaxed(value, reg);
> +	spin_unlock_irqrestore(&priv->rmw_lock, flags);
> +}
> +
> +static int jh7100_clk_enable(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
> +	return 0;
> +}
> +
> +static void jh7100_clk_disable(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
> +}
> +
> +static int jh7100_clk_is_enabled(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +
> +	return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
> +}
> +
> +static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
> +					    unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
> +
> +	return div ? parent_rate / div : 0;
> +}
> +
> +static int jh7100_clk_determine_rate(struct clk_hw *hw,
> +				     struct clk_rate_request *req)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	unsigned long parent = req->best_parent_rate;
> +	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> +	unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
> +	unsigned long result = parent / div;
> +
> +	/*
> +	 * we want the result clamped by min_rate and max_rate if possible:
> +	 * case 1: div hits the max divider value, which means it's less than
> +	 * parent / rate, so the result is greater than rate and min_rate in
> +	 * particular. we can't do anything about result > max_rate because the
> +	 * divider doesn't go any further.
> +	 * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
> +	 * always lower or equal to rate and max_rate. however the result may
> +	 * turn out lower than min_rate, but then the next higher rate is fine:
> +	 *   div - 1 = ceil(parent / rate) - 1 < parent / rate
> +	 * and thus
> +	 *   min_rate <= rate < parent / (div - 1)
> +	 */
> +	if (result < req->min_rate && div > 1)
> +		result = parent / (div - 1);
> +
> +	req->rate = result;
> +	return 0;
> +}
> +
> +static int jh7100_clk_set_rate(struct clk_hw *hw,
> +			       unsigned long rate,
> +			       unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
> +				  1UL, (unsigned long)clk->max_div);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
> +	return 0;
> +}
> +
> +static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
> +						 unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 reg = jh7100_clk_reg_get(clk);
> +	unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
> +			       ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
> +
> +	return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
> +}
> +
> +static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
> +					  struct clk_rate_request *req)
> +{
> +	unsigned long parent100 = 100 * req->best_parent_rate;
> +	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
> +	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
> +				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> +	unsigned long result = parent100 / div100;
> +
> +	/* clamp the result as in jh7100_clk_determine_rate() above */
> +	if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
> +		result = parent100 / (div100 + 1);
> +	if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
> +		result = parent100 / (div100 - 1);
> +
> +	req->rate = result;
> +	return 0;
> +}
> +
> +static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
> +				    unsigned long rate,
> +				    unsigned long parent_rate)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
> +				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
> +	u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
> +	return 0;
> +}
> +
> +static u8 jh7100_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value = jh7100_clk_reg_get(clk);
> +
> +	return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
> +}
> +
> +static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
> +	return 0;
> +}
> +
> +static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
> +					 struct clk_rate_request *req)
> +{
> +	return clk_mux_determine_rate_flags(hw, req, 0);
> +}
> +
> +static int jh7100_clk_get_phase(struct clk_hw *hw)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value = jh7100_clk_reg_get(clk);
> +
> +	return (value & JH7100_CLK_INVERT) ? 180 : 0;
> +}
> +
> +static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
> +{
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	u32 value;
> +
> +	if (degrees == 0)
> +		value = 0;
> +	else if (degrees == 180)
> +		value = JH7100_CLK_INVERT;
> +	else
> +		return -EINVAL;
> +
> +	jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
> +{
> +	static const struct debugfs_reg32 jh7100_clk_reg = {
> +		.name = "CTRL",
> +		.offset = 0,
> +	};
> +	struct jh7100_clk *clk = jh7100_clk_from(hw);
> +	struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
> +	struct debugfs_regset32 *regset;
> +
> +	regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
> +	if (!regset)
> +		return;
> +
> +	regset->regs = &jh7100_clk_reg;
> +	regset->nregs = 1;
> +	regset->base = priv->base + 4 * clk->idx;
> +
> +	debugfs_create_regset32("registers", 0400, dentry, regset);
> +}
> +#else
> +#define jh7100_clk_debug_init NULL
> +#endif
> +
> +static const struct clk_ops jh7100_clk_gate_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_div_ops = {
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_fdiv_ops = {
> +	.recalc_rate = jh7100_clk_frac_recalc_rate,
> +	.determine_rate = jh7100_clk_frac_determine_rate,
> +	.set_rate = jh7100_clk_frac_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_gdiv_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_mux_ops = {
> +	.determine_rate = jh7100_clk_mux_determine_rate,
> +	.set_parent = jh7100_clk_set_parent,
> +	.get_parent = jh7100_clk_get_parent,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_gmux_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.determine_rate = jh7100_clk_mux_determine_rate,
> +	.set_parent = jh7100_clk_set_parent,
> +	.get_parent = jh7100_clk_get_parent,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_mdiv_ops = {
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.get_parent = jh7100_clk_get_parent,
> +	.set_parent = jh7100_clk_set_parent,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_gmd_ops = {
> +	.enable = jh7100_clk_enable,
> +	.disable = jh7100_clk_disable,
> +	.is_enabled = jh7100_clk_is_enabled,
> +	.recalc_rate = jh7100_clk_recalc_rate,
> +	.determine_rate = jh7100_clk_determine_rate,
> +	.get_parent = jh7100_clk_get_parent,
> +	.set_parent = jh7100_clk_set_parent,
> +	.set_rate = jh7100_clk_set_rate,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +static const struct clk_ops jh7100_clk_inv_ops = {
> +	.get_phase = jh7100_clk_get_phase,
> +	.set_phase = jh7100_clk_set_phase,
> +	.debug_init = jh7100_clk_debug_init,
> +};
> +
> +const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
> +{
> +	if (max & JH7100_CLK_DIV_MASK) {
> +		if (max & JH7100_CLK_MUX_MASK) {
> +			if (max & JH7100_CLK_ENABLE)
> +				return &jh7100_clk_gmd_ops;
> +			return &jh7100_clk_mdiv_ops;
> +		}
> +		if (max & JH7100_CLK_ENABLE)
> +			return &jh7100_clk_gdiv_ops;
> +		if (max == JH7100_CLK_FRAC_MAX)
> +			return &jh7100_clk_fdiv_ops;
> +		return &jh7100_clk_div_ops;
> +	}
> +
> +	if (max & JH7100_CLK_MUX_MASK) {
> +		if (max & JH7100_CLK_ENABLE)
> +			return &jh7100_clk_gmux_ops;
> +		return &jh7100_clk_mux_ops;
> +	}
> +
> +	if (max & JH7100_CLK_ENABLE)
> +		return &jh7100_clk_gate_ops;
> +
> +	return &jh7100_clk_inv_ops;
> +}
> +EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
> -- 
> 2.38.1
> 
> 

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 161 bytes --]

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2022-12-20 21:54 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-20  0:50 [PATCH v3 00/11] Basic clock and reset support for StarFive JH7110 RISC-V SoC Hal Feng
2022-12-20  0:50 ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 01/11] clk: starfive: Factor out common JH7100 and JH7110 code Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 21:54   ` Conor Dooley [this message]
2022-12-20 21:54     ` Conor Dooley
2022-12-20  0:50 ` [PATCH v3 02/11] clk: starfive: Rename "jh7100" to "jh71x0" for the common code Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 22:08   ` Conor Dooley
2022-12-20 22:08     ` Conor Dooley
2022-12-23  6:23     ` Hal Feng
2022-12-23  6:23       ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 03/11] reset: Create subdirectory for StarFive drivers Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 22:15   ` Conor Dooley
2022-12-20 22:15     ` Conor Dooley
2022-12-23  7:02     ` Hal Feng
2022-12-23  7:02       ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 04/11] reset: starfive: Factor out common JH71X0 reset code Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 22:28   ` Conor Dooley
2022-12-20 22:28     ` Conor Dooley
2022-12-23  7:49     ` Hal Feng
2022-12-23  7:49       ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 05/11] reset: starfive: Rename "jh7100" to "jh71x0" for the common code Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20  2:40   ` kernel test robot
2022-12-20  2:40     ` kernel test robot
2022-12-20 22:31   ` Conor Dooley
2022-12-20 22:31     ` Conor Dooley
2022-12-24  3:48   ` kernel test robot
2022-12-24  3:48     ` kernel test robot
2022-12-20  0:50 ` [PATCH v3 06/11] reset: starfive: jh71x0: Use 32bit I/O on 32bit registers Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 22:49   ` Conor Dooley
2022-12-20 22:49     ` Conor Dooley
2022-12-20  0:50 ` [PATCH v3 07/11] dt-bindings: clock: Add StarFive JH7110 system clock and reset generator Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 20:12   ` Rob Herring
2022-12-20 20:12     ` Rob Herring
2022-12-20 23:14   ` Conor Dooley
2022-12-20 23:14     ` Conor Dooley
2022-12-20 23:16     ` Conor Dooley
2022-12-20 23:16       ` Conor Dooley
2022-12-25 16:26     ` Hal Feng
2022-12-25 16:26       ` Hal Feng
2022-12-27 20:15       ` Conor Dooley
2022-12-27 20:15         ` Conor Dooley
2023-02-16 14:42         ` Hal Feng
2023-02-16 14:42           ` Hal Feng
2023-02-16 18:20           ` Conor Dooley
2023-02-16 18:20             ` Conor Dooley
2023-02-17  2:27             ` Hal Feng
2023-02-17  2:27               ` Hal Feng
2023-02-17  7:51               ` Conor Dooley
2023-02-17  7:51                 ` Conor Dooley
2023-02-17 12:20                 ` Hal Feng
2023-02-17 12:20                   ` Hal Feng
2023-02-17 13:32                   ` Conor Dooley
2023-02-17 13:32                     ` Conor Dooley
2023-02-17 15:47                     ` Krzysztof Kozlowski
2023-02-17 15:47                       ` Krzysztof Kozlowski
2023-02-17 16:27                       ` Conor Dooley
2023-02-17 16:27                         ` Conor Dooley
2023-02-18 10:20                         ` Krzysztof Kozlowski
2023-02-18 10:20                           ` Krzysztof Kozlowski
2023-02-18 11:17                           ` Conor Dooley
2023-02-18 11:17                             ` Conor Dooley
2023-02-18 14:55                             ` Krzysztof Kozlowski
2023-02-18 14:55                               ` Krzysztof Kozlowski
2023-02-18 15:08                               ` Conor Dooley
2023-02-18 15:08                                 ` Conor Dooley
2023-02-21 22:17             ` Stephen Boyd
2023-02-21 22:17               ` Stephen Boyd
2023-02-21 23:39               ` Conor Dooley
2023-02-21 23:39                 ` Conor Dooley
2023-02-22 13:27                 ` Hal Feng
2023-02-22 13:27                   ` Hal Feng
2023-02-22 16:26                   ` Conor Dooley
2023-02-22 16:26                     ` Conor Dooley
2023-02-23  3:03                     ` Hal Feng
2023-02-23  3:03                       ` Hal Feng
2023-02-23  6:18                       ` Conor Dooley
2023-02-23  6:18                         ` Conor Dooley
2023-02-23  9:52                         ` Hal Feng
2023-02-23  9:52                           ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 08/11] dt-bindings: clock: Add StarFive JH7110 always-on " Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20 20:14   ` Rob Herring
2022-12-20 20:14     ` Rob Herring
2022-12-20 23:19   ` Conor Dooley
2022-12-20 23:19     ` Conor Dooley
2023-02-16 17:19     ` Hal Feng
2023-02-16 17:19       ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 09/11] clk: starfive: Add StarFive JH7110 system clock driver Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-23  9:57   ` kernel test robot
2022-12-23  9:57     ` kernel test robot
2023-01-05 11:32   ` kernel test robot
2023-01-05 11:32     ` kernel test robot
2023-02-19 21:23   ` Emil Renner Berthing
2023-02-19 21:23     ` Emil Renner Berthing
2023-02-21  6:44     ` Hal Feng
2023-02-21  6:44       ` Hal Feng
2022-12-20  0:50 ` [PATCH v3 10/11] clk: starfive: Add StarFive JH7110 always-on " Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-23 11:28   ` kernel test robot
2022-12-23 11:28     ` kernel test robot
2023-01-05 13:44   ` kernel test robot
2023-01-05 13:44     ` kernel test robot
2022-12-20  0:50 ` [PATCH v3 11/11] reset: starfive: Add StarFive JH7110 reset driver Hal Feng
2022-12-20  0:50   ` Hal Feng
2022-12-20  7:14   ` kernel test robot
2022-12-20  7:14     ` kernel test robot
2022-12-23 12:39   ` kernel test robot
2022-12-23 12:39     ` kernel test robot
2022-12-27 19:20   ` kernel test robot
2022-12-27 19:20     ` kernel test robot
2023-01-05 15:35   ` kernel test robot
2023-01-05 15:35     ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y6IvEnm1Wm9KM5KO@spud \
    --to=conor@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=emil.renner.berthing@canonical.com \
    --cc=hal.feng@starfivetech.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=mturquette@baylibre.com \
    --cc=p.zabel@pengutronix.de \
    --cc=palmer@dabbelt.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.