2 * Misc utility routines for accessing PMU corerev specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright 2007, Broadcom Corporation
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
25 #define PMU_ERROR(args)
28 #define PMU_MSG(args) printf args
34 /* PMU rev 0 pll control for BCM4328 and BCM5354 */
35 static void sb_pmu0_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
37 static uint32 sb_pmu0_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
38 static uint32 sb_pmu0_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
39 /* PMU rev 0 pll control for BCM4325 BCM4329 */
40 static void sb_pmu1_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
42 static uint32 sb_pmu1_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
43 static uint32 sb_pmu1_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
45 /* Setup switcher voltage */
47 BCMINITFN (sb_pmu_set_switcher_voltage) (sb_t * sbh, osl_t * osh,
48 uint8 bb_voltage, uint8 rf_voltage)
53 ASSERT (sbh->cccaps & CC_CAP_PMU);
55 /* Remember original core before switch to chipc */
56 origidx = sb_coreidx (sbh);
57 cc = sb_setcore (sbh, SB_CC, 0);
60 W_REG (osh, &cc->regcontrol_addr, 0x01);
61 W_REG (osh, &cc->regcontrol_data, (uint32) (bb_voltage & 0x1f) << 22);
63 W_REG (osh, &cc->regcontrol_addr, 0x00);
64 W_REG (osh, &cc->regcontrol_data, (uint32) (rf_voltage & 0x1f) << 14);
66 /* Return to original core */
67 sb_setcoreidx (sbh, origidx);
71 sb_pmu_set_ldo_voltage (sb_t * sbh, osl_t * osh, uint8 ldo, uint8 voltage)
73 uint8 sr_cntl_shift, rc_shift, shift, mask;
76 ASSERT (sbh->cccaps & CC_CAP_PMU);
84 case SET_LDO_VOLTAGE_LDO1:
90 case SET_LDO_VOLTAGE_LDO2:
96 case SET_LDO_VOLTAGE_LDO3:
102 case SET_LDO_VOLTAGE_PAREF:
113 case BCM4312_CHIP_ID:
116 case SET_LDO_VOLTAGE_PAREF:
132 shift = sr_cntl_shift + rc_shift;
134 sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_addr),
136 sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_data),
137 mask << shift, (voltage & mask) << shift);
141 sb_pmu_paref_ldo_enable (sb_t * sbh, osl_t * osh, bool enable)
145 ASSERT (sbh->cccaps & CC_CAP_PMU);
149 case BCM4328_CHIP_ID:
150 ldo = RES4328_PA_REF_LDO;
152 case BCM5354_CHIP_ID:
153 ldo = RES5354_PA_REF_LDO;
155 case BCM4312_CHIP_ID:
156 ldo = RES4312_PA_REF_LDO;
162 sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, min_res_mask),
163 PMURES_BIT (ldo), enable ? PMURES_BIT (ldo) : 0);
166 uint16 BCMINITFN (sb_pmu_fast_pwrup_delay) (sb_t * sbh, osl_t * osh)
168 uint16 delay = PMU_MAX_TRANSITION_DLY;
170 ASSERT (sbh->cccaps & CC_CAP_PMU);
174 case BCM4328_CHIP_ID:
178 case BCM4325_CHIP_ID:
179 case BCM4312_CHIP_ID:
188 PMU_MSG (("No PMU fast power up delay specified "
189 "for chip %x rev %d, using default %d us\n",
190 sbh->chip, sbh->chiprev, delay));
197 uint32 BCMINITFN (sb_pmu_force_ilp) (sb_t * sbh, osl_t * osh, bool force)
201 uint32 oldpmucontrol;
203 ASSERT (sbh->cccaps & CC_CAP_PMU);
205 /* Remember original core before switch to chipc */
206 origidx = sb_coreidx (sbh);
207 cc = sb_setcore (sbh, SB_CC, 0);
210 oldpmucontrol = R_REG (osh, &cc->pmucontrol);
212 W_REG (osh, &cc->pmucontrol, oldpmucontrol &
213 ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
215 W_REG (osh, &cc->pmucontrol, oldpmucontrol |
216 (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
218 /* Return to original core */
219 sb_setcoreidx (sbh, origidx);
221 return oldpmucontrol;
224 /* Setup min/max resources and up/down timers */
234 int8 action; /* 0 - set, 1 - add, -1 - remove */
238 static const pmu_res_updown_t
239 BCMINITDATA (bcm4328a0_res_updown)[] =
242 RES4328_EXT_SWITCHER_PWM, 0x0101},
244 RES4328_BB_SWITCHER_PWM, 0x1f01},
246 RES4328_BB_SWITCHER_BURST, 0x010f},
248 RES4328_BB_EXT_SWITCHER_BURST, 0x0101},
250 RES4328_ILP_REQUEST, 0x0202},
252 RES4328_RADIO_SWITCHER_PWM, 0x0f01},
254 RES4328_RADIO_SWITCHER_BURST, 0x0f01},
256 RES4328_ROM_SWITCH, 0x0101},
258 RES4328_PA_REF_LDO, 0x0f01},
260 RES4328_RADIO_LDO, 0x0f01},
262 RES4328_AFE_LDO, 0x0f01},
264 RES4328_PLL_LDO, 0x0f01},
266 RES4328_BG_FILTBYP, 0x0101},
268 RES4328_TX_FILTBYP, 0x0101},
270 RES4328_RX_FILTBYP, 0x0101},
272 RES4328_XTAL_PU, 0x0101},
274 RES4328_XTAL_EN, 0xa001},
276 RES4328_BB_PLL_FILTBYP, 0x0101},
278 RES4328_RF_PLL_FILTBYP, 0x0101},
280 RES4328_BB_PLL_PU, 0x0701}
283 static const pmu_res_depend_t
284 BCMINITDATA (bcm4328a0_res_depend)[] =
286 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
288 RES4328_ILP_REQUEST, 0,
289 PMURES_BIT (RES4328_EXT_SWITCHER_PWM) |
290 PMURES_BIT (RES4328_BB_SWITCHER_PWM)}
293 #ifdef BCMQT /* for power save on slow QT/small beacon interval */
294 static const pmu_res_updown_t
295 BCMINITDATA (bcm4325a0_res_updown_qt)[] =
298 RES4325_HT_AVAIL, 0x0300},
300 RES4325_BBPLL_PWRSW_PU, 0x0101},
302 RES4325_RFPLL_PWRSW_PU, 0x0101},
304 RES4325_ALP_AVAIL, 0x0100},
306 RES4325_XTAL_PU, 0x1000},
308 RES4325_LNLDO1_PU, 0x0800},
310 RES4325_CLDO_CBUCK_PWM, 0x0101},
312 RES4325_CBUCK_PWM, 0x0803}
315 static const pmu_res_updown_t
316 BCMINITDATA (bcm4325a0_res_updown)[] =
319 RES4325_XTAL_PU, 0x1501}
323 static const pmu_res_depend_t
324 BCMINITDATA (bcm4325a0_res_depend)[] =
326 /* Adjust HT Avail resource dependencies */
329 PMURES_BIT (RES4325_RX_PWRSW_PU) | PMURES_BIT (RES4325_TX_PWRSW_PU) |
330 PMURES_BIT (RES4325_LOGEN_PWRSW_PU) | PMURES_BIT (RES4325_AFE_PWRSW_PU)}
333 void BCMINITFN (sb_pmu_res_init) (sb_t * sbh, osl_t * osh)
337 const pmu_res_updown_t *pmu_res_updown_table = NULL;
338 int pmu_res_updown_table_sz = 0;
339 const pmu_res_depend_t *pmu_res_depend_table = NULL;
340 int pmu_res_depend_table_sz = 0;
341 uint32 min_mask = 0, max_mask = 0;
343 ASSERT (sbh->cccaps & CC_CAP_PMU);
345 /* Remember original core before switch to chipc */
346 origidx = sb_coreidx (sbh);
347 cc = sb_setcore (sbh, SB_CC, 0);
352 case BCM4328_CHIP_ID:
353 /* Down to ILP request excluding ROM */
354 min_mask = PMURES_BIT (RES4328_EXT_SWITCHER_PWM) |
355 PMURES_BIT (RES4328_BB_SWITCHER_PWM) | PMURES_BIT (RES4328_XTAL_EN);
358 min_mask |= PMURES_BIT (RES4328_ROM_SWITCH);
360 /* Allow (but don't require) PLL to turn on */
362 pmu_res_updown_table = bcm4328a0_res_updown;
363 pmu_res_updown_table_sz = ARRAYSIZE (bcm4328a0_res_updown);
364 pmu_res_depend_table = bcm4328a0_res_depend;
365 pmu_res_depend_table_sz = ARRAYSIZE (bcm4328a0_res_depend);
367 case BCM4312_CHIP_ID:
369 * min_mask = 0xcbb; max_mask = 0x7ffff;
370 * pmu_res_updown_table_sz = 0;
371 * pmu_res_depend_table_sz = 0;
374 case BCM5354_CHIP_ID:
375 /* Allow (but don't require) PLL to turn on */
379 case BCM4325_CHIP_ID:
380 /* Leave OTP powered up and power it down later. */
382 PMURES_BIT (RES4325_CBUCK_BURST) | PMURES_BIT (RES4325_LNLDO2_PU);
383 if (((sbh->chipst & CST4325_PMUTOP_2B_MASK) >>
384 CST4325_PMUTOP_2B_SHIFT) == 1)
385 min_mask |= PMURES_BIT (RES4325_CLDO_CBUCK_BURST);
386 /* Allow (but don't require) PLL to turn on */
389 pmu_res_updown_table = bcm4325a0_res_updown_qt;
390 pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown_qt);
392 pmu_res_updown_table = bcm4325a0_res_updown;
393 pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown);
394 pmu_res_depend_table = bcm4325a0_res_depend;
395 pmu_res_depend_table_sz = ARRAYSIZE (bcm4325a0_res_depend);
403 /* Program up/down timers */
404 while (pmu_res_updown_table_sz--)
406 ASSERT (pmu_res_updown_table);
407 W_REG (osh, &cc->res_table_sel,
408 pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
409 W_REG (osh, &cc->res_updn_timer,
410 pmu_res_updown_table[pmu_res_updown_table_sz].updown);
413 /* Program resource dependencies table */
414 while (pmu_res_depend_table_sz--)
416 ASSERT (pmu_res_depend_table);
417 W_REG (osh, &cc->res_table_sel,
418 pmu_res_depend_table[pmu_res_depend_table_sz].resnum);
419 switch (pmu_res_depend_table[pmu_res_depend_table_sz].action)
422 W_REG (osh, &cc->res_dep_mask,
423 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
426 OR_REG (osh, &cc->res_dep_mask,
427 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
430 AND_REG (osh, &cc->res_dep_mask,
431 ~pmu_res_depend_table[pmu_res_depend_table_sz].
440 /* program min resource mask */
443 PMU_MSG (("Changing min_res_mask to 0x%x\n", min_mask));
444 W_REG (osh, &cc->min_res_mask, min_mask);
446 /* program max resource mask */
449 PMU_MSG (("Changing max_res_mask to 0x%x\n", max_mask));
450 W_REG (osh, &cc->max_res_mask, max_mask);
453 /* Return to original core */
454 sb_setcoreidx (sbh, origidx);
457 /* setup pll and query clock speed */
466 /* the following table is based on 880Mhz Fvco */
467 #define PMU0_PLL0_FVCO 880000 /* Fvco 880Mhz */
468 static const pmu0_xtaltab0_t
469 BCMINITDATA (pmu0_xtaltab0)[] =
472 12000, 1, 73, 349525},
474 13000, 2, 67, 725937},
476 14400, 3, 61, 116508},
478 15360, 4, 57, 305834},
480 16200, 5, 54, 336579},
482 16800, 6, 52, 399457},
484 19200, 7, 45, 873813},
486 19800, 8, 44, 466033},
490 25000, 10, 70, 419430},
492 26000, 11, 67, 725937},
494 30000, 12, 58, 699050},
496 38400, 13, 45, 873813},
504 #define PMU0_XTAL0_DEFAULT 11
506 #define PMU0_XTAL0_DEFAULT 8
511 * Set new backplane PLL clock frequency
513 static void BCMINITFN (sb_pmu0_sbclk4328) (sb_t * sbh, int freq)
515 uint32 tmp, oldmax, oldmin, origidx;
518 /* Remember original core before switch to chipc */
519 origidx = sb_coreidx (sbh);
520 cc = sb_setcore (sbh, SB_CC, 0);
523 /* Set new backplane PLL clock */
524 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
525 tmp = R_REG (osh, &cc->pllcontrol_data);
526 tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK);
527 tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT;
528 W_REG (osh, &cc->pllcontrol_data, tmp);
530 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
532 oldmin = R_REG (osh, &cc->min_res_mask);
533 oldmax = R_REG (osh, &cc->max_res_mask);
534 W_REG (osh, &cc->min_res_mask, oldmin & ~PMURES_BIT (RES4328_BB_PLL_PU));
535 W_REG (osh, &cc->max_res_mask, oldmax & ~PMURES_BIT (RES4328_BB_PLL_PU));
537 /* It takes over several hundred usec to re-enable the PLL since the
538 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
540 * Be sure PLL is powered down first before re-enabling it.
543 OSL_DELAY (PLL_DELAY);
544 SPINWAIT ((R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)),
547 if (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU))
549 /* If BB_PLL not powered down yet, new backplane PLL clock
550 * may not take effect.
552 * Still early during bootup so no serial output here.
554 PMU_ERROR (("Fatal: BB_PLL not power down yet!\n"));
556 (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)));
560 W_REG (osh, &cc->max_res_mask, oldmax);
562 /* Return to original core */
563 sb_setcoreidx (sbh, origidx);
565 #endif /* BCMUSBDEV */
567 /* Set up PLL registers in the PMU as per the crystal speed.
568 * Uses xtalfreq variable, or passed-in default.
571 BCMINITFN (sb_pmu0_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
575 const pmu0_xtaltab0_t *xt;
577 if ((sb_chip (sbh) == BCM5354_CHIP_ID) && (xtal == 0))
579 /* 5354 has xtal freq of 25MHz */
583 /* Find the frequency in the table */
584 for (xt = pmu0_xtaltab0; xt->freq; xt++)
585 if (xt->freq == xtal)
588 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
590 PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf));
592 /* Check current PLL state */
593 tmp = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
597 PMU_MSG (("PLL already programmed for %d.%d MHz\n",
598 (xt->freq / 1000), (xt->freq % 1000)));
601 if (sbh->chip == BCM4328_CHIP_ID)
602 sb_pmu0_sbclk4328 (sbh, PMU0_PLL0_PC0_DIV_ARM_88MHZ);
609 PMU_MSG (("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
610 (xt->freq / 1000), (xt->freq % 1000),
611 (pmu0_xtaltab0[tmp - 1].freq / 1000),
612 (pmu0_xtaltab0[tmp - 1].freq % 1000)));
616 PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->freq / 1000),
620 /* Make sure the PLL is off */
623 case BCM4328_CHIP_ID:
624 AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU));
625 AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU));
627 case BCM5354_CHIP_ID:
628 AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU));
629 AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU));
634 SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL,
635 PMU_MAX_TRANSITION_DLY);
636 ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL));
638 PMU_MSG (("Done masking\n"));
640 /* Write PDIV in pllcontrol[0] */
641 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
642 tmp = R_REG (osh, &cc->pllcontrol_data);
643 if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ)
644 tmp |= PMU0_PLL0_PC0_PDIV_MASK;
646 tmp &= ~PMU0_PLL0_PC0_PDIV_MASK;
647 W_REG (osh, &cc->pllcontrol_data, tmp);
649 /* Write WILD in pllcontrol[1] */
650 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
651 tmp = R_REG (osh, &cc->pllcontrol_data);
653 ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) |
655 wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & PMU0_PLL0_PC1_WILD_INT_MASK)
656 | ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) &
657 PMU0_PLL0_PC1_WILD_FRAC_MASK)));
659 tmp |= PMU0_PLL0_PC1_STOP_MOD;
661 tmp &= ~PMU0_PLL0_PC1_STOP_MOD;
662 W_REG (osh, &cc->pllcontrol_data, tmp);
664 /* Write WILD in pllcontrol[2] */
665 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
666 tmp = R_REG (osh, &cc->pllcontrol_data);
667 tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) |
668 ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) &
669 PMU0_PLL0_PC2_WILD_INT_MASK));
670 W_REG (osh, &cc->pllcontrol_data, tmp);
672 PMU_MSG (("Done pll\n"));
674 /* Write XtalFreq. Set the divisor also. */
675 tmp = R_REG (osh, &cc->pmucontrol);
676 tmp = ((tmp & ~PCTL_ILP_DIV_MASK) |
677 (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
679 tmp = ((tmp & ~PCTL_XTALFREQ_MASK) |
680 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK));
681 W_REG (osh, &cc->pmucontrol, tmp);
685 BCMINITFN (sb_pmu0_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
687 const pmu0_xtaltab0_t *xt;
690 /* Find the frequency in the table */
691 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
693 for (xt = pmu0_xtaltab0; xt->freq; xt++)
697 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
699 return xt->freq * 1000;
703 BCMINITFN (sb_pmu0_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
705 const pmu0_xtaltab0_t *xt;
706 uint32 xf, tmp, divarm;
708 uint32 pdiv, wbint, wbfrac, fvco;
711 if (sb_chip (sbh) == BCM5354_CHIP_ID)
713 /* 5354 gets sb clock of 120MHz from main pll */
717 /* Find the xtal frequency in the table */
718 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
720 for (xt = pmu0_xtaltab0; xt->freq; xt++)
724 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
726 /* Read divarm from pllcontrol[0] */
727 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
728 tmp = R_REG (osh, &cc->pllcontrol_data);
729 divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT;
732 /* Calculate Fvco based on xtal freq, pdiv, and wild */
733 pdiv = tmp & PMU0_PLL0_PC0_PDIV_MASK;
735 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
736 tmp = R_REG (osh, &cc->pllcontrol_data);
738 (tmp & PMU0_PLL0_PC1_WILD_FRAC_MASK) >> PMU0_PLL0_PC1_WILD_FRAC_SHIFT;
739 wbint = (tmp & PMU0_PLL0_PC1_WILD_INT_MASK) >> PMU0_PLL0_PC1_WILD_INT_SHIFT;
741 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
742 tmp = R_REG (osh, &cc->pllcontrol_data);
744 (tmp & PMU0_PLL0_PC2_WILD_INT_MASK) << PMU0_PLL0_PC2_WILD_INT_SHIFT;
746 fvco = (xt->freq * wbint) << 8;
747 fvco += (xt->freq * (wbfrac >> 10)) >> 2;
748 fvco += (xt->freq * (wbfrac & 0x3ff)) >> 10;
754 PMU_MSG (("sb_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
755 wbint, wbfrac, fvco));
756 ASSERT (fvco == PMU0_PLL0_FVCO);
759 /* Return ARM/SB clock */
760 return PMU0_PLL0_FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
763 /* PMU corerev 1 pll programming for BCM4325 */
764 /* setup pll and query clock speed */
775 /* the following table is based on 880Mhz Fvco */
776 #define PMU1_PLL0_FVCO 880000 /* Fvco 880Mhz */
777 static const pmu1_xtaltab0_t
778 BCMINITDATA (pmu1_xtaltab0)[] =
781 12000, 1, 3, 22, 0x9, 0xFFFFEF},
783 13000, 2, 1, 6, 0xb, 0x483483},
785 14400, 3, 1, 10, 0xa, 0x1C71C7},
787 15360, 4, 1, 5, 0xb, 0x755555},
789 16200, 5, 1, 10, 0x5, 0x6E9E06},
791 16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
793 19200, 7, 1, 9, 0x5, 0x17B425},
795 19800, 8, 1, 11, 0x4, 0xA57EB},
797 20000, 9, 1, 11, 0x4, 0x0},
799 24000, 10, 3, 11, 0xa, 0x0},
801 25000, 11, 5, 16, 0xb, 0x0},
803 26000, 12, 1, 2, 0x10, 0xEC4EC4},
805 30000, 13, 3, 8, 0xb, 0x0},
807 38400, 14, 1, 5, 0x4, 0x955555},
809 40000, 15, 1, 2, 0xb, 0},
814 /* Default to 15360Khz crystal */
815 #define PMU1_XTAL0_DEFAULT 3
818 BCMINITFN (sb_pmu1_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
820 const pmu1_xtaltab0_t *xt;
823 /* Find the frequency in the table */
824 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
826 for (xt = pmu1_xtaltab0; xt->fref; xt++)
830 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
832 return xt->fref * 1000;
835 /* Set up PLL registers in the PMU as per the crystal speed.
836 * Uses xtalfreq variable, or passed-in default.
839 BCMINITFN (sb_pmu1_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
842 const pmu1_xtaltab0_t *xt;
844 uint32 buf_strength = 0;
846 /* 4312: assume default works */
847 if (sbh->chip == BCM4312_CHIP_ID)
850 /* Find the frequency in the table */
851 for (xt = pmu1_xtaltab0; xt->fref; xt++)
852 if (xt->fref == xtal)
855 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
857 PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf));
859 /* Check current PLL state */
860 if (((R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
861 PCTL_XTALFREQ_SHIFT) == xt->xf)
863 PMU_MSG (("PLL already programmed for %d.%d MHz\n",
864 (xt->fref / 1000), (xt->fref % 1000)));
868 PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->fref / 1000),
871 /* Make sure the PLL is off */
874 case BCM4325_CHIP_ID:
875 AND_REG (osh, &cc->min_res_mask,
876 ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) |
877 PMURES_BIT (RES4325_HT_AVAIL)));
878 AND_REG (osh, &cc->max_res_mask,
879 ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) |
880 PMURES_BIT (RES4325_HT_AVAIL)));
882 /* Change the BBPLL drive strength to 2 for all channels */
883 buf_strength = 0x222222;
888 SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
889 PMU_MAX_TRANSITION_DLY);
890 ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
892 PMU_MSG (("Done masking\n"));
894 /* Write p1div and p2div to pllcontrol[0] */
895 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
896 tmp = R_REG (osh, &cc->pllcontrol_data) &
897 ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
900 p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | ((xt->
903 PMU1_PLL0_PC0_P2DIV_SHIFT)
905 PMU1_PLL0_PC0_P2DIV_MASK);
906 W_REG (osh, &cc->pllcontrol_data, tmp);
908 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
909 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
910 tmp = R_REG (osh, &cc->pllcontrol_data) &
911 ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
914 ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK)
915 | ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK);
916 W_REG (osh, &cc->pllcontrol_data, tmp);
918 /* Write ndiv_frac to pllcontrol[3] */
919 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
920 tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
921 tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
922 PMU1_PLL0_PC3_NDIV_FRAC_MASK);
923 W_REG (osh, &cc->pllcontrol_data, tmp);
927 PMU_MSG (("Adjusting PLL buffer drive strength: %x\n", buf_strength));
929 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
930 tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
931 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
932 W_REG (osh, &cc->pllcontrol_data, tmp);
935 PMU_MSG (("Done pll\n"));
937 /* Write XtalFreq. Set the divisor also. */
938 tmp = R_REG (osh, &cc->pmucontrol) &
939 ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
940 tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
942 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
943 W_REG (osh, &cc->pmucontrol, tmp);
948 BCMINITFN (sb_pmu1_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
950 const pmu1_xtaltab0_t *xt;
951 uint32 xf, tmp, m1div;
953 uint32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
956 /* Find the xtal frequency in the table */
957 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
959 for (xt = pmu1_xtaltab0; xt->fref; xt++)
963 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
965 /* Read m1div from pllcontrol[1] */
966 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
967 tmp = R_REG (osh, &cc->pllcontrol_data);
968 m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
971 /* Read p2div/p1div from pllcontrol[0] */
972 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
973 tmp = R_REG (osh, &cc->pllcontrol_data);
974 p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
975 p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
977 /* Calculate Fvco based on xtal freq and ndiv and pdiv */
978 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
979 tmp = R_REG (osh, &cc->pllcontrol_data);
981 (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
983 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
984 tmp = R_REG (osh, &cc->pllcontrol_data);
986 (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
988 fvco = (xt->fref * ndiv_int) << 8;
989 fvco += (xt->fref * (ndiv_frac >> 12)) >> 4;
990 fvco += (xt->fref * (ndiv_frac & 0xfff)) >> 12;
997 PMU_MSG (("sb_pmu0_cpuclk0: ndiv_int %u ndiv_frac %u "
998 "p2div %u p1div %u fvco %u\n",
999 ndiv_int, ndiv_frac, p2div, p1div, fvco));
1000 ASSERT (fvco == PMU1_PLL0_FVCO);
1003 /* Return ARM/SB clock */
1004 return PMU1_PLL0_FVCO / m1div * 1000;
1007 void BCMINITFN (sb_pmu_pll_init) (sb_t * sbh, osl_t * osh, uint xtalfreq)
1012 ASSERT (sbh->cccaps & CC_CAP_PMU);
1014 /* Remember original core before switch to chipc */
1015 origidx = sb_coreidx (sbh);
1016 cc = sb_setcore (sbh, SB_CC, 0);
1021 case BCM4328_CHIP_ID:
1022 sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq);
1024 case BCM5354_CHIP_ID:
1025 sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq);
1027 case BCM4325_CHIP_ID:
1028 sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq);
1030 case BCM4312_CHIP_ID:
1031 sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq);
1034 PMU_MSG (("No PLL init done for chip %x rev %d pmurev %d\n",
1035 sbh->chip, sbh->chiprev, sbh->pmurev));
1039 /* Return to original core */
1040 sb_setcoreidx (sbh, origidx);
1043 uint32 BCMINITFN (sb_pmu_alp_clock) (sb_t * sbh, osl_t * osh)
1047 uint32 clock = ALP_CLOCK;
1049 ASSERT (sbh->cccaps & CC_CAP_PMU);
1051 /* Remember original core before switch to chipc */
1052 origidx = sb_coreidx (sbh);
1053 cc = sb_setcore (sbh, SB_CC, 0);
1058 case BCM4328_CHIP_ID:
1059 clock = sb_pmu0_alpclk0 (sbh, osh, cc);
1061 case BCM5354_CHIP_ID:
1062 clock = sb_pmu0_alpclk0 (sbh, osh, cc);
1064 case BCM4325_CHIP_ID:
1065 clock = sb_pmu1_alpclk0 (sbh, osh, cc);
1067 case BCM4312_CHIP_ID:
1068 clock = sb_pmu1_alpclk0 (sbh, osh, cc);
1070 clock = 20000 * 1000;
1073 PMU_MSG (("No ALP clock specified "
1074 "for chip %x rev %d pmurev %d, using default %d Hz\n",
1075 sbh->chip, sbh->chiprev, sbh->pmurev, clock));
1079 /* Return to original core */
1080 sb_setcoreidx (sbh, origidx);
1084 uint BCMINITFN (sb_pmu_cpu_clock) (sb_t * sbh, osl_t * osh)
1088 uint32 clock = HT_CLOCK;
1090 ASSERT (sbh->cccaps & CC_CAP_PMU);
1092 /* Remember original core before switch to chipc */
1093 origidx = sb_coreidx (sbh);
1094 cc = sb_setcore (sbh, SB_CC, 0);
1099 case BCM4328_CHIP_ID:
1100 clock = sb_pmu0_cpuclk0 (sbh, osh, cc);
1102 case BCM5354_CHIP_ID:
1103 clock = sb_pmu0_cpuclk0 (sbh, osh, cc);
1105 case BCM4325_CHIP_ID:
1106 clock = sb_pmu1_cpuclk0 (sbh, osh, cc);
1108 case BCM4312_CHIP_ID:
1109 clock = sb_pmu1_cpuclk0 (sbh, osh, cc);
1112 PMU_MSG (("No CPU clock specified "
1113 "for chip %x rev %d pmurev %d, using default %d Hz\n",
1114 sbh->chip, sbh->chiprev, sbh->pmurev, clock));
1118 /* Return to original core */
1119 sb_setcoreidx (sbh, origidx);
1123 void BCMINITFN (sb_pmu_init) (sb_t * sbh, osl_t * osh)
1128 ASSERT (sbh->cccaps & CC_CAP_PMU);
1130 /* Remember original core before switch to chipc */
1131 origidx = sb_coreidx (sbh);
1132 cc = sb_setcore (sbh, SB_CC, 0);
1135 if (sbh->pmurev >= 1)
1137 if (sbh->chip == BCM4325_CHIP_ID && sbh->chiprev <= 1)
1138 AND_REG (osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
1140 OR_REG (osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT);
1143 /* Return to original core */
1144 sb_setcoreidx (sbh, origidx);
1147 void BCMINITFN (sb_pmu_otp_power) (sb_t * sbh, osl_t * osh, bool on)
1152 ASSERT (sbh->cccaps & CC_CAP_PMU);
1154 /* Remember original core before switch to chipc */
1155 origidx = sb_coreidx (sbh);
1156 cc = sb_setcore (sbh, SB_CC, 0);
1161 case BCM4325_CHIP_ID:
1164 OR_REG (osh, &cc->min_res_mask, PMURES_BIT (RES4325_LNLDO2_PU));
1165 if (sbh->boardflags & BFL_BUCKBOOST)
1166 AND_REG (osh, &cc->min_res_mask,
1167 ~PMURES_BIT (RES4325_BUCK_BOOST_PWM));
1172 if (sbh->boardflags & BFL_BUCKBOOST)
1173 OR_REG (osh, &cc->min_res_mask,
1174 PMURES_BIT (RES4325_BUCK_BOOST_PWM));
1175 AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4325_LNLDO2_PU));
1182 /* Return to original core */
1183 sb_setcoreidx (sbh, origidx);
1187 sb_pmu_rcal (sb_t * sbh, osl_t * osh)
1192 ASSERT (sbh->cccaps & CC_CAP_PMU);
1194 /* Remember original core before switch to chipc */
1195 origidx = sb_coreidx (sbh);
1196 cc = sb_setcore (sbh, SB_CC, 0);
1201 case BCM4325_CHIP_ID:
1207 W_REG (osh, &cc->chipcontrol_addr, 1);
1208 AND_REG (osh, &cc->chipcontrol_data, ~0x04);
1209 OR_REG (osh, &cc->chipcontrol_data, 0x04);
1211 /* Wait for completion */
1212 SPINWAIT (0 == (R_REG (osh, &cc->chipstatus) & 0x08),
1214 ASSERT (R_REG (osh, &cc->chipstatus) & 0x08);
1216 /* Drop the LSB to convert from 5 bit code to 4 bit code */
1217 rcal_code = (uint8) (R_REG (osh, &cc->chipstatus) >> 5) & 0x0f;
1218 PMU_MSG (("RCal completed, status 0x%x, code 0x%x\n",
1219 R_REG (osh, &cc->chipstatus), rcal_code));
1221 /* Write RCal code into pmu_vreg_ctrl[32:29] */
1222 W_REG (osh, &cc->regcontrol_addr, 0);
1223 val = R_REG (osh, &cc->regcontrol_data) & ~((uint32) 0x07 << 29);
1224 val |= (uint32) (rcal_code & 0x07) << 29;
1225 W_REG (osh, &cc->regcontrol_data, val);
1226 W_REG (osh, &cc->regcontrol_addr, 1);
1227 val = R_REG (osh, &cc->regcontrol_data) & ~(uint32) 0x01;
1228 val |= (uint32) ((rcal_code >> 3) & 0x01);
1229 W_REG (osh, &cc->regcontrol_data, val);
1231 /* Write RCal code into pmu_chip_ctrl[33:30] */
1232 W_REG (osh, &cc->chipcontrol_addr, 0);
1233 val = R_REG (osh, &cc->chipcontrol_data) & ~((uint32) 0x03 << 30);
1234 val |= (uint32) (rcal_code & 0x03) << 30;
1235 W_REG (osh, &cc->chipcontrol_data, val);
1236 W_REG (osh, &cc->chipcontrol_addr, 1);
1237 val = R_REG (osh, &cc->chipcontrol_data) & ~(uint32) 0x03;
1238 val |= (uint32) ((rcal_code >> 2) & 0x03);
1239 W_REG (osh, &cc->chipcontrol_data, val);
1241 /* Set override in pmu_chip_ctrl[29] */
1242 W_REG (osh, &cc->chipcontrol_addr, 0);
1243 OR_REG (osh, &cc->chipcontrol_data, (0x01 << 29));
1245 /* Power off RCal block */
1246 W_REG (osh, &cc->chipcontrol_addr, 1);
1247 AND_REG (osh, &cc->chipcontrol_data, ~0x04);
1255 /* Return to original core */
1256 sb_setcoreidx (sbh, origidx);