clk: sunxi: rewrite sun9i_a80_get_pll4_factors()
PATCH 1/2 clk: sunxi: rewrite sun9i_a80_get_pll4_factors()
The old implementation of sun9i_a80_get_pll4_factors() has several issues, it checks against 256 / 512 in various places where it should use 255 / 511, it does the wrong thing for low frequencies which are an even multiple of 6 MHz, e.g. if you ask it for 72 MHz it will result in 144 Mhz, and it does not take into account that n must be at least 12. Moreover it is quite hard to read / follow it.
This commit rewrites it to be correct in all cases, and makes it much easier to follow the code / to read.
--- drivers/clk/sunxi/clk-sun9i-core.c | 57 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 28 deletions(-)
drivers/clk/sunxi/clk-sun9i-core.c +29 -28
@@ -24,50 +24,51 @@/** -* sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL1 +* sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL4 * PLL4 rate is calculated as follows * rate = (parent_rate * n >> p) / (m + 1); -* parent_rate is always 24Mhz +* parent_rate is always 24MHz * * p and m are named div1 and div2 in Allwinner's SDK */ static void sun9i_a80_get_pll4_factors (u32 *freq,u32 parent_rate, -u8 *n,u8 *k,u8 *m,u8 *p) +u8 *n_ret,u8 *k,u8 *m_ret,u8 *p_ret) { -int div; +int n; +int m =1 ; +int p =1 ; -/* Normalize value to a 6M multiple */ - div =DIV_ROUND_UP (*freq,6000000 ); +/* Normalize value to a 6 MHz multiple (24 MHz / 4) */ + n =DIV_ROUND_UP (*freq,6000000 ); -/* divs above 256 cannot be odd */ -if (div >256 ) - div =round_up (div,2 ); +/* If n is too large switch to steps of 12 MHz */ +if (n >255 ) { + m =0 ; + n = (n +1 ) /2 ; + } + +/* If n is still too large switch to steps of 24 MHz */ +if (n >255 ) { + p =0 ; + n = (n +1 ) /2 ; + } -/* divs above 512 must be a multiple of 4 */ -if (div >512 ) - div =round_up (div,4 ); +/* n must be between 12 and 255 */ +if (n >255 ) + n =255 ; +else if (n <12 ) + n =12 ; - *freq =6000000 * div; + *freq = ((24000000 * n) >> p) / (m +1 );/* we were called to round the frequency, we can now return */ -if (n ==NULL ) +if (n_ret ==NULL )return ; -/* p will be 1 for divs under 512 */ -if (div <512 ) - *p =1 ; -else - *p =0 ; - -/* m will be 1 if div is odd */ -if (div &1 ) - *m =1 ; -else - *m =0 ; - -/* calculate a suitable n based on m and p */ - *n = div / (*p +1 ) / (*m +1 ); + *n_ret = n; + *m_ret = m; + *p_ret = p; }static struct clk_factors_config sun9i_a80_pll4_config = {
Signature · 1 line
2.1.0
PATCH 2/2 sunxi: clk: Set sun6i-pll1 n_start = 1
For all pll-s on sun6i n == 0 means use a multiplier of 1, rather then 0 as it means on sun4i / sun5i / sun7i. n_start = 1 is already correctly set for sun6i pll6, but was missing for pll1, this commit fixes this.
--- drivers/clk/sunxi/clk-sunxi.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/sunxi/clk-sunxi.c +1 -0
@@ -584,6 +584,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = { .kwidth = 2, .mshift = 0, .mwidth = 2, + .n_start = 1, };static struct clk_factors_config sun8i_a23_pll1_config = {
Signature · 1 line
2.1.0
PATCH 2/2 sunxi: clk: Set sun6i-pll1 n_start = 1
Quoted 6 lines · Hans de Goede
For all pll-s on sun6i n == 0 means use a multiplier of 1, rather then 0 as it means on sun4i / sun5i / sun7i.
n_start= 1 is already correctly set for sun6i pll6, but was missing for pll1, this commit fixes this.Cc Chen-Yu Tsai <[email protected]>Signed-off-by Hans de Goede <[email protected]>
Applied the two, thanks!
Maxime
Signature · 10 lines
Maxime Ripard, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150125/12cdecbe/attachment.sig>
PATCH 2/2 sunxi: clk: Set sun6i-pll1 n_start = 1
Quoted 9 lines · Maxime Ripard
Quoted 6 lines · Hans de Goede
For all pll-s on sun6i n == 0 means use a multiplier of 1, rather then 0 as it means on sun4i / sun5i / sun7i.
n_start= 1 is already correctly set for sun6i pll6, but was missing for pll1, this commit fixes this.Cc Chen-Yu Tsai <[email protected]>Signed-off-by Hans de Goede <[email protected]>Applied the two, thanks!
This is the same as the one I sent, which you asked Mike to queue for 3.19.
ChenYu