From: Alban <albeu@free.fr>
To: Antony Pavlov <antonynpavlov@gmail.com>
Cc: Aban Bedel <albeu@free.fr>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@codeaurora.org>,
linux-clk@vger.kernel.org
Subject: Re: [RFC] [RESEND] MIPS: ath79: update devicetree clock support for AR9132
Date: Thu, 18 Feb 2016 13:40:53 +0100 [thread overview]
Message-ID: <20160218134053.41e4956f@tock> (raw)
In-Reply-To: <1455618598-24415-1-git-send-email-antonynpavlov@gmail.com>
On Tue, 16 Feb 2016 13:29:58 +0300
Antony Pavlov <antonynpavlov@gmail.com> wrote:
> Current ath79 clock.c code does not read reference clock and
> pll setup from devicetree. E.g. you can set any clock rate value
> in board DTS but it will have no effect on the real clk calculation.
>
> This patch fixes some AR9132 devicetree clock support deffects:
>
> * clk initialization function ath79_clocks_init_dt_ng()
> is introduced; it actually gets reference clock
> and pll block base register address from devicetree;
> * pll register parsing code moved to the separate
> ar724x_clk_init() function; this function
> can be called from platform code or from devicetree code;
> * introduces include/dt-bindings/clock/ath79-clk.h,
> so we can use human-readable macro for clks naming;
>
> The same approach can be used for adding AR9331 devicetree support.
>
> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
> ---
> arch/mips/ath79/clock.c | 130 +++++++++++++++++++++++++++-------
> arch/mips/boot/dts/qca/ar9132.dtsi | 8 ++-
> include/dt-bindings/clock/ath79-clk.h | 20 ++++++
> 3 files changed, 130 insertions(+), 28 deletions(-)
> create mode 100644 include/dt-bindings/clock/ath79-clk.h
>
> diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
> index 618dfd7..58ba7d7 100644
> --- a/arch/mips/ath79/clock.c
> +++ b/arch/mips/ath79/clock.c
> @@ -18,12 +18,16 @@
> #include <linux/clk.h>
> #include <linux/clkdev.h>
> #include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <dt-bindings/clock/ath79-clk.h>
>
> #include <asm/div64.h>
>
> #include <asm/mach-ath79/ath79.h>
> #include <asm/mach-ath79/ar71xx_regs.h>
> #include "common.h"
> +#include "machtypes.h"
>
> #define AR71XX_BASE_FREQ 40000000
> #define AR724X_BASE_FREQ 40000000
> @@ -86,37 +90,66 @@ static void __init ar71xx_clocks_init(void)
> clk_add_alias("uart", NULL, "ahb", NULL);
> }
>
> -static void __init ar724x_clocks_init(void)
> +static struct clk *clks_ng[ATH79_CLK_END];
> +static struct clk_onecell_data clk_data_ng = {
> + .clks = clks_ng,
> + .clk_num = ARRAY_SIZE(clks_ng),
> +};
I don't think this new array is needed.
> +static struct clk * __init ath79_reg_ffclk(const char *name,
> + const char *parent_name, unsigned int mult, unsigned int div)
> {
> - unsigned long ref_rate;
> - unsigned long cpu_rate;
> - unsigned long ddr_rate;
> - unsigned long ahb_rate;
> - u32 pll;
> - u32 freq;
> - u32 div;
> + struct clk *clk;
> + int err;
> +
> + clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
> + if (!clk)
> + panic("failed to allocate %s clock structure", name);
>
> - ref_rate = AR724X_BASE_FREQ;
> - pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
> + /*
> + * dt-enabled linux does not need clk_register_clkdev()
> + * but it makes happy plat_time_init() from arch/mips/ath79/setup.c
> + */
> + err = clk_register_clkdev(clk, name, NULL);
> + if (err)
> + panic("unable to register %s clock device", name);
I would prefer to get rid of the clk_register_clkdev(). Either we drop
the clocks banner for DT boards or we implement it differently.
> - div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
> - freq = div * ref_rate;
> + return clk;
> +}
>
> +static struct clk_onecell_data * __init ar724x_clk_init(
> + struct clk *ref_clk, void __iomem *pll_base)
> +{
> + u32 pll;
> + u32 mult, div, ddr_div, ahb_div;
> +
> + pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
> +
> + mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
> div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
> - freq /= div;
>
> - cpu_rate = freq;
> + ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
> + ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
>
> - div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
> - ddr_rate = freq / div;
> + clks_ng[ATH79_CLK_REF] = ref_clk;
> + clks_ng[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div);
> + clks_ng[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div);
> + clks_ng[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div);
>
> - div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
> - ahb_rate = cpu_rate / div;
> + return &clk_data_ng;
> +}
>
> - ath79_add_sys_clkdev("ref", ref_rate);
> - clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
> - clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
> - clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
> +static void __init ar724x_clocks_init(void)
> +{
> + struct clk *ref_clk;
> + struct clk_onecell_data *clk_data;
> +
> + ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ);
> +
> + clk_data = ar724x_clk_init(ref_clk, ath79_pll_base);
> +
> + /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
> + clk_register_clkdev(clk_data->clks[ATH79_CLK_REF], "ref", NULL);
>
> clk_add_alias("wdt", NULL, "ahb", NULL);
> clk_add_alias("uart", NULL, "ahb", NULL);
> @@ -407,6 +440,11 @@ static void __init qca955x_clocks_init(void)
>
> void __init ath79_clocks_init(void)
> {
> + if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) {
> + of_clk_init(NULL);
> + return;
> + }
> +
This should only be done for the SoCs that have an "ng" implementation.
> if (soc_is_ar71xx())
> ar71xx_clocks_init();
> else if (soc_is_ar724x() || soc_is_ar913x())
> @@ -419,8 +457,6 @@ void __init ath79_clocks_init(void)
> qca955x_clocks_init();
> else
> BUG();
> -
> - of_clk_init(NULL);
> }
>
> unsigned long __init
> @@ -447,8 +483,52 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
>
> CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
> CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
> -CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt);
> CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt);
> CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
> CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
> +
> +static void __init ath79_clocks_init_dt_ng(struct device_node *np)
> +{
> + struct clk *ref_clk;
> + void __iomem *pll_base;
> + struct clk_onecell_data *clk_data;
> +
> + ref_clk = of_clk_get(np, 0);
> + if (IS_ERR(ref_clk)) {
> + pr_err("%s: of_clk_get failed\n", np->full_name);
Use of_node_full_name().
> + goto err;
> + }
> +
> + pll_base = of_iomap(np, 0);
> + if (!pll_base) {
> + pr_err("%s: can't map pll registers\n", np->full_name);
> + goto err_clk;
> + }
> +
> + clk_data = ar724x_clk_init(ref_clk, pll_base);
> + if (!clk_data) {
> + pr_err("%s: clk_init failed\n", np->full_name);
> + goto err_clk;
> + }
> +
> + if (of_clk_add_provider(np, of_clk_src_onecell_get, clk_data)) {
> + pr_err("%s: could not register clk provider\n", np->full_name);
> + goto err_clk;
> + }
> +
> + /*
> + * dt-enabled linux does not need clk_register_clkdev()
> + * but it makes happy plat_time_init() from arch/mips/ath79/setup.c
> + */
> + clk_register_clkdev(clk_data->clks[ATH79_CLK_REF], "ref", NULL);
Like above it would be nice to get rid of the clk_register_clkdev().
> + return;
> +
> +err_clk:
> + clk_put(ref_clk);
> +
> +err:
> + return;
> +}
> +CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng);
> #endif
> diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi
> index 511cb4d..fb844b8 100644
> --- a/arch/mips/boot/dts/qca/ar9132.dtsi
> +++ b/arch/mips/boot/dts/qca/ar9132.dtsi
> @@ -1,3 +1,5 @@
> +#include <dt-bindings/clock/ath79-clk.h>
> +
> / {
> compatible = "qca,ar9132";
>
> @@ -57,7 +59,7 @@
> reg = <0x18020000 0x20>;
> interrupts = <3>;
>
> - clocks = <&pll 2>;
> + clocks = <&pll ATH79_CLK_AHB>;
> clock-names = "uart";
>
> reg-io-width = <4>;
> @@ -100,7 +102,7 @@
>
> interrupts = <4>;
>
> - clocks = <&pll 2>;
> + clocks = <&pll ATH79_CLK_AHB>;
> clock-names = "wdt";
> };
>
> @@ -144,7 +146,7 @@
> compatible = "qca,ar9132-spi", "qca,ar7100-spi";
> reg = <0x1f000000 0x10>;
>
> - clocks = <&pll 2>;
> + clocks = <&pll ATH79_CLK_AHB>;
> clock-names = "ahb";
>
> status = "disabled";
> diff --git a/include/dt-bindings/clock/ath79-clk.h b/include/dt-bindings/clock/ath79-clk.h
> new file mode 100644
> index 0000000..af64e36
> --- /dev/null
> +++ b/include/dt-bindings/clock/ath79-clk.h
> @@ -0,0 +1,20 @@
> +/*
> + * Copyright (C) 2014, 2016 Antony Pavlov <antonynpavlov@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#ifndef __DT_BINDINGS_ATH79_CLK_H
> +#define __DT_BINDINGS_ATH79_CLK_H
> +
> +#define ATH79_CLK_REF 0
> +#define ATH79_CLK_CPU 1
> +#define ATH79_CLK_DDR 2
> +#define ATH79_CLK_AHB 3
To renumber the clocks we would need to modify the DT binding, but I
still fail to see why that would be needed. The PLL block doesn't
output the reference clock, and we already have that clock, so why is
this change needed?
> +#define ATH79_CLK_END 4
> +
> +#endif /* __DT_BINDINGS_ATH79_CLK_H */
Adding the header and using the defines in the DTS should be in a
separate patch.
Alban
prev parent reply other threads:[~2016-02-18 12:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-16 10:29 [RFC] [RESEND] MIPS: ath79: update devicetree clock support for AR9132 Antony Pavlov
2016-02-18 12:40 ` Alban [this message]
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=20160218134053.41e4956f@tock \
--to=albeu@free.fr \
--cc=antonynpavlov@gmail.com \
--cc=linux-clk@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=sboyd@codeaurora.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).