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