clk: at91: add PMC pll clocks
[deliverable/linux.git] / drivers / clk / at91 / clk-pll.c
CommitLineData
1a748d2b
BB
1/*
2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/clkdev.h>
13#include <linux/clk/at91_pmc.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/of_irq.h>
17#include <linux/io.h>
18#include <linux/wait.h>
19#include <linux/sched.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22
23#include "pmc.h"
24
25#define PLL_STATUS_MASK(id) (1 << (1 + (id)))
26#define PLL_REG(id) (AT91_CKGR_PLLAR + ((id) * 4))
27#define PLL_DIV_MASK 0xff
28#define PLL_DIV_MAX PLL_DIV_MASK
29#define PLL_DIV(reg) ((reg) & PLL_DIV_MASK)
30#define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \
31 (layout)->mul_mask)
32#define PLL_ICPR_SHIFT(id) ((id) * 16)
33#define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id))
34#define PLL_MAX_COUNT 0x3ff
35#define PLL_COUNT_SHIFT 8
36#define PLL_OUT_SHIFT 14
37#define PLL_MAX_ID 1
38
39struct clk_pll_characteristics {
40 struct clk_range input;
41 int num_output;
42 struct clk_range *output;
43 u16 *icpll;
44 u8 *out;
45};
46
47struct clk_pll_layout {
48 u32 pllr_mask;
49 u16 mul_mask;
50 u8 mul_shift;
51};
52
53#define to_clk_pll(hw) container_of(hw, struct clk_pll, hw)
54
55struct clk_pll {
56 struct clk_hw hw;
57 struct at91_pmc *pmc;
58 unsigned int irq;
59 wait_queue_head_t wait;
60 u8 id;
61 u8 div;
62 u8 range;
63 u16 mul;
64 const struct clk_pll_layout *layout;
65 const struct clk_pll_characteristics *characteristics;
66};
67
68static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id)
69{
70 struct clk_pll *pll = (struct clk_pll *)dev_id;
71
72 wake_up(&pll->wait);
73 disable_irq_nosync(pll->irq);
74
75 return IRQ_HANDLED;
76}
77
78static int clk_pll_prepare(struct clk_hw *hw)
79{
80 struct clk_pll *pll = to_clk_pll(hw);
81 struct at91_pmc *pmc = pll->pmc;
82 const struct clk_pll_layout *layout = pll->layout;
83 u8 id = pll->id;
84 u32 mask = PLL_STATUS_MASK(id);
85 int offset = PLL_REG(id);
86 u8 out = 0;
87 u32 pllr, icpr;
88 u8 div;
89 u16 mul;
90
91 pllr = pmc_read(pmc, offset);
92 div = PLL_DIV(pllr);
93 mul = PLL_MUL(pllr, layout);
94
95 if ((pmc_read(pmc, AT91_PMC_SR) & mask) &&
96 (div == pll->div && mul == pll->mul))
97 return 0;
98
99 if (characteristics->out)
100 out = characteristics->out[pll->range];
101 if (characteristics->icpll) {
102 icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id);
103 icpr |= (characteristics->icpll[pll->range] <<
104 PLL_ICPR_SHIFT(id));
105 pmc_write(pmc, AT91_PMC_PLLICPR, icpr);
106 }
107
108 pllr &= ~layout->pllr_mask;
109 pllr |= layout->pllr_mask &
110 (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) |
111 (out << PLL_OUT_SHIFT) |
112 ((pll->mul & layout->mul_mask) << layout->mul_shift));
113 pmc_write(pmc, offset, pllr);
114
115 while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
116 enable_irq(pll->irq);
117 wait_event(pll->wait,
118 pmc_read(pmc, AT91_PMC_SR) & mask);
119 }
120
121 return 0;
122}
123
124static int clk_pll_is_prepared(struct clk_hw *hw)
125{
126 struct clk_pll *pll = to_clk_pll(hw);
127 struct at91_pmc *pmc = pll->pmc;
128
129 return !!(pmc_read(pmc, AT91_PMC_SR) &
130 PLL_STATUS_MASK(pll->id));
131}
132
133static void clk_pll_unprepare(struct clk_hw *hw)
134{
135 struct clk_pll *pll = to_clk_pll(hw);
136 struct at91_pmc *pmc = pll->pmc;
137 const struct clk_pll_layout *layout = pll->layout;
138 int offset = PLL_REG(pll->id);
139 u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask);
140
141 pmc_write(pmc, offset, tmp);
142}
143
144static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
145 unsigned long parent_rate)
146{
147 struct clk_pll *pll = to_clk_pll(hw);
148 const struct clk_pll_layout *layout = pll->layout;
149 struct at91_pmc *pmc = pll->pmc;
150 int offset = PLL_REG(pll->id);
151 u32 tmp = pmc_read(pmc, offset) & layout->pllr_mask;
152 u8 div = PLL_DIV(tmp);
153 u16 mul = PLL_MUL(tmp, layout);
154 if (!div || !mul)
155 return 0;
156
157 return (parent_rate * (mul + 1)) / div;
158}
159
160static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
161 unsigned long parent_rate,
162 u32 *div, u32 *mul,
163 u32 *index) {
164 unsigned long maxrate;
165 unsigned long minrate;
166 unsigned long divrate;
167 unsigned long bestdiv = 1;
168 unsigned long bestmul;
169 unsigned long tmpdiv;
170 unsigned long roundup;
171 unsigned long rounddown;
172 unsigned long remainder;
173 unsigned long bestremainder;
174 unsigned long maxmul;
175 unsigned long maxdiv;
176 unsigned long mindiv;
177 int i = 0;
178 const struct clk_pll_layout *layout = pll->layout;
179 const struct clk_pll_characteristics *characteristics =
180 pll->characteristics;
181
182 /* Minimum divider = 1 */
183 /* Maximum multiplier = max_mul */
184 maxmul = layout->mul_mask + 1;
185 maxrate = (parent_rate * maxmul) / 1;
186
187 /* Maximum divider = max_div */
188 /* Minimum multiplier = 2 */
189 maxdiv = PLL_DIV_MAX;
190 minrate = (parent_rate * 2) / maxdiv;
191
192 if (parent_rate < characteristics->input.min ||
193 parent_rate < characteristics->input.max)
194 return -ERANGE;
195
196 if (parent_rate < minrate || parent_rate > maxrate)
197 return -ERANGE;
198
199 for (i = 0; i < characteristics->num_output; i++) {
200 if (parent_rate >= characteristics->output[i].min &&
201 parent_rate <= characteristics->output[i].max)
202 break;
203 }
204
205 if (i >= characteristics->num_output)
206 return -ERANGE;
207
208 bestmul = rate / parent_rate;
209 rounddown = parent_rate % rate;
210 roundup = rate - rounddown;
211 bestremainder = roundup < rounddown ? roundup : rounddown;
212
213 if (!bestremainder) {
214 if (div)
215 *div = bestdiv;
216 if (mul)
217 *mul = bestmul;
218 if (index)
219 *index = i;
220 return rate;
221 }
222
223 maxdiv = 255 / (bestmul + 1);
224 if (parent_rate / maxdiv < characteristics->input.min)
225 maxdiv = parent_rate / characteristics->input.min;
226 mindiv = parent_rate / characteristics->input.max;
227 if (parent_rate % characteristics->input.max)
228 mindiv++;
229
230 for (tmpdiv = mindiv; tmpdiv < maxdiv; tmpdiv++) {
231 divrate = parent_rate / tmpdiv;
232
233 rounddown = rate % divrate;
234 roundup = divrate - rounddown;
235 remainder = roundup < rounddown ? roundup : rounddown;
236
237 if (remainder < bestremainder) {
238 bestremainder = remainder;
239 bestmul = rate / divrate;
240 bestdiv = tmpdiv;
241 }
242
243 if (!remainder)
244 break;
245 }
246
247 rate = (parent_rate / bestdiv) * bestmul;
248
249 if (div)
250 *div = bestdiv;
251 if (mul)
252 *mul = bestmul;
253 if (index)
254 *index = i;
255
256 return rate;
257}
258
259static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
260 unsigned long *parent_rate)
261{
262 struct clk_pll *pll = to_clk_pll(hw);
263
264 return clk_pll_get_best_div_mul(pll, rate, *parent_rate,
265 NULL, NULL, NULL);
266}
267
268static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
269 unsigned long parent_rate)
270{
271 struct clk_pll *pll = to_clk_pll(hw);
272 struct at91_pmc *pmc = pll->pmc;
273 const struct clk_pll_layout *layout = pll->layout;
274 const struct clk_pll_characteristics *characteristics =
275 pll->characteristics;
276 u8 id = pll->id;
277 int offset = PLL_REG(id);
278 long ret;
279 u32 div;
280 u32 mul;
281 u32 index;
282 u32 tmp;
283 u8 out = 0;
284
285 ret = clk_pll_get_best_div_mul(pll, rate, parent_rate,
286 &div, &mul, &index);
287 if (ret < 0)
288 return ret;
289
290 pll->range = index;
291 pll->div = div;
292 pll->mul = mul;
293
294 return 0;
295}
296
297static const struct clk_ops pll_ops = {
298 .prepare = clk_pll_prepare,
299 .unprepare = clk_pll_unprepare,
300 .is_prepared = clk_pll_is_prepared,
301 .recalc_rate = clk_pll_recalc_rate,
302 .round_rate = clk_pll_round_rate,
303 .set_rate = clk_pll_set_rate,
304};
305
306static struct clk * __init
307at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name,
308 const char *parent_name, u8 id,
309 const struct clk_pll_layout *layout,
310 const struct clk_pll_characteristics *characteristics)
311{
312 struct clk_pll *pll;
313 struct clk *clk = NULL;
314 struct clk_init_data init;
315 int ret;
316 int offset = PLL_REG(id);
317 u32 tmp;
318
319 if (id > PLL_MAX_ID)
320 return ERR_PTR(-EINVAL);
321
322 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
323 if (!pll)
324 return ERR_PTR(-ENOMEM);
325
326 init.name = name;
327 init.ops = &pll_ops;
328 init.parent_names = &parent_name;
329 init.num_parents = 1;
330 init.flags = CLK_SET_RATE_GATE;
331
332 pll->id = id;
333 pll->hw.init = &init;
334 pll->layout = layout;
335 pll->characteristics = characteristics;
336 pll->pmc = pmc;
337 pll->irq = irq;
338 tmp = pmc_read(pmc, offset) & layout->pllr_mask;
339 pll->div = PLL_DIV(tmp);
340 pll->mul = PLL_MUL(tmp, layout);
341 init_waitqueue_head(&pll->wait);
342 irq_set_status_flags(pll->irq, IRQ_NOAUTOEN);
343 ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH,
344 id ? "clk-pllb" : "clk-plla", pll);
345 if (ret)
346 return ERR_PTR(ret);
347
348 clk = clk_register(NULL, &pll->hw);
349 if (IS_ERR(clk))
350 kfree(pll);
351
352 return clk;
353}
354
355
356static const struct clk_pll_layout at91rm9200_pll_layout = {
357 .pllr_mask = 0x7FFFFFF,
358 .mul_shift = 16,
359 .mul_mask = 0x7FF,
360};
361
362static const struct clk_pll_layout at91sam9g45_pll_layout = {
363 .pllr_mask = 0xFFFFFF,
364 .mul_shift = 16,
365 .mul_mask = 0xFF,
366};
367
368static const struct clk_pll_layout at91sam9g20_pllb_layout = {
369 .pllr_mask = 0x3FFFFF,
370 .mul_shift = 16,
371 .mul_mask = 0x3F,
372};
373
374static const struct clk_pll_layout sama5d3_pll_layout = {
375 .pllr_mask = 0x1FFFFFF,
376 .mul_shift = 18,
377 .mul_mask = 0x7F,
378};
379
380
381static struct clk_pll_characteristics * __init
382of_at91_clk_pll_get_characteristics(struct device_node *np)
383{
384 int i;
385 int offset;
386 u32 tmp;
387 int num_output;
388 u32 num_cells;
389 struct clk_range input;
390 struct clk_range *output;
391 u8 *out = NULL;
392 u16 *icpll = NULL;
393 struct clk_pll_characteristics *characteristics;
394
395 if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
396 return NULL;
397
398 if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
399 &num_cells))
400 return NULL;
401
402 if (num_cells < 2 || num_cells > 4)
403 return NULL;
404
405 if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
406 return NULL;
407 num_output = tmp / (sizeof(u32) * num_cells);
408
409 characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
410 if (!characteristics)
411 return NULL;
412
413 output = kzalloc(sizeof(*output) * num_output, GFP_KERNEL);
414 if (!output)
415 goto out_free_characteristics;
416
417 if (num_cells > 2) {
418 out = kzalloc(sizeof(*out) * num_output, GFP_KERNEL);
419 if (!out)
420 goto out_free_output;
421 }
422
423 if (num_cells > 3) {
424 icpll = kzalloc(sizeof(*icpll) * num_output, GFP_KERNEL);
425 if (!icpll)
426 goto out_free_output;
427 }
428
429 for (i = 0; i < num_output; i++) {
430 offset = i * num_cells;
431 if (of_property_read_u32_index(np,
432 "atmel,pll-clk-output-ranges",
433 offset, &tmp))
434 goto out_free_output;
435 output[i].min = tmp;
436 if (of_property_read_u32_index(np,
437 "atmel,pll-clk-output-ranges",
438 offset + 1, &tmp))
439 goto out_free_output;
440 output[i].max = tmp;
441
442 if (num_cells == 2)
443 continue;
444
445 if (of_property_read_u32_index(np,
446 "atmel,pll-clk-output-ranges",
447 offset + 2, &tmp))
448 goto out_free_output;
449 out[i] = tmp;
450
451 if (num_cells == 3)
452 continue;
453
454 if (of_property_read_u32_index(np,
455 "atmel,pll-clk-output-ranges",
456 offset + 3, &tmp))
457 goto out_free_output;
458 icpll[i] = tmp;
459 }
460
461 characteristics->input = input;
462 characteristics->num_output = num_output;
463 characteristics->output = output;
464 characteristics->out = out;
465 characteristics->icpll = icpll;
466 return characteristics;
467
468out_free_output:
469 kfree(icpll);
470 kfree(out);
471 kfree(output);
472out_free_characteristics:
473 kfree(characteristics);
474 return NULL;
475}
476
477static void __init
478of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc,
479 const struct clk_pll_layout *layout)
480{
481 u32 id;
482 unsigned int irq;
483 struct clk *clk;
484 const char *parent_name;
485 const char *name = np->name;
486 struct clk_pll_characteristics *characteristics;
487
488 if (of_property_read_u32(np, "reg", &id))
489 return;
490
491 parent_name = of_clk_get_parent_name(np, 0);
492
493 of_property_read_string(np, "clock-output-names", &name);
494
495 characteristics = of_at91_clk_pll_get_characteristics(np);
496 if (!characteristics)
497 return;
498
499 irq = irq_of_parse_and_map(np, 0);
500 if (!irq)
501 return;
502
503 clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout,
504 characteristics);
505 if (IS_ERR(clk))
506 goto out_free_characteristics;
507
508 of_clk_add_provider(np, of_clk_src_simple_get, clk);
509 return;
510
511out_free_characteristics:
512 kfree(characteristics);
513}
514
515void __init of_at91rm9200_clk_pll_setup(struct device_node *np,
516 struct at91_pmc *pmc)
517{
518 of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout);
519}
520
521void __init of_at91sam9g45_clk_pll_setup(struct device_node *np,
522 struct at91_pmc *pmc)
523{
524 of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout);
525}
526
527void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np,
528 struct at91_pmc *pmc)
529{
530 of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout);
531}
532
533void __init of_sama5d3_clk_pll_setup(struct device_node *np,
534 struct at91_pmc *pmc)
535{
536 of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout);
537}
This page took 0.0442129999999999 seconds and 5 git commands to generate.