aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2013-09-13 05:02:15 -0400
committerMike Turquette <mturquette@linaro.org>2014-01-17 15:35:04 -0500
commitb4761198bfaf29649dc58a48e8b123ea4174ba95 (patch)
tree7c350ec98d991e2e6035a6e0098002d28ea3223c
parent975e15487d5abfd5f33fea9c1ba0b987604f0d0f (diff)
CLK: ti: add support for ti divider-clock
This patch adds support for TI divider clock binding, which simply uses the basic clock divider to provide the features needed. Signed-off-by: Tero Kristo <t-kristo@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/clock/ti/divider.txt114
-rw-r--r--drivers/clk/ti/Makefile2
-rw-r--r--drivers/clk/ti/composite.c2
-rw-r--r--drivers/clk/ti/divider.c487
-rw-r--r--include/linux/clk/ti.h2
5 files changed, 605 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/clock/ti/divider.txt b/Documentation/devicetree/bindings/clock/ti/divider.txt
new file mode 100644
index 000000000000..35a6f5c7e5c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/divider.txt
@@ -0,0 +1,114 @@
1Binding for TI divider clock
2
3Binding status: Unstable - ABI compatibility may be broken in the future
4
5This binding uses the common clock binding[1]. It assumes a
6register-mapped adjustable clock rate divider that does not gate and has
7only one input clock or parent. By default the value programmed into
8the register is one less than the actual divisor value. E.g:
9
10register value actual divisor value
110 1
121 2
132 3
14
15This assumption may be modified by the following optional properties:
16
17ti,index-starts-at-one - valid divisor values start at 1, not the default
18of 0. E.g:
19register value actual divisor value
201 1
212 2
223 3
23
24ti,index-power-of-two - valid divisor values are powers of two. E.g:
25register value actual divisor value
260 1
271 2
282 4
29
30Additionally an array of valid dividers may be supplied like so:
31
32 ti,dividers = <4>, <8>, <0>, <16>;
33
34Which will map the resulting values to a divisor table by their index:
35register value actual divisor value
360 4
371 8
382 <invalid divisor, skipped>
393 16
40
41Any zero value in this array means the corresponding bit-value is invalid
42and must not be used.
43
44The binding must also provide the register to control the divider and
45unless the divider array is provided, min and max dividers. Optionally
46the number of bits to shift that mask, if necessary. If the shift value
47is missing it is the same as supplying a zero shift.
48
49This binding can also optionally provide support to the hardware autoidle
50feature, see [2].
51
52[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
53[2] Documentation/devicetree/bindings/clock/ti/autoidle.txt
54
55Required properties:
56- compatible : shall be "ti,divider-clock" or "ti,composite-divider-clock".
57- #clock-cells : from common clock binding; shall be set to 0.
58- clocks : link to phandle of parent clock
59- reg : offset for register controlling adjustable divider
60
61Optional properties:
62- clock-output-names : from common clock binding.
63- ti,dividers : array of integers defining divisors
64- ti,bit-shift : number of bits to shift the divider value, defaults to 0
65- ti,min-div : min divisor for dividing the input clock rate, only
66 needed if the first divisor is offset from the default value (1)
67- ti,max-div : max divisor for dividing the input clock rate, only needed
68 if ti,dividers is not defined.
69- ti,index-starts-at-one : valid divisor programming starts at 1, not zero,
70 only valid if ti,dividers is not defined.
71- ti,index-power-of-two : valid divisor programming must be a power of two,
72 only valid if ti,dividers is not defined.
73- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock,
74 see [2]
75- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0,
76 see [2]
77- ti,set-rate-parent : clk_set_rate is propagated to parent
78
79Examples:
80dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 {
81 #clock-cells = <0>;
82 compatible = "ti,divider-clock";
83 clocks = <&dpll_usb_ck>;
84 ti,max-div = <127>;
85 reg = <0x190>;
86 ti,index-starts-at-one;
87};
88
89aess_fclk: aess_fclk@4a004528 {
90 #clock-cells = <0>;
91 compatible = "ti,divider-clock";
92 clocks = <&abe_clk>;
93 ti,bit-shift = <24>;
94 reg = <0x528>;
95 ti,max-div = <2>;
96};
97
98dpll_core_m3x2_div_ck: dpll_core_m3x2_div_ck {
99 #clock-cells = <0>;
100 compatible = "ti,composite-divider-clock";
101 clocks = <&dpll_core_x2_ck>;
102 ti,max-div = <31>;
103 reg = <0x0134>;
104 ti,index-starts-at-one;
105};
106
107ssi_ssr_div_fck_3430es2: ssi_ssr_div_fck_3430es2 {
108 #clock-cells = <0>;
109 compatible = "ti,composite-divider-clock";
110 clocks = <&corex2_fck>;
111 ti,bit-shift = <8>;
112 reg = <0x0a40>;
113 ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
114};
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index ac4ea50672ed..8690b0b442c0 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -1,4 +1,4 @@
1ifneq ($(CONFIG_OF),) 1ifneq ($(CONFIG_OF),)
2obj-y += clk.o autoidle.o 2obj-y += clk.o autoidle.o
3clk-common = dpll.o composite.o 3clk-common = dpll.o composite.o divider.o
4endif 4endif
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 6539b650cae0..ffb8db4829bf 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -31,7 +31,7 @@
31static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, 31static unsigned long ti_composite_recalc_rate(struct clk_hw *hw,
32 unsigned long parent_rate) 32 unsigned long parent_rate)
33{ 33{
34 return clk_divider_ops.recalc_rate(hw, parent_rate); 34 return ti_clk_divider_ops.recalc_rate(hw, parent_rate);
35} 35}
36 36
37static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate, 37static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
new file mode 100644
index 000000000000..a15e445570b2
--- /dev/null
+++ b/drivers/clk/ti/divider.c
@@ -0,0 +1,487 @@
1/*
2 * TI Divider Clock
3 *
4 * Copyright (C) 2013 Texas Instruments, Inc.
5 *
6 * Tero Kristo <t-kristo@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/clk-provider.h>
19#include <linux/slab.h>
20#include <linux/err.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
23#include <linux/clk/ti.h>
24
25#undef pr_fmt
26#define pr_fmt(fmt) "%s: " fmt, __func__
27
28#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
29
30#define div_mask(d) ((1 << ((d)->width)) - 1)
31
32static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
33{
34 unsigned int maxdiv = 0;
35 const struct clk_div_table *clkt;
36
37 for (clkt = table; clkt->div; clkt++)
38 if (clkt->div > maxdiv)
39 maxdiv = clkt->div;
40 return maxdiv;
41}
42
43static unsigned int _get_maxdiv(struct clk_divider *divider)
44{
45 if (divider->flags & CLK_DIVIDER_ONE_BASED)
46 return div_mask(divider);
47 if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
48 return 1 << div_mask(divider);
49 if (divider->table)
50 return _get_table_maxdiv(divider->table);
51 return div_mask(divider) + 1;
52}
53
54static unsigned int _get_table_div(const struct clk_div_table *table,
55 unsigned int val)
56{
57 const struct clk_div_table *clkt;
58
59 for (clkt = table; clkt->div; clkt++)
60 if (clkt->val == val)
61 return clkt->div;
62 return 0;
63}
64
65static unsigned int _get_div(struct clk_divider *divider, unsigned int val)
66{
67 if (divider->flags & CLK_DIVIDER_ONE_BASED)
68 return val;
69 if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
70 return 1 << val;
71 if (divider->table)
72 return _get_table_div(divider->table, val);
73 return val + 1;
74}
75
76static unsigned int _get_table_val(const struct clk_div_table *table,
77 unsigned int div)
78{
79 const struct clk_div_table *clkt;
80
81 for (clkt = table; clkt->div; clkt++)
82 if (clkt->div == div)
83 return clkt->val;
84 return 0;
85}
86
87static unsigned int _get_val(struct clk_divider *divider, u8 div)
88{
89 if (divider->flags & CLK_DIVIDER_ONE_BASED)
90 return div;
91 if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
92 return __ffs(div);
93 if (divider->table)
94 return _get_table_val(divider->table, div);
95 return div - 1;
96}
97
98static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
99 unsigned long parent_rate)
100{
101 struct clk_divider *divider = to_clk_divider(hw);
102 unsigned int div, val;
103
104 val = ti_clk_ll_ops->clk_readl(divider->reg) >> divider->shift;
105 val &= div_mask(divider);
106
107 div = _get_div(divider, val);
108 if (!div) {
109 WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
110 "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
111 __clk_get_name(hw->clk));
112 return parent_rate;
113 }
114
115 return parent_rate / div;
116}
117
118/*
119 * The reverse of DIV_ROUND_UP: The maximum number which
120 * divided by m is r
121 */
122#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
123
124static bool _is_valid_table_div(const struct clk_div_table *table,
125 unsigned int div)
126{
127 const struct clk_div_table *clkt;
128
129 for (clkt = table; clkt->div; clkt++)
130 if (clkt->div == div)
131 return true;
132 return false;
133}
134
135static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
136{
137 if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
138 return is_power_of_2(div);
139 if (divider->table)
140 return _is_valid_table_div(divider->table, div);
141 return true;
142}
143
144static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
145 unsigned long *best_parent_rate)
146{
147 struct clk_divider *divider = to_clk_divider(hw);
148 int i, bestdiv = 0;
149 unsigned long parent_rate, best = 0, now, maxdiv;
150 unsigned long parent_rate_saved = *best_parent_rate;
151
152 if (!rate)
153 rate = 1;
154
155 maxdiv = _get_maxdiv(divider);
156
157 if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) {
158 parent_rate = *best_parent_rate;
159 bestdiv = DIV_ROUND_UP(parent_rate, rate);
160 bestdiv = bestdiv == 0 ? 1 : bestdiv;
161 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
162 return bestdiv;
163 }
164
165 /*
166 * The maximum divider we can use without overflowing
167 * unsigned long in rate * i below
168 */
169 maxdiv = min(ULONG_MAX / rate, maxdiv);
170
171 for (i = 1; i <= maxdiv; i++) {
172 if (!_is_valid_div(divider, i))
173 continue;
174 if (rate * i == parent_rate_saved) {
175 /*
176 * It's the most ideal case if the requested rate can be
177 * divided from parent clock without needing to change
178 * parent rate, so return the divider immediately.
179 */
180 *best_parent_rate = parent_rate_saved;
181 return i;
182 }
183 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
184 MULT_ROUND_UP(rate, i));
185 now = parent_rate / i;
186 if (now <= rate && now > best) {
187 bestdiv = i;
188 best = now;
189 *best_parent_rate = parent_rate;
190 }
191 }
192
193 if (!bestdiv) {
194 bestdiv = _get_maxdiv(divider);
195 *best_parent_rate =
196 __clk_round_rate(__clk_get_parent(hw->clk), 1);
197 }
198
199 return bestdiv;
200}
201
202static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
203 unsigned long *prate)
204{
205 int div;
206 div = ti_clk_divider_bestdiv(hw, rate, prate);
207
208 return *prate / div;
209}
210
211static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
212 unsigned long parent_rate)
213{
214 struct clk_divider *divider = to_clk_divider(hw);
215 unsigned int div, value;
216 unsigned long flags = 0;
217 u32 val;
218
219 div = parent_rate / rate;
220 value = _get_val(divider, div);
221
222 if (value > div_mask(divider))
223 value = div_mask(divider);
224
225 if (divider->lock)
226 spin_lock_irqsave(divider->lock, flags);
227
228 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
229 val = div_mask(divider) << (divider->shift + 16);
230 } else {
231 val = ti_clk_ll_ops->clk_readl(divider->reg);
232 val &= ~(div_mask(divider) << divider->shift);
233 }
234 val |= value << divider->shift;
235 ti_clk_ll_ops->clk_writel(val, divider->reg);
236
237 if (divider->lock)
238 spin_unlock_irqrestore(divider->lock, flags);
239
240 return 0;
241}
242
243const struct clk_ops ti_clk_divider_ops = {
244 .recalc_rate = ti_clk_divider_recalc_rate,
245 .round_rate = ti_clk_divider_round_rate,
246 .set_rate = ti_clk_divider_set_rate,
247};
248
249static struct clk *_register_divider(struct device *dev, const char *name,
250 const char *parent_name,
251 unsigned long flags, void __iomem *reg,
252 u8 shift, u8 width, u8 clk_divider_flags,
253 const struct clk_div_table *table,
254 spinlock_t *lock)
255{
256 struct clk_divider *div;
257 struct clk *clk;
258 struct clk_init_data init;
259
260 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
261 if (width + shift > 16) {
262 pr_warn("divider value exceeds LOWORD field\n");
263 return ERR_PTR(-EINVAL);
264 }
265 }
266
267 /* allocate the divider */
268 div = kzalloc(sizeof(*div), GFP_KERNEL);
269 if (!div) {
270 pr_err("%s: could not allocate divider clk\n", __func__);
271 return ERR_PTR(-ENOMEM);
272 }
273
274 init.name = name;
275 init.ops = &ti_clk_divider_ops;
276 init.flags = flags | CLK_IS_BASIC;
277 init.parent_names = (parent_name ? &parent_name : NULL);
278 init.num_parents = (parent_name ? 1 : 0);
279
280 /* struct clk_divider assignments */
281 div->reg = reg;
282 div->shift = shift;
283 div->width = width;
284 div->flags = clk_divider_flags;
285 div->lock = lock;
286 div->hw.init = &init;
287 div->table = table;
288
289 /* register the clock */
290 clk = clk_register(dev, &div->hw);
291
292 if (IS_ERR(clk))
293 kfree(div);
294
295 return clk;
296}
297
298static struct clk_div_table
299__init *ti_clk_get_div_table(struct device_node *node)
300{
301 struct clk_div_table *table;
302 const __be32 *divspec;
303 u32 val;
304 u32 num_div;
305 u32 valid_div;
306 int i;
307
308 divspec = of_get_property(node, "ti,dividers", &num_div);
309
310 if (!divspec)
311 return NULL;
312
313 num_div /= 4;
314
315 valid_div = 0;
316
317 /* Determine required size for divider table */
318 for (i = 0; i < num_div; i++) {
319 of_property_read_u32_index(node, "ti,dividers", i, &val);
320 if (val)
321 valid_div++;
322 }
323
324 if (!valid_div) {
325 pr_err("no valid dividers for %s table\n", node->name);
326 return ERR_PTR(-EINVAL);
327 }
328
329 table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL);
330
331 if (!table)
332 return ERR_PTR(-ENOMEM);
333
334 valid_div = 0;
335
336 for (i = 0; i < num_div; i++) {
337 of_property_read_u32_index(node, "ti,dividers", i, &val);
338 if (val) {
339 table[valid_div].div = val;
340 table[valid_div].val = i;
341 valid_div++;
342 }
343 }
344
345 return table;
346}
347
348static int _get_divider_width(struct device_node *node,
349 const struct clk_div_table *table,
350 u8 flags)
351{
352 u32 min_div;
353 u32 max_div;
354 u32 val = 0;
355 u32 div;
356
357 if (!table) {
358 /* Clk divider table not provided, determine min/max divs */
359 if (of_property_read_u32(node, "ti,min-div", &min_div))
360 min_div = 1;
361
362 if (of_property_read_u32(node, "ti,max-div", &max_div)) {
363 pr_err("no max-div for %s!\n", node->name);
364 return -EINVAL;
365 }
366
367 /* Determine bit width for the field */
368 if (flags & CLK_DIVIDER_ONE_BASED)
369 val = 1;
370
371 div = min_div;
372
373 while (div < max_div) {
374 if (flags & CLK_DIVIDER_POWER_OF_TWO)
375 div <<= 1;
376 else
377 div++;
378 val++;
379 }
380 } else {
381 div = 0;
382
383 while (table[div].div) {
384 val = table[div].val;
385 div++;
386 }
387 }
388
389 return fls(val);
390}
391
392static int __init ti_clk_divider_populate(struct device_node *node,
393 void __iomem **reg, const struct clk_div_table **table,
394 u32 *flags, u8 *div_flags, u8 *width, u8 *shift)
395{
396 u32 val;
397
398 *reg = ti_clk_get_reg_addr(node, 0);
399 if (!*reg)
400 return -EINVAL;
401
402 if (!of_property_read_u32(node, "ti,bit-shift", &val))
403 *shift = val;
404 else
405 *shift = 0;
406
407 *flags = 0;
408 *div_flags = 0;
409
410 if (of_property_read_bool(node, "ti,index-starts-at-one"))
411 *div_flags |= CLK_DIVIDER_ONE_BASED;
412
413 if (of_property_read_bool(node, "ti,index-power-of-two"))
414 *div_flags |= CLK_DIVIDER_POWER_OF_TWO;
415
416 if (of_property_read_bool(node, "ti,set-rate-parent"))
417 *flags |= CLK_SET_RATE_PARENT;
418
419 *table = ti_clk_get_div_table(node);
420
421 if (IS_ERR(*table))
422 return PTR_ERR(*table);
423
424 *width = _get_divider_width(node, *table, *div_flags);
425
426 return 0;
427}
428
429/**
430 * of_ti_divider_clk_setup - Setup function for simple div rate clock
431 * @node: device node for this clock
432 *
433 * Sets up a basic divider clock.
434 */
435static void __init of_ti_divider_clk_setup(struct device_node *node)
436{
437 struct clk *clk;
438 const char *parent_name;
439 void __iomem *reg;
440 u8 clk_divider_flags = 0;
441 u8 width = 0;
442 u8 shift = 0;
443 const struct clk_div_table *table = NULL;
444 u32 flags = 0;
445
446 parent_name = of_clk_get_parent_name(node, 0);
447
448 if (ti_clk_divider_populate(node, &reg, &table, &flags,
449 &clk_divider_flags, &width, &shift))
450 goto cleanup;
451
452 clk = _register_divider(NULL, node->name, parent_name, flags, reg,
453 shift, width, clk_divider_flags, table, NULL);
454
455 if (!IS_ERR(clk)) {
456 of_clk_add_provider(node, of_clk_src_simple_get, clk);
457 of_ti_clk_autoidle_setup(node);
458 return;
459 }
460
461cleanup:
462 kfree(table);
463}
464CLK_OF_DECLARE(divider_clk, "ti,divider-clock", of_ti_divider_clk_setup);
465
466static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
467{
468 struct clk_divider *div;
469 u32 val;
470
471 div = kzalloc(sizeof(*div), GFP_KERNEL);
472 if (!div)
473 return;
474
475 if (ti_clk_divider_populate(node, &div->reg, &div->table, &val,
476 &div->flags, &div->width, &div->shift) < 0)
477 goto cleanup;
478
479 if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))
480 return;
481
482cleanup:
483 kfree(div->table);
484 kfree(div);
485}
486CLK_OF_DECLARE(ti_composite_divider_clk, "ti,composite-divider-clock",
487 of_ti_composite_divider_clk_setup);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index c8c591dd3261..17fb49e4ff5e 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -223,6 +223,8 @@ struct ti_clk_ll_ops {
223 223
224extern struct ti_clk_ll_ops *ti_clk_ll_ops; 224extern struct ti_clk_ll_ops *ti_clk_ll_ops;
225 225
226extern const struct clk_ops ti_clk_divider_ops;
227
226#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) 228#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
227 229
228void omap2_init_clk_hw_omap_clocks(struct clk *clk); 230void omap2_init_clk_hw_omap_clocks(struct clk *clk);