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