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