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