Deleted Added
full compact
at91_pmc.c (236658) at91_pmc.c (238788)
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

--- 11 unchanged lines hidden (view full) ---

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 <sys/cdefs.h>
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

--- 11 unchanged lines hidden (view full) ---

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 <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/arm/at91/at91_pmc.c 236658 2012-06-06 06:19:52Z imp $");
28__FBSDID("$FreeBSD: head/sys/arm/at91/at91_pmc.c 238788 2012-07-26 08:01:25Z andrew $");
29
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>
35#include <sys/time.h>
36#include <sys/bus.h>

--- 23 unchanged lines hidden (view full) ---

60static uint32_t pllb_init;
61
62MALLOC_DECLARE(M_PMC);
63MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
64
65#define AT91_PMC_BASE 0xffffc00
66
67static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
29
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>
35#include <sys/time.h>
36#include <sys/bus.h>

--- 23 unchanged lines hidden (view full) ---

60static uint32_t pllb_init;
61
62MALLOC_DECLARE(M_PMC);
63MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
64
65#define AT91_PMC_BASE 0xffffc00
66
67static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
68static void at91_pmc_set_upll_mode(struct at91_pmc_clock *, int);
68static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
69static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
70static void at91_pmc_clock_alias(const char *name, const char *alias);
71
72static struct at91_pmc_clock slck = {
73 .name = "slck", // 32,768 Hz slow clock
74 .hz = 32768,
75 .refcnt = 1,

--- 29 unchanged lines hidden (view full) ---

105 .refcnt = 0,
106 .id = 0,
107 .primary = 1,
108 .pll = 1,
109 .pmc_mask = PMC_IER_LOCKB,
110 .set_mode = &at91_pmc_set_pllb_mode,
111};
112
69static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
70static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
71static void at91_pmc_clock_alias(const char *name, const char *alias);
72
73static struct at91_pmc_clock slck = {
74 .name = "slck", // 32,768 Hz slow clock
75 .hz = 32768,
76 .refcnt = 1,

--- 29 unchanged lines hidden (view full) ---

106 .refcnt = 0,
107 .id = 0,
108 .primary = 1,
109 .pll = 1,
110 .pmc_mask = PMC_IER_LOCKB,
111 .set_mode = &at91_pmc_set_pllb_mode,
112};
113
114/* Used by USB on at91sam9g45 */
115static struct at91_pmc_clock upll = {
116 .name = "upll", // UTMI PLL, used for USB functions on 9G45
117 .parent = &main_ck,
118 .refcnt = 0,
119 .id = 0,
120 .primary = 1,
121 .pll = 1,
122 .pmc_mask = (1 << 6),
123 .set_mode = &at91_pmc_set_upll_mode,
124};
125
113static struct at91_pmc_clock udpck = {
114 .name = "udpck",
115 .parent = &pllb,
116 .pmc_mask = PMC_SCER_UDP,
117 .set_mode = at91_pmc_set_sys_mode
118};
119
120static struct at91_pmc_clock uhpck = {

--- 17 unchanged lines hidden (view full) ---

138};
139
140/* "+32" or the automatic peripheral clocks */
141static struct at91_pmc_clock *clock_list[16+32] = {
142 &slck,
143 &main_ck,
144 &plla,
145 &pllb,
126static struct at91_pmc_clock udpck = {
127 .name = "udpck",
128 .parent = &pllb,
129 .pmc_mask = PMC_SCER_UDP,
130 .set_mode = at91_pmc_set_sys_mode
131};
132
133static struct at91_pmc_clock uhpck = {

--- 17 unchanged lines hidden (view full) ---

151};
152
153/* "+32" or the automatic peripheral clocks */
154static struct at91_pmc_clock *clock_list[16+32] = {
155 &slck,
156 &main_ck,
157 &plla,
158 &pllb,
159 &upll,
146 &udpck,
147 &uhpck,
148 &mck,
149 &cpu
150};
151
152static inline uint32_t
153RD4(struct at91_pmc_softc *sc, bus_size_t off)

--- 40 unchanged lines hidden (view full) ---

194 }
195
196 WR4(sc, CKGR_PLLBR, value);
197 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
198 continue;
199}
200
201static void
160 &udpck,
161 &uhpck,
162 &mck,
163 &cpu
164};
165
166static inline uint32_t
167RD4(struct at91_pmc_softc *sc, bus_size_t off)

