diff mbox series

[v3,02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed

Message ID 20181104182705.18047-3-jernej.skrabec@siol.net (mailing list archive)
State New, archived
Headers show
Series Allwinner H6 DE3 and HDMI support | expand

Commit Message

Jernej Škrabec Nov. 4, 2018, 6:26 p.m. UTC
Currently MP clocks don't consider adjusting parent rate even if they
are allowed to do so. Such behaviour considerably lowers amount of
possible rates, which is very inconvenient when such clock is used for
pixel clock, for example.

In order to improve the situation, adjusting parent rate is considered
when allowed.

This code is inspired by clk_divider_bestdiv() function, which does
basically the same thing for different clock type.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 2 deletions(-)

Comments

Priit Laes Jan. 10, 2019, 9:15 a.m. UTC | #1
On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> Currently MP clocks don't consider adjusting parent rate even if they
> are allowed to do so. Such behaviour considerably lowers amount of
> possible rates, which is very inconvenient when such clock is used for
> pixel clock, for example.
> 
> In order to improve the situation, adjusting parent rate is considered
> when allowed.
> 
> This code is inspired by clk_divider_bestdiv() function, which does
> basically the same thing for different clock type.

This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC boards:

EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
EXT4-fs (mmcblk1p4): write access will be enabled during recovery
sunxi-mmc 1c11000.mmc: data error, sending stop command
sunxi-mmc 1c11000.mmc: send stop command failed


$ git bisect log
git bisect start
# good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc: dw_mmc-bluefield: simplify the probe() function
git bisect good 3df407b2a5346db1c48809706ece7a8616c79e0b
# bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
git bisect bad 00d59fde8532b2d42e80909d2e58678755e04da9
# good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes' into next
git bisect good 01e421feec0817bb3141eaae4c517410d193d440
# bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect bad 1eefdec18eded41833401cfd64749643ff72e7da
# good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag 'mtd/for-4.21' of git://git.infradead.org/linux-mtd
git bisect good eaa76499711535fd64d747cc4ef0d78ab0fd41c6
# good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag 'leds-for-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
git bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
# bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next
git bisect bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
# bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect bad e4b99d415c3908581d4703203e1e805f043a3e71
# bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and 'clk-rockchip' into clk-next
git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
# good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and 'clk-ops-const' into clk-next
git bisect good 1a501c8defe950571316d5ddd917bf44f5ed7bd4
# good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson
git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
# good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag 'clk-renesas-for-v4.21-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas
git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
# bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag 'sunxi-clk-for-4.21' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner
git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
# bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64: Fix gate bit of DSI DPHY
git bisect bad ee678706e46d0d185c27cc214ad97828e0643159
# bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64 for calculation of NM rate
git bisect bad 65b6657672388b72822e0367f06d41c1e3ffb5bb
# good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng: sun50i: h6: Fix MMC clock mux width
git bisect good db7548934603d9eda12649dff97ea5c29884405d
# bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP clock parent rate when allowed
git bisect bad 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
# first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP clock parent rate when allowed


> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
>  1 file changed, 62 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> index 5d0af4051737..0357349eb767 100644
> --- a/drivers/clk/sunxi-ng/ccu_mp.c
> +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
>  	*p = best_p;
>  }
>  
> +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
> +						      unsigned long *parent,
> +						      unsigned long rate,
> +						      unsigned int max_m,
> +						      unsigned int max_p)
> +{
> +	unsigned long parent_rate_saved;
> +	unsigned long parent_rate, now;
> +	unsigned long best_rate = 0;
> +	unsigned int _m, _p, div;
> +	unsigned long maxdiv;
> +
> +	parent_rate_saved = *parent;
> +
> +	/*
> +	 * The maximum divider we can use without overflowing
> +	 * unsigned long in rate * m * p below
> +	 */
> +	maxdiv = max_m * max_p;
> +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> +
> +	for (_p = 1; _p <= max_p; _p <<= 1) {
> +		for (_m = 1; _m <= max_m; _m++) {
> +			div = _m * _p;
> +
> +			if (div > maxdiv)
> +				break;
> +
> +			if (rate * div == parent_rate_saved) {
> +				/*
> +				 * It's the most ideal case if the requested
> +				 * rate can be divided from parent clock without
> +				 * needing to change parent rate, so return the
> +				 * divider immediately.
> +				 */
> +				*parent = parent_rate_saved;
> +				return rate;
> +			}
> +
> +			parent_rate = clk_hw_round_rate(hw, rate * div);
> +			now = parent_rate / div;
> +
> +			if (now <= rate && now > best_rate) {
> +				best_rate = now;
> +				*parent = parent_rate;
> +
> +				if (now == rate)
> +					return rate;
> +			}
> +		}
> +	}
> +
> +	return best_rate;
> +}
> +
>  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
>  				       struct clk_hw *hw,
>  				       unsigned long *parent_rate,
> @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
>  	max_m = cmp->m.max ?: 1 << cmp->m.width;
>  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
>  
> -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> -	rate = *parent_rate / p / m;
> +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> +		rate = *parent_rate / p / m;
> +	} else {
> +		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate,
> +							max_m, max_p);
> +	}
>  
>  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
>  		rate /= cmp->fixed_post_div;
> -- 
> 2.19.1
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Jernej Škrabec Jan. 10, 2019, 5:10 p.m. UTC | #2
Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > Currently MP clocks don't consider adjusting parent rate even if they
> > are allowed to do so. Such behaviour considerably lowers amount of
> > possible rates, which is very inconvenient when such clock is used for
> > pixel clock, for example.
> > 
> > In order to improve the situation, adjusting parent rate is considered
> > when allowed.
> > 
> > This code is inspired by clk_divider_bestdiv() function, which does
> > basically the same thing for different clock type.
> 
> This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC boards:
> 
> EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> sunxi-mmc 1c11000.mmc: data error, sending stop command
> sunxi-mmc 1c11000.mmc: send stop command failed
> 

I'm not familiar with A20. What is interesting is that emmc clocks don't have 
CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.

Can you post content of clk_summary with and without this patch?

Best regards,
Jernej

> 
> $ git bisect log
> git bisect start
> # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc: dw_mmc-bluefield:
> simplify the probe() function git bisect good
> 3df407b2a5346db1c48809706ece7a8616c79e0b
> # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21' of
> git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> 00d59fde8532b2d42e80909d2e58678755e04da9
> # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes' into
> next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> 'locking-core-for-linus' of
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> 1eefdec18eded41833401cfd64749643ff72e7da
> # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag 'mtd/for-4.21'
> of git://git.infradead.org/linux-mtd git bisect good
> eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> 'leds-for-4.21-rc1' of
> git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds git
> bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git bisect
> bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> 'irq-core-for-linus' of
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> e4b99d415c3908581d4703203e1e805f043a3e71
> # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and 'clk-rockchip'
> into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> 'clk-ops-const' into clk-next git bisect good
> 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson
> git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> 'clk-renesas-for-v4.21-tag2' of
> git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> 'sunxi-clk-for-4.21' of
> https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64: Fix
> gate bit of DSI DPHY git bisect bad
> ee678706e46d0d185c27cc214ad97828e0643159
> # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64 for
> calculation of NM rate git bisect bad
> 65b6657672388b72822e0367f06d41c1e3ffb5bb
> # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng: sun50i:
> h6: Fix MMC clock mux width git bisect good
> db7548934603d9eda12649dff97ea5c29884405d
> # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP
> clock parent rate when allowed git bisect bad
> 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> sunxi-ng: Adjust MP clock parent rate when allowed
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
> >  1 file changed, 62 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> > index 5d0af4051737..0357349eb767 100644
> > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > unsigned long rate,> 
> >  	*p = best_p;
> >  
> >  }
> > 
> > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
> > +						      
unsigned long *parent,
> > +						      
unsigned long rate,
> > +						      
unsigned int max_m,
> > +						      
unsigned int max_p)
> > +{
> > +	unsigned long parent_rate_saved;
> > +	unsigned long parent_rate, now;
> > +	unsigned long best_rate = 0;
> > +	unsigned int _m, _p, div;
> > +	unsigned long maxdiv;
> > +
> > +	parent_rate_saved = *parent;
> > +
> > +	/*
> > +	 * The maximum divider we can use without overflowing
> > +	 * unsigned long in rate * m * p below
> > +	 */
> > +	maxdiv = max_m * max_p;
> > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > +
> > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > +		for (_m = 1; _m <= max_m; _m++) {
> > +			div = _m * _p;
> > +
> > +			if (div > maxdiv)
> > +				break;
> > +
> > +			if (rate * div == parent_rate_saved) {
> > +				/*
> > +				 * It's the most ideal case if 
the requested
> > +				 * rate can be divided from 
parent clock without
> > +				 * needing to change parent rate, 
so return the
> > +				 * divider immediately.
> > +				 */
> > +				*parent = parent_rate_saved;
> > +				return rate;
> > +			}
> > +
> > +			parent_rate = clk_hw_round_rate(hw, rate * 
div);
> > +			now = parent_rate / div;
> > +
> > +			if (now <= rate && now > best_rate) {
> > +				best_rate = now;
> > +				*parent = parent_rate;
> > +
> > +				if (now == rate)
> > +					return rate;
> > +			}
> > +		}
> > +	}
> > +
> > +	return best_rate;
> > +}
> > +
> > 
> >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> >  
> >  				       struct clk_hw *hw,
> >  				       unsigned long 
*parent_rate,
> > 
> > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > ccu_mux_internal *mux,> 
> >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > 
> > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > -	rate = *parent_rate / p / m;
> > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, 
&p);
> > +		rate = *parent_rate / p / m;
> > +	} else {
> > +		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, 
rate,
> > +							
max_m, max_p);
> > +	}
> > 
> >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> >  	
> >  		rate /= cmp->fixed_post_div;
Priit Laes Jan. 16, 2019, 12:09 p.m. UTC | #3
On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > Currently MP clocks don't consider adjusting parent rate even if they
> > > are allowed to do so. Such behaviour considerably lowers amount of
> > > possible rates, which is very inconvenient when such clock is used for
> > > pixel clock, for example.
> > > 
> > > In order to improve the situation, adjusting parent rate is considered
> > > when allowed.
> > > 
> > > This code is inspired by clk_divider_bestdiv() function, which does
> > > basically the same thing for different clock type.
> > 
> > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC boards:
> > 
> > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > sunxi-mmc 1c11000.mmc: send stop command failed
> > 
> 
> I'm not familiar with A20. What is interesting is that emmc clocks don't have 
> CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.
> 
> Can you post content of clk_summary with and without this patch?

In both cases I booted from FEL with rootfs on sdcard and tried to mount
partition from eMMC to /mnt. With your patch, last step it fails.

pre-patch working:
pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is off?)

post-patch not working:
pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)

Also, attached the logs.

