2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.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/at91rm92reg.h>
49 #include <arm/at91/at91_pmcreg.h>
50 #include <arm/at91/at91_pmcvar.h>
52 static struct at91_pmc_softc {
53 bus_space_tag_t sc_st;
54 bus_space_handle_t sc_sh;
55 struct resource *mem_res; /* Memory resource */
57 unsigned int main_clock_hz;
61 static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
62 static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
63 static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
65 static struct at91_pmc_clock slck = {
66 .name = "slck", // 32,768 Hz slow clock
73 static struct at91_pmc_clock main_ck = {
74 .name = "main", // Main clock
78 .pmc_mask = PMC_IER_MOSCS,
81 static struct at91_pmc_clock plla = {
82 .name = "plla", // PLLA Clock, used for CPU clocking
88 .pmc_mask = PMC_IER_LOCKA,
91 static struct at91_pmc_clock pllb = {
92 .name = "pllb", // PLLB Clock, used for USB functions
98 .pmc_mask = PMC_IER_LOCKB,
99 .set_mode = &at91_pmc_set_pllb_mode,
102 static struct at91_pmc_clock udpck = {
105 .pmc_mask = PMC_SCER_UDP,
106 .set_mode = at91_pmc_set_sys_mode
109 static struct at91_pmc_clock uhpck = {
112 .pmc_mask = PMC_SCER_UHP,
113 .set_mode = at91_pmc_set_sys_mode
116 static struct at91_pmc_clock mck = {
118 .pmc_mask = PMC_IER_MCKRDY,
122 static struct at91_pmc_clock udc_clk = {
125 .pmc_mask = 1 << AT91RM92_IRQ_UDP,
126 .set_mode = &at91_pmc_set_periph_mode
129 static struct at91_pmc_clock ohci_clk = {
132 .pmc_mask = 1 << AT91RM92_IRQ_UHP,
133 .set_mode = &at91_pmc_set_periph_mode
136 static struct at91_pmc_clock *const clock_list[] = {
148 #if !defined(AT91C_MAIN_CLOCK)
149 static const unsigned int at91_mainf_tbl[] = {
150 3000000, 3276800, 3686400, 3840000, 4000000,
151 4433619, 4915200, 5000000, 5242880, 6000000,
152 6144000, 6400000, 6553600, 7159090, 7372800,
153 7864320, 8000000, 9830400, 10000000, 11059200,
154 12000000, 12288000, 13560000, 14318180, 14745600,
155 16000000, 17344700, 18432000, 20000000
157 #define MAINF_TBL_LEN (sizeof(at91_mainf_tbl) / sizeof(*at91_mainf_tbl))
160 static inline uint32_t
161 RD4(struct at91_pmc_softc *sc, bus_size_t off)
163 return bus_read_4(sc->mem_res, off);
167 WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
169 bus_write_4(sc->mem_res, off, val);
173 at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
175 struct at91_pmc_softc *sc = pmc_softc;
180 value = sc->pllb_init;
184 WR4(sc, CKGR_PLLBR, value);
185 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
190 at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
192 struct at91_pmc_softc *sc = pmc_softc;
194 WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
196 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
199 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
204 at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
206 struct at91_pmc_softc *sc = pmc_softc;
208 WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
210 while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
213 while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
217 struct at91_pmc_clock *
218 at91_pmc_clock_ref(const char *name)
222 for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++)
223 if (strcmp(name, clock_list[i]->name) == 0)
224 return (clock_list[i]);
230 at91_pmc_clock_deref(struct at91_pmc_clock *clk)
235 at91_pmc_clock_enable(struct at91_pmc_clock *clk)
237 /* XXX LOCKING? XXX */
239 at91_pmc_clock_enable(clk->parent);
240 if (clk->refcnt++ == 0 && clk->set_mode)
241 clk->set_mode(clk, 1);
245 at91_pmc_clock_disable(struct at91_pmc_clock *clk)
247 /* XXX LOCKING? XXX */
248 if (--clk->refcnt == 0 && clk->set_mode)
249 clk->set_mode(clk, 0);
251 at91_pmc_clock_disable(clk->parent);
255 at91_pmc_pll_rate(int freq, uint32_t reg, int is_pllb)
260 mul = (reg >> 16) & 0x7ff;
261 if (div != 0 && mul != 0) {
267 if (is_pllb && (reg & (1 << 28)))
273 at91_pmc_pll_calc(uint32_t main_freq, uint32_t out_freq)
275 uint32_t i, div = 0, mul = 0, diff = 1 << 30;
276 unsigned ret = (out_freq > PMC_PLL_FAST_THRESH) ? 0xbe00 : 0x3e00;
278 if (out_freq > PMC_PLL_MAX_OUT_FREQ)
281 for (i = 1; i < 256; i++) {
283 uint32_t input, mul1;
285 input = main_freq / i;
286 if (input < PMC_PLL_MIN_IN_FREQ)
288 if (input > PMC_PLL_MAX_IN_FREQ)
291 mul1 = out_freq / input;
292 if (mul1 > PMC_PLL_MULT_MAX)
294 if (mul1 < PMC_PLL_MULT_MIN)
297 diff1 = out_freq - input * mul1;
308 if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
310 return ret | ((mul - 1) << 16) | div;
316 at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
321 sc->main_clock_hz = main_clock;
322 main_ck.hz = main_clock;
323 plla.hz = at91_pmc_pll_rate(main_clock, RD4(sc, CKGR_PLLAR), 0);
326 * Initialize the usb clock. This sets up pllb, but disables the
329 sc->pllb_init = at91_pmc_pll_calc(main_clock, 48000000 * 2) |0x10000000;
330 pllb.hz = at91_pmc_pll_rate(main_clock, sc->pllb_init, 1);
331 WR4(sc, PMC_PCDR, (1 << AT91RM92_IRQ_UHP) | (1 << AT91RM92_IRQ_UDP));
332 WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
333 WR4(sc, CKGR_PLLBR, 0);
334 WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
337 * MCK and PCU derive from one of the primary clocks. Initialize
340 mckr = RD4(sc, PMC_MCKR);
341 mck.parent = clock_list[mckr & 0x3];
342 mck.parent->refcnt++;
343 freq = mck.parent->hz / (1 << ((mckr >> 2) & 3));
344 mck.hz = freq / (1 + ((mckr >> 8) & 3));
346 device_printf(sc->dev,
347 "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
349 at91_pmc_pll_rate(main_clock, RD4(sc, CKGR_PLLAR), 0) / 1000000,
350 freq / 1000000, mck.hz / 1000000);
351 WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
353 /* XXX kludge, turn on all peripherals */
354 WR4(sc, PMC_PCER, 0xffffffff);
355 /* Disable all interrupts for PMC */
356 WR4(sc, PMC_IDR, 0xffffffff);
360 at91_pmc_deactivate(device_t dev)
362 struct at91_pmc_softc *sc;
364 sc = device_get_softc(dev);
365 bus_generic_detach(sc->dev);
367 bus_release_resource(dev, SYS_RES_IOPORT,
368 rman_get_rid(sc->mem_res), sc->mem_res);
374 at91_pmc_activate(device_t dev)
376 struct at91_pmc_softc *sc;
379 sc = device_get_softc(dev);
381 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
383 if (sc->mem_res == NULL)
387 at91_pmc_deactivate(dev);
392 at91_pmc_probe(device_t dev)
395 device_set_desc(dev, "PMC");
399 #if !defined(AT91C_MAIN_CLOCK)
401 at91_pmc_sense_mainf(struct at91_pmc_softc *sc)
403 unsigned int ckgr_val;
404 unsigned int diff, matchdiff;
407 ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
410 * Try to find the standard frequency that match best.
413 matchdiff = abs(ckgr_val - at91_mainf_tbl[0]);
414 for (i = 1; i < MAINF_TBL_LEN; i++) {
415 diff = abs(ckgr_val - at91_mainf_tbl[i]);
416 if (diff < matchdiff) {
421 return (at91_mainf_tbl[match]);
426 at91_pmc_attach(device_t dev)
431 pmc_softc = device_get_softc(dev);
432 pmc_softc->dev = dev;
433 if ((err = at91_pmc_activate(dev)) != 0)
437 * Configure main clock frequency.
439 #if !defined(AT91C_MAIN_CLOCK)
440 mainf = at91_pmc_sense_mainf(pmc_softc);
442 mainf = AT91C_MAIN_CLOCK;
444 at91_pmc_init_clock(pmc_softc, mainf);
448 static device_method_t at91_pmc_methods[] = {
449 DEVMETHOD(device_probe, at91_pmc_probe),
450 DEVMETHOD(device_attach, at91_pmc_attach),
454 static driver_t at91_pmc_driver = {
457 sizeof(struct at91_pmc_softc),
459 static devclass_t at91_pmc_devclass;
461 DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, 0, 0);