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