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 */
60static DEFINE_SPINLOCK(src_lock);
61/* Base address of the SRC */
62static void __iomem *src_base;
63
64static 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
79static struct notifier_block nomadik_clk_reboot_notifier = {
80	.notifier_call = nomadik_clk_reboot_handler,
81};
82
83static const struct of_device_id nomadik_src_match[] __initconst = {
84	{ .compatible = "stericsson,nomadik-src" },
85	{ /* sentinel */ }
86};
87
88static 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
136out_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 */
145struct 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 */
157struct 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
167static 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
187static 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
206static 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
221static 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
252static 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
259static struct clk_hw * __init
260pll_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
303static 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
316static 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
328static 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
337static unsigned long
338src_clk_recalc_rate(struct clk_hw *hw,
339		    unsigned long parent_rate)
340{
341	return parent_rate;
342}
343
344static 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
351static struct clk_hw * __init
352src_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
391static u32 src_pcksr0_boot;
392static u32 src_pcksr1_boot;
393
394static 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
461static 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
485DEFINE_SHOW_ATTRIBUTE(nomadik_src_clk_debugfs);
486
487static 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}
498device_initcall(nomadik_src_clk_init_debugfs);
499
500#endif
501
502static 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}
522CLK_OF_DECLARE(nomadik_pll_clk,
523	"st,nomadik-pll-clock", of_nomadik_pll_setup);
524
525static 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}
546CLK_OF_DECLARE(nomadik_hclk_clk,
547	"st,nomadik-hclk-clock", of_nomadik_hclk_setup);
548
549static 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}
569CLK_OF_DECLARE(nomadik_src_clk,
570	"st,nomadik-src-clock", of_nomadik_src_clk_setup);
571