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/bhndvar.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 int bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc,
88 bhnd_pmu_spuravoid spuravoid);
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_core_clkctl_wait((_sc)->clkctl, (_val), (_mask))
97 #define PMURES_BIT(_bit) \
98 (1 << (BHND_PMU_ ## _bit))
100 #define PMU_CST4330_SDIOD_CHIPMODE(_sc) \
101 CHIPC_CST4330_CHIPMODE_SDIOD((_sc)->io->rd_chipst((_sc)->io_ctx))
104 * Initialize @p query state.
106 * @param[out] query On success, will be populated with a valid query instance
108 * @param dev The device owning @p query, or NULL.
109 * @param id The bhnd chip identification.
110 * @param io I/O callback functions.
111 * @param ctx I/O callback context.
114 * @retval non-zero if the query state could not be initialized.
117 bhnd_pmu_query_init(struct bhnd_pmu_query *query, device_t dev,
118 struct bhnd_chipid id, const struct bhnd_pmu_io *io, void *ctx)
124 query->caps = BHND_PMU_READ_4(query, BHND_PMU_CAP);
130 * Release any resources held by @p query.
132 * @param query A query instance previously initialized via
133 * bhnd_pmu_query_init().
136 bhnd_pmu_query_fini(struct bhnd_pmu_query *query)
142 * Perform an indirect register read.
144 * @param addr Offset of the address register.
145 * @param data Offset of the data register.
146 * @param reg Indirect register to be read.
149 bhnd_pmu_ind_read(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr,
150 bus_size_t data, uint32_t reg)
152 io->wr4(addr, reg, io_ctx);
153 return (io->rd4(data, io_ctx));
157 * Perform an indirect register write.
159 * @param addr Offset of the address register.
160 * @param data Offset of the data register.
161 * @param reg Indirect register to be written.
162 * @param val Value to be written to @p reg.
163 * @param mask Only the bits defined by @p mask will be updated from @p val.
166 bhnd_pmu_ind_write(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr,
167 bus_size_t data, uint32_t reg, uint32_t val, uint32_t mask)
171 io->wr4(addr, reg, io_ctx);
173 if (mask != UINT32_MAX) {
174 rval = io->rd4(data, io_ctx);
175 rval &= ~mask | (val & mask);
180 io->wr4(data, rval, io_ctx);
183 /* Setup switcher voltage */
185 bhnd_pmu_set_switcher_voltage(struct bhnd_pmu_softc *sc, uint8_t bb_voltage,
188 BHND_PMU_REGCTRL_WRITE(sc, 0x01, (bb_voltage & 0x1f) << 22, ~0);
189 BHND_PMU_REGCTRL_WRITE(sc, 0x00, (rf_voltage & 0x1f) << 14, ~0);
193 bhnd_pmu_set_ldo_voltage(struct bhnd_pmu_softc *sc, uint8_t ldo,
202 switch (sc->cid.chip_id) {
203 case BHND_CHIPID_BCM4328:
204 case BHND_CHIPID_BCM5354:
206 case SET_LDO_VOLTAGE_LDO1:
211 case SET_LDO_VOLTAGE_LDO2:
216 case SET_LDO_VOLTAGE_LDO3:
221 case SET_LDO_VOLTAGE_PAREF:
227 PMU_LOG(sc, "unknown BCM4328/BCM5354 LDO %hhu\n", ldo);
231 case BHND_CHIPID_BCM4312:
233 case SET_LDO_VOLTAGE_PAREF:
239 PMU_LOG(sc, "unknown BCM4312 LDO %hhu\n", ldo);
243 case BHND_CHIPID_BCM4325:
245 case SET_LDO_VOLTAGE_CLDO_PWM:
250 case SET_LDO_VOLTAGE_CLDO_BURST:
255 case SET_LDO_VOLTAGE_CBUCK_PWM:
259 /* Bit 116 & 119 are inverted in CLB for opt 2b */
260 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
261 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
264 case SET_LDO_VOLTAGE_CBUCK_BURST:
268 /* Bit 121 & 124 are inverted in CLB for opt 2b */
269 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
270 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
273 case SET_LDO_VOLTAGE_LNLDO1:
278 case SET_LDO_VOLTAGE_LNLDO2_SEL:
284 PMU_LOG(sc, "unknown BCM4325 LDO %hhu\n", ldo);
288 case BHND_CHIPID_BCM4336:
290 case SET_LDO_VOLTAGE_CLDO_PWM:
295 case SET_LDO_VOLTAGE_CLDO_BURST:
300 case SET_LDO_VOLTAGE_LNLDO1:
306 PMU_LOG(sc, "unknown BCM4336 LDO %hhu\n", ldo);
310 case BHND_CHIPID_BCM4330:
312 case SET_LDO_VOLTAGE_CBUCK_PWM:
318 PMU_LOG(sc, "unknown BCM4330 LDO %hhu\n", ldo);
322 case BHND_CHIPID_BCM4331:
324 case SET_LDO_VOLTAGE_PAREF:
330 PMU_LOG(sc, "unknown BCM4331 LDO %hhu\n", ldo);
335 PMU_LOG(sc, "cannot set LDO voltage on unsupported chip %hu\n",
340 regctrl = (voltage & mask) << shift;
341 BHND_PMU_REGCTRL_WRITE(sc, addr, regctrl, mask << shift);
346 /* d11 slow to fast clock transition time in slow clock cycles */
347 #define D11SCC_SLOW2FAST_TRANSITION 2
350 bhnd_pmu_fast_pwrup_delay(struct bhnd_pmu_softc *sc, u_int *pwrup_delay)
357 switch (sc->cid.chip_id) {
358 case BHND_CHIPID_BCM43224:
359 case BHND_CHIPID_BCM43225:
360 case BHND_CHIPID_BCM43421:
361 case BHND_CHIPID_BCM43235:
362 case BHND_CHIPID_BCM43236:
363 case BHND_CHIPID_BCM43238:
364 case BHND_CHIPID_BCM4331:
365 case BHND_CHIPID_BCM6362:
366 case BHND_CHIPID_BCM4313:
370 case BHND_CHIPID_BCM4325:
371 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4325_HT_AVAIL,
376 ilp = bhnd_pmu_ilp_clock(&sc->query);
377 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
378 ((1000000 + ilp - 1) / ilp);
379 delay = (11 * delay) / 10;
382 case BHND_CHIPID_BCM4329:
383 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4329_HT_AVAIL,
388 ilp = bhnd_pmu_ilp_clock(&sc->query);
389 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
390 ((1000000 + ilp - 1) / ilp);
391 delay = (11 * delay) / 10;
394 case BHND_CHIPID_BCM4319:
398 case BHND_CHIPID_BCM4336:
399 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4336_HT_AVAIL,
404 ilp = bhnd_pmu_ilp_clock(&sc->query);
405 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
406 ((1000000 + ilp - 1) / ilp);
407 delay = (11 * delay) / 10;
410 case BHND_CHIPID_BCM4330:
411 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4330_HT_AVAIL,
416 ilp = bhnd_pmu_ilp_clock(&sc->query);
417 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) *
418 ((1000000 + ilp - 1) / ilp);
419 delay = (11 * delay) / 10;
423 delay = BHND_PMU_MAX_TRANSITION_DLY;
427 *pwrup_delay = delay;
432 bhnd_pmu_force_ilp(struct bhnd_pmu_softc *sc, bool force)
437 pctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
441 pctrl &= ~(BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN);
443 pctrl |= (BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN);
445 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pctrl);
450 /* Setup resource up/down timers */
456 typedef bool (*pmu_res_filter) (struct bhnd_pmu_softc *sc);
458 /* Change resource dependencies masks */
460 uint32_t res_mask; /* resources (chip specific) */
461 int8_t action; /* action */
462 uint32_t depend_mask; /* changes to the dependencies mask */
463 pmu_res_filter filter; /* action is taken when filter is NULL or returns true */
466 /* Resource dependencies mask change action */
467 #define RES_DEPEND_SET 0 /* Override the dependencies mask */
468 #define RES_DEPEND_ADD 1 /* Add to the dependencies mask */
469 #define RES_DEPEND_REMOVE -1 /* Remove from the dependencies mask */
471 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
473 BHND_PMU_RES4328_EXT_SWITCHER_PWM, 0x0101}, {
474 BHND_PMU_RES4328_BB_SWITCHER_PWM, 0x1f01}, {
475 BHND_PMU_RES4328_BB_SWITCHER_BURST, 0x010f}, {
476 BHND_PMU_RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
477 BHND_PMU_RES4328_ILP_REQUEST, 0x0202}, {
478 BHND_PMU_RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
479 BHND_PMU_RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
480 BHND_PMU_RES4328_ROM_SWITCH, 0x0101}, {
481 BHND_PMU_RES4328_PA_REF_LDO, 0x0f01}, {
482 BHND_PMU_RES4328_RADIO_LDO, 0x0f01}, {
483 BHND_PMU_RES4328_AFE_LDO, 0x0f01}, {
484 BHND_PMU_RES4328_PLL_LDO, 0x0f01}, {
485 BHND_PMU_RES4328_BG_FILTBYP, 0x0101}, {
486 BHND_PMU_RES4328_TX_FILTBYP, 0x0101}, {
487 BHND_PMU_RES4328_RX_FILTBYP, 0x0101}, {
488 BHND_PMU_RES4328_XTAL_PU, 0x0101}, {
489 BHND_PMU_RES4328_XTAL_EN, 0xa001}, {
490 BHND_PMU_RES4328_BB_PLL_FILTBYP, 0x0101}, {
491 BHND_PMU_RES4328_RF_PLL_FILTBYP, 0x0101}, {
492 BHND_PMU_RES4328_BB_PLL_PU, 0x0701}
495 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
496 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
498 PMURES_BIT(RES4328_ILP_REQUEST),
500 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
501 PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
504 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
506 BHND_PMU_RES4325_XTAL_PU, 0x1501}
509 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
510 /* Adjust OTP PU resource dependencies - remove BB BURST */
512 PMURES_BIT(RES4325_OTP_PU),
514 PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
515 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
517 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
519 PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
520 PMURES_BIT(RES4325_BUCK_BOOST_PWM), bhnd_pmu_res_depfltr_bb},
521 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
523 PMURES_BIT(RES4325_HT_AVAIL),
525 PMURES_BIT(RES4325_RX_PWRSW_PU) |
526 PMURES_BIT(RES4325_TX_PWRSW_PU) |
527 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
528 PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
529 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
531 PMURES_BIT(RES4325_ILP_REQUEST) |
532 PMURES_BIT(RES4325_ABUCK_BURST) |
533 PMURES_BIT(RES4325_ABUCK_PWM) |
534 PMURES_BIT(RES4325_LNLDO1_PU) |
535 PMURES_BIT(RES4325C1_LNLDO2_PU) |
536 PMURES_BIT(RES4325_XTAL_PU) |
537 PMURES_BIT(RES4325_ALP_AVAIL) |
538 PMURES_BIT(RES4325_RX_PWRSW_PU) |
539 PMURES_BIT(RES4325_TX_PWRSW_PU) |
540 PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
541 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
542 PMURES_BIT(RES4325_AFE_PWRSW_PU) |
543 PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
544 PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
545 PMURES_BIT(RES4325B0_CBUCK_LPOM) |
546 PMURES_BIT(RES4325B0_CBUCK_BURST) |
547 PMURES_BIT(RES4325B0_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb}
550 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
552 BHND_PMU_RES4315_XTAL_PU, 0x2501}
555 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
556 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
558 PMURES_BIT(RES4315_OTP_PU),
560 PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_npaldo},
561 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
563 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
565 PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_paldo},
566 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
568 PMURES_BIT(RES4315_HT_AVAIL),
570 PMURES_BIT(RES4315_RX_PWRSW_PU) |
571 PMURES_BIT(RES4315_TX_PWRSW_PU) |
572 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
573 PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
574 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
576 PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
577 PMURES_BIT(RES4315_LNLDO1_PU) |
578 PMURES_BIT(RES4315_OTP_PU) |
579 PMURES_BIT(RES4315_LNLDO2_PU) |
580 PMURES_BIT(RES4315_XTAL_PU) |
581 PMURES_BIT(RES4315_ALP_AVAIL) |
582 PMURES_BIT(RES4315_RX_PWRSW_PU) |
583 PMURES_BIT(RES4315_TX_PWRSW_PU) |
584 PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
585 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
586 PMURES_BIT(RES4315_AFE_PWRSW_PU) |
587 PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
588 PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
589 PMURES_BIT(RES4315_CBUCK_LPOM) |
590 PMURES_BIT(RES4315_CBUCK_BURST) |
591 PMURES_BIT(RES4315_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb}
594 /* 4329 specific. needs to come back this issue later */
595 static const pmu_res_updown_t bcm4329_res_updown[] = {
597 BHND_PMU_RES4329_XTAL_PU, 0x1501}
600 static const pmu_res_depend_t bcm4329_res_depend[] = {
601 /* Adjust HT Avail resource dependencies */
603 PMURES_BIT(RES4329_HT_AVAIL),
605 PMURES_BIT(RES4329_CBUCK_LPOM) |
606 PMURES_BIT(RES4329_CBUCK_BURST) |
607 PMURES_BIT(RES4329_CBUCK_PWM) |
608 PMURES_BIT(RES4329_CLDO_PU) |
609 PMURES_BIT(RES4329_PALDO_PU) |
610 PMURES_BIT(RES4329_LNLDO1_PU) |
611 PMURES_BIT(RES4329_XTAL_PU) |
612 PMURES_BIT(RES4329_ALP_AVAIL) |
613 PMURES_BIT(RES4329_RX_PWRSW_PU) |
614 PMURES_BIT(RES4329_TX_PWRSW_PU) |
615 PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
616 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
617 PMURES_BIT(RES4329_AFE_PWRSW_PU) |
618 PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
621 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
623 BHND_PMU_RES4319_XTAL_PU, 0x3f01}
626 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
627 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
629 PMURES_BIT(RES4319_OTP_PU),
631 PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_npaldo},
632 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
634 PMURES_BIT(RES4319_HT_AVAIL),
636 PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_paldo},
637 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
639 PMURES_BIT(RES4319_HT_AVAIL),
641 PMURES_BIT(RES4319_RX_PWRSW_PU) |
642 PMURES_BIT(RES4319_TX_PWRSW_PU) |
643 PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
644 PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
645 PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
648 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
650 BHND_PMU_RES4336_HT_AVAIL, 0x0D01}
653 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
654 /* Just a dummy entry for now */
656 PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
659 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
661 BHND_PMU_RES4330_HT_AVAIL, 0x0e02}
664 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
665 /* Just a dummy entry for now */
667 PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
670 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF
673 bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc)
675 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_BUCKBOOST));
678 /* true if the power topology doesn't use the cbuck. Key on chiprev also if
679 * the chip is BCM4325. */
681 bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc)
683 if (sc->cid.chip_id == BHND_CHIPID_BCM4325 && sc->cid.chip_rev <= 1)
686 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_NOCBUCK));
689 /* true if the power topology uses the PALDO */
691 bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc)
693 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO));
696 /* true if the power topology doesn't use the PALDO */
698 bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc)
700 return (!BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO));
703 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
705 bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin, uint32_t *pmax)
707 uint32_t max_mask, min_mask;
708 uint32_t chipst, otpsel;
717 rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC);
719 /* determine min/max rsrc masks */
720 switch (sc->cid.chip_id) {
721 case BHND_CHIPID_BCM4325:
722 /* If used by this device, enable the CBUCK */
723 if (!bhnd_pmu_res_depfltr_ncb(sc))
724 min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM);
726 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
727 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B))
728 min_mask |= PMURES_BIT(RES4325B0_CLDO_PU);
730 /* Is OTP required? */
731 otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_SPROM_OTP_SEL);
732 if (otpsel != CHIPC_CST_OTP_PWRDN)
733 min_mask |= PMURES_BIT(RES4325_OTP_PU);
735 /* Leave buck boost on in burst mode for certain boards */
736 if (sc->board.board_flags & BHND_BFL_BUCKBOOST) {
737 switch (sc->board.board_type) {
738 case BHND_BOARD_BCM94325DEVBU:
739 case BHND_BOARD_BCM94325BGABU:
740 min_mask |= PMURES_BIT(
741 RES4325_BUCK_BOOST_BURST);
746 /* Allow all resources to be turned on upon requests */
747 max_mask = ~(~0 << rsrcs);
750 case BHND_CHIPID_BCM4312:
751 /* default min_mask = 0x80000cbb is wrong */
755 * pmu_res_updown_table_sz = 0;
756 * pmu_res_depend_table_sz = 0;
760 case BHND_CHIPID_BCM4322:
761 case BHND_CHIPID_BCM43221:
762 case BHND_CHIPID_BCM43231:
763 case BHND_CHIPID_BCM4342:
764 if (sc->cid.chip_rev >= 2)
767 /* request ALP(can skip for A1) */
768 min_mask = PMURES_BIT(RES4322_RF_LDO) |
769 PMURES_BIT(RES4322_XTAL_PU) |
770 PMURES_BIT(RES4322_ALP_AVAIL);
772 if (bhnd_get_attach_type(sc->chipc_dev) == BHND_ATTACH_NATIVE) {
774 PMURES_BIT(RES4322_SI_PLL_ON) |
775 PMURES_BIT(RES4322_HT_SI_AVAIL) |
776 PMURES_BIT(RES4322_PHY_PLL_ON) |
777 PMURES_BIT(RES4322_OTP_PU) |
778 PMURES_BIT(RES4322_HT_PHY_AVAIL);
783 case BHND_CHIPID_BCM43222:
784 case BHND_CHIPID_BCM43111:
785 case BHND_CHIPID_BCM43112:
786 case BHND_CHIPID_BCM43224:
787 case BHND_CHIPID_BCM43225:
788 case BHND_CHIPID_BCM43421:
789 case BHND_CHIPID_BCM43226:
790 case BHND_CHIPID_BCM43420:
791 case BHND_CHIPID_BCM43235:
792 case BHND_CHIPID_BCM43236:
793 case BHND_CHIPID_BCM43238:
794 case BHND_CHIPID_BCM43234:
795 case BHND_CHIPID_BCM43237:
796 case BHND_CHIPID_BCM4331:
797 case BHND_CHIPID_BCM43431:
798 case BHND_CHIPID_BCM6362:
799 /* use chip default */
802 case BHND_CHIPID_BCM4328:
804 PMURES_BIT(RES4328_BB_SWITCHER_PWM) |
805 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
806 PMURES_BIT(RES4328_XTAL_EN);
807 max_mask = 0xfffffff;
810 case BHND_CHIPID_BCM5354:
811 /* Allow (but don't require) PLL to turn on */
812 max_mask = 0xfffffff;
815 case BHND_CHIPID_BCM4329:
816 /* Down to save the power. */
817 if (sc->cid.chip_rev >= 0x2) {
819 PMURES_BIT(RES4329_CBUCK_LPOM) |
820 PMURES_BIT(RES4329_LNLDO1_PU) |
821 PMURES_BIT(RES4329_CLDO_PU);
824 PMURES_BIT(RES4329_CBUCK_LPOM) |
825 PMURES_BIT(RES4329_CLDO_PU);
828 /* Is OTP required? */
829 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
830 otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4329_SPROM_OTP_SEL);
831 if (otpsel != CHIPC_CST_OTP_PWRDN)
832 min_mask |= PMURES_BIT(RES4329_OTP_PU);
834 /* Allow (but don't require) PLL to turn on */
838 case BHND_CHIPID_BCM4319:
839 /* We only need a few resources to be kept on all the time */
840 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
841 PMURES_BIT(RES4319_CLDO_PU);
843 /* Allow everything else to be turned on upon requests */
844 max_mask = ~(~0 << rsrcs);
847 case BHND_CHIPID_BCM4336:
848 /* Down to save the power. */
850 PMURES_BIT(RES4336_CBUCK_LPOM) |
851 PMURES_BIT(RES4336_CLDO_PU) |
852 PMURES_BIT(RES4336_LDO3P3_PU) |
853 PMURES_BIT(RES4336_OTP_PU) |
854 PMURES_BIT(RES4336_DIS_INT_RESET_PD);
855 /* Allow (but don't require) PLL to turn on */
856 max_mask = 0x1ffffff;
859 case BHND_CHIPID_BCM4330:
860 /* Down to save the power. */
862 PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
863 | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
864 PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
865 /* Allow (but don't require) PLL to turn on */
866 max_mask = 0xfffffff;
869 case BHND_CHIPID_BCM4313:
870 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
871 PMURES_BIT(RES4313_XTAL_PU_RSRC) |
872 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
873 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
880 /* Apply nvram override to min mask */
881 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMIN, &nval);
882 if (error && error != ENOENT) {
883 PMU_LOG(sc, "NVRAM error reading %s: %d\n",
884 BHND_NVAR_RMIN, error);
887 PMU_DEBUG(sc, "Applying rmin=%#x to min_mask\n", nval);
891 /* Apply nvram override to max mask */
892 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMAX, &nval);
893 if (error && error != ENOENT) {
894 PMU_LOG(sc, "NVRAM error reading %s: %d\n",
895 BHND_NVAR_RMAX, error);
898 PMU_DEBUG(sc, "Applying rmax=%#x to max_mask\n", nval);
911 /* initialize PMU resources */
913 bhnd_pmu_res_init(struct bhnd_pmu_softc *sc)
915 const pmu_res_updown_t *pmu_res_updown_table;
916 const pmu_res_depend_t *pmu_res_depend_table;
917 size_t pmu_res_updown_table_sz;
918 size_t pmu_res_depend_table_sz;
919 uint32_t max_mask, min_mask;
923 pmu_res_depend_table = NULL;
924 pmu_res_depend_table_sz = 0;
926 pmu_res_updown_table = NULL;
927 pmu_res_updown_table_sz = 0;
929 switch (sc->cid.chip_id) {
930 case BHND_CHIPID_BCM4315:
931 /* Optimize resources up/down timers */
932 pmu_res_updown_table = bcm4315a0_res_updown;
933 pmu_res_updown_table_sz = nitems(bcm4315a0_res_updown);
935 /* Optimize resources dependencies */
936 pmu_res_depend_table = bcm4315a0_res_depend;
937 pmu_res_depend_table_sz = nitems(bcm4315a0_res_depend);
940 case BHND_CHIPID_BCM4325:
941 /* Optimize resources up/down timers */
942 pmu_res_updown_table = bcm4325a0_res_updown;
943 pmu_res_updown_table_sz = nitems(bcm4325a0_res_updown);
945 /* Optimize resources dependencies */
946 pmu_res_depend_table = bcm4325a0_res_depend;
947 pmu_res_depend_table_sz = nitems(bcm4325a0_res_depend);
950 case BHND_CHIPID_BCM4328:
951 /* Optimize resources up/down timers */
952 pmu_res_updown_table = bcm4328a0_res_updown;
953 pmu_res_updown_table_sz = nitems(bcm4328a0_res_updown);
955 /* Optimize resources dependencies */
956 pmu_res_depend_table = bcm4328a0_res_depend;
957 pmu_res_depend_table_sz = nitems(bcm4328a0_res_depend);
960 case BHND_CHIPID_BCM4329:
961 /* Optimize resources up/down timers */
962 pmu_res_updown_table = bcm4329_res_updown;
963 pmu_res_updown_table_sz = nitems(bcm4329_res_updown);
965 /* Optimize resources dependencies */
966 pmu_res_depend_table = bcm4329_res_depend;
967 pmu_res_depend_table_sz = nitems(bcm4329_res_depend);
970 case BHND_CHIPID_BCM4319:
971 /* Optimize resources up/down timers */
972 pmu_res_updown_table = bcm4319a0_res_updown;
973 pmu_res_updown_table_sz = nitems(bcm4319a0_res_updown);
975 /* Optimize resources dependencies masks */
976 pmu_res_depend_table = bcm4319a0_res_depend;
977 pmu_res_depend_table_sz = nitems(bcm4319a0_res_depend);
980 case BHND_CHIPID_BCM4336:
981 /* Optimize resources up/down timers */
982 pmu_res_updown_table = bcm4336a0_res_updown;
983 pmu_res_updown_table_sz = nitems(bcm4336a0_res_updown);
985 /* Optimize resources dependencies masks */
986 pmu_res_depend_table = bcm4336a0_res_depend;
987 pmu_res_depend_table_sz = nitems(bcm4336a0_res_depend);
990 case BHND_CHIPID_BCM4330:
991 /* Optimize resources up/down timers */
992 pmu_res_updown_table = bcm4330a0_res_updown;
993 pmu_res_updown_table_sz = nitems(bcm4330a0_res_updown);
995 /* Optimize resources dependencies masks */
996 pmu_res_depend_table = bcm4330a0_res_depend;
997 pmu_res_depend_table_sz = nitems(bcm4330a0_res_depend);
1004 rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC);
1006 /* Program up/down timers */
1007 for (size_t i = 0; i < pmu_res_updown_table_sz; i++) {
1008 const pmu_res_updown_t *updt;
1010 KASSERT(pmu_res_updown_table != NULL, ("no updown tables"));
1012 updt = &pmu_res_updown_table[pmu_res_updown_table_sz - i - 1];
1014 PMU_DEBUG(sc, "Changing rsrc %d res_updn_timer to %#x\n",
1015 updt->resnum, updt->updown);
1017 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, updt->resnum);
1018 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, updt->updown);
1021 /* Apply nvram overrides to up/down timers */
1022 for (uint8_t i = 0; i < rsrcs; i++) {
1026 snprintf(name, sizeof(name), "r%dt", i);
1027 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val);
1029 if (error == ENOENT) {
1032 PMU_LOG(sc, "NVRAM error reading %s: %d\n",
1037 PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_updn_timer\n",
1040 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1041 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, val);
1044 /* Program resource dependencies table */
1045 for (size_t i = 0; i < pmu_res_depend_table_sz; i++) {
1046 const pmu_res_depend_t *rdep;
1047 pmu_res_filter filter;
1048 uint32_t depend_mask;
1050 KASSERT(pmu_res_depend_table != NULL, ("no depend tables"));
1052 rdep = &pmu_res_depend_table[pmu_res_depend_table_sz - i - 1];
1053 filter = rdep->filter;
1055 if (filter != NULL && !filter(sc))
1058 for (uint8_t i = 0; i < rsrcs; i++) {
1059 if ((rdep->res_mask & BHND_PMURES_BIT(i)) == 0)
1062 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1063 depend_mask = BHND_PMU_READ_4(sc,
1064 BHND_PMU_RES_DEP_MASK);
1065 switch (rdep->action) {
1066 case RES_DEPEND_SET:
1067 PMU_DEBUG(sc, "Changing rsrc %hhu res_dep_mask to "
1068 "%#x\n", i, table->depend_mask);
1069 depend_mask = rdep->depend_mask;
1072 case RES_DEPEND_ADD:
1073 PMU_DEBUG(sc, "Adding %#x to rsrc %hhu "
1074 "res_dep_mask\n", table->depend_mask, i);
1076 depend_mask |= rdep->depend_mask;
1079 case RES_DEPEND_REMOVE:
1080 PMU_DEBUG(sc, "Removing %#x from rsrc %hhu "
1081 "res_dep_mask\n", table->depend_mask, i);
1083 depend_mask &= ~(rdep->depend_mask);
1087 panic("unknown RES_DEPEND action: %d\n",
1096 /* Apply nvram overrides to dependencies masks */
1097 for (uint8_t i = 0; i < rsrcs; i++) {
1101 snprintf(name, sizeof(name), "r%dd", i);
1102 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val);
1104 if (error == ENOENT) {
1107 PMU_LOG(sc, "NVRAM error reading %s: %d\n", name,
1112 PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_dep_mask\n", name,
1115 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
1116 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_DEP_MASK, val);
1119 /* Determine min/max rsrc masks */
1120 if ((error = bhnd_pmu_res_masks(sc, &min_mask, &max_mask)))
1123 /* It is required to program max_mask first and then min_mask */
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);
1131 /* Program min resource mask */
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);
1138 /* Add some delay; allow resources to come up and settle. */
1144 /* setup pll and query clock speed */
1145 struct pmu0_xtaltab0 {
1152 /* the following table is based on 880Mhz fvco */
1153 static const pmu0_xtaltab0_t pmu0_xtaltab0[] = {
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}, {
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}, {
1172 #define PMU0_XTAL0_DEFAULT 8
1174 /* setup pll and query clock speed */
1175 struct pmu1_xtaltab0 {
1184 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
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}, {
1205 /* the following table is based on 880Mhz fvco */
1206 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
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}, {
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
1244 /* the following table is based on 1760Mhz fvco */
1245 static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = {
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}, {
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
1282 /* the following table is based on 1440Mhz fvco */
1283 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
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}, {
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
1322 #define XTAL_FREQ_24000MHZ 24000
1323 #define XTAL_FREQ_30000MHZ 30000
1324 #define XTAL_FREQ_37400MHZ 37400
1325 #define XTAL_FREQ_48000MHZ 48000
1327 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
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}, {
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
1366 /* select xtal table for each chip */
1367 static const pmu1_xtaltab0_t *
1368 bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc)
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);
1385 return (pmu1_xtaltab0_1440);
1387 PMU_DEBUG(sc, "bhnd_pmu1_xtaltab0: Unknown chipid %#hx\n",
1393 /* select default xtal frequency for each chip */
1394 static const pmu1_xtaltab0_t *
1395 bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc)
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]);
1418 return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]);
1420 PMU_DEBUG(sc, "bhnd_pmu1_xtaldef0: Unknown chipid %#hx\n",
1426 /* select default pll fvco for each chip */
1428 bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc)
1430 switch (sc->cid.chip_id) {
1431 case BHND_CHIPID_BCM4329:
1433 case BHND_CHIPID_BCM4319:
1435 case BHND_CHIPID_BCM4336:
1437 case BHND_CHIPID_BCM4330:
1438 if (PMU_CST4330_SDIOD_CHIPMODE(sc))
1443 PMU_DEBUG(sc, "bhnd_pmu1_pllfvco0: Unknown chipid %#hx\n",
1449 /* query alp/xtal clock frequency */
1451 bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc)
1453 const pmu1_xtaltab0_t *xt;
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);
1460 for (xt = bhnd_pmu1_xtaltab0(sc); xt != NULL && xt->fref != 0; xt++) {
1465 /* Could not find it so assign a default value */
1466 if (xt == NULL || xt->fref == 0)
1467 xt = bhnd_pmu1_xtaldef0(sc);
1469 if (xt == NULL || xt->fref == 0) {
1470 PMU_LOG(sc, "no matching ALP/XTAL frequency found\n");
1474 return (xt->fref * 1000);
1477 /* Set up PLL registers in the PMU as per the crystal speed. */
1479 bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
1481 const pmu0_xtaltab0_t *xt;
1482 uint32_t pll_data, pll_mask;
1487 /* Use h/w default PLL config */
1489 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL "
1494 /* Find the frequency in the table */
1495 for (xt = pmu0_xtaltab0; xt->freq; xt ++) {
1496 if (xt->freq == xtal)
1501 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
1503 PMU_DEBUG(sc, "XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000,
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);
1511 if (sc->cid.chip_id == BHND_CHIPID_BCM4328) {
1512 bhnd_pmu0_sbclk4328(sc,
1513 BHND_PMU0_PLL0_PC0_DIV_ARM_88MHZ);
1516 #endif /* BCMUSBDEV */
1518 PMU_DEBUG(sc, "PLL already programmed for %d.%d MHz\n",
1519 xt->freq / 1000, xt->freq % 1000);
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);
1530 PMU_DEBUG(sc, "Programming PLL for %d.%d MHz\n",
1531 xt->freq / 1000, xt->freq % 1000);
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);
1539 case BHND_CHIPID_BCM5354:
1540 pll_res = PMURES_BIT(RES5354_BB_PLL_PU);
1543 panic("unsupported chipid %#hx\n", sc->cid.chip_id);
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);
1548 /* Wait for HT clock to shutdown. */
1549 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1551 PMU_DEBUG(sc, "Done masking\n");
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);
1558 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0, 0,
1559 BHND_PMU0_PLL0_PC0_PDIV_MASK);
1562 /* Write WILD in pllcontrol[1] */
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);
1567 if (xt->wbfrac == 0) {
1568 pll_data |= BHND_PMU0_PLL0_PC1_STOP_MOD;
1570 pll_data &= ~BHND_PMU0_PLL0_PC1_STOP_MOD;
1574 BHND_PMU0_PLL0_PC1_WILD_INT_MASK |
1575 BHND_PMU0_PLL0_PC1_WILD_FRAC_MASK;
1577 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL1, pll_data, pll_mask);
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);
1584 PMU_DEBUG(sc, "Done pll\n");
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);
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);
1594 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmu_ctrl);
1597 /* query alp/xtal clock frequency */
1599 bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc)
1601 const pmu0_xtaltab0_t *xt;
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++)
1611 /* PLL must be configured before */
1612 if (xt == NULL || xt->freq == 0)
1613 panic("unsupported frequency: %u", xf);
1615 return (xt->freq * 1000);
1618 /* query CPU clock frequency */
1620 bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc)
1622 uint32_t tmp, divarm;
1625 uint32_t pdiv, wbint, wbfrac, fvco;
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);
1636 /* Calculate fvco based on xtal freq, pdiv, and wild */
1637 pdiv = tmp & BHND_PMU0_PLL0_PC0_PDIV_MASK;
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);
1643 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL2);
1644 wbint += BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC2_WILD_INT);
1646 freq = bhnd_pmu0_alpclk0(sih, osh, cc) / 1000;
1648 fvco = (freq * wbint) << 8;
1649 fvco += (freq * (wbfrac >> 10)) >> 2;
1650 fvco += (freq * (wbfrac & 0x3ff)) >> 10;
1656 PMU_DEBUG(sc, "bhnd_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
1657 wbint, wbfrac, fvco);
1662 /* Return ARM/SB clock */
1663 return FVCO / (divarm + BHND_PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
1668 /* Set up PLL registers in the PMU as per the crystal speed. */
1670 bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
1672 const pmu1_xtaltab0_t *xt;
1673 uint32_t buf_strength;
1674 uint32_t plladdr, plldata, pllmask;
1679 FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000;
1683 /* Use h/w default PLL config */
1685 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL "
1690 /* Find the frequency in the table */
1691 for (xt = bhnd_pmu1_xtaltab0(&sc->query); xt != NULL && xt->fref != 0;
1694 if (xt->fref == xtal)
1698 /* Check current PLL state, bail out if it has been programmed or
1699 * we don't know how to program it.
1701 if (xt == NULL || xt->fref == 0) {
1702 PMU_LOG(sc, "Unsupported XTAL frequency %d.%dMHz, skipping PLL "
1703 "configuration\n", xtal / 1000, xtal % 1000);
1707 /* For 4319 bootloader already programs the PLL but bootloader does not
1708 * program the PLL4 and PLL5. So Skip this check for 4319. */
1709 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1710 if (BHND_PMU_GET_BITS(pmuctrl, BHND_PMU_CTRL_XTALFREQ) == xt->xf &&
1711 sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
1712 sc->cid.chip_id != BHND_CHIPID_BCM4330)
1714 PMU_DEBUG(sc, "PLL already programmed for %d.%dMHz\n",
1715 xt->fref / 1000, xt->fref % 1000);
1719 PMU_DEBUG(sc, "XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf);
1720 PMU_DEBUG(sc, "Programming PLL for %d.%dMHz\n", xt->fref / 1000,
1723 switch (sc->cid.chip_id) {
1724 case BHND_CHIPID_BCM4325:
1725 /* Change the BBPLL drive strength to 2 for all channels */
1726 buf_strength = 0x222222;
1728 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1729 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
1730 PMURES_BIT(RES4325_HT_AVAIL)));
1731 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1732 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
1733 PMURES_BIT(RES4325_HT_AVAIL)));
1735 /* Wait for HT clock to shutdown. */
1736 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1739 case BHND_CHIPID_BCM4329:
1740 /* Change the BBPLL drive strength to 8 for all channels */
1741 buf_strength = 0x888888;
1743 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1744 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1745 PMURES_BIT(RES4329_HT_AVAIL)));
1746 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1747 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1748 PMURES_BIT(RES4329_HT_AVAIL)));
1750 /* Wait for HT clock to shutdown. */
1751 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1753 /* Initialize PLL4 */
1754 plladdr = BHND_PMU1_PLL0_PLLCTL4;
1755 if (xt->fref == 38400)
1756 plldata = 0x200024C0;
1757 else if (xt->fref == 37400)
1758 plldata = 0x20004500;
1759 else if (xt->fref == 26000)
1760 plldata = 0x200024C0;
1762 plldata = 0x200005C0; /* Chip Dflt Settings */
1764 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0);
1766 /* Initialize PLL5 */
1767 plladdr = BHND_PMU1_PLL0_PLLCTL5;
1769 plldata = BHND_PMU_PLL_READ(sc, plladdr);
1770 plldata &= BHND_PMU1_PLL0_PC5_CLK_DRV_MASK;
1772 if (xt->fref == 38400 ||
1773 xt->fref == 37400 ||
1774 xt->fref == 26000) {
1777 plldata |= 0x25; /* Chip Dflt Settings */
1780 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0);
1783 case BHND_CHIPID_BCM4319:
1784 /* Change the BBPLL drive strength to 2 for all channels */
1785 buf_strength = 0x222222;
1787 /* Make sure the PLL is off */
1788 /* WAR65104: Disable the HT_AVAIL resource first and then
1789 * after a delay (more than downtime for HT_AVAIL) remove the
1790 * BBPLL resource; backplane clock moves to ALP from HT.
1792 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1793 ~(PMURES_BIT(RES4319_HT_AVAIL)));
1794 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1795 ~(PMURES_BIT(RES4319_HT_AVAIL)));
1798 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1799 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1800 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1801 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1805 /* Wait for HT clock to shutdown. */
1806 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1808 plldata = 0x200005c0;
1809 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, plldata, ~0);
1812 case BHND_CHIPID_BCM4336:
1813 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1814 ~(PMURES_BIT(RES4336_HT_AVAIL) |
1815 PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1816 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1817 ~(PMURES_BIT(RES4336_HT_AVAIL) |
1818 PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1821 /* Wait for HT clock to shutdown. */
1822 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1826 case BHND_CHIPID_BCM4330:
1827 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK,
1828 ~(PMURES_BIT(RES4330_HT_AVAIL) |
1829 PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1830 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
1831 ~(PMURES_BIT(RES4330_HT_AVAIL) |
1832 PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1835 /* Wait for HT clock to shutdown. */
1836 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
1841 panic("unsupported chipid %#hx\n", sc->cid.chip_id);
1844 PMU_DEBUG(sc, "Done masking\n");
1846 /* Write p1div and p2div to pllcontrol[0] */
1848 BHND_PMU_SET_BITS(xt->p1div, BHND_PMU1_PLL0_PC0_P1DIV) |
1849 BHND_PMU_SET_BITS(xt->p2div, BHND_PMU1_PLL0_PC0_P2DIV);
1850 pllmask = BHND_PMU1_PLL0_PC0_P1DIV_MASK|BHND_PMU1_PLL0_PC0_P2DIV_MASK;
1852 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1853 plldata &= ~(BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK);
1854 pllmask |= BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK;
1855 if (!xt->ndiv_frac) {
1856 plldata |= BHND_PMU_SET_BITS(1,
1857 BHND_PMU1_PLL0_PC0_BYPASS_SDMOD);
1861 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, plldata, pllmask);
1864 if (sc->cid.chip_id == BHND_CHIPID_BCM4330)
1865 bhnd_pmu_set_4330_plldivs(sc);
1867 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) {
1868 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
1869 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_VAL,
1870 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
1873 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1874 if (sc->cid.chip_id == BHND_CHIPID_BCM4336 ||
1875 sc->cid.chip_id == BHND_CHIPID_BCM4330)
1877 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB;
1878 } else if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1879 if (!(xt->ndiv_frac))
1880 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_INT;
1882 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB;
1884 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MASH;
1888 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
1889 BHND_PMU_SET_BITS(xt->ndiv_int, BHND_PMU1_PLL0_PC2_NDIV_INT) |
1890 BHND_PMU_SET_BITS(ndiv_mode, BHND_PMU1_PLL0_PC2_NDIV_MODE),
1891 BHND_PMU1_PLL0_PC2_NDIV_INT_MASK |
1892 BHND_PMU1_PLL0_PC2_NDIV_MODE_MASK);
1894 /* Write ndiv_frac to pllcontrol[3] */
1895 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
1896 BHND_PMU_SET_BITS(xt->ndiv_frac, BHND_PMU1_PLL0_PC3_NDIV_FRAC),
1897 BHND_PMU1_PLL0_PC3_NDIV_FRAC_MASK);
1899 /* Writing to pllcontrol[4] */
1900 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1904 plldata = 0x200005c0;
1906 plldata = 0x202C2820;
1913 plldata &= ~(BHND_PMU1_PLL0_PC4_KVCO_XS_MASK);
1914 plldata |= BHND_PMU_SET_BITS(xs, BHND_PMU1_PLL0_PC4_KVCO_XS);
1915 BHND_PMU_WRITE_4(sc, BHND_PMU1_PLL0_PLLCTL4, plldata);
1918 /* Write clock driving strength to pllcontrol[5] */
1920 PMU_DEBUG(sc, "Adjusting PLL buffer drive strength: %x\n",
1923 plldata = BHND_PMU_SET_BITS(buf_strength,
1924 BHND_PMU1_PLL0_PC5_CLK_DRV);
1925 pllmask = BHND_PMU1_PLL0_PC5_CLK_DRV_MASK;
1927 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
1929 BHND_PMU1_PLL0_PC5_VCO_RNG_MASK |
1930 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK;
1932 if (!xt->ndiv_frac) {
1933 plldata |= BHND_PMU_SET_BITS(0x25,
1934 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32);
1936 plldata |= BHND_PMU_SET_BITS(0x15,
1937 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32);
1941 plldata |= BHND_PMU_SET_BITS(0x1,
1942 BHND_PMU1_PLL0_PC5_VCO_RNG);
1946 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, plldata,
1950 PMU_DEBUG(sc, "Done pll\n");
1952 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1955 if (sc->cid.chip_id == BHND_CHIPID_BCM4319 &&
1956 xt->fref != XTAL_FREQ_30000MHZ)
1961 case XTAL_FREQ_24000MHZ:
1962 pll_sel = BHND_PMU_CCTRL4319USB_24MHZ_PLL_SEL;
1964 case XTAL_FREQ_48000MHZ:
1965 pll_sel = BHND_PMU_CCTRL4319USB_48MHZ_PLL_SEL;
1968 panic("unsupported 4319USB XTAL frequency: %hu\n",
1972 BHND_PMU_CCTRL_WRITE(sc, BHND_PMU1_PLL0_CHIPCTL2,
1973 BHND_PMU_SET_BITS(pll_sel, BHND_PMU_CCTRL4319USB_XTAL_SEL),
1974 BHND_PMU_CCTRL4319USB_XTAL_SEL_MASK);
1977 /* Flush deferred pll control registers writes */
1978 if (BHND_PMU_REV(sc) >= 2)
1979 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_PLL_PLLCTL_UPD);
1981 /* Write XtalFreq. Set the divisor also. */
1982 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
1983 pmuctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK | BHND_PMU_CTRL_XTALFREQ_MASK);
1984 pmuctrl |= BHND_PMU_SET_BITS(((xt->fref + 127) / 128) - 1,
1985 BHND_PMU_CTRL_ILP_DIV);
1986 pmuctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ);
1988 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) {
1989 /* clear the htstretch before clearing HTReqEn */
1990 BHND_PMU_AND_4(sc, BHND_PMU_CLKSTRETCH, ~BHND_PMU_CLKSTRETCH);
1991 pmuctrl &= ~BHND_PMU_CTRL_HT_REQ_EN;
1994 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmuctrl);
1997 /* query the CPU clock frequency */
1999 bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc)
2001 uint32_t tmp, m1div;
2003 uint32_t ndiv_int, ndiv_frac, p2div, p1div, fvco;
2006 uint32_t FVCO = bhnd_pmu1_pllfvco0(sc);
2008 /* Read m1div from pllcontrol[1] */
2009 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL1);
2010 m1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC1_M1DIV);
2013 /* Read p2div/p1div from pllcontrol[0] */
2014 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL0);
2015 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P2DIV);
2016 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P1DIV);
2018 /* Calculate fvco based on xtal freq and ndiv and pdiv */
2019 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL2);
2020 ndiv_int = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC2_NDIV_INT);
2022 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL3);
2023 ndiv_frac = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC3_NDIV_FRAC);
2025 fref = bhnd_pmu1_alpclk0(sc) / 1000;
2027 fvco = (fref * ndiv_int) << 8;
2028 fvco += (fref * (ndiv_frac >> 12)) >> 4;
2029 fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
2036 PMU_DEBUG(sc, "bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u "
2037 "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco);
2042 /* Return ARM/SB clock */
2043 return (FVCO / m1div * 1000);
2046 /* initialize PLL */
2048 bhnd_pmu_pll_init(struct bhnd_pmu_softc *sc, u_int xtalfreq)
2050 uint32_t max_mask, min_mask;
2051 uint32_t res_ht, res_pll;
2053 switch (sc->cid.chip_id) {
2054 case BHND_CHIPID_BCM4312:
2055 /* assume default works */
2057 case BHND_CHIPID_BCM4322:
2058 case BHND_CHIPID_BCM43221:
2059 case BHND_CHIPID_BCM43231:
2060 case BHND_CHIPID_BCM4342:
2061 if (sc->cid.chip_rev != 0)
2064 min_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK);
2065 max_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK);
2066 res_ht = PMURES_BIT(RES4322_HT_SI_AVAIL);
2067 res_pll = PMURES_BIT(RES4322_SI_PLL_ON);
2069 /* Have to remove HT Avail request before powering off PLL */
2070 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_ht);
2071 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_ht);
2072 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2074 /* Make sure the PLL is off */
2075 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_pll);
2076 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_pll);
2077 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2081 BHND_PMU_PLL_WRITE(sc, BHND_PMU2_SI_PLL_PLLCTL, 0x380005c0, ~0);
2084 BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask);
2086 BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask);
2090 case BHND_CHIPID_BCM4325:
2091 bhnd_pmu1_pllinit0(sc, xtalfreq);
2093 case BHND_CHIPID_BCM4328:
2094 bhnd_pmu0_pllinit0(sc, xtalfreq);
2096 case BHND_CHIPID_BCM5354:
2099 bhnd_pmu0_pllinit0(sc, xtalfreq);
2101 case BHND_CHIPID_BCM4329:
2104 bhnd_pmu1_pllinit0(sc, xtalfreq);
2107 case BHND_CHIPID_BCM4313:
2108 case BHND_CHIPID_BCM43222:
2109 case BHND_CHIPID_BCM43111:
2110 case BHND_CHIPID_BCM43112:
2111 case BHND_CHIPID_BCM43224:
2112 case BHND_CHIPID_BCM43225:
2113 case BHND_CHIPID_BCM43420:
2114 case BHND_CHIPID_BCM43421:
2115 case BHND_CHIPID_BCM43226:
2116 case BHND_CHIPID_BCM43235:
2117 case BHND_CHIPID_BCM43236:
2118 case BHND_CHIPID_BCM43238:
2119 case BHND_CHIPID_BCM43234:
2120 case BHND_CHIPID_BCM43237:
2121 case BHND_CHIPID_BCM4331:
2122 case BHND_CHIPID_BCM43431:
2123 case BHND_CHIPID_BCM43131:
2124 case BHND_CHIPID_BCM43227:
2125 case BHND_CHIPID_BCM43228:
2126 case BHND_CHIPID_BCM43428:
2127 case BHND_CHIPID_BCM6362:
2128 /* assume default works */
2131 case BHND_CHIPID_BCM4315:
2132 case BHND_CHIPID_BCM4319:
2133 case BHND_CHIPID_BCM4336:
2134 case BHND_CHIPID_BCM4330:
2135 bhnd_pmu1_pllinit0(sc, xtalfreq);
2138 PMU_DEBUG("No PLL init done for chip %#hx rev %d pmurev %d\n",
2139 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc));
2145 * Return the ALP/XTAL clock frequency, in Hz.
2147 * @param sc PMU query instance.
2150 bhnd_pmu_alp_clock(struct bhnd_pmu_query *sc)
2154 clock = BHND_PMU_ALP_CLOCK;
2155 switch (sc->cid.chip_id) {
2156 case BHND_CHIPID_BCM4328:
2157 case BHND_CHIPID_BCM5354:
2158 clock = bhnd_pmu0_alpclk0(sc);
2160 case BHND_CHIPID_BCM4315:
2161 case BHND_CHIPID_BCM4319:
2162 case BHND_CHIPID_BCM4325:
2163 case BHND_CHIPID_BCM4329:
2164 case BHND_CHIPID_BCM4330:
2165 case BHND_CHIPID_BCM4336:
2166 clock = bhnd_pmu1_alpclk0(sc);
2168 case BHND_CHIPID_BCM4312:
2169 case BHND_CHIPID_BCM4322:
2170 case BHND_CHIPID_BCM43221:
2171 case BHND_CHIPID_BCM43231:
2172 case BHND_CHIPID_BCM43222:
2173 case BHND_CHIPID_BCM43111:
2174 case BHND_CHIPID_BCM43112:
2175 case BHND_CHIPID_BCM43224:
2176 case BHND_CHIPID_BCM43225:
2177 case BHND_CHIPID_BCM43420:
2178 case BHND_CHIPID_BCM43421:
2179 case BHND_CHIPID_BCM43226:
2180 case BHND_CHIPID_BCM43235:
2181 case BHND_CHIPID_BCM43236:
2182 case BHND_CHIPID_BCM43238:
2183 case BHND_CHIPID_BCM43234:
2184 case BHND_CHIPID_BCM43237:
2185 case BHND_CHIPID_BCM4331:
2186 case BHND_CHIPID_BCM43431:
2187 case BHND_CHIPID_BCM43131:
2188 case BHND_CHIPID_BCM43227:
2189 case BHND_CHIPID_BCM43228:
2190 case BHND_CHIPID_BCM43428:
2191 case BHND_CHIPID_BCM6362:
2192 case BHND_CHIPID_BCM4342:
2193 case BHND_CHIPID_BCM4716:
2194 case BHND_CHIPID_BCM4748:
2195 case BHND_CHIPID_BCM47162:
2196 case BHND_CHIPID_BCM4313:
2197 case BHND_CHIPID_BCM5357:
2198 case BHND_CHIPID_BCM4749:
2199 case BHND_CHIPID_BCM53572:
2201 clock = 20000 * 1000;
2203 case BHND_CHIPID_BCM5356:
2204 case BHND_CHIPID_BCM4706:
2206 clock = 25000 * 1000;
2209 PMU_DEBUG("No ALP clock specified "
2210 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2211 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
2212 sih->pmurev, clock);
2219 /* Find the output of the "m" pll divider given pll controls that start with
2220 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
2223 bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
2231 if ((pll0 & 3) || (pll0 > BHND_PMU4716_MAINPLL_PLL0)) {
2232 PMU_LOG(sc, "%s: Bad pll0: %d", __func__, pll0);
2236 /* Strictly there is an m5 divider, but I'm not sure we use it */
2237 if ((m == 0) || (m > 4)) {
2238 PMU_LOG(sc, "%s: Bad m divider: %d", __func__, m);
2242 if (sc->cid.chip_id == BHND_CHIPID_BCM5357 ||
2243 sc->cid.chip_id == BHND_CHIPID_BCM4749)
2245 /* Detect failure in clock setting */
2246 tmp = sc->io->rd_chipst(sc->io_ctx);
2247 if ((tmp & 0x40000) != 0)
2248 return (133 * 1000000);
2252 /* Fetch p1 and p2 */
2253 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2254 pll0 + BHND_PMU5_PLL_P1P2_OFF);
2255 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2257 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2258 p1 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P1);
2259 p2 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P2);
2262 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2263 pll0 + BHND_PMU5_PLL_M14_OFF);
2264 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2266 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2267 div = (tmp >> ((m - 1) * BHND_PMU5_PLL_MDIV_WIDTH));
2268 div &= BHND_PMU5_PLL_MDIV_MASK;
2271 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2272 pll0 + BHND_PMU5_PLL_NM5_OFF);
2273 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2275 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2276 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_NDIV);
2278 /* Do calculation in Mhz */
2279 fc = bhnd_pmu_alp_clock(sc) / 1000000;
2280 fc = (p1 * ndiv * fc) / p2;
2282 PMU_DEBUG(sc, "%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, "
2283 "clock=%d\n", __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div);
2285 /* Return clock in Hertz */
2286 return ((fc / div) * 1000000);
2290 bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m)
2292 uint32_t chipst, clock;
2293 uint32_t ndiv, p1div, p2div, tmp;
2295 /* Get N, P1 and P2 dividers to determine CPU clock */
2296 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR,
2297 pll0 + BHND_PMU6_4706_PROCPLL_OFF);
2298 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR);
2300 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA);
2301 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_NDIV_INT);
2302 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P1DIV);
2303 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P2DIV);
2305 /* Fixed 25MHz reference clock */
2306 clock = 25 * 1000 * 1000;
2308 /* The low-cost bonding uses an input divider of 4; otherwise, 2 */
2309 chipst = sc->io->rd_chipst(sc->io_ctx);
2310 if (chipst & CHIPC_CST4706_LOWCOST_PKG)
2315 clock *= ndiv * p2div / p1div;
2318 case BHND_PMU6_MAINPLL_CPU:
2320 case BHND_PMU6_MAINPLL_MEM:
2322 case BHND_PMU6_MAINPLL_SI:
2325 PMU_LOG(sc, "bad m divider: %d", m);
2331 * Return the backplane clock frequency, in Hz.
2333 * On designs that feed the same clock to both backplane
2334 * and CPU, this returns the CPU clock speed.
2336 * @param sc PMU query instance.
2339 bhnd_pmu_si_clock(struct bhnd_pmu_query *sc)
2344 clock = BHND_PMU_HT_CLOCK;
2346 switch (sc->cid.chip_id) {
2347 case BHND_CHIPID_BCM4322:
2348 case BHND_CHIPID_BCM43221:
2349 case BHND_CHIPID_BCM43231:
2350 case BHND_CHIPID_BCM43222:
2351 case BHND_CHIPID_BCM43111:
2352 case BHND_CHIPID_BCM43112:
2353 case BHND_CHIPID_BCM43224:
2354 case BHND_CHIPID_BCM43420:
2355 case BHND_CHIPID_BCM43225:
2356 case BHND_CHIPID_BCM43421:
2357 case BHND_CHIPID_BCM43226:
2358 case BHND_CHIPID_BCM4331:
2359 case BHND_CHIPID_BCM43431:
2360 case BHND_CHIPID_BCM6362:
2361 case BHND_CHIPID_BCM4342:
2362 /* 96MHz backplane clock */
2363 clock = 96000 * 1000;
2366 case BHND_CHIPID_BCM4716:
2367 case BHND_CHIPID_BCM4748:
2368 case BHND_CHIPID_BCM47162:
2369 clock = bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2370 BHND_PMU5_MAINPLL_SI);
2373 case BHND_CHIPID_BCM4325:
2374 clock = bhnd_pmu1_cpuclk0(sc);
2377 case BHND_CHIPID_BCM4328:
2378 clock = bhnd_pmu0_cpuclk0(sc);
2381 case BHND_CHIPID_BCM4329:
2382 if (sc->cid.chip_rev == 0)
2383 clock = 38400 * 1000;
2385 clock = bhnd_pmu1_cpuclk0(sc);
2388 case BHND_CHIPID_BCM4315:
2389 case BHND_CHIPID_BCM4319:
2390 case BHND_CHIPID_BCM4336:
2391 case BHND_CHIPID_BCM4330:
2392 clock = bhnd_pmu1_cpuclk0(sc);
2395 case BHND_CHIPID_BCM4313:
2396 /* 80MHz backplane clock */
2397 clock = 80000 * 1000;
2400 case BHND_CHIPID_BCM43234:
2401 case BHND_CHIPID_BCM43235:
2402 case BHND_CHIPID_BCM43236:
2403 case BHND_CHIPID_BCM43238:
2404 chipst = sc->io->rd_chipst(sc->io_ctx);
2405 if (chipst & CHIPC_CST43236_BP_CLK)
2406 clock = 120000 * 1000;
2408 clock = 96000 * 1000;
2410 case BHND_CHIPID_BCM43237:
2411 chipst = sc->io->rd_chipst(sc->io_ctx);
2412 if (chipst & CHIPC_CST43237_BP_CLK)
2413 clock = 96000 * 1000;
2415 clock = 80000 * 1000;
2417 case BHND_CHIPID_BCM5356:
2418 clock = bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2419 BHND_PMU5_MAINPLL_SI);
2421 case BHND_CHIPID_BCM5357:
2422 case BHND_CHIPID_BCM4749:
2423 clock = bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2424 BHND_PMU5_MAINPLL_SI);
2426 case BHND_CHIPID_BCM4706:
2427 clock = bhnd_pmu6_4706_clock(sc, BHND_PMU4706_MAINPLL_PLL0,
2428 BHND_PMU6_MAINPLL_SI);
2430 case BHND_CHIPID_BCM53572:
2434 PMU_LOG(sc, "No backplane clock specified for chip %#hx rev "
2435 "%hhd pmurev %hhd, using default %dHz\n",
2436 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc), clock);
2444 * Return the CPU clock frequency, in Hz.
2446 * @param sc PMU query instance.
2449 bhnd_pmu_cpu_clock(struct bhnd_pmu_query *sc)
2451 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
2452 if (sc->cid.chip_id == BHND_CHIPID_BCM5354)
2453 return (240 * 1000 * 1000); /* 240MHz */
2455 if (sc->cid.chip_id == BHND_CHIPID_BCM53572)
2458 if (BHND_PMU_REV(sc) >= 5 &&
2459 sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
2460 sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
2461 sc->cid.chip_id != BHND_CHIPID_BCM43234 &&
2462 sc->cid.chip_id != BHND_CHIPID_BCM43235 &&
2463 sc->cid.chip_id != BHND_CHIPID_BCM43236 &&
2464 sc->cid.chip_id != BHND_CHIPID_BCM43237 &&
2465 sc->cid.chip_id != BHND_CHIPID_BCM43238 &&
2466 sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
2467 sc->cid.chip_id != BHND_CHIPID_BCM4330)
2469 switch (sc->cid.chip_id) {
2470 case BHND_CHIPID_BCM5356:
2471 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2472 BHND_PMU5_MAINPLL_CPU));
2474 case BHND_CHIPID_BCM5357:
2475 case BHND_CHIPID_BCM4749:
2476 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2477 BHND_PMU5_MAINPLL_CPU));
2479 case BHND_CHIPID_BCM4706:
2480 return (bhnd_pmu6_4706_clock(sc,
2481 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_CPU));
2484 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2485 BHND_PMU5_MAINPLL_CPU));
2488 return (bhnd_pmu_si_clock(sc));
2493 * Return the memory clock frequency, in Hz.
2495 * @param sc PMU query instance.
2498 bhnd_pmu_mem_clock(struct bhnd_pmu_query *sc)
2500 if (BHND_PMU_REV(sc) >= 5 &&
2501 sc->cid.chip_id != BHND_CHIPID_BCM4329 &&
2502 sc->cid.chip_id != BHND_CHIPID_BCM4319 &&
2503 sc->cid.chip_id != BHND_CHIPID_BCM43234 &&
2504 sc->cid.chip_id != BHND_CHIPID_BCM43235 &&
2505 sc->cid.chip_id != BHND_CHIPID_BCM43236 &&
2506 sc->cid.chip_id != BHND_CHIPID_BCM43237 &&
2507 sc->cid.chip_id != BHND_CHIPID_BCM43238 &&
2508 sc->cid.chip_id != BHND_CHIPID_BCM4336 &&
2509 sc->cid.chip_id != BHND_CHIPID_BCM4330)
2511 switch (sc->cid.chip_id) {
2512 case BHND_CHIPID_BCM5356:
2513 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0,
2514 BHND_PMU5_MAINPLL_MEM));
2516 case BHND_CHIPID_BCM5357:
2517 case BHND_CHIPID_BCM4749:
2518 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0,
2519 BHND_PMU5_MAINPLL_MEM));
2521 case BHND_CHIPID_BCM4706:
2522 return (bhnd_pmu6_4706_clock(sc,
2523 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_MEM));
2526 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0,
2527 BHND_PMU5_MAINPLL_MEM));
2531 return (bhnd_pmu_si_clock(sc));
2535 /* Measure ILP clock frequency */
2536 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */
2539 * Measure and return the ILP clock frequency, in Hz.
2541 * @param sc PMU query instance.
2544 bhnd_pmu_ilp_clock(struct bhnd_pmu_query *sc)
2546 uint32_t start, end, delta;
2548 if (sc->ilp_cps == 0) {
2549 start = BHND_PMU_READ_4(sc, BHND_PMU_TIMER);
2550 DELAY(ILP_CALC_DUR);
2551 end = BHND_PMU_READ_4(sc, BHND_PMU_TIMER);
2552 delta = end - start;
2553 sc->ilp_cps = delta * (1000 / ILP_CALC_DUR);
2556 return (sc->ilp_cps);
2559 /* SDIO Pad drive strength to select value mappings */
2561 uint8_t strength; /* Pad Drive Strength in mA */
2562 uint8_t sel; /* Chip-specific select value */
2563 } sdiod_drive_str_t;
2565 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
2566 static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = {
2574 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
2575 static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = {
2586 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
2587 static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = {
2599 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
2602 bhnd_pmu_sdiod_drive_strength_init(struct bhnd_pmu_softc *sc,
2603 uint32_t drivestrength)
2605 const sdiod_drive_str_t *str_tab;
2615 switch (SDIOD_DRVSTR_KEY(sc->cid.chip_id, BHND_PMU_REV(sc))) {
2616 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 1):
2617 str_tab = sdiod_drive_strength_tab1;
2618 str_mask = 0x30000000;
2621 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 2):
2622 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 3):
2623 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4315, 4):
2624 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4319, 7):
2625 str_tab = sdiod_drive_strength_tab2;
2626 str_mask = 0x00003800;
2629 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4336, 8):
2630 str_tab = sdiod_drive_strength_tab3;
2631 str_mask = 0x00003800;
2636 PMU_LOG(sc, "No SDIO Drive strength init done for chip %#x "
2637 "rev %hhd pmurev %hhd\n", sc->cid.chip_id, sc->cid.chip_rev,
2642 if (str_tab != NULL) {
2643 uint32_t drivestrength_sel = 0;
2644 uint32_t cc_data_temp;
2646 for (u_int i = 0; str_tab[i].strength != 0; i++) {
2647 if (drivestrength >= str_tab[i].strength) {
2648 drivestrength_sel = str_tab[i].sel;
2653 cc_data_temp = BHND_PMU_CCTRL_READ(sc, 1);
2654 cc_data_temp &= ~str_mask;
2655 drivestrength_sel <<= str_shift;
2656 cc_data_temp |= drivestrength_sel;
2657 BHND_PMU_CCTRL_WRITE(sc, 1, cc_data_temp, ~0);
2659 PMU_DEBUG(sc, "SDIO: %dmA drive strength selected, set to "
2660 "0x%08x\n", drivestrength, cc_data_temp);
2665 * Initialize the PMU.
2668 bhnd_pmu_init(struct bhnd_pmu_softc *sc)
2673 if (BHND_PMU_REV(sc) == 1) {
2674 BHND_PMU_AND_4(sc, BHND_PMU_CTRL, ~BHND_PMU_CTRL_NOILP_ON_WAIT);
2675 } else if (BHND_PMU_REV(sc) >= 2) {
2676 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_NOILP_ON_WAIT);
2679 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 2) {
2680 /* Fix for 4329b0 bad LPOM state. */
2681 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x100, ~0);
2682 BHND_PMU_REGCTRL_WRITE(sc, 3, 0x4, ~0);
2685 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) {
2686 /* Limiting the PALDO spike during init time */
2687 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x00000005, 0x00000007);
2691 /* Fetch target xtalfreq, in KHz */
2692 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_XTALFREQ,
2695 /* If not available, log any real errors, and then try to measure it */
2697 if (error != ENOENT)
2698 PMU_LOG(sc, "error fetching xtalfreq: %d\n", error);
2700 xtalfreq = bhnd_pmu_measure_alpclk(sc);
2703 /* Perform PLL initialization */
2704 bhnd_pmu_pll_init(sc, xtalfreq);
2706 if ((error = bhnd_pmu_res_init(sc)))
2709 bhnd_pmu_swreg_init(sc);
2714 /* Return up time in ILP cycles for the given resource. */
2716 bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc, uint32_t *uptime)
2719 uint32_t up, dup, dmax;
2723 /* uptime of resource 'rsrc' */
2724 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, rsrc);
2725 up = BHND_PMU_READ_4(sc, BHND_PMU_RES_UPDN_TIMER);
2726 up = BHND_PMU_GET_BITS(up, BHND_PMU_RES_UPDN_UPTME);
2728 /* Find direct dependencies of resource 'rsrc' */
2729 deps = bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(rsrc), false);
2730 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2731 if (!(deps & BHND_PMURES_BIT(i)))
2733 deps &= ~bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(i), true);
2736 /* Exclude the minimum resource set */
2737 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL)))
2742 /* max uptime of direct dependencies */
2744 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2745 if (!(deps & BHND_PMURES_BIT(i)))
2748 if ((error = bhnd_pmu_res_uptime(sc, i, &dup)))
2755 PMU_DEBUG(sc, "bhnd_pmu_res_uptime: rsrc %hhu uptime %u(deps 0x%08x "
2756 "uptime %u)\n", rsrc, up, deps, dmax);
2758 *uptime = (up + dmax + BHND_PMURES_UP_TRANSITION);
2762 /* Return dependencies (direct or all/indirect) for the given resources */
2764 bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs, bool all)
2769 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) {
2770 if (!(rsrcs & BHND_PMURES_BIT(i)))
2773 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i);
2774 deps |= BHND_PMU_READ_4(sc, BHND_PMU_RES_DEP_MASK);
2781 /* Recurse dependencies */
2783 deps |= bhnd_pmu_res_deps(sc, deps, true);
2788 /* power up/down OTP through PMU resources */
2790 bhnd_pmu_otp_power(struct bhnd_pmu_softc *sc, bool on)
2797 /* Determine rsrcs to turn on/off OTP power */
2798 switch (sc->cid.chip_id) {
2799 case BHND_CHIPID_BCM4322:
2800 case BHND_CHIPID_BCM43221:
2801 case BHND_CHIPID_BCM43231:
2802 case BHND_CHIPID_BCM4342:
2803 rsrcs = PMURES_BIT(RES4322_OTP_PU);
2805 case BHND_CHIPID_BCM4315:
2806 rsrcs = PMURES_BIT(RES4315_OTP_PU);
2808 case BHND_CHIPID_BCM4325:
2809 rsrcs = PMURES_BIT(RES4325_OTP_PU);
2811 case BHND_CHIPID_BCM4329:
2812 rsrcs = PMURES_BIT(RES4329_OTP_PU);
2814 case BHND_CHIPID_BCM4319:
2815 rsrcs = PMURES_BIT(RES4319_OTP_PU);
2817 case BHND_CHIPID_BCM4336:
2818 rsrcs = PMURES_BIT(RES4336_OTP_PU);
2820 case BHND_CHIPID_BCM4330:
2821 rsrcs = PMURES_BIT(RES4330_OTP_PU);
2828 /* Fetch all dependencies */
2829 deps = bhnd_pmu_res_deps(sc, rsrcs, true);
2831 /* Exclude the minimum resource set */
2832 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL)))
2837 /* Turn on/off the power */
2841 PMU_DEBUG(sc, "Adding rsrc 0x%x to min_res_mask\n",
2843 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, (rsrcs|deps));
2845 /* Wait for all resources to become available */
2846 for (int i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) {
2847 state = BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE);
2848 if ((state & rsrcs) == rsrcs)
2854 if ((state & rsrcs) != rsrcs) {
2855 PMU_LOG(sc, "timeout waiting for OTP resource "
2860 PMU_DEBUG(sc, "Removing rsrc 0x%x from min_res_mask\n",
2862 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~(rsrcs|deps));
2869 bhnd_pmu_rcal(struct bhnd_pmu_softc *sc)
2874 bool bluetooth_rcal;
2877 bluetooth_rcal = false;
2879 switch (sc->cid.chip_id) {
2880 case BHND_CHIPID_BCM4325:
2881 case BHND_CHIPID_BCM4329:
2883 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1);
2885 /* Power Down RCAL Block */
2886 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, ~0x04);
2888 if (sc->cid.chip_id == BHND_CHIPID_BCM4325) {
2889 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
2890 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_RCAL_VALID))
2891 bluetooth_rcal = true;
2894 /* Power Up RCAL block */
2895 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, 0x04);
2897 /* Wait for completion */
2898 for (int i = 0; i < (10 * 1000 * 1000); i++) {
2899 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
2906 KASSERT((chipst & 0x08) != 0, ("rcal completion timeout"));
2908 if (bluetooth_rcal) {
2911 /* Drop LSB to convert from 5 bit code to 4 bit code */
2912 rcal_code = (uint8_t) (chipst >> 5) & 0x0f;
2915 PMU_DEBUG("RCal completed, status 0x%x, code 0x%x\n",
2916 R_REG(&cc->chipstatus), rcal_code);
2918 /* Write RCal code into pmu_vreg_ctrl[32:29] */
2919 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 0);
2920 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA);
2921 val &= ~((uint32_t) 0x07 << 29);
2922 val |= (uint32_t) (rcal_code & 0x07) << 29;
2923 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val);
2925 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 1);
2926 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA);
2927 val &= ~(uint32_t) 0x01;
2928 val |= (uint32_t) ((rcal_code >> 3) & 0x01);
2929 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val);
2931 /* Write RCal code into pmu_chip_ctrl[33:30] */
2932 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 0);
2933 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIP_CONTROL_DATA);
2934 val &= ~((uint32_t) 0x03 << 30);
2935 val |= (uint32_t) (rcal_code & 0x03) << 30;
2936 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_DATA, val);
2938 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1);
2939 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIP_CONTROL_DATA);
2940 val &= ~(uint32_t) 0x03;
2941 val |= (uint32_t) ((rcal_code >> 2) & 0x03);
2942 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_DATA, val);
2944 /* Set override in pmu_chip_ctrl[29] */
2945 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 0);
2946 BHND_PMU_OR_4(sc, BHND_PMU_CHIP_CONTROL_DATA, (0x01 << 29));
2948 /* Power off RCal block */
2949 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1);
2950 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, ~0x04);
2958 bhnd_pmu_set_spuravoid(struct bhnd_pmu_softc *sc, bhnd_pmu_spuravoid spuravoid)
2962 /* force the HT off */
2963 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) {
2964 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK,
2965 ~BHND_PMU_RES4336_HT_AVAIL);
2967 /* wait for the ht to really go away */
2968 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL);
2971 /* update the pll changes */
2972 error = bhnd_pmu_spuravoid_pllupdate(sc, spuravoid);
2974 /* enable HT back on */
2975 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) {
2976 BHND_PMU_OR_4(sc, BHND_PMU_MAX_RES_MASK,
2977 BHND_PMU_RES4336_HT_AVAIL);
2984 bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc,
2985 bhnd_pmu_spuravoid spuravoid)
2991 /* 6362a0 has same clks as 4322[4-6] */
2992 chip_id = sc->cid.chip_id;
2993 if (chip_id == BHND_CHIPID_BCM6362 && sc->cid.chip_rev == 0) {
2994 chip_id = BHND_CHIPID_BCM43224;
2998 case BHND_CHIPID_BCM6362:
2999 KASSERT(sc->cid.chip_rev != 0, ("invalid clock config"));
3001 case BHND_CHIPID_BCM5357:
3002 case BHND_CHIPID_BCM4749:
3003 case BHND_CHIPID_BCM43235:
3004 case BHND_CHIPID_BCM43236:
3005 case BHND_CHIPID_BCM43238:
3006 case BHND_CHIPID_BCM43234:
3007 case BHND_CHIPID_BCM43237:
3008 case BHND_CHIPID_BCM53572: {
3009 uint8_t p1div, ndiv;
3010 uint8_t phypll_offset;
3012 switch (spuravoid) {
3013 case BHND_PMU_SPURAVOID_NONE:
3017 case BHND_PMU_SPURAVOID_M1:
3021 case BHND_PMU_SPURAVOID_M2:
3029 /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset
3030 * PLL0_PLLCTL[02] by 6 */
3032 if (sc->cid.chip_id == BHND_CHIPID_BCM5357)
3035 /* RMW only the P1 divider */
3036 tmp = BHND_PMU_SET_BITS(p1div, BHND_PMU1_PLL0_PC0_P1DIV);
3037 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0 + phypll_offset,
3038 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK);
3040 /* RMW only the int feedback divider */
3041 tmp = BHND_PMU_SET_BITS(ndiv, BHND_PMU1_PLL0_PC2_NDIV_INT);
3042 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2 + phypll_offset,
3043 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK);
3045 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3049 case BHND_CHIPID_BCM4331:
3050 switch (spuravoid) {
3051 case BHND_PMU_SPURAVOID_NONE:
3052 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3054 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3058 case BHND_PMU_SPURAVOID_M1:
3059 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3061 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3065 case BHND_PMU_SPURAVOID_M2:
3066 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3068 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3076 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3079 case BHND_CHIPID_BCM43224:
3080 case BHND_CHIPID_BCM43225:
3081 case BHND_CHIPID_BCM43226:
3082 case BHND_CHIPID_BCM43421:
3083 switch (spuravoid) {
3084 case BHND_PMU_SPURAVOID_NONE:
3085 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3087 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3089 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3091 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3093 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3095 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3099 case BHND_PMU_SPURAVOID_M1:
3100 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3102 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3104 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3106 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3108 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3110 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3114 case BHND_PMU_SPURAVOID_M2:
3119 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3122 case BHND_CHIPID_BCM43111:
3123 case BHND_CHIPID_BCM43112:
3124 case BHND_CHIPID_BCM43222:
3125 case BHND_CHIPID_BCM43420:
3126 switch (spuravoid) {
3127 case BHND_PMU_SPURAVOID_NONE:
3128 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3130 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3132 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3134 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3136 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3138 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3142 case BHND_PMU_SPURAVOID_M1:
3143 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3145 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3147 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3149 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3151 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3153 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3157 case BHND_PMU_SPURAVOID_M2:
3162 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3165 case BHND_CHIPID_BCM4716:
3166 case BHND_CHIPID_BCM4748:
3167 case BHND_CHIPID_BCM47162:
3168 switch (spuravoid) {
3169 case BHND_PMU_SPURAVOID_NONE:
3170 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3172 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3174 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3176 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3178 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3180 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3184 case BHND_PMU_SPURAVOID_M1:
3185 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3187 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3189 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3191 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3193 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3195 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3199 case BHND_PMU_SPURAVOID_M2:
3205 pmuctrl = BHND_PMU_CTRL_NOILP_ON_WAIT |
3206 BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3209 case BHND_CHIPID_BCM4319:
3213 case BHND_CHIPID_BCM4322:
3214 case BHND_CHIPID_BCM43221:
3215 case BHND_CHIPID_BCM43231:
3216 case BHND_CHIPID_BCM4342:
3217 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x11100070, ~0);
3218 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x1014140a, ~0);
3219 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888854, ~0);
3221 switch (spuravoid) {
3222 case BHND_PMU_SPURAVOID_NONE:
3223 /* enable 40/80/160Mhz clock mode */
3224 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3228 case BHND_PMU_SPURAVOID_M1:
3229 /* spur_avoid ON, enable 41/82/164Mhz clock mode */
3230 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3234 case BHND_PMU_SPURAVOID_M2:
3239 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3242 case BHND_CHIPID_BCM4336:
3243 /* Looks like these are only for default xtal freq 26MHz */
3244 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x02100020, ~0);
3245 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x0C0C0C0C, ~0);
3246 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 0x01240C0C, ~0);
3247 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 0x202C2820, ~0);
3248 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888825, ~0);
3250 switch (spuravoid) {
3251 case BHND_PMU_SPURAVOID_NONE:
3252 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3256 case BHND_PMU_SPURAVOID_M1:
3257 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3261 case BHND_PMU_SPURAVOID_M2:
3266 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3269 case BHND_CHIPID_BCM43131:
3270 case BHND_CHIPID_BCM43227:
3271 case BHND_CHIPID_BCM43228:
3272 case BHND_CHIPID_BCM43428:
3274 /* PLL Settings for spur avoidance on/off mode, no on2 support
3276 switch (spuravoid) {
3277 case BHND_PMU_SPURAVOID_NONE:
3278 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3280 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3282 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3284 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3286 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3288 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3292 case BHND_PMU_SPURAVOID_M1:
3293 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0,
3295 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1,
3297 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2,
3299 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3,
3301 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4,
3303 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5,
3307 case BHND_PMU_SPURAVOID_M2:
3312 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD;
3315 PMU_LOG(sc, "%s: unknown spuravoidance settings for chip %#hx, "
3316 "not changing PLL", __func__, sc->cid.chip_id);
3322 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, pmuctrl);
3328 bhnd_pmu_is_otp_powered(struct bhnd_pmu_softc *sc)
3332 /* Determine per-chip OTP resource */
3333 switch (sc->cid.chip_id) {
3334 case BHND_CHIPID_BCM4329:
3335 otp_res = PMURES_BIT(RES4329_OTP_PU);
3337 case BHND_CHIPID_BCM4319:
3338 otp_res = PMURES_BIT(RES4319_OTP_PU);
3340 case BHND_CHIPID_BCM4336:
3341 otp_res = PMURES_BIT(RES4336_OTP_PU);
3343 case BHND_CHIPID_BCM4330:
3344 otp_res = PMURES_BIT(RES4330_OTP_PU);
3347 /* These chips don't use PMU bit to power up/down OTP. OTP always on.
3348 * Use OTP_INIT command to reset/refresh state.
3350 case BHND_CHIPID_BCM43224:
3351 case BHND_CHIPID_BCM43225:
3352 case BHND_CHIPID_BCM43421:
3353 case BHND_CHIPID_BCM43236:
3354 case BHND_CHIPID_BCM43235:
3355 case BHND_CHIPID_BCM43238:
3362 /* Check resource state */
3363 if ((BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE) & otp_res) == 0)
3370 bhnd_pmu_paref_ldo_enable(struct bhnd_pmu_softc *sc, bool enable)
3374 switch (sc->cid.chip_id) {
3375 case BHND_CHIPID_BCM4328:
3376 ldo = PMURES_BIT(RES4328_PA_REF_LDO);
3378 case BHND_CHIPID_BCM5354:
3379 ldo = PMURES_BIT(RES5354_PA_REF_LDO);
3381 case BHND_CHIPID_BCM4312:
3382 ldo = PMURES_BIT(RES4312_PA_REF_LDO);
3389 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, ldo);
3391 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~ldo);
3397 /* initialize PMU switch/regulators */
3399 bhnd_pmu_swreg_init(struct bhnd_pmu_softc *sc)
3403 switch (sc->cid.chip_id) {
3404 case BHND_CHIPID_BCM4325:
3405 if (sc->cid.chip_rev <= 2)
3408 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev);
3409 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) {
3410 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM,
3412 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST,
3416 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb);
3417 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb);
3419 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0x1);
3420 if (sc->board.board_flags & BHND_BFL_LNLDO2_2P5) {
3421 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO2_SEL,
3426 case BHND_CHIPID_BCM4336:
3427 /* Reduce CLDO PWM output voltage to 1.2V */
3428 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
3429 /* Reduce CLDO BURST output voltage to 1.2V */
3430 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 0xe);
3431 /* Reduce LNLDO1 output voltage to 1.2V */
3432 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0xe);
3433 if (sc->cid.chip_rev == 0)
3434 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x400000, 0x400000);
3437 case BHND_CHIPID_BCM4330:
3438 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
3439 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
3447 bhnd_pmu_radio_enable(struct bhnd_pmu_softc *sc, device_t d11core, bool enable)
3453 if (bhnd_get_device(d11core) != BHND_COREID_D11) {
3454 device_printf(sc->dev,
3455 "bhnd_pmu_radio_enable() called on non-D11 core");
3459 switch (sc->cid.chip_id) {
3460 case BHND_CHIPID_BCM4325:
3461 if (sc->board.board_flags & BHND_BFL_FASTPWR)
3464 if ((sc->board.board_flags & BHND_BFL_BUCKBOOST) == 0)
3467 rsrcs = PMURES_BIT(RES4325_BUCK_BOOST_BURST);
3470 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, rsrcs);
3471 DELAY(100 * 1000); /* 100ms */
3473 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~rsrcs);
3478 case BHND_CHIPID_BCM4319:
3479 error = bhnd_read_config(d11core, BCMA_DMP_OOBSELOUTB74,
3485 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3487 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3490 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3492 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN,
3496 return (bhnd_write_config(d11core, BCMA_DMP_OOBSELOUTB74,
3503 /* Wait for a particular clock level to be on the backplane */
3505 bhnd_pmu_waitforclk_on_backplane(struct bhnd_pmu_softc *sc, uint32_t clk,
3510 for (uint32_t i = 0; i < delay; i += 10) {
3511 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3512 if ((pmu_st & clk) == clk)
3518 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3519 return (pmu_st & clk);
3523 * Measures the ALP clock frequency in KHz. Returns 0 if not possible.
3524 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
3527 #define EXT_ILP_HZ 32768
3530 bhnd_pmu_measure_alpclk(struct bhnd_pmu_softc *sc)
3535 if (BHND_PMU_REV(sc) < 10)
3538 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST);
3539 if (pmu_st & BHND_PMU_ST_EXTLPOAVAIL) {
3540 uint32_t alp_hz, ilp_ctr;
3542 /* Enable frequency measurement */
3543 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 1U <<
3544 BHND_PMU_XTALFREQ_REG_MEASURE_SHIFT);
3546 /* Delay for well over 4 ILP clocks */
3549 /* Read the latched number of ALP ticks per 4 ILP ticks */
3550 ilp_ctr = BHND_PMU_READ_4(sc, BHND_PMU_XTALFREQ);
3551 ilp_ctr = BHND_PMU_GET_BITS(ilp_ctr,
3552 BHND_PMU_XTALFREQ_REG_ILPCTR);
3554 /* Turn off PMU_XTALFREQ_REG_MEASURE to save power */
3555 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 0);
3557 /* Calculate ALP frequency */
3558 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
3560 /* Round to nearest 100KHz and convert to KHz */
3561 alp_khz = (alp_hz + 50000) / 100000 * 100;
3570 bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc)
3572 uint32_t FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000;
3573 uint32_t m1div, m2div, m3div, m4div, m5div, m6div;
3574 uint32_t pllc1, pllc2;
3576 m2div = m3div = m4div = m6div = FVCO / 80;
3579 if (PMU_CST4330_SDIOD_CHIPMODE(sc))
3585 pllc1 |= BHND_PMU_SET_BITS(m1div, BHND_PMU1_PLL0_PC1_M1DIV);
3586 pllc1 |= BHND_PMU_SET_BITS(m2div, BHND_PMU1_PLL0_PC1_M2DIV);
3587 pllc1 |= BHND_PMU_SET_BITS(m3div, BHND_PMU1_PLL0_PC1_M3DIV);
3588 pllc1 |= BHND_PMU_SET_BITS(m4div, BHND_PMU1_PLL0_PC1_M4DIV);
3590 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, pllc1, ~0);
3593 pllc2 |= BHND_PMU_SET_BITS(m5div, BHND_PMU1_PLL0_PC2_M5DIV);
3594 pllc2 |= BHND_PMU_SET_BITS(m6div, BHND_PMU1_PLL0_PC2_M6DIV);
3596 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, pllc2,
3597 BHND_PMU1_PLL0_PC2_M5DIV_MASK | BHND_PMU1_PLL0_PC2_M6DIV_MASK);