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)
165 return (bus_read_4(sc->mem_res, off));
169 WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
171 bus_write_4(sc->mem_res, off, val);
175 at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
177 struct at91_pmc_softc *sc = pmc_softc;
182 value = sc->pllb_init;
187 /* Workaround RM9200 Errata #26 */
188 if (at91_is_rm92() &&
189 ((value ^ RD4(sc, CKGR_PLLBR)) & 0x03f0ff) != 0) {
190 WR4(sc, CKGR_PLLBR, value ^ 1);
191 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
195 WR4(sc, CKGR_PLLBR, value);
196 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
201 at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
203 struct at91_pmc_softc *sc = pmc_softc;
205 WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
207 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
210 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
215 at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
217 struct at91_pmc_softc *sc = pmc_softc;
219 WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
221 while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
224 while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
228 struct at91_pmc_clock *
229 at91_pmc_clock_add(const char *name, uint32_t irq, struct at91_pmc_clock *parent)
231 struct at91_pmc_clock *clk;
234 clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
238 buflen = strlen(name) + 1;
239 clk->name = malloc(buflen, M_PMC, M_NOWAIT);
240 if (clk->name == NULL)
243 strlcpy(clk->name, name, buflen);
244 clk->pmc_mask = 1 << irq;
245 clk->set_mode = &at91_pmc_set_periph_mode;
249 clk->parent = parent;
251 for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
252 if (clock_list[i] == NULL) {
259 if (clk->name != NULL)
260 free(clk->name, M_PMC);
264 panic("could not allocate pmc clock '%s'", name);
269 at91_pmc_clock_alias(const char *name, const char *alias)
271 struct at91_pmc_clock *clk, *alias_clk;
273 clk = at91_pmc_clock_ref(name);
275 alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
277 if (clk && alias_clk) {
278 alias_clk->hz = clk->hz;
279 alias_clk->pmc_mask = clk->pmc_mask;
280 alias_clk->set_mode = clk->set_mode;
284 struct at91_pmc_clock *
285 at91_pmc_clock_ref(const char *name)
289 for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
290 if (clock_list[i] == NULL)
292 if (strcmp(name, clock_list[i]->name) == 0)
293 return (clock_list[i]);
296 //printf("at91_pmc: Warning - did not find clock '%s'", name);
301 at91_pmc_clock_deref(struct at91_pmc_clock *clk)
306 at91_pmc_clock_enable(struct at91_pmc_clock *clk)
308 /* XXX LOCKING? XXX */
310 at91_pmc_clock_enable(clk->parent);
311 if (clk->refcnt++ == 0 && clk->set_mode)
312 clk->set_mode(clk, 1);
316 at91_pmc_clock_disable(struct at91_pmc_clock *clk)
318 /* XXX LOCKING? XXX */
319 if (--clk->refcnt == 0 && clk->set_mode)
320 clk->set_mode(clk, 0);
322 at91_pmc_clock_disable(clk->parent);
326 at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
328 uint32_t mul, div, freq;
330 freq = clk->parent->hz;
331 div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
332 mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
334 // printf("pll = (%d / %d) * %d = %d\n",
335 // freq, div ,mul + 1, (freq/div) * (mul+1));
337 if (div != 0 && mul != 0) {
350 at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
352 uint32_t i, div = 0, mul = 0, diff = 1 << 30;
354 unsigned ret = 0x3e00;
356 if (out_freq > clk->pll_max_out)
359 for (i = 1; i < 256; i++) {
361 uint32_t input, mul1;
363 input = clk->parent->hz / i;
364 if (input < clk->pll_min_in)
366 if (input > clk->pll_max_in)
369 mul1 = out_freq / input;
370 if (mul1 > (clk->pll_mul_mask + 1))
375 diff1 = out_freq - input * mul1;
386 if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
389 if (clk->set_outb != NULL)
390 ret |= clk->set_outb(out_freq);
393 ((mul - 1) << clk->pll_mul_shift) |
394 (div << clk->pll_div_shift));
400 at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
405 if (at91_is_sam9()) {
406 uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
407 udpck.pmc_mask = PMC_SCER_UDP_SAM9;
409 mckr = RD4(sc, PMC_MCKR);
410 sc->main_clock_hz = main_clock;
411 main_ck.hz = main_clock;
413 at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
415 if (at91_cpu_is(AT91_CPU_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
419 * Initialize the usb clock. This sets up pllb, but disables the
422 sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
423 at91_pmc_pll_rate(&pllb, sc->pllb_init);
426 /* Turn off USB clocks */
427 at91_pmc_set_periph_mode(&ohci_clk, 0);
428 at91_pmc_set_periph_mode(&udc_clk, 0);
431 if (at91_is_rm92()) {
432 WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
433 WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
435 WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
437 WR4(sc, CKGR_PLLBR, 0);
440 * MCK and PCU derive from one of the primary clocks. Initialize
443 mck.parent = clock_list[mckr & 0x3];
444 mck.parent->refcnt++;
447 mck.hz = mck.parent->hz /
448 (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
450 mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
451 if (at91_is_sam9()) {
455 mck.hz /= (1 + mdiv);
457 /* Only found on SAM9G20 */
458 if (at91_cpu_is(AT91_CPU_SAM9G20))
459 cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
461 at91_master_clock = mck.hz;
463 device_printf(sc->dev,
464 "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
467 cpu.hz / 1000000, mck.hz / 1000000);
469 /* Turn off "Progamable" clocks */
470 WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
473 /* XXX kludge, turn on all peripherals */
474 WR4(sc, PMC_PCER, 0xffffffff);
476 /* Disable all interrupts for PMC */
477 WR4(sc, PMC_IDR, 0xffffffff);
481 at91_pmc_deactivate(device_t dev)
483 struct at91_pmc_softc *sc;
485 sc = device_get_softc(dev);
486 bus_generic_detach(sc->dev);
488 bus_release_resource(dev, SYS_RES_IOPORT,
489 rman_get_rid(sc->mem_res), sc->mem_res);
495 at91_pmc_activate(device_t dev)
497 struct at91_pmc_softc *sc;
500 sc = device_get_softc(dev);
502 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
504 if (sc->mem_res == NULL)
508 at91_pmc_deactivate(dev);
513 at91_pmc_probe(device_t dev)
516 device_set_desc(dev, "PMC");
520 #if !defined(AT91C_MAIN_CLOCK)
522 at91_pmc_sense_mainf(struct at91_pmc_softc *sc)
524 unsigned int ckgr_val;
525 unsigned int diff, matchdiff;
528 ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
531 * Try to find the standard frequency that match best.
534 matchdiff = abs(ckgr_val - at91_mainf_tbl[0]);
535 for (i = 1; i < MAINF_TBL_LEN; i++) {
536 diff = abs(ckgr_val - at91_mainf_tbl[i]);
537 if (diff < matchdiff) {
542 return (at91_mainf_tbl[match]);
547 at91_pmc_attach(device_t dev)
552 pmc_softc = device_get_softc(dev);
553 pmc_softc->dev = dev;
554 if ((err = at91_pmc_activate(dev)) != 0)
558 * Configure main clock frequency.
560 #if !defined(AT91C_MAIN_CLOCK)
561 mainf = at91_pmc_sense_mainf(pmc_softc);
563 mainf = AT91C_MAIN_CLOCK;
565 at91_pmc_init_clock(pmc_softc, mainf);
567 /* These clocks refrenced by "special" names */
568 at91_pmc_clock_alias("ohci0", "ohci_clk");
569 at91_pmc_clock_alias("udp0", "udp_clk");
574 static device_method_t at91_pmc_methods[] = {
575 DEVMETHOD(device_probe, at91_pmc_probe),
576 DEVMETHOD(device_attach, at91_pmc_attach),
580 static driver_t at91_pmc_driver = {
583 sizeof(struct at91_pmc_softc),
585 static devclass_t at91_pmc_devclass;
587 DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, 0, 0);