xref: /trueos/sys/arm/at91/at91_pmc.c (revision 8cc892107dae023ecf9b4c50ce15c97172a61516)
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 "opt_platform.h"
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/time.h>
38 #include <sys/bus.h>
39 #include <sys/resource.h>
40 #include <sys/rman.h>
41 #include <sys/timetc.h>
42 
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/cpufunc.h>
46 #include <machine/resource.h>
47 #include <machine/intr.h>
48 #include <arm/at91/at91reg.h>
49 #include <arm/at91/at91var.h>
50 
51 #include <arm/at91/at91_pmcreg.h>
52 #include <arm/at91/at91_pmcvar.h>
53 
54 #ifdef FDT
55 #include <dev/fdt/fdt_common.h>
56 #include <dev/ofw/ofw_bus.h>
57 #include <dev/ofw/ofw_bus_subr.h>
58 #endif
59 
60 static struct at91_pmc_softc {
61 	bus_space_tag_t		sc_st;
62 	bus_space_handle_t	sc_sh;
63 	struct resource	*mem_res;	/* Memory resource */
64 	device_t		dev;
65 } *pmc_softc;
66 
67 static uint32_t pllb_init;
68 
69 MALLOC_DECLARE(M_PMC);
70 MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
71 
72 #define AT91_PMC_BASE 0xffffc00
73 
74 static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
75 static void at91_pmc_set_upll_mode(struct at91_pmc_clock *, int);
76 static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
77 static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
78 static void at91_pmc_clock_alias(const char *name, const char *alias);
79 
80 static struct at91_pmc_clock slck = {
81 	.name = "slck",		/* 32,768 Hz slow clock */
82 	.hz = 32768,
83 	.refcnt = 1,
84 	.id = 0,
85 	.primary = 1,
86 };
87 
88 /*
89  * NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc.
90  * are now created automatically. Only "system" clocks need be defined here.
91  */
92 static struct at91_pmc_clock main_ck = {
93 	.name = "main",		/* Main clock */
94 	.refcnt = 0,
95 	.id = 1,
96 	.primary = 1,
97 	.pmc_mask = PMC_IER_MOSCS,
98 };
99 
100 static struct at91_pmc_clock plla = {
101 	.name = "plla",		/* PLLA Clock, used for CPU clocking */
102 	.parent = &main_ck,
103 	.refcnt = 1,
104 	.id = 0,
105 	.primary = 1,
106 	.pll = 1,
107 	.pmc_mask = PMC_IER_LOCKA,
108 };
109 
110 static struct at91_pmc_clock pllb = {
111 	.name = "pllb",		/* PLLB Clock, used for USB functions */
112 	.parent = &main_ck,
113 	.refcnt = 0,
114 	.id = 0,
115 	.primary = 1,
116 	.pll = 1,
117 	.pmc_mask = PMC_IER_LOCKB,
118 	.set_mode = &at91_pmc_set_pllb_mode,
119 };
120 
121 /* Used by USB on at91sam9g45 */
122 static struct at91_pmc_clock upll = {
123 	.name = "upll",		/* UTMI PLL, used for USB functions on 9G45 family */
124 	.parent = &main_ck,
125 	.refcnt = 0,
126 	.id = 0,
127 	.primary = 1,
128 	.pll = 1,
129 	.pmc_mask = (1 << 6),
130 	.set_mode = &at91_pmc_set_upll_mode,
131 };
132 
133 static struct at91_pmc_clock udpck = {
134 	.name = "udpck",
135 	.parent = &pllb,
136 	.pmc_mask = PMC_SCER_UDP,
137 	.set_mode = at91_pmc_set_sys_mode
138 };
139 
140 static struct at91_pmc_clock uhpck = {
141 	.name = "uhpck",
142 	.parent = &pllb,
143 	.pmc_mask = PMC_SCER_UHP,
144 	.set_mode = at91_pmc_set_sys_mode
145 };
146 
147 static struct at91_pmc_clock mck = {
148 	.name = "mck",		/* Master (Peripheral) Clock */
149 	.pmc_mask = PMC_IER_MCKRDY,
150 	.refcnt = 0,
151 };
152 
153 static struct at91_pmc_clock cpu = {
154 	.name = "cpu",		/* CPU Clock */
155 	.parent = &plla,
156 	.pmc_mask = PMC_SCER_PCK,
157 	.refcnt = 0,
158 };
159 
160 /* "+32" or the automatic peripheral clocks */
161 static struct at91_pmc_clock *clock_list[16+32] = {
162 	&slck,
163 	&main_ck,
164 	&plla,
165 	&pllb,
166 	&upll,
167 	&udpck,
168 	&uhpck,
169 	&mck,
170 	&cpu
171 };
172 
173 static inline uint32_t
RD4(struct at91_pmc_softc * sc,bus_size_t off)174 RD4(struct at91_pmc_softc *sc, bus_size_t off)
175 {
176 
177 	if (sc == NULL) {
178 		uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off);
179 
180 		return *p;
181 	}
182 	return (bus_read_4(sc->mem_res, off));
183 }
184 
185 static inline void
WR4(struct at91_pmc_softc * sc,bus_size_t off,uint32_t val)186 WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
187 {
188 
189 	if (sc == NULL) {
190 		uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off);
191 
192 		*p = val;
193 	} else
194 		bus_write_4(sc->mem_res, off, val);
195 }
196 
197 /*
198  * The following is unused currently since we don't ever set the PLLA
199  * frequency of the device.  If we did, we'd have to also pay attention
200  * to the ICPLLA bit in the PMC_PLLICPR register for frequencies lower
201  * than ~600MHz, which the PMC code doesn't do right now.
202  */
203 uint32_t
at91_pmc_800mhz_plla_outb(int freq)204 at91_pmc_800mhz_plla_outb(int freq)
205 {
206 	uint32_t outa;
207 
208 	/*
209 	 * Set OUTA, per the data sheet.  See Table 46-16 titled
210 	 * PLLA Frequency Regarding ICPLLA and OUTA in the SAM9X25 doc,
211 	 * Table 46-17 in the SAM9G20 doc, or Table 46-16 in the SAM9G45 doc.
212 	 * Note: the frequencies overlap by 5MHz, so we add 3 here to
213 	 * center shoot the transition.
214 	 */
215 
216 	freq /= 1000000;		/* MHz */
217 	if (freq >= 800)
218 		freq = 800;
219 	freq += 3;			/* Allow for overlap. */
220 	outa = 3 - ((freq / 50) & 3);	/* 750 / 50 = 7, see table */
221 	return (1 << 29)| (outa << 14);
222 }
223 
224 uint32_t
at91_pmc_800mhz_pllb_outb(int freq)225 at91_pmc_800mhz_pllb_outb(int freq)
226 {
227 
228 	return (0);
229 }
230 
231 void
at91_pmc_set_pllb_mode(struct at91_pmc_clock * clk,int on)232 at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
233 {
234 	struct at91_pmc_softc *sc = pmc_softc;
235 	uint32_t value;
236 
237 	value = on ? pllb_init : 0;
238 
239 	/*
240 	 * Only write to the register if the value is changing.  Besides being
241 	 * good common sense, this works around RM9200 Errata #26 (CKGR_PLL[AB]R
242 	 * must not be written with the same value currently in the register).
243 	 */
244 	if (RD4(sc, CKGR_PLLBR) != value) {
245 		WR4(sc, CKGR_PLLBR, value);
246 		while (on && (RD4(sc, PMC_SR) & PMC_IER_LOCKB) != PMC_IER_LOCKB)
247 			continue;
248 	}
249 }
250 
251 static void
at91_pmc_set_upll_mode(struct at91_pmc_clock * clk,int on)252 at91_pmc_set_upll_mode(struct at91_pmc_clock *clk, int on)
253 {
254 	struct at91_pmc_softc *sc = pmc_softc;
255 	uint32_t value;
256 
257 	if (on) {
258 		on = PMC_IER_LOCKU;
259 		value = CKGR_UCKR_UPLLEN | CKGR_UCKR_BIASEN;
260 	} else
261 		value = 0;
262 
263 	WR4(sc, CKGR_UCKR, RD4(sc, CKGR_UCKR) | value);
264 	while ((RD4(sc, PMC_SR) & PMC_IER_LOCKU) != on)
265 		continue;
266 
267 	WR4(sc, PMC_USB, PMC_USB_USBDIV(9) | PMC_USB_USBS);
268 	WR4(sc, PMC_SCER, PMC_SCER_UHP_SAM9);
269 }
270 
271 static void
at91_pmc_set_sys_mode(struct at91_pmc_clock * clk,int on)272 at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
273 {
274 	struct at91_pmc_softc *sc = pmc_softc;
275 
276 	WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
277 	if (on)
278 		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
279 			continue;
280 	else
281 		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
282 			continue;
283 }
284 
285 static void
at91_pmc_set_periph_mode(struct at91_pmc_clock * clk,int on)286 at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
287 {
288 	struct at91_pmc_softc *sc = pmc_softc;
289 
290 	WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
291 	if (on)
292 		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
293 			continue;
294 	else
295 		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
296 			continue;
297 }
298 
299 struct at91_pmc_clock *
at91_pmc_clock_add(const char * name,uint32_t irq,struct at91_pmc_clock * parent)300 at91_pmc_clock_add(const char *name, uint32_t irq,
301     struct at91_pmc_clock *parent)
302 {
303 	struct at91_pmc_clock *clk;
304 	int i, buflen;
305 
306 	clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
307 	if (clk == NULL)
308 		goto err;
309 
310 	buflen = strlen(name) + 1;
311 	clk->name = malloc(buflen, M_PMC, M_NOWAIT);
312 	if (clk->name == NULL)
313 		goto err;
314 
315 	strlcpy(clk->name, name, buflen);
316 	clk->pmc_mask = 1 << irq;
317 	clk->set_mode = &at91_pmc_set_periph_mode;
318 	if (parent == NULL)
319 		clk->parent = &mck;
320 	else
321 		clk->parent = parent;
322 
323 	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
324 		if (clock_list[i] == NULL) {
325 			clock_list[i] = clk;
326 			return (clk);
327 		}
328 	}
329 err:
330 	if (clk != NULL) {
331 		if (clk->name != NULL)
332 			free(clk->name, M_PMC);
333 		free(clk, M_PMC);
334 	}
335 
336 	panic("could not allocate pmc clock '%s'", name);
337 	return (NULL);
338 }
339 
340 static void
at91_pmc_clock_alias(const char * name,const char * alias)341 at91_pmc_clock_alias(const char *name, const char *alias)
342 {
343 	struct at91_pmc_clock *clk, *alias_clk;
344 
345 	clk = at91_pmc_clock_ref(name);
346 	if (clk)
347 		alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
348 
349 	if (clk && alias_clk) {
350 		alias_clk->hz = clk->hz;
351 		alias_clk->pmc_mask = clk->pmc_mask;
352 		alias_clk->set_mode = clk->set_mode;
353 	}
354 }
355 
356 struct at91_pmc_clock *
at91_pmc_clock_ref(const char * name)357 at91_pmc_clock_ref(const char *name)
358 {
359 	int i;
360 
361 	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
362 		if (clock_list[i] == NULL)
363 		    break;
364 		if (strcmp(name, clock_list[i]->name) == 0)
365 			return (clock_list[i]);
366 	}
367 
368 	return (NULL);
369 }
370 
371 void
at91_pmc_clock_deref(struct at91_pmc_clock * clk)372 at91_pmc_clock_deref(struct at91_pmc_clock *clk)
373 {
374 	if (clk == NULL)
375 		return;
376 }
377 
378 void
at91_pmc_clock_enable(struct at91_pmc_clock * clk)379 at91_pmc_clock_enable(struct at91_pmc_clock *clk)
380 {
381 	if (clk == NULL)
382 		return;
383 
384 	/* XXX LOCKING? XXX */
385 	if (clk->parent)
386 		at91_pmc_clock_enable(clk->parent);
387 	if (clk->refcnt++ == 0 && clk->set_mode)
388 		clk->set_mode(clk, 1);
389 }
390 
391 void
at91_pmc_clock_disable(struct at91_pmc_clock * clk)392 at91_pmc_clock_disable(struct at91_pmc_clock *clk)
393 {
394 	if (clk == NULL)
395 		return;
396 
397 	/* XXX LOCKING? XXX */
398 	if (--clk->refcnt == 0 && clk->set_mode)
399 		clk->set_mode(clk, 0);
400 	if (clk->parent)
401 		at91_pmc_clock_disable(clk->parent);
402 }
403 
404 static int
at91_pmc_pll_rate(struct at91_pmc_clock * clk,uint32_t reg)405 at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
406 {
407 	uint32_t mul, div, freq;
408 
409 	freq = clk->parent->hz;
410 	div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
411 	mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
412 
413 #if 0
414 	printf("pll = (%d /  %d) * %d = %d\n",
415 	    freq, div, mul + 1, (freq/div) * (mul+1));
416 #endif
417 
418 	if (div != 0 && mul != 0) {
419 		freq /= div;
420 		freq *= mul + 1;
421 	} else
422 		freq = 0;
423 	clk->hz = freq;
424 
425 	return (freq);
426 }
427 
428 static uint32_t
at91_pmc_pll_calc(struct at91_pmc_clock * clk,uint32_t out_freq)429 at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
430 {
431 	uint32_t i, div = 0, mul = 0, diff = 1 << 30;
432 
433 	unsigned ret = 0x3e00;
434 
435 	if (out_freq > clk->pll_max_out)
436 		goto fail;
437 
438 	for (i = 1; i < 256; i++) {
439 		int32_t diff1;
440 		uint32_t input, mul1;
441 
442 		input = clk->parent->hz / i;
443 		if (input < clk->pll_min_in)
444 			break;
445 		if (input > clk->pll_max_in)
446 			continue;
447 
448 		mul1 = out_freq / input;
449 		if (mul1 > (clk->pll_mul_mask + 1))
450 			continue;
451 		if (mul1 == 0)
452 			break;
453 
454 		diff1 = out_freq - input * mul1;
455 		if (diff1 < 0)
456 			diff1 = -diff1;
457 		if (diff > diff1) {
458 			diff = diff1;
459 			div = i;
460 			mul = mul1;
461 			if (diff == 0)
462 				break;
463 		}
464 	}
465 	if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
466 		goto fail;
467 
468 	if (clk->set_outb != NULL)
469 		ret |= clk->set_outb(out_freq);
470 
471 	return (ret |
472 		((mul - 1) << clk->pll_mul_shift) |
473 		(div << clk->pll_div_shift));
474 fail:
475 	return (0);
476 }
477 
478 #if !defined(AT91C_MAIN_CLOCK)
479 static const unsigned int at91_main_clock_tbl[] = {
480 	3000000, 3276800, 3686400, 3840000, 4000000,
481 	4433619, 4915200, 5000000, 5242880, 6000000,
482 	6144000, 6400000, 6553600, 7159090, 7372800,
483 	7864320, 8000000, 9830400, 10000000, 11059200,
484 	12000000, 12288000, 13560000, 14318180, 14745600,
485 	16000000, 17344700, 18432000, 20000000
486 };
487 #define	MAIN_CLOCK_TBL_LEN	(sizeof(at91_main_clock_tbl) / sizeof(*at91_main_clock_tbl))
488 #endif
489 
490 static unsigned int
at91_pmc_sense_main_clock(void)491 at91_pmc_sense_main_clock(void)
492 {
493 #if !defined(AT91C_MAIN_CLOCK)
494 	unsigned int ckgr_val;
495 	unsigned int diff, matchdiff, freq;
496 	int i;
497 
498 	ckgr_val = (RD4(NULL, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
499 
500 	/*
501 	 * Clocks up to 50MHz can be connected to some models.  If
502 	 * the frequency is >= 21MHz, assume that the slow clock can
503 	 * measure it correctly, and that any error can be adequately
504 	 * compensated for by roudning to the nearest 500Hz.  Users
505 	 * with fast, or odd-ball clocks will need to set
506 	 * AT91C_MAIN_CLOCK in the kernel config file.
507 	 */
508 	if (ckgr_val >= 21000000)
509 		return ((ckgr_val + 250) / 500 * 500);
510 
511 	/*
512 	 * Try to find the standard frequency that match best.
513 	 */
514 	freq = at91_main_clock_tbl[0];
515 	matchdiff = abs(ckgr_val - at91_main_clock_tbl[0]);
516 	for (i = 1; i < MAIN_CLOCK_TBL_LEN; i++) {
517 		diff = abs(ckgr_val - at91_main_clock_tbl[i]);
518 		if (diff < matchdiff) {
519 			freq = at91_main_clock_tbl[i];
520 			matchdiff = diff;
521 		}
522 	}
523 	return (freq);
524 #else
525 	return (AT91C_MAIN_CLOCK);
526 #endif
527 }
528 
529 void
at91_pmc_init_clock(void)530 at91_pmc_init_clock(void)
531 {
532 	struct at91_pmc_softc *sc = NULL;
533 	unsigned int main_clock;
534 	uint32_t mckr;
535 	uint32_t mdiv;
536 
537 	soc_info.soc_data->soc_clock_init();
538 
539 	main_clock = at91_pmc_sense_main_clock();
540 
541 	if (at91_is_sam9() || at91_is_sam9xe()) {
542 		uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
543 		udpck.pmc_mask = PMC_SCER_UDP_SAM9;
544 	}
545 
546 	/* There is no pllb on AT91SAM9G45 */
547 	if (at91_cpu_is(AT91_T_SAM9G45)) {
548 		uhpck.parent = &upll;
549 		uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
550 	}
551 
552 	mckr = RD4(sc, PMC_MCKR);
553 	main_ck.hz = main_clock;
554 
555 	/*
556 	 * Note: this means outa calc code for plla never used since
557 	 * we never change it.  If we did, we'd also have to mind
558 	 * ICPLLA to get the charge pump current right.
559 	 */
560 	at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
561 
562 	if (at91_cpu_is(AT91_T_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
563 		plla.hz /= 2;
564 
565 	/*
566 	 * Initialize the usb clock.  This sets up pllb, but disables the
567 	 * actual clock. XXX except for the if 0 :(
568 	 */
569 	if (!at91_cpu_is(AT91_T_SAM9G45)) {
570 		pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
571 		at91_pmc_pll_rate(&pllb, pllb_init);
572 #if 0
573 		/* Turn off USB clocks */
574 		at91_pmc_set_periph_mode(&ohci_clk, 0);
575 		at91_pmc_set_periph_mode(&udc_clk, 0);
576 #endif
577 	}
578 
579 	if (at91_is_rm92()) {
580 		WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
581 		WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
582 	} else
583 		WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
584 
585 	/*
586 	 * MCK and PCU derive from one of the primary clocks.  Initialize
587 	 * this relationship.
588 	 */
589 	mck.parent = clock_list[mckr & 0x3];
590 	mck.parent->refcnt++;
591 
592 	cpu.hz = mck.hz = mck.parent->hz /
593 	    (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
594 
595 	mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
596 	if (at91_is_sam9() || at91_is_sam9xe()) {
597 		/*
598 		 * On AT91SAM9G45 when mdiv == 3 we need to divide
599 		 * MCK by 3 but not, for example, on 9g20.
600 		 */
601 		if (!at91_cpu_is(AT91_T_SAM9G45) || mdiv <= 2)
602 			mdiv *= 2;
603 		if (mdiv > 0)
604 			mck.hz /= mdiv;
605 	} else
606 		mck.hz /= (1 + mdiv);
607 
608 	/* Only found on SAM9G20 */
609 	if (at91_cpu_is(AT91_T_SAM9G20))
610 		cpu.hz /= (mckr & PMC_MCKR_PDIV) ?  2 : 1;
611 
612 	at91_master_clock = mck.hz;
613 
614 	/* These clocks refrenced by "special" names */
615 	at91_pmc_clock_alias("ohci0", "ohci_clk");
616 	at91_pmc_clock_alias("udp0",  "udp_clk");
617 
618 	/* Turn off "Progamable" clocks */
619 	WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
620 	    PMC_SCER_PCK3);
621 
622 	/* XXX kludge, turn on all peripherals */
623 	WR4(sc, PMC_PCER, 0xffffffff);
624 
625 	/* Disable all interrupts for PMC */
626 	WR4(sc, PMC_IDR, 0xffffffff);
627 }
628 
629 static void
at91_pmc_deactivate(device_t dev)630 at91_pmc_deactivate(device_t dev)
631 {
632 	struct at91_pmc_softc *sc;
633 
634 	sc = device_get_softc(dev);
635 	bus_generic_detach(sc->dev);
636 	if (sc->mem_res)
637 		bus_release_resource(dev, SYS_RES_IOPORT,
638 		    rman_get_rid(sc->mem_res), sc->mem_res);
639 	sc->mem_res = 0;
640 }
641 
642 static int
at91_pmc_activate(device_t dev)643 at91_pmc_activate(device_t dev)
644 {
645 	struct at91_pmc_softc *sc;
646 	int rid;
647 
648 	sc = device_get_softc(dev);
649 	rid = 0;
650 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
651 	    RF_ACTIVE);
652 	if (sc->mem_res == NULL)
653 		goto errout;
654 	return (0);
655 errout:
656 	at91_pmc_deactivate(dev);
657 	return (ENOMEM);
658 }
659 
660 static int
at91_pmc_probe(device_t dev)661 at91_pmc_probe(device_t dev)
662 {
663 #ifdef FDT
664 	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pmc"))
665 		return (ENXIO);
666 #endif
667 	device_set_desc(dev, "PMC");
668 	return (0);
669 }
670 
671 static int
at91_pmc_attach(device_t dev)672 at91_pmc_attach(device_t dev)
673 {
674 	int err;
675 
676 	pmc_softc = device_get_softc(dev);
677 	pmc_softc->dev = dev;
678 	if ((err = at91_pmc_activate(dev)) != 0)
679 		return (err);
680 
681 	/*
682 	 * Configure main clock frequency.
683 	 */
684 	at91_pmc_init_clock();
685 
686 	/*
687 	 * Display info about clocks previously computed
688 	 */
689 	device_printf(dev,
690 	    "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
691 	    main_ck.hz,
692 	    plla.hz / 1000000,
693 	    cpu.hz / 1000000, mck.hz / 1000000);
694 
695 	return (0);
696 }
697 
698 static device_method_t at91_pmc_methods[] = {
699 	DEVMETHOD(device_probe, at91_pmc_probe),
700 	DEVMETHOD(device_attach, at91_pmc_attach),
701 	DEVMETHOD_END
702 };
703 
704 static driver_t at91_pmc_driver = {
705 	"at91_pmc",
706 	at91_pmc_methods,
707 	sizeof(struct at91_pmc_softc),
708 };
709 static devclass_t at91_pmc_devclass;
710 
711 #ifdef FDT
712 DRIVER_MODULE(at91_pmc, simplebus, at91_pmc_driver, at91_pmc_devclass, NULL,
713     NULL);
714 #else
715 DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, NULL,
716     NULL);
717 #endif
718