xref: /linux/drivers/clk/at91/clk-slow.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /*
2  * drivers/clk/at91/clk-slow.c
3  *
4  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/clk-provider.h>
15 #include <linux/clkdev.h>
16 #include <linux/slab.h>
17 #include <linux/clk/at91_pmc.h>
18 #include <linux/delay.h>
19 #include <linux/of.h>
20 #include <linux/of_address.h>
21 #include <linux/of_irq.h>
22 #include <linux/io.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/sched.h>
26 #include <linux/wait.h>
27 
28 #include "pmc.h"
29 #include "sckc.h"
30 
31 #define SLOW_CLOCK_FREQ		32768
32 #define SLOWCK_SW_CYCLES	5
33 #define SLOWCK_SW_TIME_USEC	((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
34 				 SLOW_CLOCK_FREQ)
35 
36 #define	AT91_SCKC_CR			0x00
37 #define		AT91_SCKC_RCEN		(1 << 0)
38 #define		AT91_SCKC_OSC32EN	(1 << 1)
39 #define		AT91_SCKC_OSC32BYP	(1 << 2)
40 #define		AT91_SCKC_OSCSEL	(1 << 3)
41 
42 struct clk_slow_osc {
43 	struct clk_hw hw;
44 	void __iomem *sckcr;
45 	unsigned long startup_usec;
46 };
47 
48 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
49 
50 struct clk_slow_rc_osc {
51 	struct clk_hw hw;
52 	void __iomem *sckcr;
53 	unsigned long frequency;
54 	unsigned long accuracy;
55 	unsigned long startup_usec;
56 };
57 
58 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
59 
60 struct clk_sam9260_slow {
61 	struct clk_hw hw;
62 	struct at91_pmc *pmc;
63 };
64 
65 #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
66 
67 struct clk_sam9x5_slow {
68 	struct clk_hw hw;
69 	void __iomem *sckcr;
70 	u8 parent;
71 };
72 
73 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
74 
75 static struct clk *slow_clk;
76 
77 static int clk_slow_osc_prepare(struct clk_hw *hw)
78 {
79 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
80 	void __iomem *sckcr = osc->sckcr;
81 	u32 tmp = readl(sckcr);
82 
83 	if (tmp & AT91_SCKC_OSC32BYP)
84 		return 0;
85 
86 	writel(tmp | AT91_SCKC_OSC32EN, sckcr);
87 
88 	usleep_range(osc->startup_usec, osc->startup_usec + 1);
89 
90 	return 0;
91 }
92 
93 static void clk_slow_osc_unprepare(struct clk_hw *hw)
94 {
95 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
96 	void __iomem *sckcr = osc->sckcr;
97 	u32 tmp = readl(sckcr);
98 
99 	if (tmp & AT91_SCKC_OSC32BYP)
100 		return;
101 
102 	writel(tmp & ~AT91_SCKC_OSC32EN, sckcr);
103 }
104 
105 static int clk_slow_osc_is_prepared(struct clk_hw *hw)
106 {
107 	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
108 	void __iomem *sckcr = osc->sckcr;
109 	u32 tmp = readl(sckcr);
110 
111 	if (tmp & AT91_SCKC_OSC32BYP)
112 		return 1;
113 
114 	return !!(tmp & AT91_SCKC_OSC32EN);
115 }
116 
117 static const struct clk_ops slow_osc_ops = {
118 	.prepare = clk_slow_osc_prepare,
119 	.unprepare = clk_slow_osc_unprepare,
120 	.is_prepared = clk_slow_osc_is_prepared,
121 };
122 
123 static struct clk * __init
124 at91_clk_register_slow_osc(void __iomem *sckcr,
125 			   const char *name,
126 			   const char *parent_name,
127 			   unsigned long startup,
128 			   bool bypass)
129 {
130 	struct clk_slow_osc *osc;
131 	struct clk *clk = NULL;
132 	struct clk_init_data init;
133 
134 	if (!sckcr || !name || !parent_name)
135 		return ERR_PTR(-EINVAL);
136 
137 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
138 	if (!osc)
139 		return ERR_PTR(-ENOMEM);
140 
141 	init.name = name;
142 	init.ops = &slow_osc_ops;
143 	init.parent_names = &parent_name;
144 	init.num_parents = 1;
145 	init.flags = CLK_IGNORE_UNUSED;
146 
147 	osc->hw.init = &init;
148 	osc->sckcr = sckcr;
149 	osc->startup_usec = startup;
150 
151 	if (bypass)
152 		writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
153 		       sckcr);
154 
155 	clk = clk_register(NULL, &osc->hw);
156 	if (IS_ERR(clk))
157 		kfree(osc);
158 
159 	return clk;
160 }
161 
162 void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
163 					     void __iomem *sckcr)
164 {
165 	struct clk *clk;
166 	const char *parent_name;
167 	const char *name = np->name;
168 	u32 startup;
169 	bool bypass;
170 
171 	parent_name = of_clk_get_parent_name(np, 0);
172 	of_property_read_string(np, "clock-output-names", &name);
173 	of_property_read_u32(np, "atmel,startup-time-usec", &startup);
174 	bypass = of_property_read_bool(np, "atmel,osc-bypass");
175 
176 	clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
177 					 bypass);
178 	if (IS_ERR(clk))
179 		return;
180 
181 	of_clk_add_provider(np, of_clk_src_simple_get, clk);
182 }
183 
184 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
185 						 unsigned long parent_rate)
186 {
187 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
188 
189 	return osc->frequency;
190 }
191 
192 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
193 						     unsigned long parent_acc)
194 {
195 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
196 
197 	return osc->accuracy;
198 }
199 
200 static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
201 {
202 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
203 	void __iomem *sckcr = osc->sckcr;
204 
205 	writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
206 
207 	usleep_range(osc->startup_usec, osc->startup_usec + 1);
208 
209 	return 0;
210 }
211 
212 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
213 {
214 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
215 	void __iomem *sckcr = osc->sckcr;
216 
217 	writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr);
218 }
219 
220 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
221 {
222 	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
223 
224 	return !!(readl(osc->sckcr) & AT91_SCKC_RCEN);
225 }
226 
227 static const struct clk_ops slow_rc_osc_ops = {
228 	.prepare = clk_slow_rc_osc_prepare,
229 	.unprepare = clk_slow_rc_osc_unprepare,
230 	.is_prepared = clk_slow_rc_osc_is_prepared,
231 	.recalc_rate = clk_slow_rc_osc_recalc_rate,
232 	.recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
233 };
234 
235 static struct clk * __init
236 at91_clk_register_slow_rc_osc(void __iomem *sckcr,
237 			      const char *name,
238 			      unsigned long frequency,
239 			      unsigned long accuracy,
240 			      unsigned long startup)
241 {
242 	struct clk_slow_rc_osc *osc;
243 	struct clk *clk = NULL;
244 	struct clk_init_data init;
245 
246 	if (!sckcr || !name)
247 		return ERR_PTR(-EINVAL);
248 
249 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
250 	if (!osc)
251 		return ERR_PTR(-ENOMEM);
252 
253 	init.name = name;
254 	init.ops = &slow_rc_osc_ops;
255 	init.parent_names = NULL;
256 	init.num_parents = 0;
257 	init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
258 
259 	osc->hw.init = &init;
260 	osc->sckcr = sckcr;
261 	osc->frequency = frequency;
262 	osc->accuracy = accuracy;
263 	osc->startup_usec = startup;
264 
265 	clk = clk_register(NULL, &osc->hw);
266 	if (IS_ERR(clk))
267 		kfree(osc);
268 
269 	return clk;
270 }
271 
272 void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
273 						void __iomem *sckcr)
274 {
275 	struct clk *clk;
276 	u32 frequency = 0;
277 	u32 accuracy = 0;
278 	u32 startup = 0;
279 	const char *name = np->name;
280 
281 	of_property_read_string(np, "clock-output-names", &name);
282 	of_property_read_u32(np, "clock-frequency", &frequency);
283 	of_property_read_u32(np, "clock-accuracy", &accuracy);
284 	of_property_read_u32(np, "atmel,startup-time-usec", &startup);
285 
286 	clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
287 					    startup);
288 	if (IS_ERR(clk))
289 		return;
290 
291 	of_clk_add_provider(np, of_clk_src_simple_get, clk);
292 }
293 
294 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
295 {
296 	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
297 	void __iomem *sckcr = slowck->sckcr;
298 	u32 tmp;
299 
300 	if (index > 1)
301 		return -EINVAL;
302 
303 	tmp = readl(sckcr);
304 
305 	if ((!index && !(tmp & AT91_SCKC_OSCSEL)) ||
306 	    (index && (tmp & AT91_SCKC_OSCSEL)))
307 		return 0;
308 
309 	if (index)
310 		tmp |= AT91_SCKC_OSCSEL;
311 	else
312 		tmp &= ~AT91_SCKC_OSCSEL;
313 
314 	writel(tmp, sckcr);
315 
316 	usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
317 
318 	return 0;
319 }
320 
321 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
322 {
323 	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
324 
325 	return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL);
326 }
327 
328 static const struct clk_ops sam9x5_slow_ops = {
329 	.set_parent = clk_sam9x5_slow_set_parent,
330 	.get_parent = clk_sam9x5_slow_get_parent,
331 };
332 
333 static struct clk * __init
334 at91_clk_register_sam9x5_slow(void __iomem *sckcr,
335 			      const char *name,
336 			      const char **parent_names,
337 			      int num_parents)
338 {
339 	struct clk_sam9x5_slow *slowck;
340 	struct clk *clk = NULL;
341 	struct clk_init_data init;
342 
343 	if (!sckcr || !name || !parent_names || !num_parents)
344 		return ERR_PTR(-EINVAL);
345 
346 	slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
347 	if (!slowck)
348 		return ERR_PTR(-ENOMEM);
349 
350 	init.name = name;
351 	init.ops = &sam9x5_slow_ops;
352 	init.parent_names = parent_names;
353 	init.num_parents = num_parents;
354 	init.flags = 0;
355 
356 	slowck->hw.init = &init;
357 	slowck->sckcr = sckcr;
358 	slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
359 
360 	clk = clk_register(NULL, &slowck->hw);
361 	if (IS_ERR(clk))
362 		kfree(slowck);
363 	else
364 		slow_clk = clk;
365 
366 	return clk;
367 }
368 
369 void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
370 					 void __iomem *sckcr)
371 {
372 	struct clk *clk;
373 	const char *parent_names[2];
374 	int num_parents;
375 	const char *name = np->name;
376 
377 	num_parents = of_clk_get_parent_count(np);
378 	if (num_parents <= 0 || num_parents > 2)
379 		return;
380 
381 	of_clk_parent_fill(np, parent_names, num_parents);
382 
383 	of_property_read_string(np, "clock-output-names", &name);
384 
385 	clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
386 					    num_parents);
387 	if (IS_ERR(clk))
388 		return;
389 
390 	of_clk_add_provider(np, of_clk_src_simple_get, clk);
391 }
392 
393 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
394 {
395 	struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
396 
397 	return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL);
398 }
399 
400 static const struct clk_ops sam9260_slow_ops = {
401 	.get_parent = clk_sam9260_slow_get_parent,
402 };
403 
404 static struct clk * __init
405 at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
406 			       const char *name,
407 			       const char **parent_names,
408 			       int num_parents)
409 {
410 	struct clk_sam9260_slow *slowck;
411 	struct clk *clk = NULL;
412 	struct clk_init_data init;
413 
414 	if (!pmc || !name)
415 		return ERR_PTR(-EINVAL);
416 
417 	if (!parent_names || !num_parents)
418 		return ERR_PTR(-EINVAL);
419 
420 	slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
421 	if (!slowck)
422 		return ERR_PTR(-ENOMEM);
423 
424 	init.name = name;
425 	init.ops = &sam9260_slow_ops;
426 	init.parent_names = parent_names;
427 	init.num_parents = num_parents;
428 	init.flags = 0;
429 
430 	slowck->hw.init = &init;
431 	slowck->pmc = pmc;
432 
433 	clk = clk_register(NULL, &slowck->hw);
434 	if (IS_ERR(clk))
435 		kfree(slowck);
436 	else
437 		slow_clk = clk;
438 
439 	return clk;
440 }
441 
442 void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
443 					  struct at91_pmc *pmc)
444 {
445 	struct clk *clk;
446 	const char *parent_names[2];
447 	int num_parents;
448 	const char *name = np->name;
449 
450 	num_parents = of_clk_get_parent_count(np);
451 	if (num_parents != 2)
452 		return;
453 
454 	of_clk_parent_fill(np, parent_names, num_parents);
455 
456 	of_property_read_string(np, "clock-output-names", &name);
457 
458 	clk = at91_clk_register_sam9260_slow(pmc, name, parent_names,
459 					     num_parents);
460 	if (IS_ERR(clk))
461 		return;
462 
463 	of_clk_add_provider(np, of_clk_src_simple_get, clk);
464 }
465 
466 /*
467  * FIXME: All slow clk users are not properly claiming it (get + prepare +
468  * enable) before using it.
469  * If all users properly claiming this clock decide that they don't need it
470  * anymore (or are removed), it is disabled while faulty users are still
471  * requiring it, and the system hangs.
472  * Prevent this clock from being disabled until all users are properly
473  * requesting it.
474  * Once this is done we should remove this function and the slow_clk variable.
475  */
476 static int __init of_at91_clk_slow_retain(void)
477 {
478 	if (!slow_clk)
479 		return 0;
480 
481 	__clk_get(slow_clk);
482 	clk_prepare_enable(slow_clk);
483 
484 	return 0;
485 }
486 arch_initcall(of_at91_clk_slow_retain);
487