Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clk-divider.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Sascha Hauer, Pengutronix <[email protected]>
3  * Copyright (C) 2011 Richard Zhao, Linaro <[email protected]>
4  * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Adjustable divider clock implementation
11  */
12 
13 #include <linux/clk-provider.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/io.h>
17 #include <linux/err.h>
18 #include <linux/string.h>
19 
20 /*
21  * DOC: basic adjustable divider clock that cannot gate
22  *
23  * Traits of this clock:
24  * prepare - clk_prepare only ensures that parents are prepared
25  * enable - clk_enable only ensures that parents are enabled
26  * rate - rate is adjustable. clk->rate = parent->rate / divisor
27  * parent - fixed parent. No clk_set_parent support
28  */
29 
30 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
31 
32 #define div_mask(d) ((1 << (d->width)) - 1)
33 #define is_power_of_two(i) !(i & ~i)
34 
35 static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
36 {
37  unsigned int maxdiv = 0;
38  const struct clk_div_table *clkt;
39 
40  for (clkt = table; clkt->div; clkt++)
41  if (clkt->div > maxdiv)
42  maxdiv = clkt->div;
43  return maxdiv;
44 }
45 
46 static unsigned int _get_maxdiv(struct clk_divider *divider)
47 {
48  if (divider->flags & CLK_DIVIDER_ONE_BASED)
49  return div_mask(divider);
50  if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
51  return 1 << div_mask(divider);
52  if (divider->table)
53  return _get_table_maxdiv(divider->table);
54  return div_mask(divider) + 1;
55 }
56 
57 static unsigned int _get_table_div(const struct clk_div_table *table,
58  unsigned int val)
59 {
60  const struct clk_div_table *clkt;
61 
62  for (clkt = table; clkt->div; clkt++)
63  if (clkt->val == val)
64  return clkt->div;
65  return 0;
66 }
67 
68 static unsigned int _get_div(struct clk_divider *divider, unsigned int val)
69 {
70  if (divider->flags & CLK_DIVIDER_ONE_BASED)
71  return val;
72  if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
73  return 1 << val;
74  if (divider->table)
75  return _get_table_div(divider->table, val);
76  return val + 1;
77 }
78 
79 static unsigned int _get_table_val(const struct clk_div_table *table,
80  unsigned int div)
81 {
82  const struct clk_div_table *clkt;
83 
84  for (clkt = table; clkt->div; clkt++)
85  if (clkt->div == div)
86  return clkt->val;
87  return 0;
88 }
89 
90 static unsigned int _get_val(struct clk_divider *divider, u8 div)
91 {
92  if (divider->flags & CLK_DIVIDER_ONE_BASED)
93  return div;
94  if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
95  return __ffs(div);
96  if (divider->table)
97  return _get_table_val(divider->table, div);
98  return div - 1;
99 }
100 
101 static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
102  unsigned long parent_rate)
103 {
104  struct clk_divider *divider = to_clk_divider(hw);
105  unsigned int div, val;
106 
107  val = readl(divider->reg) >> divider->shift;
108  val &= div_mask(divider);
109 
110  div = _get_div(divider, val);
111  if (!div) {
112  WARN(1, "%s: Invalid divisor for clock %s\n", __func__,
113  __clk_get_name(hw->clk));
114  return parent_rate;
115  }
116 
117  return parent_rate / div;
118 }
119 
120 /*
121  * The reverse of DIV_ROUND_UP: The maximum number which
122  * divided by m is r
123  */
124 #define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
125 
126 static bool _is_valid_table_div(const struct clk_div_table *table,
127  unsigned int div)
128 {
129  const struct clk_div_table *clkt;
130 
131  for (clkt = table; clkt->div; clkt++)
132  if (clkt->div == div)
133  return true;
134  return false;
135 }
136 
137 static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
138 {
139  if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
140  return is_power_of_two(div);
141  if (divider->table)
142  return _is_valid_table_div(divider->table, div);
143  return true;
144 }
145 
146 static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
147  unsigned long *best_parent_rate)
148 {
149  struct clk_divider *divider = to_clk_divider(hw);
150  int i, bestdiv = 0;
151  unsigned long parent_rate, best = 0, now, maxdiv;
152 
153  if (!rate)
154  rate = 1;
155 
156  maxdiv = _get_maxdiv(divider);
157 
158  if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) {
159  parent_rate = *best_parent_rate;
160  bestdiv = DIV_ROUND_UP(parent_rate, rate);
161  bestdiv = bestdiv == 0 ? 1 : bestdiv;
162  bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
163  return bestdiv;
164  }
165 
166  /*
167  * The maximum divider we can use without overflowing
168  * unsigned long in rate * i below
169  */
170  maxdiv = min(ULONG_MAX / rate, maxdiv);
171 
172  for (i = 1; i <= maxdiv; i++) {
173  if (!_is_valid_div(divider, i))
174  continue;
175  parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
176  MULT_ROUND_UP(rate, i));
177  now = parent_rate / i;
178  if (now <= rate && now > best) {
179  bestdiv = i;
180  best = now;
181  *best_parent_rate = parent_rate;
182  }
183  }
184 
185  if (!bestdiv) {
186  bestdiv = _get_maxdiv(divider);
187  *best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 1);
188  }
189 
190  return bestdiv;
191 }
192 
193 static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
194  unsigned long *prate)
195 {
196  int div;
197  div = clk_divider_bestdiv(hw, rate, prate);
198 
199  return *prate / div;
200 }
201 
202 static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
203  unsigned long parent_rate)
204 {
205  struct clk_divider *divider = to_clk_divider(hw);
206  unsigned int div, value;
207  unsigned long flags = 0;
208  u32 val;
209 
210  div = parent_rate / rate;
211  value = _get_val(divider, div);
212 
213  if (value > div_mask(divider))
214  value = div_mask(divider);
215 
216  if (divider->lock)
217  spin_lock_irqsave(divider->lock, flags);
218 
219  val = readl(divider->reg);
220  val &= ~(div_mask(divider) << divider->shift);
221  val |= value << divider->shift;
222  writel(val, divider->reg);
223 
224  if (divider->lock)
225  spin_unlock_irqrestore(divider->lock, flags);
226 
227  return 0;
228 }
229 
230 const struct clk_ops clk_divider_ops = {
231  .recalc_rate = clk_divider_recalc_rate,
232  .round_rate = clk_divider_round_rate,
233  .set_rate = clk_divider_set_rate,
234 };
235 EXPORT_SYMBOL_GPL(clk_divider_ops);
236 
237 static struct clk *_register_divider(struct device *dev, const char *name,
238  const char *parent_name, unsigned long flags,
239  void __iomem *reg, u8 shift, u8 width,
240  u8 clk_divider_flags, const struct clk_div_table *table,
241  spinlock_t *lock)
242 {
243  struct clk_divider *div;
244  struct clk *clk;
245  struct clk_init_data init;
246 
247  /* allocate the divider */
248  div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
249  if (!div) {
250  pr_err("%s: could not allocate divider clk\n", __func__);
251  return ERR_PTR(-ENOMEM);
252  }
253 
254  init.name = name;
255  init.ops = &clk_divider_ops;
256  init.flags = flags | CLK_IS_BASIC;
257  init.parent_names = (parent_name ? &parent_name: NULL);
258  init.num_parents = (parent_name ? 1 : 0);
259 
260  /* struct clk_divider assignments */
261  div->reg = reg;
262  div->shift = shift;
263  div->width = width;
264  div->flags = clk_divider_flags;
265  div->lock = lock;
266  div->hw.init = &init;
267  div->table = table;
268 
269  /* register the clock */
270  clk = clk_register(dev, &div->hw);
271 
272  if (IS_ERR(clk))
273  kfree(div);
274 
275  return clk;
276 }
277 
290 struct clk *clk_register_divider(struct device *dev, const char *name,
291  const char *parent_name, unsigned long flags,
292  void __iomem *reg, u8 shift, u8 width,
293  u8 clk_divider_flags, spinlock_t *lock)
294 {
295  return _register_divider(dev, name, parent_name, flags, reg, shift,
296  width, clk_divider_flags, NULL, lock);
297 }
298 
313 struct clk *clk_register_divider_table(struct device *dev, const char *name,
314  const char *parent_name, unsigned long flags,
315  void __iomem *reg, u8 shift, u8 width,
316  u8 clk_divider_flags, const struct clk_div_table *table,
317  spinlock_t *lock)
318 {
319  return _register_divider(dev, name, parent_name, flags, reg, shift,
320  width, clk_divider_flags, table, lock);
321 }