> 
> Best regards,
> Jernej
> 
> > 
> > $ git bisect log
> > git bisect start
> > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc: dw_mmc-bluefield:
> > simplify the probe() function git bisect good
> > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> > 00d59fde8532b2d42e80909d2e58678755e04da9
> > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes' into
> > next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > 'locking-core-for-linus' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > 1eefdec18eded41833401cfd64749643ff72e7da
> > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag 'mtd/for-4.21'
> > of git://git.infradead.org/linux-mtd git bisect good
> > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > 'leds-for-4.21-rc1' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds git
> > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git bisect
> > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > 'irq-core-for-linus' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > e4b99d415c3908581d4703203e1e805f043a3e71
> > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and 'clk-rockchip'
> > into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > 'clk-ops-const' into clk-next git bisect good
> > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson
> > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > 'clk-renesas-for-v4.21-tag2' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > 'sunxi-clk-for-4.21' of
> > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64: Fix
> > gate bit of DSI DPHY git bisect bad
> > ee678706e46d0d185c27cc214ad97828e0643159
> > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64 for
> > calculation of NM rate git bisect bad
> > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng: sun50i:
> > h6: Fix MMC clock mux width git bisect good
> > db7548934603d9eda12649dff97ea5c29884405d
> > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP
> > clock parent rate when allowed git bisect bad
> > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > sunxi-ng: Adjust MP clock parent rate when allowed
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > > 
> > >  drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
> > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> > > index 5d0af4051737..0357349eb767 100644
> > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > > unsigned long rate,> 
> > >  	*p = best_p;
> > >  
> > >  }
> > > 
> > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
> > > +						      
> unsigned long *parent,
> > > +						      
> unsigned long rate,
> > > +						      
> unsigned int max_m,
> > > +						      
> unsigned int max_p)
> > > +{
> > > +	unsigned long parent_rate_saved;
> > > +	unsigned long parent_rate, now;
> > > +	unsigned long best_rate = 0;
> > > +	unsigned int _m, _p, div;
> > > +	unsigned long maxdiv;
> > > +
> > > +	parent_rate_saved = *parent;
> > > +
> > > +	/*
> > > +	 * The maximum divider we can use without overflowing
> > > +	 * unsigned long in rate * m * p below
> > > +	 */
> > > +	maxdiv = max_m * max_p;
> > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > +
> > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > +		for (_m = 1; _m <= max_m; _m++) {
> > > +			div = _m * _p;
> > > +
> > > +			if (div > maxdiv)
> > > +				break;
> > > +
> > > +			if (rate * div == parent_rate_saved) {
> > > +				/*
> > > +				 * It's the most ideal case if 
> the requested
> > > +				 * rate can be divided from 
> parent clock without
> > > +				 * needing to change parent rate, 
> so return the
> > > +				 * divider immediately.
> > > +				 */
> > > +				*parent = parent_rate_saved;
> > > +				return rate;
> > > +			}
> > > +
> > > +			parent_rate = clk_hw_round_rate(hw, rate * 
> div);
> > > +			now = parent_rate / div;
> > > +
> > > +			if (now <= rate && now > best_rate) {
> > > +				best_rate = now;
> > > +				*parent = parent_rate;
> > > +
> > > +				if (now == rate)
> > > +					return rate;
> > > +			}
> > > +		}
> > > +	}
> > > +
> > > +	return best_rate;
> > > +}
> > > +
> > > 
> > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> > >  
> > >  				       struct clk_hw *hw,
> > >  				       unsigned long 
> *parent_rate,
> > > 
> > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > ccu_mux_internal *mux,> 
> > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > 
> > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > -	rate = *parent_rate / p / m;
> > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, 
> &p);
> > > +		rate = *parent_rate / p / m;
> > > +	} else {
> > > +		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, 
> rate,
> > > +							
> max_m, max_p);
> > > +	}
> > > 
> > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > >  	
> > >  		rate /= cmp->fixed_post_div;
> 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
 gmac_int_tx                          1        1        0   125000000          0     0  50000
    gmac_tx                           1        1        0   125000000          0     0  50000
 mii_phy_tx                           0        0        0    25000000          0     0  50000
 osc32k                               0        0        0       32768          0     0  50000
 osc24M                               2        2        1    24000000          0     0  50000
    hosc                              6        6        1    24000000          0     0  50000
       out-b                          0        0        0       32000          0     0  50000
       out-a                          0        0        0       32000          0     0  50000
       hdmi1-slow                     0        0        0    24000000          0     0  50000
       avs                            0        0        0    24000000          0     0  50000
       csi1                           0        0        0    24000000          0     0  50000
       csi0                           0        0        0    24000000          0     0  50000
       spi3                           0        0        0    24000000          0     0  50000
       keypad                         0        0        0      750000          0     0  50000
       ir1                            0        0        0    24000000          0     0  50000
       ir0                            0        0        0    24000000          0     0  50000
       pata                           0        0        0    24000000          0     0  50000
       spi2                           0        0        0    24000000          0     0  50000
       spi1                           0        0        0    24000000          0     0  50000
       spi0                           0        0        0    24000000          0     0  50000
       ts                             0        0        0    24000000          0     0  50000
       mmc3                           0        0        0    24000000          0     0  50000
          mmc3_sample                 0        0        0    24000000          0   180  50000
          mmc3_output                 0        0        0    24000000          0   180  50000
       mmc1                           0        0        0    24000000          0     0  50000
          mmc1_sample                 0        0        0    24000000          0   180  50000
          mmc1_output                 0        0        0    24000000          0   180  50000
       ms                             0        0        0    24000000          0     0  50000
       nand                           0        0        0    24000000          0     0  50000
       apb1                           3        3        0    24000000          0     0  50000
          apb1-uart7                  0        0        0    24000000          0     0  50000
          apb1-uart6                  0        0        0    24000000          0     0  50000
          apb1-uart5                  0        0        0    24000000          0     0  50000
          apb1-uart4                  0        0        0    24000000          0     0  50000
          apb1-uart3                  0        0        0    24000000          0     0  50000
          apb1-uart2                  0        0        0    24000000          0     0  50000
          apb1-uart1                  0        0        0    24000000          0     0  50000
          apb1-uart0                  1        1        0    24000000          0     0  50000
          apb1-i2c4                   0        0        0    24000000          0     0  50000
          apb1-ps21                   0        0        0    24000000          0     0  50000
          apb1-ps20                   0        0        0    24000000          0     0  50000
          apb1-scr                    0        0        0    24000000          0     0  50000
          apb1-can                    0        0        0    24000000          0     0  50000
          apb1-i2c3                   0        0        0    24000000          0     0  50000
          apb1-i2c2                   0        0        0    24000000          0     0  50000
          apb1-i2c1                   1        1        0    24000000          0     0  50000
          apb1-i2c0                   1        1        0    24000000          0     0  50000
       pll-gpu                        0        0        0  1200000000          0     0  50000
       pll-video1                     1        1        0   327000000          0     0  50000
          pll-video1-2x               1        1        0   654000000          0     0  50000
             hdmi-tmds                1        1        0    25153846          0     0  50000
                hdmi-ddc              1        1        0       89835          0     0  50000
       pll-periph-base                3        3        0  1200000000          0     0  50000
          mbus                        1        1        0   300000000          0     0  50000
          pll-periph-sata             1        1        0   100000000          0     0  50000
             sata                     1        1        0   100000000          0     0  50000
          pll-periph                  5        5        0   600000000          0     0  50000
             mmc0                     0        0        0    50000000          0     0  50000
                mmc0_sample           0        0        0    50000000          0   120  50000
                mmc0_output           0        0        0    50000000          0    90  50000
             ss                       1        1        0   150000000          0     0  50000
             usb-phy                  3        3        0   600000000          0     0  50000
             usb-ohci1                1        1        0   600000000          0     0  50000
             usb-ohci0                1        1        0   600000000          0     0  50000
             ahb                     17       17        0   300000000          0     0  50000
                ahb-gpu               0        0        0   300000000          0     0  50000
                ahb-mp                0        0        0   300000000          0     0  50000
                ahb-gmac              1        1        0   300000000          0     0  50000
                ahb-de-fe1            0        0        0   300000000          0     0  50000
                ahb-de-fe0            0        0        0   300000000          0     0  50000
                ahb-de-be1            1        1        0   300000000          0     0  50000
                ahb-de-be0            1        1        0   300000000          0     0  50000
                ahb-hdmi1             0        0        0   300000000          0     0  50000
                ahb-hdmi0             1        1        0   300000000          0     0  50000
                ahb-csi1              0        0        0   300000000          0     0  50000
                ahb-csi0              0        0        0   300000000          0     0  50000
                ahb-lcd1              1        1        0   300000000          0     0  50000
                ahb-lcd0              1        1        0   300000000          0     0  50000
                ahb-tve1              0        0        0   300000000          0     0  50000
                ahb-tve0              0        0        0   300000000          0     0  50000
                ahb-tvd               0        0        0   300000000          0     0  50000
                ahb-ve                0        0        0   300000000          0     0  50000
                ahb-hstimer           2        2        0   300000000          0     0  50000
                ahb-sata              1        1        0   300000000          0     0  50000
                ahb-pata              0        0        0   300000000          0     0  50000
                ahb-spi3              0        0        0   300000000          0     0  50000
                ahb-spi2              0        0        0   300000000          0     0  50000
                ahb-spi1              0        0        0   300000000          0     0  50000
                ahb-spi0              0        0        0   300000000          0     0  50000
                ahb-ts                0        0        0   300000000          0     0  50000
                ahb-emac              0        0        0   300000000          0     0  50000
                ahb-ace               0        0        0   300000000          0     0  50000
                ahb-sdram             1        1        0   300000000          0     0  50000
                ahb-nand              0        0        0   300000000          0     0  50000
                ahb-ms                0        0        0   300000000          0     0  50000
                ahb-mmc3              0        0        0   300000000          0     0  50000
                ahb-mmc2              0        0        0   300000000          0     0  50000
                ahb-mmc1              0        0        0   300000000          0     0  50000
                ahb-mmc0              0        0        0   300000000          0     0  50000
                ahb-bist              0        0        0   300000000          0     0  50000
                ahb-dma               1        1        0   300000000          0     0  50000
                ahb-ss                1        1        0   300000000          0     0  50000
                ahb-ohci1             1        1        0   300000000          0     0  50000
                ahb-ehci1             1        1        0   300000000          0     0  50000
                ahb-ohci0             1        1        0   300000000          0     0  50000
                ahb-ehci0             1        1        0   300000000          0     0  50000
                ahb-otg               1        1        0   300000000          0     0  50000
                apb0                  1        1        0   150000000          0     0  50000
                   apb0-keypad        0        0        0   150000000          0     0  50000
                   apb0-i2s2          0        0        0   150000000          0     0  50000
                   apb0-ir1           0        0        0   150000000          0     0  50000
                   apb0-ir0           0        0        0   150000000          0     0  50000
                   apb0-pio           1        1        0   150000000          0     0  50000
                   apb0-i2s1          0        0        0   150000000          0     0  50000
                   apb0-ac97          0        0        0   150000000          0     0  50000
                   apb0-i2s0          0        0        0   150000000          0     0  50000
                   apb0-spdif         0        0        0   150000000          0     0  50000
                   apb0-codec         0        0        0   150000000          0     0  50000
       pll-ddr-base                   2        2        0   768000000          0     0  50000
          pll-ddr-other               1        1        0   768000000          0     0  50000
             mmc2                     0        0        0    51200000          0     0  50000
                mmc2_sample           0        0        0    51200000          0   120  50000
                mmc2_output           0        0        0    51200000          0    72  50000
             de-be0                   1        1        0   256000000          0     0  50000
          pll-ddr                     4        4        0   384000000          0     0  50000
             dram-ace                 0        0        0   384000000          0     0  50000
             dram-mp                  0        0        0   384000000          0     0  50000
             dram-de-be1              1        1        0   384000000          0     0  50000
             dram-de-be0              1        1        0   384000000          0     0  50000
             dram-de-fe0              0        0        0   384000000          0     0  50000
             dram-de-fe1              0        0        0   384000000          0     0  50000
             dram-out                 1        1        0   384000000          0     0  50000
             dram-tve1                0        0        0   384000000          0     0  50000
             dram-tve0                0        0        0   384000000          0     0  50000
             dram-tvd                 0        0        0   384000000          0     0  50000
             dram-ts                  0        0        0   384000000          0     0  50000
             dram-csi1                0        0        0   384000000          0     0  50000
             dram-csi0                0        0        0   384000000          0     0  50000
             dram-ve                  0        0        0   384000000          0     0  50000
       pll-ve                         0        0        0  1200000000          0     0  50000
          ace                         0        0        0  1200000000          0     0  50000
          ve                          0        0        0  1200000000          0     0  50000
       pll-video0                     3        3        1   327000000          0     0  50000
          hdmi1                       0        0        0   327000000          0     0  50000
          gpu                         0        0        0   327000000          0     0  50000
          hdmi                        1        1        0    25153847          0     0  50000
          tcon1-ch1-sclk2             0        0        0   327000000          0     0  50000
             tcon1-ch1-sclk1          0        0        0   327000000          0     0  50000
          tcon0-ch1-sclk2             1        1        1    25153847          0     0  50000
             tcon0-ch1-sclk1          1        1        1    25153847          0     0  50000
          tvd-sclk2                   0        0        0   327000000          0     0  50000
             tvd-sclk1                0        0        0   327000000          0     0  50000
          csi-sclk                    0        0        0   327000000          0     0  50000
          tcon1-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon1-pixel-clock        0        0        0   327000000          0     0  50000
          tcon0-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon0-pixel-clock        0        0        0   327000000          0     0  50000
          de-mp                       0        0        0   327000000          0     0  50000
          de-fe1                      0        0        0   327000000          0     0  50000
          de-fe0                      0        0        0   327000000          0     0  50000
          de-be1                      1        1        0   327000000          0     0  50000
          pll-video0-2x               0        0        0   654000000          0     0  50000
       pll-audio-base                 0        0        0     1500000          0     0  50000
          pll-audio-8x                0        0        0     3000000          0     0  50000
             i2s2                     0        0        0     3000000          0     0  50000
             i2s1                     0        0        0     3000000          0     0  50000
             i2s0                     0        0        0     3000000          0     0  50000
          pll-audio-4x                0        0        0     1500000          0     0  50000
             spdif                    0        0        0     1500000          0     0  50000
          pll-audio-2x                0        0        0      750000          0     0  50000
          pll-audio                   0        0        0     1500000          0     0  50000
             codec                    0        0        0     1500000          0     0  50000
             ac97                     0        0        0     1500000          0     0  50000
       pll-core                       1        1        0   960000000          0     0  50000
          cpu                         1        1        0   960000000          0     0  50000
             axi                      0        0        0   320000000          0     0  50000
enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
 gmac_int_tx                          1        1        0   125000000          0     0  50000
    gmac_tx                           1        1        0   125000000          0     0  50000
 mii_phy_tx                           0        0        0    25000000          0     0  50000
 osc32k                               0        0        0       32768          0     0  50000
 osc24M                               2        2        1    24000000          0     0  50000
    hosc                              6        6        1    24000000          0     0  50000
       out-b                          0        0        0       32000          0     0  50000
       out-a                          0        0        0       32000          0     0  50000
       hdmi1-slow                     0        0        0    24000000          0     0  50000
       avs                            0        0        0    24000000          0     0  50000
       csi1                           0        0        0    24000000          0     0  50000
       csi0                           0        0        0    24000000          0     0  50000
       spi3                           0        0        0    24000000          0     0  50000
       keypad                         0        0        0      750000          0     0  50000
       ir1                            0        0        0    24000000          0     0  50000
       ir0                            0        0        0    24000000          0     0  50000
       pata                           0        0        0    24000000          0     0  50000
       spi2                           0        0        0    24000000          0     0  50000
       spi1                           0        0        0    24000000          0     0  50000
       spi0                           0        0        0    24000000          0     0  50000
       ts                             0        0        0    24000000          0     0  50000
       mmc3                           0        0        0    24000000          0     0  50000
          mmc3_sample                 0        0        0    24000000          0   180  50000
          mmc3_output                 0        0        0    24000000          0   180  50000
       mmc1                           0        0        0    24000000          0     0  50000
          mmc1_sample                 0        0        0    24000000          0   180  50000
          mmc1_output                 0        0        0    24000000          0   180  50000
       ms                             0        0        0    24000000          0     0  50000
       nand                           0        0        0    24000000          0     0  50000
       apb1                           3        3        0    24000000          0     0  50000
          apb1-uart7                  0        0        0    24000000          0     0  50000
          apb1-uart6                  0        0        0    24000000          0     0  50000
          apb1-uart5                  0        0        0    24000000          0     0  50000
          apb1-uart4                  0        0        0    24000000          0     0  50000
          apb1-uart3                  0        0        0    24000000          0     0  50000
          apb1-uart2                  0        0        0    24000000          0     0  50000
          apb1-uart1                  0        0        0    24000000          0     0  50000
          apb1-uart0                  1        1        0    24000000          0     0  50000
          apb1-i2c4                   0        0        0    24000000          0     0  50000
          apb1-ps21                   0        0        0    24000000          0     0  50000
          apb1-ps20                   0        0        0    24000000          0     0  50000
          apb1-scr                    0        0        0    24000000          0     0  50000
          apb1-can                    0        0        0    24000000          0     0  50000
          apb1-i2c3                   0        0        0    24000000          0     0  50000
          apb1-i2c2                   0        0        0    24000000          0     0  50000
          apb1-i2c1                   1        1        0    24000000          0     0  50000
          apb1-i2c0                   1        1        0    24000000          0     0  50000
       pll-gpu                        0        0        0  1200000000          0     0  50000
       pll-video1                     1        1        0   327000000          0     0  50000
          pll-video1-2x               1        1        0   654000000          0     0  50000
             hdmi-tmds                1        1        0    25153846          0     0  50000
                hdmi-ddc              1        1        0       89835          0     0  50000
       pll-periph-base                3        3        0  1200000000          0     0  50000
          mbus                        1        1        0   300000000          0     0  50000
          pll-periph-sata             1        1        0   100000000          0     0  50000
             sata                     1        1        0   100000000          0     0  50000
          pll-periph                  6        6        0   600000000          0     0  50000
             mmc2                     3        3        0    50000000          0     0  50000
                mmc2_sample           1        1        0    50000000          0   120  50000
                mmc2_output           1        1        0    50000000          0    60  50000
             mmc0                     0        0        0    50000000          0     0  50000
                mmc0_sample           0        0        0    50000000          0   120  50000
                mmc0_output           0        0        0    50000000          0    90  50000
             ss                       1        1        0   150000000          0     0  50000
             usb-phy                  3        3        0   600000000          0     0  50000
             usb-ohci1                1        1        0   600000000          0     0  50000
             usb-ohci0                1        1        0   600000000          0     0  50000
             ahb                     18       18        0   300000000          0     0  50000
                ahb-gpu               0        0        0   300000000          0     0  50000
                ahb-mp                0        0        0   300000000          0     0  50000
                ahb-gmac              1        1        0   300000000          0     0  50000
                ahb-de-fe1            0        0        0   300000000          0     0  50000
                ahb-de-fe0            0        0        0   300000000          0     0  50000
                ahb-de-be1            1        1        0   300000000          0     0  50000
                ahb-de-be0            1        1        0   300000000          0     0  50000
                ahb-hdmi1             0        0        0   300000000          0     0  50000
                ahb-hdmi0             1        1        0   300000000          0     0  50000
                ahb-csi1              0        0        0   300000000          0     0  50000
                ahb-csi0              0        0        0   300000000          0     0  50000
                ahb-lcd1              1        1        0   300000000          0     0  50000
                ahb-lcd0              1        1        0   300000000          0     0  50000
                ahb-tve1              0        0        0   300000000          0     0  50000
                ahb-tve0              0        0        0   300000000          0     0  50000
                ahb-tvd               0        0        0   300000000          0     0  50000
                ahb-ve                0        0        0   300000000          0     0  50000
                ahb-hstimer           2        2        0   300000000          0     0  50000
                ahb-sata              1        1        0   300000000          0     0  50000
                ahb-pata              0        0        0   300000000          0     0  50000
                ahb-spi3              0        0        0   300000000          0     0  50000
                ahb-spi2              0        0        0   300000000          0     0  50000
                ahb-spi1              0        0        0   300000000          0     0  50000
                ahb-spi0              0        0        0   300000000          0     0  50000
                ahb-ts                0        0        0   300000000          0     0  50000
                ahb-emac              0        0        0   300000000          0     0  50000
                ahb-ace               0        0        0   300000000          0     0  50000
                ahb-sdram             1        1        0   300000000          0     0  50000
                ahb-nand              0        0        0   300000000          0     0  50000
                ahb-ms                0        0        0   300000000          0     0  50000
                ahb-mmc3              0        0        0   300000000          0     0  50000
                ahb-mmc2              1        1        0   300000000          0     0  50000
                ahb-mmc1              0        0        0   300000000          0     0  50000
                ahb-mmc0              0        0        0   300000000          0     0  50000
                ahb-bist              0        0        0   300000000          0     0  50000
                ahb-dma               1        1        0   300000000          0     0  50000
                ahb-ss                1        1        0   300000000          0     0  50000
                ahb-ohci1             1        1        0   300000000          0     0  50000
                ahb-ehci1             1        1        0   300000000          0     0  50000
                ahb-ohci0             1        1        0   300000000          0     0  50000
                ahb-ehci0             1        1        0   300000000          0     0  50000
                ahb-otg               1        1        0   300000000          0     0  50000
                apb0                  1        1        0   150000000          0     0  50000
                   apb0-keypad        0        0        0   150000000          0     0  50000
                   apb0-i2s2          0        0        0   150000000          0     0  50000
                   apb0-ir1           0        0        0   150000000          0     0  50000
                   apb0-ir0           0        0        0   150000000          0     0  50000
                   apb0-pio           1        1        0   150000000          0     0  50000
                   apb0-i2s1          0        0        0   150000000          0     0  50000
                   apb0-ac97          0        0        0   150000000          0     0  50000
                   apb0-i2s0          0        0        0   150000000          0     0  50000
                   apb0-spdif         0        0        0   150000000          0     0  50000
                   apb0-codec         0        0        0   150000000          0     0  50000
       pll-ddr-base                   2        2        0   768000000          0     0  50000
          pll-ddr-other               1        1        0   768000000          0     0  50000
             de-be0                   1        1        0   256000000          0     0  50000
          pll-ddr                     4        4        0   384000000          0     0  50000
             dram-ace                 0        0        0   384000000          0     0  50000
             dram-mp                  0        0        0   384000000          0     0  50000
             dram-de-be1              1        1        0   384000000          0     0  50000
             dram-de-be0              1        1        0   384000000          0     0  50000
             dram-de-fe0              0        0        0   384000000          0     0  50000
             dram-de-fe1              0        0        0   384000000          0     0  50000
             dram-out                 1        1        0   384000000          0     0  50000
             dram-tve1                0        0        0   384000000          0     0  50000
             dram-tve0                0        0        0   384000000          0     0  50000
             dram-tvd                 0        0        0   384000000          0     0  50000
             dram-ts                  0        0        0   384000000          0     0  50000
             dram-csi1                0        0        0   384000000          0     0  50000
             dram-csi0                0        0        0   384000000          0     0  50000
             dram-ve                  0        0        0   384000000          0     0  50000
       pll-ve                         0        0        0  1200000000          0     0  50000
          ace                         0        0        0  1200000000          0     0  50000
          ve                          0        0        0  1200000000          0     0  50000
       pll-video0                     3        3        1   327000000          0     0  50000
          hdmi1                       0        0        0   327000000          0     0  50000
          gpu                         0        0        0   327000000          0     0  50000
          hdmi                        1        1        0    25153847          0     0  50000
          tcon1-ch1-sclk2             0        0        0   327000000          0     0  50000
             tcon1-ch1-sclk1          0        0        0   327000000          0     0  50000
          tcon0-ch1-sclk2             1        1        1    25153847          0     0  50000
             tcon0-ch1-sclk1          1        1        1    25153847          0     0  50000
          tvd-sclk2                   0        0        0   327000000          0     0  50000
             tvd-sclk1                0        0        0   327000000          0     0  50000
          csi-sclk                    0        0        0   327000000          0     0  50000
          tcon1-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon1-pixel-clock        0        0        0   327000000          0     0  50000
          tcon0-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon0-pixel-clock        0        0        0   327000000          0     0  50000
          de-mp                       0        0        0   327000000          0     0  50000
          de-fe1                      0        0        0   327000000          0     0  50000
          de-fe0                      0        0        0   327000000          0     0  50000
          de-be1                      1        1        0   327000000          0     0  50000
          pll-video0-2x               0        0        0   654000000          0     0  50000
       pll-audio-base                 0        0        0     1500000          0     0  50000
          pll-audio-8x                0        0        0     3000000          0     0  50000
             i2s2                     0        0        0     3000000          0     0  50000
             i2s1                     0        0        0     3000000          0     0  50000
             i2s0                     0        0        0     3000000          0     0  50000
          pll-audio-4x                0        0        0     1500000          0     0  50000
             spdif                    0        0        0     1500000          0     0  50000
          pll-audio-2x                0        0        0      750000          0     0  50000
          pll-audio                   0        0        0     1500000          0     0  50000
             codec                    0        0        0     1500000          0     0  50000
             ac97                     0        0        0     1500000          0     0  50000
       pll-core                       1        1        0   960000000          0     0  50000
          cpu                         1        1        0   960000000          0     0  50000
             axi                      0        0        0   320000000          0     0  50000