--- 40 unchanged lines hidden (view full) ---

208 }
209
210 WR4(sc, CKGR_PLLBR, value);
211 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
212 continue;
213}
214
215static void
216at91_pmc_set_upll_mode(struct at91_pmc_clock *clk, int on)
217{
218 struct at91_pmc_softc *sc = pmc_softc;
219 uint32_t value;
220
221 if (on) {
222 on = PMC_IER_LOCKU;
223 value = CKGR_UCKR_UPLLEN | CKGR_UCKR_BIASEN;
224 } else
225 value = 0;
226
227 WR4(sc, CKGR_UCKR, RD4(sc, CKGR_UCKR) | value);
228 while ((RD4(sc, PMC_SR) & PMC_IER_LOCKU) != on)
229 continue;
230
231 WR4(sc, PMC_USB, PMC_USB_USBDIV(9) | PMC_USB_USBS);
232 WR4(sc, PMC_SCER, PMC_SCER_UHP_SAM9);
233}
234
235static void
202at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
203{
204 struct at91_pmc_softc *sc = pmc_softc;
205
206 WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
207 if (on)
208 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
209 continue;

--- 251 unchanged lines hidden (view full) ---

461 uint32_t mdiv;
462
463 main_clock = at91_pmc_sense_main_clock();
464
465 if (at91_is_sam9() || at91_is_sam9xe()) {
466 uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
467 udpck.pmc_mask = PMC_SCER_UDP_SAM9;
468 }
236at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
237{
238 struct at91_pmc_softc *sc = pmc_softc;
239
240 WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
241 if (on)
242 while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
243 continue;

--- 251 unchanged lines hidden (view full) ---

495 uint32_t mdiv;
496
497 main_clock = at91_pmc_sense_main_clock();
498
499 if (at91_is_sam9() || at91_is_sam9xe()) {
500 uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
501 udpck.pmc_mask = PMC_SCER_UDP_SAM9;
502 }
503 /* There is no pllb on AT91SAM9G45 */
504 if (at91_cpu_is(AT91_T_SAM9G45)) {
505 uhpck.parent = &upll;
506 uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
507 }
508
469 mckr = RD4(sc, PMC_MCKR);
470 main_ck.hz = main_clock;
471
472 at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
473
474 if (at91_cpu_is(AT91_T_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
475 plla.hz /= 2;
476

--- 24 unchanged lines hidden (view full) ---

501 mck.parent = clock_list[mckr & 0x3];
502 mck.parent->refcnt++;
503
504 cpu.hz = mck.hz = mck.parent->hz /
505 (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
506
507 mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
508 if (at91_is_sam9() || at91_is_sam9xe()) {
509 mckr = RD4(sc, PMC_MCKR);
510 main_ck.hz = main_clock;
511
512 at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
513
514 if (at91_cpu_is(AT91_T_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
515 plla.hz /= 2;
516

--- 24 unchanged lines hidden (view full) ---

541 mck.parent = clock_list[mckr & 0x3];
542 mck.parent->refcnt++;
543
544 cpu.hz = mck.hz = mck.parent->hz /
545 (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
546
547 mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
548 if (at91_is_sam9() || at91_is_sam9xe()) {
549 /*
550 * On AT91SAM9G45 when mdiv == 3 we need to divide
551 * MCK by 3 but not, for example, on 9g20.
552 */
553 if (!at91_cpu_is(AT91_T_SAM9G45) || mdiv <= 2)
554 mdiv *= 2;
509 if (mdiv > 0)
555 if (mdiv > 0)
510 mck.hz /= mdiv * 2;
556 mck.hz /= mdiv;
511 } else
512 mck.hz /= (1 + mdiv);
513
514 /* Only found on SAM9G20 */
515 if (at91_cpu_is(AT91_T_SAM9G20))
516 cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
517
518 at91_master_clock = mck.hz;

--- 97 unchanged lines hidden ---
557 } else
558 mck.hz /= (1 + mdiv);
559
560 /* Only found on SAM9G20 */
561 if (at91_cpu_is(AT91_T_SAM9G20))
562 cpu.hz /= (mckr & PMC_MCKR_PDIV) ? 2 : 1;
563
564 at91_master_clock = mck.hz;

--- 97 unchanged lines hidden ---