initial commit, pull in sys/arch/armv7/omap
[bbb-pru.git] / prcm.c
CommitLineData
cf3c20ae 1/* $OpenBSD: prcm.c,v 1.9 2014/05/08 21:17:01 miod Exp $ */
2/*
3 * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*-
19 * Copyright (c) 2011
20 * Ben Gray <ben.r.gray@gmail.com>.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. The name of the company nor the name of the author may be used to
32 * endorse or promote products derived from this software without specific
33 * prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
36 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
38 * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
41 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
43 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
44 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 */
46
47/*
48 * Driver for the Power, Reset and Clock Management Module (PRCM).
49 */
50
51#include <sys/types.h>
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/kernel.h>
55#include <sys/time.h>
56#include <sys/device.h>
57
58#include <machine/bus.h>
59#include <machine/intr.h>
60#include <arm/cpufunc.h>
61#include <armv7/armv7/armv7var.h>
62#include <armv7/omap/prcmvar.h>
63
64#include <armv7/omap/am335x_prcmreg.h>
65#include <armv7/omap/omap3_prcmreg.h>
66#include <armv7/omap/omap4_prcmreg.h>
67
68#define PRCM_REVISION 0x0800
69#define PRCM_SYSCONFIG 0x0810
70
71uint32_t prcm_imask_mask[PRCM_REG_MAX];
72uint32_t prcm_fmask_mask[PRCM_REG_MAX];
73uint32_t prcm_imask_addr[PRCM_REG_MAX];
74uint32_t prcm_fmask_addr[PRCM_REG_MAX];
75
76#define SYS_CLK 13 /* SYS_CLK speed in MHz */
77
78struct prcm_softc {
79 struct device sc_dev;
80 bus_space_tag_t sc_iot;
81 bus_space_handle_t sc_prcm;
82 bus_space_handle_t sc_cm1;
83 bus_space_handle_t sc_cm2;
84 void (*sc_setup)(struct prcm_softc *sc);
85 void (*sc_enablemodule)(struct prcm_softc *sc, int mod);
86 void (*sc_setclock)(struct prcm_softc *sc,
87 int clock, int speed);
88 uint32_t cm1_avail;
89 uint32_t cm2_avail;
90};
91
92int prcm_match(struct device *, void *, void *);
93void prcm_attach(struct device *, struct device *, void *);
94int prcm_setup_dpll5(struct prcm_softc *);
95uint32_t prcm_v3_bit(int mod);
96uint32_t prcm_am335x_clkctrl(int mod);
97
98void prcm_am335x_enablemodule(struct prcm_softc *, int);
99void prcm_am335x_setclock(struct prcm_softc *, int, int);
100
101void prcm_v3_setup(struct prcm_softc *);
102void prcm_v3_enablemodule(struct prcm_softc *, int);
103void prcm_v3_setclock(struct prcm_softc *, int, int);
104
105void prcm_v4_enablemodule(struct prcm_softc *, int);
106int prcm_v4_hsusbhost_activate(int);
107int prcm_v4_hsusbhost_set_source(int, int);
108
109struct cfattach prcm_ca = {
110 sizeof (struct prcm_softc), NULL, prcm_attach
111};
112
113struct cfdriver prcm_cd = {
114 NULL, "prcm", DV_DULL
115};
116
117void
118prcm_attach(struct device *parent, struct device *self, void *args)
119{
120 struct armv7_attach_args *aa = args;
121 struct prcm_softc *sc = (struct prcm_softc *) self;
122 u_int32_t reg;
123
124 sc->sc_iot = aa->aa_iot;
125
126 switch (board_id) {
127 case BOARD_ID_AM335X_BEAGLEBONE:
128 sc->sc_setup = NULL;
129 sc->sc_enablemodule = prcm_am335x_enablemodule;
130 sc->sc_setclock = prcm_am335x_setclock;
131 break;
132 case BOARD_ID_OMAP3_BEAGLE:
133 case BOARD_ID_OMAP3_OVERO:
134 sc->sc_setup = prcm_v3_setup;
135 sc->sc_enablemodule = prcm_v3_enablemodule;
136 sc->sc_setclock = prcm_v3_setclock;
137 break;
138 case BOARD_ID_OMAP4_PANDA:
139 sc->sc_setup = NULL;
140 sc->sc_enablemodule = prcm_v4_enablemodule;
141 sc->sc_setclock = NULL;
142 sc->cm1_avail = 1;
143 sc->cm2_avail = 1;
144 break;
145 }
146
147 if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
148 aa->aa_dev->mem[0].size, 0, &sc->sc_prcm))
149 panic("prcm_attach: bus_space_map failed!");
150
151 if (sc->cm1_avail &&
152 bus_space_map(sc->sc_iot, aa->aa_dev->mem[1].addr,
153 aa->aa_dev->mem[1].size, 0, &sc->sc_cm1))
154 panic("prcm_attach: bus_space_map failed!");
155
156 if (sc->cm2_avail &&
157 bus_space_map(sc->sc_iot, aa->aa_dev->mem[2].addr,
158 aa->aa_dev->mem[2].size, 0, &sc->sc_cm2))
159 panic("prcm_attach: bus_space_map failed!");
160
161 reg = bus_space_read_4(sc->sc_iot, sc->sc_prcm, PRCM_REVISION);
162 printf(" rev %d.%d\n", reg >> 4 & 0xf, reg & 0xf);
163
164 if (sc->sc_setup != NULL)
165 sc->sc_setup(sc);
166}
167
168void
169prcm_v3_setup(struct prcm_softc *sc)
170{
171 /* Setup the 120MHZ DPLL5 clock, to be used by USB. */
172 prcm_setup_dpll5(sc);
173
174 prcm_fmask_mask[PRCM_REG_CORE_CLK1] = PRCM_REG_CORE_CLK1_FMASK;
175 prcm_imask_mask[PRCM_REG_CORE_CLK1] = PRCM_REG_CORE_CLK1_IMASK;
176 prcm_fmask_addr[PRCM_REG_CORE_CLK1] = PRCM_REG_CORE_CLK1_FADDR;
177 prcm_imask_addr[PRCM_REG_CORE_CLK1] = PRCM_REG_CORE_CLK1_IADDR;
178
179 prcm_fmask_mask[PRCM_REG_CORE_CLK2] = PRCM_REG_CORE_CLK2_FMASK;
180 prcm_imask_mask[PRCM_REG_CORE_CLK2] = PRCM_REG_CORE_CLK2_IMASK;
181 prcm_fmask_addr[PRCM_REG_CORE_CLK2] = PRCM_REG_CORE_CLK2_FADDR;
182 prcm_imask_addr[PRCM_REG_CORE_CLK2] = PRCM_REG_CORE_CLK2_IADDR;
183
184 prcm_fmask_mask[PRCM_REG_CORE_CLK3] = PRCM_REG_CORE_CLK3_FMASK;
185 prcm_imask_mask[PRCM_REG_CORE_CLK3] = PRCM_REG_CORE_CLK3_IMASK;
186 prcm_fmask_addr[PRCM_REG_CORE_CLK3] = PRCM_REG_CORE_CLK3_FADDR;
187 prcm_imask_addr[PRCM_REG_CORE_CLK3] = PRCM_REG_CORE_CLK3_IADDR;
188
189 prcm_fmask_mask[PRCM_REG_WKUP] = PRCM_REG_WKUP_FMASK;
190 prcm_imask_mask[PRCM_REG_WKUP] = PRCM_REG_WKUP_IMASK;
191 prcm_fmask_addr[PRCM_REG_WKUP] = PRCM_REG_WKUP_FADDR;
192 prcm_imask_addr[PRCM_REG_WKUP] = PRCM_REG_WKUP_IADDR;
193
194 prcm_fmask_mask[PRCM_REG_PER] = PRCM_REG_PER_FMASK;
195 prcm_imask_mask[PRCM_REG_PER] = PRCM_REG_PER_IMASK;
196 prcm_fmask_addr[PRCM_REG_PER] = PRCM_REG_PER_FADDR;
197 prcm_imask_addr[PRCM_REG_PER] = PRCM_REG_PER_IADDR;
198
199 prcm_fmask_mask[PRCM_REG_USBHOST] = PRCM_REG_USBHOST_FMASK;
200 prcm_imask_mask[PRCM_REG_USBHOST] = PRCM_REG_USBHOST_IMASK;
201 prcm_fmask_addr[PRCM_REG_USBHOST] = PRCM_REG_USBHOST_FADDR;
202 prcm_imask_addr[PRCM_REG_USBHOST] = PRCM_REG_USBHOST_IADDR;
203}
204
205void
206prcm_setclock(int clock, int speed)
207{
208 struct prcm_softc *sc = prcm_cd.cd_devs[0];
209
210 if (!sc->sc_setclock)
211 panic("%s: not initialised!", __func__);
212
213 sc->sc_setclock(sc, clock, speed);
214}
215
216void
217prcm_am335x_setclock(struct prcm_softc *sc, int clock, int speed)
218{
219 u_int32_t oreg, reg, mask;
220
221 /* set CLKSEL register */
222 if (clock == 1) {
223 oreg = bus_space_read_4(sc->sc_iot, sc->sc_prcm,
224 PRCM_AM335X_CLKSEL_TIMER2_CLK);
225 mask = 3;
226 reg = oreg & ~mask;
227 reg |=0x02;
228 bus_space_write_4(sc->sc_iot, sc->sc_prcm,
229 PRCM_AM335X_CLKSEL_TIMER2_CLK, reg);
230 } else if (clock == 2) {
231 oreg = bus_space_read_4(sc->sc_iot, sc->sc_prcm,
232 PRCM_AM335X_CLKSEL_TIMER3_CLK);
233 mask = 3;
234 reg = oreg & ~mask;
235 reg |=0x02;
236 bus_space_write_4(sc->sc_iot, sc->sc_prcm,
237 PRCM_AM335X_CLKSEL_TIMER3_CLK, reg);
238 }
239}
240
241void
242prcm_v3_setclock(struct prcm_softc *sc, int clock, int speed)
243{
244 u_int32_t oreg, reg, mask;
245
246 if (clock == 1) {
247 oreg = bus_space_read_4(sc->sc_iot, sc->sc_prcm, CM_CLKSEL_WKUP);
248 mask = 1;
249 reg = (oreg &~mask) | (speed & mask);
250 bus_space_write_4(sc->sc_iot, sc->sc_prcm, CM_CLKSEL_WKUP, reg);
251 } else if (clock >= 2 && clock <= 9) {
252 int shift = (clock-2);
253 oreg = bus_space_read_4(sc->sc_iot, sc->sc_prcm, CM_CLKSEL_PER);
254 mask = 1 << (shift);
255 reg = (oreg & ~mask) | ( (speed << shift) & mask);
256 bus_space_write_4(sc->sc_iot, sc->sc_prcm, CM_CLKSEL_PER, reg);
257 } else
258 panic("%s: invalid clock %d", __func__, clock);
259}
260
261uint32_t
262prcm_v3_bit(int mod)
263{
264 switch(mod) {
265 case PRCM_MMC0:
266 return PRCM_CLK_EN_MMC1;
267 case PRCM_MMC1:
268 return PRCM_CLK_EN_MMC2;
269 case PRCM_MMC2:
270 return PRCM_CLK_EN_MMC3;
271 case PRCM_USB:
272 return PRCM_CLK_EN_USB;
273 case PRCM_GPIO0:
274 return PRCM_CLK_EN_GPIO1;
275 case PRCM_GPIO1:
276 return PRCM_CLK_EN_GPIO2;
277 case PRCM_GPIO2:
278 return PRCM_CLK_EN_GPIO3;
279 case PRCM_GPIO3:
280 return PRCM_CLK_EN_GPIO4;
281 case PRCM_GPIO4:
282 return PRCM_CLK_EN_GPIO5;
283 case PRCM_GPIO5:
284 return PRCM_CLK_EN_GPIO6;
285 default:
286 panic("%s: module not found\n", __func__);
287 }
288}
289
290uint32_t
291prcm_am335x_clkctrl(int mod)
292{
293 switch(mod) {
294 case PRCM_TIMER2:
295 return PRCM_AM335X_TIMER2_CLKCTRL;
296 case PRCM_TIMER3:
297 return PRCM_AM335X_TIMER3_CLKCTRL;
298 case PRCM_MMC0:
299 return PRCM_AM335X_MMC0_CLKCTRL;
300 case PRCM_MMC1:
301 return PRCM_AM335X_MMC1_CLKCTRL;
302 case PRCM_MMC2:
303 return PRCM_AM335X_MMC2_CLKCTRL;
304 case PRCM_USB:
305 return PRCM_AM335X_USB0_CLKCTRL;
306 case PRCM_GPIO0:
307 return PRCM_AM335X_GPIO0_CLKCTRL;
308 case PRCM_GPIO1:
309 return PRCM_AM335X_GPIO1_CLKCTRL;
310 case PRCM_GPIO2:
311 return PRCM_AM335X_GPIO2_CLKCTRL;
312 case PRCM_GPIO3:
313 return PRCM_AM335X_GPIO3_CLKCTRL;
314 case PRCM_TPCC:
315 return PRCM_AM335X_TPCC_CLKCTRL;
316 case PRCM_TPTC0:
317 return PRCM_AM335X_TPTC0_CLKCTRL;
318 case PRCM_TPTC1:
319 return PRCM_AM335X_TPTC1_CLKCTRL;
320 case PRCM_TPTC2:
321 return PRCM_AM335X_TPTC2_CLKCTRL;
322 case PRCM_I2C0:
323 return PRCM_AM335X_I2C0_CLKCTRL;
324 case PRCM_I2C1:
325 return PRCM_AM335X_I2C1_CLKCTRL;
326 case PRCM_I2C2:
327 return PRCM_AM335X_I2C2_CLKCTRL;
328 default:
329 panic("%s: module not found\n", __func__);
330 }
331}
332
333void
334prcm_enablemodule(int mod)
335{
336 struct prcm_softc *sc = prcm_cd.cd_devs[0];
337
338 if (!sc->sc_enablemodule)
339 panic("%s: not initialised!", __func__);
340
341 sc->sc_enablemodule(sc, mod);
342}
343
344void
345prcm_am335x_enablemodule(struct prcm_softc *sc, int mod)
346{
347 uint32_t clkctrl;
348 int reg;
349
350 /*set enable bits in CLKCTRL register */
351 reg = prcm_am335x_clkctrl(mod);
352 clkctrl = bus_space_read_4(sc->sc_iot, sc->sc_prcm, reg);
353 clkctrl &=~AM335X_CLKCTRL_MODULEMODE_MASK;
354 clkctrl |= AM335X_CLKCTRL_MODULEMODE_ENABLE;
355 bus_space_write_4(sc->sc_iot, sc->sc_prcm, reg, clkctrl);
356
357 /* wait until module is enabled */
358 while (bus_space_read_4(sc->sc_iot, sc->sc_prcm, reg) & 0x30000)
359 ;
360}
361
362void
363prcm_v3_enablemodule(struct prcm_softc *sc, int mod)
364{
365 uint32_t bit;
366 uint32_t fclk, iclk, fmask, imask, mbit;
367 int freg, ireg, reg;
368
369 bit = prcm_v3_bit(mod);
370 reg = bit >> 5;
371
372 freg = prcm_fmask_addr[reg];
373 ireg = prcm_imask_addr[reg];
374 fmask = prcm_fmask_mask[reg];
375 imask = prcm_imask_mask[reg];
376
377 mbit = 1 << (bit & 0x1f);
378 if (fmask & mbit) { /* dont access the register if bit isn't present */
379 fclk = bus_space_read_4(sc->sc_iot, sc->sc_prcm, freg);
380 bus_space_write_4(sc->sc_iot, sc->sc_prcm, freg, fclk | mbit);
381 }
382 if (imask & mbit) { /* dont access the register if bit isn't present */
383 iclk = bus_space_read_4(sc->sc_iot, sc->sc_prcm, ireg);
384 bus_space_write_4(sc->sc_iot, sc->sc_prcm, ireg, iclk | mbit);
385 }
386 printf("\n");
387}
388
389void
390prcm_v4_enablemodule(struct prcm_softc *sc, int mod)
391{
392 switch (mod) {
393 case PRCM_MMC0:
394 break;
395 case PRCM_USBP1_PHY:
396 case PRCM_USBP2_PHY:
397 prcm_v4_hsusbhost_set_source(mod, 0);
398 case PRCM_USB:
399 case PRCM_USBTLL:
400 case PRCM_USBP1_UTMI:
401 case PRCM_USBP1_HSIC:
402 case PRCM_USBP2_UTMI:
403 case PRCM_USBP2_HSIC:
404 prcm_v4_hsusbhost_activate(mod);
405 return;
406 case PRCM_GPIO0:
407 case PRCM_GPIO1:
408 case PRCM_GPIO2:
409 case PRCM_GPIO3:
410 case PRCM_GPIO4:
411 case PRCM_GPIO5:
412 /* XXX */
413 break;
414 default:
415 panic("%s: module not found\n", __func__);
416 }
417}
418
419int
420prcm_v4_hsusbhost_activate(int type)
421{
422 struct prcm_softc *sc = prcm_cd.cd_devs[0];
423 uint32_t i;
424 uint32_t clksel_reg_off;
425 uint32_t clksel, oclksel;
426
427 switch (type) {
428 case PRCM_USB:
429 case PRCM_USBP1_PHY:
430 case PRCM_USBP2_PHY:
431 /* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
432 clksel_reg_off = O4_L3INIT_CM2_OFFSET + 0x58;
433 clksel = bus_space_read_4(sc->sc_iot, sc->sc_cm2, clksel_reg_off);
434 oclksel = clksel;
435 /* Enable the module and also enable the optional func clocks */
436 if (type == PRCM_USB) {
437 clksel &= ~O4_CLKCTRL_MODULEMODE_MASK;
438 clksel |= /*O4_CLKCTRL_MODULEMODE_ENABLE*/2;
439
440 clksel |= (0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
441 }
442
443 break;
444
445 default:
446 panic("%s: invalid type %d", __func__, type);
447 return (EINVAL);
448 }
449 bus_space_write_4(sc->sc_iot, sc->sc_cm2, clksel_reg_off, clksel);
450
451 /* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
452 for (i = 0; i < O4_MAX_MODULE_ENABLE_WAIT; i++) {
453 clksel = bus_space_read_4(sc->sc_iot, sc->sc_cm2, clksel_reg_off);
454 if ((clksel & O4_CLKCTRL_IDLEST_MASK) == O4_CLKCTRL_IDLEST_ENABLED)
455 break;
456 }
457
458 /* Check the enabled state */
459 if ((clksel & O4_CLKCTRL_IDLEST_MASK) != O4_CLKCTRL_IDLEST_ENABLED) {
460 printf("Error: HERE failed to enable module with clock %d\n", type);
461 printf("Error: 0x%08x => 0x%08x\n", clksel_reg_off, clksel);
462 return (ETIMEDOUT);
463 }
464
465 return (0);
466}
467
468int
469prcm_v4_hsusbhost_set_source(int clk, int clksrc)
470{
471 struct prcm_softc *sc = prcm_cd.cd_devs[0];
472 uint32_t clksel_reg_off;
473 uint32_t clksel;
474 unsigned int bit;
475
476 if (clk == PRCM_USBP1_PHY)
477 bit = 24;
478 else if (clk != PRCM_USBP2_PHY)
479 bit = 25;
480 else
481 return (-EINVAL);
482
483 /* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
484 clksel_reg_off = O4_L3INIT_CM2_OFFSET + 0x58;
485 clksel = bus_space_read_4(sc->sc_iot, sc->sc_cm2, clksel_reg_off);
486
487 /* XXX: Set the clock source to either external or internal */
488 if (clksrc == 0)
489 clksel |= (0x1 << bit);
490 else
491 clksel &= ~(0x1 << bit);
492
493 bus_space_write_4(sc->sc_iot, sc->sc_cm2, clksel_reg_off, clksel);
494
495 return (0);
496}
497
498/*
499 * OMAP35xx Power, Reset, and Clock Management Reference Guide
500 * (sprufa5.pdf) and AM/DM37x Multimedia Device Technical Reference
501 * Manual (sprugn4h.pdf) note that DPLL5 provides a 120MHz clock for
502 * peripheral domain modules (page 107 and page 302).
503 * The reference clock for DPLL5 is DPLL5_ALWON_FCLK which is
504 * SYS_CLK, running at 13MHz.
505 */
506int
507prcm_setup_dpll5(struct prcm_softc *sc)
508{
509 uint32_t val;
510
511 /*
512 * We need to set the multiplier and divider values for PLL.
513 * To end up with 120MHz we take SYS_CLK, divide by it and multiply
514 * with 120 (sprugn4h.pdf, 13.4.11.4.1 SSC Configuration)
515 */
516 val = ((120 & 0x7ff) << 8) | ((SYS_CLK - 1) & 0x7f);
517 bus_space_write_4(sc->sc_iot, sc->sc_prcm, CM_CLKSEL4_PLL, val);
518
519 /* Clock divider from the PLL to the 120MHz clock. */
520 bus_space_write_4(sc->sc_iot, sc->sc_prcm, CM_CLKSEL5_PLL, val);
521
522 /*
523 * spruf98o.pdf, page 2319:
524 * PERIPH2_DPLL_FREQSEL is 0x7 1.75MHz to 2.1MHz
525 * EN_PERIPH2_DPLL is 0x7
526 */
527 val = (7 << 4) | (7 << 0);
528 bus_space_write_4(sc->sc_iot, sc->sc_prcm, CM_CLKEN2_PLL, val);
529
530 /* Disable the interconnect clock auto-idle. */
531 bus_space_write_4(sc->sc_iot, sc->sc_prcm, CM_AUTOIDLE2_PLL, 0x0);
532
533 /* Wait until DPLL5 is locked and there's clock activity. */
534 while ((val = bus_space_read_4(sc->sc_iot, sc->sc_prcm,
535 CM_IDLEST_CKGEN) & 0x01) == 0x00) {
536#ifdef DIAGNOSTIC
537 printf("CM_IDLEST_PLL = 0x%08x\n", val);
538#endif
539 }
540
541 return 0;
542}