xref: /openbmc/linux/drivers/clk/at91/clk-main.c (revision f97769fd)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/clkdev.h>
8 #include <linux/clk/at91_pmc.h>
9 #include <linux/delay.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/regmap.h>
12 
13 #include "pmc.h"
14 
15 #define SLOW_CLOCK_FREQ		32768
16 #define MAINF_DIV		16
17 #define MAINFRDY_TIMEOUT	(((MAINF_DIV + 1) * USEC_PER_SEC) / \
18 				 SLOW_CLOCK_FREQ)
19 #define MAINF_LOOP_MIN_WAIT	(USEC_PER_SEC / SLOW_CLOCK_FREQ)
20 #define MAINF_LOOP_MAX_WAIT	MAINFRDY_TIMEOUT
21 
22 #define MOR_KEY_MASK		(0xff << 16)
23 
24 #define clk_main_parent_select(s)	(((s) & \
25 					(AT91_PMC_MOSCEN | \
26 					AT91_PMC_OSCBYPASS)) ? 1 : 0)
27 
28 struct clk_main_osc {
29 	struct clk_hw hw;
30 	struct regmap *regmap;
31 };
32 
33 #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
34 
35 struct clk_main_rc_osc {
36 	struct clk_hw hw;
37 	struct regmap *regmap;
38 	unsigned long frequency;
39 	unsigned long accuracy;
40 };
41 
42 #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
43 
44 struct clk_rm9200_main {
45 	struct clk_hw hw;
46 	struct regmap *regmap;
47 };
48 
49 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
50 
51 struct clk_sam9x5_main {
52 	struct clk_hw hw;
53 	struct regmap *regmap;
54 	u8 parent;
55 };
56 
57 #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
58 
59 static inline bool clk_main_osc_ready(struct regmap *regmap)
60 {
61 	unsigned int status;
62 
63 	regmap_read(regmap, AT91_PMC_SR, &status);
64 
65 	return status & AT91_PMC_MOSCS;
66 }
67 
68 static int clk_main_osc_prepare(struct clk_hw *hw)
69 {
70 	struct clk_main_osc *osc = to_clk_main_osc(hw);
71 	struct regmap *regmap = osc->regmap;
72 	u32 tmp;
73 
74 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
75 	tmp &= ~MOR_KEY_MASK;
76 
77 	if (tmp & AT91_PMC_OSCBYPASS)
78 		return 0;
79 
80 	if (!(tmp & AT91_PMC_MOSCEN)) {
81 		tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
82 		regmap_write(regmap, AT91_CKGR_MOR, tmp);
83 	}
84 
85 	while (!clk_main_osc_ready(regmap))
86 		cpu_relax();
87 
88 	return 0;
89 }
90 
91 static void clk_main_osc_unprepare(struct clk_hw *hw)
92 {
93 	struct clk_main_osc *osc = to_clk_main_osc(hw);
94 	struct regmap *regmap = osc->regmap;
95 	u32 tmp;
96 
97 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
98 	if (tmp & AT91_PMC_OSCBYPASS)
99 		return;
100 
101 	if (!(tmp & AT91_PMC_MOSCEN))
102 		return;
103 
104 	tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
105 	regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
106 }
107 
108 static int clk_main_osc_is_prepared(struct clk_hw *hw)
109 {
110 	struct clk_main_osc *osc = to_clk_main_osc(hw);
111 	struct regmap *regmap = osc->regmap;
112 	u32 tmp, status;
113 
114 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
115 	if (tmp & AT91_PMC_OSCBYPASS)
116 		return 1;
117 
118 	regmap_read(regmap, AT91_PMC_SR, &status);
119 
120 	return (status & AT91_PMC_MOSCS) && clk_main_parent_select(tmp);
121 }
122 
123 static const struct clk_ops main_osc_ops = {
124 	.prepare = clk_main_osc_prepare,
125 	.unprepare = clk_main_osc_unprepare,
126 	.is_prepared = clk_main_osc_is_prepared,
127 };
128 
129 struct clk_hw * __init
130 at91_clk_register_main_osc(struct regmap *regmap,
131 			   const char *name,
132 			   const char *parent_name,
133 			   bool bypass)
134 {
135 	struct clk_main_osc *osc;
136 	struct clk_init_data init;
137 	struct clk_hw *hw;
138 	int ret;
139 
140 	if (!name || !parent_name)
141 		return ERR_PTR(-EINVAL);
142 
143 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
144 	if (!osc)
145 		return ERR_PTR(-ENOMEM);
146 
147 	init.name = name;
148 	init.ops = &main_osc_ops;
149 	init.parent_names = &parent_name;
150 	init.num_parents = 1;
151 	init.flags = CLK_IGNORE_UNUSED;
152 
153 	osc->hw.init = &init;
154 	osc->regmap = regmap;
155 
156 	if (bypass)
157 		regmap_update_bits(regmap,
158 				   AT91_CKGR_MOR, MOR_KEY_MASK |
159 				   AT91_PMC_OSCBYPASS,
160 				   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
161 
162 	hw = &osc->hw;
163 	ret = clk_hw_register(NULL, &osc->hw);
164 	if (ret) {
165 		kfree(osc);
166 		hw = ERR_PTR(ret);
167 	}
168 
169 	return hw;
170 }
171 
172 static bool clk_main_rc_osc_ready(struct regmap *regmap)
173 {
174 	unsigned int status;
175 
176 	regmap_read(regmap, AT91_PMC_SR, &status);
177 
178 	return !!(status & AT91_PMC_MOSCRCS);
179 }
180 
181 static int clk_main_rc_osc_prepare(struct clk_hw *hw)
182 {
183 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
184 	struct regmap *regmap = osc->regmap;
185 	unsigned int mor;
186 
187 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
188 
189 	if (!(mor & AT91_PMC_MOSCRCEN))
190 		regmap_update_bits(regmap, AT91_CKGR_MOR,
191 				   MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
192 				   AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
193 
194 	while (!clk_main_rc_osc_ready(regmap))
195 		cpu_relax();
196 
197 	return 0;
198 }
199 
200 static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
201 {
202 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
203 	struct regmap *regmap = osc->regmap;
204 	unsigned int mor;
205 
206 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
207 
208 	if (!(mor & AT91_PMC_MOSCRCEN))
209 		return;
210 
211 	regmap_update_bits(regmap, AT91_CKGR_MOR,
212 			   MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
213 }
214 
215 static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
216 {
217 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
218 	struct regmap *regmap = osc->regmap;
219 	unsigned int mor, status;
220 
221 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
222 	regmap_read(regmap, AT91_PMC_SR, &status);
223 
224 	return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
225 }
226 
227 static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
228 						 unsigned long parent_rate)
229 {
230 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
231 
232 	return osc->frequency;
233 }
234 
235 static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
236 						     unsigned long parent_acc)
237 {
238 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
239 
240 	return osc->accuracy;
241 }
242 
243 static const struct clk_ops main_rc_osc_ops = {
244 	.prepare = clk_main_rc_osc_prepare,
245 	.unprepare = clk_main_rc_osc_unprepare,
246 	.is_prepared = clk_main_rc_osc_is_prepared,
247 	.recalc_rate = clk_main_rc_osc_recalc_rate,
248 	.recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
249 };
250 
251 struct clk_hw * __init
252 at91_clk_register_main_rc_osc(struct regmap *regmap,
253 			      const char *name,
254 			      u32 frequency, u32 accuracy)
255 {
256 	struct clk_main_rc_osc *osc;
257 	struct clk_init_data init;
258 	struct clk_hw *hw;
259 	int ret;
260 
261 	if (!name || !frequency)
262 		return ERR_PTR(-EINVAL);
263 
264 	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
265 	if (!osc)
266 		return ERR_PTR(-ENOMEM);
267 
268 	init.name = name;
269 	init.ops = &main_rc_osc_ops;
270 	init.parent_names = NULL;
271 	init.num_parents = 0;
272 	init.flags = CLK_IGNORE_UNUSED;
273 
274 	osc->hw.init = &init;
275 	osc->regmap = regmap;
276 	osc->frequency = frequency;
277 	osc->accuracy = accuracy;
278 
279 	hw = &osc->hw;
280 	ret = clk_hw_register(NULL, hw);
281 	if (ret) {
282 		kfree(osc);
283 		hw = ERR_PTR(ret);
284 	}
285 
286 	return hw;
287 }
288 
289 static int clk_main_probe_frequency(struct regmap *regmap)
290 {
291 	unsigned long prep_time, timeout;
292 	unsigned int mcfr;
293 
294 	timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
295 	do {
296 		prep_time = jiffies;
297 		regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
298 		if (mcfr & AT91_PMC_MAINRDY)
299 			return 0;
300 		if (system_state < SYSTEM_RUNNING)
301 			udelay(MAINF_LOOP_MIN_WAIT);
302 		else
303 			usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
304 	} while (time_before(prep_time, timeout));
305 
306 	return -ETIMEDOUT;
307 }
308 
309 static unsigned long clk_main_recalc_rate(struct regmap *regmap,
310 					  unsigned long parent_rate)
311 {
312 	unsigned int mcfr;
313 
314 	if (parent_rate)
315 		return parent_rate;
316 
317 	pr_warn("Main crystal frequency not set, using approximate value\n");
318 	regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
319 	if (!(mcfr & AT91_PMC_MAINRDY))
320 		return 0;
321 
322 	return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
323 }
324 
325 static int clk_rm9200_main_prepare(struct clk_hw *hw)
326 {
327 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
328 
329 	return clk_main_probe_frequency(clkmain->regmap);
330 }
331 
332 static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
333 {
334 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
335 	unsigned int status;
336 
337 	regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
338 
339 	return !!(status & AT91_PMC_MAINRDY);
340 }
341 
342 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
343 						 unsigned long parent_rate)
344 {
345 	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
346 
347 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
348 }
349 
350 static const struct clk_ops rm9200_main_ops = {
351 	.prepare = clk_rm9200_main_prepare,
352 	.is_prepared = clk_rm9200_main_is_prepared,
353 	.recalc_rate = clk_rm9200_main_recalc_rate,
354 };
355 
356 struct clk_hw * __init
357 at91_clk_register_rm9200_main(struct regmap *regmap,
358 			      const char *name,
359 			      const char *parent_name)
360 {
361 	struct clk_rm9200_main *clkmain;
362 	struct clk_init_data init;
363 	struct clk_hw *hw;
364 	int ret;
365 
366 	if (!name)
367 		return ERR_PTR(-EINVAL);
368 
369 	if (!parent_name)
370 		return ERR_PTR(-EINVAL);
371 
372 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
373 	if (!clkmain)
374 		return ERR_PTR(-ENOMEM);
375 
376 	init.name = name;
377 	init.ops = &rm9200_main_ops;
378 	init.parent_names = &parent_name;
379 	init.num_parents = 1;
380 	init.flags = 0;
381 
382 	clkmain->hw.init = &init;
383 	clkmain->regmap = regmap;
384 
385 	hw = &clkmain->hw;
386 	ret = clk_hw_register(NULL, &clkmain->hw);
387 	if (ret) {
388 		kfree(clkmain);
389 		hw = ERR_PTR(ret);
390 	}
391 
392 	return hw;
393 }
394 
395 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
396 {
397 	unsigned int status;
398 
399 	regmap_read(regmap, AT91_PMC_SR, &status);
400 
401 	return !!(status & AT91_PMC_MOSCSELS);
402 }
403 
404 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
405 {
406 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
407 	struct regmap *regmap = clkmain->regmap;
408 
409 	while (!clk_sam9x5_main_ready(regmap))
410 		cpu_relax();
411 
412 	return clk_main_probe_frequency(regmap);
413 }
414 
415 static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
416 {
417 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
418 
419 	return clk_sam9x5_main_ready(clkmain->regmap);
420 }
421 
422 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
423 						 unsigned long parent_rate)
424 {
425 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
426 
427 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
428 }
429 
430 static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
431 {
432 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
433 	struct regmap *regmap = clkmain->regmap;
434 	unsigned int tmp;
435 
436 	if (index > 1)
437 		return -EINVAL;
438 
439 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
440 	tmp &= ~MOR_KEY_MASK;
441 
442 	if (index && !(tmp & AT91_PMC_MOSCSEL))
443 		regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
444 	else if (!index && (tmp & AT91_PMC_MOSCSEL))
445 		regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
446 
447 	while (!clk_sam9x5_main_ready(regmap))
448 		cpu_relax();
449 
450 	return 0;
451 }
452 
453 static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
454 {
455 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
456 	unsigned int status;
457 
458 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
459 
460 	return clk_main_parent_select(status);
461 }
462 
463 static const struct clk_ops sam9x5_main_ops = {
464 	.prepare = clk_sam9x5_main_prepare,
465 	.is_prepared = clk_sam9x5_main_is_prepared,
466 	.recalc_rate = clk_sam9x5_main_recalc_rate,
467 	.set_parent = clk_sam9x5_main_set_parent,
468 	.get_parent = clk_sam9x5_main_get_parent,
469 };
470 
471 struct clk_hw * __init
472 at91_clk_register_sam9x5_main(struct regmap *regmap,
473 			      const char *name,
474 			      const char **parent_names,
475 			      int num_parents)
476 {
477 	struct clk_sam9x5_main *clkmain;
478 	struct clk_init_data init;
479 	unsigned int status;
480 	struct clk_hw *hw;
481 	int ret;
482 
483 	if (!name)
484 		return ERR_PTR(-EINVAL);
485 
486 	if (!parent_names || !num_parents)
487 		return ERR_PTR(-EINVAL);
488 
489 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
490 	if (!clkmain)
491 		return ERR_PTR(-ENOMEM);
492 
493 	init.name = name;
494 	init.ops = &sam9x5_main_ops;
495 	init.parent_names = parent_names;
496 	init.num_parents = num_parents;
497 	init.flags = CLK_SET_PARENT_GATE;
498 
499 	clkmain->hw.init = &init;
500 	clkmain->regmap = regmap;
501 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
502 	clkmain->parent = clk_main_parent_select(status);
503 
504 	hw = &clkmain->hw;
505 	ret = clk_hw_register(NULL, &clkmain->hw);
506 	if (ret) {
507 		kfree(clkmain);
508 		hw = ERR_PTR(ret);
509 	}
510 
511 	return hw;
512 }
513