1 /*-
2  * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
3  * Copyright (c) 2010 Greg Ansley.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: stable/9/sys/arm/at91/at91_pmc.c 236081 2012-05-26 09:05:45Z marius $");
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/malloc.h>
34 #include <sys/module.h>
35 #include <sys/time.h>
36 #include <sys/bus.h>
37 #include <sys/resource.h>
38 #include <sys/rman.h>
39 #include <sys/timetc.h>
40 
41 #include <machine/bus.h>
42 #include <machine/cpu.h>
43 #include <machine/cpufunc.h>
44 #include <machine/resource.h>
45 #include <machine/frame.h>
46 #include <machine/intr.h>
47 #include <arm/at91/at91reg.h>
48 #include <arm/at91/at91var.h>
49 
50 #include <arm/at91/at91_pmcreg.h>
51 #include <arm/at91/at91_pmcvar.h>
52 
53 static struct at91_pmc_softc {
54 	bus_space_tag_t		sc_st;
55 	bus_space_handle_t	sc_sh;
56 	struct resource	*mem_res;	/* Memory resource */
57 	device_t		dev;
58 	unsigned int		main_clock_hz;
59 	uint32_t		pllb_init;
60 } *pmc_softc;
61 
62 MALLOC_DECLARE(M_PMC);
63 MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
64 
65 static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
66 static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
67 static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
68 static void at91_pmc_clock_alias(const char *name, const char *alias);
69 
70 static struct at91_pmc_clock slck = {
71 	.name = "slck",		// 32,768 Hz slow clock
72 	.hz = 32768,
73 	.refcnt = 1,
74 	.id = 0,
75 	.primary = 1,
76 };
77 
78 /*
79  * NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc.
80  * are now created automatically. Only "system" clocks need be defined here.
81  */
82 static struct at91_pmc_clock main_ck = {
83 	.name = "main",		// Main clock
84 	.refcnt = 0,
85 	.id = 1,
86 	.primary = 1,
87 	.pmc_mask = PMC_IER_MOSCS,
88 };
89 
90 static struct at91_pmc_clock plla = {
91 	.name = "plla",		// PLLA Clock, used for CPU clocking
92 	.parent = &main_ck,
93 	.refcnt = 1,
94 	.id = 0,
95 	.primary = 1,
96 	.pll = 1,
97 	.pmc_mask = PMC_IER_LOCKA,
98 };
99 
100 static struct at91_pmc_clock pllb = {
101 	.name = "pllb",		// PLLB Clock, used for USB functions
102 	.parent = &main_ck,
103 	.refcnt = 0,
104 	.id = 0,
105 	.primary = 1,
106 	.pll = 1,
107 	.pmc_mask = PMC_IER_LOCKB,
108 	.set_mode = &at91_pmc_set_pllb_mode,
109 };
110 
111 static struct at91_pmc_clock udpck = {
112 	.name = "udpck",
113 	.parent = &pllb,
114 	.pmc_mask = PMC_SCER_UDP,
115 	.set_mode = at91_pmc_set_sys_mode
116 };
117 
118 static struct at91_pmc_clock uhpck = {
119 	.name = "uhpck",
120 	.parent = &pllb,
121 	.pmc_mask = PMC_SCER_UHP,
122 	.set_mode = at91_pmc_set_sys_mode
123 };
124 
125 static struct at91_pmc_clock mck = {
126 	.name = "mck",		// Master (Peripheral) Clock
127 	.pmc_mask = PMC_IER_MCKRDY,
128 	.refcnt = 0,
129 };
130 
131 static struct at91_pmc_clock cpu = {
132 	.name = "cpu",		// CPU Clock
133 	.parent = &plla,
134 	.pmc_mask = PMC_SCER_PCK,
135 	.refcnt = 0,
136 };
137 
138 /* "+32" or the automatic peripheral clocks */
139 static struct at91_pmc_clock *clock_list[16+32] = {
140 	&slck,
141 	&main_ck,
142 	&plla,
143 	&pllb,
144 	&udpck,
145 	&uhpck,
146 	&mck,
147 	&cpu
148 };
149 
150 #if !defined(AT91C_MAIN_CLOCK)
151 static const unsigned int at91_mainf_tbl[] = {
152 	3000000, 3276800, 3686400, 3840000, 4000000,
153 	4433619, 4915200, 5000000, 5242880, 6000000,
154 	6144000, 6400000, 6553600, 7159090, 7372800,
155 	7864320, 8000000, 9830400, 10000000, 11059200,
156 	12000000, 12288000, 13560000, 14318180, 14745600,
157 	16000000, 17344700, 18432000, 20000000
158 };
159 #define	MAINF_TBL_LEN	(sizeof(at91_mainf_tbl) / sizeof(*at91_mainf_tbl))
160 #endif
161 
162 static inline uint32_t
RD4(struct at91_pmc_softc * sc,bus_size_t off)163 RD4(struct at91_pmc_softc *sc, bus_size_t off)
164 {
165 
166 	return (bus_read_4(sc->mem_res, off));
167 }
168 
169 static inline void
WR4(struct at91_pmc_softc * sc,bus_size_t off,uint32_t val)170 WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
171 {
172 
173 	bus_write_4(sc->mem_res, off, val);
174 }
175 
176 void
at91_pmc_set_pllb_mode(struct at91_pmc_clock * clk,int on)177 at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
178 {
179 	struct at91_pmc_softc *sc = pmc_softc;
180 	uint32_t value;
181 
182 	if (on) {
183 		on = PMC_IER_LOCKB;
184 		value = sc->pllb_init;
185 	} else
186 		value = 0;
187 
188 	/* Workaround RM9200 Errata #26 */
189 	if (at91_is_rm92() &&
190 	   ((value ^ RD4(sc, CKGR_PLLBR)) & 0x03f0ff) != 0) {
191 		WR4(sc, CKGR_PLLBR, value ^ 1);
192 		while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
193 			continue;
194 	}
195 
196 	WR4(sc, CKGR_PLLBR, value);
197 	while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
198 		continue;
199 }
200 
201 static void
at91_pmc_set_sys_mode(struct at91_pmc_clock * clk,int on)202 at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
203 {
204 	struct at91_pmc_softc *sc = pmc_softc;
205 
206 	WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
207 	if (on)
208 		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
209 			continue;
210 	else
211 		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
212 			continue;
213 }
214 
215 static void
at91_pmc_set_periph_mode(struct at91_pmc_clock * clk,int on)216 at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
217 {
218 	struct at91_pmc_softc *sc = pmc_softc;
219 
220 	WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
221 	if (on)
222 		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
223 			continue;
224 	else
225 		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
226 			continue;
227 }
228 
229 struct at91_pmc_clock *
at91_pmc_clock_add(const char * name,uint32_t irq,struct at91_pmc_clock * parent)230 at91_pmc_clock_add(const char *name, uint32_t irq,
231     struct at91_pmc_clock *parent)
232 {
233 	struct at91_pmc_clock *clk;
234 	int i, buflen;
235 
236 	clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
237 	if (clk == NULL)
238 		goto err;
239 
240 	buflen = strlen(name) + 1;
241 	clk->name = malloc(buflen, M_PMC, M_NOWAIT);
242 	if (clk->name == NULL)
243 		goto err;
244 
245 	strlcpy(clk->name, name, buflen);
246 	clk->pmc_mask = 1 << irq;
247 	clk->set_mode = &at91_pmc_set_periph_mode;
248 	if (parent == NULL)
249 		clk->parent = &mck;
250 	else
251 		clk->parent = parent;
252 
253 	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
254 		if (clock_list[i] == NULL) {
255 			clock_list[i] = clk;
256 			return (clk);
257 		}
258 	}
259 err:
260 	if (clk != NULL) {
261 		if (clk->name != NULL)
262 			free(clk->name, M_PMC);
263 		free(clk, M_PMC);
264 	}
265 
266 	panic("could not allocate pmc clock '%s'", name);
267 	return (NULL);
268 }
269 
270 static void
at91_pmc_clock_alias(const char * name,const char * alias)271 at91_pmc_clock_alias(const char *name, const char *alias)
272 {
273 	struct at91_pmc_clock *clk, *alias_clk;
274 
275 	clk = at91_pmc_clock_ref(name);
276 	if (clk)
277 		alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
278 
279 	if (clk && alias_clk) {
280 		alias_clk->hz = clk->hz;
281 		alias_clk->pmc_mask = clk->pmc_mask;
282 		alias_clk->set_mode = clk->set_mode;
283 	}
284 }
285 
286 struct at91_pmc_clock *
at91_pmc_clock_ref(const char * name)287 at91_pmc_clock_ref(const char *name)
288 {
289 	int i;
290 
291 	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
292 		if (clock_list[i] == NULL)
293 		    break;
294 		if (strcmp(name, clock_list[i]->name) == 0)
295 			return (clock_list[i]);
296 	}
297 
298 	//printf("at91_pmc: Warning - did not find clock '%s'", name);
299 	return (NULL);
300 }
301 
302 void
at91_pmc_clock_deref(struct at91_pmc_clock * clk)303 at91_pmc_clock_deref(struct at91_pmc_clock *clk)
304 {
305 
306 }
307 
308 void
at91_pmc_clock_enable(struct at91_pmc_clock * clk)309 at91_pmc_clock_enable(struct at91_pmc_clock *clk)
310 {
311 
312 	/* XXX LOCKING? XXX */
313 	if (clk->parent)
314 		at91_pmc_clock_enable(clk->parent);
315 	if (clk->refcnt++ == 0 && clk->set_mode)
316 		clk->set_mode(clk, 1);
317 }
318 
319 void
at91_pmc_clock_disable(struct at91_pmc_clock * clk)320 at91_pmc_clock_disable(struct at91_pmc_clock *clk)
321 {
322 
323 	/* XXX LOCKING? XXX */
324 	if (--clk->refcnt == 0 && clk->set_mode)
325 		clk->set_mode(clk, 0);
326 	if (clk->parent)
327 		at91_pmc_clock_disable(clk->parent);
328 }
329 
330 static int
at91_pmc_pll_rate(struct at91_pmc_clock * clk,uint32_t reg)331 at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
332 {
333 	uint32_t mul, div, freq;
334 
335 	freq = clk->parent->hz;
336 	div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
337 	mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
338 
339 #if 0
340 	printf("pll = (%d /  %d) * %d = %d\n",
341 	    freq, div, mul + 1, (freq/div) * (mul+1));
342 #endif
343 
344 	if (div != 0 && mul != 0) {
345 		freq /= div;
346 		freq *= mul + 1;
347 	} else
348 		freq = 0;
349 	clk->hz = freq;
350 
351 	return (freq);
352 }
353 
354 static uint32_t
at91_pmc_pll_calc(struct at91_pmc_clock * clk,uint32_t out_freq)355 at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
356 {
357 	uint32_t i, div = 0, mul = 0, diff = 1 << 30;
358 
359 	unsigned ret = 0x3e00;
360 
361 	if (out_freq > clk->pll_max_out)
362 		goto fail;
363 
364 	for (i = 1; i < 256; i++) {
365 		int32_t diff1;
366 		uint32_t input, mul1;
367 
368 		input = clk->parent->hz / i;
369 		if (input < clk->pll_min_in)
370 			break;
371 		if (input > clk->pll_max_in)
372 			continue;
373 
374 		mul1 = out_freq / input;
375 		if (mul1 > (clk->pll_mul_mask + 1))
376 			continue;
377 		if (mul1 == 0)
378 			break;
379 
380 		diff1 = out_freq - input * mul1;
381 		if (diff1 < 0)
382 			diff1 = -diff1;
383 		if (diff > diff1) {
384 			diff = diff1;
385 			div = i;
386 			mul = mul1;
387 			if (diff == 0)
388 				break;
389 		}
390 	}
391 	if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
392 		goto fail;
393 
394 	if (clk->set_outb != NULL)
395 		ret |= clk->set_outb(out_freq);
396 
397 	return (ret |
398 		((mul - 1) << clk->pll_mul_shift) |
399 		(div << clk->pll_div_shift));
400 fail:
401 	return (0);
402 }
403 
404 static void
at91_pmc_init_clock(struct at91_pmc_softc * sc,unsigned int main_clock)405 at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
406 {
407 	uint32_t mckr;
408 	uint32_t mdiv;
409 
410 	if (at91_is_sam9() || at91_is_sam9xe()) {
411 		uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
412 		udpck.pmc_mask = PMC_SCER_UDP_SAM9;
413 	}
414 	mckr = RD4(sc, PMC_MCKR);
415 	sc->main_clock_hz = main_clock;
416 	main_ck.hz = main_clock;
417 
418 	at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
419 
420 	if (at91_cpu_is(AT91_CPU_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
421 		plla.hz /= 2;
422 
423 	/*
424 	 * Initialize the usb clock.  This sets up pllb, but disables the
425 	 * actual clock.
426 	 */
427 	sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
428 	at91_pmc_pll_rate(&pllb, sc->pllb_init);
429 
430 #if 0
431 	/* Turn off USB clocks */
432 	at91_pmc_set_periph_mode(&ohci_clk, 0);
433 	at91_pmc_set_periph_mode(&udc_clk, 0);
434 #endif
435 
436 	if (at91_is_rm92()) {
437 		WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
438 		WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
439 	} else
440 		WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
441 	WR4(sc, CKGR_PLLBR, 0);
442 
443 	/*
444 	 * MCK and PCU derive from one of the primary clocks.  Initialize
445 	 * this relationship.
446 	 */
447 	mck.parent = clock_list[mckr & 0x3];
448 	mck.parent->refcnt++;
449 
450 	cpu.hz = mck.hz = mck.parent->hz /
451 	    (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
452 
453 	mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
454 	if (at91_is_sam9() || at91_is_sam9xe()) {
455 		if (mdiv > 0)
456 			mck.hz /= mdiv * 2;
457 	} else
458 		mck.hz /= (1 + mdiv);
459 
460 	/* Only found on SAM9G20 */
461 	if (at91_cpu_is(AT91_CPU_SAM9G20))
462 		cpu.hz /= (mckr & PMC_MCKR_PDIV) ?  2 : 1;
463 
464 	at91_master_clock = mck.hz;
465 
466 	device_printf(sc->dev,
467 	    "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
468 	    sc->main_clock_hz,
469 	    plla.hz / 1000000,
470 	    cpu.hz / 1000000, mck.hz / 1000000);
471 
472 	/* Turn off "Progamable" clocks */
473 	WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
474 	    PMC_SCER_PCK3);
475 
476 	/* XXX kludge, turn on all peripherals */
477 	WR4(sc, PMC_PCER, 0xffffffff);
478 
479 	/* Disable all interrupts for PMC */
480 	WR4(sc, PMC_IDR, 0xffffffff);
481 }
482 
483 static void
at91_pmc_deactivate(device_t dev)484 at91_pmc_deactivate(device_t dev)
485 {
486 	struct at91_pmc_softc *sc;
487 
488 	sc = device_get_softc(dev);
489 	bus_generic_detach(sc->dev);
490 	if (sc->mem_res)
491 		bus_release_resource(dev, SYS_RES_IOPORT,
492 		    rman_get_rid(sc->mem_res), sc->mem_res);
493 	sc->mem_res = 0;
494 }
495 
496 static int
at91_pmc_activate(device_t dev)497 at91_pmc_activate(device_t dev)
498 {
499 	struct at91_pmc_softc *sc;
500 	int rid;
501 
502 	sc = device_get_softc(dev);
503 	rid = 0;
504 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
505 	    RF_ACTIVE);
506 	if (sc->mem_res == NULL)
507 		goto errout;
508 	return (0);
509 errout:
510 	at91_pmc_deactivate(dev);
511 	return (ENOMEM);
512 }
513 
514 static int
at91_pmc_probe(device_t dev)515 at91_pmc_probe(device_t dev)
516 {
517 
518 	device_set_desc(dev, "PMC");
519 	return (0);
520 }
521 
522 #if !defined(AT91C_MAIN_CLOCK)
523 static unsigned int
at91_pmc_sense_mainf(struct at91_pmc_softc * sc)524 at91_pmc_sense_mainf(struct at91_pmc_softc *sc)
525 {
526 	unsigned int ckgr_val;
527 	unsigned int diff, matchdiff;
528 	int i, match;
529 
530 	ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
531 
532 	/*
533 	 * Try to find the standard frequency that match best.
534 	 */
535 	match = 0;
536 	matchdiff = abs(ckgr_val - at91_mainf_tbl[0]);
537 	for (i = 1; i < MAINF_TBL_LEN; i++) {
538 		diff = abs(ckgr_val - at91_mainf_tbl[i]);
539 		if (diff < matchdiff) {
540 			match = i;
541 			matchdiff = diff;
542 		}
543 	}
544 	return (at91_mainf_tbl[match]);
545 }
546 #endif
547 
548 static int
at91_pmc_attach(device_t dev)549 at91_pmc_attach(device_t dev)
550 {
551 	unsigned int mainf;
552 	int err;
553 
554 	pmc_softc = device_get_softc(dev);
555 	pmc_softc->dev = dev;
556 	if ((err = at91_pmc_activate(dev)) != 0)
557 		return (err);
558 
559 	/*
560 	 * Configure main clock frequency.
561 	 */
562 #if !defined(AT91C_MAIN_CLOCK)
563 	mainf = at91_pmc_sense_mainf(pmc_softc);
564 #else
565 	mainf = AT91C_MAIN_CLOCK;
566 #endif
567 	at91_pmc_init_clock(pmc_softc, mainf);
568 
569 	/* These clocks refrenced by "special" names */
570 	at91_pmc_clock_alias("ohci0", "ohci_clk");
571 	at91_pmc_clock_alias("udp0",  "udp_clk");
572 
573 	return (0);
574 }
575 
576 static device_method_t at91_pmc_methods[] = {
577 	DEVMETHOD(device_probe, at91_pmc_probe),
578 	DEVMETHOD(device_attach, at91_pmc_attach),
579 	DEVMETHOD_END
580 };
581 
582 static driver_t at91_pmc_driver = {
583 	"at91_pmc",
584 	at91_pmc_methods,
585 	sizeof(struct at91_pmc_softc),
586 };
587 static devclass_t at91_pmc_devclass;
588 
589 DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, NULL,
590     NULL);
591