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