2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
3 * Copyright (c) 2010 Greg Ansley. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
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>
37 #include <sys/resource.h>
39 #include <sys/timetc.h>
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>
50 #include <arm/at91/at91_pmcreg.h>
51 #include <arm/at91/at91_pmcvar.h>
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 */
58 unsigned int main_clock_hz;
62 MALLOC_DECLARE(M_PMC);
63 MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
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);
70 static struct at91_pmc_clock slck = {
71 .name = "slck", // 32,768 Hz slow clock
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.
82 static struct at91_pmc_clock main_ck = {
83 .name = "main", // Main clock
87 .pmc_mask = PMC_IER_MOSCS,
90 static struct at91_pmc_clock plla = {
91 .name = "plla", // PLLA Clock, used for CPU clocking
97 .pmc_mask = PMC_IER_LOCKA,
100 static struct at91_pmc_clock pllb = {
101 .name = "pllb", // PLLB Clock, used for USB functions
107 .pmc_mask = PMC_IER_LOCKB,
108 .set_mode = &at91_pmc_set_pllb_mode,
111 static struct at91_pmc_clock udpck = {
114 .pmc_mask = PMC_SCER_UDP,
115 .set_mode = at91_pmc_set_sys_mode
118 static struct at91_pmc_clock uhpck = {
121 .pmc_mask = PMC_SCER_UHP,
122 .set_mode = at91_pmc_set_sys_mode
125 static struct at91_pmc_clock mck = {
126 .name = "mck", // Master (Peripheral) Clock
127 .pmc_mask = PMC_IER_MCKRDY,
131 static struct at91_pmc_clock cpu = {
132 .name = "cpu", // CPU Clock
134 .pmc_mask = PMC_SCER_PCK,
138 /* "+32" or the automatic peripheral clocks */
139 static struct at91_pmc_clock *clock_list[16+32] = {
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
159 #define MAINF_TBL_LEN (sizeof(at91_mainf_tbl) / sizeof(*at91_mainf_tbl))
162 static inline uint32_t
163 RD4(struct at91_pmc_softc *sc, bus_size_t off)
166 return (bus_read_4(sc->mem_res, off));
170 WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
173 bus_write_4(sc->mem_res, off, val);
177 at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
179 struct at91_pmc_softc *sc = pmc_softc;
184 value = sc->pllb_init;
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)
196 WR4(sc, CKGR_PLLBR, value);
197 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
202 at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
204 struct at91_pmc_softc *sc = pmc_softc;
206 WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
208 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
211 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
216 at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
218 struct at91_pmc_softc *sc = pmc_softc;
220 WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
222 while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
225 while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
229 struct at91_pmc_clock *
230 at91_pmc_clock_add(const char *name, uint32_t irq,
231 struct at91_pmc_clock *parent)
233 struct at91_pmc_clock *clk;
236 clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
240 buflen = strlen(name) + 1;
241 clk->name = malloc(buflen, M_PMC, M_NOWAIT);
242 if (clk->name == NULL)
245 strlcpy(clk->name, name, buflen);
246 clk->pmc_mask = 1 << irq;
247 clk->set_mode = &at91_pmc_set_periph_mode;
251 clk->parent = parent;
253 for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
254 if (clock_list[i] == NULL) {
261 if (clk->name != NULL)
262 free(clk->name, M_PMC);
266 panic("could not allocate pmc clock '%s'", name);
271 at91_pmc_clock_alias(const char *name, const char *alias)
273 struct at91_pmc_clock *clk, *alias_clk;
275 clk = at91_pmc_clock_ref(name);
277 alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
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;
286 struct at91_pmc_clock *
287 at91_pmc_clock_ref(const char *name)
291 for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
292 if (clock_list[i] == NULL)
294 if (strcmp(name, clock_list[i]->name) == 0)
295 return (clock_list[i]);
298 //printf("at91_pmc: Warning - did not find clock '%s'", name);
303 at91_pmc_clock_deref(struct at91_pmc_clock *clk)
309 at91_pmc_clock_enable(struct at91_pmc_clock *clk)
312 /* XXX LOCKING? XXX */
314 at91_pmc_clock_enable(clk->parent);
315 if (clk->refcnt++ == 0 && clk->set_mode)
316 clk->set_mode(clk, 1);
320 at91_pmc_clock_disable(struct at91_pmc_clock *clk)
323 /* XXX LOCKING? XXX */
324 if (--clk->refcnt == 0 && clk->set_mode)
325 clk->set_mode(clk, 0);
327 at91_pmc_clock_disable(clk->parent);
331 at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
333 uint32_t mul, div, freq;
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;
340 printf("pll = (%d / %d) * %d = %d\n",
341 freq, div, mul + 1, (freq/div) * (mul+1));
344 if (div != 0 && mul != 0) {
355 at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
357 uint32_t i, div = 0, mul = 0, diff = 1 << 30;
359 unsigned ret = 0x3e00;
361 if (out_freq > clk->pll_max_out)
364 for (i = 1; i < 256; i++) {
366 uint32_t input, mul1;
368 input = clk->parent->hz / i;
369 if (input < clk->pll_min_in)
371 if (input > clk->pll_max_in)
374 mul1 = out_freq / input;
375 if (mul1 > (clk->pll_mul_mask + 1))
380 diff1 = out_freq - input * mul1;
391 if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
394 if (clk->set_outb != NULL)
395 ret |= clk->set_outb(out_freq);
398 ((mul - 1) << clk->pll_mul_shift) |
399 (div << clk->pll_div_shift));
405 at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
410 if (at91_is_sam9() || at91_is_sam9xe()) {
411 uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
412 udpck.pmc_mask = PMC_SCER_UDP_SAM9;
414 mckr = RD4(sc, PMC_MCKR);
415 sc->main_clock_hz = main_clock;
416 main_ck.hz = main_clock;
418 at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
420 if (at91_cpu_is(AT91_CPU_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
424 * Initialize the usb clock. This sets up pllb, but disables the
427 sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
428 at91_pmc_pll_rate(&pllb, sc->pllb_init);
431 /* Turn off USB clocks */
432 at91_pmc_set_periph_mode(&ohci_clk, 0);
433 at91_pmc_set_periph_mode(&udc_clk, 0);
436 if (at91_is_rm92()) {
437 WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
438 WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
440 WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
441 WR4(sc, CKGR_PLLBR, 0);
444 * MCK and PCU derive from one of the primary clocks. Initialize
447 mck.parent = clock_list[mckr & 0x3];
448 mck.parent->refcnt++;
450 cpu.hz = mck.hz = mck.parent->hz /
451 (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
453 mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
454 if (at91_is_sam9() || at91_is_sam9xe()) {
458 mck.hz /= (1 + mdiv);
460 /* Only found on SAM9G20 */
461 if (at91_cpu_is(AT91_CPU_SAM9G20))
462 cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
464 at91_master_clock = mck.hz;
466 device_printf(sc->dev,
467 "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
470 cpu.hz / 1000000, mck.hz / 1000000);
472 /* Turn off "Progamable" clocks */
473 WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
476 /* XXX kludge, turn on all peripherals */
477 WR4(sc, PMC_PCER, 0xffffffff);
479 /* Disable all interrupts for PMC */
480 WR4(sc, PMC_IDR, 0xffffffff);
484 at91_pmc_deactivate(device_t dev)
486 struct at91_pmc_softc *sc;
488 sc = device_get_softc(dev);
489 bus_generic_detach(sc->dev);
491 bus_release_resource(dev, SYS_RES_IOPORT,
492 rman_get_rid(sc->mem_res), sc->mem_res);
497 at91_pmc_activate(device_t dev)
499 struct at91_pmc_softc *sc;
502 sc = device_get_softc(dev);
504 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
506 if (sc->mem_res == NULL)
510 at91_pmc_deactivate(dev);
515 at91_pmc_probe(device_t dev)
518 device_set_desc(dev, "PMC");
522 #if !defined(AT91C_MAIN_CLOCK)
524 at91_pmc_sense_mainf(struct at91_pmc_softc *sc)
526 unsigned int ckgr_val;
527 unsigned int diff, matchdiff;
530 ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
533 * Try to find the standard frequency that match best.
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) {
544 return (at91_mainf_tbl[match]);
549 at91_pmc_attach(device_t dev)
554 pmc_softc = device_get_softc(dev);
555 pmc_softc->dev = dev;
556 if ((err = at91_pmc_activate(dev)) != 0)
560 * Configure main clock frequency.
562 #if !defined(AT91C_MAIN_CLOCK)
563 mainf = at91_pmc_sense_mainf(pmc_softc);
565 mainf = AT91C_MAIN_CLOCK;
567 at91_pmc_init_clock(pmc_softc, mainf);
569 /* These clocks refrenced by "special" names */
570 at91_pmc_clock_alias("ohci0", "ohci_clk");
571 at91_pmc_clock_alias("udp0", "udp_clk");
576 static device_method_t at91_pmc_methods[] = {
577 DEVMETHOD(device_probe, at91_pmc_probe),
578 DEVMETHOD(device_attach, at91_pmc_attach),
582 static driver_t at91_pmc_driver = {
585 sizeof(struct at91_pmc_softc),
587 static devclass_t at91_pmc_devclass;
589 DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, NULL,