2 * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
3 * Copyright (C) 2010, Broadcom Corporation.
6 * This file is derived from the hndpmu.c source contributed by Broadcom
7 * to to the Linux staging repository, as well as later revisions of hndpmu.c
8 * distributed with the Asus RT-N16 firmware source code release.
10 * Permission to use, copy, modify, and/or distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include <sys/cdefs.h>
24 __FBSDID("$FreeBSD$");
26 #include <sys/types.h>
28 #include <dev/bhnd/bhnd.h>
29 #include <dev/bhnd/cores/chipc/chipc.h>
30 #include <dev/bhnd/cores/chipc/chipcreg.h>
32 #include <dev/bhnd/bcma/bcma_dmp.h>
34 #include "bhnd_nvram_map.h"
36 #include "bhnd_pmureg.h"
37 #include "bhnd_pmuvar.h"
39 #include "bhnd_pmu_private.h"
41 #define PMU_LOG(_sc, _fmt, ...) do { \
42 if (_sc->dev != NULL) \
43 device_printf(_sc->dev, _fmt, ##__VA_ARGS__); \
45 printf(_fmt, ##__VA_ARGS__); \
49 #define PMU_DEBUG(_sc, _fmt, ...) PMU_LOG(_sc, _fmt, ##__VA_ARGS__)
51 #define PMU_DEBUG(_sc, _fmt, ...)
54 typedef struct pmu0_xtaltab0 pmu0_xtaltab0_t;
55 typedef struct pmu1_xtaltab0 pmu1_xtaltab0_t;
57 /* PLL controls/clocks */
58 static const pmu1_xtaltab0_t *bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc);
59 static const pmu1_xtaltab0_t *bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc);
61 static void bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal);
62 static uint32_t bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc);
63 static uint32_t bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc);
65 static void bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal);
66 static uint32_t bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc);
67 static uint32_t bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc);
68 static uint32_t bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc);
70 static uint32_t bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m);
72 static uint32_t bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0,
76 static bool bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc);
77 static bool bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc);
78 static bool bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc);
79 static bool bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc);
80 static uint32_t bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs,
82 static int bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc,
84 static int bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin,
87 static void bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc,
89 static void bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc);
91 #define BHND_PMU_REV(_sc) \
92 ((uint8_t)BHND_PMU_GET_BITS((_sc)->caps, BHND_PMU_CAP_REV))
94 #define PMU_WAIT_CLKST(_sc, _val, _mask) \
95 bhnd_pmu_wait_clkst((_sc), (_sc)->dev, (_sc)->res, \
96 BHND_CLK_CTL_ST, (_val), (_mask))
98 #define PMURES_BIT(_bit) \
99 (1 << (BHND_PMU_ ## _bit))
101 #define PMU_CST4330_SDIOD_CHIPMODE(_sc) \
102 CHIPC_CST4330_CHIPMODE_SDIOD((_sc)->io->rd_chipst((_sc)->io_ctx))
105 * Initialize @p query state.
107 * @param[out] query On success, will be populated with a valid query instance
109 * @param dev The device owning @p query, or NULL.
110 * @param id The bhnd chip identification.
111 * @param io I/O callback functions.
112 * @param ctx I/O callback context.
115 * @retval non-zero if the query state could not be initialized.
118 bhnd_pmu_query_init(struct bhnd_pmu_query *query, device_t dev,
119 struct bhnd_chipid id, const struct bhnd_pmu_io *io, void *ctx)
125 query->caps = BHND_PMU_READ_4(query, BHND_PMU_CAP);
131 * Release any resources held by @p query.
133 * @param query A query instance previously initialized via
134 * bhnd_pmu_query_init().
137 bhnd_pmu_query_fini(struct bhnd_pmu_query *query)
143 * Perform an indirect register read.
145 * @param addr Offset of the address register.
146 * @param data Offset of the data register.
147 * @param reg Indirect register to be read.
150 bhnd_pmu_ind_read(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr,
151 bus_size_t data, uint32_t reg)
153 io->wr4(addr, reg, io_ctx);
154 return (io->rd4(data, io_ctx));
158 * Perform an indirect register write.
160 * @param addr Offset of the address register.
161 * @param data Offset of the data register.
162 * @param reg Indirect register to be written.
163 * @param val Value to be written to @p reg.
164 * @param mask Only the bits defined by @p mask will be updated from @p val.
167 bhnd_pmu_ind_write(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr,
168 bus_size_t data, uint32_t reg, uint32_t val, uint32_t mask)
172 io->wr4(addr, reg, io_ctx);
174 if (mask != UINT32_MAX) {
175 rval = io->rd4(data, io_ctx);
176 rval &= ~mask | (val & mask);
181 io->wr4(data, rval, io_ctx);
185 * Wait for up to BHND_PMU_MAX_TRANSITION_DLY microseconds for the per-core
186 * clock status to be equal to @p value after applying @p mask.
188 * @param sc PMU driver state.
189 * @param dev Requesting device.
190 * @param r An active resource mapping the clock status register.
191 * @param clkst_reg Offset to the CLK_CTL_ST register.
192 * @param value Value to wait for.
193 * @param mask Mask to apply prior to value comparison.
196 bhnd_pmu_wait_clkst(struct bhnd_pmu_softc *sc, device_t dev,
197 struct bhnd_resource *r, bus_size_t clkst_reg, uint32_t value,
202 /* Bitswapped HTAVAIL/ALPAVAIL work-around */
203 if (sc->quirks & BPMU_QUIRK_CLKCTL_CCS0) {
204 uint32_t fmask, fval;
206 fmask = mask & ~(BHND_CCS_HTAVAIL | BHND_CCS_ALPAVAIL);
207 fval = value & ~(BHND_CCS_HTAVAIL | BHND_CCS_ALPAVAIL);
209 if (mask & BHND_CCS_HTAVAIL)
210 fmask |= BHND_CCS0_HTAVAIL;
211 if (value & BHND_CCS_HTAVAIL)
212 fval |= BHND_CCS0_HTAVAIL;
214 if (mask & BHND_CCS_ALPAVAIL)
215 fmask |= BHND_CCS0_ALPAVAIL;
216 if (value & BHND_CCS_ALPAVAIL)
217 fval |= BHND_CCS0_ALPAVAIL;
223 for (uint32_t i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) {
224 clkst = bhnd_bus_read_4(r, clkst_reg);
225 if ((clkst & mask) == (value & mask))
231 device_printf(dev, "clkst wait timeout (value=%#x, "
232 "mask=%#x)\n", value, mask);
237 /* Setup switcher voltage */
239 bhnd_pmu_set_switcher_voltage(struct bhnd_pmu_softc *sc, uint8_t bb_voltage,
242 BHND_PMU_REGCTRL_WRITE(sc, 0x01, (bb_voltage & 0x1f) << 22, ~0);
243 BHND_PMU_REGCTRL_WRITE(sc, 0x00, (rf_voltage & 0x1f) << 14, ~0);
247 bhnd_pmu_set_ldo_voltage(struct bhnd_pmu_softc *sc, uint8_t ldo,
256 switch (sc->cid.chip_id) {
257 case BHND_CHIPID_BCM4328:
258 case BHND_CHIPID_BCM5354:
260 case SET_LDO_VOLTAGE_LDO1:
265 case SET_LDO_VOLTAGE_LDO2:
270 case SET_LDO_VOLTAGE_LDO3:
275 case SET_LDO_VOLTAGE_PAREF:
281 panic("unknown BCM4328/BCM5354 LDO %hhu\n", ldo);
284 case BHND_CHIPID_BCM4312:
286 case SET_LDO_VOLTAGE_PAREF:
292 panic("unknown BCM4312 LDO %hhu\n", ldo);
295 case BHND_CHIPID_BCM4325:
297 case SET_LDO_VOLTAGE_CLDO_PWM:
302 case SET_LDO_VOLTAGE_CLDO_BURST:
307 case SET_LDO_VOLTAGE_CBUCK_PWM:
311 /* Bit 116 & 119 are inverted in CLB for opt 2b */
312 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
313 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
316 case SET_LDO_VOLTAGE_CBUCK_BURST:
320 /* Bit 121 & 124 are inverted in CLB for opt 2b */
321 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
322 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
325 case SET_LDO_VOLTAGE_LNLDO1:
330 case SET_LDO_VOLTAGE_LNLDO2_SEL:
336 panic("unknown BCM4325 LDO %hhu\n", ldo);
339 case BHND_CHIPID_BCM4336:
341 case SET_LDO_VOLTAGE_CLDO_PWM:
346 case SET_LDO_VOLTAGE_CLDO_BURST:
351 case SET_LDO_VOLTAGE_LNLDO1:
357 panic("unknown BCM4336 LDO %hhu\n", ldo);
360 case BHND_CHIPID_BCM4330:
362 case SET_LDO_VOLTAGE_CBUCK_PWM:
368 panic("unknown BCM4330 LDO %hhu\n", ldo);
371 case BHND_CHIPID_BCM4331:
373 case SET_LDO_VOLTAGE_PAREF:
379 panic("unknown BCM4331 LDO %hhu\n", ldo);
383 panic("cannot set LDO voltage on unsupported chip %hu\n",
388 regctrl = (voltage & mask) << shift;
389 BHND_PMU_REGCTRL_WRITE(sc, addr, regctrl, mask << shift);
392 /* d11 slow to fast clock transition time in slow clock cycles */
393 #define D11SCC_SLOW2FAST_TRANSITION 2
396 bhnd_pmu_fast_pwrup_delay(struct bhnd_pmu_softc *sc, uint16_t *pwrup_delay)
403 switch (sc->cid.chip_id) {
404 case BHND_CHIPID_BCM43224:
405 case BHND_CHIPID_BCM43225:
406 case BHND_CHIPID_BCM43421:
407 case BHND_CHIPID_BCM43235:
408 case BHND_CHIPID_BCM43236:
409 case BHND_CHIPID_BCM43238:
410 case BHND_CHIPID_BCM4331:
411 case BHND_CHIPID_BCM6362:
412 case BHND_CHIPID_BCM4313:
416 case BHND_CHIPID_BCM4325:
417 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4325_HT_AVAIL,
422 ilp = bhnd_pmu_ilp_clock(&sc->query);
423 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
424 ((1000000 + ilp - 1) / ilp);
425 delay = (11 * delay) / 10;
428 case BHND_CHIPID_BCM4329:
429 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4329_HT_AVAIL,
434 ilp = bhnd_pmu_ilp_clock(&sc->query);
435 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
436 ((1000000 + ilp - 1) / ilp);
437 delay = (11 * delay) / 10;
440 case BHND_CHIPID_BCM4319:
444 case BHND_CHIPID_BCM4336:
445 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4336_HT_AVAIL,
450 ilp = bhnd_pmu_ilp_clock(&sc->query);
451 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
452 ((1000000 + ilp - 1) / ilp);
453 delay = (11 * delay) / 10;
456 case BHND_CHIPID_BCM4330:
457 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4330_HT_AVAIL,
462 ilp = bhnd_pmu_ilp_clock(&sc->query);
463 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
464 ((1000000 + ilp - 1) / ilp);
465 delay = (11 * delay) / 10;
469 delay = BHND_PMU_MAX_TRANSITION_DLY;
473 *pwrup_delay = (uint16_t)delay;
478 bhnd_pmu_force_ilp(struct bhnd_pmu_softc *sc, bool force)
483 pctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
487 pctrl &= ~(BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN);
489 pctrl |= (BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN);
491 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pctrl);
496 /* Setup resource up/down timers */
502 typedef bool (*pmu_res_filter) (struct bhnd_pmu_softc *sc);
504 /* Change resource dependencies masks */
506 uint32_t res_mask; /* resources (chip specific) */
507 int8_t action; /* action */
508 uint32_t depend_mask; /* changes to the dependencies mask */
509 pmu_res_filter filter; /* action is taken when filter is NULL or returns true */
512 /* Resource dependencies mask change action */
513 #define RES_DEPEND_SET 0 /* Override the dependencies mask */
514 #define RES_DEPEND_ADD 1 /* Add to the dependencies mask */
515 #define RES_DEPEND_REMOVE -1 /* Remove from the dependencies mask */
517 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
519 BHND_PMU_RES4328_EXT_SWITCHER_PWM, 0x0101}, {
520 BHND_PMU_RES4328_BB_SWITCHER_PWM, 0x1f01}, {
521 BHND_PMU_RES4328_BB_SWITCHER_BURST, 0x010f}, {
522 BHND_PMU_RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
523 BHND_PMU_RES4328_ILP_REQUEST, 0x0202}, {
524 BHND_PMU_RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
525 BHND_PMU_RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
526 BHND_PMU_RES4328_ROM_SWITCH, 0x0101}, {
527 BHND_PMU_RES4328_PA_REF_LDO, 0x0f01}, {
528 BHND_PMU_RES4328_RADIO_LDO, 0x0f01}, {
529 BHND_PMU_RES4328_AFE_LDO, 0x0f01}, {
530 BHND_PMU_RES4328_PLL_LDO, 0x0f01}, {
531 BHND_PMU_RES4328_BG_FILTBYP, 0x0101}, {
532 BHND_PMU_RES4328_TX_FILTBYP, 0x0101}, {
533 BHND_PMU_RES4328_RX_FILTBYP, 0x0101}, {
534 BHND_PMU_RES4328_XTAL_PU, 0x0101}, {
535 BHND_PMU_RES4328_XTAL_EN, 0xa001}, {
536 BHND_PMU_RES4328_BB_PLL_FILTBYP, 0x0101}, {
537 BHND_PMU_RES4328_RF_PLL_FILTBYP, 0x0101}, {
538 BHND_PMU_RES4328_BB_PLL_PU, 0x0701}
541 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
542 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
544 PMURES_BIT(RES4328_ILP_REQUEST),
546 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
547 PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
550 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
552 BHND_PMU_RES4325_XTAL_PU, 0x1501}
555 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
556 /* Adjust OTP PU resource dependencies - remove BB BURST */
558 PMURES_BIT(RES4325_OTP_PU),
560 PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
561 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
563 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
565 PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
566 PMURES_BIT(RES4325_BUCK_BOOST_PWM), bhnd_pmu_res_depfltr_bb},
567 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
569 PMURES_BIT(RES4325_HT_AVAIL),
571 PMURES_BIT(RES4325_RX_PWRSW_PU) |
572 PMURES_BIT(RES4325_TX_PWRSW_PU) |
573 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
574 PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
575 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
577 PMURES_BIT(RES4325_ILP_REQUEST) |
578 PMURES_BIT(RES4325_ABUCK_BURST) |
579 PMURES_BIT(RES4325_ABUCK_PWM) |
580 PMURES_BIT(RES4325_LNLDO1_PU) |
581 PMURES_BIT(RES4325C1_LNLDO2_PU) |
582 PMURES_BIT(RES4325_XTAL_PU) |
583 PMURES_BIT(RES4325_ALP_AVAIL) |
584 PMURES_BIT(RES4325_RX_PWRSW_PU) |
585 PMURES_BIT(RES4325_TX_PWRSW_PU) |
586 PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
587 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
588 PMURES_BIT(RES4325_AFE_PWRSW_PU) |
589 PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
590 PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
591 PMURES_BIT(RES4325B0_CBUCK_LPOM) |
592 PMURES_BIT(RES4325B0_CBUCK_BURST) |
593 PMURES_BIT(RES4325B0_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb}
596 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
598 BHND_PMU_RES4315_XTAL_PU, 0x2501}
601 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
602 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
604 PMURES_BIT(RES4315_OTP_PU),
606 PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_npaldo},
607 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
609 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
611 PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_paldo},
612 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
614 PMURES_BIT(RES4315_HT_AVAIL),
616 PMURES_BIT(RES4315_RX_PWRSW_PU) |
617 PMURES_BIT(RES4315_TX_PWRSW_PU) |
618 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
619 PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
620 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
622 PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
623 PMURES_BIT(RES4315_LNLDO1_PU) |
624 PMURES_BIT(RES4315_OTP_PU) |
625 PMURES_BIT(RES4315_LNLDO2_PU) |
626 PMURES_BIT(RES4315_XTAL_PU) |
627 PMURES_BIT(RES4315_ALP_AVAIL) |
628 PMURES_BIT(RES4315_RX_PWRSW_PU) |
629 PMURES_BIT(RES4315_TX_PWRSW_PU) |
630 PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
631 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
632 PMURES_BIT(RES4315_AFE_PWRSW_PU) |
633 PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
634 PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
635 PMURES_BIT(RES4315_CBUCK_LPOM) |
636 PMURES_BIT(RES4315_CBUCK_BURST) |
637 PMURES_BIT(RES4315_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb}
640 /* 4329 specific. needs to come back this issue later */
641 static const pmu_res_updown_t bcm4329_res_updown[] = {
643 BHND_PMU_RES4329_XTAL_PU, 0x1501}
646 static const pmu_res_depend_t bcm4329_res_depend[] = {
647 /* Adjust HT Avail resource dependencies */
649 PMURES_BIT(RES4329_HT_AVAIL),
651 PMURES_BIT(RES4329_CBUCK_LPOM) |
652 PMURES_BIT(RES4329_CBUCK_BURST) |
653 PMURES_BIT(RES4329_CBUCK_PWM) |
654 PMURES_BIT(RES4329_CLDO_PU) |
655 PMURES_BIT(RES4329_PALDO_PU) |
656 PMURES_BIT(RES4329_LNLDO1_PU) |
657 PMURES_BIT(RES4329_XTAL_PU) |
658 PMURES_BIT(RES4329_ALP_AVAIL) |
659 PMURES_BIT(RES4329_RX_PWRSW_PU) |
660 PMURES_BIT(RES4329_TX_PWRSW_PU) |
661 PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
662 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
663 PMURES_BIT(RES4329_AFE_PWRSW_PU) |
664 PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
667 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
669 BHND_PMU_RES4319_XTAL_PU, 0x3f01}
672 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
673 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
675 PMURES_BIT(RES4319_OTP_PU),
677 PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_npaldo},
678 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
680 PMURES_BIT(RES4319_HT_AVAIL),
682 PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_paldo},
683 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
685 PMURES_BIT(RES4319_HT_AVAIL),
687 PMURES_BIT(RES4319_RX_PWRSW_PU) |
688 PMURES_BIT(RES4319_TX_PWRSW_PU) |
689 PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
690 PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
691 PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
694 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
696 BHND_PMU_RES4336_HT_AVAIL, 0x0D01}
699 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
700 /* Just a dummy entry for now */
702 PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
705 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
707 BHND_PMU_RES4330_HT_AVAIL, 0x0e02}
710 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
711 /* Just a dummy entry for now */
713 PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
716 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF
719 bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc)
721 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_BUCKBOOST));
724 /* true if the power topology doesn't use the cbuck. Key on chiprev also if
725 * the chip is BCM4325. */
727 bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc)
729 if (sc->cid.chip_id == BHND_CHIPID_BCM4325 && sc->cid.chip_rev <= 1)
732 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_NOCBUCK));
735 /* true if the power topology uses the PALDO */
737 bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc)
739 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO));
742 /* true if the power topology doesn't use the PALDO */
744 bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc)
746 return (!BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO));
749 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
751 bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin, uint32_t *pmax)
753 uint32_t max_mask, min_mask;
754 uint32_t chipst, otpsel;
763 rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC);
765 /* determine min/max rsrc masks */
766 switch (sc->cid.chip_id) {
767 case BHND_CHIPID_BCM4325:
768 /* If used by this device, enable the CBUCK */
769 if (!bhnd_pmu_res_depfltr_ncb(sc))
770 min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM);
772 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
773 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
774 min_mask |= PMURES_BIT(RES4325B0_CLDO_PU);
776 /* Is OTP required? */
777 otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_SPROM_OTP_SEL);
778 if (otpsel != CHIPC_CST_OTP_PWRDN)
779 min_mask |= PMURES_BIT(RES4325_OTP_PU);
781 /* Leave buck boost on in burst mode for certain boards */
782 if (sc->board.board_flags & BHND_BFL_BUCKBOOST) {
783 switch (sc->board.board_type) {
784 case BHND_BOARD_BCM94325DEVBU:
785 case BHND_BOARD_BCM94325BGABU:
786 min_mask |= PMURES_BIT(
787 RES4325_BUCK_BOOST_BURST);
792 /* Allow all resources to be turned on upon requests */
793 max_mask = ~(~0 << rsrcs);
796 case BHND_CHIPID_BCM4312:
797 /* default min_mask = 0x80000cbb is wrong */
801 * pmu_res_updown_table_sz = 0;
802 * pmu_res_depend_table_sz = 0;
806 case BHND_CHIPID_BCM4322:
807 case BHND_CHIPID_BCM43221:
808 case BHND_CHIPID_BCM43231:
809 case BHND_CHIPID_BCM4342:
810 if (sc->cid.chip_rev >= 2)
813 /* request ALP(can skip for A1) */
814 min_mask = PMURES_BIT(RES4322_RF_LDO) |
815 PMURES_BIT(RES4322_XTAL_PU) |
816 PMURES_BIT(RES4322_ALP_AVAIL);
818 if (bhnd_get_attach_type(sc->chipc_dev) == BHND_ATTACH_NATIVE) {
820 PMURES_BIT(RES4322_SI_PLL_ON) |
821 PMURES_BIT(RES4322_HT_SI_AVAIL) |
822 PMURES_BIT(RES4322_PHY_PLL_ON) |
823 PMURES_BIT(RES4322_OTP_PU) |
824 PMURES_BIT(RES4322_HT_PHY_AVAIL);
829 case BHND_CHIPID_BCM43222:
830 case BHND_CHIPID_BCM43111:
831 case BHND_CHIPID_BCM43112:
832 case BHND_CHIPID_BCM43224:
833 case BHND_CHIPID_BCM43225:
834 case BHND_CHIPID_BCM43421:
835 case BHND_CHIPID_BCM43226:
836 case BHND_CHIPID_BCM43420:
837 case BHND_CHIPID_BCM43235:
838 case BHND_CHIPID_BCM43236:
839 case BHND_CHIPID_BCM43238:
840 case BHND_CHIPID_BCM43234:
841 case BHND_CHIPID_BCM43237:
842 case BHND_CHIPID_BCM4331:
843 case BHND_CHIPID_BCM43431:
844 case BHND_CHIPID_BCM6362:
845 /* use chip default */
848 case BHND_CHIPID_BCM4328:
850 PMURES_BIT(RES4328_BB_SWITCHER_PWM) |
851 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
852 PMURES_BIT(RES4328_XTAL_EN);
853 max_mask = 0xfffffff;
856 case BHND_CHIPID_BCM5354:
857 /* Allow (but don't require) PLL to turn on */
858 max_mask = 0xfffffff;
861 case BHND_CHIPID_BCM4329:
862 /* Down to save the power. */
863 if (sc->cid.chip_rev >= 0x2) {
865 PMURES_BIT(RES4329_CBUCK_LPOM) |
866 PMURES_BIT(RES4329_LNLDO1_PU) |
867 PMURES_BIT(RES4329_CLDO_PU);
870 PMURES_BIT(RES4329_CBUCK_LPOM) |
871 PMURES_BIT(RES4329_CLDO_PU);
874 /* Is OTP required? */
875 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
876 otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4329_SPROM_OTP_SEL);
877 if (otpsel != CHIPC_CST_OTP_PWRDN)
878 min_mask |= PMURES_BIT(RES4329_OTP_PU);
880 /* Allow (but don't require) PLL to turn on */
884 case BHND_CHIPID_BCM4319:
885 /* We only need a few resources to be kept on all the time */
886 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
887 PMURES_BIT(RES4319_CLDO_PU);
889 /* Allow everything else to be turned on upon requests */
890 max_mask = ~(~0 << rsrcs);
893 case BHND_CHIPID_BCM4336:
894 /* Down to save the power. */
896 PMURES_BIT(RES4336_CBUCK_LPOM) |
897 PMURES_BIT(RES4336_CLDO_PU) |
898 PMURES_BIT(RES4336_LDO3P3_PU) |
899 PMURES_BIT(RES4336_OTP_PU) |
900 PMURES_BIT(RES4336_DIS_INT_RESET_PD);
901 /* Allow (but don't require) PLL to turn on */
902 max_mask = 0x1ffffff;
905 case BHND_CHIPID_BCM4330:
906 /* Down to save the power. */
908 PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
909 | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
910 PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
911 /* Allow (but don't require) PLL to turn on */
912 max_mask = 0xfffffff;
915 case BHND_CHIPID_BCM4313:
916 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
917 PMURES_BIT(RES4313_XTAL_PU_RSRC) |
918 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
919 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
926 /* Apply nvram override to min mask */
927 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMIN, &nval);
928 if (error && error != ENOENT) {
929 PMU_LOG(sc, "NVRAM error reading %s: %d\n",
930 BHND_NVAR_RMIN, error);
933 PMU_DEBUG(sc, "Applying rmin=%#x to min_mask\n", nval);
937 /* Apply nvram override to max mask */
938 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMAX, &nval);
939 if (error && error != ENOENT) {
940 PMU_LOG(sc, "NVRAM error reading %s: %d\n",
941 BHND_NVAR_RMAX, error);
944 PMU_DEBUG(sc, "Applying rmax=%#x to max_mask\n", nval);
957 /* initialize PMU resources */
959 bhnd_pmu_res_init(struct bhnd_pmu_softc *sc)
961 const pmu_res_updown_t *pmu_res_updown_table;
962 const pmu_res_depend_t *pmu_res_depend_table;
963 size_t pmu_res_updown_table_sz;
964 size_t pmu_res_depend_table_sz;
965 uint32_t max_mask, min_mask;
969 pmu_res_depend_table = NULL;
970 pmu_res_depend_table_sz = 0;
972 pmu_res_updown_table = NULL;
973 pmu_res_updown_table_sz = 0;
975 switch (sc->cid.chip_id) {
976 case BHND_CHIPID_BCM4315:
977 /* Optimize resources up/down timers */
978 pmu_res_updown_table = bcm4315a0_res_updown;
979 pmu_res_updown_table_sz = nitems(bcm4315a0_res_updown);
981 /* Optimize resources dependencies */
982 pmu_res_depend_table = bcm4315a0_res_depend;
983 pmu_res_depend_table_sz = nitems(bcm4315a0_res_depend);
986 case BHND_CHIPID_BCM4325:
987 /* Optimize resources up/down timers */
988 pmu_res_updown_table = bcm4325a0_res_updown;
989 pmu_res_updown_table_sz = nitems(bcm4325a0_res_updown);
991 /* Optimize resources dependencies */
992 pmu_res_depend_table = bcm4325a0_res_depend;
993 pmu_res_depend_table_sz = nitems(bcm4325a0_res_depend);
996 case BHND_CHIPID_BCM4328:
997 /* Optimize resources up/down timers */
998 pmu_res_updown_table = bcm4328a0_res_updown;
999 pmu_res_updown_table_sz = nitems(bcm4328a0_res_updown);
1001 /* Optimize resources dependencies */
1002 pmu_res_depend_table = bcm4328a0_res_depend;
1003 pmu_res_depend_table_sz = nitems(bcm4328a0_res_depend);
1006 case BHND_CHIPID_BCM4329:
1007 /* Optimize resources up/down timers */
1008 pmu_res_updown_table = bcm4329_res_updown;
1009 pmu_res_updown_table_sz = nitems(bcm4329_res_updown);
1011 /* Optimize resources dependencies */
1012 pmu_res_depend_table = bcm4329_res_depend;
1013 pmu_res_depend_table_sz = nitems(bcm4329_res_depend);
1016 case BHND_CHIPID_BCM4319:
1017 /* Optimize resources up/down timers */
1018 pmu_res_updown_table = bcm4319a0_res_updown;
1019 pmu_res_updown_table_sz = nitems(bcm4319a0_res_updown);
1021 /* Optimize resources dependencies masks */
1022 pmu_res_depend_table = bcm4319a0_res_depend;
1023 pmu_res_depend_table_sz = nitems(bcm4319a0_res_depend);
1026 case BHND_CHIPID_BCM4336:
1027 /* Optimize resources up/down timers */
1028 pmu_res_updown_table = bcm4336a0_res_updown;
1029 pmu_res_updown_table_sz = nitems(bcm4336a0_res_updown);
1031 /* Optimize resources dependencies masks */
1032 pmu_res_depend_table = bcm4336a0_res_depend;
1033 pmu_res_depend_table_sz = nitems(bcm4336a0_res_depend);
1036 case BHND_CHIPID_BCM4330:
1037 /* Optimize resources up/down timers */
1038 pmu_res_updown_table = bcm4330a0_res_updown;
1039 pmu_res_updown_table_sz = nitems(bcm4330a0_res_updown);
1041 /* Optimize resources dependencies masks */
1042 pmu_res_depend_table = bcm4330a0_res_depend;
1043 pmu_res_depend_table_sz = nitems(bcm4330a0_res_depend);
1050 rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC);
1052 /* Program up/down timers */
1053 for (size_t i = 0; i < pmu_res_updown_table_sz; i++) {
1054 const pmu_res_updown_t *updt;
1056 KASSERT(pmu_res_updown_table != NULL, ("no updown tables"));
1058 updt = &pmu_res_updown_table[pmu_res_updown_table_sz - i - 1];
1060 PMU_DEBUG(sc, "Changing rsrc %d res_updn_timer to %#x\n",
1061 updt->resnum, updt->updown);
1063 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, updt->resnum);
1064 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, updt->updown);
1067 /* Apply nvram overrides to up/down timers */
1068 for (uint8_t i = 0; i < rsrcs; i++) {
1072 snprintf(name, sizeof(name), "r%dt", i);
1073 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val);
1075 if (error == ENOENT) {
1078 PMU_LOG(sc, "NVRAM error reading %s: %d\n",
1083 PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_updn_timer\n",
1086 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1087 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, val);
1090 /* Program resource dependencies table */
1091 for (size_t i = 0; i < pmu_res_depend_table_sz; i++) {
1092 const pmu_res_depend_t *rdep;
1093 pmu_res_filter filter;
1094 uint32_t depend_mask;
1096 KASSERT(pmu_res_depend_table != NULL, ("no depend tables"));
1098 rdep = &pmu_res_depend_table[pmu_res_depend_table_sz - i - 1];
1099 filter = rdep->filter;
1101 if (filter != NULL && !filter(sc))
1104 for (uint8_t i = 0; i < rsrcs; i++) {
1105 if ((rdep->res_mask & BHND_PMURES_BIT(i)) == 0)
1108 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1109 depend_mask = BHND_PMU_READ_4(sc,
1110 BHND_PMU_RES_DEP_MASK);
1111 switch (rdep->action) {
1112 case RES_DEPEND_SET:
1113 PMU_DEBUG(sc, "Changing rsrc %hhu res_dep_mask to "
1114 "%#x\n", i, table->depend_mask);
1115 depend_mask = rdep->depend_mask;
1118 case RES_DEPEND_ADD:
1119 PMU_DEBUG(sc, "Adding %#x to rsrc %hhu "
1120 "res_dep_mask\n", table->depend_mask, i);
1122 depend_mask |= rdep->depend_mask;
1125 case RES_DEPEND_REMOVE:
1126 PMU_DEBUG(sc, "Removing %#x from rsrc %hhu "
1127 "res_dep_mask\n", table->depend_mask, i);
1129 depend_mask &= ~(rdep->depend_mask);
1133 panic("unknown RES_DEPEND action: %d\n",
1142 /* Apply nvram overrides to dependencies masks */
1143 for (uint8_t i = 0; i < rsrcs; i++) {
1147 snprintf(name, sizeof(name), "r%dd", i);
1148 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val);
1150 if (error == ENOENT) {
1153 PMU_LOG(sc, "NVRAM error reading %s: %d\n", name,
1158 PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_dep_mask\n", name,
1161 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1162 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_DEP_MASK, val);
1165 /* Determine min/max rsrc masks */
1166 if ((error = bhnd_pmu_res_masks(sc, &min_mask, &max_mask)))
1169 /* It is required to program max_mask first and then min_mask */
1171 /* Program max resource mask */
1172 if (max_mask != 0) {
1173 PMU_DEBUG(sc, "Changing max_res_mask to 0x%x\n", max_mask);
1174 BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask);
1177 /* Program min resource mask */
1179 if (min_mask != 0) {
1180 PMU_DEBUG(sc, "Changing min_res_mask to 0x%x\n", min_mask);
1181 BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask);
1184 /* Add some delay; allow resources to come up and settle. */
1190 /* setup pll and query clock speed */
1191 struct pmu0_xtaltab0 {
1198 /* the following table is based on 880Mhz fvco */
1199 static const pmu0_xtaltab0_t pmu0_xtaltab0[] = {
1201 12000, 1, 73, 349525}, {
1202 13000, 2, 67, 725937}, {
1203 14400, 3, 61, 116508}, {
1204 15360, 4, 57, 305834}, {
1205 16200, 5, 54, 336579}, {
1206 16800, 6, 52, 399457}, {
1207 19200, 7, 45, 873813}, {
1208 19800, 8, 44, 466033}, {
1210 25000, 10, 70, 419430}, {
1211 26000, 11, 67, 725937}, {
1212 30000, 12, 58, 699050}, {
1213 38400, 13, 45, 873813}, {
1214 40000, 14, 45, 0}, {
1218 #define PMU0_XTAL0_DEFAULT 8
1220 /* setup pll and query clock speed */
1221 struct pmu1_xtaltab0 {
1230 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
1232 12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
1233 13000, 2, 1, 6, 0xb, 0x483483}, {
1234 14400, 3, 1, 10, 0xa, 0x1C71C7}, {
1235 15360, 4, 1, 5, 0xb, 0x755555}, {
1236 16200, 5, 1, 10, 0x5, 0x6E9E06}, {
1237 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
1238 19200, 7, 1, 4, 0xb, 0x755555}, {
1239 19800, 8, 1, 11, 0x4, 0xA57EB}, {
1240 20000, 9, 1, 11, 0x4, 0x0}, {
1241 24000, 10, 3, 11, 0xa, 0x0}, {
1242 25000, 11, 5, 16, 0xb, 0x0}, {
1243 26000, 12, 1, 1, 0x21, 0xD89D89}, {
1244 30000, 13, 3, 8, 0xb, 0x0}, {
1245 37400, 14, 3, 1, 0x46, 0x969696}, {
1246 38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
1247 40000, 16, 1, 2, 0xb, 0}, {
1251 /* the following table is based on 880Mhz fvco */
1252 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
1254 12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
1255 13000, 2, 1, 6, 0xb, 0x483483}, {
1256 14400, 3, 1, 10, 0xa, 0x1C71C7}, {
1257 15360, 4, 1, 5, 0xb, 0x755555}, {
1258 16200, 5, 1, 10, 0x5, 0x6E9E06}, {
1259 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
1260 19200, 7, 1, 4, 0xb, 0x755555}, {
1261 19800, 8, 1, 11, 0x4, 0xA57EB}, {
1262 20000, 9, 1, 11, 0x4, 0x0}, {
1263 24000, 10, 3, 11, 0xa, 0x0}, {
1264 25000, 11, 5, 16, 0xb, 0x0}, {
1265 26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
1266 30000, 13, 3, 8, 0xb, 0x0}, {
1267 33600, 14, 1, 2, 0xd, 0x186186}, {
1268 38400, 15, 1, 2, 0xb, 0x755555}, {
1269 40000, 16, 1, 2, 0xb, 0}, {
1273 #define PMU1_XTALTAB0_880_12000K 0
1274 #define PMU1_XTALTAB0_880_13000K 1
1275 #define PMU1_XTALTAB0_880_14400K 2
1276 #define PMU1_XTALTAB0_880_15360K 3
1277 #define PMU1_XTALTAB0_880_16200K 4
1278 #define PMU1_XTALTAB0_880_16800K 5
1279 #define PMU1_XTALTAB0_880_19200K 6
1280 #define PMU1_XTALTAB0_880_19800K 7
1281 #define PMU1_XTALTAB0_880_20000K 8
1282 #define PMU1_XTALTAB0_880_24000K 9
1283 #define PMU1_XTALTAB0_880_25000K 10
1284 #define PMU1_XTALTAB0_880_26000K 11
1285 #define PMU1_XTALTAB0_880_30000K 12
1286 #define PMU1_XTALTAB0_880_37400K 13
1287 #define PMU1_XTALTAB0_880_38400K 14
1288 #define PMU1_XTALTAB0_880_40000K 15
1290 /* the following table is based on 1760Mhz fvco */
1291 static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = {
1293 12000, 1, 3, 44, 0x9, 0xFFFFEF}, {
1294 13000, 2, 1, 12, 0xb, 0x483483}, {
1295 14400, 3, 1, 20, 0xa, 0x1C71C7}, {
1296 15360, 4, 1, 10, 0xb, 0x755555}, {
1297 16200, 5, 1, 20, 0x5, 0x6E9E06}, {
1298 16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, {
1299 19200, 7, 1, 18, 0x5, 0x17B425}, {
1300 19800, 8, 1, 22, 0x4, 0xA57EB}, {
1301 20000, 9, 1, 22, 0x4, 0x0}, {
1302 24000, 10, 3, 22, 0xa, 0x0}, {
1303 25000, 11, 5, 32, 0xb, 0x0}, {
1304 26000, 12, 1, 4, 0x10, 0xEC4EC4}, {
1305 30000, 13, 3, 16, 0xb, 0x0}, {
1306 38400, 14, 1, 10, 0x4, 0x955555}, {
1307 40000, 15, 1, 4, 0xb, 0}, {
1312 #define PMU1_XTALTAB0_1760_12000K 0
1313 #define PMU1_XTALTAB0_1760_13000K 1
1314 #define PMU1_XTALTAB0_1760_14400K 2
1315 #define PMU1_XTALTAB0_1760_15360K 3
1316 #define PMU1_XTALTAB0_1760_16200K 4
1317 #define PMU1_XTALTAB0_1760_16800K 5
1318 #define PMU1_XTALTAB0_1760_19200K 6
1319 #define PMU1_XTALTAB0_1760_19800K 7
1320 #define PMU1_XTALTAB0_1760_20000K 8
1321 #define PMU1_XTALTAB0_1760_24000K 9
1322 #define PMU1_XTALTAB0_1760_25000K 10
1323 #define PMU1_XTALTAB0_1760_26000K 11
1324 #define PMU1_XTALTAB0_1760_30000K 12
1325 #define PMU1_XTALTAB0_1760_38400K 13
1326 #define PMU1_XTALTAB0_1760_40000K 14
1328 /* the following table is based on 1440Mhz fvco */
1329 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
1331 12000, 1, 1, 1, 0x78, 0x0}, {
1332 13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
1333 14400, 3, 1, 1, 0x64, 0x0}, {
1334 15360, 4, 1, 1, 0x5D, 0xC00000}, {
1335 16200, 5, 1, 1, 0x58, 0xE38E38}, {
1336 16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
1337 19200, 7, 1, 1, 0x4B, 0}, {
1338 19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
1339 20000, 9, 1, 1, 0x48, 0x0}, {
1340 25000, 10, 1, 1, 0x39, 0x999999}, {
1341 26000, 11, 1, 1, 0x37, 0x627627}, {
1342 30000, 12, 1, 1, 0x30, 0x0}, {
1343 37400, 13, 2, 1, 0x4D, 0x15E76}, {
1344 38400, 13, 2, 1, 0x4B, 0x0}, {
1345 40000, 14, 2, 1, 0x48, 0x0}, {
1346 48000, 15, 2, 1, 0x3c, 0x0}, {
1351 #define PMU1_XTALTAB0_1440_12000K 0
1352 #define PMU1_XTALTAB0_1440_13000K 1
1353 #define PMU1_XTALTAB0_1440_14400K 2
1354 #define PMU1_XTALTAB0_1440_15360K 3
1355 #define PMU1_XTALTAB0_1440_16200K 4
1356 #define PMU1_XTALTAB0_1440_16800K 5
1357 #define PMU1_XTALTAB0_1440_19200K 6
1358 #define PMU1_XTALTAB0_1440_19800K 7
1359 #define PMU1_XTALTAB0_1440_20000K 8
1360 #define PMU1_XTALTAB0_1440_25000K 9
1361 #define PMU1_XTALTAB0_1440_26000K 10
1362 #define PMU1_XTALTAB0_1440_30000K 11
1363 #define PMU1_XTALTAB0_1440_37400K 12
1364 #define PMU1_XTALTAB0_1440_38400K 13
1365 #define PMU1_XTALTAB0_1440_40000K 14
1366 #define PMU1_XTALTAB0_1440_48000K 15
1368 #define XTAL_FREQ_24000MHZ 24000
1369 #define XTAL_FREQ_30000MHZ 30000
1370 #define XTAL_FREQ_37400MHZ 37400
1371 #define XTAL_FREQ_48000MHZ 48000
1373 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
1375 12000, 1, 1, 1, 0x50, 0x0}, {
1376 13000, 2, 1, 1, 0x49, 0xD89D89}, {
1377 14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
1378 15360, 4, 1, 1, 0x3E, 0x800000}, {
1379 16200, 5, 1, 1, 0x39, 0x425ED0}, {
1380 16800, 6, 1, 1, 0x39, 0x249249}, {
1381 19200, 7, 1, 1, 0x32, 0x0}, {
1382 19800, 8, 1, 1, 0x30, 0x7C1F07}, {
1383 20000, 9, 1, 1, 0x30, 0x0}, {
1384 25000, 10, 1, 1, 0x26, 0x666666}, {
1385 26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
1386 30000, 12, 1, 1, 0x20, 0x0}, {
1387 37400, 13, 2, 1, 0x33, 0x563EF9}, {
1388 38400, 14, 2, 1, 0x32, 0x0}, {
1389 40000, 15, 2, 1, 0x30, 0x0}, {
1390 48000, 16, 2, 1, 0x28, 0x0}, {
1395 #define PMU1_XTALTAB0_960_12000K 0
1396 #define PMU1_XTALTAB0_960_13000K 1
1397 #define PMU1_XTALTAB0_960_14400K 2
1398 #define PMU1_XTALTAB0_960_15360K 3
1399 #define PMU1_XTALTAB0_960_16200K 4
1400 #define PMU1_XTALTAB0_960_16800K 5
1401 #define PMU1_XTALTAB0_960_19200K 6
1402 #define PMU1_XTALTAB0_960_19800K 7
1403 #define PMU1_XTALTAB0_960_20000K 8
1404 #define PMU1_XTALTAB0_960_25000K 9
1405 #define PMU1_XTALTAB0_960_26000K 10
1406 #define PMU1_XTALTAB0_960_30000K 11
1407 #define PMU1_XTALTAB0_960_37400K 12
1408 #define PMU1_XTALTAB0_960_38400K 13
1409 #define PMU1_XTALTAB0_960_40000K 14
1410 #define PMU1_XTALTAB0_960_48000K 15
1412 /* select xtal table for each chip */
1413 static const pmu1_xtaltab0_t *
1414 bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc)
1416 switch (sc->cid.chip_id) {
1417 case BHND_CHIPID_BCM4315:
1418 return (pmu1_xtaltab0_1760);
1419 case BHND_CHIPID_BCM4319:
1420 return (pmu1_xtaltab0_1440);
1421 case BHND_CHIPID_BCM4325:
1422 return (pmu1_xtaltab0_880);
1423 case BHND_CHIPID_BCM4329:
1424 return (pmu1_xtaltab0_880_4329);
1425 case BHND_CHIPID_BCM4336:
1426 return (pmu1_xtaltab0_960);
1427 case BHND_CHIPID_BCM4330:
1428 if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1429 return (pmu1_xtaltab0_960);
1431 return (pmu1_xtaltab0_1440);
1433 PMU_DEBUG(sc, "bhnd_pmu1_xtaltab0: Unknown chipid %#hx\n",
1439 /* select default xtal frequency for each chip */
1440 static const pmu1_xtaltab0_t *
1441 bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc)
1443 switch (sc->cid.chip_id) {
1444 case BHND_CHIPID_BCM4315:
1445 /* Default to 26000Khz */
1446 return (&pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_26000K]);
1447 case BHND_CHIPID_BCM4319:
1448 /* Default to 30000Khz */
1449 return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K]);
1450 case BHND_CHIPID_BCM4325:
1451 /* Default to 26000Khz */
1452 return (&pmu1_xtaltab0_880[PMU1_XTALTAB0_880_26000K]);
1453 case BHND_CHIPID_BCM4329:
1454 /* Default to 38400Khz */
1455 return (&pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]);
1456 case BHND_CHIPID_BCM4336:
1457 /* Default to 26000Khz */
1458 return (&pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K]);
1459 case BHND_CHIPID_BCM4330:
1460 /* Default to 37400Khz */
1461 if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1462 return (&pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]);
1464 return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]);
1466 PMU_DEBUG(sc, "bhnd_pmu1_xtaldef0: Unknown chipid %#hx\n",
1472 /* select default pll fvco for each chip */
1474 bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc)
1476 switch (sc->cid.chip_id) {
1477 case BHND_CHIPID_BCM4329:
1479 case BHND_CHIPID_BCM4319:
1481 case BHND_CHIPID_BCM4336:
1483 case BHND_CHIPID_BCM4330:
1484 if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1489 PMU_DEBUG(sc, "bhnd_pmu1_pllfvco0: Unknown chipid %#hx\n",
1495 /* query alp/xtal clock frequency */
1497 bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc)
1499 const pmu1_xtaltab0_t *xt;
1502 /* Find the frequency in the table */
1503 xf = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1504 xf = BHND_PMU_GET_BITS(xf, BHND_PMU_CTRL_XTALFREQ);
1506 for (xt = bhnd_pmu1_xtaltab0(sc); xt != NULL && xt->fref != 0; xt++) {
1511 /* Could not find it so assign a default value */
1512 if (xt == NULL || xt->fref == 0)
1513 xt = bhnd_pmu1_xtaldef0(sc);
1515 if (xt == NULL || xt->fref == 0) {
1516 PMU_LOG(sc, "no matching ALP/XTAL frequency found\n");
1520 return (xt->fref * 1000);
1523 /* Set up PLL registers in the PMU as per the crystal speed. */
1525 bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
1527 const pmu0_xtaltab0_t *xt;
1528 uint32_t pll_data, pll_mask;
1533 /* Use h/w default PLL config */
1535 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL "
1540 /* Find the frequency in the table */
1541 for (xt = pmu0_xtaltab0; xt->freq; xt ++) {
1542 if (xt->freq == xtal)
1547 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
1549 PMU_DEBUG(sc, "XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000,
1552 /* Check current PLL state */
1553 pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1554 xf = BHND_PMU_GET_BITS(pmu_ctrl, BHND_PMU_CTRL_XTALFREQ);
1557 if (sc->cid.chip_id == BHND_CHIPID_BCM4328) {
1558 bhnd_pmu0_sbclk4328(sc,
1559 BHND_PMU0_PLL0_PC0_DIV_ARM_88MHZ);
1562 #endif /* BCMUSBDEV */
1564 PMU_DEBUG(sc, "PLL already programmed for %d.%d MHz\n",
1565 xt->freq / 1000, xt->freq % 1000);
1571 "Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
1572 xt->freq / 1000, xt->freq % 1000,
1573 pmu0_xtaltab0[tmp-1].freq / 1000,
1574 pmu0_xtaltab0[tmp-1].freq % 1000);
1576 PMU_DEBUG(sc, "Programming PLL for %d.%d MHz\n",
1577 xt->freq / 1000, xt->freq % 1000);
1580 /* Make sure the PLL is off */
1581 switch (sc->cid.chip_id) {
1582 case BHND_CHIPID_BCM4328:
1583 pll_res = PMURES_BIT(RES4328_BB_PLL_PU);
1585 case BHND_CHIPID_BCM5354:
1586 pll_res = PMURES_BIT(RES5354_BB_PLL_PU);
1589 panic("unsupported chipid %#hx\n", sc->cid.chip_id);
1591 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~pll_res);
1592 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~pll_res);
1594 /* Wait for HT clock to shutdown. */
1595 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1597 PMU_DEBUG(sc, "Done masking\n");
1599 /* Write PDIV in pllcontrol[0] */
1600 if (xt->freq >= BHND_PMU0_PLL0_PC0_PDIV_FREQ) {
1601 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0,
1602 BHND_PMU0_PLL0_PC0_PDIV_MASK, BHND_PMU0_PLL0_PC0_PDIV_MASK);
1604 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0, 0,
1605 BHND_PMU0_PLL0_PC0_PDIV_MASK);
1608 /* Write WILD in pllcontrol[1] */
1610 BHND_PMU_SET_BITS(xt->wbint, BHND_PMU0_PLL0_PC1_WILD_INT) |
1611 BHND_PMU_SET_BITS(xt->wbfrac, BHND_PMU0_PLL0_PC1_WILD_FRAC);
1613 if (xt->wbfrac == 0) {
1614 pll_data |= BHND_PMU0_PLL0_PC1_STOP_MOD;
1616 pll_data &= ~BHND_PMU0_PLL0_PC1_STOP_MOD;
1620 BHND_PMU0_PLL0_PC1_WILD_INT_MASK |
1621 BHND_PMU0_PLL0_PC1_WILD_FRAC_MASK;
1623 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL1, pll_data, pll_mask);
1625 /* Write WILD in pllcontrol[2] */
1626 pll_data = BHND_PMU_SET_BITS(xt->wbint, BHND_PMU0_PLL0_PC2_WILD_INT);
1627 pll_mask = BHND_PMU0_PLL0_PC2_WILD_INT_MASK;
1628 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL2, pll_data, pll_mask);
1630 PMU_DEBUG(sc, "Done pll\n");
1632 /* Write XtalFreq. Set the divisor also. */
1633 pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1634 pmu_ctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK|BHND_PMU_CTRL_XTALFREQ_MASK);
1636 pmu_ctrl |= BHND_PMU_SET_BITS(((xt->freq + 127) / 128) - 1,
1637 BHND_PMU_CTRL_ILP_DIV);
1638 pmu_ctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ);
1640 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmu_ctrl);
1643 /* query alp/xtal clock frequency */
1645 bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc)
1647 const pmu0_xtaltab0_t *xt;
1650 /* Find the frequency in the table */
1651 xf = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1652 xf = BHND_PMU_GET_BITS(xf, BHND_PMU_CTRL_XTALFREQ);
1653 for (xt = pmu0_xtaltab0; xt->freq; xt++)
1657 /* PLL must be configured before */
1658 if (xt == NULL || xt->freq == 0)
1659 panic("unsupported frequency: %u", xf);
1661 return (xt->freq * 1000);
1664 /* query CPU clock frequency */
1666 bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc)
1668 uint32_t tmp, divarm;
1671 uint32_t pdiv, wbint, wbfrac, fvco;
1677 /* Read divarm from pllcontrol[0] */
1678 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL0);
1679 divarm = BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC0_DIV_ARM);
1682 /* Calculate fvco based on xtal freq, pdiv, and wild */
1683 pdiv = tmp & BHND_PMU0_PLL0_PC0_PDIV_MASK;
1685 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL1);
1686 wbfrac = BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC1_WILD_FRAC);
1687 wbint = BHND_PMU_GET_BITS(tmp, PMU0_PLL0_PC1_WILD_INT);
1689 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL2);
1690 wbint += BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC2_WILD_INT);
1692 freq = bhnd_pmu0_alpclk0(sih, osh, cc) / 1000;
1694 fvco = (freq * wbint) << 8;
1695 fvco += (freq * (wbfrac >> 10)) >> 2;
1696 fvco += (freq * (wbfrac & 0x3ff)) >> 10;
1702 PMU_DEBUG(sc, "bhnd_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
1703 wbint, wbfrac, fvco);
1708 /* Return ARM/SB clock */
1709 return FVCO / (divarm + BHND_PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
1714 /* Set up PLL registers in the PMU as per the crystal speed. */
1716 bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
1718 const pmu1_xtaltab0_t *xt;
1719 uint32_t buf_strength;
1720 uint32_t plladdr, plldata, pllmask;
1725 FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000;
1729 /* Use h/w default PLL config */
1731 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL "
1736 /* Find the frequency in the table */
1737 for (xt = bhnd_pmu1_xtaltab0(&sc->query); xt != NULL && xt->fref != 0;
1740 if (xt->fref == xtal)
1744 /* Check current PLL state, bail out if it has been programmed or
1745 * we don't know how to program it.
1747 if (xt == NULL || xt->fref == 0) {
1748 PMU_LOG(sc, "Unsupported XTAL frequency %d.%dMHz, skipping PLL "
1749 "configuration\n", xtal / 1000, xtal % 1000);
1753 /* For 4319 bootloader already programs the PLL but bootloader does not
1754 * program the PLL4 and PLL5. So Skip this check for 4319. */
1755 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1756 if (BHND_PMU_GET_BITS(pmuctrl, BHND_PMU_CTRL_XTALFREQ) == xt->xf &&
1757 sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
1758 sc->cid.chip_id != BHND_CHIPID_BCM4330)
1760 PMU_DEBUG(sc, "PLL already programmed for %d.%dMHz\n",
1761 xt->fref / 1000, xt->fref % 1000);
1765 PMU_DEBUG(sc, "XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf);
1766 PMU_DEBUG(sc, "Programming PLL for %d.%dMHz\n", xt->fref / 1000,
1769 switch (sc->cid.chip_id) {
1770 case BHND_CHIPID_BCM4325:
1771 /* Change the BBPLL drive strength to 2 for all channels */
1772 buf_strength = 0x222222;
1774 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1775 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
1776 PMURES_BIT(RES4325_HT_AVAIL)));
1777 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1778 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
1779 PMURES_BIT(RES4325_HT_AVAIL)));
1781 /* Wait for HT clock to shutdown. */
1782 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1785 case BHND_CHIPID_BCM4329:
1786 /* Change the BBPLL drive strength to 8 for all channels */
1787 buf_strength = 0x888888;
1789 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1790 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1791 PMURES_BIT(RES4329_HT_AVAIL)));
1792 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1793 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1794 PMURES_BIT(RES4329_HT_AVAIL)));
1796 /* Wait for HT clock to shutdown. */
1797 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1799 /* Initialize PLL4 */
1800 plladdr = BHND_PMU1_PLL0_PLLCTL4;
1801 if (xt->fref == 38400)
1802 plldata = 0x200024C0;
1803 else if (xt->fref == 37400)
1804 plldata = 0x20004500;
1805 else if (xt->fref == 26000)
1806 plldata = 0x200024C0;
1808 plldata = 0x200005C0; /* Chip Dflt Settings */
1810 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0);
1812 /* Initialize PLL5 */
1813 plladdr = BHND_PMU1_PLL0_PLLCTL5;
1815 plldata = BHND_PMU_PLL_READ(sc, plladdr);
1816 plldata &= BHND_PMU1_PLL0_PC5_CLK_DRV_MASK;
1818 if (xt->fref == 38400 ||
1819 xt->fref == 37400 ||
1820 xt->fref == 26000) {
1823 plldata |= 0x25; /* Chip Dflt Settings */
1826 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0);
1829 case BHND_CHIPID_BCM4319:
1830 /* Change the BBPLL drive strength to 2 for all channels */
1831 buf_strength = 0x222222;
1833 /* Make sure the PLL is off */
1834 /* WAR65104: Disable the HT_AVAIL resource first and then
1835 * after a delay (more than downtime for HT_AVAIL) remove the
1836 * BBPLL resource; backplane clock moves to ALP from HT.
1838 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1839 ~(PMURES_BIT(RES4319_HT_AVAIL)));
1840 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1841 ~(PMURES_BIT(RES4319_HT_AVAIL)));
1844 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1845 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1846 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1847 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1851 /* Wait for HT clock to shutdown. */
1852 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1854 plldata = 0x200005c0;
1855 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, plldata, ~0);
1858 case BHND_CHIPID_BCM4336:
1859 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1860 ~(PMURES_BIT(RES4336_HT_AVAIL) |
1861 PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1862 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1863 ~(PMURES_BIT(RES4336_HT_AVAIL) |
1864 PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1867 /* Wait for HT clock to shutdown. */
1868 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1872 case BHND_CHIPID_BCM4330:
1873 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1874 ~(PMURES_BIT(RES4330_HT_AVAIL) |
1875 PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1876 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1877 ~(PMURES_BIT(RES4330_HT_AVAIL) |
1878 PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1881 /* Wait for HT clock to shutdown. */
1882 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1887 panic("unsupported chipid %#hx\n", sc->cid.chip_id);
1890 PMU_DEBUG(sc, "Done masking\n");
1892 /* Write p1div and p2div to pllcontrol[0] */
1894 BHND_PMU_SET_BITS(xt->p1div, BHND_PMU1_PLL0_PC0_P1DIV) |
1895 BHND_PMU_SET_BITS(xt->p2div, BHND_PMU1_PLL0_PC0_P2DIV);
1896 pllmask = BHND_PMU1_PLL0_PC0_P1DIV_MASK|BHND_PMU1_PLL0_PC0_P2DIV_MASK;
1898 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1899 plldata &= ~(BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK);
1900 pllmask |= BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK;
1901 if (!xt->ndiv_frac) {
1902 plldata |= BHND_PMU_SET_BITS(1,
1903 BHND_PMU1_PLL0_PC0_BYPASS_SDMOD);
1907 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, plldata, pllmask);
1910 if (sc->cid.chip_id == BHND_CHIPID_BCM4330)
1911 bhnd_pmu_set_4330_plldivs(sc);
1913 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) {
1914 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
1915 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_VAL,
1916 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
1919 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1920 if (sc->cid.chip_id == BHND_CHIPID_BCM4336 ||
1921 sc->cid.chip_id == BHND_CHIPID_BCM4330)
1923 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB;
1924 } else if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1925 if (!(xt->ndiv_frac))
1926 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_INT;
1928 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB;
1930 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MASH;
1934 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
1935 BHND_PMU_SET_BITS(xt->ndiv_int, BHND_PMU1_PLL0_PC2_NDIV_INT) |
1936 BHND_PMU_SET_BITS(ndiv_mode, BHND_PMU1_PLL0_PC2_NDIV_MODE),
1937 BHND_PMU1_PLL0_PC2_NDIV_INT_MASK |
1938 BHND_PMU1_PLL0_PC2_NDIV_MODE_MASK);
1940 /* Write ndiv_frac to pllcontrol[3] */
1941 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
1942 BHND_PMU_SET_BITS(xt->ndiv_frac, BHND_PMU1_PLL0_PC3_NDIV_FRAC),
1943 BHND_PMU1_PLL0_PC3_NDIV_FRAC_MASK);
1945 /* Writing to pllcontrol[4] */
1946 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1950 plldata = 0x200005c0;
1952 plldata = 0x202C2820;
1959 plldata &= ~(BHND_PMU1_PLL0_PC4_KVCO_XS_MASK);
1960 plldata |= BHND_PMU_SET_BITS(xs, BHND_PMU1_PLL0_PC4_KVCO_XS);
1961 BHND_PMU_WRITE_4(sc, BHND_PMU1_PLL0_PLLCTL4, plldata);
1964 /* Write clock driving strength to pllcontrol[5] */
1966 PMU_DEBUG(sc, "Adjusting PLL buffer drive strength: %x\n",
1969 plldata = BHND_PMU_SET_BITS(buf_strength,
1970 BHND_PMU1_PLL0_PC5_CLK_DRV);
1971 pllmask = BHND_PMU1_PLL0_PC5_CLK_DRV_MASK;
1973 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1975 BHND_PMU1_PLL0_PC5_VCO_RNG_MASK |
1976 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK;
1978 if (!xt->ndiv_frac) {
1979 plldata |= BHND_PMU_SET_BITS(0x25,
1980 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32);
1982 plldata |= BHND_PMU_SET_BITS(0x15,
1983 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32);
1987 plldata |= BHND_PMU_SET_BITS(0x1,
1988 BHND_PMU1_PLL0_PC5_VCO_RNG);
1992 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, plldata,
1996 PMU_DEBUG(sc, "Done pll\n");
1998 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
2001 if (sc->cid.chip_id == BHND_CHIPID_BCM4319 &&
2002 xt->fref != XTAL_FREQ_30000MHZ)
2007 case XTAL_FREQ_24000MHZ:
2008 pll_sel = BHND_PMU_CCTL_4319USB_24MHZ_PLL_SEL;
2010 case XTAL_FREQ_48000MHZ:
2011 pll_sel = BHND_PMU_CCTL_4319USB_48MHZ_PLL_SEL;
2014 panic("unsupported 4319USB XTAL frequency: %hu\n",
2018 BHND_PMU_CCTRL_WRITE(sc, BHND_PMU1_PLL0_CHIPCTL2,
2019 BHND_PMU_SET_BITS(pll_sel, BHND_PMU_CCTL_4319USB_XTAL_SEL),
2020 BHND_PMU_CCTL_4319USB_XTAL_SEL_MASK);
2023 /* Flush deferred pll control registers writes */
2024 if (BHND_PMU_REV(sc) >= 2)
2025 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_PLL_PLLCTL_UPD);
2027 /* Write XtalFreq. Set the divisor also. */
2028 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
2029 pmuctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK | BHND_PMU_CTRL_XTALFREQ_MASK);
2030 pmuctrl |= BHND_PMU_SET_BITS(((xt->fref + 127) / 128) - 1,
2031 BHND_PMU_CTRL_ILP_DIV);
2032 pmuctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ);
2034 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) {
2035 /* clear the htstretch before clearing HTReqEn */
2036 BHND_PMU_AND_4(sc, BHND_PMU_CLKSTRETCH, ~BHND_PMU_CLKSTRETCH);
2037 pmuctrl &= ~BHND_PMU_CTRL_HT_REQ_EN;
2040 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmuctrl);
2043 /* query the CPU clock frequency */
2045 bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc)
2047 uint32_t tmp, m1div;
2049 uint32_t ndiv_int, ndiv_frac, p2div, p1div, fvco;
2052 uint32_t FVCO = bhnd_pmu1_pllfvco0(sc);
2054 /* Read m1div from pllcontrol[1] */
2055 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL1);
2056 m1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC1_M1DIV);
2059 /* Read p2div/p1div from pllcontrol[0] */
2060 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL0);
2061 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P2DIV);
2062 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P1DIV);
2064 /* Calculate fvco based on xtal freq and ndiv and pdiv */
2065 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL2);
2066 ndiv_int = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC2_NDIV_INT);
2068 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL3);
2069 ndiv_frac = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC3_NDIV_FRAC);
2071 fref = bhnd_pmu1_alpclk0(sc) / 1000;
2073 fvco = (fref * ndiv_int) << 8;
2074 fvco += (fref * (ndiv_frac >> 12)) >> 4;
2075 fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
2082 PMU_DEBUG(sc, "bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u "
2083 "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco);
2088 /* Return ARM/SB clock */
2089 return (FVCO / m1div * 1000);
2092 /* initialize PLL */
2094 bhnd_pmu_pll_init(struct bhnd_pmu_softc *sc, u_int xtalfreq)
2096 uint32_t max_mask, min_mask;
2097 uint32_t res_ht, res_pll;
2099 switch (sc->cid.chip_id) {
2100 case BHND_CHIPID_BCM4312:
2101 /* assume default works */
2103 case BHND_CHIPID_BCM4322:
2104 case BHND_CHIPID_BCM43221:
2105 case BHND_CHIPID_BCM43231:
2106 case BHND_CHIPID_BCM4342:
2107 if (sc->cid.chip_rev != 0)
2110 min_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK);
2111 max_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK);
2112 res_ht = PMURES_BIT(RES4322_HT_SI_AVAIL);
2113 res_pll = PMURES_BIT(RES4322_SI_PLL_ON);
2115 /* Have to remove HT Avail request before powering off PLL */
2116 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_ht);
2117 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_ht);
2118 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2120 /* Make sure the PLL is off */
2121 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_pll);
2122 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_pll);
2123 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2127 BHND_PMU_PLL_WRITE(sc, BHND_PMU2_SI_PLL_PLLCTL, 0x380005c0, ~0);
2130 BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask);
2132 BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask);
2136 case BHND_CHIPID_BCM4325:
2137 bhnd_pmu1_pllinit0(sc, xtalfreq);
2139 case BHND_CHIPID_BCM4328:
2140 bhnd_pmu0_pllinit0(sc, xtalfreq);
2142 case BHND_CHIPID_BCM5354:
2145 bhnd_pmu0_pllinit0(sc, xtalfreq);
2147 case BHND_CHIPID_BCM4329:
2150 bhnd_pmu1_pllinit0(sc, xtalfreq);
2153 case BHND_CHIPID_BCM4313:
2154 case BHND_CHIPID_BCM43222:
2155 case BHND_CHIPID_BCM43111:
2156 case BHND_CHIPID_BCM43112:
2157 case BHND_CHIPID_BCM43224:
2158 case BHND_CHIPID_BCM43225:
2159 case BHND_CHIPID_BCM43420:
2160 case BHND_CHIPID_BCM43421:
2161 case BHND_CHIPID_BCM43226:
2162 case BHND_CHIPID_BCM43235:
2163 case BHND_CHIPID_BCM43236:
2164 case BHND_CHIPID_BCM43238:
2165 case BHND_CHIPID_BCM43234:
2166 case BHND_CHIPID_BCM43237:
2167 case BHND_CHIPID_BCM4331:
2168 case BHND_CHIPID_BCM43431:
2169 case BHND_CHIPID_BCM43131:
2170 case BHND_CHIPID_BCM43227:
2171 case BHND_CHIPID_BCM43228:
2172 case BHND_CHIPID_BCM43428:
2173 case BHND_CHIPID_BCM6362:
2174 /* assume default works */
2177 case BHND_CHIPID_BCM4315:
2178 case BHND_CHIPID_BCM4319:
2179 case BHND_CHIPID_BCM4336:
2180 case BHND_CHIPID_BCM4330:
2181 bhnd_pmu1_pllinit0(sc, xtalfreq);
2184 PMU_DEBUG("No PLL init done for chip %#hx rev %d pmurev %d\n",
2185 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc));
2191 * Return the ALP/XTAL clock frequency, in Hz.
2193 * @param sc PMU query instance.
2196 bhnd_pmu_alp_clock(struct bhnd_pmu_query *sc)
2200 clock = BHND_PMU_ALP_CLOCK;
2201 switch (sc->cid.chip_id) {
2202 case BHND_CHIPID_BCM4328:
2203 case BHND_CHIPID_BCM5354:
2204 clock = bhnd_pmu0_alpclk0(sc);
2206 case BHND_CHIPID_BCM4315:
2207 case BHND_CHIPID_BCM4319:
2208 case BHND_CHIPID_BCM4325:
2209 case BHND_CHIPID_BCM4329:
2210 case BHND_CHIPID_BCM4330:
2211 case BHND_CHIPID_BCM4336:
2212 clock = bhnd_pmu1_alpclk0(sc);
2214 case BHND_CHIPID_BCM4312:
2215 case BHND_CHIPID_BCM4322:
2216 case BHND_CHIPID_BCM43221:
2217 case BHND_CHIPID_BCM43231:
2218 case BHND_CHIPID_BCM43222:
2219 case BHND_CHIPID_BCM43111:
2220 case BHND_CHIPID_BCM43112:
2221 case BHND_CHIPID_BCM43224:
2222 case BHND_CHIPID_BCM43225:
2223 case BHND_CHIPID_BCM43420:
2224 case BHND_CHIPID_BCM43421:
2225 case BHND_CHIPID_BCM43226:
2226 case BHND_CHIPID_BCM43235:
2227 case BHND_CHIPID_BCM43236:
2228 case BHND_CHIPID_BCM43238:
2229 case BHND_CHIPID_BCM43234:
2230 case BHND_CHIPID_BCM43237:
2231 case BHND_CHIPID_BCM4331:
2232 case BHND_CHIPID_BCM43431:
2233 case BHND_CHIPID_BCM43131:
2234 case BHND_CHIPID_BCM43227:
2235 case BHND_CHIPID_BCM43228:
2236 case BHND_CHIPID_BCM43428:
2237 case BHND_CHIPID_BCM6362:
2238 case BHND_CHIPID_BCM4342:
2239 case BHND_CHIPID_BCM4716:
2240 case BHND_CHIPID_BCM4748:
2241 case BHND_CHIPID_BCM47162:
2242 case BHND_CHIPID_BCM4313:
2243 case BHND_CHIPID_BCM5357:
2244 case BHND_CHIPID_BCM4749:
2245 case BHND_CHIPID_BCM53572:
2247 clock = 20000 * 1000;
2249 case BHND_CHIPID_BCM5356:
2250 case BHND_CHIPID_BCM4706:
2252 clock = 25000 * 1000;
2255 PMU_DEBUG("No ALP clock specified "
2256 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2257 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
2258 sih->pmurev, clock);
2265 /* Find the output of the "m" pll divider given pll controls that start with
2266 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
2269 bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
2277 if ((pll0 & 3) || (pll0 > BHND_PMU4716_MAINPLL_PLL0)) {
2278 PMU_LOG(sc, "%s: Bad pll0: %d", __func__, pll0);
2282 /* Strictly there is an m5 divider, but I'm not sure we use it */
2283 if ((m == 0) || (m > 4)) {
2284 PMU_LOG(sc, "%s: Bad m divider: %d", __func__, m);
2288 if (sc->cid.chip_id == BHND_CHIPID_BCM5357 ||
2289 sc->cid.chip_id == BHND_CHIPID_BCM4749)
2291 /* Detect failure in clock setting */
2292 tmp = sc->io->rd_chipst(sc->io_ctx);
2293 if ((tmp & 0x40000) != 0)
2294 return (133 * 1000000);
2298 /* Fetch p1 and p2 */
2299 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2300 pll0 + BHND_PMU5_PLL_P1P2_OFF);
2301 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2303 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2304 p1 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P1);
2305 p2 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P2);
2308 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2309 pll0 + BHND_PMU5_PLL_M14_OFF);
2310 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2312 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2313 div = (tmp >> ((m - 1) * BHND_PMU5_PLL_MDIV_WIDTH));
2314 div &= BHND_PMU5_PLL_MDIV_MASK;
2317 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2318 pll0 + BHND_PMU5_PLL_NM5_OFF);
2319 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2321 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2322 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_NDIV);
2324 /* Do calculation in Mhz */
2325 fc = bhnd_pmu_alp_clock(sc) / 1000000;
2326 fc = (p1 * ndiv * fc) / p2;
2328 PMU_DEBUG(sc, "%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, "
2329 "clock=%d\n", __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div);
2331 /* Return clock in Hertz */
2332 return ((fc / div) * 1000000);
2336 bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
2338 uint32_t chipst, clock;
2339 uint32_t ndiv, p1div, p2div, tmp;
2341 /* Get N, P1 and P2 dividers to determine CPU clock */
2342 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2343 pll0 + BHND_PMU6_4706_PROCPLL_OFF);
2344 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2346 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2347 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_NDIV_INT);
2348 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P1DIV);
2349 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P2DIV);
2351 /* Fixed 25MHz reference clock */
2352 clock = 25 * 1000 * 1000;
2354 /* The low-cost bonding uses an input divider of 4; otherwise, 2 */
2355 chipst = sc->io->rd_chipst(sc->io_ctx);
2356 if (chipst & CHIPC_CST4706_LOWCOST_PKG)
2361 clock *= ndiv * p2div / p1div;
2364 case BHND_PMU6_MAINPLL_CPU:
2366 case BHND_PMU6_MAINPLL_MEM:
2368 case BHND_PMU6_MAINPLL_SI:
2371 PMU_LOG(sc, "bad m divider: %d", m);
2377 * Return the backplane clock frequency, in Hz.
2379 * On designs that feed the same clock to both backplane
2380 * and CPU, this returns the CPU clock speed.
2382 * @param sc PMU query instance.
2385 bhnd_pmu_si_clock(struct bhnd_pmu_query *sc)
2390 clock = BHND_PMU_HT_CLOCK;
2392 switch (sc->cid.chip_id) {
2393 case BHND_CHIPID_BCM4322:
2394 case BHND_CHIPID_BCM43221:
2395 case BHND_CHIPID_BCM43231:
2396 case BHND_CHIPID_BCM43222:
2397 case BHND_CHIPID_BCM43111:
2398 case BHND_CHIPID_BCM43112:
2399 case BHND_CHIPID_BCM43224:
2400 case BHND_CHIPID_BCM43420:
2401 case BHND_CHIPID_BCM43225:
2402 case BHND_CHIPID_BCM43421:
2403 case BHND_CHIPID_BCM43226:
2404 case BHND_CHIPID_BCM4331:
2405 case BHND_CHIPID_BCM43431:
2406 case BHND_CHIPID_BCM6362:
2407 case BHND_CHIPID_BCM4342:
2408 /* 96MHz backplane clock */
2409 clock = 96000 * 1000;
2412 case BHND_CHIPID_BCM4716:
2413 case BHND_CHIPID_BCM4748:
2414 case BHND_CHIPID_BCM47162:
2415 clock = bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2416 BHND_PMU5_MAINPLL_SI);
2419 case BHND_CHIPID_BCM4325:
2420 clock = bhnd_pmu1_cpuclk0(sc);
2423 case BHND_CHIPID_BCM4328:
2424 clock = bhnd_pmu0_cpuclk0(sc);
2427 case BHND_CHIPID_BCM4329:
2428 if (sc->cid.chip_rev == 0)
2429 clock = 38400 * 1000;
2431 clock = bhnd_pmu1_cpuclk0(sc);
2434 case BHND_CHIPID_BCM4315:
2435 case BHND_CHIPID_BCM4319:
2436 case BHND_CHIPID_BCM4336:
2437 case BHND_CHIPID_BCM4330:
2438 clock = bhnd_pmu1_cpuclk0(sc);
2441 case BHND_CHIPID_BCM4313:
2442 /* 80MHz backplane clock */
2443 clock = 80000 * 1000;
2446 case BHND_CHIPID_BCM43234:
2447 case BHND_CHIPID_BCM43235:
2448 case BHND_CHIPID_BCM43236:
2449 case BHND_CHIPID_BCM43238:
2450 chipst = sc->io->rd_chipst(sc->io_ctx);
2451 if (chipst & CHIPC_CST43236_BP_CLK)
2452 clock = 120000 * 1000;
2454 clock = 96000 * 1000;
2456 case BHND_CHIPID_BCM43237:
2457 chipst = sc->io->rd_chipst(sc->io_ctx);
2458 if (chipst & CHIPC_CST43237_BP_CLK)
2459 clock = 96000 * 1000;
2461 clock = 80000 * 1000;
2463 case BHND_CHIPID_BCM5356:
2464 clock = bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2465 BHND_PMU5_MAINPLL_SI);
2467 case BHND_CHIPID_BCM5357:
2468 case BHND_CHIPID_BCM4749:
2469 clock = bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2470 BHND_PMU5_MAINPLL_SI);
2472 case BHND_CHIPID_BCM4706:
2473 clock = bhnd_pmu6_4706_clock(sc, BHND_PMU4706_MAINPLL_PLL0,
2474 BHND_PMU6_MAINPLL_SI);
2476 case BHND_CHIPID_BCM53572:
2480 PMU_LOG(sc, "No backplane clock specified for chip %#hx rev "
2481 "%hhd pmurev %hhd, using default %dHz\n",
2482 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc), clock);
2490 * Return the CPU clock frequency, in Hz.
2492 * @param sc PMU query instance.
2495 bhnd_pmu_cpu_clock(struct bhnd_pmu_query *sc)
2497 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
2498 if (sc->cid.chip_id == BHND_CHIPID_BCM5354)
2499 return (240 * 1000 * 1000); /* 240MHz */
2501 if (sc->cid.chip_id == BHND_CHIPID_BCM53572)
2504 if (BHND_PMU_REV(sc) >= 5 &&
2505 sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
2506 sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
2507 sc->cid.chip_id != BHND_CHIPID_BCM43234 &&
2508 sc->cid.chip_id != BHND_CHIPID_BCM43235 &&
2509 sc->cid.chip_id != BHND_CHIPID_BCM43236 &&
2510 sc->cid.chip_id != BHND_CHIPID_BCM43237 &&
2511 sc->cid.chip_id != BHND_CHIPID_BCM43238 &&
2512 sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
2513 sc->cid.chip_id != BHND_CHIPID_BCM4330)
2515 switch (sc->cid.chip_id) {
2516 case BHND_CHIPID_BCM5356:
2517 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2518 BHND_PMU5_MAINPLL_CPU));
2520 case BHND_CHIPID_BCM5357:
2521 case BHND_CHIPID_BCM4749:
2522 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2523 BHND_PMU5_MAINPLL_CPU));
2525 case BHND_CHIPID_BCM4706:
2526 return (bhnd_pmu6_4706_clock(sc,
2527 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_CPU));
2530 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2531 BHND_PMU5_MAINPLL_CPU));
2534 return (bhnd_pmu_si_clock(sc));
2539 * Return the memory clock frequency, in Hz.
2541 * @param sc PMU query instance.
2544 bhnd_pmu_mem_clock(struct bhnd_pmu_query *sc)
2546 if (BHND_PMU_REV(sc) >= 5 &&
2547 sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
2548 sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
2549 sc->cid.chip_id != BHND_CHIPID_BCM43234 &&
2550 sc->cid.chip_id != BHND_CHIPID_BCM43235 &&
2551 sc->cid.chip_id != BHND_CHIPID_BCM43236 &&
2552 sc->cid.chip_id != BHND_CHIPID_BCM43237 &&
2553 sc->cid.chip_id != BHND_CHIPID_BCM43238 &&
2554 sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
2555 sc->cid.chip_id != BHND_CHIPID_BCM4330)
2557 switch (sc->cid.chip_id) {
2558 case BHND_CHIPID_BCM5356:
2559 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2560 BHND_PMU5_MAINPLL_MEM));
2562 case BHND_CHIPID_BCM5357:
2563 case BHND_CHIPID_BCM4749:
2564 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2565 BHND_PMU5_MAINPLL_MEM));
2567 case BHND_CHIPID_BCM4706:
2568 return (bhnd_pmu6_4706_clock(sc,
2569 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_MEM));
2572 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2573 BHND_PMU5_MAINPLL_MEM));
2577 return (bhnd_pmu_si_clock(sc));
2581 /* Measure ILP clock frequency */
2582 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */
2585 * Measure and return the ILP clock frequency, in Hz.
2587 * @param sc PMU query instance.
2590 bhnd_pmu_ilp_clock(struct bhnd_pmu_query *sc)
2592 uint32_t start, end, delta;
2594 if (sc->ilp_cps == 0) {
2595 start = BHND_PMU_READ_4(sc, BHND_PMU_TIMER);
2596 DELAY(ILP_CALC_DUR);
2597 end = BHND_PMU_READ_4(sc, BHND_PMU_TIMER);
2598 delta = end - start;
2599 sc->ilp_cps = delta * (1000 / ILP_CALC_DUR);
2602 return (sc->ilp_cps);
2605 /* SDIO Pad drive strength to select value mappings */
2607 uint8_t strength; /* Pad Drive Strength in mA */
2608 uint8_t sel; /* Chip-specific select value */
2609 } sdiod_drive_str_t;
2611 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
2612 static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = {
2620 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
2621 static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = {
2632 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
2633 static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = {
2645 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
2648 bhnd_pmu_sdiod_drive_strength_init(struct bhnd_pmu_softc *sc,
2649 uint32_t drivestrength)
2651 const sdiod_drive_str_t *str_tab;
2661 switch (SDIOD_DRVSTR_KEY(sc->cid.chip_id, BHND_PMU_REV(sc))) {
2662 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 1):
2663 str_tab = sdiod_drive_strength_tab1;
2664 str_mask = 0x30000000;
2667 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 2):
2668 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 3):
2669 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4315, 4):
2670 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4319, 7):
2671 str_tab = sdiod_drive_strength_tab2;
2672 str_mask = 0x00003800;
2675 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4336, 8):
2676 str_tab = sdiod_drive_strength_tab3;
2677 str_mask = 0x00003800;
2682 PMU_LOG(sc, "No SDIO Drive strength init done for chip %#x "
2683 "rev %hhd pmurev %hhd\n", sc->cid.chip_id, sc->cid.chip_rev,
2688 if (str_tab != NULL) {
2689 uint32_t drivestrength_sel = 0;
2690 uint32_t cc_data_temp;
2692 for (u_int i = 0; str_tab[i].strength != 0; i++) {
2693 if (drivestrength >= str_tab[i].strength) {
2694 drivestrength_sel = str_tab[i].sel;
2699 cc_data_temp = BHND_PMU_CCTRL_READ(sc, 1);
2700 cc_data_temp &= ~str_mask;
2701 drivestrength_sel <<= str_shift;
2702 cc_data_temp |= drivestrength_sel;
2703 BHND_PMU_CCTRL_WRITE(sc, 1, cc_data_temp, ~0);
2705 PMU_DEBUG(sc, "SDIO: %dmA drive strength selected, set to "
2706 "0x%08x\n", drivestrength, cc_data_temp);
2711 * Initialize the PMU.
2714 bhnd_pmu_init(struct bhnd_pmu_softc *sc)
2719 if (BHND_PMU_REV(sc) == 1) {
2720 BHND_PMU_AND_4(sc, BHND_PMU_CTRL, ~BHND_PMU_CTRL_NOILP_ON_WAIT);
2721 } else if (BHND_PMU_REV(sc) >= 2) {
2722 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_NOILP_ON_WAIT);
2725 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 2) {
2726 /* Fix for 4329b0 bad LPOM state. */
2727 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x100, ~0);
2728 BHND_PMU_REGCTRL_WRITE(sc, 3, 0x4, ~0);
2731 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
2732 /* Limiting the PALDO spike during init time */
2733 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x00000005, 0x00000007);
2737 /* Fetch target xtalfreq, in KHz */
2738 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_XTALFREQ,
2741 /* If not available, log any real errors, and then try to measure it */
2743 if (error != ENOENT)
2744 PMU_LOG(sc, "error fetching xtalfreq: %d\n", error);
2746 xtalfreq = bhnd_pmu_measure_alpclk(sc);
2749 /* Perform PLL initialization */
2750 bhnd_pmu_pll_init(sc, xtalfreq);
2752 if ((error = bhnd_pmu_res_init(sc)))
2755 bhnd_pmu_swreg_init(sc);
2760 /* Return up time in ILP cycles for the given resource. */
2762 bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc, uint32_t *uptime)
2765 uint32_t up, dup, dmax;
2769 /* uptime of resource 'rsrc' */
2770 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, rsrc);
2771 up = BHND_PMU_READ_4(sc, BHND_PMU_RES_UPDN_TIMER);
2772 up = BHND_PMU_GET_BITS(up, BHND_PMU_RES_UPDN_UPTME);
2774 /* Find direct dependencies of resource 'rsrc' */
2775 deps = bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(rsrc), false);
2776 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2777 if (!(deps & BHND_PMURES_BIT(i)))
2779 deps &= ~bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(i), true);
2782 /* Exclude the minimum resource set */
2783 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL)))
2788 /* max uptime of direct dependencies */
2790 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2791 if (!(deps & BHND_PMURES_BIT(i)))
2794 if ((error = bhnd_pmu_res_uptime(sc, i, &dup)))
2801 PMU_DEBUG(sc, "bhnd_pmu_res_uptime: rsrc %hhu uptime %u(deps 0x%08x "
2802 "uptime %u)\n", rsrc, up, deps, dmax);
2804 *uptime = (up + dmax + BHND_PMURES_UP_TRANSITION);
2808 /* Return dependencies (direct or all/indirect) for the given resources */
2810 bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs, bool all)
2815 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2816 if (!(rsrcs & BHND_PMURES_BIT(i)))
2819 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
2820 deps |= BHND_PMU_READ_4(sc, BHND_PMU_RES_DEP_MASK);
2827 /* Recurse dependencies */
2829 deps |= bhnd_pmu_res_deps(sc, deps, true);
2834 /* power up/down OTP through PMU resources */
2836 bhnd_pmu_otp_power(struct bhnd_pmu_softc *sc, bool on)
2843 /* Determine rsrcs to turn on/off OTP power */
2844 switch (sc->cid.chip_id) {
2845 case BHND_CHIPID_BCM4322:
2846 case BHND_CHIPID_BCM43221:
2847 case BHND_CHIPID_BCM43231:
2848 case BHND_CHIPID_BCM4342:
2849 rsrcs = PMURES_BIT(RES4322_OTP_PU);
2851 case BHND_CHIPID_BCM4315:
2852 rsrcs = PMURES_BIT(RES4315_OTP_PU);
2854 case BHND_CHIPID_BCM4325:
2855 rsrcs = PMURES_BIT(RES4325_OTP_PU);
2857 case BHND_CHIPID_BCM4329:
2858 rsrcs = PMURES_BIT(RES4329_OTP_PU);
2860 case BHND_CHIPID_BCM4319:
2861 rsrcs = PMURES_BIT(RES4319_OTP_PU);
2863 case BHND_CHIPID_BCM4336:
2864 rsrcs = PMURES_BIT(RES4336_OTP_PU);
2866 case BHND_CHIPID_BCM4330:
2867 rsrcs = PMURES_BIT(RES4330_OTP_PU);
2874 /* Fetch all dependencies */
2875 deps = bhnd_pmu_res_deps(sc, rsrcs, true);
2877 /* Exclude the minimum resource set */
2878 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL)))
2883 /* Turn on/off the power */
2887 PMU_DEBUG(sc, "Adding rsrc 0x%x to min_res_mask\n",
2889 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, (rsrcs|deps));
2891 /* Wait for all resources to become available */
2892 for (int i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) {
2893 state = BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE);
2894 if ((state & rsrcs) == rsrcs)
2900 if ((state & rsrcs) != rsrcs) {
2901 PMU_LOG(sc, "timeout waiting for OTP resource "
2906 PMU_DEBUG(sc, "Removing rsrc 0x%x from min_res_mask\n",
2908 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~(rsrcs|deps));
2915 bhnd_pmu_rcal(struct bhnd_pmu_softc *sc)
2920 bool bluetooth_rcal;
2923 bluetooth_rcal = false;
2925 switch (sc->cid.chip_id) {
2926 case BHND_CHIPID_BCM4325:
2927 case BHND_CHIPID_BCM4329:
2929 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 1);
2931 /* Power Down RCAL Block */
2932 BHND_PMU_AND_4(sc, BHND_PMU_CHIPCTL_DATA, ~0x04);
2934 if (sc->cid.chip_id == BHND_CHIPID_BCM4325) {
2935 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
2936 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_RCAL_VALID))
2937 bluetooth_rcal = true;
2940 /* Power Up RCAL block */
2941 BHND_PMU_AND_4(sc, BHND_PMU_CHIPCTL_DATA, 0x04);
2943 /* Wait for completion */
2944 for (int i = 0; i < (10 * 1000 * 1000); i++) {
2945 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
2952 KASSERT((chipst & 0x08) != 0, ("rcal completion timeout"));
2954 if (bluetooth_rcal) {
2957 /* Drop LSB to convert from 5 bit code to 4 bit code */
2958 rcal_code = (uint8_t) (chipst >> 5) & 0x0f;
2961 PMU_DEBUG("RCal completed, status 0x%x, code 0x%x\n",
2962 R_REG(&cc->chipstatus), rcal_code);
2964 /* Write RCal code into pmu_vreg_ctrl[32:29] */
2965 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 0);
2966 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA);
2967 val &= ~((uint32_t) 0x07 << 29);
2968 val |= (uint32_t) (rcal_code & 0x07) << 29;
2969 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val);
2971 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 1);
2972 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA);
2973 val &= ~(uint32_t) 0x01;
2974 val |= (uint32_t) ((rcal_code >> 3) & 0x01);
2975 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val);
2977 /* Write RCal code into pmu_chip_ctrl[33:30] */
2978 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 0);
2979 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIPCTL_DATA);
2980 val &= ~((uint32_t) 0x03 << 30);
2981 val |= (uint32_t) (rcal_code & 0x03) << 30;
2982 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_DATA, val);
2984 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 1);
2985 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIPCTL_DATA);
2986 val &= ~(uint32_t) 0x03;
2987 val |= (uint32_t) ((rcal_code >> 2) & 0x03);
2988 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_DATA, val);
2990 /* Set override in pmu_chip_ctrl[29] */
2991 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 0);
2992 BHND_PMU_OR_4(sc, BHND_PMU_CHIPCTL_DATA, (0x01 << 29));
2994 /* Power off RCal block */
2995 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIPCTL_ADDR, 1);
2996 BHND_PMU_AND_4(sc, BHND_PMU_CHIPCTL_DATA, ~0x04);
3004 bhnd_pmu_spuravoid(struct bhnd_pmu_softc *sc, uint8_t spuravoid)
3006 /* force the HT off */
3007 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) {
3008 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
3009 ~BHND_PMU_RES4336_HT_AVAIL);
3011 /* wait for the ht to really go away */
3012 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
3015 /* update the pll changes */
3016 bhnd_pmu_spuravoid_pllupdate(sc, spuravoid);
3018 /* enable HT back on */
3019 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) {
3020 BHND_PMU_OR_4(sc, BHND_PMU_MAX_RES_MASK,
3021 BHND_PMU_RES4336_HT_AVAIL);
3026 bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc, uint8_t spuravoid)
3031 uint8_t phypll_offset;
3033 uint8_t bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
3034 uint8_t bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
3036 /* 6362a0 has same clks as 4322[4-6] */
3037 chip_id = sc->cid.chip_id;
3038 if (chip_id == BHND_CHIPID_BCM6362 && sc->cid.chip_rev == 0) {
3039 chip_id = BHND_CHIPID_BCM43224;
3043 case BHND_CHIPID_BCM6362:
3044 KASSERT(sc->cid.chip_rev != 0, ("invalid clock config"));
3046 case BHND_CHIPID_BCM5357:
3047 case BHND_CHIPID_BCM4749:
3048 case BHND_CHIPID_BCM43235:
3049 case BHND_CHIPID_BCM43236:
3050 case BHND_CHIPID_BCM43238:
3051 case BHND_CHIPID_BCM43234:
3052 case BHND_CHIPID_BCM43237:
3053 case BHND_CHIPID_BCM53572:
3054 KASSERT(spuravoid < nitems(bcm5357_bcm43236_p1div),
3055 ("spuravoid %hhu outside p1div table\n", spuravoid));
3057 KASSERT(spuravoid < nitems(bcm5357_bcm43236_ndiv),
3058 ("spuravoid %hhu outside ndiv table\n", spuravoid));
3060 /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset
3061 * PLL0_PLLCTL[02] by 6 */
3063 if (sc->cid.chip_id == BHND_CHIPID_BCM5357)
3066 /* RMW only the P1 divider */
3067 tmp = BHND_PMU_SET_BITS(bcm5357_bcm43236_p1div[spuravoid],
3068 BHND_PMU1_PLL0_PC0_P1DIV);
3069 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0 + phypll_offset,
3070 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK);
3072 /* RMW only the int feedback divider */
3073 tmp = BHND_PMU_SET_BITS(bcm5357_bcm43236_ndiv[spuravoid],
3074 BHND_PMU1_PLL0_PC2_NDIV_INT);
3075 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2 + phypll_offset,
3076 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK);
3078 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3081 case BHND_CHIPID_BCM4331:
3082 if (spuravoid == 2) {
3083 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3085 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3087 } else if (spuravoid == 1) {
3088 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3090 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3093 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3095 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3098 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3101 case BHND_CHIPID_BCM43224:
3102 case BHND_CHIPID_BCM43225:
3103 case BHND_CHIPID_BCM43226:
3104 case BHND_CHIPID_BCM43421:
3105 if (spuravoid == 1) {
3106 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3108 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3110 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3112 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3114 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3116 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3119 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3121 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3123 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3125 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3127 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3129 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3132 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3135 case BHND_CHIPID_BCM43111:
3136 case BHND_CHIPID_BCM43112:
3137 case BHND_CHIPID_BCM43222:
3138 case BHND_CHIPID_BCM43420:
3139 if (spuravoid == 1) {
3140 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3142 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3144 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3146 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3148 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3150 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3153 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3155 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3157 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3159 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3161 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3163 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3167 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3170 case BHND_CHIPID_BCM4716:
3171 case BHND_CHIPID_BCM4748:
3172 case BHND_CHIPID_BCM47162:
3173 if (spuravoid == 1) {
3174 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3176 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3178 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3180 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3182 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3184 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3187 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3189 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3191 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3193 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3195 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3197 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3201 pmuctrl = BHND_PMU_CTRL_NOILP_ON_WAIT |
3202 BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3205 case BHND_CHIPID_BCM4319:
3209 case BHND_CHIPID_BCM4322:
3210 case BHND_CHIPID_BCM43221:
3211 case BHND_CHIPID_BCM43231:
3212 case BHND_CHIPID_BCM4342:
3213 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x11100070, ~0);
3214 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x1014140a, ~0);
3215 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888854, ~0);
3217 if (spuravoid == 1) {
3218 /* spur_avoid ON, enable 41/82/164Mhz clock mode */
3219 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3222 /* enable 40/80/160Mhz clock mode */
3223 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3227 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3230 case BHND_CHIPID_BCM4336:
3231 /* Looks like these are only for default xtal freq 26MHz */
3232 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x02100020, ~0);
3233 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x0C0C0C0C, ~0);
3234 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 0x01240C0C, ~0);
3235 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 0x202C2820, ~0);
3236 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888825, ~0);
3238 if (spuravoid == 1) {
3243 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, tmp, ~0);
3245 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3247 case BHND_CHIPID_BCM43131:
3248 case BHND_CHIPID_BCM43227:
3249 case BHND_CHIPID_BCM43228:
3250 case BHND_CHIPID_BCM43428:
3252 /* PLL Settings for spur avoidance on/off mode, no on2 support
3254 if (spuravoid == 1) {
3255 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3257 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3259 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3261 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3263 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3265 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3268 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3270 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3272 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3274 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3276 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3278 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3281 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3284 PMU_LOG(sc, "%s: unknown spuravoidance settings for chip %#hx, "
3285 "not changing PLL", __func__, sc->cid.chip_id);
3291 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, pmuctrl);
3295 bhnd_pmu_is_otp_powered(struct bhnd_pmu_softc *sc)
3299 /* Determine per-chip OTP resource */
3300 switch (sc->cid.chip_id) {
3301 case BHND_CHIPID_BCM4329:
3302 otp_res = PMURES_BIT(RES4329_OTP_PU);
3304 case BHND_CHIPID_BCM4319:
3305 otp_res = PMURES_BIT(RES4319_OTP_PU);
3307 case BHND_CHIPID_BCM4336:
3308 otp_res = PMURES_BIT(RES4336_OTP_PU);
3310 case BHND_CHIPID_BCM4330:
3311 otp_res = PMURES_BIT(RES4330_OTP_PU);
3314 /* These chips don't use PMU bit to power up/down OTP. OTP always on.
3315 * Use OTP_INIT command to reset/refresh state.
3317 case BHND_CHIPID_BCM43224:
3318 case BHND_CHIPID_BCM43225:
3319 case BHND_CHIPID_BCM43421:
3320 case BHND_CHIPID_BCM43236:
3321 case BHND_CHIPID_BCM43235:
3322 case BHND_CHIPID_BCM43238:
3329 /* Check resource state */
3330 if ((BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE) & otp_res) == 0)
3337 bhnd_pmu_paref_ldo_enable(struct bhnd_pmu_softc *sc, bool enable)
3341 switch (sc->cid.chip_id) {
3342 case BHND_CHIPID_BCM4328:
3343 ldo = PMURES_BIT(RES4328_PA_REF_LDO);
3345 case BHND_CHIPID_BCM5354:
3346 ldo = PMURES_BIT(RES5354_PA_REF_LDO);
3348 case BHND_CHIPID_BCM4312:
3349 ldo = PMURES_BIT(RES4312_PA_REF_LDO);
3356 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, ldo);
3358 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~ldo);
3362 /* initialize PMU switch/regulators */
3364 bhnd_pmu_swreg_init(struct bhnd_pmu_softc *sc)
3368 switch (sc->cid.chip_id) {
3369 case BHND_CHIPID_BCM4325:
3370 if (sc->cid.chip_rev <= 2)
3373 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
3374 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) {
3375 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM,
3377 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST,
3381 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb);
3382 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb);
3384 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0x1);
3385 if (sc->board.board_flags & BHND_BFL_LNLDO2_2P5) {
3386 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO2_SEL,
3391 case BHND_CHIPID_BCM4336:
3392 /* Reduce CLDO PWM output voltage to 1.2V */
3393 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
3394 /* Reduce CLDO BURST output voltage to 1.2V */
3395 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 0xe);
3396 /* Reduce LNLDO1 output voltage to 1.2V */
3397 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0xe);
3398 if (sc->cid.chip_rev == 0)
3399 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x400000, 0x400000);
3402 case BHND_CHIPID_BCM4330:
3403 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
3404 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
3412 bhnd_pmu_radio_enable(struct bhnd_pmu_softc *sc, device_t d11core, bool enable)
3418 if (bhnd_get_device(d11core) != BHND_COREID_D11) {
3419 device_printf(sc->dev,
3420 "bhnd_pmu_radio_enable() called on non-D11 core");
3424 switch (sc->cid.chip_id) {
3425 case BHND_CHIPID_BCM4325:
3426 if (sc->board.board_flags & BHND_BFL_FASTPWR)
3429 if ((sc->board.board_flags & BHND_BFL_BUCKBOOST) == 0)
3432 rsrcs = PMURES_BIT(RES4325_BUCK_BOOST_BURST);
3435 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, rsrcs);
3436 DELAY(100 * 1000); /* 100ms */
3438 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~rsrcs);
3443 case BHND_CHIPID_BCM4319:
3444 error = bhnd_read_config(d11core, BCMA_DMP_OOBSELOUTB74,
3450 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3452 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3455 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3457 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3461 return (bhnd_write_config(d11core, BCMA_DMP_OOBSELOUTB74,
3468 /* Wait for a particular clock level to be on the backplane */
3470 bhnd_pmu_waitforclk_on_backplane(struct bhnd_pmu_softc *sc, uint32_t clk,
3475 for (uint32_t i = 0; i < delay; i += 10) {
3476 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3477 if ((pmu_st & clk) == clk)
3483 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3484 return (pmu_st & clk);
3488 * Measures the ALP clock frequency in KHz. Returns 0 if not possible.
3489 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
3492 #define EXT_ILP_HZ 32768
3495 bhnd_pmu_measure_alpclk(struct bhnd_pmu_softc *sc)
3500 if (BHND_PMU_REV(sc) < 10)
3503 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3504 if (pmu_st & BHND_PMU_ST_EXTLPOAVAIL) {
3505 uint32_t alp_hz, ilp_ctr;
3507 /* Enable frequency measurement */
3508 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 1U <<
3509 BHND_PMU_XTALFREQ_REG_MEASURE_SHIFT);
3511 /* Delay for well over 4 ILP clocks */
3514 /* Read the latched number of ALP ticks per 4 ILP ticks */
3515 ilp_ctr = BHND_PMU_READ_4(sc, BHND_PMU_XTALFREQ);
3516 ilp_ctr = BHND_PMU_GET_BITS(ilp_ctr,
3517 BHND_PMU_XTALFREQ_REG_ILPCTR);
3519 /* Turn off PMU_XTALFREQ_REG_MEASURE to save power */
3520 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 0);
3522 /* Calculate ALP frequency */
3523 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
3525 /* Round to nearest 100KHz and convert to KHz */
3526 alp_khz = (alp_hz + 50000) / 100000 * 100;
3535 bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc)
3537 uint32_t FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000;
3538 uint32_t m1div, m2div, m3div, m4div, m5div, m6div;
3539 uint32_t pllc1, pllc2;
3541 m2div = m3div = m4div = m6div = FVCO / 80;
3544 if (PMU_CST4330_SDIOD_CHIPMODE(sc))
3550 pllc1 |= BHND_PMU_SET_BITS(m1div, BHND_PMU1_PLL0_PC1_M1DIV);
3551 pllc1 |= BHND_PMU_SET_BITS(m2div, BHND_PMU1_PLL0_PC1_M2DIV);
3552 pllc1 |= BHND_PMU_SET_BITS(m3div, BHND_PMU1_PLL0_PC1_M3DIV);
3553 pllc1 |= BHND_PMU_SET_BITS(m4div, BHND_PMU1_PLL0_PC1_M4DIV);
3555 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, pllc1, ~0);
3558 pllc2 |= BHND_PMU_SET_BITS(m5div, BHND_PMU1_PLL0_PC2_M5DIV);
3559 pllc2 |= BHND_PMU_SET_BITS(m6div, BHND_PMU1_PLL0_PC2_M6DIV);
3561 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, pllc2,
3562 BHND_PMU1_PLL0_PC2_M5DIV_MASK | BHND_PMU1_PLL0_PC2_M6DIV_MASK);