Jernej Škrabec Jan. 16, 2019, 5 p.m. UTC | #4
Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > Currently MP clocks don't consider adjusting parent rate even if they
> > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > possible rates, which is very inconvenient when such clock is used for
> > > > pixel clock, for example.
> > > > 
> > > > In order to improve the situation, adjusting parent rate is considered
> > > > when allowed.
> > > > 
> > > > This code is inspired by clk_divider_bestdiv() function, which does
> > > > basically the same thing for different clock type.
> > > 
> > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > boards:
> > > 
> > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > sunxi-mmc 1c11000.mmc: send stop command failed
> > 
> > I'm not familiar with A20. What is interesting is that emmc clocks don't
> > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.
> > 
> > Can you post content of clk_summary with and without this patch?
> 
> In both cases I booted from FEL with rootfs on sdcard and tried to mount
> partition from eMMC to /mnt. With your patch, last step it fails.
> 
> pre-patch working:
> pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is off?)
> 
> post-patch not working:
> pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> 
> Also, attached the logs.

Thanks. Just one more request. Can you enable debug messages in mmc driver? 
I'm interested in output of this line:

dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
		clock, rate);

Just wondering what it should be.

Best regards,
Jernej

> 
> > Best regards,
> > Jernej
> > 
> > > $ git bisect log
> > > git bisect start
> > > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc:
> > > dw_mmc-bluefield:
> > > simplify the probe() function git bisect good
> > > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21'
> > > of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> > > 00d59fde8532b2d42e80909d2e58678755e04da9
> > > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes'
> > > into next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > > 'locking-core-for-linus' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > 1eefdec18eded41833401cfd64749643ff72e7da
> > > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag
> > > 'mtd/for-4.21'
> > > of git://git.infradead.org/linux-mtd git bisect good
> > > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > > 'leds-for-4.21-rc1' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
> > > git
> > > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git
> > > bisect
> > > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > > 'irq-core-for-linus' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > e4b99d415c3908581d4703203e1e805f043a3e71
> > > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and
> > > 'clk-rockchip'
> > > into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> > > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > > 'clk-ops-const' into clk-next git bisect good
> > > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into
> > > clk-meson
> > > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > > 'clk-renesas-for-v4.21-tag2' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> > > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > > 'sunxi-clk-for-4.21' of
> > > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > > clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64:
> > > Fix
> > > gate bit of DSI DPHY git bisect bad
> > > ee678706e46d0d185c27cc214ad97828e0643159
> > > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64
> > > for calculation of NM rate git bisect bad
> > > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng:
> > > sun50i:
> > > h6: Fix MMC clock mux width git bisect good
> > > db7548934603d9eda12649dff97ea5c29884405d
> > > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust
> > > MP
> > > clock parent rate when allowed git bisect bad
> > > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > > sunxi-ng: Adjust MP clock parent rate when allowed
> > > 
> > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > ---
> > > > 
> > > >  drivers/clk/sunxi-ng/ccu_mp.c | 64
> > > >  +++++++++++++++++++++++++++++++++--
> > > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > index 5d0af4051737..0357349eb767 100644
> > > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > > > unsigned long rate,>
> > > > 
> > > >  	*p = best_p;
> > > >  
> > > >  }
> > > > 
> > > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw
> > > > *hw,
> > > > +
> > 
> > unsigned long *parent,
> > 
> > > > +
> > 
> > unsigned long rate,
> > 
> > > > +
> > 
> > unsigned int max_m,
> > 
> > > > +
> > 
> > unsigned int max_p)
> > 
> > > > +{
> > > > +	unsigned long parent_rate_saved;
> > > > +	unsigned long parent_rate, now;
> > > > +	unsigned long best_rate = 0;
> > > > +	unsigned int _m, _p, div;
> > > > +	unsigned long maxdiv;
> > > > +
> > > > +	parent_rate_saved = *parent;
> > > > +
> > > > +	/*
> > > > +	 * The maximum divider we can use without overflowing
> > > > +	 * unsigned long in rate * m * p below
> > > > +	 */
> > > > +	maxdiv = max_m * max_p;
> > > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > > +
> > > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > > +		for (_m = 1; _m <= max_m; _m++) {
> > > > +			div = _m * _p;
> > > > +
> > > > +			if (div > maxdiv)
> > > > +				break;
> > > > +
> > > > +			if (rate * div == parent_rate_saved) {
> > > > +				/*
> > > > +				 * It's the most ideal case if
> > 
> > the requested
> > 
> > > > +				 * rate can be divided from
> > 
> > parent clock without
> > 
> > > > +				 * needing to change parent 
rate,
> > 
> > so return the
> > 
> > > > +				 * divider immediately.
> > > > +				 */
> > > > +				*parent = parent_rate_saved;
> > > > +				return rate;
> > > > +			}
> > > > +
> > > > +			parent_rate = clk_hw_round_rate(hw, rate *
> > 
> > div);
> > 
> > > > +			now = parent_rate / div;
> > > > +
> > > > +			if (now <= rate && now > best_rate) {
> > > > +				best_rate = now;
> > > > +				*parent = parent_rate;
> > > > +
> > > > +				if (now == rate)
> > > > +					return rate;
> > > > +			}
> > > > +		}
> > > > +	}
> > > > +
> > > > +	return best_rate;
> > > > +}
> > > > +
> > > > 
> > > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> > > >  
> > > >  				       struct clk_hw *hw,
> > > >  				       unsigned long
> > 
> > *parent_rate,
> > 
> > > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > > ccu_mux_internal *mux,>
> > > > 
> > > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > > 
> > > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > > -	rate = *parent_rate / p / m;
> > > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m,
> > 
> > &p);
> > 
> > > > +		rate = *parent_rate / p / m;
> > > > +	} else {
> > > > +		rate = ccu_mp_find_best_with_parent_adj(hw, 
parent_rate,
> > 
> > rate,
> > 
> > > > +
> > 
> > max_m, max_p);
> > 
> > > > +	}
> > > > 
> > > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > > >  	
> > > >  		rate /= cmp->fixed_post_div;
Priit Laes Jan. 17, 2019, 7:24 a.m. UTC | #5
On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > > Currently MP clocks don't consider adjusting parent rate even if they
> > > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > > possible rates, which is very inconvenient when such clock is used for
> > > > > pixel clock, for example.
> > > > > 
> > > > > In order to improve the situation, adjusting parent rate is considered
> > > > > when allowed.
> > > > > 
> > > > > This code is inspired by clk_divider_bestdiv() function, which does
> > > > > basically the same thing for different clock type.
> > > > 
> > > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > > boards:
> > > > 
> > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > 
> > > I'm not familiar with A20. What is interesting is that emmc clocks don't
> > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.
> > > 
> > > Can you post content of clk_summary with and without this patch?
> > 
> > In both cases I booted from FEL with rootfs on sdcard and tried to mount
> > partition from eMMC to /mnt. With your patch, last step it fails.
> > 
> > pre-patch working:
> > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is off?)
> > 
> > post-patch not working:
> > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > 
> > Also, attached the logs.
> 
> Thanks. Just one more request. Can you enable debug messages in mmc driver? 
> I'm interested in output of this line:
> 
> dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> 		clock, rate);

1c11000 is eMMC:
[snip]
[    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    2.203340] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    2.211412] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    4.967865] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    8.755345] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    9.082510] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000

Here I tried to mount partition from eMMC...

