2 * Nomadik clock implementation
3 * Copyright (C) 2013 ST-Ericsson AB
4 * License terms: GNU General Public License (GPL) version 2
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/clk.h>
12 #include <linux/clkdev.h>
13 #include <linux/err.h>
15 #include <linux/clk-provider.h>
17 #include <linux/of_address.h>
18 #include <linux/debugfs.h>
19 #include <linux/seq_file.h>
20 #include <linux/spinlock.h>
21 #include <linux/reboot.h>
24 * The Nomadik clock tree is described in the STN8815A12 DB V4.2
25 * reference manual for the chip, page 94 ff.
26 * Clock IDs are in the STn8815 Reference Manual table 3, page 27.
30 #define SRC_XTALCR 0x0CU
31 #define SRC_XTALCR_XTALTIMEN BIT(20)
32 #define SRC_XTALCR_SXTALDIS BIT(19)
33 #define SRC_XTALCR_MXTALSTAT BIT(2)
34 #define SRC_XTALCR_MXTALEN BIT(1)
35 #define SRC_XTALCR_MXTALOVER BIT(0)
36 #define SRC_PLLCR 0x10U
37 #define SRC_PLLCR_PLLTIMEN BIT(29)
38 #define SRC_PLLCR_PLL2EN BIT(28)
39 #define SRC_PLLCR_PLL1STAT BIT(2)
40 #define SRC_PLLCR_PLL1EN BIT(1)
41 #define SRC_PLLCR_PLL1OVER BIT(0)
42 #define SRC_PLLFR 0x14U
43 #define SRC_PCKEN0 0x24U
44 #define SRC_PCKDIS0 0x28U
45 #define SRC_PCKENSR0 0x2CU
46 #define SRC_PCKSR0 0x30U
47 #define SRC_PCKEN1 0x34U
48 #define SRC_PCKDIS1 0x38U
49 #define SRC_PCKENSR1 0x3CU
50 #define SRC_PCKSR1 0x40U
52 /* Lock protecting the SRC_CR register */
53 static DEFINE_SPINLOCK(src_lock
);
54 /* Base address of the SRC */
55 static void __iomem
*src_base
;
58 * struct clk_pll1 - Nomadik PLL1 clock
59 * @hw: corresponding clock hardware entry
60 * @id: PLL instance: 1 or 2
68 * struct clk_src - Nomadik src clock
69 * @hw: corresponding clock hardware entry
71 * @group1: true if the clock is in group1, else it is in group0
72 * @clkbit: bit 0...31 corresponding to the clock in each clock register
81 #define to_pll(_hw) container_of(_hw, struct clk_pll, hw)
82 #define to_src(_hw) container_of(_hw, struct clk_src, hw)
84 static int pll_clk_enable(struct clk_hw
*hw
)
86 struct clk_pll
*pll
= to_pll(hw
);
90 val
= readl(src_base
+ SRC_PLLCR
);
92 if (val
& SRC_PLLCR_PLL1OVER
) {
93 val
|= SRC_PLLCR_PLL1EN
;
94 writel(val
, src_base
+ SRC_PLLCR
);
96 } else if (pll
->id
== 2) {
97 val
|= SRC_PLLCR_PLL2EN
;
98 writel(val
, src_base
+ SRC_PLLCR
);
100 spin_unlock(&src_lock
);
104 static void pll_clk_disable(struct clk_hw
*hw
)
106 struct clk_pll
*pll
= to_pll(hw
);
109 spin_lock(&src_lock
);
110 val
= readl(src_base
+ SRC_PLLCR
);
112 if (val
& SRC_PLLCR_PLL1OVER
) {
113 val
&= ~SRC_PLLCR_PLL1EN
;
114 writel(val
, src_base
+ SRC_PLLCR
);
116 } else if (pll
->id
== 2) {
117 val
&= ~SRC_PLLCR_PLL2EN
;
118 writel(val
, src_base
+ SRC_PLLCR
);
120 spin_unlock(&src_lock
);
123 static int pll_clk_is_enabled(struct clk_hw
*hw
)
125 struct clk_pll
*pll
= to_pll(hw
);
128 val
= readl(src_base
+ SRC_PLLCR
);
130 if (val
& SRC_PLLCR_PLL1OVER
)
131 return !!(val
& SRC_PLLCR_PLL1EN
);
132 } else if (pll
->id
== 2) {
133 return !!(val
& SRC_PLLCR_PLL2EN
);
138 static unsigned long pll_clk_recalc_rate(struct clk_hw
*hw
,
139 unsigned long parent_rate
)
141 struct clk_pll
*pll
= to_pll(hw
);
144 val
= readl(src_base
+ SRC_PLLFR
);
150 mul
= (val
>> 8) & 0x3FU
;
153 return (parent_rate
* mul
) >> div
;
159 mul
= (val
>> 24) & 0x3FU
;
161 return (parent_rate
* mul
);
169 static const struct clk_ops pll_clk_ops
= {
170 .enable
= pll_clk_enable
,
171 .disable
= pll_clk_disable
,
172 .is_enabled
= pll_clk_is_enabled
,
173 .recalc_rate
= pll_clk_recalc_rate
,
176 static struct clk
* __init
177 pll_clk_register(struct device
*dev
, const char *name
,
178 const char *parent_name
, u32 id
)
182 struct clk_init_data init
;
184 if (id
!= 1 && id
!= 2) {
185 pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__
);
186 return ERR_PTR(-EINVAL
);
189 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
191 pr_err("%s: could not allocate PLL clk\n", __func__
);
192 return ERR_PTR(-ENOMEM
);
196 init
.ops
= &pll_clk_ops
;
197 init
.parent_names
= (parent_name
? &parent_name
: NULL
);
198 init
.num_parents
= (parent_name
? 1 : 0);
199 pll
->hw
.init
= &init
;
202 pr_debug("register PLL1 clock \"%s\"\n", name
);
204 clk
= clk_register(dev
, &pll
->hw
);
212 * The Nomadik SRC clocks are gated, but not in the sense that
213 * you read-modify-write a register. Instead there are separate
214 * clock enable and clock disable registers. Writing a '1' bit in
215 * the enable register for a certain clock ungates that clock without
216 * affecting the other clocks. The disable register works the opposite
220 static int src_clk_enable(struct clk_hw
*hw
)
222 struct clk_src
*sclk
= to_src(hw
);
223 u32 enreg
= sclk
->group1
? SRC_PCKEN1
: SRC_PCKEN0
;
224 u32 sreg
= sclk
->group1
? SRC_PCKSR1
: SRC_PCKSR0
;
226 writel(sclk
->clkbit
, src_base
+ enreg
);
227 /* spin until enabled */
228 while (!(readl(src_base
+ sreg
) & sclk
->clkbit
))
233 static void src_clk_disable(struct clk_hw
*hw
)
235 struct clk_src
*sclk
= to_src(hw
);
236 u32 disreg
= sclk
->group1
? SRC_PCKDIS1
: SRC_PCKDIS0
;
237 u32 sreg
= sclk
->group1
? SRC_PCKSR1
: SRC_PCKSR0
;
239 writel(sclk
->clkbit
, src_base
+ disreg
);
240 /* spin until disabled */
241 while (readl(src_base
+ sreg
) & sclk
->clkbit
)
245 static int src_clk_is_enabled(struct clk_hw
*hw
)
247 struct clk_src
*sclk
= to_src(hw
);
248 u32 sreg
= sclk
->group1
? SRC_PCKSR1
: SRC_PCKSR0
;
249 u32 val
= readl(src_base
+ sreg
);
251 return !!(val
& sclk
->clkbit
);
255 src_clk_recalc_rate(struct clk_hw
*hw
,
256 unsigned long parent_rate
)
261 static const struct clk_ops src_clk_ops
= {
262 .enable
= src_clk_enable
,
263 .disable
= src_clk_disable
,
264 .is_enabled
= src_clk_is_enabled
,
265 .recalc_rate
= src_clk_recalc_rate
,
268 static struct clk
* __init
269 src_clk_register(struct device
*dev
, const char *name
,
270 const char *parent_name
, u8 id
)
273 struct clk_src
*sclk
;
274 struct clk_init_data init
;
276 sclk
= kzalloc(sizeof(*sclk
), GFP_KERNEL
);
278 pr_err("could not allocate SRC clock %s\n",
280 return ERR_PTR(-ENOMEM
);
283 init
.ops
= &src_clk_ops
;
284 /* Do not force-disable the static SDRAM controller */
286 init
.flags
= CLK_IGNORE_UNUSED
;
289 init
.parent_names
= (parent_name
? &parent_name
: NULL
);
290 init
.num_parents
= (parent_name
? 1 : 0);
291 sclk
->hw
.init
= &init
;
293 sclk
->group1
= (id
> 31);
294 sclk
->clkbit
= BIT(id
& 0x1f);
296 pr_debug("register clock \"%s\" ID: %d group: %d bits: %08x\n",
297 name
, id
, sclk
->group1
, sclk
->clkbit
);
299 clk
= clk_register(dev
, &sclk
->hw
);
306 #ifdef CONFIG_DEBUG_FS
308 static u32 src_pcksr0_boot
;
309 static u32 src_pcksr1_boot
;
311 static const char * const src_clk_names
[] = {
378 static int nomadik_src_clk_show(struct seq_file
*s
, void *what
)
381 u32 src_pcksr0
= readl(src_base
+ SRC_PCKSR0
);
382 u32 src_pcksr1
= readl(src_base
+ SRC_PCKSR1
);
383 u32 src_pckensr0
= readl(src_base
+ SRC_PCKENSR0
);
384 u32 src_pckensr1
= readl(src_base
+ SRC_PCKENSR1
);
386 seq_printf(s
, "Clock: Boot: Now: Request: ASKED:\n");
387 for (i
= 0; i
< ARRAY_SIZE(src_clk_names
); i
++) {
388 u32 pcksrb
= (i
< 0x20) ? src_pcksr0_boot
: src_pcksr1_boot
;
389 u32 pcksr
= (i
< 0x20) ? src_pcksr0
: src_pcksr1
;
390 u32 pckreq
= (i
< 0x20) ? src_pckensr0
: src_pckensr1
;
391 u32 mask
= BIT(i
& 0x1f);
393 seq_printf(s
, "%s %s %s %s\n",
395 (pcksrb
& mask
) ? "on " : "off",
396 (pcksr
& mask
) ? "on " : "off",
397 (pckreq
& mask
) ? "on " : "off");
402 static int nomadik_src_clk_open(struct inode
*inode
, struct file
*file
)
404 return single_open(file
, nomadik_src_clk_show
, NULL
);
407 static const struct file_operations nomadik_src_clk_debugfs_ops
= {
408 .open
= nomadik_src_clk_open
,
411 .release
= single_release
,
414 static int __init
nomadik_src_clk_init_debugfs(void)
416 src_pcksr0_boot
= readl(src_base
+ SRC_PCKSR0
);
417 src_pcksr1_boot
= readl(src_base
+ SRC_PCKSR1
);
418 debugfs_create_file("nomadik-src-clk", S_IFREG
| S_IRUGO
,
419 NULL
, NULL
, &nomadik_src_clk_debugfs_ops
);
423 module_init(nomadik_src_clk_init_debugfs
);
427 static void __init
of_nomadik_pll_setup(struct device_node
*np
)
429 struct clk
*clk
= ERR_PTR(-EINVAL
);
430 const char *clk_name
= np
->name
;
431 const char *parent_name
;
434 if (of_property_read_u32(np
, "pll-id", &pll_id
)) {
435 pr_err("%s: PLL \"%s\" missing pll-id property\n",
439 parent_name
= of_clk_get_parent_name(np
, 0);
440 clk
= pll_clk_register(NULL
, clk_name
, parent_name
, pll_id
);
442 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
445 static void __init
of_nomadik_hclk_setup(struct device_node
*np
)
447 struct clk
*clk
= ERR_PTR(-EINVAL
);
448 const char *clk_name
= np
->name
;
449 const char *parent_name
;
451 parent_name
= of_clk_get_parent_name(np
, 0);
453 * The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
455 clk
= clk_register_divider(NULL
, clk_name
, parent_name
,
456 0, src_base
+ SRC_CR
,
458 CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
461 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
464 static void __init
of_nomadik_src_clk_setup(struct device_node
*np
)
466 struct clk
*clk
= ERR_PTR(-EINVAL
);
467 const char *clk_name
= np
->name
;
468 const char *parent_name
;
471 if (of_property_read_u32(np
, "clock-id", &clk_id
)) {
472 pr_err("%s: SRC clock \"%s\" missing clock-id property\n",
476 parent_name
= of_clk_get_parent_name(np
, 0);
477 clk
= src_clk_register(NULL
, clk_name
, parent_name
, clk_id
);
479 of_clk_add_provider(np
, of_clk_src_simple_get
, clk
);
482 static const __initconst
struct of_device_id nomadik_src_match
[] = {
483 { .compatible
= "stericsson,nomadik-src" },
487 static const __initconst
struct of_device_id nomadik_src_clk_match
[] = {
489 .compatible
= "fixed-clock",
490 .data
= of_fixed_clk_setup
,
493 .compatible
= "fixed-factor-clock",
494 .data
= of_fixed_factor_clk_setup
,
497 .compatible
= "st,nomadik-pll-clock",
498 .data
= of_nomadik_pll_setup
,
501 .compatible
= "st,nomadik-hclk-clock",
502 .data
= of_nomadik_hclk_setup
,
505 .compatible
= "st,nomadik-src-clock",
506 .data
= of_nomadik_src_clk_setup
,
511 static int nomadik_clk_reboot_handler(struct notifier_block
*this,
517 /* The main chrystal need to be enabled for reboot to work */
518 val
= readl(src_base
+ SRC_XTALCR
);
519 val
&= ~SRC_XTALCR_MXTALOVER
;
520 val
|= SRC_XTALCR_MXTALEN
;
521 pr_crit("force-enabling MXTALO\n");
522 writel(val
, src_base
+ SRC_XTALCR
);
526 static struct notifier_block nomadik_clk_reboot_notifier
= {
527 .notifier_call
= nomadik_clk_reboot_handler
,
530 void __init
nomadik_clk_init(void)
532 struct device_node
*np
;
535 np
= of_find_matching_node(NULL
, nomadik_src_match
);
537 pr_crit("no matching node for SRC, aborting clock init\n");
540 src_base
= of_iomap(np
, 0);
542 pr_err("%s: must have src parent node with REGS (%s)\n",
546 val
= readl(src_base
+ SRC_XTALCR
);
547 pr_info("SXTALO is %s\n",
548 (val
& SRC_XTALCR_SXTALDIS
) ? "disabled" : "enabled");
549 pr_info("MXTAL is %s\n",
550 (val
& SRC_XTALCR_MXTALSTAT
) ? "enabled" : "disabled");
551 if (of_property_read_bool(np
, "disable-sxtalo")) {
552 /* The machine uses an external oscillator circuit */
553 val
|= SRC_XTALCR_SXTALDIS
;
554 pr_info("disabling SXTALO\n");
556 if (of_property_read_bool(np
, "disable-mxtalo")) {
557 /* Disable this too: also run by external oscillator */
558 val
|= SRC_XTALCR_MXTALOVER
;
559 val
&= ~SRC_XTALCR_MXTALEN
;
560 pr_info("disabling MXTALO\n");
562 writel(val
, src_base
+ SRC_XTALCR
);
563 register_reboot_notifier(&nomadik_clk_reboot_notifier
);
565 of_clk_init(nomadik_src_clk_match
);