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