[   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[   72.269629] sunxi-mmc 1c11000.mmc: data error, sending stop command
[   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
[/snip]

And clock tree:
[snip]
pll-periph-base                3        3        0  1200000000          0     0  50000
   pll-periph                  6        6        0   600000000          0     0  50000
      mmc2                     3        3        0    50000000          0     0  50000
         mmc2_sample           1        1        0    50000000          0   120  50000
         mmc2_output           1        1        0    50000000          0    60  50000
      ahb                     18       18        0   300000000          0     0  50000
         ahb-mmc2              1        1        0   300000000          0     0  50000
[/snip]


And without patch:
[snip]
[    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.047129] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.054324] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.064481] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.091624] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.168067] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    2.210817] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    5.103358] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    8.950237] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[  113.707979] EXT4-fs (mmcblk1p4): recovery complete
[  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered data mode. Opts: (null)
[/snip]

And clock tree:
[snip]
pll-ddr-base                   2        2        0   768000000          0     0  50000
   pll-ddr-other               1        1        0   768000000          0     0  50000
      mmc2                     0        0        0    51200000          0     0  50000
         mmc2_sample           0        0        0    51200000          0   120  50000
         mmc2_output           0        0        0    51200000          0    72  50000
[/snip]


> 
> Just wondering what it should be.
> 
> Best regards,
> Jernej
> 
> > 
> > > Best regards,
> > > Jernej
> > > 
> > > > $ git bisect log
> > > > git bisect start
> > > > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc:
> > > > dw_mmc-bluefield:
> > > > simplify the probe() function git bisect good
> > > > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > > > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21'
> > > > of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> > > > 00d59fde8532b2d42e80909d2e58678755e04da9
> > > > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes'
> > > > into next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > > > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > > > 'locking-core-for-linus' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > 1eefdec18eded41833401cfd64749643ff72e7da
> > > > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag
> > > > 'mtd/for-4.21'
> > > > of git://git.infradead.org/linux-mtd git bisect good
> > > > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > > > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > > > 'leds-for-4.21-rc1' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
> > > > git
> > > > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > > > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git
> > > > bisect
> > > > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > > > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > > > 'irq-core-for-linus' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > e4b99d415c3908581d4703203e1e805f043a3e71
> > > > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > > > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and
> > > > 'clk-rockchip'
> > > > into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> > > > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > > > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > > > 'clk-ops-const' into clk-next git bisect good
> > > > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > > > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > > > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into
> > > > clk-meson
> > > > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > > > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > > > 'clk-renesas-for-v4.21-tag2' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> > > > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > > > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > > > 'sunxi-clk-for-4.21' of
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > > > clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > > > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64:
> > > > Fix
> > > > gate bit of DSI DPHY git bisect bad
> > > > ee678706e46d0d185c27cc214ad97828e0643159
> > > > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64
> > > > for calculation of NM rate git bisect bad
> > > > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > > > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng:
> > > > sun50i:
> > > > h6: Fix MMC clock mux width git bisect good
> > > > db7548934603d9eda12649dff97ea5c29884405d
> > > > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust
> > > > MP
> > > > clock parent rate when allowed git bisect bad
> > > > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > > > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > > > sunxi-ng: Adjust MP clock parent rate when allowed
> > > > 
> > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > ---
> > > > > 
> > > > >  drivers/clk/sunxi-ng/ccu_mp.c | 64
> > > > >  +++++++++++++++++++++++++++++++++--
> > > > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > index 5d0af4051737..0357349eb767 100644
> > > > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > > > > unsigned long rate,>
> > > > > 
> > > > >  	*p = best_p;
> > > > >  
> > > > >  }
> > > > > 
> > > > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw
> > > > > *hw,
> > > > > +
> > > 
> > > unsigned long *parent,
> > > 
> > > > > +
> > > 
> > > unsigned long rate,
> > > 
> > > > > +
> > > 
> > > unsigned int max_m,
> > > 
> > > > > +
> > > 
> > > unsigned int max_p)
> > > 
> > > > > +{
> > > > > +	unsigned long parent_rate_saved;
> > > > > +	unsigned long parent_rate, now;
> > > > > +	unsigned long best_rate = 0;
> > > > > +	unsigned int _m, _p, div;
> > > > > +	unsigned long maxdiv;
> > > > > +
> > > > > +	parent_rate_saved = *parent;
> > > > > +
> > > > > +	/*
> > > > > +	 * The maximum divider we can use without overflowing
> > > > > +	 * unsigned long in rate * m * p below
> > > > > +	 */
> > > > > +	maxdiv = max_m * max_p;
> > > > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > > > +
> > > > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > > > +		for (_m = 1; _m <= max_m; _m++) {
> > > > > +			div = _m * _p;
> > > > > +
> > > > > +			if (div > maxdiv)
> > > > > +				break;
> > > > > +
> > > > > +			if (rate * div == parent_rate_saved) {
> > > > > +				/*
> > > > > +				 * It's the most ideal case if
> > > 
> > > the requested
> > > 
> > > > > +				 * rate can be divided from
> > > 
> > > parent clock without
> > > 
> > > > > +				 * needing to change parent 
> rate,
> > > 
> > > so return the
> > > 
> > > > > +				 * divider immediately.
> > > > > +				 */
> > > > > +				*parent = parent_rate_saved;
> > > > > +				return rate;
> > > > > +			}
> > > > > +
> > > > > +			parent_rate = clk_hw_round_rate(hw, rate *
> > > 
> > > div);
> > > 
> > > > > +			now = parent_rate / div;
> > > > > +
> > > > > +			if (now <= rate && now > best_rate) {
> > > > > +				best_rate = now;
> > > > > +				*parent = parent_rate;
> > > > > +
> > > > > +				if (now == rate)
> > > > > +					return rate;
> > > > > +			}
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	return best_rate;
> > > > > +}
> > > > > +
> > > > > 
> > > > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> > > > >  
> > > > >  				       struct clk_hw *hw,
> > > > >  				       unsigned long
> > > 
> > > *parent_rate,
> > > 
> > > > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > > > ccu_mux_internal *mux,>
> > > > > 
> > > > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > > > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > > > 
> > > > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > > > -	rate = *parent_rate / p / m;
> > > > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m,
> > > 
> > > &p);
> > > 
> > > > > +		rate = *parent_rate / p / m;
> > > > > +	} else {
> > > > > +		rate = ccu_mp_find_best_with_parent_adj(hw, 
> parent_rate,
> > > 
> > > rate,
> > > 
> > > > > +
> > > 
> > > max_m, max_p);
> > > 
> > > > > +	}
> > > > > 
> > > > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > > > >  	
> > > > >  		rate /= cmp->fixed_post_div;
> 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Jernej Škrabec Jan. 18, 2019, 9:51 p.m. UTC | #6
Dne četrtek, 17. januar 2019 ob 08:24:02 CET je Priit Laes napisal(a):
> On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> > Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > > > Currently MP clocks don't consider adjusting parent rate even if
> > > > > > they
> > > > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > > > possible rates, which is very inconvenient when such clock is used
> > > > > > for
> > > > > > pixel clock, for example.
> > > > > > 
> > > > > > In order to improve the situation, adjusting parent rate is
> > > > > > considered
> > > > > > when allowed.
> > > > > > 
> > > > > > This code is inspired by clk_divider_bestdiv() function, which
> > > > > > does
> > > > > > basically the same thing for different clock type.
> > > > > 
> > > > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > > > boards:
> > > > > 
> > > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > > 
> > > > I'm not familiar with A20. What is interesting is that emmc clocks
> > > > don't
> > > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any
> > > > difference.
> > > > 
> > > > Can you post content of clk_summary with and without this patch?
> > > 
> > > In both cases I booted from FEL with rootfs on sdcard and tried to mount
> > > partition from eMMC to /mnt. With your patch, last step it fails.
> > > 
> > > pre-patch working:
> > > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is
> > > off?)
> > > 
> > > post-patch not working:
> > > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > > 
> > > Also, attached the logs.
> > 
> > Thanks. Just one more request. Can you enable debug messages in mmc
> > driver?
> > I'm interested in output of this line:
> > 
> > dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> > 
> > 		clock, rate);
> 
> 1c11000 is eMMC:
> [snip]
> [    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> 52000000 [    2.203340] sunxi-mmc 1c11000.mmc: setting clk to 52000000,
> rounded 52000000 [    2.211412] sunxi-mmc 1c11000.mmc: setting clk to
> 52000000, rounded 52000000 [    4.967865] sunxi-mmc 1c11000.mmc: setting
> clk to 52000000, rounded 52000000 [    8.755345] sunxi-mmc 1c11000.mmc:
> setting clk to 52000000, rounded 52000000 [    9.082510] sunxi-mmc
> 1c11000.mmc: setting clk to 52000000, rounded 52000000
> 
> Here I tried to mount partition from eMMC...
> 
> [   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> 52000000 [   72.269629] sunxi-mmc 1c11000.mmc: data error, sending stop
> command [   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
> [/snip]
> 
> And clock tree:
> [snip]
> pll-periph-base                3        3        0  1200000000          0   
>  0  50000 pll-periph                  6        6        0   600000000      
>    0     0  50000 mmc2                     3        3        0    50000000 
>         0     0  50000 mmc2_sample           1        1        0   
> 50000000          0   120  50000 mmc2_output           1        1        0 
>   50000000          0    60  50000 ahb                     18       18     
>   0   300000000          0     0  50000 ahb-mmc2              1        1   
>     0   300000000          0     0  50000 [/snip]
> 
> 
> And without patch:
> [snip]
> [    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded
> 400000 [    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000,
> rounded 400000 [    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> 400000, rounded 400000 [    2.047129] sunxi-mmc 1c11000.mmc: XXX: setting
> clk to 400000, rounded 400000 [    2.054324] sunxi-mmc 1c11000.mmc: XXX:
> setting clk to 400000, rounded 400000 [    2.064481] sunxi-mmc 1c11000.mmc:
> XXX: setting clk to 400000, rounded 400000 [    2.091624] sunxi-mmc
> 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [    2.168067]
> sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [   
> 2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> 51200000 [    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> 52000000, rounded 51200000 [    2.210817] sunxi-mmc 1c11000.mmc: XXX:
> setting clk to 52000000, rounded 51200000 [    5.103358] sunxi-mmc
> 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [    8.950237]
> sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [   
> 9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> 51200000 [  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> 52000000, rounded 51200000 [  113.707979] EXT4-fs (mmcblk1p4): recovery
> complete
> [  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered data
> mode. Opts: (null) [/snip]
> 
> And clock tree:
> [snip]
> pll-ddr-base                   2        2        0   768000000          0   
>  0  50000 pll-ddr-other               1        1        0   768000000      
>    0     0  50000 mmc2                     0        0        0    51200000 
>         0     0  50000 mmc2_sample           0        0        0   
> 51200000          0   120  50000 mmc2_output           0        0        0 
>   51200000          0    72  50000 [/snip]
> 

It seems to me that clock rate is set properly. It's even better than before 
since there is no error between wanted and real clock. I bet that if you call 
clk_get_rate() directly behind clk_set_rate() in mmc driver, you'll get 
correct value.

However, it seems that at some point some other peripheral changes it's parent 
clock rate, which inadvertely changes emmc2 clock rate too. The only possible 
clock which could interfere is sata. Can you disable driver in you kernel 
config and try again?

Best regards,
Jernej

> > Just wondering what it should be.
> > 
> > Best regards,
> > Jernej
> > 
> > > > Best regards,
> > > > Jernej
> > > > 
> > > > > $ git bisect log
> > > > > git bisect start
> > > > > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc:
> > > > > dw_mmc-bluefield:
> > > > > simplify the probe() function git bisect good
> > > > > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > > > > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag
> > > > > 'mmc-v4.21'
> > > > > of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect
> > > > > bad
> > > > > 00d59fde8532b2d42e80909d2e58678755e04da9
> > > > > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch
> > > > > 'fixes'
> > > > > into next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > > > > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > > > > 'locking-core-for-linus' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > > 1eefdec18eded41833401cfd64749643ff72e7da
> > > > > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag
> > > > > 'mtd/for-4.21'
> > > > > of git://git.infradead.org/linux-mtd git bisect good
> > > > > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > > > > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > > > > 'leds-for-4.21-rc1' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-led
> > > > > s
> > > > > git
> > > > > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > > > > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git
> > > > > bisect
> > > > > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > > > > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > > > > 'irq-core-for-linus' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > > e4b99d415c3908581d4703203e1e805f043a3e71
> > > > > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > > > > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and
> > > > > 'clk-rockchip'
> > > > > into clk-next git bisect bad
> > > > > ffe05540d18013db62c43627836a3638e9a2c7aa
> > > > > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > > > > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > > > > 'clk-ops-const' into clk-next git bisect good
> > > > > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > > > > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > > > > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into
> > > > > clk-meson
> > > > > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > > > > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > > > > 'clk-renesas-for-v4.21-tag2' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers
> > > > > into
> > > > > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > > > > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > > > > 'sunxi-clk-for-4.21' of
> > > > > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > > > > clk-allwinner git bisect bad
> > > > > a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > > > > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng:
> > > > > a64:
> > > > > Fix
> > > > > gate bit of DSI DPHY git bisect bad
> > > > > ee678706e46d0d185c27cc214ad97828e0643159
> > > > > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use
> > > > > u64
> > > > > for calculation of NM rate git bisect bad
> > > > > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > > > > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng:
> > > > > sun50i:
> > > > > h6: Fix MMC clock mux width git bisect good
> > > > > db7548934603d9eda12649dff97ea5c29884405d
> > > > > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng:
> > > > > Adjust
> > > > > MP
> > > > > clock parent rate when allowed git bisect bad
> > > > > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > > > > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > > > > sunxi-ng: Adjust MP clock parent rate when allowed
> > > > > 
> > > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > > ---
> > > > > > 
> > > > > >  drivers/clk/sunxi-ng/ccu_mp.c | 64
> > > > > >  +++++++++++++++++++++++++++++++++--
> > > > > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > index 5d0af4051737..0357349eb767 100644
> > > > > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long
> > > > > > parent,
> > > > > > unsigned long rate,>
> > > > > > 
> > > > > >  	*p = best_p;
> > > > > >  
> > > > > >  }
> > > > > > 
> > > > > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct
> > > > > > clk_hw
> > > > > > *hw,
> > > > > > +
> > > > 
> > > > unsigned long *parent,
> > > > 
> > > > > > +
> > > > 
> > > > unsigned long rate,
> > > > 
> > > > > > +
> > > > 
> > > > unsigned int max_m,
> > > > 
> > > > > > +
> > > > 
> > > > unsigned int max_p)
> > > > 
> > > > > > +{
> > > > > > +	unsigned long parent_rate_saved;
> > > > > > +	unsigned long parent_rate, now;
> > > > > > +	unsigned long best_rate = 0;
> > > > > > +	unsigned int _m, _p, div;
> > > > > > +	unsigned long maxdiv;
> > > > > > +
> > > > > > +	parent_rate_saved = *parent;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * The maximum divider we can use without overflowing
> > > > > > +	 * unsigned long in rate * m * p below
> > > > > > +	 */
> > > > > > +	maxdiv = max_m * max_p;
> > > > > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > > > > +
> > > > > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > > > > +		for (_m = 1; _m <= max_m; _m++) {
> > > > > > +			div = _m * _p;
> > > > > > +
> > > > > > +			if (div > maxdiv)
> > > > > > +				break;
> > > > > > +
> > > > > > +			if (rate * div == parent_rate_saved) {
> > > > > > +				/*
> > > > > > +				 * It's the most ideal case if
> > > > 
> > > > the requested
> > > > 
> > > > > > +				 * rate can be divided from
> > > > 
> > > > parent clock without
> > > > 
> > > > > > +				 * needing to change parent
> > 
> > rate,
> > 
> > > > so return the
> > > > 
> > > > > > +				 * divider immediately.
> > > > > > +				 */
> > > > > > +				*parent = parent_rate_saved;
> > > > > > +				return rate;
> > > > > > +			}
> > > > > > +
> > > > > > +			parent_rate = clk_hw_round_rate(hw, rate *
> > > > 
> > > > div);
> > > > 
> > > > > > +			now = parent_rate / div;
> > > > > > +
> > > > > > +			if (now <= rate && now > best_rate) {
> > > > > > +				best_rate = now;
> > > > > > +				*parent = parent_rate;
> > > > > > +
> > > > > > +				if (now == rate)
> > > > > > +					return rate;
> > > > > > +			}
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	return best_rate;
> > > > > > +}
> > > > > > +
> > > > > > 
> > > > > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal
> > > > > >  *mux,
> > > > > >  
> > > > > >  				       struct clk_hw *hw,
> > > > > >  				       unsigned long
> > > > 
> > > > *parent_rate,
> > > > 
> > > > > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > > > > ccu_mux_internal *mux,>
> > > > > > 
> > > > > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > > > > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > > > > 
> > > > > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > > > > -	rate = *parent_rate / p / m;
> > > > > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > > > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m,
> > > > 
> > > > &p);
> > > > 
> > > > > > +		rate = *parent_rate / p / m;
> > > > > > +	} else {
> > > > > > +		rate = ccu_mp_find_best_with_parent_adj(hw,
> > 
> > parent_rate,
> > 
> > > > rate,
> > > > 
> > > > > > +
> > > > 
> > > > max_m, max_p);
> > > > 
> > > > > > +	}
> > > > > > 
> > > > > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > > > > >  	
> > > > > >  		rate /= cmp->fixed_post_div;
Priit Laes Jan. 21, 2019, 8:37 a.m. UTC | #7
On Fri, Jan 18, 2019 at 10:51:10PM +0100, Jernej Škrabec wrote:
> Dne četrtek, 17. januar 2019 ob 08:24:02 CET je Priit Laes napisal(a):
> > On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> > > Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > > > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > > > > Currently MP clocks don't consider adjusting parent rate even if
> > > > > > > they
> > > > > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > > > > possible rates, which is very inconvenient when such clock is used
> > > > > > > for
> > > > > > > pixel clock, for example.
> > > > > > > 
> > > > > > > In order to improve the situation, adjusting parent rate is
> > > > > > > considered
> > > > > > > when allowed.
> > > > > > > 
> > > > > > > This code is inspired by clk_divider_bestdiv() function, which
> > > > > > > does
> > > > > > > basically the same thing for different clock type.
> > > > > > 
> > > > > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > > > > boards:
> > > > > > 
> > > > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > > > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > > > 
> > > > > I'm not familiar with A20. What is interesting is that emmc clocks
> > > > > don't
> > > > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any
> > > > > difference.
> > > > > 
> > > > > Can you post content of clk_summary with and without this patch?
> > > > 
> > > > In both cases I booted from FEL with rootfs on sdcard and tried to mount
> > > > partition from eMMC to /mnt. With your patch, last step it fails.
> > > > 
> > > > pre-patch working:
> > > > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is
> > > > off?)
> > > > 
> > > > post-patch not working:
> > > > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > > > 
> > > > Also, attached the logs.
> > > 
> > > Thanks. Just one more request. Can you enable debug messages in mmc
> > > driver?
> > > I'm interested in output of this line:
> > > 
> > > dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> > > 
> > > 		clock, rate);
> > 
> > 1c11000 is eMMC:
> > [snip]
> > [    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > [    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > 52000000 [    2.203340] sunxi-mmc 1c11000.mmc: setting clk to 52000000,
> > rounded 52000000 [    2.211412] sunxi-mmc 1c11000.mmc: setting clk to
> > 52000000, rounded 52000000 [    4.967865] sunxi-mmc 1c11000.mmc: setting
> > clk to 52000000, rounded 52000000 [    8.755345] sunxi-mmc 1c11000.mmc:
> > setting clk to 52000000, rounded 52000000 [    9.082510] sunxi-mmc
> > 1c11000.mmc: setting clk to 52000000, rounded 52000000
> > 
> > Here I tried to mount partition from eMMC...
> > 
> > [   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > 52000000 [   72.269629] sunxi-mmc 1c11000.mmc: data error, sending stop
> > command [   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
> > [/snip]
> > 
> > And clock tree:
> > [snip]
> > pll-periph-base                3        3        0  1200000000          0   
> >  0  50000 pll-periph                  6        6        0   600000000      
> >    0     0  50000 mmc2                     3        3        0    50000000 
> >         0     0  50000 mmc2_sample           1        1        0   
> > 50000000          0   120  50000 mmc2_output           1        1        0 
> >   50000000          0    60  50000 ahb                     18       18     
> >   0   300000000          0     0  50000 ahb-mmc2              1        1   
> >     0   300000000          0     0  50000 [/snip]
> > 
> > 
> > And without patch:
> > [snip]
> > [    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded
> > 400000 [    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000,
> > rounded 400000 [    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > 400000, rounded 400000 [    2.047129] sunxi-mmc 1c11000.mmc: XXX: setting
> > clk to 400000, rounded 400000 [    2.054324] sunxi-mmc 1c11000.mmc: XXX:
> > setting clk to 400000, rounded 400000 [    2.064481] sunxi-mmc 1c11000.mmc:
> > XXX: setting clk to 400000, rounded 400000 [    2.091624] sunxi-mmc
> > 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [    2.168067]
> > sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [   
> > 2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > 51200000 [    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > 52000000, rounded 51200000 [    2.210817] sunxi-mmc 1c11000.mmc: XXX:
> > setting clk to 52000000, rounded 51200000 [    5.103358] sunxi-mmc
> > 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [    8.950237]
> > sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [   
> > 9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > 51200000 [  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > 52000000, rounded 51200000 [  113.707979] EXT4-fs (mmcblk1p4): recovery
> > complete
> > [  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered data
> > mode. Opts: (null) [/snip]
> > 
> > And clock tree:
> > [snip]
> > pll-ddr-base                   2        2        0   768000000          0   
> >  0  50000 pll-ddr-other               1        1        0   768000000      
> >    0     0  50000 mmc2                     0        0        0    51200000 
> >         0     0  50000 mmc2_sample           0        0        0   
> > 51200000          0   120  50000 mmc2_output           0        0        0 
> >   51200000          0    72  50000 [/snip]
> > 
> 
> It seems to me that clock rate is set properly. It's even better than before 
> since there is no error between wanted and real clock. I bet that if you call 
> clk_get_rate() directly behind clk_set_rate() in mmc driver, you'll get 
> correct value.
> 
> However, it seems that at some point some other peripheral changes it's parent 
> clock rate, which inadvertely changes emmc2 clock rate too. The only possible 
> clock which could interfere is sata. Can you disable driver in you kernel 
> config and try again?

OK, tried following things in succession, but SATA disabling does not work:

a) Marked all ahci stuff in devicetree as disabled
b) Disable CONFIG_AHCI_SUNXI in kernel
c) Even disabled SATA stuff in u-boot

> 
> Best regards,
> Jernej
Priit Laes Jan. 21, 2019, 1:34 p.m. UTC | #8
On Mon, Jan 21, 2019 at 08:37:29AM +0000, Priit Laes wrote:
> On Fri, Jan 18, 2019 at 10:51:10PM +0100, Jernej Škrabec wrote:
> > Dne četrtek, 17. januar 2019 ob 08:24:02 CET je Priit Laes napisal(a):
> > > On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> > > > Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > > > > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > > > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > > > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > > > > > Currently MP clocks don't consider adjusting parent rate even if
> > > > > > > > they
> > > > > > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > > > > > possible rates, which is very inconvenient when such clock is used
> > > > > > > > for
> > > > > > > > pixel clock, for example.
> > > > > > > > 
> > > > > > > > In order to improve the situation, adjusting parent rate is
> > > > > > > > considered
> > > > > > > > when allowed.
> > > > > > > > 
> > > > > > > > This code is inspired by clk_divider_bestdiv() function, which
> > > > > > > > does
> > > > > > > > basically the same thing for different clock type.
> > > > > > > 
> > > > > > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > > > > > boards:
> > > > > > > 
> > > > > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > > > > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > > > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > > > > 
> > > > > > I'm not familiar with A20. What is interesting is that emmc clocks
> > > > > > don't
> > > > > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any
> > > > > > difference.
> > > > > > 
> > > > > > Can you post content of clk_summary with and without this patch?
> > > > > 
> > > > > In both cases I booted from FEL with rootfs on sdcard and tried to mount
> > > > > partition from eMMC to /mnt. With your patch, last step it fails.
> > > > > 
> > > > > pre-patch working:
> > > > > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is
> > > > > off?)
> > > > > 
> > > > > post-patch not working:
> > > > > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > > > > 
> > > > > Also, attached the logs.
> > > > 
> > > > Thanks. Just one more request. Can you enable debug messages in mmc
> > > > driver?
> > > > I'm interested in output of this line:
> > > > 
> > > > dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> > > > 
> > > > 		clock, rate);
> > > 
> > > 1c11000 is eMMC:
> > > [snip]
> > > [    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> > > [    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > > 52000000 [    2.203340] sunxi-mmc 1c11000.mmc: setting clk to 52000000,
> > > rounded 52000000 [    2.211412] sunxi-mmc 1c11000.mmc: setting clk to
> > > 52000000, rounded 52000000 [    4.967865] sunxi-mmc 1c11000.mmc: setting
> > > clk to 52000000, rounded 52000000 [    8.755345] sunxi-mmc 1c11000.mmc:
> > > setting clk to 52000000, rounded 52000000 [    9.082510] sunxi-mmc
> > > 1c11000.mmc: setting clk to 52000000, rounded 52000000
> > > 
> > > Here I tried to mount partition from eMMC...
> > > 
> > > [   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > > 52000000 [   72.269629] sunxi-mmc 1c11000.mmc: data error, sending stop
> > > command [   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
> > > [/snip]
> > > 
> > > And clock tree:
> > > [snip]
> > > pll-periph-base                3        3        0  1200000000          0   
> > >  0  50000 pll-periph                  6        6        0   600000000      
> > >    0     0  50000 mmc2                     3        3        0    50000000 
> > >         0     0  50000 mmc2_sample           1        1        0   
> > > 50000000          0   120  50000 mmc2_output           1        1        0 
> > >   50000000          0    60  50000 ahb                     18       18     
> > >   0   300000000          0     0  50000 ahb-mmc2              1        1   
> > >     0   300000000          0     0  50000 [/snip]
> > > 
> > > 
> > > And without patch:
> > > [snip]
> > > [    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded
> > > 400000 [    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000,
> > > rounded 400000 [    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > 400000, rounded 400000 [    2.047129] sunxi-mmc 1c11000.mmc: XXX: setting
> > > clk to 400000, rounded 400000 [    2.054324] sunxi-mmc 1c11000.mmc: XXX:
> > > setting clk to 400000, rounded 400000 [    2.064481] sunxi-mmc 1c11000.mmc:
> > > XXX: setting clk to 400000, rounded 400000 [    2.091624] sunxi-mmc
> > > 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [    2.168067]
> > > sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [   
> > > 2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > > 51200000 [    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > 52000000, rounded 51200000 [    2.210817] sunxi-mmc 1c11000.mmc: XXX:
> > > setting clk to 52000000, rounded 51200000 [    5.103358] sunxi-mmc
> > > 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [    8.950237]
> > > sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [   
> > > 9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > > 51200000 [  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > 52000000, rounded 51200000 [  113.707979] EXT4-fs (mmcblk1p4): recovery
> > > complete
> > > [  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered data
> > > mode. Opts: (null) [/snip]
> > > 
> > > And clock tree:
> > > [snip]
> > > pll-ddr-base                   2        2        0   768000000          0   
> > >  0  50000 pll-ddr-other               1        1        0   768000000      
> > >    0     0  50000 mmc2                     0        0        0    51200000 
> > >         0     0  50000 mmc2_sample           0        0        0   
> > > 51200000          0   120  50000 mmc2_output           0        0        0 
> > >   51200000          0    72  50000 [/snip]
> > > 
> > 
> > It seems to me that clock rate is set properly. It's even better than before 
> > since there is no error between wanted and real clock. I bet that if you call 
> > clk_get_rate() directly behind clk_set_rate() in mmc driver, you'll get 
> > correct value.
> > 
> > However, it seems that at some point some other peripheral changes it's parent 
> > clock rate, which inadvertely changes emmc2 clock rate too. The only possible 
> > clock which could interfere is sata. Can you disable driver in you kernel 
> > config and try again?
> 
> OK, tried following things in succession, but SATA disabling does not work:
> 
> a) Marked all ahci stuff in devicetree as disabled
> b) Disable CONFIG_AHCI_SUNXI in kernel
> c) Even disabled SATA stuff in u-boot

But it works, when I allow mmc2 clock to set parent rate:

pll-periph-base                3        3        0   312000000          0     0  50000
   mbus                        1        1        0    78000000          0     0  50000
   pll-periph-sata             1        1        0    26000000          0     0  50000
      sata                     1        1        0    26000000          0     0  50000
   pll-periph                  5        5        0   156000000          0     0  50000
      mmc2                     0        0        0    52000000          0     0  50000
         mmc2_sample           0        0        0    52000000          0   120  50000
         mmc2_output           0        0        0    52000000          0   120  50000
      mmc0                     0        0        0    39000000          0     0  50000
         mmc0_sample           0        0        0    39000000          0    90  50000
         mmc0_output           0        0        0    39000000          0    90  50000


Now, what I don't understand is why the `enable count` does not increase :(

---
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
index 129ebd2588fd..605e13b4ef90 100644
--- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
@@ -498,7 +498,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
                                  16, 2,        /* P */
                                  24, 2,        /* mux */
                                  BIT(31),      /* gate */
-                                 0);
+                                 CLK_SET_RATE_PARENT);
 
 /* MMC output and sample clocks are not present on A10 */
 static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",


> 
> > 
> > Best regards,
> > Jernej
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Jernej Škrabec Jan. 21, 2019, 6:13 p.m. UTC | #9
Dne ponedeljek, 21. januar 2019 ob 14:34:33 CET je Priit Laes napisal(a):
> On Mon, Jan 21, 2019 at 08:37:29AM +0000, Priit Laes wrote:
> > On Fri, Jan 18, 2019 at 10:51:10PM +0100, Jernej Škrabec wrote:
> > > Dne četrtek, 17. januar 2019 ob 08:24:02 CET je Priit Laes napisal(a):
> > > > On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> > > > > Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > > > > > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > > > > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes 
napisal(a):
> > > > > > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec 
wrote:
> > > > > > > > > Currently MP clocks don't consider adjusting parent rate
> > > > > > > > > even if
> > > > > > > > > they
> > > > > > > > > are allowed to do so. Such behaviour considerably lowers
> > > > > > > > > amount of
> > > > > > > > > possible rates, which is very inconvenient when such clock
> > > > > > > > > is used
> > > > > > > > > for
> > > > > > > > > pixel clock, for example.
> > > > > > > > > 
> > > > > > > > > In order to improve the situation, adjusting parent rate is
> > > > > > > > > considered
> > > > > > > > > when allowed.
> > > > > > > > > 
> > > > > > > > > This code is inspired by clk_divider_bestdiv() function,
> > > > > > > > > which
> > > > > > > > > does
> > > > > > > > > basically the same thing for different clock type.
> > > > > > > > 
> > > > > > > > This patch seems to break the eMMC support on
> > > > > > > > Olinuxino-Lime2-eMMC
> > > > > > > > boards:
> > > > > > > > 
> > > > > > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly
> > > > > > > > filesystem
> > > > > > > > EXT4-fs (mmcblk1p4): write access will be enabled during
> > > > > > > > recovery
> > > > > > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > > > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > > > > > 
> > > > > > > I'm not familiar with A20. What is interesting is that emmc
> > > > > > > clocks
> > > > > > > don't
> > > > > > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any
> > > > > > > difference.
> > > > > > > 
> > > > > > > Can you post content of clk_summary with and without this patch?
> > > > > > 
> > > > > > In both cases I booted from FEL with rootfs on sdcard and tried to
> > > > > > mount
> > > > > > partition from eMMC to /mnt. With your patch, last step it fails.
> > > > > > 
> > > > > > pre-patch working:
> > > > > > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2
> > > > > > is
> > > > > > off?)
> > > > > > 
> > > > > > post-patch not working:
> > > > > > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > > > > > 
> > > > > > Also, attached the logs.
> > > > > 
> > > > > Thanks. Just one more request. Can you enable debug messages in mmc
> > > > > driver?
> > > > > I'm interested in output of this line:
> > > > > 
> > > > > dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> > > > > 
> > > > > 		clock, rate);
> > > > 
> > > > 1c11000 is eMMC:
> > > > [snip]
> > > > [    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > 400000
> > > > [    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > > > 52000000 [    2.203340] sunxi-mmc 1c11000.mmc: setting clk to
> > > > 52000000,
> > > > rounded 52000000 [    2.211412] sunxi-mmc 1c11000.mmc: setting clk to
> > > > 52000000, rounded 52000000 [    4.967865] sunxi-mmc 1c11000.mmc:
> > > > setting
> > > > clk to 52000000, rounded 52000000 [    8.755345] sunxi-mmc
> > > > 1c11000.mmc:
> > > > setting clk to 52000000, rounded 52000000 [    9.082510] sunxi-mmc
> > > > 1c11000.mmc: setting clk to 52000000, rounded 52000000
> > > > 
> > > > Here I tried to mount partition from eMMC...
> > > > 
> > > > [   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > > > 52000000 [   72.269629] sunxi-mmc 1c11000.mmc: data error, sending
> > > > stop
> > > > command [   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
> > > > [/snip]
> > > > 
> > > > And clock tree:
> > > > [snip]
> > > > pll-periph-base                3        3        0  1200000000        
> > > >  0
> > > > 
> > > >  0  50000 pll-periph                  6        6        0   600000000
> > > >  
> > > >    0     0  50000 mmc2                     3        3        0   
> > > >    50000000
> > > >    
> > > >         0     0  50000 mmc2_sample           1        1        0
> > > > 
> > > > 50000000          0   120  50000 mmc2_output           1        1     
> > > >   0
> > > > 
> > > >   50000000          0    60  50000 ahb                     18       18
> > > >   0   300000000          0     0  50000 ahb-mmc2              1       
> > > >   1
> > > >   
> > > >     0   300000000          0     0  50000 [/snip]
> > > > 
> > > > And without patch:
> > > > [snip]
> > > > [    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000,
> > > > rounded
> > > > 400000 [    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > > 400000,
> > > > rounded 400000 [    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk
> > > > to
> > > > 400000, rounded 400000 [    2.047129] sunxi-mmc 1c11000.mmc: XXX:
> > > > setting
> > > > clk to 400000, rounded 400000 [    2.054324] sunxi-mmc 1c11000.mmc:
> > > > XXX:
> > > > setting clk to 400000, rounded 400000 [    2.064481] sunxi-mmc
> > > > 1c11000.mmc:
> > > > XXX: setting clk to 400000, rounded 400000 [    2.091624] sunxi-mmc
> > > > 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [    2.168067]
> > > > sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [
> > > > 2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > > > 51200000 [    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > > 52000000, rounded 51200000 [    2.210817] sunxi-mmc 1c11000.mmc: XXX:
> > > > setting clk to 52000000, rounded 51200000 [    5.103358] sunxi-mmc
> > > > 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [   
> > > > 8.950237]
> > > > sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
> > > > [
> > > > 9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > > > 51200000 [  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > > 52000000, rounded 51200000 [  113.707979] EXT4-fs (mmcblk1p4):
> > > > recovery
> > > > complete
> > > > [  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered
> > > > data
> > > > mode. Opts: (null) [/snip]
> > > > 
> > > > And clock tree:
> > > > [snip]
> > > > pll-ddr-base                   2        2        0   768000000        
> > > >  0
> > > > 
> > > >  0  50000 pll-ddr-other               1        1        0   768000000
> > > >  
> > > >    0     0  50000 mmc2                     0        0        0   
> > > >    51200000
> > > >    
> > > >         0     0  50000 mmc2_sample           0        0        0
> > > > 
> > > > 51200000          0   120  50000 mmc2_output           0        0     
> > > >   0
> > > > 
> > > >   51200000          0    72  50000 [/snip]
> > > 
> > > It seems to me that clock rate is set properly. It's even better than
> > > before since there is no error between wanted and real clock. I bet
> > > that if you call clk_get_rate() directly behind clk_set_rate() in mmc
> > > driver, you'll get correct value.
> > > 
> > > However, it seems that at some point some other peripheral changes it's
> > > parent clock rate, which inadvertely changes emmc2 clock rate too. The
> > > only possible clock which could interfere is sata. Can you disable
> > > driver in you kernel config and try again?
> > 
> > OK, tried following things in succession, but SATA disabling does not
> > work:
> > 
> > a) Marked all ahci stuff in devicetree as disabled
> > b) Disable CONFIG_AHCI_SUNXI in kernel
> > c) Even disabled SATA stuff in u-boot
> 
> But it works, when I allow mmc2 clock to set parent rate:

Strange, I checked both pre- and post- patch clk_summary you sent me and in 
both cases both mmc2 parent clocks have same rate as before. This would need a 
more detailed analysis with a lot of debug print, but don't have such board.

CLK_SET_PARENT rate might be viable solution, but  you have to be sure that 
any clock using pll-periph as a parent is in expected range.

On the plus side, if this works, eMMC will work faster due to 8 MHz clock rate 
increase :)

> 
> pll-periph-base                3        3        0   312000000          0   
>  0  50000 mbus                        1        1        0    78000000      
>    0     0  50000 pll-periph-sata             1        1        0   
> 26000000          0     0  50000 sata                     1        1       
> 0    26000000          0     0  50000 pll-periph                  5       
> 5        0   156000000          0     0  50000 mmc2                     0  
>      0        0    52000000          0     0  50000 mmc2_sample           0
>        0        0    52000000          0   120  50000 mmc2_output          
> 0        0        0    52000000          0   120  50000 mmc0               
>      0        0        0    39000000          0     0  50000 mmc0_sample   
>        0        0        0    39000000          0    90  50000 mmc0_output 
>          0        0        0    39000000          0    90  50000
> 
> 
> Now, what I don't understand is why the `enable count` does not increase :(

mmc has suspend/resume functionality which might power down mmc when not in 
use and thus disable clocks. Try initiate some big transfer from/to eMMC and 
check clocks in between.

BR,
Jernej

> 
> ---
> diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
> b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c index 129ebd2588fd..605e13b4ef90
> 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
> @@ -498,7 +498,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2",
> mod0_default_parents, 0x090, 16, 2,        /* P */
>                                   24, 2,        /* mux */
>                                   BIT(31),      /* gate */
> -                                 0);
> +                                 CLK_SET_RATE_PARENT);
> 
>  /* MMC output and sample clocks are not present on A10 */
>  static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
> 
> > > Best regards,
> > > Jernej
Priit Laes March 19, 2019, 10:34 a.m. UTC | #10
On Mon, Jan 21, 2019 at 07:13:07PM +0100, Jernej Škrabec wrote:
> Dne ponedeljek, 21. januar 2019 ob 14:34:33 CET je Priit Laes napisal(a):
> > On Mon, Jan 21, 2019 at 08:37:29AM +0000, Priit Laes wrote:
> > > On Fri, Jan 18, 2019 at 10:51:10PM +0100, Jernej Škrabec wrote:
> > > > Dne četrtek, 17. januar 2019 ob 08:24:02 CET je Priit Laes napisal(a):
> > > > > On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> > > > > > Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > > > > > > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > > > > > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes 
> napisal(a):
> > > > > > > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec 
> wrote:
> > > > > > > > > > Currently MP clocks don't consider adjusting parent rate
> > > > > > > > > > even if
> > > > > > > > > > they
> > > > > > > > > > are allowed to do so. Such behaviour considerably lowers
> > > > > > > > > > amount of
> > > > > > > > > > possible rates, which is very inconvenient when such clock
> > > > > > > > > > is used
> > > > > > > > > > for
> > > > > > > > > > pixel clock, for example.
> > > > > > > > > > 
> > > > > > > > > > In order to improve the situation, adjusting parent rate is
> > > > > > > > > > considered
> > > > > > > > > > when allowed.
> > > > > > > > > > 
> > > > > > > > > > This code is inspired by clk_divider_bestdiv() function,
> > > > > > > > > > which
> > > > > > > > > > does
> > > > > > > > > > basically the same thing for different clock type.
> > > > > > > > > 
> > > > > > > > > This patch seems to break the eMMC support on
> > > > > > > > > Olinuxino-Lime2-eMMC
> > > > > > > > > boards:
> > > > > > > > > 
> > > > > > > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly
> > > > > > > > > filesystem
> > > > > > > > > EXT4-fs (mmcblk1p4): write access will be enabled during
> > > > > > > > > recovery
> > > > > > > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > > > > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > > > > > > 
> > > > > > > > I'm not familiar with A20. What is interesting is that emmc
> > > > > > > > clocks
> > > > > > > > don't
> > > > > > > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any
> > > > > > > > difference.
> > > > > > > > 
> > > > > > > > Can you post content of clk_summary with and without this patch?
> > > > > > > 
> > > > > > > In both cases I booted from FEL with rootfs on sdcard and tried to
> > > > > > > mount
> > > > > > > partition from eMMC to /mnt. With your patch, last step it fails.
> > > > > > > 
> > > > > > > pre-patch working:
> > > > > > > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2
> > > > > > > is
> > > > > > > off?)
> > > > > > > 
> > > > > > > post-patch not working:
> > > > > > > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > > > > > > 
> > > > > > > Also, attached the logs.
> > > > > > 
> > > > > > Thanks. Just one more request. Can you enable debug messages in mmc
> > > > > > driver?
> > > > > > I'm interested in output of this line:
> > > > > > 
> > > > > > dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> > > > > > 
> > > > > > 		clock, rate);
> > > > > 
> > > > > 1c11000 is eMMC:
> > > > > [snip]
> > > > > [    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded
> > > > > 400000
> > > > > [    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > > > > 52000000 [    2.203340] sunxi-mmc 1c11000.mmc: setting clk to
> > > > > 52000000,
> > > > > rounded 52000000 [    2.211412] sunxi-mmc 1c11000.mmc: setting clk to
> > > > > 52000000, rounded 52000000 [    4.967865] sunxi-mmc 1c11000.mmc:
> > > > > setting
> > > > > clk to 52000000, rounded 52000000 [    8.755345] sunxi-mmc
> > > > > 1c11000.mmc:
> > > > > setting clk to 52000000, rounded 52000000 [    9.082510] sunxi-mmc
> > > > > 1c11000.mmc: setting clk to 52000000, rounded 52000000
> > > > > 
> > > > > Here I tried to mount partition from eMMC...
> > > > > 
> > > > > [   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> > > > > 52000000 [   72.269629] sunxi-mmc 1c11000.mmc: data error, sending
> > > > > stop
> > > > > command [   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
> > > > > [/snip]
> > > > > 
> > > > > And clock tree:
> > > > > [snip]
> > > > > pll-periph-base                3        3        0  1200000000        
> > > > >  0
> > > > > 
> > > > >  0  50000 pll-periph                  6        6        0   600000000
> > > > >  
> > > > >    0     0  50000 mmc2                     3        3        0   
> > > > >    50000000
> > > > >    
> > > > >         0     0  50000 mmc2_sample           1        1        0
> > > > > 
> > > > > 50000000          0   120  50000 mmc2_output           1        1     
> > > > >   0
> > > > > 
> > > > >   50000000          0    60  50000 ahb                     18       18
> > > > >   0   300000000          0     0  50000 ahb-mmc2              1       
> > > > >   1
> > > > >   
> > > > >     0   300000000          0     0  50000 [/snip]
> > > > > 
> > > > > And without patch:
> > > > > [snip]
> > > > > [    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000,
> > > > > rounded
> > > > > 400000 [    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > > > 400000,
> > > > > rounded 400000 [    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk
> > > > > to
> > > > > 400000, rounded 400000 [    2.047129] sunxi-mmc 1c11000.mmc: XXX:
> > > > > setting
> > > > > clk to 400000, rounded 400000 [    2.054324] sunxi-mmc 1c11000.mmc:
> > > > > XXX:
> > > > > setting clk to 400000, rounded 400000 [    2.064481] sunxi-mmc
> > > > > 1c11000.mmc:
> > > > > XXX: setting clk to 400000, rounded 400000 [    2.091624] sunxi-mmc
> > > > > 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [    2.168067]
> > > > > sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [
> > > > > 2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > > > > 51200000 [    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > > > 52000000, rounded 51200000 [    2.210817] sunxi-mmc 1c11000.mmc: XXX:
> > > > > setting clk to 52000000, rounded 51200000 [    5.103358] sunxi-mmc
> > > > > 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [   
> > > > > 8.950237]
> > > > > sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
> > > > > [
> > > > > 9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> > > > > 51200000 [  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> > > > > 52000000, rounded 51200000 [  113.707979] EXT4-fs (mmcblk1p4):
> > > > > recovery
> > > > > complete
> > > > > [  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered
> > > > > data
> > > > > mode. Opts: (null) [/snip]
> > > > > 
> > > > > And clock tree:
> > > > > [snip]
> > > > > pll-ddr-base                   2        2        0   768000000        
> > > > >  0
> > > > > 
> > > > >  0  50000 pll-ddr-other               1        1        0   768000000
> > > > >  
> > > > >    0     0  50000 mmc2                     0        0        0   
> > > > >    51200000
> > > > >    
> > > > >         0     0  50000 mmc2_sample           0        0        0
> > > > > 
> > > > > 51200000          0   120  50000 mmc2_output           0        0     
> > > > >   0
> > > > > 
> > > > >   51200000          0    72  50000 [/snip]
> > > > 
> > > > It seems to me that clock rate is set properly. It's even better than
> > > > before since there is no error between wanted and real clock. I bet
> > > > that if you call clk_get_rate() directly behind clk_set_rate() in mmc
> > > > driver, you'll get correct value.
> > > > 
> > > > However, it seems that at some point some other peripheral changes it's
> > > > parent clock rate, which inadvertely changes emmc2 clock rate too. The
> > > > only possible clock which could interfere is sata. Can you disable
> > > > driver in you kernel config and try again?
> > > 
> > > OK, tried following things in succession, but SATA disabling does not
> > > work:
> > > 
> > > a) Marked all ahci stuff in devicetree as disabled
> > > b) Disable CONFIG_AHCI_SUNXI in kernel
> > > c) Even disabled SATA stuff in u-boot
> > 
> > But it works, when I allow mmc2 clock to set parent rate:
> 
> Strange, I checked both pre- and post- patch clk_summary you sent me and in 
> both cases both mmc2 parent clocks have same rate as before. This would need a 
> more detailed analysis with a lot of debug print, but don't have such board.
> 
> CLK_SET_PARENT rate might be viable solution, but  you have to be sure that 
> any clock using pll-periph as a parent is in expected range.
> 
> On the plus side, if this works, eMMC will work faster due to 8 MHz clock rate 
> increase :)
> 
> > 
> > pll-periph-base                3        3        0   312000000          0   
> >  0  50000 mbus                        1        1        0    78000000      
> >    0     0  50000 pll-periph-sata             1        1        0   
> > 26000000          0     0  50000 sata                     1        1       
> > 0    26000000          0     0  50000 pll-periph                  5       
> > 5        0   156000000          0     0  50000 mmc2                     0  
> >      0        0    52000000          0     0  50000 mmc2_sample           0
> >        0        0    52000000          0   120  50000 mmc2_output          
> > 0        0        0    52000000          0   120  50000 mmc0               
> >      0        0        0    39000000          0     0  50000 mmc0_sample   
> >        0        0        0    39000000          0    90  50000 mmc0_output 
> >          0        0        0    39000000          0    90  50000
> > 
> > 
> > Now, what I don't understand is why the `enable count` does not increase :(
> 
> mmc has suspend/resume functionality which might power down mmc when not in 
> use and thus disable clocks. Try initiate some big transfer from/to eMMC and 
> check clocks in between.

OK, seems like everything magically started working again in 5.1.0-rc1:

pll-periph-base       3 3 0  1200000000  0     0  50000
   mbus               1 1 0   300000000  0     0  50000
   pll-periph-sata    1 1 0   100000000  0     0  50000
      sata            1 1 0   100000000  0     0  50000
   pll-periph         3 3 0   600000000  0     0  50000
      mmc2            0 0 0    50000000  0     0  50000
         mmc2_sample  0 0 0    50000000  0   120  50000
         mmc2_output  0 0 0    50000000  0    60  50000

> BR,
> Jernej
> 
> > 
> > ---
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
> > b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c index 129ebd2588fd..605e13b4ef90
> > 100644
> > --- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
> > +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
> > @@ -498,7 +498,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2",
> > mod0_default_parents, 0x090, 16, 2,        /* P */
> >                                   24, 2,        /* mux */
> >                                   BIT(31),      /* gate */
> > -                                 0);
> > +                                 CLK_SET_RATE_PARENT);
> > 
> >  /* MMC output and sample clocks are not present on A10 */
> >  static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
> > 
> > > > Best regards,
> > > > Jernej
> 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
diff mbox series

Patch

diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index 5d0af4051737..0357349eb767 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -40,6 +40,61 @@  static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
 	*p = best_p;
 }
 
+static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
+						      unsigned long *parent,
+						      unsigned long rate,
+						      unsigned int max_m,
+						      unsigned int max_p)
+{
+	unsigned long parent_rate_saved;
+	unsigned long parent_rate, now;
+	unsigned long best_rate = 0;
+	unsigned int _m, _p, div;
+	unsigned long maxdiv;
+
+	parent_rate_saved = *parent;
+
+	/*
+	 * The maximum divider we can use without overflowing
+	 * unsigned long in rate * m * p below
+	 */
+	maxdiv = max_m * max_p;
+	maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+	for (_p = 1; _p <= max_p; _p <<= 1) {
+		for (_m = 1; _m <= max_m; _m++) {
+			div = _m * _p;
+
+			if (div > maxdiv)
+				break;
+
+			if (rate * div == parent_rate_saved) {
+				/*
+				 * It's the most ideal case if the requested
+				 * rate can be divided from parent clock without
+				 * needing to change parent rate, so return the
+				 * divider immediately.
+				 */
+				*parent = parent_rate_saved;
+				return rate;
+			}
+
+			parent_rate = clk_hw_round_rate(hw, rate * div);
+			now = parent_rate / div;
+
+			if (now <= rate && now > best_rate) {
+				best_rate = now;
+				*parent = parent_rate;
+
+				if (now == rate)
+					return rate;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
 static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
 				       struct clk_hw *hw,
 				       unsigned long *parent_rate,
@@ -56,8 +111,13 @@  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
 	max_m = cmp->m.max ?: 1 << cmp->m.width;
 	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
 
-	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
-	rate = *parent_rate / p / m;
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
+		rate = *parent_rate / p / m;
+	} else {
+		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate,
+							max_m, max_p);
+	}
 
 	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= cmp->fixed_post_div;