1 // SPDX-License-Identifier: GPL-2.0-only
3 * Nomadik clock implementation
4 * Copyright (C) 2013 ST-Ericsson AB
5 * Author: Linus Walleij <linus.walleij@linaro.org>
8 #define pr_fmt(fmt) "Nomadik SRC clocks: " fmt
10 #include <linux/bitops.h>
11 #include <linux/slab.h>
12 #include <linux/err.h>
14 #include <linux/clk-provider.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>
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.
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
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
;
64 static int nomadik_clk_reboot_handler(struct notifier_block
*this,
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
);
79 static struct notifier_block nomadik_clk_reboot_notifier
= {
80 .notifier_call
= nomadik_clk_reboot_handler
,
83 static const struct of_device_id nomadik_src_match
[] __initconst
= {
84 { .compatible
= "stericsson,nomadik-src" },
88 static void __init
nomadik_src_init(void)
90 struct device_node
*np
;
93 np
= of_find_matching_node(NULL
, nomadik_src_match
);
95 pr_crit("no matching node for SRC, aborting clock init\n");
98 src_base
= of_iomap(np
, 0);
100 pr_err("%s: must have src parent node with REGS (%pOFn)\n",
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
);
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");
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");
133 writel(val
, src_base
+ SRC_XTALCR
);
134 register_reboot_notifier(&nomadik_clk_reboot_notifier
);
141 * struct clk_pll - Nomadik PLL clock
142 * @hw: corresponding clock hardware entry
143 * @id: PLL instance: 1 or 2
151 * struct clk_src - Nomadik src clock
152 * @hw: corresponding clock hardware entry
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
164 #define to_pll(_hw) container_of(_hw, struct clk_pll, hw)
165 #define to_src(_hw) container_of(_hw, struct clk_src, hw)
167 static int pll_clk_enable(struct clk_hw
*hw
)
169 struct clk_pll
*pll
= to_pll(hw
);
172 spin_lock(&src_lock
);
173 val
= readl(src_base
+ SRC_PLLCR
);
175 if (val
& SRC_PLLCR_PLL1OVER
) {
176 val
|= SRC_PLLCR_PLL1EN
;
177 writel(val
, src_base
+ SRC_PLLCR
);
179 } else if (pll
->id
== 2) {
180 val
|= SRC_PLLCR_PLL2EN
;
181 writel(val
, src_base
+ SRC_PLLCR
);
183 spin_unlock(&src_lock
);
187 static void pll_clk_disable(struct clk_hw
*hw
)
189 struct clk_pll
*pll
= to_pll(hw
);
192 spin_lock(&src_lock
);
193 val
= readl(src_base
+ SRC_PLLCR
);
195 if (val
& SRC_PLLCR_PLL1OVER
) {
196 val
&= ~SRC_PLLCR_PLL1EN
;
197 writel(val
, src_base
+ SRC_PLLCR
);
199 } else if (pll
->id
== 2) {
200 val
&= ~SRC_PLLCR_PLL2EN
;
201 writel(val
, src_base
+ SRC_PLLCR
);
203 spin_unlock(&src_lock
);
206 static int pll_clk_is_enabled(struct clk_hw
*hw
)
208 struct clk_pll
*pll
= to_pll(hw
);
211 val
= readl(src_base
+ SRC_PLLCR
);
213 if (val
& SRC_PLLCR_PLL1OVER
)
214 return !!(val
& SRC_PLLCR_PLL1EN
);
215 } else if (pll
->id
== 2) {
216 return !!(val
& SRC_PLLCR_PLL2EN
);
221 static unsigned long pll_clk_recalc_rate(struct clk_hw
*hw
,
222 unsigned long parent_rate
)
224 struct clk_pll
*pll
= to_pll(hw
);
227 val
= readl(src_base
+ SRC_PLLFR
);
233 mul
= (val
>> 8) & 0x3FU
;
236 return (parent_rate
* mul
) >> div
;
242 mul
= (val
>> 24) & 0x3FU
;
244 return (parent_rate
* mul
);
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
,
259 static struct clk_hw
* __init
260 pll_clk_register(struct device
*dev
, const char *name
,
261 const char *parent_name
, u32 id
)
265 struct clk_init_data init
;
267 if (id
!= 1 && id
!= 2) {
268 pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__
);
269 return ERR_PTR(-EINVAL
);
272 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
274 return ERR_PTR(-ENOMEM
);
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
;
283 pr_debug("register PLL1 clock \"%s\"\n", name
);
285 ret
= clk_hw_register(dev
, &pll
->hw
);
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
303 static int src_clk_enable(struct clk_hw
*hw
)
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
;
309 writel(sclk
->clkbit
, src_base
+ enreg
);
310 /* spin until enabled */
311 while (!(readl(src_base
+ sreg
) & sclk
->clkbit
))
316 static void src_clk_disable(struct clk_hw
*hw
)
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
;
322 writel(sclk
->clkbit
, src_base
+ disreg
);
323 /* spin until disabled */
324 while (readl(src_base
+ sreg
) & sclk
->clkbit
)
328 static int src_clk_is_enabled(struct clk_hw
*hw
)
330 struct clk_src
*sclk
= to_src(hw
);
331 u32 sreg
= sclk
->group1
? SRC_PCKSR1
: SRC_PCKSR0
;
332 u32 val
= readl(src_base
+ sreg
);
334 return !!(val
& sclk
->clkbit
);
338 src_clk_recalc_rate(struct clk_hw
*hw
,
339 unsigned long parent_rate
)
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
,
351 static struct clk_hw
* __init
352 src_clk_register(struct device
*dev
, const char *name
,
353 const char *parent_name
, u8 id
)
356 struct clk_src
*sclk
;
357 struct clk_init_data init
;
359 sclk
= kzalloc(sizeof(*sclk
), GFP_KERNEL
);
361 return ERR_PTR(-ENOMEM
);
364 init
.ops
= &src_clk_ops
;
365 /* Do not force-disable the static SDRAM controller */
367 init
.flags
= CLK_IGNORE_UNUSED
;
370 init
.parent_names
= (parent_name
? &parent_name
: NULL
);
371 init
.num_parents
= (parent_name
? 1 : 0);
372 sclk
->hw
.init
= &init
;
374 sclk
->group1
= (id
> 31);
375 sclk
->clkbit
= BIT(id
& 0x1f);
377 pr_debug("register clock \"%s\" ID: %d group: %d bits: %08x\n",
378 name
, id
, sclk
->group1
, sclk
->clkbit
);
380 ret
= clk_hw_register(dev
, &sclk
->hw
);
389 #ifdef CONFIG_DEBUG_FS
391 static u32 src_pcksr0_boot
;
392 static u32 src_pcksr1_boot
;
394 static const char * const src_clk_names
[] = {
461 static int nomadik_src_clk_debugfs_show(struct seq_file
*s
, void *what
)
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
);
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);
476 seq_printf(s
, "%s %s %s %s\n",
478 (pcksrb
& mask
) ? "on " : "off",
479 (pcksr
& mask
) ? "on " : "off",
480 (pckreq
& mask
) ? "on " : "off");
485 DEFINE_SHOW_ATTRIBUTE(nomadik_src_clk_debugfs
);
487 static int __init
nomadik_src_clk_init_debugfs(void)
489 /* Vital for multiplatform */
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
);
498 device_initcall(nomadik_src_clk_init_debugfs
);
502 static void __init
of_nomadik_pll_setup(struct device_node
*np
)
505 const char *clk_name
= np
->name
;
506 const char *parent_name
;
512 if (of_property_read_u32(np
, "pll-id", &pll_id
)) {
513 pr_err("%s: PLL \"%s\" missing pll-id property\n",
517 parent_name
= of_clk_get_parent_name(np
, 0);
518 hw
= pll_clk_register(NULL
, clk_name
, parent_name
, pll_id
);
520 of_clk_add_hw_provider(np
, of_clk_hw_simple_get
, hw
);
522 CLK_OF_DECLARE(nomadik_pll_clk
,
523 "st,nomadik-pll-clock", of_nomadik_pll_setup
);
525 static void __init
of_nomadik_hclk_setup(struct device_node
*np
)
528 const char *clk_name
= np
->name
;
529 const char *parent_name
;
534 parent_name
= of_clk_get_parent_name(np
, 0);
536 * The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
538 hw
= clk_hw_register_divider(NULL
, clk_name
, parent_name
,
539 0, src_base
+ SRC_CR
,
541 CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
544 of_clk_add_hw_provider(np
, of_clk_hw_simple_get
, hw
);
546 CLK_OF_DECLARE(nomadik_hclk_clk
,
547 "st,nomadik-hclk-clock", of_nomadik_hclk_setup
);
549 static void __init
of_nomadik_src_clk_setup(struct device_node
*np
)
552 const char *clk_name
= np
->name
;
553 const char *parent_name
;
559 if (of_property_read_u32(np
, "clock-id", &clk_id
)) {
560 pr_err("%s: SRC clock \"%s\" missing clock-id property\n",
564 parent_name
= of_clk_get_parent_name(np
, 0);
565 hw
= src_clk_register(NULL
, clk_name
, parent_name
, clk_id
);
567 of_clk_add_hw_provider(np
, of_clk_hw_simple_get
, hw
);
569 CLK_OF_DECLARE(nomadik_src_clk
,
570 "st,nomadik-src-clock", of_nomadik_src_clk_setup
);