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