1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Compatible code for non CCF AT91 platforms.
4  *
5  * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
8  */
9 #include <common.h>
10 #include <clk-uclass.h>
11 #include <dm.h>
12 #include <asm/global_data.h>
13 #include <dm/device_compat.h>
14 #include <dm/lists.h>
15 #include <dm/util.h>
16 #include <mach/at91_pmc.h>
17 #include <mach/at91_sfr.h>
18 #include <regmap.h>
19 #include <syscon.h>
20 
21 #include "pmc.h"
22 
23 DECLARE_GLOBAL_DATA_PTR;
24 
25 struct pmc_plat {
26 	struct at91_pmc *reg_base;
27 	struct regmap *regmap_sfr;
28 };
29 
30 static const struct udevice_id at91_pmc_match[] = {
31 	{ .compatible = "atmel,at91rm9200-pmc" },
32 	{ .compatible = "atmel,at91sam9260-pmc" },
33 	{ .compatible = "atmel,at91sam9g45-pmc" },
34 	{ .compatible = "atmel,at91sam9n12-pmc" },
35 	{ .compatible = "atmel,at91sam9x5-pmc" },
36 	{ .compatible = "atmel,sama5d3-pmc" },
37 	{ .compatible = "atmel,sama5d2-pmc" },
38 	{}
39 };
40 
41 U_BOOT_DRIVER(at91_pmc) = {
42 	.name = "at91-pmc",
43 	.id = UCLASS_SIMPLE_BUS,
44 	.of_match = at91_pmc_match,
45 };
46 
at91_pmc_core_probe(struct udevice * dev)47 static int at91_pmc_core_probe(struct udevice *dev)
48 {
49 	struct pmc_plat *plat = dev_get_plat(dev);
50 
51 	dev = dev_get_parent(dev);
52 
53 	plat->reg_base = dev_read_addr_ptr(dev);
54 
55 	return 0;
56 }
57 
58 /**
59  * at91_clk_sub_device_bind() - for the at91 clock driver
60  * Recursively bind its children as clk devices.
61  *
62  * @return: 0 on success, or negative error code on failure
63  */
at91_clk_sub_device_bind(struct udevice * dev,const char * drv_name)64 int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
65 {
66 	const void *fdt = gd->fdt_blob;
67 	int offset = dev_of_offset(dev);
68 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
69 	const char *name;
70 	int ret;
71 
72 	for (offset = fdt_first_subnode(fdt, offset);
73 	     offset > 0;
74 	     offset = fdt_next_subnode(fdt, offset)) {
75 		if (pre_reloc_only &&
76 		    !ofnode_pre_reloc(offset_to_ofnode(offset)))
77 			continue;
78 		/*
79 		 * If this node has "compatible" property, this is not
80 		 * a clock sub-node, but a normal device. skip.
81 		 */
82 		fdt_get_property(fdt, offset, "compatible", &ret);
83 		if (ret >= 0)
84 			continue;
85 
86 		if (ret != -FDT_ERR_NOTFOUND)
87 			return ret;
88 
89 		name = fdt_get_name(fdt, offset, NULL);
90 		if (!name)
91 			return -EINVAL;
92 		ret = device_bind_driver_to_node(dev, drv_name, name,
93 					offset_to_ofnode(offset), NULL);
94 		if (ret)
95 			return ret;
96 	}
97 
98 	return 0;
99 }
100 
at91_clk_of_xlate(struct clk * clk,struct ofnode_phandle_args * args)101 int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
102 {
103 	int periph;
104 
105 	if (args->args_count) {
106 		debug("Invalid args_count: %d\n", args->args_count);
107 		return -EINVAL;
108 	}
109 
110 	periph = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(clk->dev), "reg",
111 				 -1);
112 	if (periph < 0)
113 		return -EINVAL;
114 
115 	clk->id = periph;
116 
117 	return 0;
118 }
119 
at91_clk_probe(struct udevice * dev)120 int at91_clk_probe(struct udevice *dev)
121 {
122 	struct udevice *dev_periph_container, *dev_pmc;
123 	struct pmc_plat *plat = dev_get_plat(dev);
124 
125 	dev_periph_container = dev_get_parent(dev);
126 	dev_pmc = dev_get_parent(dev_periph_container);
127 
128 	plat->reg_base = dev_read_addr_ptr(dev_pmc);
129 
130 	return 0;
131 }
132 
133 /* SCKC specific code. */
134 static const struct udevice_id at91_sckc_match[] = {
135 	{ .compatible = "atmel,at91sam9x5-sckc" },
136 	{}
137 };
138 
139 U_BOOT_DRIVER(at91_sckc) = {
140 	.name = "at91-sckc",
141 	.id = UCLASS_SIMPLE_BUS,
142 	.of_match = at91_sckc_match,
143 };
144 
145 /* Slow clock specific code. */
at91_slow_clk_enable(struct clk * clk)146 static int at91_slow_clk_enable(struct clk *clk)
147 {
148 	return 0;
149 }
150 
at91_slow_clk_get_rate(struct clk * clk)151 static ulong at91_slow_clk_get_rate(struct clk *clk)
152 {
153 	return CONFIG_SYS_AT91_SLOW_CLOCK;
154 }
155 
156 static struct clk_ops at91_slow_clk_ops = {
157 	.enable = at91_slow_clk_enable,
158 	.get_rate = at91_slow_clk_get_rate,
159 };
160 
161 static const struct udevice_id at91_slow_clk_match[] = {
162 	{ .compatible = "atmel,at91sam9x5-clk-slow" },
163 	{}
164 };
165 
166 U_BOOT_DRIVER(at91_slow_clk) = {
167 	.name = "at91-slow-clk",
168 	.id = UCLASS_CLK,
169 	.of_match = at91_slow_clk_match,
170 	.ops = &at91_slow_clk_ops,
171 };
172 
173 /* Master clock specific code. */
at91_master_clk_get_rate(struct clk * clk)174 static ulong at91_master_clk_get_rate(struct clk *clk)
175 {
176 	return gd->arch.mck_rate_hz;
177 }
178 
179 static struct clk_ops at91_master_clk_ops = {
180 	.get_rate = at91_master_clk_get_rate,
181 };
182 
183 static const struct udevice_id at91_master_clk_match[] = {
184 	{ .compatible = "atmel,at91rm9200-clk-master" },
185 	{ .compatible = "atmel,at91sam9x5-clk-master" },
186 	{}
187 };
188 
189 U_BOOT_DRIVER(at91_master_clk) = {
190 	.name = "at91-master-clk",
191 	.id = UCLASS_CLK,
192 	.of_match = at91_master_clk_match,
193 	.ops = &at91_master_clk_ops,
194 };
195 
196 /* Main osc clock specific code. */
main_osc_clk_enable(struct clk * clk)197 static int main_osc_clk_enable(struct clk *clk)
198 {
199 	struct pmc_plat *plat = dev_get_plat(clk->dev);
200 	struct at91_pmc *pmc = plat->reg_base;
201 
202 	if (readl(&pmc->sr) & AT91_PMC_MOSCSELS)
203 		return 0;
204 
205 	return -EINVAL;
206 }
207 
main_osc_clk_get_rate(struct clk * clk)208 static ulong main_osc_clk_get_rate(struct clk *clk)
209 {
210 	return gd->arch.main_clk_rate_hz;
211 }
212 
213 static struct clk_ops main_osc_clk_ops = {
214 	.enable = main_osc_clk_enable,
215 	.get_rate = main_osc_clk_get_rate,
216 };
217 
main_osc_clk_probe(struct udevice * dev)218 static int main_osc_clk_probe(struct udevice *dev)
219 {
220 	return at91_pmc_core_probe(dev);
221 }
222 
223 static const struct udevice_id main_osc_clk_match[] = {
224 	{ .compatible = "atmel,at91sam9x5-clk-main" },
225 	{}
226 };
227 
228 U_BOOT_DRIVER(at91sam9x5_main_osc_clk) = {
229 	.name = "at91sam9x5-main-osc-clk",
230 	.id = UCLASS_CLK,
231 	.of_match = main_osc_clk_match,
232 	.probe = main_osc_clk_probe,
233 	.plat_auto	= sizeof(struct pmc_plat),
234 	.ops = &main_osc_clk_ops,
235 };
236 
237 /* PLLA clock specific code. */
plla_clk_enable(struct clk * clk)238 static int plla_clk_enable(struct clk *clk)
239 {
240 	struct pmc_plat *plat = dev_get_plat(clk->dev);
241 	struct at91_pmc *pmc = plat->reg_base;
242 
243 	if (readl(&pmc->sr) & AT91_PMC_LOCKA)
244 		return 0;
245 
246 	return -EINVAL;
247 }
248 
plla_clk_get_rate(struct clk * clk)249 static ulong plla_clk_get_rate(struct clk *clk)
250 {
251 	return gd->arch.plla_rate_hz;
252 }
253 
254 static struct clk_ops plla_clk_ops = {
255 	.enable = plla_clk_enable,
256 	.get_rate = plla_clk_get_rate,
257 };
258 
plla_clk_probe(struct udevice * dev)259 static int plla_clk_probe(struct udevice *dev)
260 {
261 	return at91_pmc_core_probe(dev);
262 }
263 
264 static const struct udevice_id plla_clk_match[] = {
265 	{ .compatible = "atmel,sama5d3-clk-pll" },
266 	{}
267 };
268 
269 U_BOOT_DRIVER(at91_plla_clk) = {
270 	.name = "at91-plla-clk",
271 	.id = UCLASS_CLK,
272 	.of_match = plla_clk_match,
273 	.probe = plla_clk_probe,
274 	.plat_auto	= sizeof(struct pmc_plat),
275 	.ops = &plla_clk_ops,
276 };
277 
278 /* PLLA DIV clock specific code. */
at91_plladiv_clk_enable(struct clk * clk)279 static int at91_plladiv_clk_enable(struct clk *clk)
280 {
281 	return 0;
282 }
283 
at91_plladiv_clk_get_rate(struct clk * clk)284 static ulong at91_plladiv_clk_get_rate(struct clk *clk)
285 {
286 	struct pmc_plat *plat = dev_get_plat(clk->dev);
287 	struct at91_pmc *pmc = plat->reg_base;
288 	struct clk source;
289 	ulong clk_rate;
290 	int ret;
291 
292 	ret = clk_get_by_index(clk->dev, 0, &source);
293 	if (ret)
294 		return -EINVAL;
295 
296 	clk_rate = clk_get_rate(&source);
297 	if (readl(&pmc->mckr) & AT91_PMC_MCKR_PLLADIV_2)
298 		clk_rate /= 2;
299 
300 	return clk_rate;
301 }
302 
at91_plladiv_clk_set_rate(struct clk * clk,ulong rate)303 static ulong at91_plladiv_clk_set_rate(struct clk *clk, ulong rate)
304 {
305 	struct pmc_plat *plat = dev_get_plat(clk->dev);
306 	struct at91_pmc *pmc = plat->reg_base;
307 	struct clk source;
308 	ulong parent_rate;
309 	int ret;
310 
311 	ret = clk_get_by_index(clk->dev, 0, &source);
312 	if (ret)
313 		return -EINVAL;
314 
315 	parent_rate = clk_get_rate(&source);
316 	if ((parent_rate != rate) && ((parent_rate) / 2 != rate))
317 		return -EINVAL;
318 
319 	if (parent_rate != rate) {
320 		writel((readl(&pmc->mckr) | AT91_PMC_MCKR_PLLADIV_2),
321 		       &pmc->mckr);
322 	}
323 
324 	return 0;
325 }
326 
327 static struct clk_ops at91_plladiv_clk_ops = {
328 	.enable = at91_plladiv_clk_enable,
329 	.get_rate = at91_plladiv_clk_get_rate,
330 	.set_rate = at91_plladiv_clk_set_rate,
331 };
332 
at91_plladiv_clk_probe(struct udevice * dev)333 static int at91_plladiv_clk_probe(struct udevice *dev)
334 {
335 	return at91_pmc_core_probe(dev);
336 }
337 
338 static const struct udevice_id at91_plladiv_clk_match[] = {
339 	{ .compatible = "atmel,at91sam9x5-clk-plldiv" },
340 	{}
341 };
342 
343 U_BOOT_DRIVER(at91_plladiv_clk) = {
344 	.name = "at91-plladiv-clk",
345 	.id = UCLASS_CLK,
346 	.of_match = at91_plladiv_clk_match,
347 	.probe = at91_plladiv_clk_probe,
348 	.plat_auto	= sizeof(struct pmc_plat),
349 	.ops = &at91_plladiv_clk_ops,
350 };
351 
352 /* System clock specific code. */
353 #define SYSTEM_MAX_ID		31
354 
355 /**
356  * at91_system_clk_bind() - for the system clock driver
357  * Recursively bind its children as clk devices.
358  *
359  * @return: 0 on success, or negative error code on failure
360  */
at91_system_clk_bind(struct udevice * dev)361 static int at91_system_clk_bind(struct udevice *dev)
362 {
363 	return at91_clk_sub_device_bind(dev, "system-clk");
364 }
365 
366 static const struct udevice_id at91_system_clk_match[] = {
367 	{ .compatible = "atmel,at91rm9200-clk-system" },
368 	{}
369 };
370 
371 U_BOOT_DRIVER(at91_system_clk) = {
372 	.name = "at91-system-clk",
373 	.id = UCLASS_MISC,
374 	.of_match = at91_system_clk_match,
375 	.bind = at91_system_clk_bind,
376 };
377 
is_pck(int id)378 static inline int is_pck(int id)
379 {
380 	return (id >= 8) && (id <= 15);
381 }
382 
system_clk_get_rate(struct clk * clk)383 static ulong system_clk_get_rate(struct clk *clk)
384 {
385 	struct clk clk_dev;
386 	int ret;
387 
388 	ret = clk_get_by_index(clk->dev, 0, &clk_dev);
389 	if (ret)
390 		return -EINVAL;
391 
392 	return clk_get_rate(&clk_dev);
393 }
394 
system_clk_set_rate(struct clk * clk,ulong rate)395 static ulong system_clk_set_rate(struct clk *clk, ulong rate)
396 {
397 	struct clk clk_dev;
398 	int ret;
399 
400 	ret = clk_get_by_index(clk->dev, 0, &clk_dev);
401 	if (ret)
402 		return -EINVAL;
403 
404 	return clk_set_rate(&clk_dev, rate);
405 }
406 
system_clk_enable(struct clk * clk)407 static int system_clk_enable(struct clk *clk)
408 {
409 	struct pmc_plat *plat = dev_get_plat(clk->dev);
410 	struct at91_pmc *pmc = plat->reg_base;
411 	u32 mask;
412 
413 	if (clk->id > SYSTEM_MAX_ID)
414 		return -EINVAL;
415 
416 	mask = BIT(clk->id);
417 
418 	writel(mask, &pmc->scer);
419 
420 	/**
421 	 * For the programmable clocks the Ready status in the PMC
422 	 * status register should be checked after enabling.
423 	 * For other clocks this is unnecessary.
424 	 */
425 	if (!is_pck(clk->id))
426 		return 0;
427 
428 	while (!(readl(&pmc->sr) & mask))
429 		;
430 
431 	return 0;
432 }
433 
434 static struct clk_ops system_clk_ops = {
435 	.of_xlate = at91_clk_of_xlate,
436 	.get_rate = system_clk_get_rate,
437 	.set_rate = system_clk_set_rate,
438 	.enable = system_clk_enable,
439 };
440 
441 U_BOOT_DRIVER(system_clk) = {
442 	.name = "system-clk",
443 	.id = UCLASS_CLK,
444 	.probe = at91_clk_probe,
445 	.plat_auto	= sizeof(struct pmc_plat),
446 	.ops = &system_clk_ops,
447 };
448 
449 /* Peripheral clock specific code. */
450 #define PERIPHERAL_ID_MIN	2
451 #define PERIPHERAL_ID_MAX	31
452 #define PERIPHERAL_MASK(id)	(1 << ((id) & PERIPHERAL_ID_MAX))
453 
454 enum periph_clk_type {
455 	CLK_PERIPH_AT91RM9200 = 0,
456 	CLK_PERIPH_AT91SAM9X5,
457 };
458 
459 /**
460  * sam9x5_periph_clk_bind() - for the periph clock driver
461  * Recursively bind its children as clk devices.
462  *
463  * @return: 0 on success, or negative error code on failure
464  */
sam9x5_periph_clk_bind(struct udevice * dev)465 static int sam9x5_periph_clk_bind(struct udevice *dev)
466 {
467 	return at91_clk_sub_device_bind(dev, "periph-clk");
468 }
469 
470 static const struct udevice_id sam9x5_periph_clk_match[] = {
471 	{
472 		.compatible = "atmel,at91rm9200-clk-peripheral",
473 		.data = CLK_PERIPH_AT91RM9200,
474 	},
475 	{
476 		.compatible = "atmel,at91sam9x5-clk-peripheral",
477 		.data = CLK_PERIPH_AT91SAM9X5,
478 	},
479 	{}
480 };
481 
482 U_BOOT_DRIVER(sam9x5_periph_clk) = {
483 	.name = "sam9x5-periph-clk",
484 	.id = UCLASS_MISC,
485 	.of_match = sam9x5_periph_clk_match,
486 	.bind = sam9x5_periph_clk_bind,
487 };
488 
periph_clk_enable(struct clk * clk)489 static int periph_clk_enable(struct clk *clk)
490 {
491 	struct pmc_plat *plat = dev_get_plat(clk->dev);
492 	struct at91_pmc *pmc = plat->reg_base;
493 	enum periph_clk_type clk_type;
494 	void *addr;
495 
496 	if (clk->id < PERIPHERAL_ID_MIN)
497 		return -1;
498 
499 	clk_type = dev_get_driver_data(dev_get_parent(clk->dev));
500 	if (clk_type == CLK_PERIPH_AT91RM9200) {
501 		addr = &pmc->pcer;
502 		if (clk->id > PERIPHERAL_ID_MAX)
503 			addr = &pmc->pcer1;
504 
505 		setbits_le32(addr, PERIPHERAL_MASK(clk->id));
506 	} else {
507 		writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
508 		setbits_le32(&pmc->pcr,
509 			     AT91_PMC_PCR_CMD_WRITE | AT91_PMC_PCR_EN);
510 	}
511 
512 	return 0;
513 }
514 
periph_get_rate(struct clk * clk)515 static ulong periph_get_rate(struct clk *clk)
516 {
517 	struct udevice *dev;
518 	struct clk clk_dev;
519 	ulong clk_rate;
520 	int ret;
521 
522 	dev = dev_get_parent(clk->dev);
523 
524 	ret = clk_get_by_index(dev, 0, &clk_dev);
525 	if (ret)
526 		return ret;
527 
528 	clk_rate = clk_get_rate(&clk_dev);
529 
530 	clk_free(&clk_dev);
531 
532 	return clk_rate;
533 }
534 
535 static struct clk_ops periph_clk_ops = {
536 	.of_xlate = at91_clk_of_xlate,
537 	.enable = periph_clk_enable,
538 	.get_rate = periph_get_rate,
539 };
540 
541 U_BOOT_DRIVER(clk_periph) = {
542 	.name	= "periph-clk",
543 	.id	= UCLASS_CLK,
544 	.plat_auto	= sizeof(struct pmc_plat),
545 	.probe = at91_clk_probe,
546 	.ops	= &periph_clk_ops,
547 };
548 
549 /* UTMI clock specific code. */
550 #ifdef CONFIG_AT91_UTMI
551 
552 /*
553  * The purpose of this clock is to generate a 480 MHz signal. A different
554  * rate can't be configured.
555  */
556 #define UTMI_RATE	480000000
557 
utmi_clk_enable(struct clk * clk)558 static int utmi_clk_enable(struct clk *clk)
559 {
560 	struct pmc_plat *plat = dev_get_plat(clk->dev);
561 	struct at91_pmc *pmc = plat->reg_base;
562 	struct clk clk_dev;
563 	ulong clk_rate;
564 	u32 utmi_ref_clk_freq;
565 	u32 tmp;
566 	int err;
567 	int timeout = 2000000;
568 
569 	if (readl(&pmc->sr) & AT91_PMC_LOCKU)
570 		return 0;
571 
572 	/*
573 	 * If mainck rate is different from 12 MHz, we have to configure the
574 	 * FREQ field of the SFR_UTMICKTRIM register to generate properly
575 	 * the utmi clock.
576 	 */
577 	err = clk_get_by_index(clk->dev, 0, &clk_dev);
578 	if (err)
579 		return -EINVAL;
580 
581 	clk_rate = clk_get_rate(&clk_dev);
582 	switch (clk_rate) {
583 	case 12000000:
584 		utmi_ref_clk_freq = 0;
585 		break;
586 	case 16000000:
587 		utmi_ref_clk_freq = 1;
588 		break;
589 	case 24000000:
590 		utmi_ref_clk_freq = 2;
591 		break;
592 	/*
593 	 * Not supported on SAMA5D2 but it's not an issue since MAINCK
594 	 * maximum value is 24 MHz.
595 	 */
596 	case 48000000:
597 		utmi_ref_clk_freq = 3;
598 		break;
599 	default:
600 		printf("UTMICK: unsupported mainck rate\n");
601 		return -EINVAL;
602 	}
603 
604 	if (plat->regmap_sfr) {
605 		err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp);
606 		if (err)
607 			return -EINVAL;
608 
609 		tmp &= ~AT91_UTMICKTRIM_FREQ;
610 		tmp |= utmi_ref_clk_freq;
611 		err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp);
612 		if (err)
613 			return -EINVAL;
614 	} else if (utmi_ref_clk_freq) {
615 		printf("UTMICK: sfr node required\n");
616 		return -EINVAL;
617 	}
618 
619 	tmp = readl(&pmc->uckr);
620 	tmp |= AT91_PMC_UPLLEN |
621 	       AT91_PMC_UPLLCOUNT |
622 	       AT91_PMC_BIASEN;
623 	writel(tmp, &pmc->uckr);
624 
625 	while ((--timeout) && !(readl(&pmc->sr) & AT91_PMC_LOCKU))
626 		;
627 	if (!timeout) {
628 		printf("UTMICK: timeout waiting for UPLL lock\n");
629 		return -ETIMEDOUT;
630 	}
631 
632 	return 0;
633 }
634 
utmi_clk_get_rate(struct clk * clk)635 static ulong utmi_clk_get_rate(struct clk *clk)
636 {
637 	/* UTMI clk rate is fixed. */
638 	return UTMI_RATE;
639 }
640 
641 static struct clk_ops utmi_clk_ops = {
642 	.enable = utmi_clk_enable,
643 	.get_rate = utmi_clk_get_rate,
644 };
645 
utmi_clk_of_to_plat(struct udevice * dev)646 static int utmi_clk_of_to_plat(struct udevice *dev)
647 {
648 	struct pmc_plat *plat = dev_get_plat(dev);
649 	struct udevice *syscon;
650 
651 	uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
652 				     "regmap-sfr", &syscon);
653 
654 	if (syscon)
655 		plat->regmap_sfr = syscon_get_regmap(syscon);
656 
657 	return 0;
658 }
659 
utmi_clk_probe(struct udevice * dev)660 static int utmi_clk_probe(struct udevice *dev)
661 {
662 	return at91_pmc_core_probe(dev);
663 }
664 
665 static const struct udevice_id utmi_clk_match[] = {
666 	{ .compatible = "atmel,at91sam9x5-clk-utmi" },
667 	{}
668 };
669 
670 U_BOOT_DRIVER(at91sam9x5_utmi_clk) = {
671 	.name = "at91sam9x5-utmi-clk",
672 	.id = UCLASS_CLK,
673 	.of_match = utmi_clk_match,
674 	.probe = utmi_clk_probe,
675 	.of_to_plat = utmi_clk_of_to_plat,
676 	.plat_auto	= sizeof(struct pmc_plat),
677 	.ops = &utmi_clk_ops,
678 };
679 
680 #endif /* CONFIG_AT91_UTMI */
681 
682 /* H32MX clock specific code. */
683 #ifdef CONFIG_AT91_H32MX
684 
685 #define H32MX_MAX_FREQ	90000000
686 
sama5d4_h32mx_clk_get_rate(struct clk * clk)687 static ulong sama5d4_h32mx_clk_get_rate(struct clk *clk)
688 {
689 	struct pmc_plat *plat = dev_get_plat(clk->dev);
690 	struct at91_pmc *pmc = plat->reg_base;
691 	ulong rate = gd->arch.mck_rate_hz;
692 
693 	if (readl(&pmc->mckr) & AT91_PMC_MCKR_H32MXDIV)
694 		rate /= 2;
695 
696 	if (rate > H32MX_MAX_FREQ)
697 		dev_dbg(clk->dev, "H32MX clock is too fast\n");
698 
699 	return rate;
700 }
701 
702 static struct clk_ops sama5d4_h32mx_clk_ops = {
703 	.get_rate = sama5d4_h32mx_clk_get_rate,
704 };
705 
sama5d4_h32mx_clk_probe(struct udevice * dev)706 static int sama5d4_h32mx_clk_probe(struct udevice *dev)
707 {
708 	return at91_pmc_core_probe(dev);
709 }
710 
711 static const struct udevice_id sama5d4_h32mx_clk_match[] = {
712 	{ .compatible = "atmel,sama5d4-clk-h32mx" },
713 	{}
714 };
715 
716 U_BOOT_DRIVER(sama5d4_h32mx_clk) = {
717 	.name = "sama5d4-h32mx-clk",
718 	.id = UCLASS_CLK,
719 	.of_match = sama5d4_h32mx_clk_match,
720 	.probe = sama5d4_h32mx_clk_probe,
721 	.plat_auto	= sizeof(struct pmc_plat),
722 	.ops = &sama5d4_h32mx_clk_ops,
723 };
724 
725 #endif /* CONFIG_AT91_H32MX */
726 
727 /* Generic clock specific code. */
728 #ifdef CONFIG_AT91_GENERIC_CLK
729 
730 #define GENERATED_SOURCE_MAX	6
731 #define GENERATED_MAX_DIV	255
732 
733 /**
734  * generated_clk_bind() - for the generated clock driver
735  * Recursively bind its children as clk devices.
736  *
737  * @return: 0 on success, or negative error code on failure
738  */
generated_clk_bind(struct udevice * dev)739 static int generated_clk_bind(struct udevice *dev)
740 {
741 	return at91_clk_sub_device_bind(dev, "generic-clk");
742 }
743 
744 static const struct udevice_id generated_clk_match[] = {
745 	{ .compatible = "atmel,sama5d2-clk-generated" },
746 	{}
747 };
748 
749 U_BOOT_DRIVER(generated_clk) = {
750 	.name = "generated-clk",
751 	.id = UCLASS_MISC,
752 	.of_match = generated_clk_match,
753 	.bind = generated_clk_bind,
754 };
755 
756 struct generic_clk_priv {
757 	u32 num_parents;
758 };
759 
generic_clk_get_rate(struct clk * clk)760 static ulong generic_clk_get_rate(struct clk *clk)
761 {
762 	struct pmc_plat *plat = dev_get_plat(clk->dev);
763 	struct at91_pmc *pmc = plat->reg_base;
764 	struct clk parent;
765 	ulong clk_rate;
766 	u32 tmp, gckdiv;
767 	u8 clock_source, parent_index;
768 	int ret;
769 
770 	writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
771 	tmp = readl(&pmc->pcr);
772 	clock_source = (tmp >> AT91_PMC_PCR_GCKCSS_OFFSET) &
773 		    AT91_PMC_PCR_GCKCSS_MASK;
774 	gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK;
775 
776 	parent_index = clock_source - 1;
777 	ret = clk_get_by_index(dev_get_parent(clk->dev), parent_index, &parent);
778 	if (ret)
779 		return 0;
780 
781 	clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
782 
783 	clk_free(&parent);
784 
785 	return clk_rate;
786 }
787 
generic_clk_set_rate(struct clk * clk,ulong rate)788 static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
789 {
790 	struct pmc_plat *plat = dev_get_plat(clk->dev);
791 	struct at91_pmc *pmc = plat->reg_base;
792 	struct generic_clk_priv *priv = dev_get_priv(clk->dev);
793 	struct clk parent, best_parent;
794 	ulong tmp_rate, best_rate = rate, parent_rate;
795 	int tmp_diff, best_diff = -1;
796 	u32 div, best_div = 0;
797 	u8 best_parent_index, best_clock_source = 0;
798 	u8 i;
799 	u32 tmp;
800 	int ret;
801 
802 	for (i = 0; i < priv->num_parents; i++) {
803 		ret = clk_get_by_index(dev_get_parent(clk->dev), i, &parent);
804 		if (ret)
805 			return ret;
806 
807 		parent_rate = clk_get_rate(&parent);
808 		if (IS_ERR_VALUE(parent_rate))
809 			return parent_rate;
810 
811 		for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
812 			tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
813 			tmp_diff = abs(rate - tmp_rate);
814 
815 			if (best_diff < 0 || best_diff > tmp_diff) {
816 				best_rate = tmp_rate;
817 				best_diff = tmp_diff;
818 
819 				best_div = div - 1;
820 				best_parent = parent;
821 				best_parent_index = i;
822 				best_clock_source = best_parent_index + 1;
823 			}
824 
825 			if (!best_diff || tmp_rate < rate)
826 				break;
827 		}
828 
829 		if (!best_diff)
830 			break;
831 	}
832 
833 	debug("GCK: best parent: %s, best_rate = %ld, best_div = %d\n",
834 	      best_parent.dev->name, best_rate, best_div);
835 
836 	ret = clk_enable(&best_parent);
837 	if (ret)
838 		return ret;
839 
840 	writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
841 	tmp = readl(&pmc->pcr);
842 	tmp &= ~(AT91_PMC_PCR_GCKDIV | AT91_PMC_PCR_GCKCSS);
843 	tmp |= AT91_PMC_PCR_GCKCSS_(best_clock_source) |
844 	       AT91_PMC_PCR_CMD_WRITE |
845 	       AT91_PMC_PCR_GCKDIV_(best_div) |
846 	       AT91_PMC_PCR_GCKEN;
847 	writel(tmp, &pmc->pcr);
848 
849 	while (!(readl(&pmc->sr) & AT91_PMC_GCKRDY))
850 		;
851 
852 	return 0;
853 }
854 
855 static struct clk_ops generic_clk_ops = {
856 	.of_xlate = at91_clk_of_xlate,
857 	.get_rate = generic_clk_get_rate,
858 	.set_rate = generic_clk_set_rate,
859 };
860 
generic_clk_of_to_plat(struct udevice * dev)861 static int generic_clk_of_to_plat(struct udevice *dev)
862 {
863 	struct generic_clk_priv *priv = dev_get_priv(dev);
864 	u32 cells[GENERATED_SOURCE_MAX];
865 	u32 num_parents;
866 
867 	num_parents = fdtdec_get_int_array_count(gd->fdt_blob,
868 			dev_of_offset(dev_get_parent(dev)), "clocks", cells,
869 			GENERATED_SOURCE_MAX);
870 
871 	if (!num_parents)
872 		return -1;
873 
874 	priv->num_parents = num_parents;
875 
876 	return 0;
877 }
878 
879 U_BOOT_DRIVER(generic_clk) = {
880 	.name = "generic-clk",
881 	.id = UCLASS_CLK,
882 	.probe = at91_clk_probe,
883 	.of_to_plat = generic_clk_of_to_plat,
884 	.priv_auto	= sizeof(struct generic_clk_priv),
885 	.plat_auto	= sizeof(struct pmc_plat),
886 	.ops = &generic_clk_ops,
887 };
888 
889 #endif /* CONFIG_AT91_GENERIC_CLK */
890 
891 /* USB clock specific code. */
892 #ifdef CONFIG_AT91_USB_CLK
893 
894 #define AT91_USB_CLK_SOURCE_MAX	2
895 #define AT91_USB_CLK_MAX_DIV	15
896 
897 struct at91_usb_clk_priv {
898 	u32 num_clksource;
899 };
900 
at91_usb_clk_get_rate(struct clk * clk)901 static ulong at91_usb_clk_get_rate(struct clk *clk)
902 {
903 	struct pmc_plat *plat = dev_get_plat(clk->dev);
904 	struct at91_pmc *pmc = plat->reg_base;
905 	struct clk source;
906 	u32 tmp, usbdiv;
907 	u8 source_index;
908 	int ret;
909 
910 	tmp = readl(&pmc->pcr);
911 	source_index = (tmp >> AT91_PMC_USB_USBS_OFFSET) &
912 			AT91_PMC_USB_USBS_MASK;
913 	usbdiv = (tmp >> AT91_PMC_USB_DIV_OFFSET) & AT91_PMC_USB_DIV_MASK;
914 
915 	ret = clk_get_by_index(clk->dev, source_index, &source);
916 	if (ret)
917 		return 0;
918 
919 	return clk_get_rate(&source) / (usbdiv + 1);
920 }
921 
at91_usb_clk_set_rate(struct clk * clk,ulong rate)922 static ulong at91_usb_clk_set_rate(struct clk *clk, ulong rate)
923 {
924 	struct pmc_plat *plat = dev_get_plat(clk->dev);
925 	struct at91_pmc *pmc = plat->reg_base;
926 	struct at91_usb_clk_priv *priv = dev_get_priv(clk->dev);
927 	struct clk source, best_source;
928 	ulong tmp_rate, best_rate = rate, source_rate;
929 	int tmp_diff, best_diff = -1;
930 	u32 div, best_div = 0;
931 	u8 best_source_index = 0;
932 	u8 i;
933 	u32 tmp;
934 	int ret;
935 
936 	for (i = 0; i < priv->num_clksource; i++) {
937 		ret = clk_get_by_index(clk->dev, i, &source);
938 		if (ret)
939 			return ret;
940 
941 		source_rate = clk_get_rate(&source);
942 		if (IS_ERR_VALUE(source_rate))
943 			return source_rate;
944 
945 		for (div = 1; div < AT91_USB_CLK_MAX_DIV + 2; div++) {
946 			tmp_rate = DIV_ROUND_CLOSEST(source_rate, div);
947 			tmp_diff = abs(rate - tmp_rate);
948 
949 			if (best_diff < 0 || best_diff > tmp_diff) {
950 				best_rate = tmp_rate;
951 				best_diff = tmp_diff;
952 
953 				best_div = div - 1;
954 				best_source = source;
955 				best_source_index = i;
956 			}
957 
958 			if (!best_diff || tmp_rate < rate)
959 				break;
960 		}
961 
962 		if (!best_diff)
963 			break;
964 	}
965 
966 	debug("AT91 USB: best sourc: %s, best_rate = %ld, best_div = %d\n",
967 	      best_source.dev->name, best_rate, best_div);
968 
969 	ret = clk_enable(&best_source);
970 	if (ret)
971 		return ret;
972 
973 	tmp = AT91_PMC_USB_USBS_(best_source_index) |
974 	      AT91_PMC_USB_DIV_(best_div);
975 	writel(tmp, &pmc->usb);
976 
977 	return 0;
978 }
979 
980 static struct clk_ops at91_usb_clk_ops = {
981 	.get_rate = at91_usb_clk_get_rate,
982 	.set_rate = at91_usb_clk_set_rate,
983 };
984 
at91_usb_clk_of_to_plat(struct udevice * dev)985 static int at91_usb_clk_of_to_plat(struct udevice *dev)
986 {
987 	struct at91_usb_clk_priv *priv = dev_get_priv(dev);
988 	u32 cells[AT91_USB_CLK_SOURCE_MAX];
989 	u32 num_clksource;
990 
991 	num_clksource = fdtdec_get_int_array_count(gd->fdt_blob,
992 						   dev_of_offset(dev),
993 						   "clocks", cells,
994 						   AT91_USB_CLK_SOURCE_MAX);
995 
996 	if (!num_clksource)
997 		return -1;
998 
999 	priv->num_clksource = num_clksource;
1000 
1001 	return 0;
1002 }
1003 
at91_usb_clk_probe(struct udevice * dev)1004 static int at91_usb_clk_probe(struct udevice *dev)
1005 {
1006 	return at91_pmc_core_probe(dev);
1007 }
1008 
1009 static const struct udevice_id at91_usb_clk_match[] = {
1010 	{ .compatible = "atmel,at91sam9x5-clk-usb" },
1011 	{}
1012 };
1013 
1014 U_BOOT_DRIVER(at91_usb_clk) = {
1015 	.name = "at91-usb-clk",
1016 	.id = UCLASS_CLK,
1017 	.of_match = at91_usb_clk_match,
1018 	.probe = at91_usb_clk_probe,
1019 	.of_to_plat = at91_usb_clk_of_to_plat,
1020 	.priv_auto	= sizeof(struct at91_usb_clk_priv),
1021 	.plat_auto	= sizeof(struct pmc_plat),
1022 	.ops = &at91_usb_clk_ops,
1023 };
1024 
1025 #endif /* CONFIG_AT91_USB_CLK */
1026