GNU Linux-libre 4.4.294-gnu1
[releases.git] / drivers / clk / at91 / clk-usb.c
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/io.h>
17
18 #include "pmc.h"
19
20 #define USB_SOURCE_MAX          2
21
22 #define SAM9X5_USB_DIV_SHIFT    8
23 #define SAM9X5_USB_MAX_DIV      0xf
24
25 #define RM9200_USB_DIV_SHIFT    28
26 #define RM9200_USB_DIV_TAB_SIZE 4
27
28 struct at91sam9x5_clk_usb {
29         struct clk_hw hw;
30         struct at91_pmc *pmc;
31 };
32
33 #define to_at91sam9x5_clk_usb(hw) \
34         container_of(hw, struct at91sam9x5_clk_usb, hw)
35
36 struct at91rm9200_clk_usb {
37         struct clk_hw hw;
38         struct at91_pmc *pmc;
39         u32 divisors[4];
40 };
41
42 #define to_at91rm9200_clk_usb(hw) \
43         container_of(hw, struct at91rm9200_clk_usb, hw)
44
45 static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
46                                                     unsigned long parent_rate)
47 {
48         u32 tmp;
49         u8 usbdiv;
50         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
51         struct at91_pmc *pmc = usb->pmc;
52
53         tmp = pmc_read(pmc, AT91_PMC_USB);
54         usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
55
56         return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1));
57 }
58
59 static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw,
60                                              struct clk_rate_request *req)
61 {
62         struct clk_hw *parent;
63         long best_rate = -EINVAL;
64         unsigned long tmp_rate;
65         int best_diff = -1;
66         int tmp_diff;
67         int i;
68
69         for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
70                 int div;
71
72                 parent = clk_hw_get_parent_by_index(hw, i);
73                 if (!parent)
74                         continue;
75
76                 for (div = 1; div < SAM9X5_USB_MAX_DIV + 2; div++) {
77                         unsigned long tmp_parent_rate;
78
79                         tmp_parent_rate = req->rate * div;
80                         tmp_parent_rate = clk_hw_round_rate(parent,
81                                                            tmp_parent_rate);
82                         if (!tmp_parent_rate)
83                                 continue;
84
85                         tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div);
86                         if (tmp_rate < req->rate)
87                                 tmp_diff = req->rate - tmp_rate;
88                         else
89                                 tmp_diff = tmp_rate - req->rate;
90
91                         if (best_diff < 0 || best_diff > tmp_diff) {
92                                 best_rate = tmp_rate;
93                                 best_diff = tmp_diff;
94                                 req->best_parent_rate = tmp_parent_rate;
95                                 req->best_parent_hw = parent;
96                         }
97
98                         if (!best_diff || tmp_rate < req->rate)
99                                 break;
100                 }
101
102                 if (!best_diff)
103                         break;
104         }
105
106         if (best_rate < 0)
107                 return best_rate;
108
109         req->rate = best_rate;
110         return 0;
111 }
112
113 static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
114 {
115         u32 tmp;
116         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
117         struct at91_pmc *pmc = usb->pmc;
118
119         if (index > 1)
120                 return -EINVAL;
121         tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS;
122         if (index)
123                 tmp |= AT91_PMC_USBS;
124         pmc_write(pmc, AT91_PMC_USB, tmp);
125         return 0;
126 }
127
128 static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
129 {
130         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
131         struct at91_pmc *pmc = usb->pmc;
132
133         return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS;
134 }
135
136 static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
137                                        unsigned long parent_rate)
138 {
139         u32 tmp;
140         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
141         struct at91_pmc *pmc = usb->pmc;
142         unsigned long div;
143
144         if (!rate)
145                 return -EINVAL;
146
147         div = DIV_ROUND_CLOSEST(parent_rate, rate);
148         if (div > SAM9X5_USB_MAX_DIV + 1 || !div)
149                 return -EINVAL;
150
151         tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV;
152         tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT;
153         pmc_write(pmc, AT91_PMC_USB, tmp);
154
155         return 0;
156 }
157
158 static const struct clk_ops at91sam9x5_usb_ops = {
159         .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
160         .determine_rate = at91sam9x5_clk_usb_determine_rate,
161         .get_parent = at91sam9x5_clk_usb_get_parent,
162         .set_parent = at91sam9x5_clk_usb_set_parent,
163         .set_rate = at91sam9x5_clk_usb_set_rate,
164 };
165
166 static int at91sam9n12_clk_usb_enable(struct clk_hw *hw)
167 {
168         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
169         struct at91_pmc *pmc = usb->pmc;
170
171         pmc_write(pmc, AT91_PMC_USB,
172                   pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS);
173         return 0;
174 }
175
176 static void at91sam9n12_clk_usb_disable(struct clk_hw *hw)
177 {
178         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
179         struct at91_pmc *pmc = usb->pmc;
180
181         pmc_write(pmc, AT91_PMC_USB,
182                   pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS);
183 }
184
185 static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw)
186 {
187         struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
188         struct at91_pmc *pmc = usb->pmc;
189
190         return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS);
191 }
192
193 static const struct clk_ops at91sam9n12_usb_ops = {
194         .enable = at91sam9n12_clk_usb_enable,
195         .disable = at91sam9n12_clk_usb_disable,
196         .is_enabled = at91sam9n12_clk_usb_is_enabled,
197         .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
198         .determine_rate = at91sam9x5_clk_usb_determine_rate,
199         .set_rate = at91sam9x5_clk_usb_set_rate,
200 };
201
202 static struct clk * __init
203 at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name,
204                             const char **parent_names, u8 num_parents)
205 {
206         struct at91sam9x5_clk_usb *usb;
207         struct clk *clk = NULL;
208         struct clk_init_data init;
209
210         usb = kzalloc(sizeof(*usb), GFP_KERNEL);
211         if (!usb)
212                 return ERR_PTR(-ENOMEM);
213
214         init.name = name;
215         init.ops = &at91sam9x5_usb_ops;
216         init.parent_names = parent_names;
217         init.num_parents = num_parents;
218         init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
219                      CLK_SET_RATE_PARENT;
220
221         usb->hw.init = &init;
222         usb->pmc = pmc;
223
224         clk = clk_register(NULL, &usb->hw);
225         if (IS_ERR(clk))
226                 kfree(usb);
227
228         return clk;
229 }
230
231 static struct clk * __init
232 at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name,
233                              const char *parent_name)
234 {
235         struct at91sam9x5_clk_usb *usb;
236         struct clk *clk = NULL;
237         struct clk_init_data init;
238
239         usb = kzalloc(sizeof(*usb), GFP_KERNEL);
240         if (!usb)
241                 return ERR_PTR(-ENOMEM);
242
243         init.name = name;
244         init.ops = &at91sam9n12_usb_ops;
245         init.parent_names = &parent_name;
246         init.num_parents = 1;
247         init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
248
249         usb->hw.init = &init;
250         usb->pmc = pmc;
251
252         clk = clk_register(NULL, &usb->hw);
253         if (IS_ERR(clk))
254                 kfree(usb);
255
256         return clk;
257 }
258
259 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
260                                                     unsigned long parent_rate)
261 {
262         struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
263         struct at91_pmc *pmc = usb->pmc;
264         u32 tmp;
265         u8 usbdiv;
266
267         tmp = pmc_read(pmc, AT91_CKGR_PLLBR);
268         usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT;
269         if (usb->divisors[usbdiv])
270                 return parent_rate / usb->divisors[usbdiv];
271
272         return 0;
273 }
274
275 static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
276                                           unsigned long *parent_rate)
277 {
278         struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
279         struct clk_hw *parent = clk_hw_get_parent(hw);
280         unsigned long bestrate = 0;
281         int bestdiff = -1;
282         unsigned long tmprate;
283         int tmpdiff;
284         int i = 0;
285
286         for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
287                 unsigned long tmp_parent_rate;
288
289                 if (!usb->divisors[i])
290                         continue;
291
292                 tmp_parent_rate = rate * usb->divisors[i];
293                 tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate);
294                 tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]);
295                 if (tmprate < rate)
296                         tmpdiff = rate - tmprate;
297                 else
298                         tmpdiff = tmprate - rate;
299
300                 if (bestdiff < 0 || bestdiff > tmpdiff) {
301                         bestrate = tmprate;
302                         bestdiff = tmpdiff;
303                         *parent_rate = tmp_parent_rate;
304                 }
305
306                 if (!bestdiff)
307                         break;
308         }
309
310         return bestrate;
311 }
312
313 static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
314                                        unsigned long parent_rate)
315 {
316         u32 tmp;
317         int i;
318         struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
319         struct at91_pmc *pmc = usb->pmc;
320         unsigned long div;
321
322         if (!rate)
323                 return -EINVAL;
324
325         div = DIV_ROUND_CLOSEST(parent_rate, rate);
326
327         for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
328                 if (usb->divisors[i] == div) {
329                         tmp = pmc_read(pmc, AT91_CKGR_PLLBR) &
330                               ~AT91_PMC_USBDIV;
331                         tmp |= i << RM9200_USB_DIV_SHIFT;
332                         pmc_write(pmc, AT91_CKGR_PLLBR, tmp);
333                         return 0;
334                 }
335         }
336
337         return -EINVAL;
338 }
339
340 static const struct clk_ops at91rm9200_usb_ops = {
341         .recalc_rate = at91rm9200_clk_usb_recalc_rate,
342         .round_rate = at91rm9200_clk_usb_round_rate,
343         .set_rate = at91rm9200_clk_usb_set_rate,
344 };
345
346 static struct clk * __init
347 at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name,
348                             const char *parent_name, const u32 *divisors)
349 {
350         struct at91rm9200_clk_usb *usb;
351         struct clk *clk = NULL;
352         struct clk_init_data init;
353
354         usb = kzalloc(sizeof(*usb), GFP_KERNEL);
355         if (!usb)
356                 return ERR_PTR(-ENOMEM);
357
358         init.name = name;
359         init.ops = &at91rm9200_usb_ops;
360         init.parent_names = &parent_name;
361         init.num_parents = 1;
362         init.flags = CLK_SET_RATE_PARENT;
363
364         usb->hw.init = &init;
365         usb->pmc = pmc;
366         memcpy(usb->divisors, divisors, sizeof(usb->divisors));
367
368         clk = clk_register(NULL, &usb->hw);
369         if (IS_ERR(clk))
370                 kfree(usb);
371
372         return clk;
373 }
374
375 void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
376                                         struct at91_pmc *pmc)
377 {
378         struct clk *clk;
379         int num_parents;
380         const char *parent_names[USB_SOURCE_MAX];
381         const char *name = np->name;
382
383         num_parents = of_clk_get_parent_count(np);
384         if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
385                 return;
386
387         of_clk_parent_fill(np, parent_names, num_parents);
388
389         of_property_read_string(np, "clock-output-names", &name);
390
391         clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents);
392         if (IS_ERR(clk))
393                 return;
394
395         of_clk_add_provider(np, of_clk_src_simple_get, clk);
396 }
397
398 void __init of_at91sam9n12_clk_usb_setup(struct device_node *np,
399                                          struct at91_pmc *pmc)
400 {
401         struct clk *clk;
402         const char *parent_name;
403         const char *name = np->name;
404
405         parent_name = of_clk_get_parent_name(np, 0);
406         if (!parent_name)
407                 return;
408
409         of_property_read_string(np, "clock-output-names", &name);
410
411         clk = at91sam9n12_clk_register_usb(pmc, name, parent_name);
412         if (IS_ERR(clk))
413                 return;
414
415         of_clk_add_provider(np, of_clk_src_simple_get, clk);
416 }
417
418 void __init of_at91rm9200_clk_usb_setup(struct device_node *np,
419                                         struct at91_pmc *pmc)
420 {
421         struct clk *clk;
422         const char *parent_name;
423         const char *name = np->name;
424         u32 divisors[4] = {0, 0, 0, 0};
425
426         parent_name = of_clk_get_parent_name(np, 0);
427         if (!parent_name)
428                 return;
429
430         of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
431         if (!divisors[0])
432                 return;
433
434         of_property_read_string(np, "clock-output-names", &name);
435
436         clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors);
437         if (IS_ERR(clk))
438                 return;
439
440         of_clk_add_provider(np, of_clk_src_simple_get, clk);
441 }