2018-05-15 16:37:51

by Jerome Brunet

[permalink] [raw]
Subject: [PATCH v2 0/2] clk: meson: mpll: add round closest support

ATM, the mpll driver can only round the requested rate down, even if
rounding up would have provided a better approximation of the requested
rate.

This patchset adds a flag to enable rounding to the closest rate possible,
even if it means rounding up.

The flag is then enabled on the axg platform to improve the rates provided
to the audio subsystem.

Changes since v1: [0]
* Fix an error in calculation while rounding the rate down
(Thanks Martin for reporting it)

[0]: https://lkml.kernel.org/r/[email protected]

Jerome Brunet (2):
clk: meson: mpll: add round closest support
clk: meson: axg: let mpll clocks round closest

drivers/clk/meson/axg.c | 4 ++++
drivers/clk/meson/clk-mpll.c | 24 +++++++++++++++++++-----
drivers/clk/meson/clkc.h | 3 +++
3 files changed, 26 insertions(+), 5 deletions(-)

--
2.14.3



2018-05-15 16:37:36

by Jerome Brunet

[permalink] [raw]
Subject: [PATCH v2 2/2] clk: meson: axg: let mpll clocks round closest

Let the mpll dividers achieve the closest rate possible, even if
it means rounding the requested rate up.

This is done to improve the accuracy of the rates provided by these
plls to the audio subsystem

Signed-off-by: Jerome Brunet <[email protected]>
---
drivers/clk/meson/axg.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 5f5d468c1efe..bd4dbc696b88 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -461,6 +461,7 @@ static struct clk_regmap axg_mpll0_div = {
.width = 1,
},
.lock = &meson_clk_lock,
+ .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "mpll0_div",
@@ -507,6 +508,7 @@ static struct clk_regmap axg_mpll1_div = {
.width = 1,
},
.lock = &meson_clk_lock,
+ .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "mpll1_div",
@@ -553,6 +555,7 @@ static struct clk_regmap axg_mpll2_div = {
.width = 1,
},
.lock = &meson_clk_lock,
+ .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "mpll2_div",
@@ -599,6 +602,7 @@ static struct clk_regmap axg_mpll3_div = {
.width = 1,
},
.lock = &meson_clk_lock,
+ .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "mpll3_div",
--
2.14.3


2018-05-15 16:39:07

by Jerome Brunet

[permalink] [raw]
Subject: [PATCH v2 1/2] clk: meson: mpll: add round closest support

Allow the mpll driver to round the requested rate up if
CLK_MESON_MPLL_ROUND_CLOSEST is set and it provides a rate closer to the
requested rate.

Signed-off-by: Jerome Brunet <[email protected]>
---
drivers/clk/meson/clk-mpll.c | 24 +++++++++++++++++++-----
drivers/clk/meson/clkc.h | 3 +++
2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 0df1227b65b3..d233549de244 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -89,10 +89,23 @@ static long rate_from_params(unsigned long parent_rate,
static void params_from_rate(unsigned long requested_rate,
unsigned long parent_rate,
unsigned int *sdm,
- unsigned int *n2)
+ unsigned int *n2,
+ u8 flags)
{
uint64_t div = parent_rate;
- unsigned long rem = do_div(div, requested_rate);
+ uint64_t frac = do_div(div, requested_rate);
+
+ frac *= SDM_DEN;
+
+ if (flags & CLK_MESON_MPLL_ROUND_CLOSEST)
+ *sdm = DIV_ROUND_CLOSEST_ULL(frac, requested_rate);
+ else
+ *sdm = DIV_ROUND_UP_ULL(frac, requested_rate);
+
+ if (*sdm == SDM_DEN) {
+ *sdm = 0;
+ div += 1;
+ }

if (div < N2_MIN) {
*n2 = N2_MIN;
@@ -102,7 +115,6 @@ static void params_from_rate(unsigned long requested_rate,
*sdm = SDM_DEN - 1;
} else {
*n2 = div;
- *sdm = DIV_ROUND_UP_ULL((u64)rem * SDM_DEN, requested_rate);
}
}

@@ -125,9 +137,11 @@ static long mpll_round_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long *parent_rate)
{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
unsigned int sdm, n2;

- params_from_rate(rate, *parent_rate, &sdm, &n2);
+ params_from_rate(rate, *parent_rate, &sdm, &n2, mpll->flags);
return rate_from_params(*parent_rate, sdm, n2);
}

