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;
> }
>
>
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox