From 9b15c5248e430f418621414f876170f08ca0a2cd Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Thu, 12 Jan 2017 16:37:24 +0100 Subject: [PATCH 02/82] clk: sunxi-ng: Allow to limit the use of NKMP clock's P factor Some SoCs mandate the maximum clock rate for which the use of postdivider P factor is allowed. Allow to configure maximum clock rate. Signed-off-by: Ondrej Jirman --- drivers/clk/sunxi-ng/ccu_nkmp.c | 13 ++++++++----- drivers/clk/sunxi-ng/ccu_nkmp.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 1ad53d1016a3..080bf4a4ace6 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -33,16 +33,19 @@ static unsigned long ccu_nkmp_calc_rate(unsigned long parent, } static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, - struct _ccu_nkmp *nkmp) + struct _ccu_nkmp *nkmp, struct ccu_nkmp *_nkmp) { unsigned long best_rate = 0; unsigned long best_n = 0, best_k = 0, best_m = 0, best_p = 0; - unsigned long _n, _k, _m, _p; + unsigned long _n, _k, _m, _p, _max_p; + + _max_p = (_nkmp->max_rate_for_p == 0 || rate <= _nkmp->max_rate_for_p) ? + nkmp->max_p : nkmp->min_p; for (_k = nkmp->min_k; _k <= nkmp->max_k; _k++) { for (_n = nkmp->min_n; _n <= nkmp->max_n; _n++) { for (_m = nkmp->min_m; _m <= nkmp->max_m; _m++) { - for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) { + for (_p = nkmp->min_p; _p <= _max_p; _p <<= 1) { unsigned long tmp_rate; tmp_rate = ccu_nkmp_calc_rate(parent, @@ -146,7 +149,7 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, _nkmp.min_p = 1; _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); - ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); + ccu_nkmp_find_best(*parent_rate, rate, &_nkmp, nkmp); rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, _nkmp.m, _nkmp.p); @@ -177,7 +180,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, _nkmp.min_p = 1; _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); - ccu_nkmp_find_best(parent_rate, rate, &_nkmp); + ccu_nkmp_find_best(parent_rate, rate, &_nkmp, nkmp); if (nkmp->n.width) n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1, diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h index 6940503e7fc4..bbea3e5ed6fb 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.h +++ b/drivers/clk/sunxi-ng/ccu_nkmp.h @@ -33,6 +33,7 @@ struct ccu_nkmp { struct ccu_mult_internal k; struct ccu_div_internal m; struct ccu_div_internal p; + unsigned long max_rate_for_p; unsigned int fixed_post_div; -- 2.20.1