Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / clk / clk-nomadik.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Nomadik clock implementation
4  * Copyright (C) 2013 ST-Ericsson AB
5  * Author: Linus Walleij <linus.walleij@linaro.org>
6  */
7
8 #define pr_fmt(fmt) "Nomadik SRC clocks: " fmt
9
10 #include <linux/bitops.h>
11 #include <linux/slab.h>
12 #include <linux/err.h>
13 #include <linux/io.h>
14 #include <linux/clk-provider.h>
15 #include <linux/of.h>
16 #include <linux/of_address.h>
17 #include <linux/debugfs.h>
18 #include <linux/seq_file.h>
19 #include <linux/spinlock.h>
20 #include <linux/reboot.h>
21
22 /*
23  * The Nomadik clock tree is described in the STN8815A12 DB V4.2
24  * reference manual for the chip, page 94 ff.
25  * Clock IDs are in the STn8815 Reference Manual table 3, page 27.
26  */
27
28 #define SRC_CR                  0x00U
29 #define SRC_CR_T0_ENSEL         BIT(15)
30 #define SRC_CR_T1_ENSEL         BIT(17)
31 #define SRC_CR_T2_ENSEL         BIT(19)
32 #define SRC_CR_T3_ENSEL         BIT(21)
33 #define SRC_CR_T4_ENSEL         BIT(23)
34 #define SRC_CR_T5_ENSEL         BIT(25)
35 #define SRC_CR_T6_ENSEL         BIT(27)
36 #define SRC_CR_T7_ENSEL         BIT(29)
37 #define SRC_XTALCR              0x0CU
38 #define SRC_XTALCR_XTALTIMEN    BIT(20)
39 #define SRC_XTALCR_SXTALDIS     BIT(19)
40 #define SRC_XTALCR_MXTALSTAT    BIT(2)
41 #define SRC_XTALCR_MXTALEN      BIT(1)
42 #define SRC_XTALCR_MXTALOVER    BIT(0)
43 #define SRC_PLLCR               0x10U
44 #define SRC_PLLCR_PLLTIMEN      BIT(29)
45 #define SRC_PLLCR_PLL2EN        BIT(28)
46 #define SRC_PLLCR_PLL1STAT      BIT(2)
47 #define SRC_PLLCR_PLL1EN        BIT(1)
48 #define SRC_PLLCR_PLL1OVER      BIT(0)
49 #define SRC_PLLFR               0x14U
50 #define SRC_PCKEN0              0x24U
51 #define SRC_PCKDIS0             0x28U
52 #define SRC_PCKENSR0            0x2CU
53 #define SRC_PCKSR0              0x30U
54 #define SRC_PCKEN1              0x34U
55 #define SRC_PCKDIS1             0x38U
56 #define SRC_PCKENSR1            0x3CU
57 #define SRC_PCKSR1              0x40U
58
59 /* Lock protecting the SRC_CR register */
60 static DEFINE_SPINLOCK(src_lock);
61 /* Base address of the SRC */
62 static void __iomem *src_base;
63
64 static int nomadik_clk_reboot_handler(struct notifier_block *this,
65                                 unsigned long code,
66                                 void *unused)
67 {
68         u32 val;
69
70         /* The main chrystal need to be enabled for reboot to work */
71         val = readl(src_base + SRC_XTALCR);
72         val &= ~SRC_XTALCR_MXTALOVER;
73         val |= SRC_XTALCR_MXTALEN;
74         pr_crit("force-enabling MXTALO\n");
75         writel(val, src_base + SRC_XTALCR);
76         return NOTIFY_OK;
77 }
78
79 static struct notifier_block nomadik_clk_reboot_notifier = {
80         .notifier_call = nomadik_clk_reboot_handler,
81 };
82
83 static const struct of_device_id nomadik_src_match[] __initconst = {
84         { .compatible = "stericsson,nomadik-src" },
85         { /* sentinel */ }
86 };
87
88 static void __init nomadik_src_init(void)
89 {
90         struct device_node *np;
91         u32 val;
92
93         np = of_find_matching_node(NULL, nomadik_src_match);
94         if (!np) {
95                 pr_crit("no matching node for SRC, aborting clock init\n");
96                 return;
97         }
98         src_base = of_iomap(np, 0);
99         if (!src_base) {
100                 pr_err("%s: must have src parent node with REGS (%pOFn)\n",
101                        __func__, np);
102                 goto out_put;
103         }
104
105         /* Set all timers to use the 2.4 MHz TIMCLK */
106         val = readl(src_base + SRC_CR);
107         val |= SRC_CR_T0_ENSEL;
108         val |= SRC_CR_T1_ENSEL;
109         val |= SRC_CR_T2_ENSEL;
110         val |= SRC_CR_T3_ENSEL;
111         val |= SRC_CR_T4_ENSEL;
112         val |= SRC_CR_T5_ENSEL;
113         val |= SRC_CR_T6_ENSEL;
114         val |= SRC_CR_T7_ENSEL;
115         writel(val, src_base + SRC_CR);
116
117         val = readl(src_base + SRC_XTALCR);
118         pr_info("SXTALO is %s\n",
119                 (val & SRC_XTALCR_SXTALDIS) ? "disabled" : "enabled");
120         pr_info("MXTAL is %s\n",
121                 (val & SRC_XTALCR_MXTALSTAT) ? "enabled" : "disabled");
122         if (of_property_read_bool(np, "disable-sxtalo")) {
123                 /* The machine uses an external oscillator circuit */
124                 val |= SRC_XTALCR_SXTALDIS;
125                 pr_info("disabling SXTALO\n");
126         }
127         if (of_property_read_bool(np, "disable-mxtalo")) {
128                 /* Disable this too: also run by external oscillator */
129                 val |= SRC_XTALCR_MXTALOVER;
130                 val &= ~SRC_XTALCR_MXTALEN;
131                 pr_info("disabling MXTALO\n");
132         }
133         writel(val, src_base + SRC_XTALCR);
134         register_reboot_notifier(&nomadik_clk_reboot_notifier);
135
136 out_put:
137         of_node_put(np);
138 }
139
140 /**
141  * struct clk_pll - Nomadik PLL clock
142  * @hw: corresponding clock hardware entry
143  * @id: PLL instance: 1 or 2
144  */
145 struct clk_pll {
146         struct clk_hw hw;
147         int id;
148 };
149
150 /**
151  * struct clk_src - Nomadik src clock
152  * @hw: corresponding clock hardware entry
153  * @id: the clock ID
154  * @group1: true if the clock is in group1, else it is in group0
155  * @clkbit: bit 0...31 corresponding to the clock in each clock register
156  */
157 struct clk_src {
158         struct clk_hw hw;
159         int id;
160         bool group1;
161         u32 clkbit;
162 };
163
164 #define to_pll(_hw) container_of(_hw, struct clk_pll, hw)
165 #define to_src(_hw) container_of(_hw, struct clk_src, hw)
166
167 static int pll_clk_enable(struct clk_hw *hw)
168 {
169         struct clk_pll *pll = to_pll(hw);
170         u32 val;
171
172         spin_lock(&src_lock);
173         val = readl(src_base + SRC_PLLCR);
174         if (pll->id == 1) {
175                 if (val & SRC_PLLCR_PLL1OVER) {
176                         val |= SRC_PLLCR_PLL1EN;
177                         writel(val, src_base + SRC_PLLCR);
178                 }
179         } else if (pll->id == 2) {
180                 val |= SRC_PLLCR_PLL2EN;
181                 writel(val, src_base + SRC_PLLCR);
182         }
183         spin_unlock(&src_lock);
184         return 0;
185 }
186
187 static void pll_clk_disable(struct clk_hw *hw)
188 {
189         struct clk_pll *pll = to_pll(hw);
190         u32 val;
191
192         spin_lock(&src_lock);
193         val = readl(src_base + SRC_PLLCR);
194         if (pll->id == 1) {
195                 if (val & SRC_PLLCR_PLL1OVER) {
196                         val &= ~SRC_PLLCR_PLL1EN;
197                         writel(val, src_base + SRC_PLLCR);
198                 }
199         } else if (pll->id == 2) {
200                 val &= ~SRC_PLLCR_PLL2EN;
201                 writel(val, src_base + SRC_PLLCR);
202         }
203         spin_unlock(&src_lock);
204 }
205
206 static int pll_clk_is_enabled(struct clk_hw *hw)
207 {
208         struct clk_pll *pll = to_pll(hw);
209         u32 val;
210
211         val = readl(src_base + SRC_PLLCR);
212         if (pll->id == 1) {
213                 if (val & SRC_PLLCR_PLL1OVER)
214                         return !!(val & SRC_PLLCR_PLL1EN);
215         } else if (pll->id == 2) {
216                 return !!(val & SRC_PLLCR_PLL2EN);
217         }
218         return 1;
219 }
220
221 static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
222                                           unsigned long parent_rate)
223 {
224         struct clk_pll *pll = to_pll(hw);
225         u32 val;
226
227         val = readl(src_base + SRC_PLLFR);
228
229         if (pll->id == 1) {
230                 u8 mul;
231                 u8 div;
232
233                 mul = (val >> 8) & 0x3FU;
234                 mul += 2;
235                 div = val & 0x07U;
236                 return (parent_rate * mul) >> div;
237         }
238
239         if (pll->id == 2) {
240                 u8 mul;
241
242                 mul = (val >> 24) & 0x3FU;
243                 mul += 2;
244                 return (parent_rate * mul);
245         }
246
247         /* Unknown PLL */
248         return 0;
249 }
250
251
252 static const struct clk_ops pll_clk_ops = {
253         .enable = pll_clk_enable,
254         .disable = pll_clk_disable,
255         .is_enabled = pll_clk_is_enabled,
256         .recalc_rate = pll_clk_recalc_rate,
257 };
258
259 static struct clk_hw * __init
260 pll_clk_register(struct device *dev, const char *name,
261                  const char *parent_name, u32 id)
262 {
263         int ret;
264         struct clk_pll *pll;
265         struct clk_init_data init;
266
267         if (id != 1 && id != 2) {
268                 pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__);
269                 return ERR_PTR(-EINVAL);
270         }
271
272         pll = kzalloc(sizeof(*pll), GFP_KERNEL);
273         if (!pll)
274                 return ERR_PTR(-ENOMEM);
275
276         init.name = name;
277         init.ops = &pll_clk_ops;
278         init.parent_names = (parent_name ? &parent_name : NULL);
279         init.num_parents = (parent_name ? 1 : 0);
280         pll->hw.init = &init;
281         pll->id = id;
282
283         pr_debug("register PLL1 clock \"%s\"\n", name);
284
285         ret = clk_hw_register(dev, &pll->hw);
286         if (ret) {
287                 kfree(pll);
288                 return ERR_PTR(ret);
289         }
290
291         return &pll->hw;
292 }
293
294 /*
295  * The Nomadik SRC clocks are gated, but not in the sense that
296  * you read-modify-write a register. Instead there are separate
297  * clock enable and clock disable registers. Writing a '1' bit in
298  * the enable register for a certain clock ungates that clock without
299  * affecting the other clocks. The disable register works the opposite
300  * way.
301  */
302
303 static int src_clk_enable(struct clk_hw *hw)
304 {
305         struct clk_src *sclk = to_src(hw);
306         u32 enreg = sclk->group1 ? SRC_PCKEN1 : SRC_PCKEN0;
307         u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
308
309         writel(sclk->clkbit, src_base + enreg);
310         /* spin until enabled */
311         while (!(readl(src_base + sreg) & sclk->clkbit))
312                 cpu_relax();
313         return 0;
314 }
315
316 static void src_clk_disable(struct clk_hw *hw)
317 {
318         struct clk_src *sclk = to_src(hw);
319         u32 disreg = sclk->group1 ? SRC_PCKDIS1 : SRC_PCKDIS0;
320         u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
321
322         writel(sclk->clkbit, src_base + disreg);
323         /* spin until disabled */
324         while (readl(src_base + sreg) & sclk->clkbit)
325                 cpu_relax();
326 }
327
328 static int src_clk_is_enabled(struct clk_hw *hw)
329 {
330         struct clk_src *sclk = to_src(hw);
331         u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
332         u32 val = readl(src_base + sreg);
333
334         return !!(val & sclk->clkbit);
335 }
336
337 static unsigned long
338 src_clk_recalc_rate(struct clk_hw *hw,
339                     unsigned long parent_rate)
340 {
341         return parent_rate;
342 }
343
344 static const struct clk_ops src_clk_ops = {
345         .enable = src_clk_enable,
346         .disable = src_clk_disable,
347         .is_enabled = src_clk_is_enabled,
348         .recalc_rate = src_clk_recalc_rate,
349 };
350
351 static struct clk_hw * __init
352 src_clk_register(struct device *dev, const char *name,
353                  const char *parent_name, u8 id)
354 {
355         int ret;
356         struct clk_src *sclk;
357         struct clk_init_data init;
358
359         sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
360         if (!sclk)
361                 return ERR_PTR(-ENOMEM);
362
363         init.name = name;
364         init.ops = &src_clk_ops;
365         /* Do not force-disable the static SDRAM controller */
366         if (id == 2)
367                 init.flags = CLK_IGNORE_UNUSED;
368         else
369                 init.flags = 0;
370         init.parent_names = (parent_name ? &parent_name : NULL);
371         init.num_parents = (parent_name ? 1 : 0);
372         sclk->hw.init = &init;
373         sclk->id = id;
374         sclk->group1 = (id > 31);
375         sclk->clkbit = BIT(id & 0x1f);
376
377         pr_debug("register clock \"%s\" ID: %d group: %d bits: %08x\n",
378                  name, id, sclk->group1, sclk->clkbit);
379
380         ret = clk_hw_register(dev, &sclk->hw);
381         if (ret) {
382                 kfree(sclk);
383                 return ERR_PTR(ret);
384         }
385
386         return &sclk->hw;
387 }
388
389 #ifdef CONFIG_DEBUG_FS
390
391 static u32 src_pcksr0_boot;
392 static u32 src_pcksr1_boot;
393
394 static const char * const src_clk_names[] = {
395         "HCLKDMA0  ",
396         "HCLKSMC   ",
397         "HCLKSDRAM ",
398         "HCLKDMA1  ",
399         "HCLKCLCD  ",
400         "PCLKIRDA  ",
401         "PCLKSSP   ",
402         "PCLKUART0 ",
403         "PCLKSDI   ",
404         "PCLKI2C0  ",
405         "PCLKI2C1  ",
406         "PCLKUART1 ",
407         "PCLMSP0   ",
408         "HCLKUSB   ",
409         "HCLKDIF   ",
410         "HCLKSAA   ",
411         "HCLKSVA   ",
412         "PCLKHSI   ",
413         "PCLKXTI   ",
414         "PCLKUART2 ",
415         "PCLKMSP1  ",
416         "PCLKMSP2  ",
417         "PCLKOWM   ",
418         "HCLKHPI   ",
419         "PCLKSKE   ",
420         "PCLKHSEM  ",
421         "HCLK3D    ",
422         "HCLKHASH  ",
423         "HCLKCRYP  ",
424         "PCLKMSHC  ",
425         "HCLKUSBM  ",
426         "HCLKRNG   ",
427         "RESERVED  ",
428         "RESERVED  ",
429         "RESERVED  ",
430         "RESERVED  ",
431         "CLDCLK    ",
432         "IRDACLK   ",
433         "SSPICLK   ",
434         "UART0CLK  ",
435         "SDICLK    ",
436         "I2C0CLK   ",
437         "I2C1CLK   ",
438         "UART1CLK  ",
439         "MSPCLK0   ",
440         "USBCLK    ",
441         "DIFCLK    ",
442         "IPI2CCLK  ",
443         "IPBMCCLK  ",
444         "HSICLKRX  ",
445         "HSICLKTX  ",
446         "UART2CLK  ",
447         "MSPCLK1   ",
448         "MSPCLK2   ",
449         "OWMCLK    ",
450         "RESERVED  ",
451         "SKECLK    ",
452         "RESERVED  ",
453         "3DCLK     ",
454         "PCLKMSP3  ",
455         "MSPCLK3   ",
456         "MSHCCLK   ",
457         "USBMCLK   ",
458         "RNGCCLK   ",
459 };
460
461 static int nomadik_src_clk_debugfs_show(struct seq_file *s, void *what)
462 {
463         int i;
464         u32 src_pcksr0 = readl(src_base + SRC_PCKSR0);
465         u32 src_pcksr1 = readl(src_base + SRC_PCKSR1);
466         u32 src_pckensr0 = readl(src_base + SRC_PCKENSR0);
467         u32 src_pckensr1 = readl(src_base + SRC_PCKENSR1);
468
469         seq_puts(s, "Clock:      Boot:   Now:    Request: ASKED:\n");
470         for (i = 0; i < ARRAY_SIZE(src_clk_names); i++) {
471                 u32 pcksrb = (i < 0x20) ? src_pcksr0_boot : src_pcksr1_boot;
472                 u32 pcksr = (i < 0x20) ? src_pcksr0 : src_pcksr1;
473                 u32 pckreq = (i < 0x20) ? src_pckensr0 : src_pckensr1;
474                 u32 mask = BIT(i & 0x1f);
475
476                 seq_printf(s, "%s  %s     %s     %s\n",
477                            src_clk_names[i],
478                            (pcksrb & mask) ? "on " : "off",
479                            (pcksr & mask) ? "on " : "off",
480                            (pckreq & mask) ? "on " : "off");
481         }
482         return 0;
483 }
484
485 DEFINE_SHOW_ATTRIBUTE(nomadik_src_clk_debugfs);
486
487 static int __init nomadik_src_clk_init_debugfs(void)
488 {
489         /* Vital for multiplatform */
490         if (!src_base)
491                 return -ENODEV;
492         src_pcksr0_boot = readl(src_base + SRC_PCKSR0);
493         src_pcksr1_boot = readl(src_base + SRC_PCKSR1);
494         debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO,
495                             NULL, NULL, &nomadik_src_clk_debugfs_fops);
496         return 0;
497 }
498 device_initcall(nomadik_src_clk_init_debugfs);
499
500 #endif
501
502 static void __init of_nomadik_pll_setup(struct device_node *np)
503 {
504         struct clk_hw *hw;
505         const char *clk_name = np->name;
506         const char *parent_name;
507         u32 pll_id;
508
509         if (!src_base)
510                 nomadik_src_init();
511
512         if (of_property_read_u32(np, "pll-id", &pll_id)) {
513                 pr_err("%s: PLL \"%s\" missing pll-id property\n",
514                         __func__, clk_name);
515                 return;
516         }
517         parent_name = of_clk_get_parent_name(np, 0);
518         hw = pll_clk_register(NULL, clk_name, parent_name, pll_id);
519         if (!IS_ERR(hw))
520                 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
521 }
522 CLK_OF_DECLARE(nomadik_pll_clk,
523         "st,nomadik-pll-clock", of_nomadik_pll_setup);
524
525 static void __init of_nomadik_hclk_setup(struct device_node *np)
526 {
527         struct clk_hw *hw;
528         const char *clk_name = np->name;
529         const char *parent_name;
530
531         if (!src_base)
532                 nomadik_src_init();
533
534         parent_name = of_clk_get_parent_name(np, 0);
535         /*
536          * The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
537          */
538         hw = clk_hw_register_divider(NULL, clk_name, parent_name,
539                            0, src_base + SRC_CR,
540                            13, 2,
541                            CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
542                            &src_lock);
543         if (!IS_ERR(hw))
544                 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
545 }
546 CLK_OF_DECLARE(nomadik_hclk_clk,
547         "st,nomadik-hclk-clock", of_nomadik_hclk_setup);
548
549 static void __init of_nomadik_src_clk_setup(struct device_node *np)
550 {
551         struct clk_hw *hw;
552         const char *clk_name = np->name;
553         const char *parent_name;
554         u32 clk_id;
555
556         if (!src_base)
557                 nomadik_src_init();
558
559         if (of_property_read_u32(np, "clock-id", &clk_id)) {
560                 pr_err("%s: SRC clock \"%s\" missing clock-id property\n",
561                         __func__, clk_name);
562                 return;
563         }
564         parent_name = of_clk_get_parent_name(np, 0);
565         hw = src_clk_register(NULL, clk_name, parent_name, clk_id);
566         if (!IS_ERR(hw))
567                 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
568 }
569 CLK_OF_DECLARE(nomadik_src_clk,
570         "st,nomadik-src-clock", of_nomadik_src_clk_setup);