Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / clk / clk-axi-clkgen.c
1 /*
2  * AXI clkgen driver
3  *
4  * Copyright 2012-2013 Analog Devices Inc.
5  *  Author: Lars-Peter Clausen <lars@metafoo.de>
6  *
7  * Licensed under the GPL-2.
8  *
9  */
10
11 #include <linux/platform_device.h>
12 #include <linux/clk-provider.h>
13 #include <linux/clk.h>
14 #include <linux/slab.h>
15 #include <linux/io.h>
16 #include <linux/of.h>
17 #include <linux/module.h>
18 #include <linux/err.h>
19
20 #define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04
21 #define AXI_CLKGEN_V1_REG_CLK_OUT1      0x08
22 #define AXI_CLKGEN_V1_REG_CLK_OUT2      0x0c
23 #define AXI_CLKGEN_V1_REG_CLK_DIV       0x10
24 #define AXI_CLKGEN_V1_REG_CLK_FB1       0x14
25 #define AXI_CLKGEN_V1_REG_CLK_FB2       0x18
26 #define AXI_CLKGEN_V1_REG_LOCK1         0x1c
27 #define AXI_CLKGEN_V1_REG_LOCK2         0x20
28 #define AXI_CLKGEN_V1_REG_LOCK3         0x24
29 #define AXI_CLKGEN_V1_REG_FILTER1       0x28
30 #define AXI_CLKGEN_V1_REG_FILTER2       0x2c
31
32 #define AXI_CLKGEN_V2_REG_RESET         0x40
33 #define AXI_CLKGEN_V2_REG_DRP_CNTRL     0x70
34 #define AXI_CLKGEN_V2_REG_DRP_STATUS    0x74
35
36 #define AXI_CLKGEN_V2_RESET_MMCM_ENABLE BIT(1)
37 #define AXI_CLKGEN_V2_RESET_ENABLE      BIT(0)
38
39 #define AXI_CLKGEN_V2_DRP_CNTRL_SEL     BIT(29)
40 #define AXI_CLKGEN_V2_DRP_CNTRL_READ    BIT(28)
41
42 #define AXI_CLKGEN_V2_DRP_STATUS_BUSY   BIT(16)
43
44 #define MMCM_REG_CLKOUT0_1      0x08
45 #define MMCM_REG_CLKOUT0_2      0x09
46 #define MMCM_REG_CLK_FB1        0x14
47 #define MMCM_REG_CLK_FB2        0x15
48 #define MMCM_REG_CLK_DIV        0x16
49 #define MMCM_REG_LOCK1          0x18
50 #define MMCM_REG_LOCK2          0x19
51 #define MMCM_REG_LOCK3          0x1a
52 #define MMCM_REG_FILTER1        0x4e
53 #define MMCM_REG_FILTER2        0x4f
54
55 struct axi_clkgen;
56
57 struct axi_clkgen_mmcm_ops {
58         void (*enable)(struct axi_clkgen *axi_clkgen, bool enable);
59         int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg,
60                      unsigned int val, unsigned int mask);
61         int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg,
62                     unsigned int *val);
63 };
64
65 struct axi_clkgen {
66         void __iomem *base;
67         const struct axi_clkgen_mmcm_ops *mmcm_ops;
68         struct clk_hw clk_hw;
69 };
70
71 static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
72         bool enable)
73 {
74         axi_clkgen->mmcm_ops->enable(axi_clkgen, enable);
75 }
76
77 static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
78         unsigned int reg, unsigned int val, unsigned int mask)
79 {
80         return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask);
81 }
82
83 static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
84         unsigned int reg, unsigned int *val)
85 {
86         return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val);
87 }
88
89 static uint32_t axi_clkgen_lookup_filter(unsigned int m)
90 {
91         switch (m) {
92         case 0:
93                 return 0x01001990;
94         case 1:
95                 return 0x01001190;
96         case 2:
97                 return 0x01009890;
98         case 3:
99                 return 0x01001890;
100         case 4:
101                 return 0x01008890;
102         case 5 ... 8:
103                 return 0x01009090;
104         case 9 ... 11:
105                 return 0x01000890;
106         case 12:
107                 return 0x08009090;
108         case 13 ... 22:
109                 return 0x01001090;
110         case 23 ... 36:
111                 return 0x01008090;
112         case 37 ... 46:
113                 return 0x08001090;
114         default:
115                 return 0x08008090;
116         }
117 }
118
119 static const uint32_t axi_clkgen_lock_table[] = {
120         0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8,
121         0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8,
122         0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339,
123         0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271,
124         0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4,
125         0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190,
126         0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e,
127         0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c,
128         0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113,
129 };
130
131 static uint32_t axi_clkgen_lookup_lock(unsigned int m)
132 {
133         if (m < ARRAY_SIZE(axi_clkgen_lock_table))
134                 return axi_clkgen_lock_table[m];
135         return 0x1f1f00fa;
136 }
137
138 static const unsigned int fpfd_min = 10000;
139 static const unsigned int fpfd_max = 300000;
140 static const unsigned int fvco_min = 600000;
141 static const unsigned int fvco_max = 1200000;
142
143 static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
144         unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout)
145 {
146         unsigned long d, d_min, d_max, _d_min, _d_max;
147         unsigned long m, m_min, m_max;
148         unsigned long f, dout, best_f, fvco;
149
150         fin /= 1000;
151         fout /= 1000;
152
153         best_f = ULONG_MAX;
154         *best_d = 0;
155         *best_m = 0;
156         *best_dout = 0;
157
158         d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1);
159         d_max = min_t(unsigned long, fin / fpfd_min, 80);
160
161         m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1);
162         m_max = min_t(unsigned long, fvco_max * d_max / fin, 64);
163
164         for (m = m_min; m <= m_max; m++) {
165                 _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max));
166                 _d_max = min(d_max, fin * m / fvco_min);
167
168                 for (d = _d_min; d <= _d_max; d++) {
169                         fvco = fin * m / d;
170
171                         dout = DIV_ROUND_CLOSEST(fvco, fout);
172                         dout = clamp_t(unsigned long, dout, 1, 128);
173                         f = fvco / dout;
174                         if (abs(f - fout) < abs(best_f - fout)) {
175                                 best_f = f;
176                                 *best_d = d;
177                                 *best_m = m;
178                                 *best_dout = dout;
179                                 if (best_f == fout)
180                                         return;
181                         }
182                 }
183         }
184 }
185
186 static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low,
187         unsigned int *high, unsigned int *edge, unsigned int *nocount)
188 {
189         if (divider == 1)
190                 *nocount = 1;
191         else
192                 *nocount = 0;
193
194         *high = divider / 2;
195         *edge = divider % 2;
196         *low = divider - *high;
197 }
198
199 static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
200         unsigned int reg, unsigned int val)
201 {
202         writel(val, axi_clkgen->base + reg);
203 }
204
205 static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
206         unsigned int reg, unsigned int *val)
207 {
208         *val = readl(axi_clkgen->base + reg);
209 }
210
211 static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg)
212 {
213         switch (reg) {
214         case MMCM_REG_CLKOUT0_1:
215                 return AXI_CLKGEN_V1_REG_CLK_OUT1;
216         case MMCM_REG_CLKOUT0_2:
217                 return AXI_CLKGEN_V1_REG_CLK_OUT2;
218         case MMCM_REG_CLK_FB1:
219                 return AXI_CLKGEN_V1_REG_CLK_FB1;
220         case MMCM_REG_CLK_FB2:
221                 return AXI_CLKGEN_V1_REG_CLK_FB2;
222         case MMCM_REG_CLK_DIV:
223                 return AXI_CLKGEN_V1_REG_CLK_DIV;
224         case MMCM_REG_LOCK1:
225                 return AXI_CLKGEN_V1_REG_LOCK1;
226         case MMCM_REG_LOCK2:
227                 return AXI_CLKGEN_V1_REG_LOCK2;
228         case MMCM_REG_LOCK3:
229                 return AXI_CLKGEN_V1_REG_LOCK3;
230         case MMCM_REG_FILTER1:
231                 return AXI_CLKGEN_V1_REG_FILTER1;
232         case MMCM_REG_FILTER2:
233                 return AXI_CLKGEN_V1_REG_FILTER2;
234         default:
235                 return 0;
236         }
237 }
238
239 static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen,
240         unsigned int reg, unsigned int val, unsigned int mask)
241 {
242         reg = axi_clkgen_v1_map_mmcm_reg(reg);
243         if (reg == 0)
244                 return -EINVAL;
245
246         axi_clkgen_write(axi_clkgen, reg, val);
247
248         return 0;
249 }
250
251 static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen,
252         unsigned int reg, unsigned int *val)
253 {
254         reg = axi_clkgen_v1_map_mmcm_reg(reg);
255         if (reg == 0)
256                 return -EINVAL;
257
258         axi_clkgen_read(axi_clkgen, reg, val);
259
260         return 0;
261 }
262
263 static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen,
264         bool enable)
265 {
266         axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable);
267 }
268
269 static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = {
270         .write = axi_clkgen_v1_mmcm_write,
271         .read = axi_clkgen_v1_mmcm_read,
272         .enable = axi_clkgen_v1_mmcm_enable,
273 };
274
275 static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
276 {
277         unsigned int timeout = 10000;
278         unsigned int val;
279
280         do {
281                 axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_STATUS, &val);
282         } while ((val & AXI_CLKGEN_V2_DRP_STATUS_BUSY) && --timeout);
283
284         if (val & AXI_CLKGEN_V2_DRP_STATUS_BUSY)
285                 return -EIO;
286
287         return val & 0xffff;
288 }
289
290 static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
291         unsigned int reg, unsigned int *val)
292 {
293         unsigned int reg_val;
294         int ret;
295
296         ret = axi_clkgen_wait_non_busy(axi_clkgen);
297         if (ret < 0)
298                 return ret;
299
300         reg_val = AXI_CLKGEN_V2_DRP_CNTRL_SEL | AXI_CLKGEN_V2_DRP_CNTRL_READ;
301         reg_val |= (reg << 16);
302
303         axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
304
305         ret = axi_clkgen_wait_non_busy(axi_clkgen);
306         if (ret < 0)
307                 return ret;
308
309         *val = ret;
310
311         return 0;
312 }
313
314 static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
315         unsigned int reg, unsigned int val, unsigned int mask)
316 {
317         unsigned int reg_val = 0;
318         int ret;
319
320         ret = axi_clkgen_wait_non_busy(axi_clkgen);
321         if (ret < 0)
322                 return ret;
323
324         if (mask != 0xffff) {
325                 axi_clkgen_v2_mmcm_read(axi_clkgen, reg, &reg_val);
326                 reg_val &= ~mask;
327         }
328
329         reg_val |= AXI_CLKGEN_V2_DRP_CNTRL_SEL | (reg << 16) | (val & mask);
330
331         axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
332
333         return 0;
334 }
335
336 static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
337         bool enable)
338 {
339         unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
340
341         if (enable)
342                 val |= AXI_CLKGEN_V2_RESET_MMCM_ENABLE;
343
344         axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
345 }
346
347 static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = {
348         .write = axi_clkgen_v2_mmcm_write,
349         .read = axi_clkgen_v2_mmcm_read,
350         .enable = axi_clkgen_v2_mmcm_enable,
351 };
352
353 static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
354 {
355         return container_of(clk_hw, struct axi_clkgen, clk_hw);
356 }
357
358 static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
359         unsigned long rate, unsigned long parent_rate)
360 {
361         struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
362         unsigned int d, m, dout;
363         unsigned int nocount;
364         unsigned int high;
365         unsigned int edge;
366         unsigned int low;
367         uint32_t filter;
368         uint32_t lock;
369
370         if (parent_rate == 0 || rate == 0)
371                 return -EINVAL;
372
373         axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout);
374
375         if (d == 0 || dout == 0 || m == 0)
376                 return -EINVAL;
377
378         filter = axi_clkgen_lookup_filter(m - 1);
379         lock = axi_clkgen_lookup_lock(m - 1);
380
381         axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
382         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_1,
383                 (high << 6) | low, 0xefff);
384         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_2,
385                 (edge << 7) | (nocount << 6), 0x03ff);
386
387         axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
388         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV,
389                 (edge << 13) | (nocount << 12) | (high << 6) | low, 0x3fff);
390
391         axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
392         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB1,
393                 (high << 6) | low, 0xefff);
394         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB2,
395                 (edge << 7) | (nocount << 6), 0x03ff);
396
397         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff);
398         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2,
399                 (((lock >> 16) & 0x1f) << 10) | 0x1, 0x7fff);
400         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK3,
401                 (((lock >> 24) & 0x1f) << 10) | 0x3e9, 0x7fff);
402         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER1, filter >> 16, 0x9900);
403         axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER2, filter, 0x9900);
404
405         return 0;
406 }
407
408 static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
409         unsigned long *parent_rate)
410 {
411         unsigned int d, m, dout;
412
413         axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout);
414
415         if (d == 0 || dout == 0 || m == 0)
416                 return -EINVAL;
417
418         return *parent_rate / d * m / dout;
419 }
420
421 static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
422         unsigned long parent_rate)
423 {
424         struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
425         unsigned int d, m, dout;
426         unsigned int reg;
427         unsigned long long tmp;
428
429         axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
430         dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
431         axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &reg);
432         d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
433         axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
434         m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
435
436         if (d == 0 || dout == 0)
437                 return 0;
438
439         tmp = (unsigned long long)(parent_rate / d) * m;
440         do_div(tmp, dout);
441
442         if (tmp > ULONG_MAX)
443                 return ULONG_MAX;
444
445         return tmp;
446 }
447
448 static int axi_clkgen_enable(struct clk_hw *clk_hw)
449 {
450         struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
451
452         axi_clkgen_mmcm_enable(axi_clkgen, true);
453
454         return 0;
455 }
456
457 static void axi_clkgen_disable(struct clk_hw *clk_hw)
458 {
459         struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
460
461         axi_clkgen_mmcm_enable(axi_clkgen, false);
462 }
463
464 static const struct clk_ops axi_clkgen_ops = {
465         .recalc_rate = axi_clkgen_recalc_rate,
466         .round_rate = axi_clkgen_round_rate,
467         .set_rate = axi_clkgen_set_rate,
468         .enable = axi_clkgen_enable,
469         .disable = axi_clkgen_disable,
470 };
471
472 static const struct of_device_id axi_clkgen_ids[] = {
473         {
474                 .compatible = "adi,axi-clkgen-1.00.a",
475                 .data = &axi_clkgen_v1_mmcm_ops
476         }, {
477                 .compatible = "adi,axi-clkgen-2.00.a",
478                 .data = &axi_clkgen_v2_mmcm_ops,
479         },
480         { },
481 };
482 MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
483
484 static int axi_clkgen_probe(struct platform_device *pdev)
485 {
486         const struct of_device_id *id;
487         struct axi_clkgen *axi_clkgen;
488         struct clk_init_data init;
489         const char *parent_name;
490         const char *clk_name;
491         struct resource *mem;
492         struct clk *clk;
493
494         if (!pdev->dev.of_node)
495                 return -ENODEV;
496
497         id = of_match_node(axi_clkgen_ids, pdev->dev.of_node);
498         if (!id)
499                 return -ENODEV;
500
501         axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
502         if (!axi_clkgen)
503                 return -ENOMEM;
504
505         axi_clkgen->mmcm_ops = id->data;
506
507         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
508         axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
509         if (IS_ERR(axi_clkgen->base))
510                 return PTR_ERR(axi_clkgen->base);
511
512         parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
513         if (!parent_name)
514                 return -EINVAL;
515
516         clk_name = pdev->dev.of_node->name;
517         of_property_read_string(pdev->dev.of_node, "clock-output-names",
518                 &clk_name);
519
520         init.name = clk_name;
521         init.ops = &axi_clkgen_ops;
522         init.flags = CLK_SET_RATE_GATE;
523         init.parent_names = &parent_name;
524         init.num_parents = 1;
525
526         axi_clkgen_mmcm_enable(axi_clkgen, false);
527
528         axi_clkgen->clk_hw.init = &init;
529         clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
530         if (IS_ERR(clk))
531                 return PTR_ERR(clk);
532
533         return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get,
534                                     clk);
535 }
536
537 static int axi_clkgen_remove(struct platform_device *pdev)
538 {
539         of_clk_del_provider(pdev->dev.of_node);
540
541         return 0;
542 }
543
544 static struct platform_driver axi_clkgen_driver = {
545         .driver = {
546                 .name = "adi-axi-clkgen",
547                 .of_match_table = axi_clkgen_ids,
548         },
549         .probe = axi_clkgen_probe,
550         .remove = axi_clkgen_remove,
551 };
552 module_platform_driver(axi_clkgen_driver);
553
554 MODULE_LICENSE("GPL v2");
555 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
556 MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator");