All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Anderson <seanga2@gmail.com>
To: u-boot@lists.denx.de
Cc: Lukasz Majewski <lukma@denx.de>,
	Leo Liang <ycliang@andestech.com>,
	Damien Le Moal <Damien.LeMoal@wdc.com>
Subject: Re: [PATCH v2 05/11] clk: k210: Re-add support for setting rate
Date: Fri, 4 Jun 2021 00:17:52 -0400	[thread overview]
Message-ID: <2f0797cb-8117-e717-1dd1-90fd3ebbd3e1@gmail.com> (raw)
In-Reply-To: <20210604035834.625772-6-seanga2@gmail.com>

On 6/3/21 11:58 PM, Sean Anderson wrote:
> This adds support for setting clock rates, which was left out of the
> initial CCF expunging. There are several tricky bits here, mostly related
> to the PLLS:
> 
> * The PLL's bypass is broken. If the PLL is reconfigured, any child clocks
>    will be stopped.
> * PLL0 is the parent of ACLK which is the CPU and SRAM's clock. To prevent
>    stopping the CPU while we configure PLL0's rate, ACLK is reparented
>    to IN0 while PLL0 is disabled.
> * PLL1 is the parent of the AISRAM clock. This clock cannot be reparented,
>    so we instead just disallow changing PLL1's rate after relocation (when
>    we are using the AISRAM).
> 
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> ---
> 
> Changes in v2:
> - Only force probe clocks pre-reloc
> 
>   drivers/clk/kendryte/clk.c | 89 +++++++++++++++++++++++++++++++++++---
>   1 file changed, 84 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c
> index 203d5f741c..a1742eb856 100644
> --- a/drivers/clk/kendryte/clk.c
> +++ b/drivers/clk/kendryte/clk.c
> @@ -17,6 +17,8 @@
>   #include <kendryte/pll.h>
>   #include <linux/bitfield.h>
>   
> +DECLARE_GLOBAL_DATA_PTR;
> +
>   /**
>    * struct k210_clk_priv - K210 clock driver private data
>    * @base: The base address of the sysctl device
> @@ -1059,11 +1061,6 @@ static ulong k210_clk_get_rate(struct clk *clk)
>   	return do_k210_clk_get_rate(dev_get_priv(clk->dev), clk->id);
>   }
>   
> -static ulong k210_clk_set_rate(struct clk *clk, unsigned long rate)
> -{
> -	return -ENOSYS;
> -}
> -
>   static int do_k210_clk_set_parent(struct k210_clk_priv *priv, int id, int new)
>   {
>   	int i;
> @@ -1089,6 +1086,81 @@ static int k210_clk_set_parent(struct clk *clk, struct clk *parent)
>   				      parent->id);
>   }
>   
> +static ulong k210_clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> +	int parent, ret, err;
> +	ulong rate_in, val;
> +	const struct k210_div_params *div;
> +	struct k210_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +	if (clk->id == K210_CLK_IN0)
> +		return clk_set_rate(&priv->in0, rate);
> +
> +	parent = k210_clk_get_parent(priv, clk->id);
> +	rate_in = do_k210_clk_get_rate(priv, parent);
> +
> +	log_debug("id=%ld rate=%lu rate_in=%lu\n", clk->id, rate, rate_in);
> +
> +	if (clk->id == K210_CLK_PLL0) {
> +		/* Bypass ACLK so the CPU keeps going */
> +		ret = do_k210_clk_set_parent(priv, K210_CLK_ACLK, K210_CLK_IN0);
> +		if (ret)
> +			return ret;
> +	} else if (clk->id == K210_CLK_PLL1 && gd->flags & GD_FLG_RELOC) {
> +		/*
> +		 * We can't bypass the AI clock like we can ACLK, and after
> +		 * relocation we are using the AI ram.
> +		 */
> +		return -EPERM;
> +	}
> +
> +	if (k210_clks[clk->id].flags & K210_CLKF_PLL) {
> +		ret = k210_pll_set_rate(priv, k210_clks[clk->id].pll, rate,
> +					rate_in);
> +		if (!IS_ERR_VALUE(ret) && clk->id == K210_CLK_PLL0) {
> +			/*
> +			 * This may have the side effect of reparenting ACLK,
> +			 * but I don't really want to keep track of what the old
> +			 * parent was.
> +			 */
> +			err = do_k210_clk_set_parent(priv, K210_CLK_ACLK,
> +						     K210_CLK_PLL0);
> +			if (err)
> +				return err;
> +		}
> +		return ret;
> +	}
> +
> +	if (k210_clks[clk->id].div == K210_CLK_DIV_NONE)
> +		return -ENOSYS;
> +	div = &k210_divs[k210_clks[clk->id].div];
> +
> +	switch (div->type) {
> +	case K210_DIV_ONE:
> +		val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, rate);
> +		val = val ? val - 1 : 0;
> +		break;
> +	case K210_DIV_EVEN:
> +		val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, 2 * rate);
> +		break;
> +	case K210_DIV_POWER:
> +		/* This is ACLK, which has no divider on IN0 */
> +		if (parent == K210_CLK_IN0)
> +			return -ENOSYS;
> +
> +		DIV_ROUND_CLOSEST_ULL((u64)rate_in, rate);
> +		val = __ffs(val);
> +		break;
> +	default:
> +		assert(false);
> +		return -EINVAL;
> +	};
> +
> +	val = val ? val - 1 : 0;
> +	k210_clk_writel(priv, div->off, div->shift, div->width, val);
> +	return do_k210_clk_get_rate(priv, clk->id);
> +}
> +
>   static int k210_clk_endisable(struct k210_clk_priv *priv, int id, bool enable)
>   {
>   	int parent = k210_clk_get_parent(priv, id);
> @@ -1163,6 +1235,13 @@ static int k210_clk_probe(struct udevice *dev)
>   	if (ret)
>   		return ret;
>   
> +	/*
> +	 * Force setting defaults, even before relocation. This is so we can
> +	 * set the clock rate for PLL1 before we relocate into aisram.
> +	 */
> +	if (gd->flags & GD_FLG_RELOC)

The polarity of this if is inverted, should be if (!(...))

> +		clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE);
> +
>   	return 0;
>   }
>   
> 


  reply	other threads:[~2021-06-04  4:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-04  3:58 [PATCH v2 00/11] clk: k210: Rewrite K210 clock without CCF Sean Anderson
2021-06-04  3:58 ` [PATCH v2 01/11] clk: Allow force setting clock defaults before relocation Sean Anderson
2021-06-04  3:58 ` [PATCH v2 02/11] clk: k210: Rewrite to remove CCF Sean Anderson
2021-06-04  3:58 ` [PATCH v2 03/11] clk: k210: Move pll into the rest of the driver Sean Anderson
2021-06-04  3:58 ` [PATCH v2 04/11] clk: k210: Implement soc_clk_dump Sean Anderson
2021-06-04  3:58 ` [PATCH v2 05/11] clk: k210: Re-add support for setting rate Sean Anderson
2021-06-04  4:17   ` Sean Anderson [this message]
2021-06-04  3:58 ` [PATCH v2 06/11] clk: k210: Don't set PLL rates if we are already at the correct rate Sean Anderson
2021-06-04  3:58 ` [PATCH v2 07/11] clk: k210: Remove bypass driver Sean Anderson
2021-06-04  3:58 ` [PATCH v2 08/11] clk: k210: Move k210 clock out of its own subdirectory Sean Anderson
2021-06-04  3:58 ` [PATCH v2 09/11] k210: dts: Set PLL1 to the same rate as PLL0 Sean Anderson
2021-06-04  3:58 ` [PATCH v2 10/11] k210: Don't imply CCF Sean Anderson
2021-06-04  3:58 ` [PATCH v2 11/11] test: Add K210 PLL tests to sandbox defconfigs Sean Anderson
2021-06-04  4:28 ` [PATCH v2 00/11] clk: k210: Rewrite K210 clock without CCF Damien Le Moal
2021-06-04  4:40   ` Sean Anderson
2021-06-10 18:00 ` Leo Liang

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=2f0797cb-8117-e717-1dd1-90fd3ebbd3e1@gmail.com \
    --to=seanga2@gmail.com \
    --cc=Damien.LeMoal@wdc.com \
    --cc=lukma@denx.de \
    --cc=u-boot@lists.denx.de \
    --cc=ycliang@andestech.com \
    /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.