1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * TI Divider Clock
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2013 Texas Instruments, Inc.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Tero Kristo <t-kristo@ti.com>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify
9*4882a593Smuzhiyun * it under the terms of the GNU General Public License version 2 as
10*4882a593Smuzhiyun * published by the Free Software Foundation.
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13*4882a593Smuzhiyun * kind, whether express or implied; without even the implied warranty
14*4882a593Smuzhiyun * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*4882a593Smuzhiyun * GNU General Public License for more details.
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/clk-provider.h>
19*4882a593Smuzhiyun #include <linux/slab.h>
20*4882a593Smuzhiyun #include <linux/err.h>
21*4882a593Smuzhiyun #include <linux/of.h>
22*4882a593Smuzhiyun #include <linux/of_address.h>
23*4882a593Smuzhiyun #include <linux/clk/ti.h>
24*4882a593Smuzhiyun #include "clock.h"
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #undef pr_fmt
27*4882a593Smuzhiyun #define pr_fmt(fmt) "%s: " fmt, __func__
28*4882a593Smuzhiyun
_get_table_div(const struct clk_div_table * table,unsigned int val)29*4882a593Smuzhiyun static unsigned int _get_table_div(const struct clk_div_table *table,
30*4882a593Smuzhiyun unsigned int val)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun const struct clk_div_table *clkt;
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun for (clkt = table; clkt->div; clkt++)
35*4882a593Smuzhiyun if (clkt->val == val)
36*4882a593Smuzhiyun return clkt->div;
37*4882a593Smuzhiyun return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun
_setup_mask(struct clk_omap_divider * divider)40*4882a593Smuzhiyun static void _setup_mask(struct clk_omap_divider *divider)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun u16 mask;
43*4882a593Smuzhiyun u32 max_val;
44*4882a593Smuzhiyun const struct clk_div_table *clkt;
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun if (divider->table) {
47*4882a593Smuzhiyun max_val = 0;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun for (clkt = divider->table; clkt->div; clkt++)
50*4882a593Smuzhiyun if (clkt->val > max_val)
51*4882a593Smuzhiyun max_val = clkt->val;
52*4882a593Smuzhiyun } else {
53*4882a593Smuzhiyun max_val = divider->max;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun if (!(divider->flags & CLK_DIVIDER_ONE_BASED) &&
56*4882a593Smuzhiyun !(divider->flags & CLK_DIVIDER_POWER_OF_TWO))
57*4882a593Smuzhiyun max_val--;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
61*4882a593Smuzhiyun mask = fls(max_val) - 1;
62*4882a593Smuzhiyun else
63*4882a593Smuzhiyun mask = max_val;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun divider->mask = (1 << fls(mask)) - 1;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
_get_div(struct clk_omap_divider * divider,unsigned int val)68*4882a593Smuzhiyun static unsigned int _get_div(struct clk_omap_divider *divider, unsigned int val)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun if (divider->flags & CLK_DIVIDER_ONE_BASED)
71*4882a593Smuzhiyun return val;
72*4882a593Smuzhiyun if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
73*4882a593Smuzhiyun return 1 << val;
74*4882a593Smuzhiyun if (divider->table)
75*4882a593Smuzhiyun return _get_table_div(divider->table, val);
76*4882a593Smuzhiyun return val + 1;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
_get_table_val(const struct clk_div_table * table,unsigned int div)79*4882a593Smuzhiyun static unsigned int _get_table_val(const struct clk_div_table *table,
80*4882a593Smuzhiyun unsigned int div)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun const struct clk_div_table *clkt;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun for (clkt = table; clkt->div; clkt++)
85*4882a593Smuzhiyun if (clkt->div == div)
86*4882a593Smuzhiyun return clkt->val;
87*4882a593Smuzhiyun return 0;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
_get_val(struct clk_omap_divider * divider,u8 div)90*4882a593Smuzhiyun static unsigned int _get_val(struct clk_omap_divider *divider, u8 div)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun if (divider->flags & CLK_DIVIDER_ONE_BASED)
93*4882a593Smuzhiyun return div;
94*4882a593Smuzhiyun if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
95*4882a593Smuzhiyun return __ffs(div);
96*4882a593Smuzhiyun if (divider->table)
97*4882a593Smuzhiyun return _get_table_val(divider->table, div);
98*4882a593Smuzhiyun return div - 1;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
ti_clk_divider_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)101*4882a593Smuzhiyun static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
102*4882a593Smuzhiyun unsigned long parent_rate)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun struct clk_omap_divider *divider = to_clk_omap_divider(hw);
105*4882a593Smuzhiyun unsigned int div, val;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift;
108*4882a593Smuzhiyun val &= divider->mask;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun div = _get_div(divider, val);
111*4882a593Smuzhiyun if (!div) {
112*4882a593Smuzhiyun WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
113*4882a593Smuzhiyun "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
114*4882a593Smuzhiyun clk_hw_get_name(hw));
115*4882a593Smuzhiyun return parent_rate;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun return DIV_ROUND_UP(parent_rate, div);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /*
122*4882a593Smuzhiyun * The reverse of DIV_ROUND_UP: The maximum number which
123*4882a593Smuzhiyun * divided by m is r
124*4882a593Smuzhiyun */
125*4882a593Smuzhiyun #define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
126*4882a593Smuzhiyun
_is_valid_table_div(const struct clk_div_table * table,unsigned int div)127*4882a593Smuzhiyun static bool _is_valid_table_div(const struct clk_div_table *table,
128*4882a593Smuzhiyun unsigned int div)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun const struct clk_div_table *clkt;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun for (clkt = table; clkt->div; clkt++)
133*4882a593Smuzhiyun if (clkt->div == div)
134*4882a593Smuzhiyun return true;
135*4882a593Smuzhiyun return false;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
_is_valid_div(struct clk_omap_divider * divider,unsigned int div)138*4882a593Smuzhiyun static bool _is_valid_div(struct clk_omap_divider *divider, unsigned int div)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
141*4882a593Smuzhiyun return is_power_of_2(div);
142*4882a593Smuzhiyun if (divider->table)
143*4882a593Smuzhiyun return _is_valid_table_div(divider->table, div);
144*4882a593Smuzhiyun return true;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
_div_round_up(const struct clk_div_table * table,unsigned long parent_rate,unsigned long rate)147*4882a593Smuzhiyun static int _div_round_up(const struct clk_div_table *table,
148*4882a593Smuzhiyun unsigned long parent_rate, unsigned long rate)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun const struct clk_div_table *clkt;
151*4882a593Smuzhiyun int up = INT_MAX;
152*4882a593Smuzhiyun int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun for (clkt = table; clkt->div; clkt++) {
155*4882a593Smuzhiyun if (clkt->div == div)
156*4882a593Smuzhiyun return clkt->div;
157*4882a593Smuzhiyun else if (clkt->div < div)
158*4882a593Smuzhiyun continue;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun if ((clkt->div - div) < (up - div))
161*4882a593Smuzhiyun up = clkt->div;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun return up;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
_div_round(const struct clk_div_table * table,unsigned long parent_rate,unsigned long rate)167*4882a593Smuzhiyun static int _div_round(const struct clk_div_table *table,
168*4882a593Smuzhiyun unsigned long parent_rate, unsigned long rate)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun if (!table)
171*4882a593Smuzhiyun return DIV_ROUND_UP(parent_rate, rate);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun return _div_round_up(table, parent_rate, rate);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
ti_clk_divider_bestdiv(struct clk_hw * hw,unsigned long rate,unsigned long * best_parent_rate)176*4882a593Smuzhiyun static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
177*4882a593Smuzhiyun unsigned long *best_parent_rate)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun struct clk_omap_divider *divider = to_clk_omap_divider(hw);
180*4882a593Smuzhiyun int i, bestdiv = 0;
181*4882a593Smuzhiyun unsigned long parent_rate, best = 0, now, maxdiv;
182*4882a593Smuzhiyun unsigned long parent_rate_saved = *best_parent_rate;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun if (!rate)
185*4882a593Smuzhiyun rate = 1;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun maxdiv = divider->max;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
190*4882a593Smuzhiyun parent_rate = *best_parent_rate;
191*4882a593Smuzhiyun bestdiv = _div_round(divider->table, parent_rate, rate);
192*4882a593Smuzhiyun bestdiv = bestdiv == 0 ? 1 : bestdiv;
193*4882a593Smuzhiyun bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
194*4882a593Smuzhiyun return bestdiv;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /*
198*4882a593Smuzhiyun * The maximum divider we can use without overflowing
199*4882a593Smuzhiyun * unsigned long in rate * i below
200*4882a593Smuzhiyun */
201*4882a593Smuzhiyun maxdiv = min(ULONG_MAX / rate, maxdiv);
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun for (i = 1; i <= maxdiv; i++) {
204*4882a593Smuzhiyun if (!_is_valid_div(divider, i))
205*4882a593Smuzhiyun continue;
206*4882a593Smuzhiyun if (rate * i == parent_rate_saved) {
207*4882a593Smuzhiyun /*
208*4882a593Smuzhiyun * It's the most ideal case if the requested rate can be
209*4882a593Smuzhiyun * divided from parent clock without needing to change
210*4882a593Smuzhiyun * parent rate, so return the divider immediately.
211*4882a593Smuzhiyun */
212*4882a593Smuzhiyun *best_parent_rate = parent_rate_saved;
213*4882a593Smuzhiyun return i;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
216*4882a593Smuzhiyun MULT_ROUND_UP(rate, i));
217*4882a593Smuzhiyun now = DIV_ROUND_UP(parent_rate, i);
218*4882a593Smuzhiyun if (now <= rate && now > best) {
219*4882a593Smuzhiyun bestdiv = i;
220*4882a593Smuzhiyun best = now;
221*4882a593Smuzhiyun *best_parent_rate = parent_rate;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun if (!bestdiv) {
226*4882a593Smuzhiyun bestdiv = divider->max;
227*4882a593Smuzhiyun *best_parent_rate =
228*4882a593Smuzhiyun clk_hw_round_rate(clk_hw_get_parent(hw), 1);
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun return bestdiv;
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
ti_clk_divider_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * prate)234*4882a593Smuzhiyun static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
235*4882a593Smuzhiyun unsigned long *prate)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun int div;
238*4882a593Smuzhiyun div = ti_clk_divider_bestdiv(hw, rate, prate);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun return DIV_ROUND_UP(*prate, div);
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
ti_clk_divider_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)243*4882a593Smuzhiyun static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
244*4882a593Smuzhiyun unsigned long parent_rate)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun struct clk_omap_divider *divider;
247*4882a593Smuzhiyun unsigned int div, value;
248*4882a593Smuzhiyun u32 val;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun if (!hw || !rate)
251*4882a593Smuzhiyun return -EINVAL;
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun divider = to_clk_omap_divider(hw);
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun div = DIV_ROUND_UP(parent_rate, rate);
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun if (div > divider->max)
258*4882a593Smuzhiyun div = divider->max;
259*4882a593Smuzhiyun if (div < divider->min)
260*4882a593Smuzhiyun div = divider->min;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun value = _get_val(divider, div);
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun val = ti_clk_ll_ops->clk_readl(÷r->reg);
265*4882a593Smuzhiyun val &= ~(divider->mask << divider->shift);
266*4882a593Smuzhiyun val |= value << divider->shift;
267*4882a593Smuzhiyun ti_clk_ll_ops->clk_writel(val, ÷r->reg);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun ti_clk_latch(÷r->reg, divider->latch);
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun return 0;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun /**
275*4882a593Smuzhiyun * clk_divider_save_context - Save the divider value
276*4882a593Smuzhiyun * @hw: pointer struct clk_hw
277*4882a593Smuzhiyun *
278*4882a593Smuzhiyun * Save the divider value
279*4882a593Smuzhiyun */
clk_divider_save_context(struct clk_hw * hw)280*4882a593Smuzhiyun static int clk_divider_save_context(struct clk_hw *hw)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun struct clk_omap_divider *divider = to_clk_omap_divider(hw);
283*4882a593Smuzhiyun u32 val;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift;
286*4882a593Smuzhiyun divider->context = val & divider->mask;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /**
292*4882a593Smuzhiyun * clk_divider_restore_context - restore the saved the divider value
293*4882a593Smuzhiyun * @hw: pointer struct clk_hw
294*4882a593Smuzhiyun *
295*4882a593Smuzhiyun * Restore the saved the divider value
296*4882a593Smuzhiyun */
clk_divider_restore_context(struct clk_hw * hw)297*4882a593Smuzhiyun static void clk_divider_restore_context(struct clk_hw *hw)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun struct clk_omap_divider *divider = to_clk_omap_divider(hw);
300*4882a593Smuzhiyun u32 val;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun val = ti_clk_ll_ops->clk_readl(÷r->reg);
303*4882a593Smuzhiyun val &= ~(divider->mask << divider->shift);
304*4882a593Smuzhiyun val |= divider->context << divider->shift;
305*4882a593Smuzhiyun ti_clk_ll_ops->clk_writel(val, ÷r->reg);
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun const struct clk_ops ti_clk_divider_ops = {
309*4882a593Smuzhiyun .recalc_rate = ti_clk_divider_recalc_rate,
310*4882a593Smuzhiyun .round_rate = ti_clk_divider_round_rate,
311*4882a593Smuzhiyun .set_rate = ti_clk_divider_set_rate,
312*4882a593Smuzhiyun .save_context = clk_divider_save_context,
313*4882a593Smuzhiyun .restore_context = clk_divider_restore_context,
314*4882a593Smuzhiyun };
315*4882a593Smuzhiyun
_register_divider(struct device_node * node,u32 flags,struct clk_omap_divider * div)316*4882a593Smuzhiyun static struct clk *_register_divider(struct device_node *node,
317*4882a593Smuzhiyun u32 flags,
318*4882a593Smuzhiyun struct clk_omap_divider *div)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun struct clk *clk;
321*4882a593Smuzhiyun struct clk_init_data init;
322*4882a593Smuzhiyun const char *parent_name;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun parent_name = of_clk_get_parent_name(node, 0);
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun init.name = node->name;
327*4882a593Smuzhiyun init.ops = &ti_clk_divider_ops;
328*4882a593Smuzhiyun init.flags = flags;
329*4882a593Smuzhiyun init.parent_names = (parent_name ? &parent_name : NULL);
330*4882a593Smuzhiyun init.num_parents = (parent_name ? 1 : 0);
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun div->hw.init = &init;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* register the clock */
335*4882a593Smuzhiyun clk = ti_clk_register(NULL, &div->hw, node->name);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun if (IS_ERR(clk))
338*4882a593Smuzhiyun kfree(div);
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun return clk;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
ti_clk_parse_divider_data(int * div_table,int num_dividers,int max_div,u8 flags,struct clk_omap_divider * divider)343*4882a593Smuzhiyun int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
344*4882a593Smuzhiyun u8 flags, struct clk_omap_divider *divider)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun int valid_div = 0;
347*4882a593Smuzhiyun int i;
348*4882a593Smuzhiyun struct clk_div_table *tmp;
349*4882a593Smuzhiyun u16 min_div = 0;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun if (!div_table) {
352*4882a593Smuzhiyun divider->min = 1;
353*4882a593Smuzhiyun divider->max = max_div;
354*4882a593Smuzhiyun _setup_mask(divider);
355*4882a593Smuzhiyun return 0;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun i = 0;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun while (!num_dividers || i < num_dividers) {
361*4882a593Smuzhiyun if (div_table[i] == -1)
362*4882a593Smuzhiyun break;
363*4882a593Smuzhiyun if (div_table[i])
364*4882a593Smuzhiyun valid_div++;
365*4882a593Smuzhiyun i++;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun num_dividers = i;
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL);
371*4882a593Smuzhiyun if (!tmp)
372*4882a593Smuzhiyun return -ENOMEM;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun valid_div = 0;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun for (i = 0; i < num_dividers; i++)
377*4882a593Smuzhiyun if (div_table[i] > 0) {
378*4882a593Smuzhiyun tmp[valid_div].div = div_table[i];
379*4882a593Smuzhiyun tmp[valid_div].val = i;
380*4882a593Smuzhiyun valid_div++;
381*4882a593Smuzhiyun if (div_table[i] > max_div)
382*4882a593Smuzhiyun max_div = div_table[i];
383*4882a593Smuzhiyun if (!min_div || div_table[i] < min_div)
384*4882a593Smuzhiyun min_div = div_table[i];
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun divider->min = min_div;
388*4882a593Smuzhiyun divider->max = max_div;
389*4882a593Smuzhiyun divider->table = tmp;
390*4882a593Smuzhiyun _setup_mask(divider);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
ti_clk_get_div_table(struct device_node * node,struct clk_omap_divider * div)395*4882a593Smuzhiyun static int __init ti_clk_get_div_table(struct device_node *node,
396*4882a593Smuzhiyun struct clk_omap_divider *div)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun struct clk_div_table *table;
399*4882a593Smuzhiyun const __be32 *divspec;
400*4882a593Smuzhiyun u32 val;
401*4882a593Smuzhiyun u32 num_div;
402*4882a593Smuzhiyun u32 valid_div;
403*4882a593Smuzhiyun int i;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun divspec = of_get_property(node, "ti,dividers", &num_div);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun if (!divspec)
408*4882a593Smuzhiyun return 0;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun num_div /= 4;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun valid_div = 0;
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun /* Determine required size for divider table */
415*4882a593Smuzhiyun for (i = 0; i < num_div; i++) {
416*4882a593Smuzhiyun of_property_read_u32_index(node, "ti,dividers", i, &val);
417*4882a593Smuzhiyun if (val)
418*4882a593Smuzhiyun valid_div++;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (!valid_div) {
422*4882a593Smuzhiyun pr_err("no valid dividers for %pOFn table\n", node);
423*4882a593Smuzhiyun return -EINVAL;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun table = kcalloc(valid_div + 1, sizeof(*table), GFP_KERNEL);
427*4882a593Smuzhiyun if (!table)
428*4882a593Smuzhiyun return -ENOMEM;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun valid_div = 0;
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun for (i = 0; i < num_div; i++) {
433*4882a593Smuzhiyun of_property_read_u32_index(node, "ti,dividers", i, &val);
434*4882a593Smuzhiyun if (val) {
435*4882a593Smuzhiyun table[valid_div].div = val;
436*4882a593Smuzhiyun table[valid_div].val = i;
437*4882a593Smuzhiyun valid_div++;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun div->table = table;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun return 0;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
_populate_divider_min_max(struct device_node * node,struct clk_omap_divider * divider)446*4882a593Smuzhiyun static int _populate_divider_min_max(struct device_node *node,
447*4882a593Smuzhiyun struct clk_omap_divider *divider)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun u32 min_div = 0;
450*4882a593Smuzhiyun u32 max_div = 0;
451*4882a593Smuzhiyun u32 val;
452*4882a593Smuzhiyun const struct clk_div_table *clkt;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun if (!divider->table) {
455*4882a593Smuzhiyun /* Clk divider table not provided, determine min/max divs */
456*4882a593Smuzhiyun if (of_property_read_u32(node, "ti,min-div", &min_div))
457*4882a593Smuzhiyun min_div = 1;
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun if (of_property_read_u32(node, "ti,max-div", &max_div)) {
460*4882a593Smuzhiyun pr_err("no max-div for %pOFn!\n", node);
461*4882a593Smuzhiyun return -EINVAL;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun } else {
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun for (clkt = divider->table; clkt->div; clkt++) {
466*4882a593Smuzhiyun val = clkt->div;
467*4882a593Smuzhiyun if (val > max_div)
468*4882a593Smuzhiyun max_div = val;
469*4882a593Smuzhiyun if (!min_div || val < min_div)
470*4882a593Smuzhiyun min_div = val;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun divider->min = min_div;
475*4882a593Smuzhiyun divider->max = max_div;
476*4882a593Smuzhiyun _setup_mask(divider);
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun return 0;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
ti_clk_divider_populate(struct device_node * node,struct clk_omap_divider * div,u32 * flags)481*4882a593Smuzhiyun static int __init ti_clk_divider_populate(struct device_node *node,
482*4882a593Smuzhiyun struct clk_omap_divider *div,
483*4882a593Smuzhiyun u32 *flags)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun u32 val;
486*4882a593Smuzhiyun int ret;
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun ret = ti_clk_get_reg_addr(node, 0, &div->reg);
489*4882a593Smuzhiyun if (ret)
490*4882a593Smuzhiyun return ret;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if (!of_property_read_u32(node, "ti,bit-shift", &val))
493*4882a593Smuzhiyun div->shift = val;
494*4882a593Smuzhiyun else
495*4882a593Smuzhiyun div->shift = 0;
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun if (!of_property_read_u32(node, "ti,latch-bit", &val))
498*4882a593Smuzhiyun div->latch = val;
499*4882a593Smuzhiyun else
500*4882a593Smuzhiyun div->latch = -EINVAL;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun *flags = 0;
503*4882a593Smuzhiyun div->flags = 0;
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun if (of_property_read_bool(node, "ti,index-starts-at-one"))
506*4882a593Smuzhiyun div->flags |= CLK_DIVIDER_ONE_BASED;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun if (of_property_read_bool(node, "ti,index-power-of-two"))
509*4882a593Smuzhiyun div->flags |= CLK_DIVIDER_POWER_OF_TWO;
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun if (of_property_read_bool(node, "ti,set-rate-parent"))
512*4882a593Smuzhiyun *flags |= CLK_SET_RATE_PARENT;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun ret = ti_clk_get_div_table(node, div);
515*4882a593Smuzhiyun if (ret)
516*4882a593Smuzhiyun return ret;
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun return _populate_divider_min_max(node, div);
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun /**
522*4882a593Smuzhiyun * of_ti_divider_clk_setup - Setup function for simple div rate clock
523*4882a593Smuzhiyun * @node: device node for this clock
524*4882a593Smuzhiyun *
525*4882a593Smuzhiyun * Sets up a basic divider clock.
526*4882a593Smuzhiyun */
of_ti_divider_clk_setup(struct device_node * node)527*4882a593Smuzhiyun static void __init of_ti_divider_clk_setup(struct device_node *node)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun struct clk *clk;
530*4882a593Smuzhiyun u32 flags = 0;
531*4882a593Smuzhiyun struct clk_omap_divider *div;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun div = kzalloc(sizeof(*div), GFP_KERNEL);
534*4882a593Smuzhiyun if (!div)
535*4882a593Smuzhiyun return;
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun if (ti_clk_divider_populate(node, div, &flags))
538*4882a593Smuzhiyun goto cleanup;
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun clk = _register_divider(node, flags, div);
541*4882a593Smuzhiyun if (!IS_ERR(clk)) {
542*4882a593Smuzhiyun of_clk_add_provider(node, of_clk_src_simple_get, clk);
543*4882a593Smuzhiyun of_ti_clk_autoidle_setup(node);
544*4882a593Smuzhiyun return;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun cleanup:
548*4882a593Smuzhiyun kfree(div->table);
549*4882a593Smuzhiyun kfree(div);
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun CLK_OF_DECLARE(divider_clk, "ti,divider-clock", of_ti_divider_clk_setup);
552*4882a593Smuzhiyun
of_ti_composite_divider_clk_setup(struct device_node * node)553*4882a593Smuzhiyun static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun struct clk_omap_divider *div;
556*4882a593Smuzhiyun u32 tmp;
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun div = kzalloc(sizeof(*div), GFP_KERNEL);
559*4882a593Smuzhiyun if (!div)
560*4882a593Smuzhiyun return;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun if (ti_clk_divider_populate(node, div, &tmp))
563*4882a593Smuzhiyun goto cleanup;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))
566*4882a593Smuzhiyun return;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun cleanup:
569*4882a593Smuzhiyun kfree(div->table);
570*4882a593Smuzhiyun kfree(div);
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun CLK_OF_DECLARE(ti_composite_divider_clk, "ti,composite-divider-clock",
573*4882a593Smuzhiyun of_ti_composite_divider_clk_setup);
574