aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.io>2018-03-16 10:02:11 -0400
committerMaxime Ripard <maxime.ripard@bootlin.com>2018-03-18 16:16:54 -0400
commita910f251ee084230e2f8d214f1621346cec94e69 (patch)
tree0d6f3659b49faa55ca3b4af6a8f07f0bf52ed4ad /drivers
parent55de0f31df1a31b346edfe98d061f11162ff1ad4 (diff)
clk: sunxi-ng: Support fixed post-dividers on NKMP style clocks
On the new Allwinner H6 SoC, multiple PLL's are NMP style clocks (modelled as NKMP with no K) and have fixed post-dividers. Add fixed post divider support to the NKMP style clocks. Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkmp.c20
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkmp.h2
2 files changed, 19 insertions, 3 deletions
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index c3f6fe7be565..ebd9436d2c7c 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -95,7 +95,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
95 unsigned long parent_rate) 95 unsigned long parent_rate)
96{ 96{
97 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); 97 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
98 unsigned long n, m, k, p; 98 unsigned long n, m, k, p, rate;
99 u32 reg; 99 u32 reg;
100 100
101 reg = readl(nkmp->common.base + nkmp->common.reg); 101 reg = readl(nkmp->common.base + nkmp->common.reg);
@@ -121,7 +121,11 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
121 p = reg >> nkmp->p.shift; 121 p = reg >> nkmp->p.shift;
122 p &= (1 << nkmp->p.width) - 1; 122 p &= (1 << nkmp->p.width) - 1;
123 123
124 return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); 124 rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p);
125 if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
126 rate /= nkmp->fixed_post_div;
127
128 return rate;
125} 129}
126 130
127static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, 131static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -130,6 +134,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
130 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); 134 struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
131 struct _ccu_nkmp _nkmp; 135 struct _ccu_nkmp _nkmp;
132 136
137 if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
138 rate *= nkmp->fixed_post_div;
139
133 _nkmp.min_n = nkmp->n.min ?: 1; 140 _nkmp.min_n = nkmp->n.min ?: 1;
134 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; 141 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
135 _nkmp.min_k = nkmp->k.min ?: 1; 142 _nkmp.min_k = nkmp->k.min ?: 1;
@@ -141,8 +148,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
141 148
142 ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); 149 ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
143 150
144 return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, 151 rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k,
145 _nkmp.m, _nkmp.p); 152 _nkmp.m, _nkmp.p);
153 if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
154 rate = rate / nkmp->fixed_post_div;
155
156 return rate;
146} 157}
147 158
148static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, 159static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -154,6 +165,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
154 unsigned long flags; 165 unsigned long flags;
155 u32 reg; 166 u32 reg;
156 167
168 if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
169 rate = rate * nkmp->fixed_post_div;
170
157 _nkmp.min_n = nkmp->n.min ?: 1; 171 _nkmp.min_n = nkmp->n.min ?: 1;
158 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; 172 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
159 _nkmp.min_k = nkmp->k.min ?: 1; 173 _nkmp.min_k = nkmp->k.min ?: 1;
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h
index a82facbc6144..6940503e7fc4 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.h
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.h
@@ -34,6 +34,8 @@ struct ccu_nkmp {
34 struct ccu_div_internal m; 34 struct ccu_div_internal m;
35 struct ccu_div_internal p; 35 struct ccu_div_internal p;
36 36
37 unsigned int fixed_post_div;
38
37 struct ccu_common common; 39 struct ccu_common common;
38}; 40};
39 41