Linux-libre 5.4.49-gnu
[librecmc/linux-libre.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_MAIN + 1,
356                                             ndck(data->sck, data->num_sck),
357                                             ndck(data->pck, data->num_pck), 0);
358         if (!at91sam9260_pmc)
359                 return;
360
361         bypass = of_property_read_bool(np, "atmel,osc-bypass");
362
363         hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
364                                         bypass);
365         if (IS_ERR(hw))
366                 goto err_free;
367
368         hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc");
369         if (IS_ERR(hw))
370                 goto err_free;
371
372         at91sam9260_pmc->chws[PMC_MAIN] = hw;
373
374         if (data->has_slck) {
375                 hw = clk_hw_register_fixed_rate_with_accuracy(NULL,
376                                                               "slow_rc_osc",
377                                                               NULL, 0, 32768,
378                                                               50000000);
379                 if (IS_ERR(hw))
380                         goto err_free;
381
382                 parent_names[0] = "slow_rc_osc";
383                 parent_names[1] = "slow_xtal";
384                 hw = at91_clk_register_sam9260_slow(regmap, "slck",
385                                                     parent_names, 2);
386                 if (IS_ERR(hw))
387                         goto err_free;
388
389                 at91sam9260_pmc->chws[PMC_SLOW] = hw;
390                 slck_name = "slck";
391         } else {
392                 slck_name = slowxtal_name;
393         }
394
395         hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
396                                    data->plla_layout,
397                                    data->plla_characteristics);
398         if (IS_ERR(hw))
399                 goto err_free;
400
401         hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
402                                    data->pllb_layout,
403                                    data->pllb_characteristics);
404         if (IS_ERR(hw))
405                 goto err_free;
406
407         parent_names[0] = slck_name;
408         parent_names[1] = "mainck";
409         parent_names[2] = "pllack";
410         parent_names[3] = "pllbck";
411         hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
412                                       &at91rm9200_master_layout,
413                                       data->mck_characteristics);
414         if (IS_ERR(hw))
415                 goto err_free;
416
417         at91sam9260_pmc->chws[PMC_MCK] = hw;
418
419         hw = at91rm9200_clk_register_usb(regmap, "usbck", "pllbck", usb_div);
420         if (IS_ERR(hw))
421                 goto err_free;
422
423         parent_names[0] = slck_name;
424         parent_names[1] = "mainck";
425         parent_names[2] = "pllack";
426         parent_names[3] = "pllbck";
427         for (i = 0; i < data->num_progck; i++) {
428                 char name[6];
429
430                 snprintf(name, sizeof(name), "prog%d", i);
431
432                 hw = at91_clk_register_programmable(regmap, name,
433                                                     parent_names, 4, i,
434                                                     &at91rm9200_programmable_layout);
435                 if (IS_ERR(hw))
436                         goto err_free;
437         }
438
439         for (i = 0; i < data->num_sck; i++) {
440                 hw = at91_clk_register_system(regmap, data->sck[i].n,
441                                               data->sck[i].p,
442                                               data->sck[i].id);
443                 if (IS_ERR(hw))
444                         goto err_free;
445
446                 at91sam9260_pmc->shws[data->sck[i].id] = hw;
447         }
448
449         for (i = 0; i < data->num_pck; i++) {
450                 hw = at91_clk_register_peripheral(regmap,
451                                                   data->pck[i].n,
452                                                   "masterck",
453                                                   data->pck[i].id);
454                 if (IS_ERR(hw))
455                         goto err_free;
456
457                 at91sam9260_pmc->phws[data->pck[i].id] = hw;
458         }
459
460         of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9260_pmc);
461
462         return;
463
464 err_free:
465         pmc_data_free(at91sam9260_pmc);
466 }
467
468 static void __init at91sam9260_pmc_setup(struct device_node *np)
469 {
470         at91sam926x_pmc_setup(np, &at91sam9260_data);
471 }
472 CLK_OF_DECLARE_DRIVER(at91sam9260_pmc, "atmel,at91sam9260-pmc",
473                       at91sam9260_pmc_setup);
474
475 static void __init at91sam9261_pmc_setup(struct device_node *np)
476 {
477         at91sam926x_pmc_setup(np, &at91sam9261_data);
478 }
479 CLK_OF_DECLARE_DRIVER(at91sam9261_pmc, "atmel,at91sam9261-pmc",
480                       at91sam9261_pmc_setup);
481
482 static void __init at91sam9263_pmc_setup(struct device_node *np)
483 {
484         at91sam926x_pmc_setup(np, &at91sam9263_data);
485 }
486 CLK_OF_DECLARE_DRIVER(at91sam9263_pmc, "atmel,at91sam9263-pmc",
487                       at91sam9263_pmc_setup);
488
489 static void __init at91sam9g20_pmc_setup(struct device_node *np)
490 {
491         at91sam926x_pmc_setup(np, &at91sam9g20_data);
492 }
493 CLK_OF_DECLARE_DRIVER(at91sam9g20_pmc, "atmel,at91sam9g20-pmc",
494                       at91sam9g20_pmc_setup);