]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/arm/at91/at91_pmc.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / arm / at91 / at91_pmc.c
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
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
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
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
225 at91_pmc_800mhz_pllb_outb(int freq)
226 {
227
228         return (0);
229 }
230
231 void
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
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
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
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 *
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
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 *
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
372 at91_pmc_clock_deref(struct at91_pmc_clock *clk)
373 {
374         if (clk == NULL)
375                 return;
376 }
377
378 void
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
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
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
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
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
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
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
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
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
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