@@ -140,7 +154,7 @@ static int mpll_set_rate(struct clk_hw *hw,
unsigned int sdm, n2;
unsigned long flags = 0;

- params_from_rate(rate, parent_rate, &sdm, &n2);
+ params_from_rate(rate, parent_rate, &sdm, &n2, mpll->flags);

if (mpll->lock)
spin_lock_irqsave(mpll->lock, flags);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 8fe73c4edca8..8cc265cd3d2b 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -97,8 +97,11 @@ struct meson_clk_mpll_data {
struct parm ssen;
struct parm misc;
spinlock_t *lock;
+ u8 flags;
};

+#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
+
struct meson_clk_audio_div_data {
struct parm div;
u8 flags;
--
2.14.3


2018-05-15 16:47:54

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] clk: meson: mpll: add round closest support

On 15/05/2018 18:36, Jerome Brunet wrote:
> Allow the mpll driver to round the requested rate up if
> CLK_MESON_MPLL_ROUND_CLOSEST is set and it provides a rate closer to the
> requested rate.
>
> Signed-off-by: Jerome Brunet <[email protected]>
> ---
> drivers/clk/meson/clk-mpll.c | 24 +++++++++++++++++++-----
> drivers/clk/meson/clkc.h | 3 +++
> 2 files changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
> index 0df1227b65b3..d233549de244 100644
> --- a/drivers/clk/meson/clk-mpll.c
> +++ b/drivers/clk/meson/clk-mpll.c
> @@ -89,10 +89,23 @@ static long rate_from_params(unsigned long parent_rate,
> static void params_from_rate(unsigned long requested_rate,
> unsigned long parent_rate,
> unsigned int *sdm,
> - unsigned int *n2)
> + unsigned int *n2,
> + u8 flags)
> {
> uint64_t div = parent_rate;
> - unsigned long rem = do_div(div, requested_rate);
> + uint64_t frac = do_div(div, requested_rate);
> +
> + frac *= SDM_DEN;
> +
> + if (flags & CLK_MESON_MPLL_ROUND_CLOSEST)
> + *sdm = DIV_ROUND_CLOSEST_ULL(frac, requested_rate);
> + else
> + *sdm = DIV_ROUND_UP_ULL(frac, requested_rate);
> +
> + if (*sdm == SDM_DEN) {
> + *sdm = 0;
> + div += 1;
> + }
>
> if (div < N2_MIN) {
> *n2 = N2_MIN;
> @@ -102,7 +115,6 @@ static void params_from_rate(unsigned long requested_rate,
> *sdm = SDM_DEN - 1;
> } else {
> *n2 = div;
> - *sdm = DIV_ROUND_UP_ULL((u64)rem * SDM_DEN, requested_rate);
> }
> }
>
> @@ -125,9 +137,11 @@ static long mpll_round_rate(struct clk_hw *hw,
> unsigned long rate,
> unsigned long *parent_rate)
> {
> + struct clk_regmap *clk = to_clk_regmap(hw);
> + struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
> unsigned int sdm, n2;
>
> - params_from_rate(rate, *parent_rate, &sdm, &n2);
> + params_from_rate(rate, *parent_rate, &sdm, &n2, mpll->flags);
> return rate_from_params(*parent_rate, sdm, n2);
> }
>
> @@ -140,7 +154,7 @@ static int mpll_set_rate(struct clk_hw *hw,
> unsigned int sdm, n2;
> unsigned long flags = 0;
>
> - params_from_rate(rate, parent_rate, &sdm, &n2);
> + params_from_rate(rate, parent_rate, &sdm, &n2, mpll->flags);
>
> if (mpll->lock)
> spin_lock_irqsave(mpll->lock, flags);
> diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
> index 8fe73c4edca8..8cc265cd3d2b 100644
> --- a/drivers/clk/meson/clkc.h
> +++ b/drivers/clk/meson/clkc.h
> @@ -97,8 +97,11 @@ struct meson_clk_mpll_data {
> struct parm ssen;
> struct parm misc;
> spinlock_t *lock;
> + u8 flags;
> };
>
> +#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
> +
> struct meson_clk_audio_div_data {
> struct parm div;
> u8 flags;
>

Acked-by: Neil Armstrong <[email protected]>

2018-05-15 16:48:48

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] clk: meson: axg: let mpll clocks round closest

On 15/05/2018 18:36, Jerome Brunet wrote:
> Let the mpll dividers achieve the closest rate possible, even if
> it means rounding the requested rate up.
>
> This is done to improve the accuracy of the rates provided by these
> plls to the audio subsystem
>
> Signed-off-by: Jerome Brunet <[email protected]>
> ---
> drivers/clk/meson/axg.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 5f5d468c1efe..bd4dbc696b88 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -461,6 +461,7 @@ static struct clk_regmap axg_mpll0_div = {
> .width = 1,
> },
> .lock = &meson_clk_lock,
> + .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
> },
> .hw.init = &(struct clk_init_data){
> .name = "mpll0_div",
> @@ -507,6 +508,7 @@ static struct clk_regmap axg_mpll1_div = {
> .width = 1,
> },
> .lock = &meson_clk_lock,
> + .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
> },
> .hw.init = &(struct clk_init_data){
> .name = "mpll1_div",
> @@ -553,6 +555,7 @@ static struct clk_regmap axg_mpll2_div = {
> .width = 1,
> },
> .lock = &meson_clk_lock,
> + .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
> },
> .hw.init = &(struct clk_init_data){
> .name = "mpll2_div",
> @@ -599,6 +602,7 @@ static struct clk_regmap axg_mpll3_div = {
> .width = 1,
> },
> .lock = &meson_clk_lock,
> + .flags = CLK_MESON_MPLL_ROUND_CLOSEST,
> },
> .hw.init = &(struct clk_init_data){
> .name = "mpll3_div",
>

Acked-by: Neil Armstrong <[email protected]>

2018-05-21 09:19:50

by Martin Blumenstingl

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] clk: meson: mpll: add round closest support

On Tue, May 15, 2018 at 6:36 PM, Jerome Brunet <[email protected]> wrote:
> Allow the mpll driver to round the requested rate up if
> CLK_MESON_MPLL_ROUND_CLOSEST is set and it provides a rate closer to the
> requested rate.
>
> Signed-off-by: Jerome Brunet <[email protected]>
Acked-by: Martin Blumenstingl<[email protected]>


I gave it a quick spin on Odroid-C1 (which uses an RGMII Ethernet PHY
and the RGMII TX clock is supplied by MPLL2). the clock tree looks
fine and Ethernet is still working:
mpll2_div 1 1 0 249999701
0 0
mpll2 1 1 0 249999701
0 0
c9410000.ethernet#m250_sel 1 1 0
249999701 0 0
c9410000.ethernet#m250_div 1 1 0
249999701 0 0
c9410000.ethernet#fixed_div2 1 1
0 124999850 0 0
c9410000.ethernet#rgmii_tx_en 1 1
0 124999850 0 0

2018-05-21 09:33:54

by Jerome Brunet

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] clk: meson: mpll: add round closest support

On Mon, 2018-05-21 at 11:18 +0200, Martin Blumenstingl wrote:
> On Tue, May 15, 2018 at 6:36 PM, Jerome Brunet <[email protected]> wrote:
> > Allow the mpll driver to round the requested rate up if
> > CLK_MESON_MPLL_ROUND_CLOSEST is set and it provides a rate closer to the
> > requested rate.
> >
> > Signed-off-by: Jerome Brunet <[email protected]>
>
> Acked-by: Martin Blumenstingl<[email protected]>

Thx for the feedback Martin.
Applied.

2018-05-21 09:35:18

by Jerome Brunet

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] clk: meson: axg: let mpll clocks round closest

On Tue, 2018-05-15 at 18:46 +0200, Neil Armstrong wrote:
> On 15/05/2018 18:36, Jerome Brunet wrote:
> > Let the mpll dividers achieve the closest rate possible, even if
> > it means rounding the requested rate up.
> >
> > This is done to improve the accuracy of the rates provided by these
> > plls to the audio subsystem
> >
> > Signed-off-by: Jerome Brunet <[email protected]>
> > ---
> >
[...]
>
> Acked-by: Neil Armstrong <[email protected]>

Applied