Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
[linux-2.6-microblaze.git] / drivers / clk / at91 / at91sam9260.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/clk-provider.h>
3 #include <linux/mfd/syscon.h>
4 #include <linux/slab.h>
5
6 #include <dt-bindings/clock/at91.h>
7
8 #include "pmc.h"
9
10 struct sck {
11         char *n;
12         char *p;
13         u8 id;
14 };
15
16 struct pck {
17         char *n;
18         u8 id;
19 };
20
21 struct at91sam926x_data {
22         const struct clk_pll_layout *plla_layout;
23         const struct clk_pll_characteristics *plla_characteristics;
24         const struct clk_pll_layout *pllb_layout;
25         const struct clk_pll_characteristics *pllb_characteristics;
26         const struct clk_master_characteristics *mck_characteristics;
27         const struct sck *sck;
28         const struct pck *pck;
29         u8 num_sck;
30         u8 num_pck;
31         u8 num_progck;
32         bool has_slck;
33 };
34
35 static const struct clk_master_characteristics sam9260_mck_characteristics = {
36         .output = { .min = 0, .max = 105000000 },
37         .divisors = { 1, 2, 4, 0 },
38 };
39
40 static u8 sam9260_plla_out[] = { 0, 2 };
41
42 static u16 sam9260_plla_icpll[] = { 1, 1 };
43
44 static const struct clk_range sam9260_plla_outputs[] = {
45         { .min = 80000000, .max = 160000000 },
46         { .min = 150000000, .max = 240000000 },
47 };
48
49 static const struct clk_pll_characteristics sam9260_plla_characteristics = {
50         .input = { .min = 1000000, .max = 32000000 },
51         .num_output = ARRAY_SIZE(sam9260_plla_outputs),
52         .output = sam9260_plla_outputs,
53         .icpll = sam9260_plla_icpll,
54         .out = sam9260_plla_out,
55 };
56
57 static u8 sam9260_pllb_out[] = { 1 };
58
59 static u16 sam9260_pllb_icpll[] = { 1 };
60
61 static const struct clk_range sam9260_pllb_outputs[] = {
62         { .min = 70000000, .max = 130000000 },
63 };
64
65 static const struct clk_pll_characteristics sam9260_pllb_characteristics = {
66         .input = { .min = 1000000, .max = 5000000 },
67         .num_output = ARRAY_SIZE(sam9260_pllb_outputs),
68         .output = sam9260_pllb_outputs,
69         .icpll = sam9260_pllb_icpll,
70         .out = sam9260_pllb_out,
71 };
72
73 static const struct sck at91sam9260_systemck[] = {
74         { .n = "uhpck", .p = "usbck",    .id = 6 },
75         { .n = "udpck", .p = "usbck",    .id = 7 },
76         { .n = "pck0",  .p = "prog0",    .id = 8 },
77         { .n = "pck1",  .p = "prog1",    .id = 9 },
78 };
79
80 static const struct pck at91sam9260_periphck[] = {
81         { .n = "pioA_clk",   .id = 2 },
82         { .n = "pioB_clk",   .id = 3 },
83         { .n = "pioC_clk",   .id = 4 },
84         { .n = "adc_clk",    .id = 5 },
85         { .n = "usart0_clk", .id = 6 },
86         { .n = "usart1_clk", .id = 7 },
87         { .n = "usart2_clk", .id = 8 },
88         { .n = "mci0_clk",   .id = 9 },
89         { .n = "udc_clk",    .id = 10 },
90         { .n = "twi0_clk",   .id = 11 },
91         { .n = "spi0_clk",   .id = 12 },
92         { .n = "spi1_clk",   .id = 13 },
93         { .n = "ssc0_clk",   .id = 14 },
94         { .n = "tc0_clk",    .id = 17 },
95         { .n = "tc1_clk",    .id = 18 },
96         { .n = "tc2_clk",    .id = 19 },
97         { .n = "ohci_clk",   .id = 20 },
98         { .n = "macb0_clk",  .id = 21 },
99         { .n = "isi_clk",    .id = 22 },
100         { .n = "usart3_clk", .id = 23 },
101         { .n = "uart0_clk",  .id = 24 },
102         { .n = "uart1_clk",  .id = 25 },
103         { .n = "tc3_clk",    .id = 26 },
104         { .n = "tc4_clk",    .id = 27 },
105         { .n = "tc5_clk",    .id = 28 },
106 };
107
108 static struct at91sam926x_data at91sam9260_data = {
109         .plla_layout = &at91rm9200_pll_layout,
110         .plla_characteristics = &sam9260_plla_characteristics,
111         .pllb_layout = &at91rm9200_pll_layout,
112         .pllb_characteristics = &sam9260_pllb_characteristics,
113         .mck_characteristics = &sam9260_mck_characteristics,
114         .sck = at91sam9260_systemck,
115         .num_sck = ARRAY_SIZE(at91sam9260_systemck),
116         .pck = at91sam9260_periphck,
117         .num_pck = ARRAY_SIZE(at91sam9260_periphck),
118         .num_progck = 2,
119         .has_slck = true,
120 };
121
122 static const struct clk_master_characteristics sam9g20_mck_characteristics = {
123         .output = { .min = 0, .max = 133000000 },
124         .divisors = { 1, 2, 4, 6 },
125 };
126
127 static u8 sam9g20_plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
128
129 static u16 sam9g20_plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
130
131 static const struct clk_range sam9g20_plla_outputs[] = {
132         { .min = 745000000, .max = 800000000 },
133         { .min = 695000000, .max = 750000000 },
134         { .min = 645000000, .max = 700000000 },
135         { .min = 595000000, .max = 650000000 },
136         { .min = 545000000, .max = 600000000 },
137         { .min = 495000000, .max = 550000000 },
138         { .min = 445000000, .max = 500000000 },
139         { .min = 400000000, .max = 450000000 },
140 };
141
142 static const struct clk_pll_characteristics sam9g20_plla_characteristics = {
143         .input = { .min = 2000000, .max = 32000000 },
144         .num_output = ARRAY_SIZE(sam9g20_plla_outputs),
145         .output = sam9g20_plla_outputs,
146         .icpll = sam9g20_plla_icpll,
147         .out = sam9g20_plla_out,
148 };
149
150 static u8 sam9g20_pllb_out[] = { 0 };
151
152 static u16 sam9g20_pllb_icpll[] = { 0 };
153
154 static const struct clk_range sam9g20_pllb_outputs[] = {
155         { .min = 30000000, .max = 100000000 },
156 };
157
158 static const struct clk_pll_characteristics sam9g20_pllb_characteristics = {
159         .input = { .min = 2000000, .max = 32000000 },
160         .num_output = ARRAY_SIZE(sam9g20_pllb_outputs),
161         .output = sam9g20_pllb_outputs,
162         .icpll = sam9g20_pllb_icpll,
163         .out = sam9g20_pllb_out,
164 };
165
166 static struct at91sam926x_data at91sam9g20_data = {
167         .plla_layout = &at91sam9g45_pll_layout,
168         .plla_characteristics = &sam9g20_plla_characteristics,
169         .pllb_layout = &at91sam9g20_pllb_layout,
170         .pllb_characteristics = &sam9g20_pllb_characteristics,
171         .mck_characteristics = &sam9g20_mck_characteristics,
172         .sck = at91sam9260_systemck,
173         .num_sck = ARRAY_SIZE(at91sam9260_systemck),
174         .pck = at91sam9260_periphck,
175         .num_pck = ARRAY_SIZE(at91sam9260_periphck),
176         .num_progck = 2,
177         .has_slck = true,
178 };
179
180 static const struct clk_master_characteristics sam9261_mck_characteristics = {
181         .output = { .min = 0, .max = 94000000 },
182         .divisors = { 1, 2, 4, 0 },
183 };
184
185 static const struct clk_range sam9261_plla_outputs[] = {
186         { .min = 80000000, .max = 200000000 },
187         { .min = 190000000, .max = 240000000 },
188 };
189
190 static const struct clk_pll_characteristics sam9261_plla_characteristics = {
191         .input = { .min = 1000000, .max = 32000000 },
192         .num_output = ARRAY_SIZE(sam9261_plla_outputs),
193         .output = sam9261_plla_outputs,
194         .icpll = sam9260_plla_icpll,
195         .out = sam9260_plla_out,
196 };
197
198 static u8 sam9261_pllb_out[] = { 1 };
199
200 static u16 sam9261_pllb_icpll[] = { 1 };
201
202 static const struct clk_range sam9261_pllb_outputs[] = {
203         { .min = 70000000, .max = 130000000 },
204 };
205
206 static const struct clk_pll_characteristics sam9261_pllb_characteristics = {
207         .input = { .min = 1000000, .max = 5000000 },
208         .num_output = ARRAY_SIZE(sam9261_pllb_outputs),
209         .output = sam9261_pllb_outputs,
210         .icpll = sam9261_pllb_icpll,
211         .out = sam9261_pllb_out,
212 };
213
214 static const struct sck at91sam9261_systemck[] = {
215         { .n = "uhpck", .p = "usbck",    .id = 6 },
216         { .n = "udpck", .p = "usbck",    .id = 7 },
217         { .n = "pck0",  .p = "prog0",    .id = 8 },
218         { .n = "pck1",  .p = "prog1",    .id = 9 },
219         { .n = "pck2",  .p = "prog2",    .id = 10 },
220         { .n = "pck3",  .p = "prog3",    .id = 11 },
221         { .n = "hclk0", .p = "masterck", .id = 16 },
222         { .n = "hclk1", .p = "masterck", .id = 17 },
223 };
224
225 static const struct pck at91sam9261_periphck[] = {
226         { .n = "pioA_clk",   .id = 2, },
227         { .n = "pioB_clk",   .id = 3, },
228         { .n = "pioC_clk",   .id = 4, },
229         { .n = "usart0_clk", .id = 6, },
230         { .n = "usart1_clk", .id = 7, },
231         { .n = "usart2_clk", .id = 8, },
232         { .n = "mci0_clk",   .id = 9, },
233         { .n = "udc_clk",    .id = 10, },
234         { .n = "twi0_clk",   .id = 11, },
235         { .n = "spi0_clk",   .id = 12, },
236         { .n = "spi1_clk",   .id = 13, },
237         { .n = "ssc0_clk",   .id = 14, },
238         { .n = "ssc1_clk",   .id = 15, },
239         { .n = "ssc2_clk",   .id = 16, },
240         { .n = "tc0_clk",    .id = 17, },
241         { .n = "tc1_clk",    .id = 18, },
242         { .n = "tc2_clk",    .id = 19, },
243         { .n = "ohci_clk",   .id = 20, },
244         { .n = "lcd_clk",    .id = 21, },
245 };
246
247 static struct at91sam926x_data at91sam9261_data = {
248         .plla_layout = &at91rm9200_pll_layout,
249         .plla_characteristics = &sam9261_plla_characteristics,
250         .pllb_layout = &at91rm9200_pll_layout,
251         .pllb_characteristics = &sam9261_pllb_characteristics,
252         .mck_characteristics = &sam9261_mck_characteristics,
253         .sck = at91sam9261_systemck,
254         .num_sck = ARRAY_SIZE(at91sam9261_systemck),
255         .pck = at91sam9261_periphck,
256         .num_pck = ARRAY_SIZE(at91sam9261_periphck),
257         .num_progck = 4,
258 };
259
260 static const struct clk_master_characteristics sam9263_mck_characteristics = {
261         .output = { .min = 0, .max = 120000000 },
262         .divisors = { 1, 2, 4, 0 },
263 };
264
265 static const struct clk_range sam9263_pll_outputs[] = {
266         { .min = 80000000, .max = 200000000 },
267         { .min = 190000000, .max = 240000000 },
268 };
269
270 static const struct clk_pll_characteristics sam9263_pll_characteristics = {
271         .input = { .min = 1000000, .max = 32000000 },
272         .num_output = ARRAY_SIZE(sam9263_pll_outputs),
273         .output = sam9263_pll_outputs,
274         .icpll = sam9260_plla_icpll,
275         .out = sam9260_plla_out,
276 };
277
278 static const struct sck at91sam9263_systemck[] = {
279         { .n = "uhpck", .p = "usbck",    .id = 6 },
280         { .n = "udpck", .p = "usbck",    .id = 7 },
281         { .n = "pck0",  .p = "prog0",    .id = 8 },
282         { .n = "pck1",  .p = "prog1",    .id = 9 },
283         { .n = "pck2",  .p = "prog2",    .id = 10 },
284         { .n = "pck3",  .p = "prog3",    .id = 11 },
285 };
286
287 static const struct pck at91sam9263_periphck[] = {
288         { .n = "pioA_clk",   .id = 2, },
289         { .n = "pioB_clk",   .id = 3, },
290         { .n = "pioCDE_clk", .id = 4, },
291         { .n = "usart0_clk", .id = 7, },
292         { .n = "usart1_clk", .id = 8, },
293         { .n = "usart2_clk", .id = 9, },
294         { .n = "mci0_clk",   .id = 10, },
295         { .n = "mci1_clk",   .id = 11, },
296         { .n = "can_clk",    .id = 12, },
297         { .n = "twi0_clk",   .id = 13, },
298         { .n = "spi0_clk",   .id = 14, },
299         { .n = "spi1_clk",   .id = 15, },
300         { .n = "ssc0_clk",   .id = 16, },
301         { .n = "ssc1_clk",   .id = 17, },
302         { .n = "ac97_clk",   .id = 18, },
303         { .n = "tcb_clk",    .id = 19, },
304         { .n = "pwm_clk",    .id = 20, },
305         { .n = "macb0_clk",  .id = 21, },
306         { .n = "g2de_clk",   .id = 23, },
307         { .n = "udc_clk",    .id = 24, },
308         { .n = "isi_clk",    .id = 25, },
309         { .n = "lcd_clk",    .id = 26, },
310         { .n = "dma_clk",    .id = 27, },
311         { .n = "ohci_clk",   .id = 29, },
312 };
313
314 static struct at91sam926x_data at91sam9263_data = {
315         .plla_layout = &at91rm9200_pll_layout,
316         .plla_characteristics = &sam9263_pll_characteristics,
317         .pllb_layout = &at91rm9200_pll_layout,
318         .pllb_characteristics = &sam9263_pll_characteristics,
319         .mck_characteristics = &sam9263_mck_characteristics,
320         .sck = at91sam9263_systemck,
321         .num_sck = ARRAY_SIZE(at91sam9263_systemck),
322         .pck = at91sam9263_periphck,
323         .num_pck = ARRAY_SIZE(at91sam9263_periphck),
324         .num_progck = 4,
325 };
326
327 static void __init at91sam926x_pmc_setup(struct device_node *np,
328                                          struct at91sam926x_data *data)
329 {
330         const char *slowxtal_name, *mainxtal_name;
331         struct pmc_data *at91sam9260_pmc;
332         u32 usb_div[] = { 1, 2, 4, 0 };
333         const char *parent_names[6];
334         const char *slck_name;
335         struct regmap *regmap;
336         struct clk_hw *hw;
337         int i;
338         bool bypass;
339
340         i = of_property_match_string(np, "clock-names", "slow_xtal");
341         if (i < 0)
342                 return;
343
344         slowxtal_name = of_clk_get_parent_name(np, i);
345
346         i = of_property_match_string(np, "clock-names", "main_xtal");
347         if (i < 0)
348                 return;
349         mainxtal_name = of_clk_get_parent_name(np, i);
350
351         regmap = device_node_to_regmap(np);
352         if (IS_ERR(regmap))
353                 return;
354
355         at91sam9260_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
356                                             ndck(data->sck, data->num_sck),
357                                             ndck(data->pck, data->num_pck),
358                                             0, data->num_progck);
359         if (!at91sam9260_pmc)
360                 return;
361
362         bypass = of_property_read_bool(np, "atmel,osc-bypass");
363
364         hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
365                                         bypass);
366         if (IS_ERR(hw))
367                 goto err_free;
368
369         hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc");
370         if (IS_ERR(hw))
371                 goto err_free;
372
373         at91sam9260_pmc->chws[PMC_MAIN] = hw;
374
375         if (data->has_slck) {
376                 hw = clk_hw_register_fixed_rate_with_accuracy(NULL,
377                                                               "slow_rc_osc",
378                                                               NULL, 0, 32768,
379                                                               50000000);
380                 if (IS_ERR(hw))
381                         goto err_free;
382
383                 parent_names[0] = "slow_rc_osc";
384                 parent_names[1] = "slow_xtal";
385                 hw = at91_clk_register_sam9260_slow(regmap, "slck",
386                                                     parent_names, 2);
387                 if (IS_ERR(hw))
388                         goto err_free;
389
390                 at91sam9260_pmc->chws[PMC_SLOW] = hw;
391                 slck_name = "slck";
392         } else {
393                 slck_name = slowxtal_name;
394         }
395
396         hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
397                                    data->plla_layout,
398                                    data->plla_characteristics);
399         if (IS_ERR(hw))
400                 goto err_free;
401
402         at91sam9260_pmc->chws[PMC_PLLACK] = hw;
403
404         hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
405                                    data->pllb_layout,
406                                    data->pllb_characteristics);
407         if (IS_ERR(hw))
408                 goto err_free;
409
410         at91sam9260_pmc->chws[PMC_PLLBCK] = hw;
411
412         parent_names[0] = slck_name;
413         parent_names[1] = "mainck";
414         parent_names[2] = "pllack";
415         parent_names[3] = "pllbck";
416         hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
417                                       &at91rm9200_master_layout,
418                                       data->mck_characteristics);
419         if (IS_ERR(hw))
420                 goto err_free;
421
422         at91sam9260_pmc->chws[PMC_MCK] = hw;
423
424         hw = at91rm9200_clk_register_usb(regmap, "usbck", "pllbck", usb_div);
425         if (IS_ERR(hw))
426                 goto err_free;
427
428         parent_names[0] = slck_name;
429         parent_names[1] = "mainck";
430         parent_names[2] = "pllack";
431         parent_names[3] = "pllbck";
432         for (i = 0; i < data->num_progck; i++) {
433                 char name[6];
434
435                 snprintf(name, sizeof(name), "prog%d", i);
436
437                 hw = at91_clk_register_programmable(regmap, name,
438                                                     parent_names, 4, i,
439                                                     &at91rm9200_programmable_layout,
440                                                     NULL);
441                 if (IS_ERR(hw))
442                         goto err_free;
443
444                 at91sam9260_pmc->pchws[i] = hw;
445         }
446
447         for (i = 0; i < data->num_sck; i++) {
448                 hw = at91_clk_register_system(regmap, data->sck[i].n,
449                                               data->sck[i].p,
450                                               data->sck[i].id);
451                 if (IS_ERR(hw))
452                         goto err_free;
453
454                 at91sam9260_pmc->shws[data->sck[i].id] = hw;
455         }
456
457         for (i = 0; i < data->num_pck; i++) {
458                 hw = at91_clk_register_peripheral(regmap,
459                                                   data->pck[i].n,
460                                                   "masterck",
461                                                   data->pck[i].id);
462                 if (IS_ERR(hw))
463                         goto err_free;
464
465                 at91sam9260_pmc->phws[data->pck[i].id] = hw;
466         }
467
468         of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9260_pmc);
469
470         return;
471
472 err_free:
473         kfree(at91sam9260_pmc);
474 }
475
476 static void __init at91sam9260_pmc_setup(struct device_node *np)
477 {
478         at91sam926x_pmc_setup(np, &at91sam9260_data);
479 }
480 CLK_OF_DECLARE_DRIVER(at91sam9260_pmc, "atmel,at91sam9260-pmc",
481                       at91sam9260_pmc_setup);
482
483 static void __init at91sam9261_pmc_setup(struct device_node *np)
484 {
485         at91sam926x_pmc_setup(np, &at91sam9261_data);
486 }
487 CLK_OF_DECLARE_DRIVER(at91sam9261_pmc, "atmel,at91sam9261-pmc",
488                       at91sam9261_pmc_setup);
489
490 static void __init at91sam9263_pmc_setup(struct device_node *np)
491 {
492         at91sam926x_pmc_setup(np, &at91sam9263_data);
493 }
494 CLK_OF_DECLARE_DRIVER(at91sam9263_pmc, "atmel,at91sam9263-pmc",
495                       at91sam9263_pmc_setup);
496
497 static void __init at91sam9g20_pmc_setup(struct device_node *np)
498 {
499         at91sam926x_pmc_setup(np, &at91sam9g20_data);
500 }
501 CLK_OF_DECLARE_DRIVER(at91sam9g20_pmc, "atmel,at91sam9g20-pmc",
502                       at91sam9g20_pmc_setup);