xref: /freebsd/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c (revision d6b92ffa)
1 /*-
2  * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
3  * Copyright (C) 2010, Broadcom Corporation.
4  * All rights reserved.
5  *
6  * This file is derived from the hndpmu.c source contributed by Broadcom
7  * to to the Linux staging repository, as well as later revisions of hndpmu.c
8  * distributed with the Asus RT-N16 firmware source code release.
9  *
10  * Permission to use, copy, modify, and/or distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #include <sys/cdefs.h>
24 __FBSDID("$FreeBSD$");
25 
26 #include <sys/types.h>
27 
28 #include <dev/bhnd/bhnd.h>
29 #include <dev/bhnd/cores/chipc/chipc.h>
30 #include <dev/bhnd/cores/chipc/chipcreg.h>
31 
32 #include <dev/bhnd/bcma/bcma_dmp.h>
33 
34 #include "bhnd_nvram_map.h"
35 
36 #include "bhnd_pmureg.h"
37 #include "bhnd_pmuvar.h"
38 
39 #include "bhnd_pmu_private.h"
40 
41 #define	PMU_LOG(_sc, _fmt, ...)	do {				\
42 	if (_sc->dev != NULL)					\
43 		device_printf(_sc->dev, _fmt, ##__VA_ARGS__);	\
44 	else							\
45 		printf(_fmt, ##__VA_ARGS__);			\
46 } while (0)
47 
48 #ifdef BCMDBG
49 #define	PMU_DEBUG(_sc, _fmt, ...)	PMU_LOG(_sc, _fmt, ##__VA_ARGS__)
50 #else
51 #define	PMU_DEBUG(_sc, _fmt, ...)
52 #endif
53 
54 typedef struct pmu0_xtaltab0 pmu0_xtaltab0_t;
55 typedef struct pmu1_xtaltab0 pmu1_xtaltab0_t;
56 
57 /* PLL controls/clocks */
58 static const pmu1_xtaltab0_t *bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc);
59 static const pmu1_xtaltab0_t *bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc);
60 
61 static void	bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal);
62 static uint32_t	bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc);
63 static uint32_t	bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc);
64 
65 static void	bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal);
66 static uint32_t	bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc);
67 static uint32_t	bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc);
68 static uint32_t	bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc);
69 
70 static uint32_t	bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m);
71 
72 static uint32_t	bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0,
73 		    u_int m);
74 
75 /* PMU resources */
76 static bool	bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc);
77 static bool	bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc);
78 static bool	bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc);
79 static bool	bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc);
80 static uint32_t	bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs,
81 		    bool all);
82 static int	bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc,
83 		    uint32_t *uptime);
84 static int	bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin,
85 		    uint32_t *pmax);
86 
87 static void	bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc,
88 		    uint8_t spuravoid);
89 static void	bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc);
90 
91 #define	BHND_PMU_REV(_sc)			\
92 	((uint8_t)BHND_PMU_GET_BITS((_sc)->caps, BHND_PMU_CAP_REV))
93 
94 #define	PMU_WAIT_CLKST(_sc, _val, _mask)			\
95 	bhnd_pmu_wait_clkst((_sc), (_sc)->dev, (_sc)->res,	\
96 	    BHND_CLK_CTL_ST, (_val), (_mask))
97 
98 #define	PMURES_BIT(_bit)			\
99 	(1 << (BHND_PMU_ ## _bit))
100 
101 #define	PMU_CST4330_SDIOD_CHIPMODE(_sc)		\
102 	CHIPC_CST4330_CHIPMODE_SDIOD((_sc)->io->rd_chipst((_sc)->io_ctx))
103 
104 /**
105  * Initialize @p query state.
106  *
107  * @param[out] query On success, will be populated with a valid query instance
108  * state.
109  * @param dev The device owning @p query, or NULL.
110  * @param id The bhnd chip identification.
111  * @param io I/O callback functions.
112  * @param ctx I/O callback context.
113  *
114  * @retval 0 success
115  * @retval non-zero if the query state could not be initialized.
116  */
117 int
118 bhnd_pmu_query_init(struct bhnd_pmu_query *query, device_t dev,
119     struct bhnd_chipid id, const struct bhnd_pmu_io *io, void *ctx)
120 {
121 	query->dev = dev;
122 	query->io = io;
123 	query->io_ctx = ctx;
124 	query->cid = id;
125 	query->caps = BHND_PMU_READ_4(query, BHND_PMU_CAP);
126 
127 	return (0);
128 }
129 
130 /**
131  * Release any resources held by @p query.
132  *
133  * @param query A query instance previously initialized via
134  * bhnd_pmu_query_init().
135  */
136 void
137 bhnd_pmu_query_fini(struct bhnd_pmu_query *query)
138 {
139 	/* nothing to do */
140 }
141 
142 /**
143  * Perform an indirect register read.
144  *
145  * @param addr Offset of the address register.
146  * @param data Offset of the data register.
147  * @param reg Indirect register to be read.
148  */
149 uint32_t
150 bhnd_pmu_ind_read(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr,
151     bus_size_t data, uint32_t reg)
152 {
153 	io->wr4(addr, reg, io_ctx);
154 	return (io->rd4(data, io_ctx));
155 }
156 
157 /**
158  * Perform an indirect register write.
159  *
160  * @param addr Offset of the address register.
161  * @param data Offset of the data register.
162  * @param reg Indirect register to be written.
163  * @param val Value to be written to @p reg.
164  * @param mask Only the bits defined by @p mask will be updated from @p val.
165  */
166 void
167 bhnd_pmu_ind_write(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr,
168     bus_size_t data, uint32_t reg, uint32_t val, uint32_t mask)
169 {
170 	uint32_t rval;
171 
172 	io->wr4(addr, reg, io_ctx);
173 
174 	if (mask != UINT32_MAX) {
175 		rval = io->rd4(data, io_ctx);
176 		rval &= ~mask | (val & mask);
177 	} else {
178 		rval = val;
179 	}
180 
181 	io->wr4(data, rval, io_ctx);
182 }
183 
184 /**
185  * Wait for up to BHND_PMU_MAX_TRANSITION_DLY microseconds for the per-core
186  * clock status to be equal to @p value after applying @p mask.
187  *
188  * @param sc PMU driver state.
189  * @param dev Requesting device.
190  * @param r An active resource mapping the clock status register.
191  * @param clkst_reg Offset to the CLK_CTL_ST register.
192  * @param value Value to wait for.
193  * @param mask Mask to apply prior to value comparison.
194  */
195 bool
196 bhnd_pmu_wait_clkst(struct bhnd_pmu_softc *sc, device_t dev,
197     struct bhnd_resource *r, bus_size_t clkst_reg, uint32_t value,
198     uint32_t mask)
199 {
200 	uint32_t	clkst;
201 
202 	/* Bitswapped HTAVAIL/ALPAVAIL work-around */
203 	if (sc->quirks & BPMU_QUIRK_CLKCTL_CCS0) {
204 		uint32_t fmask, fval;
205 
206 		fmask = mask & ~(BHND_CCS_HTAVAIL | BHND_CCS_ALPAVAIL);
207 		fval = value & ~(BHND_CCS_HTAVAIL | BHND_CCS_ALPAVAIL);
208 
209 		if (mask & BHND_CCS_HTAVAIL)
210 			fmask |= BHND_CCS0_HTAVAIL;
211 		if (value & BHND_CCS_HTAVAIL)
212 			fval |= BHND_CCS0_HTAVAIL;
213 
214 		if (mask & BHND_CCS_ALPAVAIL)
215 			fmask |= BHND_CCS0_ALPAVAIL;
216 		if (value & BHND_CCS_ALPAVAIL)
217 			fval |= BHND_CCS0_ALPAVAIL;
218 
219 		mask = fmask;
220 		value = fval;
221 	}
222 
223 	for (uint32_t i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) {
224 		clkst = bhnd_bus_read_4(r, clkst_reg);
225 		if ((clkst & mask) == (value & mask))
226 			return (true);
227 
228 		DELAY(10);
229 	}
230 
231 	device_printf(dev, "clkst wait timeout (value=%#x, "
232 	    "mask=%#x)\n", value, mask);
233 
234 	return (false);
235 }
236 
237 /* Setup switcher voltage */
238 void
239 bhnd_pmu_set_switcher_voltage(struct bhnd_pmu_softc *sc, uint8_t bb_voltage,
240     uint8_t rf_voltage)
241 {
242 	BHND_PMU_REGCTRL_WRITE(sc, 0x01, (bb_voltage & 0x1f) << 22, ~0);
243 	BHND_PMU_REGCTRL_WRITE(sc, 0x00, (rf_voltage & 0x1f) << 14, ~0);
244 }
245 
246 void
247 bhnd_pmu_set_ldo_voltage(struct bhnd_pmu_softc *sc, uint8_t ldo,
248     uint8_t voltage)
249 {
250 	uint32_t	chipst;
251 	uint32_t	regctrl;
252 	uint8_t		shift;
253 	uint8_t		mask;
254 	uint8_t		addr;
255 
256 	switch (sc->cid.chip_id) {
257 	case BHND_CHIPID_BCM4328:
258 	case BHND_CHIPID_BCM5354:
259 		switch (ldo) {
260 		case SET_LDO_VOLTAGE_LDO1:
261 			addr = 2;
262 			shift = 17 + 8;
263 			mask = 0xf;
264 			break;
265 		case SET_LDO_VOLTAGE_LDO2:
266 			addr = 3;
267 			shift = 1;
268 			mask = 0xf;
269 			break;
270 		case SET_LDO_VOLTAGE_LDO3:
271 			addr = 3;
272 			shift = 9;
273 			mask = 0xf;
274 			break;
275 		case SET_LDO_VOLTAGE_PAREF:
276 			addr = 3;
277 			shift = 17;
278 			mask = 0x3f;
279 			break;
280 		default:
281 			panic("unknown BCM4328/BCM5354 LDO %hhu\n", ldo);
282 		}
283 		break;
284 	case BHND_CHIPID_BCM4312:
285 		switch (ldo) {
286 		case SET_LDO_VOLTAGE_PAREF:
287 			addr = 0;
288 			shift = 21;
289 			mask = 0x3f;
290 			break;
291 		default:
292 			panic("unknown BCM4312 LDO %hhu\n", ldo);
293 		}
294 		break;
295 	case BHND_CHIPID_BCM4325:
296 		switch (ldo) {
297 		case SET_LDO_VOLTAGE_CLDO_PWM:
298 			addr = 5;
299 			shift = 9;
300 			mask = 0xf;
301 			break;
302 		case SET_LDO_VOLTAGE_CLDO_BURST:
303 			addr = 5;
304 			shift = 13;
305 			mask = 0xf;
306 			break;
307 		case SET_LDO_VOLTAGE_CBUCK_PWM:
308 			addr = 3;
309 			shift = 20;
310 			mask = 0x1f;
311 			/* Bit 116 & 119 are inverted in CLB for opt 2b */
312 			chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
313 			if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
314 				voltage ^= 0x9;
315 			break;
316 		case SET_LDO_VOLTAGE_CBUCK_BURST:
317 			addr = 3;
318 			shift = 25;
319 			mask = 0x1f;
320 			/* Bit 121 & 124 are inverted in CLB for opt 2b */
321 			chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
322 			if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
323 				voltage ^= 0x9;
324 			break;
325 		case SET_LDO_VOLTAGE_LNLDO1:
326 			addr = 5;
327 			shift = 17;
328 			mask = 0x1f;
329 			break;
330 		case SET_LDO_VOLTAGE_LNLDO2_SEL:
331 			addr = 6;
332 			shift = 0;
333 			mask = 0x1;
334 			break;
335 		default:
336 			panic("unknown BCM4325 LDO %hhu\n", ldo);
337 		}
338 		break;
339 	case BHND_CHIPID_BCM4336:
340 		switch (ldo) {
341 		case SET_LDO_VOLTAGE_CLDO_PWM:
342 			addr = 4;
343 			shift = 1;
344 			mask = 0xf;
345 			break;
346 		case SET_LDO_VOLTAGE_CLDO_BURST:
347 			addr = 4;
348 			shift = 5;
349 			mask = 0xf;
350 			break;
351 		case SET_LDO_VOLTAGE_LNLDO1:
352 			addr = 4;
353 			shift = 17;
354 			mask = 0xf;
355 			break;
356 		default:
357 			panic("unknown BCM4336 LDO %hhu\n", ldo);
358 		}
359 		break;
360 	case BHND_CHIPID_BCM4330:
361 		switch (ldo) {
362 		case SET_LDO_VOLTAGE_CBUCK_PWM:
363 			addr = 3;
364 			shift = 0;
365 			mask = 0x1f;
366 			break;
367 		default:
368 			panic("unknown BCM4330 LDO %hhu\n", ldo);
369 		}
370 		break;
371 	case BHND_CHIPID_BCM4331:
372 		switch (ldo) {
373 		case  SET_LDO_VOLTAGE_PAREF:
374 			addr = 1;
375 			shift = 0;
376 			mask = 0xf;
377 			break;
378 		default:
379 			panic("unknown BCM4331 LDO %hhu\n", ldo);
380 		}
381 		break;
382 	default:
383 		panic("cannot set LDO voltage on unsupported chip %hu\n",
384 		    sc->cid.chip_id);
385 		return;
386 	}
387 
388 	regctrl = (voltage & mask) << shift;
389 	BHND_PMU_REGCTRL_WRITE(sc, addr, regctrl, mask << shift);
390 }
391 
392 /* d11 slow to fast clock transition time in slow clock cycles */
393 #define	D11SCC_SLOW2FAST_TRANSITION	2
394 
395 int
396 bhnd_pmu_fast_pwrup_delay(struct bhnd_pmu_softc *sc, uint16_t *pwrup_delay)
397 {
398 	uint32_t	ilp;
399 	uint32_t	uptime;
400 	u_int		delay;
401 	int		error;
402 
403 	switch (sc->cid.chip_id) {
404 	case BHND_CHIPID_BCM43224:
405 	case BHND_CHIPID_BCM43225:
406 	case BHND_CHIPID_BCM43421:
407 	case BHND_CHIPID_BCM43235:
408 	case BHND_CHIPID_BCM43236:
409 	case BHND_CHIPID_BCM43238:
410 	case BHND_CHIPID_BCM4331:
411 	case BHND_CHIPID_BCM6362:
412 	case BHND_CHIPID_BCM4313:
413 		delay = 3700;
414 		break;
415 
416 	case BHND_CHIPID_BCM4325:
417 		error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4325_HT_AVAIL,
418 		    &uptime);
419 		if (error)
420 			return (error);
421 
422 		ilp = bhnd_pmu_ilp_clock(&sc->query);
423 		delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
424 		    ((1000000 + ilp - 1) / ilp);
425 		delay = (11 * delay) / 10;
426 		break;
427 
428 	case BHND_CHIPID_BCM4329:
429 		error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4329_HT_AVAIL,
430 		    &uptime);
431 		if (error)
432 			return (error);
433 
434 		ilp = bhnd_pmu_ilp_clock(&sc->query);
435 		delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
436 		    ((1000000 + ilp - 1) / ilp);
437 		delay = (11 * delay) / 10;
438 		break;
439 
440 	case BHND_CHIPID_BCM4319:
441 		delay = 3700;
442 		break;
443 
444 	case BHND_CHIPID_BCM4336:
445 		error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4336_HT_AVAIL,
446 		    &uptime);
447 		if (error)
448 			return (error);
449 
450 		ilp = bhnd_pmu_ilp_clock(&sc->query);
451 		delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
452 		    ((1000000 + ilp - 1) / ilp);
453 		delay = (11 * delay) / 10;
454 		break;
455 
456 	case BHND_CHIPID_BCM4330:
457 		error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4330_HT_AVAIL,
458 		    &uptime);
459 		if (error)
460 			return (error);
461 
462 		ilp = bhnd_pmu_ilp_clock(&sc->query);
463 		delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
464 		    ((1000000 + ilp - 1) / ilp);
465 		delay = (11 * delay) / 10;
466 		break;
467 
468 	default:
469 		delay = BHND_PMU_MAX_TRANSITION_DLY;
470 		break;
471 	}
472 
473 	*pwrup_delay = (uint16_t)delay;
474 	return (0);
475 }
476 
477 uint32_t
478 bhnd_pmu_force_ilp(struct bhnd_pmu_softc *sc, bool force)
479 {
480 	uint32_t	orig;
481 	uint32_t	pctrl;
482 
483 	pctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
484 	orig = pctrl;
485 
486 	if (force)
487 		pctrl &= ~(BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN);
488 	else
489 		pctrl |= (BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN);
490 
491 	BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pctrl);
492 
493 	return (orig);
494 }
495 
496 /* Setup resource up/down timers */
497 typedef struct {
498 	uint8_t		resnum;
499 	uint16_t	updown;
500 } pmu_res_updown_t;
501 
502 typedef bool (*pmu_res_filter) (struct bhnd_pmu_softc *sc);
503 
504 /* Change resource dependencies masks */
505 typedef struct {
506 	uint32_t	res_mask;	/* resources (chip specific) */
507 	int8_t		action;		/* action */
508 	uint32_t	depend_mask;	/* changes to the dependencies mask */
509 	pmu_res_filter	filter;		/* action is taken when filter is NULL or returns true */
510 } pmu_res_depend_t;
511 
512 /* Resource dependencies mask change action */
513 #define	RES_DEPEND_SET		0	/* Override the dependencies mask */
514 #define	RES_DEPEND_ADD		1	/* Add to the  dependencies mask */
515 #define	RES_DEPEND_REMOVE	-1	/* Remove from the dependencies mask */
516 
517 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
518 	{
519 	BHND_PMU_RES4328_EXT_SWITCHER_PWM, 0x0101}, {
520 	BHND_PMU_RES4328_BB_SWITCHER_PWM, 0x1f01}, {
521 	BHND_PMU_RES4328_BB_SWITCHER_BURST, 0x010f}, {
522 	BHND_PMU_RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
523 	BHND_PMU_RES4328_ILP_REQUEST, 0x0202}, {
524 	BHND_PMU_RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
525 	BHND_PMU_RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
526 	BHND_PMU_RES4328_ROM_SWITCH, 0x0101}, {
527 	BHND_PMU_RES4328_PA_REF_LDO, 0x0f01}, {
528 	BHND_PMU_RES4328_RADIO_LDO, 0x0f01}, {
529 	BHND_PMU_RES4328_AFE_LDO, 0x0f01}, {
530 	BHND_PMU_RES4328_PLL_LDO, 0x0f01}, {
531 	BHND_PMU_RES4328_BG_FILTBYP, 0x0101}, {
532 	BHND_PMU_RES4328_TX_FILTBYP, 0x0101}, {
533 	BHND_PMU_RES4328_RX_FILTBYP, 0x0101}, {
534 	BHND_PMU_RES4328_XTAL_PU, 0x0101}, {
535 	BHND_PMU_RES4328_XTAL_EN, 0xa001}, {
536 	BHND_PMU_RES4328_BB_PLL_FILTBYP, 0x0101}, {
537 	BHND_PMU_RES4328_RF_PLL_FILTBYP, 0x0101}, {
538 	BHND_PMU_RES4328_BB_PLL_PU, 0x0701}
539 };
540 
541 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
542 	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
543 	{
544 	PMURES_BIT(RES4328_ILP_REQUEST),
545 		    RES_DEPEND_SET,
546 		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
547 		    PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
548 };
549 
550 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
551 	{
552 	BHND_PMU_RES4325_XTAL_PU, 0x1501}
553 };
554 
555 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
556 	/* Adjust OTP PU resource dependencies - remove BB BURST */
557 	{
558 	PMURES_BIT(RES4325_OTP_PU),
559 		    RES_DEPEND_REMOVE,
560 		    PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
561 	/* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
562 	{
563 	PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
564 		    RES_DEPEND_ADD,
565 		    PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
566 		    PMURES_BIT(RES4325_BUCK_BOOST_PWM), bhnd_pmu_res_depfltr_bb},
567 	/* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
568 	{
569 	PMURES_BIT(RES4325_HT_AVAIL),
570 		    RES_DEPEND_ADD,
571 		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
572 		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
573 		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
574 		    PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
575 	/* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
576 	{
577 	PMURES_BIT(RES4325_ILP_REQUEST) |
578 		    PMURES_BIT(RES4325_ABUCK_BURST) |
579 		    PMURES_BIT(RES4325_ABUCK_PWM) |
580 		    PMURES_BIT(RES4325_LNLDO1_PU) |
581 		    PMURES_BIT(RES4325C1_LNLDO2_PU) |
582 		    PMURES_BIT(RES4325_XTAL_PU) |
583 		    PMURES_BIT(RES4325_ALP_AVAIL) |
584 		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
585 		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
586 		    PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
587 		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
588 		    PMURES_BIT(RES4325_AFE_PWRSW_PU) |
589 		    PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
590 		    PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
591 		    PMURES_BIT(RES4325B0_CBUCK_LPOM) |
592 		    PMURES_BIT(RES4325B0_CBUCK_BURST) |
593 		    PMURES_BIT(RES4325B0_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb}
594 };
595 
596 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
597 	{
598 	BHND_PMU_RES4315_XTAL_PU, 0x2501}
599 };
600 
601 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
602 	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
603 	{
604 	PMURES_BIT(RES4315_OTP_PU),
605 		    RES_DEPEND_REMOVE,
606 		    PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_npaldo},
607 	/* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
608 	{
609 	PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
610 		    RES_DEPEND_ADD,
611 		    PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_paldo},
612 	/* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
613 	{
614 	PMURES_BIT(RES4315_HT_AVAIL),
615 		    RES_DEPEND_ADD,
616 		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
617 		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
618 		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
619 		    PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
620 	/* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
621 	{
622 	PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
623 		    PMURES_BIT(RES4315_LNLDO1_PU) |
624 		    PMURES_BIT(RES4315_OTP_PU) |
625 		    PMURES_BIT(RES4315_LNLDO2_PU) |
626 		    PMURES_BIT(RES4315_XTAL_PU) |
627 		    PMURES_BIT(RES4315_ALP_AVAIL) |
628 		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
629 		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
630 		    PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
631 		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
632 		    PMURES_BIT(RES4315_AFE_PWRSW_PU) |
633 		    PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
634 		    PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
635 		    PMURES_BIT(RES4315_CBUCK_LPOM) |
636 		    PMURES_BIT(RES4315_CBUCK_BURST) |
637 		    PMURES_BIT(RES4315_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb}
638 };
639 
640 /* 4329 specific. needs to come back this issue later */
641 static const pmu_res_updown_t bcm4329_res_updown[] = {
642 	{
643 	BHND_PMU_RES4329_XTAL_PU, 0x1501}
644 };
645 
646 static const pmu_res_depend_t bcm4329_res_depend[] = {
647 	/* Adjust HT Avail resource dependencies */
648 	{
649 	PMURES_BIT(RES4329_HT_AVAIL),
650 		    RES_DEPEND_ADD,
651 		    PMURES_BIT(RES4329_CBUCK_LPOM) |
652 		    PMURES_BIT(RES4329_CBUCK_BURST) |
653 		    PMURES_BIT(RES4329_CBUCK_PWM) |
654 		    PMURES_BIT(RES4329_CLDO_PU) |
655 		    PMURES_BIT(RES4329_PALDO_PU) |
656 		    PMURES_BIT(RES4329_LNLDO1_PU) |
657 		    PMURES_BIT(RES4329_XTAL_PU) |
658 		    PMURES_BIT(RES4329_ALP_AVAIL) |
659 		    PMURES_BIT(RES4329_RX_PWRSW_PU) |
660 		    PMURES_BIT(RES4329_TX_PWRSW_PU) |
661 		    PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
662 		    PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
663 		    PMURES_BIT(RES4329_AFE_PWRSW_PU) |
664 		    PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
665 };
666 
667 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
668 	{
669 	BHND_PMU_RES4319_XTAL_PU, 0x3f01}
670 };
671 
672 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
673 	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
674 	{
675 	PMURES_BIT(RES4319_OTP_PU),
676 		    RES_DEPEND_REMOVE,
677 		    PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_npaldo},
678 	    /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
679 	{
680 	PMURES_BIT(RES4319_HT_AVAIL),
681 		    RES_DEPEND_ADD,
682 		    PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_paldo},
683 	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
684 	{
685 	PMURES_BIT(RES4319_HT_AVAIL),
686 		    RES_DEPEND_ADD,
687 		    PMURES_BIT(RES4319_RX_PWRSW_PU) |
688 		    PMURES_BIT(RES4319_TX_PWRSW_PU) |
689 		    PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
690 		    PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
691 		    PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
692 };
693 
694 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
695 	{
696 	BHND_PMU_RES4336_HT_AVAIL, 0x0D01}
697 };
698 
699 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
700 	/* Just a dummy entry for now */
701 	{
702 	PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
703 };
704 
705 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
706 	{
707 	BHND_PMU_RES4330_HT_AVAIL, 0x0e02}
708 };
709 
710 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
711 	/* Just a dummy entry for now */
712 	{
713 	PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
714 };
715 
716 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF
717  * and WLAN PA */
718 static bool
719 bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc)
720 {
721 	return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_BUCKBOOST));
722 }
723 
724 /* true if the power topology doesn't use the cbuck. Key on chiprev also if
725  * the chip is BCM4325. */
726 static bool
727 bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc)
728 {
729 	if (sc->cid.chip_id == BHND_CHIPID_BCM4325 && sc->cid.chip_rev <= 1)
730 		return (false);
731 
732 	return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_NOCBUCK));
733 }
734 
735 /* true if the power topology uses the PALDO */
736 static bool
737 bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc)
738 {
739 	return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO));
740 }
741 
742 /* true if the power topology doesn't use the PALDO */
743 static bool
744 bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc)
745 {
746 	return (!BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO));
747 }
748 
749 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
750 static int
751 bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin, uint32_t *pmax)
752 {
753 	uint32_t	max_mask, min_mask;
754 	uint32_t	chipst, otpsel;
755 	uint32_t	nval;
756 	uint8_t		rsrcs;
757 	int		error;
758 
759 	max_mask = 0;
760 	min_mask = 0;
761 
762 	/* # resources */
763 	rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC);
764 
765 	/* determine min/max rsrc masks */
766 	switch (sc->cid.chip_id) {
767 	case BHND_CHIPID_BCM4325:
768 		/* If used by this device, enable the CBUCK */
769 		if (!bhnd_pmu_res_depfltr_ncb(sc))
770 			min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM);
771 
772 		chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
773 		if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
774 			min_mask |= PMURES_BIT(RES4325B0_CLDO_PU);
775 
776 		/* Is OTP required? */
777 		otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_SPROM_OTP_SEL);
778 		if (otpsel != CHIPC_CST_OTP_PWRDN)
779 			min_mask |= PMURES_BIT(RES4325_OTP_PU);
780 
781 		/* Leave buck boost on in burst mode for certain boards */
782 		if (sc->board.board_flags & BHND_BFL_BUCKBOOST) {
783 			switch (sc->board.board_type) {
784 			case BHND_BOARD_BCM94325DEVBU:
785 			case BHND_BOARD_BCM94325BGABU:
786 				min_mask |= PMURES_BIT(
787 				    RES4325_BUCK_BOOST_BURST);
788 				break;
789 			}
790 		}
791 
792 		/* Allow all resources to be turned on upon requests */
793 		max_mask = ~(~0 << rsrcs);
794 		break;
795 
796 	case BHND_CHIPID_BCM4312:
797 		/* default min_mask = 0x80000cbb is wrong */
798 		min_mask = 0xcbb;
799 		/*
800 		 * max_mask = 0x7fff;
801 		 * pmu_res_updown_table_sz = 0;
802 		 * pmu_res_depend_table_sz = 0;
803 		 */
804 		break;
805 
806 	case BHND_CHIPID_BCM4322:
807 	case BHND_CHIPID_BCM43221:
808 	case BHND_CHIPID_BCM43231:
809 	case BHND_CHIPID_BCM4342:
810 		if (sc->cid.chip_rev >= 2)
811 			break;
812 
813 		/* request ALP(can skip for A1) */
814 		min_mask = PMURES_BIT(RES4322_RF_LDO) |
815 			   PMURES_BIT(RES4322_XTAL_PU) |
816 			   PMURES_BIT(RES4322_ALP_AVAIL);
817 
818 		if (bhnd_get_attach_type(sc->chipc_dev) == BHND_ATTACH_NATIVE) {
819 			min_mask |=
820 			    PMURES_BIT(RES4322_SI_PLL_ON) |
821 			    PMURES_BIT(RES4322_HT_SI_AVAIL) |
822 			    PMURES_BIT(RES4322_PHY_PLL_ON) |
823 			    PMURES_BIT(RES4322_OTP_PU) |
824 			    PMURES_BIT(RES4322_HT_PHY_AVAIL);
825 			max_mask = 0x1ff;
826 		}
827 		break;
828 
829 	case BHND_CHIPID_BCM43222:
830 	case BHND_CHIPID_BCM43111:
831 	case BHND_CHIPID_BCM43112:
832 	case BHND_CHIPID_BCM43224:
833 	case BHND_CHIPID_BCM43225:
834 	case BHND_CHIPID_BCM43421:
835 	case BHND_CHIPID_BCM43226:
836 	case BHND_CHIPID_BCM43420:
837 	case BHND_CHIPID_BCM43235:
838 	case BHND_CHIPID_BCM43236:
839 	case BHND_CHIPID_BCM43238:
840 	case BHND_CHIPID_BCM43234:
841 	case BHND_CHIPID_BCM43237:
842 	case BHND_CHIPID_BCM4331:
843 	case BHND_CHIPID_BCM43431:
844 	case BHND_CHIPID_BCM6362:
845 		/* use chip default */
846 		break;
847 
848 	case BHND_CHIPID_BCM4328:
849 		min_mask =
850 		    PMURES_BIT(RES4328_BB_SWITCHER_PWM) |
851 		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
852 		    PMURES_BIT(RES4328_XTAL_EN);
853 		max_mask = 0xfffffff;
854 		break;
855 
856 	case BHND_CHIPID_BCM5354:
857 		/* Allow (but don't require) PLL to turn on */
858 		max_mask = 0xfffffff;
859 		break;
860 
861 	case BHND_CHIPID_BCM4329:
862 		/* Down to save the power. */
863 		if (sc->cid.chip_rev >= 0x2) {
864 			min_mask =
865 			    PMURES_BIT(RES4329_CBUCK_LPOM) |
866 			    PMURES_BIT(RES4329_LNLDO1_PU) |
867 			    PMURES_BIT(RES4329_CLDO_PU);
868 		} else {
869 			min_mask =
870 			    PMURES_BIT(RES4329_CBUCK_LPOM) |
871 			    PMURES_BIT(RES4329_CLDO_PU);
872 		}
873 
874 		/* Is OTP required? */
875 		chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
876 		otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4329_SPROM_OTP_SEL);
877 		if (otpsel != CHIPC_CST_OTP_PWRDN)
878 			min_mask |= PMURES_BIT(RES4329_OTP_PU);
879 
880 		/* Allow (but don't require) PLL to turn on */
881 		max_mask = 0x3ff63e;
882 		break;
883 
884 	case BHND_CHIPID_BCM4319:
885 		/* We only need a few resources to be kept on all the time */
886 		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
887 		    PMURES_BIT(RES4319_CLDO_PU);
888 
889 		/* Allow everything else to be turned on upon requests */
890 		max_mask = ~(~0 << rsrcs);
891 		break;
892 
893 	case BHND_CHIPID_BCM4336:
894 		/* Down to save the power. */
895 		min_mask =
896 		    PMURES_BIT(RES4336_CBUCK_LPOM) |
897 		    PMURES_BIT(RES4336_CLDO_PU) |
898 		    PMURES_BIT(RES4336_LDO3P3_PU) |
899 		    PMURES_BIT(RES4336_OTP_PU) |
900 		    PMURES_BIT(RES4336_DIS_INT_RESET_PD);
901 		/* Allow (but don't require) PLL to turn on */
902 		max_mask = 0x1ffffff;
903 		break;
904 
905 	case BHND_CHIPID_BCM4330:
906 		/* Down to save the power. */
907 		min_mask =
908 		    PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
909 		    | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
910 		    PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
911 		/* Allow (but don't require) PLL to turn on */
912 		max_mask = 0xfffffff;
913 		break;
914 
915 	case BHND_CHIPID_BCM4313:
916 		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
917 		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
918 		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
919 		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
920 		max_mask = 0xffff;
921 		break;
922 	default:
923 		break;
924 	}
925 
926 	/* Apply nvram override to min mask */
927 	error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMIN, &nval);
928 	if (error && error != ENOENT) {
929 		PMU_LOG(sc, "NVRAM error reading %s: %d\n",
930 		    BHND_NVAR_RMIN, error);
931 		return (error);
932 	} else if (!error) {
933 		PMU_DEBUG(sc, "Applying rmin=%#x to min_mask\n", nval);
934 		min_mask = nval;
935 	}
936 
937 	/* Apply nvram override to max mask */
938 	error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMAX, &nval);
939 	if (error && error != ENOENT) {
940 		PMU_LOG(sc, "NVRAM error reading %s: %d\n",
941 		    BHND_NVAR_RMAX, error);
942 		return (error);
943 	} else if (!error) {
944 		PMU_DEBUG(sc, "Applying rmax=%#x to max_mask\n", nval);
945 		min_mask = nval;
946 	}
947 
948 	if (pmin != NULL)
949 		*pmin = min_mask;
950 
951 	if (pmax != NULL)
952 		*pmax = max_mask;
953 
954 	return (0);
955 }
956 
957 /* initialize PMU resources */
958 int
959 bhnd_pmu_res_init(struct bhnd_pmu_softc *sc)
960 {
961 	const pmu_res_updown_t		*pmu_res_updown_table;
962 	const pmu_res_depend_t		*pmu_res_depend_table;
963 	size_t				 pmu_res_updown_table_sz;
964 	size_t				 pmu_res_depend_table_sz;
965 	uint32_t			 max_mask, min_mask;
966 	uint8_t				 rsrcs;
967 	int				 error;
968 
969 	pmu_res_depend_table = NULL;
970 	pmu_res_depend_table_sz = 0;
971 
972 	pmu_res_updown_table = NULL;
973 	pmu_res_updown_table_sz = 0;
974 
975 	switch (sc->cid.chip_id) {
976 	case BHND_CHIPID_BCM4315:
977 		/* Optimize resources up/down timers */
978 		pmu_res_updown_table = bcm4315a0_res_updown;
979 		pmu_res_updown_table_sz = nitems(bcm4315a0_res_updown);
980 
981 		/* Optimize resources dependencies */
982 		pmu_res_depend_table = bcm4315a0_res_depend;
983 		pmu_res_depend_table_sz = nitems(bcm4315a0_res_depend);
984 		break;
985 
986 	case BHND_CHIPID_BCM4325:
987 		/* Optimize resources up/down timers */
988 		pmu_res_updown_table = bcm4325a0_res_updown;
989 		pmu_res_updown_table_sz = nitems(bcm4325a0_res_updown);
990 
991 		/* Optimize resources dependencies */
992 		pmu_res_depend_table = bcm4325a0_res_depend;
993 		pmu_res_depend_table_sz = nitems(bcm4325a0_res_depend);
994 		break;
995 
996 	case BHND_CHIPID_BCM4328:
997 		/* Optimize resources up/down timers */
998 		pmu_res_updown_table = bcm4328a0_res_updown;
999 		pmu_res_updown_table_sz = nitems(bcm4328a0_res_updown);
1000 
1001 		/* Optimize resources dependencies */
1002 		pmu_res_depend_table = bcm4328a0_res_depend;
1003 		pmu_res_depend_table_sz = nitems(bcm4328a0_res_depend);
1004 		break;
1005 
1006 	case BHND_CHIPID_BCM4329:
1007 		/* Optimize resources up/down timers */
1008 		pmu_res_updown_table = bcm4329_res_updown;
1009 		pmu_res_updown_table_sz = nitems(bcm4329_res_updown);
1010 
1011 		/* Optimize resources dependencies */
1012 		pmu_res_depend_table = bcm4329_res_depend;
1013 		pmu_res_depend_table_sz = nitems(bcm4329_res_depend);
1014 		break;
1015 
1016 	case BHND_CHIPID_BCM4319:
1017 		/* Optimize resources up/down timers */
1018 		pmu_res_updown_table = bcm4319a0_res_updown;
1019 		pmu_res_updown_table_sz = nitems(bcm4319a0_res_updown);
1020 
1021 		/* Optimize resources dependencies masks */
1022 		pmu_res_depend_table = bcm4319a0_res_depend;
1023 		pmu_res_depend_table_sz = nitems(bcm4319a0_res_depend);
1024 		break;
1025 
1026 	case BHND_CHIPID_BCM4336:
1027 		/* Optimize resources up/down timers */
1028 		pmu_res_updown_table = bcm4336a0_res_updown;
1029 		pmu_res_updown_table_sz = nitems(bcm4336a0_res_updown);
1030 
1031 		/* Optimize resources dependencies masks */
1032 		pmu_res_depend_table = bcm4336a0_res_depend;
1033 		pmu_res_depend_table_sz = nitems(bcm4336a0_res_depend);
1034 		break;
1035 
1036 	case BHND_CHIPID_BCM4330:
1037 		/* Optimize resources up/down timers */
1038 		pmu_res_updown_table = bcm4330a0_res_updown;
1039 		pmu_res_updown_table_sz = nitems(bcm4330a0_res_updown);
1040 
1041 		/* Optimize resources dependencies masks */
1042 		pmu_res_depend_table = bcm4330a0_res_depend;
1043 		pmu_res_depend_table_sz = nitems(bcm4330a0_res_depend);
1044 		break;
1045 	default:
1046 		break;
1047 	}
1048 
1049 	/* # resources */
1050 	rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC);
1051 
1052 	/* Program up/down timers */
1053 	for (size_t i = 0; i < pmu_res_updown_table_sz; i++) {
1054 		const pmu_res_updown_t	*updt;
1055 
1056 		KASSERT(pmu_res_updown_table != NULL, ("no updown tables"));
1057 
1058 		updt = &pmu_res_updown_table[pmu_res_updown_table_sz - i - 1];
1059 
1060 		PMU_DEBUG(sc, "Changing rsrc %d res_updn_timer to %#x\n",
1061 		    updt->resnum, updt->updown);
1062 
1063 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, updt->resnum);
1064 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, updt->updown);
1065 	}
1066 
1067 	/* Apply nvram overrides to up/down timers */
1068 	for (uint8_t i = 0; i < rsrcs; i++) {
1069 		char		name[6];
1070 		uint32_t	val;
1071 
1072 		snprintf(name, sizeof(name), "r%dt", i);
1073 		error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val);
1074 
1075 		if (error == ENOENT) {
1076 			continue;
1077 		} else if (error) {
1078 			PMU_LOG(sc, "NVRAM error reading %s: %d\n",
1079 			    name, error);
1080 			return (error);
1081 		}
1082 
1083 		PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_updn_timer\n",
1084 		    name, val, i);
1085 
1086 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1087 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, val);
1088 	}
1089 
1090 	/* Program resource dependencies table */
1091 	for (size_t i = 0; i < pmu_res_depend_table_sz; i++) {
1092 		const pmu_res_depend_t	*rdep;
1093 		pmu_res_filter		 filter;
1094 		uint32_t		 depend_mask;
1095 
1096 		KASSERT(pmu_res_depend_table != NULL, ("no depend tables"));
1097 
1098 		rdep = &pmu_res_depend_table[pmu_res_depend_table_sz - i - 1];
1099 		filter = rdep->filter;
1100 
1101 		if (filter != NULL && !filter(sc))
1102 			continue;
1103 
1104 		for (uint8_t i = 0; i < rsrcs; i++) {
1105 			if ((rdep->res_mask & BHND_PMURES_BIT(i)) == 0)
1106 				continue;
1107 
1108 			BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1109 			depend_mask = BHND_PMU_READ_4(sc,
1110 			    BHND_PMU_RES_DEP_MASK);
1111 			switch (rdep->action) {
1112 			case RES_DEPEND_SET:
1113 				PMU_DEBUG(sc, "Changing rsrc %hhu res_dep_mask to "
1114 				    "%#x\n", i, table->depend_mask);
1115 				depend_mask = rdep->depend_mask;
1116 				break;
1117 
1118 			case RES_DEPEND_ADD:
1119 				PMU_DEBUG(sc, "Adding %#x to rsrc %hhu "
1120 				    "res_dep_mask\n", table->depend_mask, i);
1121 
1122 				depend_mask |= rdep->depend_mask;
1123 				break;
1124 
1125 			case RES_DEPEND_REMOVE:
1126 				PMU_DEBUG(sc, "Removing %#x from rsrc %hhu "
1127 				    "res_dep_mask\n", table->depend_mask, i);
1128 
1129 				depend_mask &= ~(rdep->depend_mask);
1130 				break;
1131 
1132 			default:
1133 				panic("unknown RES_DEPEND action: %d\n",
1134 				    rdep->action);
1135 				break;
1136 			}
1137 
1138 
1139 		}
1140 	}
1141 
1142 	/* Apply nvram overrides to dependencies masks */
1143 	for (uint8_t i = 0; i < rsrcs; i++) {
1144 		char		name[6];
1145 		uint32_t	val;
1146 
1147 		snprintf(name, sizeof(name), "r%dd", i);
1148 		error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val);
1149 
1150 		if (error == ENOENT) {
1151 			continue;
1152 		} else if (error) {
1153 			PMU_LOG(sc, "NVRAM error reading %s: %d\n", name,
1154 			    error);
1155 			return (error);
1156 		}
1157 
1158 		PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_dep_mask\n", name,
1159 		    val, i);
1160 
1161 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1162 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_DEP_MASK, val);
1163 	}
1164 
1165 	/* Determine min/max rsrc masks */
1166 	if ((error = bhnd_pmu_res_masks(sc, &min_mask, &max_mask)))
1167 		return (error);
1168 
1169 	/* It is required to program max_mask first and then min_mask */
1170 
1171 	/* Program max resource mask */
1172 	if (max_mask != 0) {
1173 		PMU_DEBUG(sc, "Changing max_res_mask to 0x%x\n", max_mask);
1174 		BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask);
1175 	}
1176 
1177 	/* Program min resource mask */
1178 
1179 	if (min_mask != 0) {
1180 		PMU_DEBUG(sc, "Changing min_res_mask to 0x%x\n", min_mask);
1181 		BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask);
1182 	}
1183 
1184 	/* Add some delay; allow resources to come up and settle. */
1185 	DELAY(2000);
1186 
1187 	return (0);
1188 }
1189 
1190 /* setup pll and query clock speed */
1191 struct pmu0_xtaltab0 {
1192 	uint16_t	freq;
1193 	uint8_t		xf;
1194 	uint8_t		wbint;
1195 	uint32_t	wbfrac;
1196 };
1197 
1198 /* the following table is based on 880Mhz fvco */
1199 static const pmu0_xtaltab0_t pmu0_xtaltab0[] = {
1200 	{
1201 	12000, 1, 73, 349525}, {
1202 	13000, 2, 67, 725937}, {
1203 	14400, 3, 61, 116508}, {
1204 	15360, 4, 57, 305834}, {
1205 	16200, 5, 54, 336579}, {
1206 	16800, 6, 52, 399457}, {
1207 	19200, 7, 45, 873813}, {
1208 	19800, 8, 44, 466033}, {
1209 	20000, 9, 44, 0}, {
1210 	25000, 10, 70, 419430}, {
1211 	26000, 11, 67, 725937}, {
1212 	30000, 12, 58, 699050}, {
1213 	38400, 13, 45, 873813}, {
1214 	40000, 14, 45, 0}, {
1215 	0, 0, 0, 0}
1216 };
1217 
1218 #define	PMU0_XTAL0_DEFAULT	8
1219 
1220 /* setup pll and query clock speed */
1221 struct pmu1_xtaltab0 {
1222 	uint16_t	fref;
1223 	uint8_t		xf;
1224 	uint8_t		p1div;
1225 	uint8_t		p2div;
1226 	uint8_t		ndiv_int;
1227 	uint32_t	ndiv_frac;
1228 };
1229 
1230 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
1231 	{
1232 	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
1233 	13000, 2, 1, 6, 0xb, 0x483483}, {
1234 	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
1235 	15360, 4, 1, 5, 0xb, 0x755555}, {
1236 	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
1237 	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
1238 	19200, 7, 1, 4, 0xb, 0x755555}, {
1239 	19800, 8, 1, 11, 0x4, 0xA57EB}, {
1240 	20000, 9, 1, 11, 0x4, 0x0}, {
1241 	24000, 10, 3, 11, 0xa, 0x0}, {
1242 	25000, 11, 5, 16, 0xb, 0x0}, {
1243 	26000, 12, 1, 1, 0x21, 0xD89D89}, {
1244 	30000, 13, 3, 8, 0xb, 0x0}, {
1245 	37400, 14, 3, 1, 0x46, 0x969696}, {
1246 	38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
1247 	40000, 16, 1, 2, 0xb, 0}, {
1248 	0, 0, 0, 0, 0, 0}
1249 };
1250 
1251 /* the following table is based on 880Mhz fvco */
1252 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
1253 	{
1254 	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
1255 	13000, 2, 1, 6, 0xb, 0x483483}, {
1256 	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
1257 	15360, 4, 1, 5, 0xb, 0x755555}, {
1258 	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
1259 	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
1260 	19200, 7, 1, 4, 0xb, 0x755555}, {
1261 	19800, 8, 1, 11, 0x4, 0xA57EB}, {
1262 	20000, 9, 1, 11, 0x4, 0x0}, {
1263 	24000, 10, 3, 11, 0xa, 0x0}, {
1264 	25000, 11, 5, 16, 0xb, 0x0}, {
1265 	26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
1266 	30000, 13, 3, 8, 0xb, 0x0}, {
1267 	33600, 14, 1, 2, 0xd, 0x186186}, {
1268 	38400, 15, 1, 2, 0xb, 0x755555}, {
1269 	40000, 16, 1, 2, 0xb, 0}, {
1270 	0, 0, 0, 0, 0, 0}
1271 };
1272 
1273 #define	PMU1_XTALTAB0_880_12000K	0
1274 #define	PMU1_XTALTAB0_880_13000K	1
1275 #define	PMU1_XTALTAB0_880_14400K	2
1276 #define	PMU1_XTALTAB0_880_15360K	3
1277 #define	PMU1_XTALTAB0_880_16200K	4
1278 #define	PMU1_XTALTAB0_880_16800K	5
1279 #define	PMU1_XTALTAB0_880_19200K	6
1280 #define	PMU1_XTALTAB0_880_19800K	7
1281 #define	PMU1_XTALTAB0_880_20000K	8
1282 #define	PMU1_XTALTAB0_880_24000K	9
1283 #define	PMU1_XTALTAB0_880_25000K	10
1284 #define	PMU1_XTALTAB0_880_26000K	11
1285 #define	PMU1_XTALTAB0_880_30000K	12
1286 #define	PMU1_XTALTAB0_880_37400K	13
1287 #define	PMU1_XTALTAB0_880_38400K	14
1288 #define	PMU1_XTALTAB0_880_40000K	15
1289 
1290 /* the following table is based on 1760Mhz fvco */
1291 static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = {
1292 	{
1293 	12000, 1, 3, 44, 0x9, 0xFFFFEF}, {
1294 	13000, 2, 1, 12, 0xb, 0x483483}, {
1295 	14400, 3, 1, 20, 0xa, 0x1C71C7}, {
1296 	15360, 4, 1, 10, 0xb, 0x755555}, {
1297 	16200, 5, 1, 20, 0x5, 0x6E9E06}, {
1298 	16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, {
1299 	19200, 7, 1, 18, 0x5, 0x17B425}, {
1300 	19800, 8, 1, 22, 0x4, 0xA57EB}, {
1301 	20000, 9, 1, 22, 0x4, 0x0}, {
1302 	24000, 10, 3, 22, 0xa, 0x0}, {
1303 	25000, 11, 5, 32, 0xb, 0x0}, {
1304 	26000, 12, 1, 4, 0x10, 0xEC4EC4}, {
1305 	30000, 13, 3, 16, 0xb, 0x0}, {
1306 	38400, 14, 1, 10, 0x4, 0x955555}, {
1307 	40000, 15, 1, 4, 0xb, 0}, {
1308 	0, 0, 0, 0, 0, 0}
1309 };
1310 
1311 /* table index */
1312 #define	PMU1_XTALTAB0_1760_12000K	0
1313 #define	PMU1_XTALTAB0_1760_13000K	1
1314 #define	PMU1_XTALTAB0_1760_14400K	2
1315 #define	PMU1_XTALTAB0_1760_15360K	3
1316 #define	PMU1_XTALTAB0_1760_16200K	4
1317 #define	PMU1_XTALTAB0_1760_16800K	5
1318 #define	PMU1_XTALTAB0_1760_19200K	6
1319 #define	PMU1_XTALTAB0_1760_19800K	7
1320 #define	PMU1_XTALTAB0_1760_20000K	8
1321 #define	PMU1_XTALTAB0_1760_24000K	9
1322 #define	PMU1_XTALTAB0_1760_25000K	10
1323 #define	PMU1_XTALTAB0_1760_26000K	11
1324 #define	PMU1_XTALTAB0_1760_30000K	12
1325 #define	PMU1_XTALTAB0_1760_38400K	13
1326 #define	PMU1_XTALTAB0_1760_40000K	14
1327 
1328 /* the following table is based on 1440Mhz fvco */
1329 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
1330 	{
1331 	12000, 1, 1, 1, 0x78, 0x0}, {
1332 	13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
1333 	14400, 3, 1, 1, 0x64, 0x0}, {
1334 	15360, 4, 1, 1, 0x5D, 0xC00000}, {
1335 	16200, 5, 1, 1, 0x58, 0xE38E38}, {
1336 	16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
1337 	19200, 7, 1, 1, 0x4B, 0}, {
1338 	19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
1339 	20000, 9, 1, 1, 0x48, 0x0}, {
1340 	25000, 10, 1, 1, 0x39, 0x999999}, {
1341 	26000, 11, 1, 1, 0x37, 0x627627}, {
1342 	30000, 12, 1, 1, 0x30, 0x0}, {
1343 	37400, 13, 2, 1, 0x4D, 0x15E76}, {
1344 	38400, 13, 2, 1, 0x4B, 0x0}, {
1345 	40000, 14, 2, 1, 0x48, 0x0}, {
1346 	48000, 15, 2, 1, 0x3c, 0x0}, {
1347 	0, 0, 0, 0, 0, 0}
1348 };
1349 
1350 /* table index */
1351 #define	PMU1_XTALTAB0_1440_12000K	0
1352 #define	PMU1_XTALTAB0_1440_13000K	1
1353 #define	PMU1_XTALTAB0_1440_14400K	2
1354 #define	PMU1_XTALTAB0_1440_15360K	3
1355 #define	PMU1_XTALTAB0_1440_16200K	4
1356 #define	PMU1_XTALTAB0_1440_16800K	5
1357 #define	PMU1_XTALTAB0_1440_19200K	6
1358 #define	PMU1_XTALTAB0_1440_19800K	7
1359 #define	PMU1_XTALTAB0_1440_20000K	8
1360 #define	PMU1_XTALTAB0_1440_25000K	9
1361 #define	PMU1_XTALTAB0_1440_26000K	10
1362 #define	PMU1_XTALTAB0_1440_30000K	11
1363 #define	PMU1_XTALTAB0_1440_37400K	12
1364 #define	PMU1_XTALTAB0_1440_38400K	13
1365 #define	PMU1_XTALTAB0_1440_40000K	14
1366 #define	PMU1_XTALTAB0_1440_48000K	15
1367 
1368 #define	XTAL_FREQ_24000MHZ		24000
1369 #define	XTAL_FREQ_30000MHZ		30000
1370 #define	XTAL_FREQ_37400MHZ		37400
1371 #define	XTAL_FREQ_48000MHZ		48000
1372 
1373 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
1374 	{
1375 	12000, 1, 1, 1, 0x50, 0x0}, {
1376 	13000, 2, 1, 1, 0x49, 0xD89D89}, {
1377 	14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
1378 	15360, 4, 1, 1, 0x3E, 0x800000}, {
1379 	16200, 5, 1, 1, 0x39, 0x425ED0}, {
1380 	16800, 6, 1, 1, 0x39, 0x249249}, {
1381 	19200, 7, 1, 1, 0x32, 0x0}, {
1382 	19800, 8, 1, 1, 0x30, 0x7C1F07}, {
1383 	20000, 9, 1, 1, 0x30, 0x0}, {
1384 	25000, 10, 1, 1, 0x26, 0x666666}, {
1385 	26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
1386 	30000, 12, 1, 1, 0x20, 0x0}, {
1387 	37400, 13, 2, 1, 0x33, 0x563EF9}, {
1388 	38400, 14, 2, 1, 0x32, 0x0}, {
1389 	40000, 15, 2, 1, 0x30, 0x0}, {
1390 	48000, 16, 2, 1, 0x28, 0x0}, {
1391 	0, 0, 0, 0, 0, 0}
1392 };
1393 
1394 /* table index */
1395 #define	PMU1_XTALTAB0_960_12000K	0
1396 #define	PMU1_XTALTAB0_960_13000K	1
1397 #define	PMU1_XTALTAB0_960_14400K	2
1398 #define	PMU1_XTALTAB0_960_15360K	3
1399 #define	PMU1_XTALTAB0_960_16200K	4
1400 #define	PMU1_XTALTAB0_960_16800K	5
1401 #define	PMU1_XTALTAB0_960_19200K	6
1402 #define	PMU1_XTALTAB0_960_19800K	7
1403 #define	PMU1_XTALTAB0_960_20000K	8
1404 #define	PMU1_XTALTAB0_960_25000K	9
1405 #define	PMU1_XTALTAB0_960_26000K	10
1406 #define	PMU1_XTALTAB0_960_30000K	11
1407 #define	PMU1_XTALTAB0_960_37400K	12
1408 #define	PMU1_XTALTAB0_960_38400K	13
1409 #define	PMU1_XTALTAB0_960_40000K	14
1410 #define	PMU1_XTALTAB0_960_48000K	15
1411 
1412 /* select xtal table for each chip */
1413 static const pmu1_xtaltab0_t *
1414 bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc)
1415 {
1416 	switch (sc->cid.chip_id) {
1417 	case BHND_CHIPID_BCM4315:
1418 		return (pmu1_xtaltab0_1760);
1419 	case BHND_CHIPID_BCM4319:
1420 		return (pmu1_xtaltab0_1440);
1421 	case BHND_CHIPID_BCM4325:
1422 		return (pmu1_xtaltab0_880);
1423 	case BHND_CHIPID_BCM4329:
1424 		return (pmu1_xtaltab0_880_4329);
1425 	case BHND_CHIPID_BCM4336:
1426 		return (pmu1_xtaltab0_960);
1427 	case BHND_CHIPID_BCM4330:
1428 		if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1429 			return (pmu1_xtaltab0_960);
1430 		else
1431 			return (pmu1_xtaltab0_1440);
1432 	default:
1433 		PMU_DEBUG(sc, "bhnd_pmu1_xtaltab0: Unknown chipid %#hx\n",
1434 		    sc->cid.chip_id);
1435 		return (NULL);
1436 	}
1437 }
1438 
1439 /* select default xtal frequency for each chip */
1440 static const pmu1_xtaltab0_t *
1441 bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc)
1442 {
1443 	switch (sc->cid.chip_id) {
1444 	case BHND_CHIPID_BCM4315:
1445 		/* Default to 26000Khz */
1446 		return (&pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_26000K]);
1447 	case BHND_CHIPID_BCM4319:
1448 		/* Default to 30000Khz */
1449 		return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K]);
1450 	case BHND_CHIPID_BCM4325:
1451 		/* Default to 26000Khz */
1452 		return (&pmu1_xtaltab0_880[PMU1_XTALTAB0_880_26000K]);
1453 	case BHND_CHIPID_BCM4329:
1454 		/* Default to 38400Khz */
1455 		return (&pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]);
1456 	case BHND_CHIPID_BCM4336:
1457 		/* Default to 26000Khz */
1458 		return (&pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K]);
1459 	case BHND_CHIPID_BCM4330:
1460 		/* Default to 37400Khz */
1461 		if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1462 			return (&pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]);
1463 		else
1464 			return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]);
1465 	default:
1466 		PMU_DEBUG(sc, "bhnd_pmu1_xtaldef0: Unknown chipid %#hx\n",
1467 		    sc->cid.chip_id);
1468 		return (NULL);
1469 	}
1470 }
1471 
1472 /* select default pll fvco for each chip */
1473 static uint32_t
1474 bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc)
1475 {
1476 	switch (sc->cid.chip_id) {
1477 	case BHND_CHIPID_BCM4329:
1478 		return (FVCO_880);
1479 	case BHND_CHIPID_BCM4319:
1480 		return (FVCO_1440);
1481 	case BHND_CHIPID_BCM4336:
1482 		return (FVCO_960);
1483 	case BHND_CHIPID_BCM4330:
1484 		if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1485 			return (FVCO_960);
1486 		else
1487 			return (FVCO_1440);
1488 	default:
1489 		PMU_DEBUG(sc, "bhnd_pmu1_pllfvco0: Unknown chipid %#hx\n",
1490 		    sc->cid.chip_id);
1491 		return (0);
1492 	}
1493 }
1494 
1495 /* query alp/xtal clock frequency */
1496 static uint32_t
1497 bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc)
1498 {
1499 	const pmu1_xtaltab0_t	*xt;
1500 	uint32_t		 xf;
1501 
1502 	/* Find the frequency in the table */
1503 	xf = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1504 	xf = BHND_PMU_GET_BITS(xf, BHND_PMU_CTRL_XTALFREQ);
1505 
1506 	for (xt = bhnd_pmu1_xtaltab0(sc); xt != NULL && xt->fref != 0; xt++) {
1507 		if (xt->xf == xf)
1508 			break;
1509 	}
1510 
1511 	/* Could not find it so assign a default value */
1512 	if (xt == NULL || xt->fref == 0)
1513 		xt = bhnd_pmu1_xtaldef0(sc);
1514 
1515 	if (xt == NULL || xt->fref == 0) {
1516 		PMU_LOG(sc, "no matching ALP/XTAL frequency found\n");
1517 		return (0);
1518 	}
1519 
1520 	return (xt->fref * 1000);
1521 }
1522 
1523 /* Set up PLL registers in the PMU as per the crystal speed. */
1524 static void
1525 bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
1526 {
1527 	const pmu0_xtaltab0_t	*xt;
1528 	uint32_t		 pll_data, pll_mask;
1529 	uint32_t		 pll_res;
1530 	uint32_t		 pmu_ctrl;
1531 	uint32_t		 xf;
1532 
1533 	/* Use h/w default PLL config */
1534 	if (xtal == 0) {
1535 		PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL "
1536 		    "configuration\n");
1537 		return;
1538 	}
1539 
1540 	/* Find the frequency in the table */
1541 	for (xt = pmu0_xtaltab0; xt->freq; xt ++) {
1542 		if (xt->freq == xtal)
1543 			break;
1544 	}
1545 
1546 	if (xt->freq == 0)
1547 		xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
1548 
1549 	PMU_DEBUG(sc, "XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000,
1550 	    xt->xf);
1551 
1552 	/* Check current PLL state */
1553 	pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1554 	xf = BHND_PMU_GET_BITS(pmu_ctrl, BHND_PMU_CTRL_XTALFREQ);
1555 	if (xf == xt->xf) {
1556 #ifdef BCMUSBDEV
1557 		if (sc->cid.chip_id == BHND_CHIPID_BCM4328) {
1558 			bhnd_pmu0_sbclk4328(sc,
1559 			    BHND_PMU0_PLL0_PC0_DIV_ARM_88MHZ);
1560 			return;
1561 		}
1562 #endif	/* BCMUSBDEV */
1563 
1564 		PMU_DEBUG(sc, "PLL already programmed for %d.%d MHz\n",
1565 		         xt->freq / 1000, xt->freq % 1000);
1566 		return;
1567 	}
1568 
1569 	if (xf != 0) {
1570 		PMU_DEBUG(sc,
1571 		    "Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
1572 		    xt->freq / 1000, xt->freq % 1000,
1573 		    pmu0_xtaltab0[tmp-1].freq / 1000,
1574 		    pmu0_xtaltab0[tmp-1].freq % 1000);
1575 	} else {
1576 		PMU_DEBUG(sc, "Programming PLL for %d.%d MHz\n",
1577 		    xt->freq / 1000, xt->freq % 1000);
1578 	}
1579 
1580 	/* Make sure the PLL is off */
1581 	switch (sc->cid.chip_id) {
1582 	case BHND_CHIPID_BCM4328:
1583 		pll_res = PMURES_BIT(RES4328_BB_PLL_PU);
1584 		break;
1585 	case BHND_CHIPID_BCM5354:
1586 		pll_res = PMURES_BIT(RES5354_BB_PLL_PU);
1587 		break;
1588 	default:
1589 		panic("unsupported chipid %#hx\n", sc->cid.chip_id);
1590 	}
1591 	BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~pll_res);
1592 	BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~pll_res);
1593 
1594 	/* Wait for HT clock to shutdown. */
1595 	PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1596 
1597 	PMU_DEBUG(sc, "Done masking\n");
1598 
1599 	/* Write PDIV in pllcontrol[0] */
1600 	if (xt->freq >= BHND_PMU0_PLL0_PC0_PDIV_FREQ) {
1601 		BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0,
1602 		    BHND_PMU0_PLL0_PC0_PDIV_MASK, BHND_PMU0_PLL0_PC0_PDIV_MASK);
1603 	} else {
1604 		BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0, 0,
1605 		    BHND_PMU0_PLL0_PC0_PDIV_MASK);
1606 	}
1607 
1608 	/* Write WILD in pllcontrol[1] */
1609 	pll_data =
1610 	    BHND_PMU_SET_BITS(xt->wbint, BHND_PMU0_PLL0_PC1_WILD_INT) |
1611 	    BHND_PMU_SET_BITS(xt->wbfrac, BHND_PMU0_PLL0_PC1_WILD_FRAC);
1612 
1613 	if (xt->wbfrac == 0) {
1614 		pll_data |= BHND_PMU0_PLL0_PC1_STOP_MOD;
1615 	} else {
1616 		pll_data &= ~BHND_PMU0_PLL0_PC1_STOP_MOD;
1617 	}
1618 
1619 	pll_mask =
1620 	    BHND_PMU0_PLL0_PC1_WILD_INT_MASK |
1621 	    BHND_PMU0_PLL0_PC1_WILD_FRAC_MASK;
1622 
1623 	BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL1, pll_data, pll_mask);
1624 
1625 	/* Write WILD in pllcontrol[2] */
1626 	pll_data = BHND_PMU_SET_BITS(xt->wbint, BHND_PMU0_PLL0_PC2_WILD_INT);
1627 	pll_mask = BHND_PMU0_PLL0_PC2_WILD_INT_MASK;
1628 	BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL2, pll_data, pll_mask);
1629 
1630 	PMU_DEBUG(sc, "Done pll\n");
1631 
1632 	/* Write XtalFreq. Set the divisor also. */
1633 	pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1634 	pmu_ctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK|BHND_PMU_CTRL_XTALFREQ_MASK);
1635 
1636 	pmu_ctrl |= BHND_PMU_SET_BITS(((xt->freq + 127) / 128) - 1,
1637 	    BHND_PMU_CTRL_ILP_DIV);
1638 	pmu_ctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ);
1639 
1640 	BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmu_ctrl);
1641 }
1642 
1643 /* query alp/xtal clock frequency */
1644 static uint32_t
1645 bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc)
1646 {
1647 	const pmu0_xtaltab0_t	*xt;
1648 	uint32_t		 xf;
1649 
1650 	/* Find the frequency in the table */
1651 	xf = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1652 	xf = BHND_PMU_GET_BITS(xf, BHND_PMU_CTRL_XTALFREQ);
1653 	for (xt = pmu0_xtaltab0; xt->freq; xt++)
1654 		if (xt->xf == xf)
1655 			break;
1656 
1657 	/* PLL must be configured before */
1658 	if (xt == NULL || xt->freq == 0)
1659 		panic("unsupported frequency: %u", xf);
1660 
1661 	return (xt->freq * 1000);
1662 }
1663 
1664 /* query CPU clock frequency */
1665 static uint32_t
1666 bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc)
1667 {
1668 	uint32_t tmp, divarm;
1669 	uint32_t FVCO;
1670 #ifdef BCMDBG
1671 	uint32_t pdiv, wbint, wbfrac, fvco;
1672 	uint32_t freq;
1673 #endif
1674 
1675 	FVCO = FVCO_880;
1676 
1677 	/* Read divarm from pllcontrol[0] */
1678 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL0);
1679 	divarm = BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC0_DIV_ARM);
1680 
1681 #ifdef BCMDBG
1682 	/* Calculate fvco based on xtal freq, pdiv, and wild */
1683 	pdiv = tmp & BHND_PMU0_PLL0_PC0_PDIV_MASK;
1684 
1685 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL1);
1686 	wbfrac = BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC1_WILD_FRAC);
1687 	wbint = BHND_PMU_GET_BITS(tmp, PMU0_PLL0_PC1_WILD_INT);
1688 
1689 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL2);
1690 	wbint += BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC2_WILD_INT);
1691 
1692 	freq = bhnd_pmu0_alpclk0(sih, osh, cc) / 1000;
1693 
1694 	fvco = (freq * wbint) << 8;
1695 	fvco += (freq * (wbfrac >> 10)) >> 2;
1696 	fvco += (freq * (wbfrac & 0x3ff)) >> 10;
1697 	fvco >>= 8;
1698 	fvco >>= pdiv;
1699 	fvco /= 1000;
1700 	fvco *= 1000;
1701 
1702 	PMU_DEBUG(sc, "bhnd_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
1703 	         wbint, wbfrac, fvco);
1704 
1705 	FVCO = fvco;
1706 #endif	/* BCMDBG */
1707 
1708 	/* Return ARM/SB clock */
1709 	return FVCO / (divarm + BHND_PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
1710 }
1711 
1712 
1713 
1714 /* Set up PLL registers in the PMU as per the crystal speed. */
1715 static void
1716 bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
1717 {
1718 	const pmu1_xtaltab0_t		*xt;
1719 	uint32_t			 buf_strength;
1720 	uint32_t			 plladdr, plldata, pllmask;
1721 	uint32_t			 pmuctrl;
1722 	uint32_t			 FVCO;
1723 	uint8_t				 ndiv_mode;
1724 
1725 	FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000;
1726 	buf_strength = 0;
1727 	ndiv_mode = 1;
1728 
1729 	/* Use h/w default PLL config */
1730 	if (xtal == 0) {
1731 		PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL "
1732 		    "configuration\n");
1733 		return;
1734 	}
1735 
1736 	/* Find the frequency in the table */
1737 	for (xt = bhnd_pmu1_xtaltab0(&sc->query); xt != NULL && xt->fref != 0;
1738 	    xt++)
1739 	{
1740 		if (xt->fref == xtal)
1741 			break;
1742 	}
1743 
1744 	/* Check current PLL state, bail out if it has been programmed or
1745 	 * we don't know how to program it.
1746 	 */
1747 	if (xt == NULL || xt->fref == 0) {
1748 		PMU_LOG(sc, "Unsupported XTAL frequency %d.%dMHz, skipping PLL "
1749 		    "configuration\n", xtal / 1000, xtal % 1000);
1750 		return;
1751 	}
1752 
1753 	/* For 4319 bootloader already programs the PLL but bootloader does not
1754 	 * program the PLL4 and PLL5. So Skip this check for 4319. */
1755 	pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1756 	if (BHND_PMU_GET_BITS(pmuctrl, BHND_PMU_CTRL_XTALFREQ) == xt->xf &&
1757 	    sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
1758 	    sc->cid.chip_id != BHND_CHIPID_BCM4330)
1759 	{
1760 		PMU_DEBUG(sc, "PLL already programmed for %d.%dMHz\n",
1761 		    xt->fref / 1000, xt->fref % 1000);
1762 		return;
1763 	}
1764 
1765 	PMU_DEBUG(sc, "XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf);
1766 	PMU_DEBUG(sc, "Programming PLL for %d.%dMHz\n", xt->fref / 1000,
1767 		 xt->fref % 1000);
1768 
1769 	switch (sc->cid.chip_id) {
1770 	case BHND_CHIPID_BCM4325:
1771 		/* Change the BBPLL drive strength to 2 for all channels */
1772 		buf_strength = 0x222222;
1773 
1774 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1775 			~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
1776 			  PMURES_BIT(RES4325_HT_AVAIL)));
1777 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1778 			~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
1779 			  PMURES_BIT(RES4325_HT_AVAIL)));
1780 
1781 		/* Wait for HT clock to shutdown. */
1782 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1783 		break;
1784 
1785 	case BHND_CHIPID_BCM4329:
1786 		/* Change the BBPLL drive strength to 8 for all channels */
1787 		buf_strength = 0x888888;
1788 
1789 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1790 			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1791 			  PMURES_BIT(RES4329_HT_AVAIL)));
1792 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1793 			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1794 			  PMURES_BIT(RES4329_HT_AVAIL)));
1795 
1796 		/* Wait for HT clock to shutdown. */
1797 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1798 
1799 		/* Initialize PLL4 */
1800 		plladdr = BHND_PMU1_PLL0_PLLCTL4;
1801 		if (xt->fref == 38400)
1802 			plldata = 0x200024C0;
1803 		else if (xt->fref == 37400)
1804 			plldata = 0x20004500;
1805 		else if (xt->fref == 26000)
1806 			plldata = 0x200024C0;
1807 		else
1808 			plldata = 0x200005C0;	/* Chip Dflt Settings */
1809 
1810 		BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0);
1811 
1812 		/* Initialize PLL5 */
1813 		plladdr = BHND_PMU1_PLL0_PLLCTL5;
1814 
1815 		plldata = BHND_PMU_PLL_READ(sc, plladdr);
1816 		plldata &= BHND_PMU1_PLL0_PC5_CLK_DRV_MASK;
1817 
1818 		if (xt->fref == 38400 ||
1819 		    xt->fref == 37400 ||
1820 		    xt->fref == 26000) {
1821 			plldata |= 0x15;
1822 		} else {
1823 			plldata |= 0x25;	/* Chip Dflt Settings */
1824 		}
1825 
1826 		BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0);
1827 		break;
1828 
1829 	case BHND_CHIPID_BCM4319:
1830 		/* Change the BBPLL drive strength to 2 for all channels */
1831 		buf_strength = 0x222222;
1832 
1833 		/* Make sure the PLL is off */
1834 		/* WAR65104: Disable the HT_AVAIL resource first and then
1835 		 * after a delay (more than downtime for HT_AVAIL) remove the
1836 		 * BBPLL resource; backplane clock moves to ALP from HT.
1837 		 */
1838 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1839 			~(PMURES_BIT(RES4319_HT_AVAIL)));
1840 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1841 			~(PMURES_BIT(RES4319_HT_AVAIL)));
1842 
1843 		DELAY(100);
1844 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1845 			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1846 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1847 			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1848 
1849 		DELAY(100);
1850 
1851 		/* Wait for HT clock to shutdown. */
1852 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1853 
1854 		plldata = 0x200005c0;
1855 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, plldata, ~0);
1856 		break;
1857 
1858 	case BHND_CHIPID_BCM4336:
1859 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1860 			~(PMURES_BIT(RES4336_HT_AVAIL) |
1861 			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1862 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1863 			~(PMURES_BIT(RES4336_HT_AVAIL) |
1864 			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1865 		DELAY(100);
1866 
1867 		/* Wait for HT clock to shutdown. */
1868 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1869 
1870 		break;
1871 
1872 	case BHND_CHIPID_BCM4330:
1873 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1874 			~(PMURES_BIT(RES4330_HT_AVAIL) |
1875 			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1876 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1877 			~(PMURES_BIT(RES4330_HT_AVAIL) |
1878 			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1879 		DELAY(100);
1880 
1881 		/* Wait for HT clock to shutdown. */
1882 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1883 
1884 		break;
1885 
1886 	default:
1887 		panic("unsupported chipid %#hx\n", sc->cid.chip_id);
1888 	}
1889 
1890 	PMU_DEBUG(sc, "Done masking\n");
1891 
1892 	/* Write p1div and p2div to pllcontrol[0] */
1893 	plldata =
1894 	    BHND_PMU_SET_BITS(xt->p1div, BHND_PMU1_PLL0_PC0_P1DIV) |
1895 	    BHND_PMU_SET_BITS(xt->p2div, BHND_PMU1_PLL0_PC0_P2DIV);
1896 	pllmask = BHND_PMU1_PLL0_PC0_P1DIV_MASK|BHND_PMU1_PLL0_PC0_P2DIV_MASK;
1897 
1898 	if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1899 		plldata &= ~(BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK);
1900 		pllmask |= BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK;
1901 		if (!xt->ndiv_frac) {
1902 			plldata |= BHND_PMU_SET_BITS(1,
1903 			    BHND_PMU1_PLL0_PC0_BYPASS_SDMOD);
1904 		}
1905 	}
1906 
1907 	BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, plldata, pllmask);
1908 
1909 
1910 	if (sc->cid.chip_id == BHND_CHIPID_BCM4330)
1911 		bhnd_pmu_set_4330_plldivs(sc);
1912 
1913 	if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) {
1914 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
1915 		    BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_VAL,
1916 		    BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
1917 	}
1918 
1919 	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1920 	if (sc->cid.chip_id == BHND_CHIPID_BCM4336 ||
1921 	    sc->cid.chip_id == BHND_CHIPID_BCM4330)
1922 	{
1923 		ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB;
1924 	} else if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1925 		if (!(xt->ndiv_frac))
1926 			ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_INT;
1927 		else
1928 			ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB;
1929 	} else {
1930 		ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MASH;
1931 	}
1932 
1933 
1934 	BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
1935 	    BHND_PMU_SET_BITS(xt->ndiv_int, BHND_PMU1_PLL0_PC2_NDIV_INT) |
1936 	    BHND_PMU_SET_BITS(ndiv_mode, BHND_PMU1_PLL0_PC2_NDIV_MODE),
1937 	    BHND_PMU1_PLL0_PC2_NDIV_INT_MASK |
1938 	    BHND_PMU1_PLL0_PC2_NDIV_MODE_MASK);
1939 
1940 	/* Write ndiv_frac to pllcontrol[3] */
1941 	BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
1942 	    BHND_PMU_SET_BITS(xt->ndiv_frac, BHND_PMU1_PLL0_PC3_NDIV_FRAC),
1943 	    BHND_PMU1_PLL0_PC3_NDIV_FRAC_MASK);
1944 
1945 	/* Writing to pllcontrol[4]  */
1946 	if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1947 		uint8_t xs;
1948 
1949 		if (!xt->ndiv_frac)
1950 		        plldata = 0x200005c0;
1951 		else
1952 		        plldata = 0x202C2820;
1953 
1954 		if (FVCO < 1600)
1955 			xs = 4;
1956 		else
1957 		        xs = 7;
1958 
1959 		plldata &= ~(BHND_PMU1_PLL0_PC4_KVCO_XS_MASK);
1960 		plldata |= BHND_PMU_SET_BITS(xs, BHND_PMU1_PLL0_PC4_KVCO_XS);
1961 		BHND_PMU_WRITE_4(sc, BHND_PMU1_PLL0_PLLCTL4, plldata);
1962 	}
1963 
1964 	/* Write clock driving strength to pllcontrol[5] */
1965 	if (buf_strength) {
1966 		PMU_DEBUG(sc, "Adjusting PLL buffer drive strength: %x\n",
1967 		    buf_strength);
1968 
1969 		plldata = BHND_PMU_SET_BITS(buf_strength,
1970 		    BHND_PMU1_PLL0_PC5_CLK_DRV);
1971 		pllmask = BHND_PMU1_PLL0_PC5_CLK_DRV_MASK;
1972 
1973 		if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1974 			pllmask |=
1975 			    BHND_PMU1_PLL0_PC5_VCO_RNG_MASK |
1976 			    BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK;
1977 
1978 			if (!xt->ndiv_frac) {
1979 				plldata |= BHND_PMU_SET_BITS(0x25,
1980 				    BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32);
1981 			} else {
1982 				plldata |= BHND_PMU_SET_BITS(0x15,
1983 				    BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32);
1984 			}
1985 
1986 			if (FVCO >= 1600) {
1987 				plldata |= BHND_PMU_SET_BITS(0x1,
1988 				    BHND_PMU1_PLL0_PC5_VCO_RNG);
1989 			}
1990 		}
1991 
1992 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, plldata,
1993 		    pllmask);
1994 	}
1995 
1996 	PMU_DEBUG(sc, "Done pll\n");
1997 
1998 	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1999 	 * to be updated.
2000 	 */
2001 	if (sc->cid.chip_id == BHND_CHIPID_BCM4319 &&
2002 	    xt->fref != XTAL_FREQ_30000MHZ)
2003 	{
2004 		uint32_t pll_sel;
2005 
2006 		switch (xt->fref) {
2007 		case XTAL_FREQ_24000MHZ:
2008 			pll_sel = BHND_PMU_CCTL_4319USB_24MHZ_PLL_SEL;
2009 			break;
2010 		case XTAL_FREQ_48000MHZ:
2011 			pll_sel = BHND_PMU_CCTL_4319USB_48MHZ_PLL_SEL;
2012 			break;
2013 		default:
2014 			panic("unsupported 4319USB XTAL frequency: %hu\n",
2015 			    xt->fref);
2016 		}
2017 
2018 		BHND_PMU_CCTRL_WRITE(sc, BHND_PMU1_PLL0_CHIPCTL2,
2019 		    BHND_PMU_SET_BITS(pll_sel, BHND_PMU_CCTL_4319USB_XTAL_SEL),
2020 		    BHND_PMU_CCTL_4319USB_XTAL_SEL_MASK);
2021 	}
2022 
2023 	/* Flush deferred pll control registers writes */
2024 	if (BHND_PMU_REV(sc) >= 2)
2025 		BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_PLL_PLLCTL_UPD);
2026 
2027 	/* Write XtalFreq. Set the divisor also. */
2028 	pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
2029 	pmuctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK | BHND_PMU_CTRL_XTALFREQ_MASK);
2030 	pmuctrl |= BHND_PMU_SET_BITS(((xt->fref + 127) / 128) - 1,
2031 	    BHND_PMU_CTRL_ILP_DIV);
2032 	pmuctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ);
2033 
2034 	if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) {
2035 		/* clear the htstretch before clearing HTReqEn */
2036 		BHND_PMU_AND_4(sc, BHND_PMU_CLKSTRETCH, ~BHND_PMU_CLKSTRETCH);
2037 		pmuctrl &= ~BHND_PMU_CTRL_HT_REQ_EN;
2038 	}
2039 
2040 	BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmuctrl);
2041 }
2042 
2043 /* query the CPU clock frequency */
2044 static uint32_t
2045 bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc)
2046 {
2047 	uint32_t tmp, m1div;
2048 #ifdef BCMDBG
2049 	uint32_t ndiv_int, ndiv_frac, p2div, p1div, fvco;
2050 	uint32_t fref;
2051 #endif
2052 	uint32_t FVCO = bhnd_pmu1_pllfvco0(sc);
2053 
2054 	/* Read m1div from pllcontrol[1] */
2055 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL1);
2056 	m1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC1_M1DIV);
2057 
2058 #ifdef BCMDBG
2059 	/* Read p2div/p1div from pllcontrol[0] */
2060 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL0);
2061 	p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P2DIV);
2062 	p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P1DIV);
2063 
2064 	/* Calculate fvco based on xtal freq and ndiv and pdiv */
2065 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL2);
2066 	ndiv_int = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC2_NDIV_INT);
2067 
2068 	tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL3);
2069 	ndiv_frac = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC3_NDIV_FRAC);
2070 
2071 	fref = bhnd_pmu1_alpclk0(sc) / 1000;
2072 
2073 	fvco = (fref * ndiv_int) << 8;
2074 	fvco += (fref * (ndiv_frac >> 12)) >> 4;
2075 	fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
2076 	fvco >>= 8;
2077 	fvco *= p2div;
2078 	fvco /= p1div;
2079 	fvco /= 1000;
2080 	fvco *= 1000;
2081 
2082 	PMU_DEBUG(sc, "bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u "
2083 	    "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco);
2084 
2085 	FVCO = fvco;
2086 #endif				/* BCMDBG */
2087 
2088 	/* Return ARM/SB clock */
2089 	return (FVCO / m1div * 1000);
2090 }
2091 
2092 /* initialize PLL */
2093 void
2094 bhnd_pmu_pll_init(struct bhnd_pmu_softc *sc, u_int xtalfreq)
2095 {
2096 	uint32_t max_mask, min_mask;
2097 	uint32_t res_ht, res_pll;
2098 
2099 	switch (sc->cid.chip_id) {
2100 	case BHND_CHIPID_BCM4312:
2101 		/* assume default works */
2102 		break;
2103 	case BHND_CHIPID_BCM4322:
2104 	case BHND_CHIPID_BCM43221:
2105 	case BHND_CHIPID_BCM43231:
2106 	case BHND_CHIPID_BCM4342:
2107 		if (sc->cid.chip_rev != 0)
2108 			break;
2109 
2110 		min_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK);
2111 		max_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK);
2112 		res_ht = PMURES_BIT(RES4322_HT_SI_AVAIL);
2113 		res_pll = PMURES_BIT(RES4322_SI_PLL_ON);
2114 
2115 		/* Have to remove HT Avail request before powering off PLL */
2116 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_ht);
2117 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_ht);
2118 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2119 
2120 		/* Make sure the PLL is off */
2121 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_pll);
2122 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_pll);
2123 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2124 
2125 		DELAY(1000);
2126 
2127 		BHND_PMU_PLL_WRITE(sc, BHND_PMU2_SI_PLL_PLLCTL, 0x380005c0, ~0);
2128 		DELAY(100);
2129 
2130 		BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask);
2131 		DELAY(100);
2132 		BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask);
2133 		DELAY(100);
2134 
2135 		break;
2136 	case BHND_CHIPID_BCM4325:
2137 		bhnd_pmu1_pllinit0(sc, xtalfreq);
2138 		break;
2139 	case BHND_CHIPID_BCM4328:
2140 		bhnd_pmu0_pllinit0(sc, xtalfreq);
2141 		break;
2142 	case BHND_CHIPID_BCM5354:
2143 		if (xtalfreq == 0)
2144 			xtalfreq = 25000;
2145 		bhnd_pmu0_pllinit0(sc, xtalfreq);
2146 		break;
2147 	case BHND_CHIPID_BCM4329:
2148 		if (xtalfreq == 0)
2149 			xtalfreq = 38400;
2150 		bhnd_pmu1_pllinit0(sc, xtalfreq);
2151 		break;
2152 
2153 	case BHND_CHIPID_BCM4313:
2154 	case BHND_CHIPID_BCM43222:
2155 	case BHND_CHIPID_BCM43111:
2156 	case BHND_CHIPID_BCM43112:
2157 	case BHND_CHIPID_BCM43224:
2158 	case BHND_CHIPID_BCM43225:
2159 	case BHND_CHIPID_BCM43420:
2160 	case BHND_CHIPID_BCM43421:
2161 	case BHND_CHIPID_BCM43226:
2162 	case BHND_CHIPID_BCM43235:
2163 	case BHND_CHIPID_BCM43236:
2164 	case BHND_CHIPID_BCM43238:
2165 	case BHND_CHIPID_BCM43234:
2166 	case BHND_CHIPID_BCM43237:
2167 	case BHND_CHIPID_BCM4331:
2168 	case BHND_CHIPID_BCM43431:
2169 	case BHND_CHIPID_BCM43131:
2170 	case BHND_CHIPID_BCM43227:
2171 	case BHND_CHIPID_BCM43228:
2172 	case BHND_CHIPID_BCM43428:
2173 	case BHND_CHIPID_BCM6362:
2174 		/* assume default works */
2175 		break;
2176 
2177 	case BHND_CHIPID_BCM4315:
2178 	case BHND_CHIPID_BCM4319:
2179 	case BHND_CHIPID_BCM4336:
2180 	case BHND_CHIPID_BCM4330:
2181 		bhnd_pmu1_pllinit0(sc, xtalfreq);
2182 		break;
2183 	default:
2184 		PMU_DEBUG("No PLL init done for chip %#hx rev %d pmurev %d\n",
2185 		    sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc));
2186 		break;
2187 	}
2188 }
2189 
2190 /**
2191  * Return the ALP/XTAL clock frequency, in Hz.
2192  *
2193  * @param sc PMU query instance.
2194  */
2195 uint32_t
2196 bhnd_pmu_alp_clock(struct bhnd_pmu_query *sc)
2197 {
2198 	uint32_t clock;
2199 
2200 	clock = BHND_PMU_ALP_CLOCK;
2201 	switch (sc->cid.chip_id) {
2202 	case BHND_CHIPID_BCM4328:
2203 	case BHND_CHIPID_BCM5354:
2204 		clock = bhnd_pmu0_alpclk0(sc);
2205 		break;
2206 	case BHND_CHIPID_BCM4315:
2207 	case BHND_CHIPID_BCM4319:
2208 	case BHND_CHIPID_BCM4325:
2209 	case BHND_CHIPID_BCM4329:
2210 	case BHND_CHIPID_BCM4330:
2211 	case BHND_CHIPID_BCM4336:
2212 		clock = bhnd_pmu1_alpclk0(sc);
2213 		break;
2214 	case BHND_CHIPID_BCM4312:
2215 	case BHND_CHIPID_BCM4322:
2216 	case BHND_CHIPID_BCM43221:
2217 	case BHND_CHIPID_BCM43231:
2218 	case BHND_CHIPID_BCM43222:
2219 	case BHND_CHIPID_BCM43111:
2220 	case BHND_CHIPID_BCM43112:
2221 	case BHND_CHIPID_BCM43224:
2222 	case BHND_CHIPID_BCM43225:
2223 	case BHND_CHIPID_BCM43420:
2224 	case BHND_CHIPID_BCM43421:
2225 	case BHND_CHIPID_BCM43226:
2226 	case BHND_CHIPID_BCM43235:
2227 	case BHND_CHIPID_BCM43236:
2228 	case BHND_CHIPID_BCM43238:
2229 	case BHND_CHIPID_BCM43234:
2230 	case BHND_CHIPID_BCM43237:
2231 	case BHND_CHIPID_BCM4331:
2232 	case BHND_CHIPID_BCM43431:
2233 	case BHND_CHIPID_BCM43131:
2234 	case BHND_CHIPID_BCM43227:
2235 	case BHND_CHIPID_BCM43228:
2236 	case BHND_CHIPID_BCM43428:
2237 	case BHND_CHIPID_BCM6362:
2238 	case BHND_CHIPID_BCM4342:
2239 	case BHND_CHIPID_BCM4716:
2240 	case BHND_CHIPID_BCM4748:
2241 	case BHND_CHIPID_BCM47162:
2242 	case BHND_CHIPID_BCM4313:
2243 	case BHND_CHIPID_BCM5357:
2244 	case BHND_CHIPID_BCM4749:
2245 	case BHND_CHIPID_BCM53572:
2246 		/* always 20Mhz */
2247 		clock = 20000 * 1000;
2248 		break;
2249 	case BHND_CHIPID_BCM5356:
2250 	case BHND_CHIPID_BCM4706:
2251 		/* always 25Mhz */
2252 		clock = 25000 * 1000;
2253 		break;
2254 	default:
2255 		PMU_DEBUG("No ALP clock specified "
2256 			 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2257 			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
2258 			 sih->pmurev, clock);
2259 		break;
2260 	}
2261 
2262 	return (clock);
2263 }
2264 
2265 /* Find the output of the "m" pll divider given pll controls that start with
2266  * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
2267  */
2268 static uint32_t
2269 bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
2270 {
2271 	uint32_t div;
2272 	uint32_t fc;
2273 	uint32_t ndiv;
2274 	uint32_t p1, p2;
2275 	uint32_t tmp;
2276 
2277 	if ((pll0 & 3) || (pll0 > BHND_PMU4716_MAINPLL_PLL0)) {
2278 		PMU_LOG(sc, "%s: Bad pll0: %d", __func__, pll0);
2279 		return (0);
2280 	}
2281 
2282 	/* Strictly there is an m5 divider, but I'm not sure we use it */
2283 	if ((m == 0) || (m > 4)) {
2284 		PMU_LOG(sc, "%s: Bad m divider: %d", __func__, m);
2285 		return (0);
2286 	}
2287 
2288 	if (sc->cid.chip_id == BHND_CHIPID_BCM5357 ||
2289 	    sc->cid.chip_id == BHND_CHIPID_BCM4749)
2290 	{
2291 		/* Detect failure in clock setting */
2292 		tmp = sc->io->rd_chipst(sc->io_ctx);
2293 		if ((tmp & 0x40000) != 0)
2294 			return (133 * 1000000);
2295 	}
2296 
2297 
2298 	/* Fetch p1 and p2 */
2299 	BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2300 	    pll0 + BHND_PMU5_PLL_P1P2_OFF);
2301 	BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2302 
2303 	tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2304 	p1 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P1);
2305 	p2 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P2);
2306 
2307 	/* Fetch div */
2308 	BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2309 	    pll0 + BHND_PMU5_PLL_M14_OFF);
2310 	BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2311 
2312 	tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2313 	div = (tmp >> ((m - 1) * BHND_PMU5_PLL_MDIV_WIDTH));
2314 	div &= BHND_PMU5_PLL_MDIV_MASK;
2315 
2316 	/* Fetch ndiv */
2317 	BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2318 	    pll0 + BHND_PMU5_PLL_NM5_OFF);
2319 	BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2320 
2321 	tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2322 	ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_NDIV);
2323 
2324 	/* Do calculation in Mhz */
2325 	fc = bhnd_pmu_alp_clock(sc) / 1000000;
2326 	fc = (p1 * ndiv * fc) / p2;
2327 
2328 	PMU_DEBUG(sc, "%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, "
2329 	    "clock=%d\n", __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div);
2330 
2331 	/* Return clock in Hertz */
2332 	return ((fc / div) * 1000000);
2333 }
2334 
2335 static uint32_t
2336 bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
2337 {
2338 	uint32_t chipst, clock;
2339 	uint32_t ndiv, p1div, p2div, tmp;
2340 
2341 	/* Get N, P1 and P2 dividers to determine CPU clock */
2342 	BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2343 	    pll0 + BHND_PMU6_4706_PROCPLL_OFF);
2344 	BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2345 
2346 	tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2347 	ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_NDIV_INT);
2348 	p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P1DIV);
2349 	p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P2DIV);
2350 
2351 	/* Fixed 25MHz reference clock */
2352 	clock = 25 * 1000 * 1000;
2353 
2354 	/* The low-cost bonding uses an input divider of 4; otherwise, 2 */
2355 	chipst = sc->io->rd_chipst(sc->io_ctx);
2356 	if (chipst & CHIPC_CST4706_LOWCOST_PKG)
2357 		clock /= 4;
2358 	else
2359 		clock /= 2;
2360 
2361 	clock *= ndiv * p2div / p1div;
2362 
2363 	switch (m) {
2364 	case BHND_PMU6_MAINPLL_CPU:
2365 		return (clock);
2366 	case BHND_PMU6_MAINPLL_MEM:
2367 		return (clock / 2);
2368 	case BHND_PMU6_MAINPLL_SI:
2369 		return (clock / 4);
2370 	default:
2371 		PMU_LOG(sc, "bad m divider: %d", m);
2372 		return (0);
2373 	}
2374 }
2375 
2376 /**
2377  * Return the backplane clock frequency, in Hz.
2378  *
2379  * On designs that feed the same clock to both backplane
2380  * and CPU, this returns the CPU clock speed.
2381  *
2382  * @param sc PMU query instance.
2383  */
2384 uint32_t
2385 bhnd_pmu_si_clock(struct bhnd_pmu_query *sc)
2386 {
2387 	uint32_t chipst;
2388 	uint32_t clock;
2389 
2390 	clock = BHND_PMU_HT_CLOCK;
2391 
2392 	switch (sc->cid.chip_id) {
2393 	case BHND_CHIPID_BCM4322:
2394 	case BHND_CHIPID_BCM43221:
2395 	case BHND_CHIPID_BCM43231:
2396 	case BHND_CHIPID_BCM43222:
2397 	case BHND_CHIPID_BCM43111:
2398 	case BHND_CHIPID_BCM43112:
2399 	case BHND_CHIPID_BCM43224:
2400 	case BHND_CHIPID_BCM43420:
2401 	case BHND_CHIPID_BCM43225:
2402 	case BHND_CHIPID_BCM43421:
2403 	case BHND_CHIPID_BCM43226:
2404 	case BHND_CHIPID_BCM4331:
2405 	case BHND_CHIPID_BCM43431:
2406 	case BHND_CHIPID_BCM6362:
2407 	case BHND_CHIPID_BCM4342:
2408 		/* 96MHz backplane clock */
2409 		clock = 96000 * 1000;
2410 		break;
2411 
2412 	case BHND_CHIPID_BCM4716:
2413 	case BHND_CHIPID_BCM4748:
2414 	case BHND_CHIPID_BCM47162:
2415 		clock = bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2416 		    BHND_PMU5_MAINPLL_SI);
2417 		break;
2418 
2419 	case BHND_CHIPID_BCM4325:
2420 		clock = bhnd_pmu1_cpuclk0(sc);
2421 		break;
2422 
2423 	case BHND_CHIPID_BCM4328:
2424 		clock = bhnd_pmu0_cpuclk0(sc);
2425 		break;
2426 
2427 	case BHND_CHIPID_BCM4329:
2428 		if (sc->cid.chip_rev == 0)
2429 			clock = 38400 * 1000;
2430 		else
2431 			clock = bhnd_pmu1_cpuclk0(sc);
2432 		break;
2433 
2434 	case BHND_CHIPID_BCM4315:
2435 	case BHND_CHIPID_BCM4319:
2436 	case BHND_CHIPID_BCM4336:
2437 	case BHND_CHIPID_BCM4330:
2438 		clock = bhnd_pmu1_cpuclk0(sc);
2439 		break;
2440 
2441 	case BHND_CHIPID_BCM4313:
2442 		/* 80MHz backplane clock */
2443 		clock = 80000 * 1000;
2444 		break;
2445 
2446 	case BHND_CHIPID_BCM43234:
2447 	case BHND_CHIPID_BCM43235:
2448 	case BHND_CHIPID_BCM43236:
2449 	case BHND_CHIPID_BCM43238:
2450 		chipst = sc->io->rd_chipst(sc->io_ctx);
2451 		if (chipst & CHIPC_CST43236_BP_CLK)
2452 			clock = 120000 * 1000;
2453 		else
2454 			clock = 96000 * 1000;
2455 		break;
2456 	case BHND_CHIPID_BCM43237:
2457 		chipst = sc->io->rd_chipst(sc->io_ctx);
2458 		if (chipst & CHIPC_CST43237_BP_CLK)
2459 			clock = 96000 * 1000;
2460 		else
2461 			clock = 80000 * 1000;
2462 		break;
2463 	case BHND_CHIPID_BCM5356:
2464 		clock = bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2465 		    BHND_PMU5_MAINPLL_SI);
2466 		break;
2467 	case BHND_CHIPID_BCM5357:
2468 	case BHND_CHIPID_BCM4749:
2469 		clock = bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2470 		    BHND_PMU5_MAINPLL_SI);
2471 		break;
2472 	case BHND_CHIPID_BCM4706:
2473 		clock = bhnd_pmu6_4706_clock(sc, BHND_PMU4706_MAINPLL_PLL0,
2474 		    BHND_PMU6_MAINPLL_SI);
2475 		break;
2476 	case BHND_CHIPID_BCM53572:
2477 		clock = 75000000;
2478 		break;
2479 	default:
2480 		PMU_LOG(sc, "No backplane clock specified for chip %#hx rev "
2481 		    "%hhd pmurev %hhd, using default %dHz\n",
2482 		    sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc), clock);
2483 		break;
2484 	}
2485 
2486 	return (clock);
2487 }
2488 
2489 /**
2490  * Return the CPU clock frequency, in Hz.
2491  *
2492  * @param sc PMU query instance.
2493  */
2494 uint32_t
2495 bhnd_pmu_cpu_clock(struct bhnd_pmu_query *sc)
2496 {
2497 	/* 5354 chip uses a non programmable PLL of frequency 240MHz */
2498 	if (sc->cid.chip_id == BHND_CHIPID_BCM5354)
2499 		return (240 * 1000 * 1000); /* 240MHz */
2500 
2501 	if (sc->cid.chip_id == BHND_CHIPID_BCM53572)
2502 		return (300000000);
2503 
2504 	if (BHND_PMU_REV(sc) >= 5 &&
2505 	    sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
2506 	    sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
2507 	    sc->cid.chip_id != BHND_CHIPID_BCM43234 &&
2508 	    sc->cid.chip_id != BHND_CHIPID_BCM43235 &&
2509 	    sc->cid.chip_id != BHND_CHIPID_BCM43236 &&
2510 	    sc->cid.chip_id != BHND_CHIPID_BCM43237 &&
2511 	    sc->cid.chip_id != BHND_CHIPID_BCM43238 &&
2512 	    sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
2513 	    sc->cid.chip_id != BHND_CHIPID_BCM4330)
2514 	{
2515 		switch (sc->cid.chip_id) {
2516 		case BHND_CHIPID_BCM5356:
2517 			return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2518 			    BHND_PMU5_MAINPLL_CPU));
2519 
2520 		case BHND_CHIPID_BCM5357:
2521 		case BHND_CHIPID_BCM4749:
2522 			return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2523 			    BHND_PMU5_MAINPLL_CPU));
2524 
2525 		case BHND_CHIPID_BCM4706:
2526 			return (bhnd_pmu6_4706_clock(sc,
2527 			    BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_CPU));
2528 
2529 		default:
2530 			return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2531 			    BHND_PMU5_MAINPLL_CPU));
2532 		}
2533 	} else {
2534 		return (bhnd_pmu_si_clock(sc));
2535 	}
2536 }
2537 
2538 /**
2539  * Return the memory clock frequency, in Hz.
2540  *
2541  * @param sc PMU query instance.
2542  */
2543 uint32_t
2544 bhnd_pmu_mem_clock(struct bhnd_pmu_query *sc)
2545 {
2546 	if (BHND_PMU_REV(sc) >= 5 &&
2547 	    sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
2548 	    sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
2549 	    sc->cid.chip_id != BHND_CHIPID_BCM43234 &&
2550 	    sc->cid.chip_id != BHND_CHIPID_BCM43235 &&
2551 	    sc->cid.chip_id != BHND_CHIPID_BCM43236 &&
2552 	    sc->cid.chip_id != BHND_CHIPID_BCM43237 &&
2553 	    sc->cid.chip_id != BHND_CHIPID_BCM43238 &&
2554 	    sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
2555 	    sc->cid.chip_id != BHND_CHIPID_BCM4330)
2556 	{
2557 		switch (sc->cid.chip_id) {
2558 		case BHND_CHIPID_BCM5356:
2559 			return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2560 			    BHND_PMU5_MAINPLL_MEM));
2561 
2562 		case BHND_CHIPID_BCM5357:
2563 		case BHND_CHIPID_BCM4749:
2564 			return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2565 			    BHND_PMU5_MAINPLL_MEM));
2566 
2567 		case BHND_CHIPID_BCM4706:
2568 			return (bhnd_pmu6_4706_clock(sc,
2569 			    BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_MEM));
2570 
2571 		default:
2572 			return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2573 			    BHND_PMU5_MAINPLL_MEM));
2574 		}
2575 
2576 	} else {
2577 		return (bhnd_pmu_si_clock(sc));
2578 	}
2579 }
2580 
2581 /* Measure ILP clock frequency */
2582 #define	ILP_CALC_DUR	10	/* ms, make sure 1000 can be divided by it. */
2583 
2584 /**
2585  * Measure and return the ILP clock frequency, in Hz.
2586  *
2587  * @param sc PMU query instance.
2588  */
2589 uint32_t
2590 bhnd_pmu_ilp_clock(struct bhnd_pmu_query *sc)
2591 {
2592 	uint32_t start, end, delta;
2593 
2594 	if (sc->ilp_cps == 0) {
2595 		start = BHND_PMU_READ_4(sc, BHND_PMU_TIMER);
2596 		DELAY(ILP_CALC_DUR);
2597 		end = BHND_PMU_READ_4(sc, BHND_PMU_TIMER);
2598 		delta = end - start;
2599 		sc->ilp_cps = delta * (1000 / ILP_CALC_DUR);
2600 	}
2601 
2602 	return (sc->ilp_cps);
2603 }
2604 
2605 /* SDIO Pad drive strength to select value mappings */
2606 typedef struct {
2607 	uint8_t	strength;	/* Pad Drive Strength in mA */
2608 	uint8_t	sel;		/* Chip-specific select value */
2609 } sdiod_drive_str_t;
2610 
2611 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
2612 static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = {
2613 	{
2614 	4, 0x2}, {
2615 	2, 0x3}, {
2616 	1, 0x0}, {
2617 	0, 0x0}
2618 	};
2619 
2620 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
2621 static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = {
2622 	{
2623 	12, 0x7}, {
2624 	10, 0x6}, {
2625 	8, 0x5}, {
2626 	6, 0x4}, {
2627 	4, 0x2}, {
2628 	2, 0x1}, {
2629 	0, 0x0}
2630 	};
2631 
2632 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
2633 static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = {
2634 	{
2635 	32, 0x7}, {
2636 	26, 0x6}, {
2637 	22, 0x5}, {
2638 	16, 0x4}, {
2639 	12, 0x3}, {
2640 	8, 0x2}, {
2641 	4, 0x1}, {
2642 	0, 0x0}
2643 	};
2644 
2645 #define	SDIOD_DRVSTR_KEY(chip, pmu)	(((chip) << 16) | (pmu))
2646 
2647 void
2648 bhnd_pmu_sdiod_drive_strength_init(struct bhnd_pmu_softc *sc,
2649     uint32_t drivestrength)
2650 {
2651 	const sdiod_drive_str_t	*str_tab;
2652 	uint32_t		 str_mask;
2653 	uint32_t		 str_shift;
2654 	u_int			 intr_val;
2655 
2656 	str_tab = NULL;
2657 	str_mask = 0;
2658 	str_shift = 0;
2659 	intr_val = 0;
2660 
2661 	switch (SDIOD_DRVSTR_KEY(sc->cid.chip_id, BHND_PMU_REV(sc))) {
2662 	case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 1):
2663 		str_tab = sdiod_drive_strength_tab1;
2664 		str_mask = 0x30000000;
2665 		str_shift = 28;
2666 		break;
2667 	case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 2):
2668 	case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 3):
2669 	case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4315, 4):
2670 	case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4319, 7):
2671 		str_tab = sdiod_drive_strength_tab2;
2672 		str_mask = 0x00003800;
2673 		str_shift = 11;
2674 		break;
2675 	case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4336, 8):
2676 		str_tab = sdiod_drive_strength_tab3;
2677 		str_mask = 0x00003800;
2678 		str_shift = 11;
2679 		break;
2680 
2681 	default:
2682 		PMU_LOG(sc, "No SDIO Drive strength init done for chip %#x "
2683 		    "rev %hhd pmurev %hhd\n", sc->cid.chip_id, sc->cid.chip_rev,
2684 		    BHND_PMU_REV(sc));
2685 		break;
2686 	}
2687 
2688 	if (str_tab != NULL) {
2689 		uint32_t drivestrength_sel = 0;
2690 		uint32_t cc_data_temp;
2691 
2692 		for (u_int i = 0; str_tab[i].strength != 0; i++) {
2693 			if (drivestrength >= str_tab[i].strength) {
2694 				drivestrength_sel = str_tab[i].sel;
2695 				break;
2696 			}
2697 		}
2698 
2699 		cc_data_temp = BHND_PMU_CCTRL_READ(sc, 1);
2700 		cc_data_temp &= ~str_mask;
2701 		drivestrength_sel <<= str_shift;
2702 		cc_data_temp |= drivestrength_sel;
2703 		BHND_PMU_CCTRL_WRITE(sc, 1, cc_data_temp, ~0);
2704 
2705 		PMU_DEBUG(sc, "SDIO: %dmA drive strength selected, set to "
2706 		    "0x%08x\n", drivestrength, cc_data_temp);
2707 	}
2708 }
2709 
2710 /**
2711  * Initialize the PMU.
2712  */
2713 int
2714 bhnd_pmu_init(struct bhnd_pmu_softc *sc)
2715 {
2716 	uint32_t	xtalfreq;
2717 	int		error;
2718 
2719 	if (BHND_PMU_REV(sc) == 1) {
2720 		BHND_PMU_AND_4(sc, BHND_PMU_CTRL, ~BHND_PMU_CTRL_NOILP_ON_WAIT);
2721 	} else if (BHND_PMU_REV(sc) >= 2) {
2722 		BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_NOILP_ON_WAIT);
2723 	}
2724 
2725 	if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 2) {
2726 		/* Fix for 4329b0 bad LPOM state. */
2727 		BHND_PMU_REGCTRL_WRITE(sc, 2, 0x100, ~0);
2728 		BHND_PMU_REGCTRL_WRITE(sc, 3, 0x4, ~0);
2729 	}
2730 
2731 	if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
2732 		/* Limiting the PALDO spike during init time */
2733 		BHND_PMU_REGCTRL_WRITE(sc, 2, 0x00000005, 0x00000007);
2734 	}
2735 
2736 
2737 	/* Fetch target xtalfreq, in KHz */
2738 	error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_XTALFREQ,
2739 	    &xtalfreq);
2740 
2741 	/* If not available, log any real errors, and then try to measure it */
2742 	if (error) {
2743 		if (error != ENOENT)
2744 			PMU_LOG(sc, "error fetching xtalfreq: %d\n", error);
2745 
2746 		xtalfreq = bhnd_pmu_measure_alpclk(sc);
2747 	}
2748 
2749 	/* Perform PLL initialization */
2750 	bhnd_pmu_pll_init(sc, xtalfreq);
2751 
2752 	if ((error = bhnd_pmu_res_init(sc)))
2753 		return (error);
2754 
2755 	bhnd_pmu_swreg_init(sc);
2756 
2757 	return (0);
2758 }
2759 
2760 /* Return up time in ILP cycles for the given resource. */
2761 static int
2762 bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc, uint32_t *uptime)
2763 {
2764 	uint32_t	deps;
2765 	uint32_t	up, dup, dmax;
2766 	uint32_t	min_mask;
2767 	int		error;
2768 
2769 	/* uptime of resource 'rsrc' */
2770 	BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, rsrc);
2771 	up = BHND_PMU_READ_4(sc, BHND_PMU_RES_UPDN_TIMER);
2772 	up = BHND_PMU_GET_BITS(up, BHND_PMU_RES_UPDN_UPTME);
2773 
2774 	/* Find direct dependencies of resource 'rsrc' */
2775 	deps = bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(rsrc), false);
2776 	for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2777 		if (!(deps & BHND_PMURES_BIT(i)))
2778 			continue;
2779 		deps &= ~bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(i), true);
2780 	}
2781 
2782 	/* Exclude the minimum resource set */
2783 	if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL)))
2784 		return (error);
2785 
2786 	deps &= ~min_mask;
2787 
2788 	/* max uptime of direct dependencies */
2789 	dmax = 0;
2790 	for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2791 		if (!(deps & BHND_PMURES_BIT(i)))
2792 			continue;
2793 
2794 		if ((error = bhnd_pmu_res_uptime(sc, i, &dup)))
2795 			return (error);
2796 
2797 		if (dmax < dup)
2798 			dmax = dup;
2799 	}
2800 
2801 	PMU_DEBUG(sc, "bhnd_pmu_res_uptime: rsrc %hhu uptime %u(deps 0x%08x "
2802 	    "uptime %u)\n", rsrc, up, deps, dmax);
2803 
2804 	*uptime = (up + dmax + BHND_PMURES_UP_TRANSITION);
2805 	return (0);
2806 }
2807 
2808 /* Return dependencies (direct or all/indirect) for the given resources */
2809 static uint32_t
2810 bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs, bool all)
2811 {
2812 	uint32_t deps;
2813 
2814 	deps = 0;
2815 	for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2816 		if (!(rsrcs & BHND_PMURES_BIT(i)))
2817 			continue;
2818 
2819 		BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
2820 		deps |= BHND_PMU_READ_4(sc, BHND_PMU_RES_DEP_MASK);
2821 	}
2822 
2823 	/* None found? */
2824 	if (deps == 0)
2825 		return (0);
2826 
2827 	/* Recurse dependencies */
2828 	if (all)
2829 		deps |= bhnd_pmu_res_deps(sc, deps, true);
2830 
2831 	return (deps);
2832 }
2833 
2834 /* power up/down OTP through PMU resources */
2835 int
2836 bhnd_pmu_otp_power(struct bhnd_pmu_softc *sc, bool on)
2837 {
2838 	uint32_t	deps;
2839 	uint32_t	min_mask;
2840 	uint32_t	rsrcs;
2841 	int		error;
2842 
2843 	/* Determine rsrcs to turn on/off OTP power */
2844 	switch (sc->cid.chip_id) {
2845 	case BHND_CHIPID_BCM4322:
2846 	case BHND_CHIPID_BCM43221:
2847 	case BHND_CHIPID_BCM43231:
2848 	case BHND_CHIPID_BCM4342:
2849 		rsrcs = PMURES_BIT(RES4322_OTP_PU);
2850 		break;
2851 	case BHND_CHIPID_BCM4315:
2852 		rsrcs = PMURES_BIT(RES4315_OTP_PU);
2853 		break;
2854 	case BHND_CHIPID_BCM4325:
2855 		rsrcs = PMURES_BIT(RES4325_OTP_PU);
2856 		break;
2857 	case BHND_CHIPID_BCM4329:
2858 		rsrcs = PMURES_BIT(RES4329_OTP_PU);
2859 		break;
2860 	case BHND_CHIPID_BCM4319:
2861 		rsrcs = PMURES_BIT(RES4319_OTP_PU);
2862 		break;
2863 	case BHND_CHIPID_BCM4336:
2864 		rsrcs = PMURES_BIT(RES4336_OTP_PU);
2865 		break;
2866 	case BHND_CHIPID_BCM4330:
2867 		rsrcs = PMURES_BIT(RES4330_OTP_PU);
2868 		break;
2869 	default:
2870 		/* Not required? */
2871 		return (0);
2872 	}
2873 
2874 	/* Fetch all dependencies */
2875 	deps = bhnd_pmu_res_deps(sc, rsrcs, true);
2876 
2877 	/* Exclude the minimum resource set */
2878 	if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL)))
2879 		return (error);
2880 
2881 	deps &= ~min_mask;
2882 
2883 	/* Turn on/off the power */
2884 	if (on) {
2885 		uint32_t state;
2886 
2887 		PMU_DEBUG(sc, "Adding rsrc 0x%x to min_res_mask\n",
2888 		    rsrcs | deps);
2889 		BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, (rsrcs|deps));
2890 
2891 		/* Wait for all resources to become available */
2892 		for (int i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) {
2893 			state = BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE);
2894 			if ((state & rsrcs) == rsrcs)
2895 				break;
2896 
2897 			DELAY(10);
2898 		}
2899 
2900 		if ((state & rsrcs) != rsrcs) {
2901 			PMU_LOG(sc, "timeout waiting for OTP resource "
2902 			    "enable\n");
2903 			return (ENXIO);
2904 		}
2905 	} else {
2906 		PMU_DEBUG(sc, "Removing rsrc 0x%x from min_res_mask\n",
2907 		    rsrcs | deps);
2908 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~(rsrcs|deps));
2909 	}
2910 
2911 	return (0);
2912 }
2913 
2914 void
2915 bhnd_pmu_rcal(struct bhnd_pmu_softc *sc)
2916 {
2917 	uint32_t	chipst;
2918 	uint32_t	val;
2919 	uint8_t		rcal_code;
2920 	bool		bluetooth_rcal;
2921 
2922 
2923 	bluetooth_rcal = false;
2924 
2925 	switch (sc->cid.chip_id) {
2926 	case BHND_CHIPID_BCM4325:
2927 	case BHND_CHIPID_BCM4329:
2928 		/* Kick RCal */
2929 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 1);
2930 
2931 		/* Power Down RCAL Block */
2932 		BHND_PMU_AND_4(sc, BHND_PMU_CHIPCTL_DATA, ~0x04);
2933 
2934 		if (sc->cid.chip_id == BHND_CHIPID_BCM4325) {
2935 			chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
2936 			if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_RCAL_VALID))
2937 				bluetooth_rcal = true;
2938 		}
2939 
2940 		/* Power Up RCAL block */
2941 		BHND_PMU_AND_4(sc, BHND_PMU_CHIPCTL_DATA, 0x04);
2942 
2943 		/* Wait for completion */
2944 		for (int i = 0; i < (10 * 1000 * 1000); i++) {
2945 			chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
2946 
2947 			if (chipst & 0x08)
2948 				break;
2949 
2950 			DELAY(10);
2951 		}
2952 		KASSERT((chipst & 0x08) != 0, ("rcal completion timeout"));
2953 
2954 		if (bluetooth_rcal) {
2955 			rcal_code = 0x6;
2956 		} else {
2957 			/* Drop LSB to convert from 5 bit code to 4 bit code */
2958 			rcal_code = (uint8_t) (chipst >> 5) & 0x0f;
2959 		}
2960 
2961 		PMU_DEBUG("RCal completed, status 0x%x, code 0x%x\n",
2962 		    R_REG(&cc->chipstatus), rcal_code);
2963 
2964 		/* Write RCal code into pmu_vreg_ctrl[32:29] */
2965 		BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 0);
2966 		val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA);
2967 		val &= ~((uint32_t) 0x07 << 29);
2968 		val |= (uint32_t) (rcal_code & 0x07) << 29;
2969 		BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val);
2970 
2971 		BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 1);
2972 		val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA);
2973 		val &= ~(uint32_t) 0x01;
2974 		val |= (uint32_t) ((rcal_code >> 3) & 0x01);
2975 		BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val);
2976 
2977 		/* Write RCal code into pmu_chip_ctrl[33:30] */
2978 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 0);
2979 		val = BHND_PMU_READ_4(sc, BHND_PMU_CHIPCTL_DATA);
2980 		val &= ~((uint32_t) 0x03 << 30);
2981 		val |= (uint32_t) (rcal_code & 0x03) << 30;
2982 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_DATA, val);
2983 
2984 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 1);
2985 		val = BHND_PMU_READ_4(sc, BHND_PMU_CHIPCTL_DATA);
2986 		val &= ~(uint32_t) 0x03;
2987 		val |= (uint32_t) ((rcal_code >> 2) & 0x03);
2988 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_DATA, val);
2989 
2990 		/* Set override in pmu_chip_ctrl[29] */
2991 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 0);
2992 		BHND_PMU_OR_4(sc, BHND_PMU_CHIPCTL_DATA, (0x01 << 29));
2993 
2994 		/* Power off RCal block */
2995 		BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 1);
2996 		BHND_PMU_AND_4(sc, BHND_PMU_CHIPCTL_DATA, ~0x04);
2997 		break;
2998 	default:
2999 		break;
3000 	}
3001 }
3002 
3003 void
3004 bhnd_pmu_spuravoid(struct bhnd_pmu_softc *sc, uint8_t spuravoid)
3005 {
3006 	/* force the HT off  */
3007 	if (sc->cid.chip_id == BHND_CHIPID_BCM4336) {
3008 		BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
3009 		    ~BHND_PMU_RES4336_HT_AVAIL);
3010 
3011 		/* wait for the ht to really go away */
3012 		PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
3013 	}
3014 
3015 	/* update the pll changes */
3016 	bhnd_pmu_spuravoid_pllupdate(sc, spuravoid);
3017 
3018 	/* enable HT back on  */
3019 	if (sc->cid.chip_id == BHND_CHIPID_BCM4336) {
3020 		BHND_PMU_OR_4(sc, BHND_PMU_MAX_RES_MASK,
3021 		    BHND_PMU_RES4336_HT_AVAIL);
3022 	}
3023 }
3024 
3025 static void
3026 bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc, uint8_t spuravoid)
3027 {
3028 	uint16_t	chip_id;
3029 	uint32_t	tmp;
3030 	uint32_t	pmuctrl;
3031 	uint8_t		phypll_offset;
3032 
3033 	uint8_t bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
3034 	uint8_t bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
3035 
3036 	/* 6362a0 has same clks as 4322[4-6] */
3037 	chip_id = sc->cid.chip_id;
3038 	if (chip_id == BHND_CHIPID_BCM6362 && sc->cid.chip_rev == 0) {
3039 		chip_id = BHND_CHIPID_BCM43224;
3040 	}
3041 
3042 	switch (chip_id) {
3043 	case BHND_CHIPID_BCM6362:
3044 		KASSERT(sc->cid.chip_rev != 0, ("invalid clock config"));
3045 		/* fallthrough */
3046 	case BHND_CHIPID_BCM5357:
3047 	case BHND_CHIPID_BCM4749:
3048 	case BHND_CHIPID_BCM43235:
3049 	case BHND_CHIPID_BCM43236:
3050 	case BHND_CHIPID_BCM43238:
3051 	case BHND_CHIPID_BCM43234:
3052 	case BHND_CHIPID_BCM43237:
3053 	case BHND_CHIPID_BCM53572:
3054 		KASSERT(spuravoid < nitems(bcm5357_bcm43236_p1div),
3055 		    ("spuravoid %hhu outside p1div table\n", spuravoid));
3056 
3057 		KASSERT(spuravoid < nitems(bcm5357_bcm43236_ndiv),
3058 		    ("spuravoid %hhu outside ndiv table\n", spuravoid));
3059 
3060 		/* BCM5357 needs to touch PLL1_PLLCTL[02], so offset
3061 		 * PLL0_PLLCTL[02] by 6 */
3062 		phypll_offset = 0;
3063 		if (sc->cid.chip_id == BHND_CHIPID_BCM5357)
3064 			phypll_offset = 6;
3065 
3066 		/* RMW only the P1 divider */
3067 		tmp = BHND_PMU_SET_BITS(bcm5357_bcm43236_p1div[spuravoid],
3068 		    BHND_PMU1_PLL0_PC0_P1DIV);
3069 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0 + phypll_offset,
3070 		    tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK);
3071 
3072 		/* RMW only the int feedback divider */
3073 		tmp = BHND_PMU_SET_BITS(bcm5357_bcm43236_ndiv[spuravoid],
3074 		    BHND_PMU1_PLL0_PC2_NDIV_INT);
3075 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2 + phypll_offset,
3076 		    tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK);
3077 
3078 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3079 		break;
3080 
3081 	case BHND_CHIPID_BCM4331:
3082 		if (spuravoid == 2) {
3083 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3084 			    0x11500014, ~0);
3085 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3086 			    0x0FC00a08, ~0);
3087 		} else if (spuravoid == 1) {
3088 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3089 			    0x11500014, ~0);
3090 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3091 			    0x0F600a08, ~0);
3092 		} else {
3093 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3094 			    0x11100014, ~0);
3095 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3096 			    0x03000a08, ~0);
3097 		}
3098 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3099 		break;
3100 
3101 	case BHND_CHIPID_BCM43224:
3102 	case BHND_CHIPID_BCM43225:
3103 	case BHND_CHIPID_BCM43226:
3104 	case BHND_CHIPID_BCM43421:
3105 		if (spuravoid == 1) {
3106 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3107 			    0x11500010, ~0);
3108 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3109 			    0x000C0C06, ~0);
3110 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3111 			    0x0F600a08, ~0);
3112 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3113 			    0x00000000, ~0);
3114 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3115 			    0x2001E920, ~0);
3116 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3117 			    0x88888815, ~0);
3118 		} else {
3119 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3120 			    0x11100010, ~0);
3121 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3122 			    0x000c0c06, ~0);
3123 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3124 			    0x03000a08, ~0);
3125 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3126 			    0x00000000, ~0);
3127 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3128 			    0x200005c0, ~0);
3129 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3130 			    0x88888815, ~0);
3131 		}
3132 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3133 		break;
3134 
3135 	case BHND_CHIPID_BCM43111:
3136 	case BHND_CHIPID_BCM43112:
3137 	case BHND_CHIPID_BCM43222:
3138 	case BHND_CHIPID_BCM43420:
3139 		if (spuravoid == 1) {
3140 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3141 			    0x11500008, ~0);
3142 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3143 			    0x0c000c06, ~0);
3144 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3145 			    0x0f600a08, ~0);
3146 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3147 			    0x00000000, ~0);
3148 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3149 			    0x2001e920, ~0);
3150 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3151 			    0x88888815, ~0);
3152 		} else {
3153 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3154 			    0x11100008, ~0);
3155 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3156 			    0x0c000c06, ~0);
3157 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3158 			    0x03000a08, ~0);
3159 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3160 			    0x00000000, ~0);
3161 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3162 			    0x200005c0, ~0);
3163 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3164 			    0x88888855, ~0);
3165 		}
3166 
3167 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3168 		break;
3169 
3170 	case BHND_CHIPID_BCM4716:
3171 	case BHND_CHIPID_BCM4748:
3172 	case BHND_CHIPID_BCM47162:
3173 		if (spuravoid == 1) {
3174 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3175 			    0x11500060, ~0);
3176 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3177 			    0x080C0C06, ~0);
3178 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3179 			    0x0F600000, ~0);
3180 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3181 			    0x00000000, ~0);
3182 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3183 			    0x2001E924, ~0);
3184 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3185 			    0x88888815, ~0);
3186 		} else {
3187 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3188 			    0x11100060, ~0);
3189 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3190 			    0x080c0c06, ~0);
3191 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3192 			    0x03000000, ~0);
3193 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3194 			    0x00000000, ~0);
3195 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3196 			    0x200005c0, ~0);
3197 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3198 			    0x88888815, ~0);
3199 		}
3200 
3201 		pmuctrl = BHND_PMU_CTRL_NOILP_ON_WAIT |
3202 			  BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3203 		break;
3204 
3205 	case BHND_CHIPID_BCM4319:
3206 		pmuctrl = 0;
3207 		break;
3208 
3209 	case BHND_CHIPID_BCM4322:
3210 	case BHND_CHIPID_BCM43221:
3211 	case BHND_CHIPID_BCM43231:
3212 	case BHND_CHIPID_BCM4342:
3213 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x11100070, ~0);
3214 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x1014140a, ~0);
3215 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888854, ~0);
3216 
3217 		if (spuravoid == 1) {
3218 			/* spur_avoid ON, enable 41/82/164Mhz clock mode */
3219 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3220 			    0x05201828, ~0);
3221 		} else {
3222 			/* enable 40/80/160Mhz clock mode */
3223 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3224 			    0x05001828, ~0);
3225 		}
3226 
3227 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3228 		break;
3229 
3230 	case BHND_CHIPID_BCM4336:
3231 		/* Looks like these are only for default xtal freq 26MHz */
3232 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x02100020, ~0);
3233 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x0C0C0C0C, ~0);
3234 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 0x01240C0C, ~0);
3235 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 0x202C2820, ~0);
3236 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888825, ~0);
3237 
3238 		if (spuravoid == 1) {
3239 			tmp = 0x00EC4EC4;
3240 		} else {
3241 			tmp = 0x00762762;
3242 		}
3243 		BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, tmp, ~0);
3244 
3245 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3246 		break;
3247 	case BHND_CHIPID_BCM43131:
3248 	case BHND_CHIPID_BCM43227:
3249 	case BHND_CHIPID_BCM43228:
3250 	case BHND_CHIPID_BCM43428:
3251 		/* LCNXN */
3252 		/* PLL Settings for spur avoidance on/off mode, no on2 support
3253 		 * for 43228A0 */
3254 		if (spuravoid == 1) {
3255 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3256 			    0x01100014, ~0);
3257 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3258 			    0x040C0C06, ~0);
3259 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3260 			    0x03140A08, ~0);
3261 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3262 			    0x00333333, ~0);
3263 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3264 			    0x202C2820, ~0);
3265 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3266 			    0x88888815, ~0);
3267 		} else {
3268 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3269 			    0x11100014, ~0);
3270 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3271 			    0x040c0c06, ~0);
3272 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3273 			    0x03000a08, ~0);
3274 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3275 			    0x00000000, ~0);
3276 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3277 			    0x200005c0, ~0);
3278 			BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3279 			    0x88888815, ~0);
3280 		}
3281 		pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3282 		break;
3283 	default:
3284 		PMU_LOG(sc, "%s: unknown spuravoidance settings for chip %#hx, "
3285 		    "not changing PLL", __func__, sc->cid.chip_id);
3286 		pmuctrl = 0;
3287 		break;
3288 	}
3289 
3290 	if (pmuctrl != 0)
3291 		BHND_PMU_OR_4(sc, BHND_PMU_CTRL, pmuctrl);
3292 }
3293 
3294 bool
3295 bhnd_pmu_is_otp_powered(struct bhnd_pmu_softc *sc)
3296 {
3297 	uint32_t			 otp_res;
3298 
3299 	/* Determine per-chip OTP resource */
3300 	switch (sc->cid.chip_id) {
3301 	case BHND_CHIPID_BCM4329:
3302 		otp_res = PMURES_BIT(RES4329_OTP_PU);
3303 		break;
3304 	case BHND_CHIPID_BCM4319:
3305 		otp_res = PMURES_BIT(RES4319_OTP_PU);
3306 		break;
3307 	case BHND_CHIPID_BCM4336:
3308 		otp_res = PMURES_BIT(RES4336_OTP_PU);
3309 		break;
3310 	case BHND_CHIPID_BCM4330:
3311 		otp_res = PMURES_BIT(RES4330_OTP_PU);
3312 		break;
3313 
3314 	/* These chips don't use PMU bit to power up/down OTP. OTP always on.
3315 	 * Use OTP_INIT command to reset/refresh state.
3316 	 */
3317 	case BHND_CHIPID_BCM43224:
3318 	case BHND_CHIPID_BCM43225:
3319 	case BHND_CHIPID_BCM43421:
3320 	case BHND_CHIPID_BCM43236:
3321 	case BHND_CHIPID_BCM43235:
3322 	case BHND_CHIPID_BCM43238:
3323 		return (true);
3324 
3325 	default:
3326 		return (true);
3327 	}
3328 
3329 	/* Check resource state */
3330 	if ((BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE) & otp_res) == 0)
3331 		return (false);
3332 
3333 	return (true);
3334 }
3335 
3336 void
3337 bhnd_pmu_paref_ldo_enable(struct bhnd_pmu_softc *sc, bool enable)
3338 {
3339 	uint32_t ldo;
3340 
3341 	switch (sc->cid.chip_id) {
3342 	case BHND_CHIPID_BCM4328:
3343 		ldo = PMURES_BIT(RES4328_PA_REF_LDO);
3344 		break;
3345 	case BHND_CHIPID_BCM5354:
3346 		ldo = PMURES_BIT(RES5354_PA_REF_LDO);
3347 		break;
3348 	case BHND_CHIPID_BCM4312:
3349 		ldo = PMURES_BIT(RES4312_PA_REF_LDO);
3350 		break;
3351 	default:
3352 		return;
3353 	}
3354 
3355 	if (enable) {
3356 		BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, ldo);
3357 	} else {
3358 		BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~ldo);
3359 	}
3360 }
3361 
3362 /* initialize PMU switch/regulators */
3363 void
3364 bhnd_pmu_swreg_init(struct bhnd_pmu_softc *sc)
3365 {
3366 	uint32_t chipst;
3367 
3368 	switch (sc->cid.chip_id) {
3369 	case BHND_CHIPID_BCM4325:
3370 		if (sc->cid.chip_rev <= 2)
3371 			break;
3372 
3373 		chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
3374 		if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) {
3375 			bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM,
3376 			    0xf);
3377 			bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST,
3378 			    0xf);
3379 		}
3380 
3381 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb);
3382 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb);
3383 
3384 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0x1);
3385 		if (sc->board.board_flags & BHND_BFL_LNLDO2_2P5) {
3386 			bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO2_SEL,
3387 			    0x1);
3388 		}
3389 
3390 		break;
3391 	case BHND_CHIPID_BCM4336:
3392 		/* Reduce CLDO PWM output voltage to 1.2V */
3393 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
3394 		/* Reduce CLDO BURST output voltage to 1.2V */
3395 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 0xe);
3396 		/* Reduce LNLDO1 output voltage to 1.2V */
3397 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0xe);
3398 		if (sc->cid.chip_rev == 0)
3399 			BHND_PMU_REGCTRL_WRITE(sc, 2, 0x400000, 0x400000);
3400 		break;
3401 
3402 	case BHND_CHIPID_BCM4330:
3403 		/* CBUCK Voltage is 1.8 by default and set that to 1.5 */
3404 		bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
3405 		break;
3406 	default:
3407 		break;
3408 	}
3409 }
3410 
3411 int
3412 bhnd_pmu_radio_enable(struct bhnd_pmu_softc *sc, device_t d11core, bool enable)
3413 {
3414 	uint32_t	oobsel;
3415 	uint32_t	rsrcs;
3416 	int		error;
3417 
3418 	if (bhnd_get_device(d11core) != BHND_COREID_D11) {
3419 		device_printf(sc->dev,
3420 		    "bhnd_pmu_radio_enable() called on non-D11 core");
3421 		return (EINVAL);
3422 	}
3423 
3424 	switch (sc->cid.chip_id) {
3425 	case BHND_CHIPID_BCM4325:
3426 		if (sc->board.board_flags & BHND_BFL_FASTPWR)
3427 			break;
3428 
3429 		if ((sc->board.board_flags & BHND_BFL_BUCKBOOST) == 0)
3430 			break;
3431 
3432 		rsrcs = PMURES_BIT(RES4325_BUCK_BOOST_BURST);
3433 
3434 		if (enable) {
3435 			BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, rsrcs);
3436 			DELAY(100 * 1000); /* 100ms */
3437 		} else {
3438 			BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~rsrcs);
3439 		}
3440 
3441 		return (0);
3442 
3443 	case BHND_CHIPID_BCM4319:
3444 		error = bhnd_read_config(d11core, BCMA_DMP_OOBSELOUTB74,
3445 		    &oobsel, 4);
3446 		if (error)
3447 			return (error);
3448 
3449 		if (enable) {
3450 			oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3451 			    BCMA_DMP_OOBSEL_5);
3452 			oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3453 			    BCMA_DMP_OOBSEL_6);
3454 		} else {
3455 			oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3456 			    BCMA_DMP_OOBSEL_5);
3457 			oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3458 			    BCMA_DMP_OOBSEL_6);
3459 		}
3460 
3461 		return (bhnd_write_config(d11core, BCMA_DMP_OOBSELOUTB74,
3462 		    &oobsel, 4));
3463 	}
3464 
3465 	return (0);
3466 }
3467 
3468 /* Wait for a particular clock level to be on the backplane */
3469 uint32_t
3470 bhnd_pmu_waitforclk_on_backplane(struct bhnd_pmu_softc *sc, uint32_t clk,
3471     uint32_t delay)
3472 {
3473 	uint32_t pmu_st;
3474 
3475 	for (uint32_t i = 0; i < delay; i += 10) {
3476 		pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3477 		if ((pmu_st & clk) == clk)
3478 			return (clk);
3479 
3480 		DELAY(10);
3481 	}
3482 
3483 	pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3484 	return (pmu_st & clk);
3485 }
3486 
3487 /*
3488  * Measures the ALP clock frequency in KHz.  Returns 0 if not possible.
3489  * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
3490  */
3491 
3492 #define	EXT_ILP_HZ 32768
3493 
3494 uint32_t
3495 bhnd_pmu_measure_alpclk(struct bhnd_pmu_softc *sc)
3496 {
3497 	uint32_t alp_khz;
3498 	uint32_t pmu_st;
3499 
3500 	if (BHND_PMU_REV(sc) < 10)
3501 		return (0);
3502 
3503 	pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3504 	if (pmu_st & BHND_PMU_ST_EXTLPOAVAIL) {
3505 		uint32_t alp_hz, ilp_ctr;
3506 
3507 		/* Enable frequency measurement */
3508 		BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 1U <<
3509 		    BHND_PMU_XTALFREQ_REG_MEASURE_SHIFT);
3510 
3511 		/* Delay for well over 4 ILP clocks */
3512 		DELAY(1000);
3513 
3514 		/* Read the latched number of ALP ticks per 4 ILP ticks */
3515 		ilp_ctr = BHND_PMU_READ_4(sc, BHND_PMU_XTALFREQ);
3516 		ilp_ctr = BHND_PMU_GET_BITS(ilp_ctr,
3517 		    BHND_PMU_XTALFREQ_REG_ILPCTR);
3518 
3519 		/* Turn off PMU_XTALFREQ_REG_MEASURE to save power */
3520 		BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 0);
3521 
3522 		/* Calculate ALP frequency */
3523 		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
3524 
3525 		/* Round to nearest 100KHz and convert to KHz */
3526 		alp_khz = (alp_hz + 50000) / 100000 * 100;
3527 	} else {
3528 		alp_khz = 0;
3529 	}
3530 
3531 	return (alp_khz);
3532 }
3533 
3534 static void
3535 bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc)
3536 {
3537 	uint32_t FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000;
3538 	uint32_t m1div, m2div, m3div, m4div, m5div, m6div;
3539 	uint32_t pllc1, pllc2;
3540 
3541 	m2div = m3div = m4div = m6div = FVCO / 80;
3542 	m5div = FVCO / 160;
3543 
3544 	if (PMU_CST4330_SDIOD_CHIPMODE(sc))
3545 		m1div = FVCO / 80;
3546 	else
3547 		m1div = FVCO / 90;
3548 
3549 	pllc1 = 0;
3550 	pllc1 |= BHND_PMU_SET_BITS(m1div, BHND_PMU1_PLL0_PC1_M1DIV);
3551 	pllc1 |= BHND_PMU_SET_BITS(m2div, BHND_PMU1_PLL0_PC1_M2DIV);
3552 	pllc1 |= BHND_PMU_SET_BITS(m3div, BHND_PMU1_PLL0_PC1_M3DIV);
3553 	pllc1 |= BHND_PMU_SET_BITS(m4div, BHND_PMU1_PLL0_PC1_M4DIV);
3554 
3555 	BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, pllc1, ~0);
3556 
3557 	pllc2 = 0;
3558 	pllc2 |= BHND_PMU_SET_BITS(m5div, BHND_PMU1_PLL0_PC2_M5DIV);
3559 	pllc2 |= BHND_PMU_SET_BITS(m6div, BHND_PMU1_PLL0_PC2_M6DIV);
3560 
3561 	BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, pllc2,
3562 	    BHND_PMU1_PLL0_PC2_M5DIV_MASK | BHND_PMU1_PLL0_PC2_M6DIV_MASK);
3563 }
3564