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