[PATCH v2] clk: sunxi: Refactor A31 PLL6 so that it can be reused
Chen-Yu Tsai
wens at csie.org
Thu Nov 26 01:19:23 PST 2015
Hi,
On Thu, Nov 26, 2015 at 4:58 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> Remove the fixed dividers from the PLL6 driver to be able to have a
> reusable driver that can be used across several SoCs that share the same
> controller, but don't have the same set of dividers for this clock, and to
> also be reused multiple times in the same SoC, since we're droping the
> clock name.
>
> Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> ---
> Hi Jens,
>
> Here is an alternative (untested) patch to deal with the PLL6 issue you're
> experiencing with the H3.
>
> It doesn't rely on parsing clock-output-names that turns out to be pretty
> fragile.
>
> Let me know what you think,
> Maxime
>
> Changes from v1:
> - Make the pll6 clock the /2 output, and add a multiplier for the
> non-divided output
>
> arch/arm/boot/dts/sun6i-a31.dtsi | 36 ++++++++++++++++++------------------
> arch/arm/boot/dts/sun8i-a23-a33.dtsi | 25 +++++++++++++++++--------
> arch/arm/boot/dts/sun8i-a23.dtsi | 2 +-
> arch/arm/boot/dts/sun8i-a33.dtsi | 4 ++--
> drivers/clk/sunxi/clk-sunxi.c | 24 +++++++-----------------
> 5 files changed, 45 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 9c79af0c03b2..d6cb1e467bd5 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -456,9 +456,9 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
> }
>
> /**
> - * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2
> - * PLL6x2 rate is calculated as follows
> - * rate = parent_rate * (n + 1) * (k + 1)
> + * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6
> + * PLL6 rate is calculated as follows
> + * rate = parent_rate * (n + 1) * (k + 1) / 2
> * parent_rate is always 24Mhz
> */
>
> @@ -467,9 +467,9 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
> {
> u8 div;
>
> - /* Normalize value to a parent_rate multiple (24M) */
> - div = *freq / parent_rate;
> - *freq = parent_rate * div;
> + /* Normalize value to a parent_rate multiple (24M / 2) */
> + div = *freq / (parent_rate / 2);
> + *freq = (parent_rate / 2) * div;
This doesn't work with clk_factors_recalc_rate(). You'd get the wrong
clock rate read back. What you're doing here is no different than the
first incarnation of sun6i PLL6 driver in 92ef67c53ad9 ("clk: sunxi:
Add support for PLL6 on the A31"). The kernel readout of the clock
rate was wrong by a factor of 2.
I mentioned some while back that it may make sense to have a custom
.recalc_rate callback for some factor clocks with non-standard
formulas.
For this particular case you could just add a .post_div field
to factors_clk, and deal with it there.
Regards
ChenYu
>
> /* we were called to round the frequency, we can now return */
> if (n == NULL)
> @@ -718,7 +718,6 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = {
> .enable = 31,
> .table = &sun6i_a31_pll6_config,
> .getter = sun6i_a31_get_pll6_factors,
> - .name = "pll6x2",
> };
>
> static const struct factors_data sun5i_a13_ahb_data __initconst = {
> @@ -951,15 +950,6 @@ static const struct divs_data pll6_divs_data __initconst = {
> }
> };
>
> -static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
> - .factors = &sun6i_a31_pll6_data,
> - .ndivs = 2,
> - .div = {
> - { .fixed = 2 }, /* normal output */
> - { .self = 1 }, /* base factor clock, 2x */
> - }
> -};
> -
> /**
> * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
> *
> @@ -1101,6 +1091,7 @@ free_clkdata:
> static const struct of_device_id clk_factors_match[] __initconst = {
> {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,},
> {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
> + {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
> {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,},
> {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
> {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
> @@ -1122,7 +1113,6 @@ static const struct of_device_id clk_div_match[] __initconst = {
> static const struct of_device_id clk_divs_match[] __initconst = {
> {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,},
> {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,},
> - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,},
> {}
> };
>
> --
> 2.6.3
>
More information about the linux-arm-kernel
mailing list