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.
24 #define PMU_ERROR(args)
27 #define PMU_MSG(args) printf args
33 /* PMU rev 0 pll control for BCM4328 and BCM5354 */
34 static void sb_pmu0_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
36 static uint32 sb_pmu0_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
37 static uint32 sb_pmu0_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
38 /* PMU rev 0 pll control for BCM4325 BCM4329 */
39 static void sb_pmu1_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
41 static uint32 sb_pmu1_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
42 static uint32 sb_pmu1_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
44 /* Setup switcher voltage */
46 BCMINITFN (sb_pmu_set_switcher_voltage) (sb_t * sbh, osl_t * osh,
47 uint8 bb_voltage, uint8 rf_voltage)
52 ASSERT (sbh->cccaps & CC_CAP_PMU);
54 /* Remember original core before switch to chipc */
55 origidx = sb_coreidx (sbh);
56 cc = sb_setcore (sbh, SB_CC, 0);
59 W_REG (osh, &cc->regcontrol_addr, 0x01);
60 W_REG (osh, &cc->regcontrol_data, (uint32) (bb_voltage & 0x1f) << 22);
62 W_REG (osh, &cc->regcontrol_addr, 0x00);
63 W_REG (osh, &cc->regcontrol_data, (uint32) (rf_voltage & 0x1f) << 14);
65 /* Return to original core */
66 sb_setcoreidx (sbh, origidx);
70 sb_pmu_set_ldo_voltage (sb_t * sbh, osl_t * osh, uint8 ldo, uint8 voltage)
72 uint8 sr_cntl_shift, rc_shift, shift, mask;
75 ASSERT (sbh->cccaps & CC_CAP_PMU);
83 case SET_LDO_VOLTAGE_LDO1:
89 case SET_LDO_VOLTAGE_LDO2:
95 case SET_LDO_VOLTAGE_LDO3:
101 case SET_LDO_VOLTAGE_PAREF:
112 case BCM4312_CHIP_ID:
115 case SET_LDO_VOLTAGE_PAREF:
131 shift = sr_cntl_shift + rc_shift;
133 sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_addr),
135 sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_data),
136 mask << shift, (voltage & mask) << shift);
140 sb_pmu_paref_ldo_enable (sb_t * sbh, osl_t * osh, bool enable)
144 ASSERT (sbh->cccaps & CC_CAP_PMU);
148 case BCM4328_CHIP_ID:
149 ldo = RES4328_PA_REF_LDO;
151 case BCM5354_CHIP_ID:
152 ldo = RES5354_PA_REF_LDO;
154 case BCM4312_CHIP_ID:
155 ldo = RES4312_PA_REF_LDO;
161 sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, min_res_mask),
162 PMURES_BIT (ldo), enable ? PMURES_BIT (ldo) : 0);
165 uint16 BCMINITFN (sb_pmu_fast_pwrup_delay) (sb_t * sbh, osl_t * osh)
167 uint16 delay = PMU_MAX_TRANSITION_DLY;
169 ASSERT (sbh->cccaps & CC_CAP_PMU);
173 case BCM4328_CHIP_ID:
177 case BCM4325_CHIP_ID:
178 case BCM4312_CHIP_ID:
187 PMU_MSG (("No PMU fast power up delay specified "
188 "for chip %x rev %d, using default %d us\n",
189 sbh->chip, sbh->chiprev, delay));
196 uint32 BCMINITFN (sb_pmu_force_ilp) (sb_t * sbh, osl_t * osh, bool force)
200 uint32 oldpmucontrol;
202 ASSERT (sbh->cccaps & CC_CAP_PMU);
204 /* Remember original core before switch to chipc */
205 origidx = sb_coreidx (sbh);
206 cc = sb_setcore (sbh, SB_CC, 0);
209 oldpmucontrol = R_REG (osh, &cc->pmucontrol);
211 W_REG (osh, &cc->pmucontrol, oldpmucontrol &
212 ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
214 W_REG (osh, &cc->pmucontrol, oldpmucontrol |
215 (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
217 /* Return to original core */
218 sb_setcoreidx (sbh, origidx);
220 return oldpmucontrol;
223 /* Setup min/max resources and up/down timers */
233 int8 action; /* 0 - set, 1 - add, -1 - remove */
237 static const pmu_res_updown_t
238 BCMINITDATA (bcm4328a0_res_updown)[] =
241 RES4328_EXT_SWITCHER_PWM, 0x0101},
243 RES4328_BB_SWITCHER_PWM, 0x1f01},
245 RES4328_BB_SWITCHER_BURST, 0x010f},
247 RES4328_BB_EXT_SWITCHER_BURST, 0x0101},
249 RES4328_ILP_REQUEST, 0x0202},
251 RES4328_RADIO_SWITCHER_PWM, 0x0f01},
253 RES4328_RADIO_SWITCHER_BURST, 0x0f01},
255 RES4328_ROM_SWITCH, 0x0101},
257 RES4328_PA_REF_LDO, 0x0f01},
259 RES4328_RADIO_LDO, 0x0f01},
261 RES4328_AFE_LDO, 0x0f01},
263 RES4328_PLL_LDO, 0x0f01},
265 RES4328_BG_FILTBYP, 0x0101},
267 RES4328_TX_FILTBYP, 0x0101},
269 RES4328_RX_FILTBYP, 0x0101},
271 RES4328_XTAL_PU, 0x0101},
273 RES4328_XTAL_EN, 0xa001},
275 RES4328_BB_PLL_FILTBYP, 0x0101},
277 RES4328_RF_PLL_FILTBYP, 0x0101},
279 RES4328_BB_PLL_PU, 0x0701}
282 static const pmu_res_depend_t
283 BCMINITDATA (bcm4328a0_res_depend)[] =
285 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
287 RES4328_ILP_REQUEST, 0,
288 PMURES_BIT (RES4328_EXT_SWITCHER_PWM) |
289 PMURES_BIT (RES4328_BB_SWITCHER_PWM)}
292 #ifdef BCMQT /* for power save on slow QT/small beacon interval */
293 static const pmu_res_updown_t
294 BCMINITDATA (bcm4325a0_res_updown_qt)[] =
297 RES4325_HT_AVAIL, 0x0300},
299 RES4325_BBPLL_PWRSW_PU, 0x0101},
301 RES4325_RFPLL_PWRSW_PU, 0x0101},
303 RES4325_ALP_AVAIL, 0x0100},
305 RES4325_XTAL_PU, 0x1000},
307 RES4325_LNLDO1_PU, 0x0800},
309 RES4325_CLDO_CBUCK_PWM, 0x0101},
311 RES4325_CBUCK_PWM, 0x0803}
314 static const pmu_res_updown_t
315 BCMINITDATA (bcm4325a0_res_updown)[] =
318 RES4325_XTAL_PU, 0x1501}
322 static const pmu_res_depend_t
323 BCMINITDATA (bcm4325a0_res_depend)[] =
325 /* Adjust HT Avail resource dependencies */
328 PMURES_BIT (RES4325_RX_PWRSW_PU) | PMURES_BIT (RES4325_TX_PWRSW_PU) |
329 PMURES_BIT (RES4325_LOGEN_PWRSW_PU) | PMURES_BIT (RES4325_AFE_PWRSW_PU)}
332 void BCMINITFN (sb_pmu_res_init) (sb_t * sbh, osl_t * osh)
336 const pmu_res_updown_t *pmu_res_updown_table = NULL;
337 int pmu_res_updown_table_sz = 0;
338 const pmu_res_depend_t *pmu_res_depend_table = NULL;
339 int pmu_res_depend_table_sz = 0;
340 uint32 min_mask = 0, max_mask = 0;
342 ASSERT (sbh->cccaps & CC_CAP_PMU);
344 /* Remember original core before switch to chipc */
345 origidx = sb_coreidx (sbh);
346 cc = sb_setcore (sbh, SB_CC, 0);
351 case BCM4328_CHIP_ID:
352 /* Down to ILP request excluding ROM */
353 min_mask = PMURES_BIT (RES4328_EXT_SWITCHER_PWM) |
354 PMURES_BIT (RES4328_BB_SWITCHER_PWM) | PMURES_BIT (RES4328_XTAL_EN);
357 min_mask |= PMURES_BIT (RES4328_ROM_SWITCH);
359 /* Allow (but don't require) PLL to turn on */
361 pmu_res_updown_table = bcm4328a0_res_updown;
362 pmu_res_updown_table_sz = ARRAYSIZE (bcm4328a0_res_updown);
363 pmu_res_depend_table = bcm4328a0_res_depend;
364 pmu_res_depend_table_sz = ARRAYSIZE (bcm4328a0_res_depend);
366 case BCM4312_CHIP_ID:
368 * min_mask = 0xcbb; max_mask = 0x7ffff;
369 * pmu_res_updown_table_sz = 0;
370 * pmu_res_depend_table_sz = 0;
373 case BCM5354_CHIP_ID:
374 /* Allow (but don't require) PLL to turn on */
378 case BCM4325_CHIP_ID:
379 /* Leave OTP powered up and power it down later. */
381 PMURES_BIT (RES4325_CBUCK_BURST) | PMURES_BIT (RES4325_LNLDO2_PU);
382 if (((sbh->chipst & CST4325_PMUTOP_2B_MASK) >>
383 CST4325_PMUTOP_2B_SHIFT) == 1)
384 min_mask |= PMURES_BIT (RES4325_CLDO_CBUCK_BURST);
385 /* Allow (but don't require) PLL to turn on */
388 pmu_res_updown_table = bcm4325a0_res_updown_qt;
389 pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown_qt);
391 pmu_res_updown_table = bcm4325a0_res_updown;
392 pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown);
393 pmu_res_depend_table = bcm4325a0_res_depend;
394 pmu_res_depend_table_sz = ARRAYSIZE (bcm4325a0_res_depend);
402 /* Program up/down timers */
403 while (pmu_res_updown_table_sz--)
405 ASSERT (pmu_res_updown_table);
406 W_REG (osh, &cc->res_table_sel,
407 pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
408 W_REG (osh, &cc->res_updn_timer,
409 pmu_res_updown_table[pmu_res_updown_table_sz].updown);
412 /* Program resource dependencies table */
413 while (pmu_res_depend_table_sz--)
415 ASSERT (pmu_res_depend_table);
416 W_REG (osh, &cc->res_table_sel,
417 pmu_res_depend_table[pmu_res_depend_table_sz].resnum);
418 switch (pmu_res_depend_table[pmu_res_depend_table_sz].action)
421 W_REG (osh, &cc->res_dep_mask,
422 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
425 OR_REG (osh, &cc->res_dep_mask,
426 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
429 AND_REG (osh, &cc->res_dep_mask,
430 ~pmu_res_depend_table[pmu_res_depend_table_sz].
439 /* program min resource mask */
442 PMU_MSG (("Changing min_res_mask to 0x%x\n", min_mask));
443 W_REG (osh, &cc->min_res_mask, min_mask);
445 /* program max resource mask */
448 PMU_MSG (("Changing max_res_mask to 0x%x\n", max_mask));
449 W_REG (osh, &cc->max_res_mask, max_mask);
452 /* Return to original core */
453 sb_setcoreidx (sbh, origidx);
456 /* setup pll and query clock speed */
465 /* the following table is based on 880Mhz Fvco */
466 #define PMU0_PLL0_FVCO 880000 /* Fvco 880Mhz */
467 static const pmu0_xtaltab0_t
468 BCMINITDATA (pmu0_xtaltab0)[] =
471 12000, 1, 73, 349525},
473 13000, 2, 67, 725937},
475 14400, 3, 61, 116508},
477 15360, 4, 57, 305834},
479 16200, 5, 54, 336579},
481 16800, 6, 52, 399457},
483 19200, 7, 45, 873813},
485 19800, 8, 44, 466033},
489 25000, 10, 70, 419430},
491 26000, 11, 67, 725937},
493 30000, 12, 58, 699050},
495 38400, 13, 45, 873813},
503 #define PMU0_XTAL0_DEFAULT 11
505 #define PMU0_XTAL0_DEFAULT 8
510 * Set new backplane PLL clock frequency
512 static void BCMINITFN (sb_pmu0_sbclk4328) (sb_t * sbh, int freq)
514 uint32 tmp, oldmax, oldmin, origidx;
517 /* Remember original core before switch to chipc */
518 origidx = sb_coreidx (sbh);
519 cc = sb_setcore (sbh, SB_CC, 0);
522 /* Set new backplane PLL clock */
523 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
524 tmp = R_REG (osh, &cc->pllcontrol_data);
525 tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK);
526 tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT;
527 W_REG (osh, &cc->pllcontrol_data, tmp);
529 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
531 oldmin = R_REG (osh, &cc->min_res_mask);
532 oldmax = R_REG (osh, &cc->max_res_mask);
533 W_REG (osh, &cc->min_res_mask, oldmin & ~PMURES_BIT (RES4328_BB_PLL_PU));
534 W_REG (osh, &cc->max_res_mask, oldmax & ~PMURES_BIT (RES4328_BB_PLL_PU));
536 /* It takes over several hundred usec to re-enable the PLL since the
537 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
539 * Be sure PLL is powered down first before re-enabling it.
542 OSL_DELAY (PLL_DELAY);
543 SPINWAIT ((R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)),
546 if (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU))
548 /* If BB_PLL not powered down yet, new backplane PLL clock
549 * may not take effect.
551 * Still early during bootup so no serial output here.
553 PMU_ERROR (("Fatal: BB_PLL not power down yet!\n"));
555 (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)));
559 W_REG (osh, &cc->max_res_mask, oldmax);
561 /* Return to original core */
562 sb_setcoreidx (sbh, origidx);
564 #endif /* BCMUSBDEV */
566 /* Set up PLL registers in the PMU as per the crystal speed.
567 * Uses xtalfreq variable, or passed-in default.
570 BCMINITFN (sb_pmu0_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
574 const pmu0_xtaltab0_t *xt;
576 if ((sb_chip (sbh) == BCM5354_CHIP_ID) && (xtal == 0))
578 /* 5354 has xtal freq of 25MHz */
582 /* Find the frequency in the table */
583 for (xt = pmu0_xtaltab0; xt->freq; xt++)
584 if (xt->freq == xtal)
587 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
589 PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf));
591 /* Check current PLL state */
592 tmp = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
596 PMU_MSG (("PLL already programmed for %d.%d MHz\n",
597 (xt->freq / 1000), (xt->freq % 1000)));
600 if (sbh->chip == BCM4328_CHIP_ID)
601 sb_pmu0_sbclk4328 (sbh, PMU0_PLL0_PC0_DIV_ARM_88MHZ);
608 PMU_MSG (("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
609 (xt->freq / 1000), (xt->freq % 1000),
610 (pmu0_xtaltab0[tmp - 1].freq / 1000),
611 (pmu0_xtaltab0[tmp - 1].freq % 1000)));
615 PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->freq / 1000),
619 /* Make sure the PLL is off */
622 case BCM4328_CHIP_ID:
623 AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU));
624 AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU));
626 case BCM5354_CHIP_ID:
627 AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU));
628 AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU));
633 SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL,
634 PMU_MAX_TRANSITION_DLY);
635 ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL));
637 PMU_MSG (("Done masking\n"));
639 /* Write PDIV in pllcontrol[0] */
640 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
641 tmp = R_REG (osh, &cc->pllcontrol_data);
642 if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ)
643 tmp |= PMU0_PLL0_PC0_PDIV_MASK;
645 tmp &= ~PMU0_PLL0_PC0_PDIV_MASK;
646 W_REG (osh, &cc->pllcontrol_data, tmp);
648 /* Write WILD in pllcontrol[1] */
649 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
650 tmp = R_REG (osh, &cc->pllcontrol_data);
652 ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) |
654 wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & PMU0_PLL0_PC1_WILD_INT_MASK)
655 | ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) &
656 PMU0_PLL0_PC1_WILD_FRAC_MASK)));
658 tmp |= PMU0_PLL0_PC1_STOP_MOD;
660 tmp &= ~PMU0_PLL0_PC1_STOP_MOD;
661 W_REG (osh, &cc->pllcontrol_data, tmp);
663 /* Write WILD in pllcontrol[2] */
664 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
665 tmp = R_REG (osh, &cc->pllcontrol_data);
666 tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) |
667 ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) &
668 PMU0_PLL0_PC2_WILD_INT_MASK));
669 W_REG (osh, &cc->pllcontrol_data, tmp);
671 PMU_MSG (("Done pll\n"));
673 /* Write XtalFreq. Set the divisor also. */
674 tmp = R_REG (osh, &cc->pmucontrol);
675 tmp = ((tmp & ~PCTL_ILP_DIV_MASK) |
676 (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
678 tmp = ((tmp & ~PCTL_XTALFREQ_MASK) |
679 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK));
680 W_REG (osh, &cc->pmucontrol, tmp);
684 BCMINITFN (sb_pmu0_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
686 const pmu0_xtaltab0_t *xt;
689 /* Find the frequency in the table */
690 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
692 for (xt = pmu0_xtaltab0; xt->freq; xt++)
696 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
698 return xt->freq * 1000;
702 BCMINITFN (sb_pmu0_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
704 const pmu0_xtaltab0_t *xt;
705 uint32 xf, tmp, divarm;
707 uint32 pdiv, wbint, wbfrac, fvco;
710 if (sb_chip (sbh) == BCM5354_CHIP_ID)
712 /* 5354 gets sb clock of 120MHz from main pll */
716 /* Find the xtal frequency in the table */
717 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
719 for (xt = pmu0_xtaltab0; xt->freq; xt++)
723 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
725 /* Read divarm from pllcontrol[0] */
726 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
727 tmp = R_REG (osh, &cc->pllcontrol_data);
728 divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT;
731 /* Calculate Fvco based on xtal freq, pdiv, and wild */
732 pdiv = tmp & PMU0_PLL0_PC0_PDIV_MASK;
734 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
735 tmp = R_REG (osh, &cc->pllcontrol_data);
737 (tmp & PMU0_PLL0_PC1_WILD_FRAC_MASK) >> PMU0_PLL0_PC1_WILD_FRAC_SHIFT;
738 wbint = (tmp & PMU0_PLL0_PC1_WILD_INT_MASK) >> PMU0_PLL0_PC1_WILD_INT_SHIFT;
740 W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
741 tmp = R_REG (osh, &cc->pllcontrol_data);
743 (tmp & PMU0_PLL0_PC2_WILD_INT_MASK) << PMU0_PLL0_PC2_WILD_INT_SHIFT;
745 fvco = (xt->freq * wbint) << 8;
746 fvco += (xt->freq * (wbfrac >> 10)) >> 2;
747 fvco += (xt->freq * (wbfrac & 0x3ff)) >> 10;
753 PMU_MSG (("sb_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
754 wbint, wbfrac, fvco));
755 ASSERT (fvco == PMU0_PLL0_FVCO);
758 /* Return ARM/SB clock */
759 return PMU0_PLL0_FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
762 /* PMU corerev 1 pll programming for BCM4325 */
763 /* setup pll and query clock speed */
774 /* the following table is based on 880Mhz Fvco */
775 #define PMU1_PLL0_FVCO 880000 /* Fvco 880Mhz */
776 static const pmu1_xtaltab0_t
777 BCMINITDATA (pmu1_xtaltab0)[] =
780 12000, 1, 3, 22, 0x9, 0xFFFFEF},
782 13000, 2, 1, 6, 0xb, 0x483483},
784 14400, 3, 1, 10, 0xa, 0x1C71C7},
786 15360, 4, 1, 5, 0xb, 0x755555},
788 16200, 5, 1, 10, 0x5, 0x6E9E06},
790 16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
792 19200, 7, 1, 9, 0x5, 0x17B425},
794 19800, 8, 1, 11, 0x4, 0xA57EB},
796 20000, 9, 1, 11, 0x4, 0x0},
798 24000, 10, 3, 11, 0xa, 0x0},
800 25000, 11, 5, 16, 0xb, 0x0},
802 26000, 12, 1, 2, 0x10, 0xEC4EC4},
804 30000, 13, 3, 8, 0xb, 0x0},
806 38400, 14, 1, 5, 0x4, 0x955555},
808 40000, 15, 1, 2, 0xb, 0},
813 /* Default to 15360Khz crystal */
814 #define PMU1_XTAL0_DEFAULT 3
817 BCMINITFN (sb_pmu1_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
819 const pmu1_xtaltab0_t *xt;
822 /* Find the frequency in the table */
823 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
825 for (xt = pmu1_xtaltab0; xt->fref; xt++)
829 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
831 return xt->fref * 1000;
834 /* Set up PLL registers in the PMU as per the crystal speed.
835 * Uses xtalfreq variable, or passed-in default.
838 BCMINITFN (sb_pmu1_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
841 const pmu1_xtaltab0_t *xt;
843 uint32 buf_strength = 0;
845 /* 4312: assume default works */
846 if (sbh->chip == BCM4312_CHIP_ID)
849 /* Find the frequency in the table */
850 for (xt = pmu1_xtaltab0; xt->fref; xt++)
851 if (xt->fref == xtal)
854 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
856 PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf));
858 /* Check current PLL state */
859 if (((R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
860 PCTL_XTALFREQ_SHIFT) == xt->xf)
862 PMU_MSG (("PLL already programmed for %d.%d MHz\n",
863 (xt->fref / 1000), (xt->fref % 1000)));
867 PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->fref / 1000),
870 /* Make sure the PLL is off */
873 case BCM4325_CHIP_ID:
874 AND_REG (osh, &cc->min_res_mask,
875 ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) |
876 PMURES_BIT (RES4325_HT_AVAIL)));
877 AND_REG (osh, &cc->max_res_mask,
878 ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) |
879 PMURES_BIT (RES4325_HT_AVAIL)));
881 /* Change the BBPLL drive strength to 2 for all channels */
882 buf_strength = 0x222222;
887 SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
888 PMU_MAX_TRANSITION_DLY);
889 ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
891 PMU_MSG (("Done masking\n"));
893 /* Write p1div and p2div to pllcontrol[0] */
894 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
895 tmp = R_REG (osh, &cc->pllcontrol_data) &
896 ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
899 p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | ((xt->
902 PMU1_PLL0_PC0_P2DIV_SHIFT)
904 PMU1_PLL0_PC0_P2DIV_MASK);
905 W_REG (osh, &cc->pllcontrol_data, tmp);
907 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
908 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
909 tmp = R_REG (osh, &cc->pllcontrol_data) &
910 ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
913 ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK)
914 | ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK);
915 W_REG (osh, &cc->pllcontrol_data, tmp);
917 /* Write ndiv_frac to pllcontrol[3] */
918 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
919 tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
920 tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
921 PMU1_PLL0_PC3_NDIV_FRAC_MASK);
922 W_REG (osh, &cc->pllcontrol_data, tmp);
926 PMU_MSG (("Adjusting PLL buffer drive strength: %x\n", buf_strength));
928 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
929 tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
930 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
931 W_REG (osh, &cc->pllcontrol_data, tmp);
934 PMU_MSG (("Done pll\n"));
936 /* Write XtalFreq. Set the divisor also. */
937 tmp = R_REG (osh, &cc->pmucontrol) &
938 ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
939 tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
941 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
942 W_REG (osh, &cc->pmucontrol, tmp);
947 BCMINITFN (sb_pmu1_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
949 const pmu1_xtaltab0_t *xt;
950 uint32 xf, tmp, m1div;
952 uint32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
955 /* Find the xtal frequency in the table */
956 xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
958 for (xt = pmu1_xtaltab0; xt->fref; xt++)
962 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
964 /* Read m1div from pllcontrol[1] */
965 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
966 tmp = R_REG (osh, &cc->pllcontrol_data);
967 m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
970 /* Read p2div/p1div from pllcontrol[0] */
971 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
972 tmp = R_REG (osh, &cc->pllcontrol_data);
973 p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
974 p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
976 /* Calculate Fvco based on xtal freq and ndiv and pdiv */
977 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
978 tmp = R_REG (osh, &cc->pllcontrol_data);
980 (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
982 W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
983 tmp = R_REG (osh, &cc->pllcontrol_data);
985 (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
987 fvco = (xt->fref * ndiv_int) << 8;
988 fvco += (xt->fref * (ndiv_frac >> 12)) >> 4;
989 fvco += (xt->fref * (ndiv_frac & 0xfff)) >> 12;
996 PMU_MSG (("sb_pmu0_cpuclk0: ndiv_int %u ndiv_frac %u "
997 "p2div %u p1div %u fvco %u\n",
998 ndiv_int, ndiv_frac, p2div, p1div, fvco));
999 ASSERT (fvco == PMU1_PLL0_FVCO);
1002 /* Return ARM/SB clock */
1003 return PMU1_PLL0_FVCO / m1div * 1000;
1006 void BCMINITFN (sb_pmu_pll_init) (sb_t * sbh, osl_t * osh, uint xtalfreq)
1011 ASSERT (sbh->cccaps & CC_CAP_PMU);
1013 /* Remember original core before switch to chipc */
1014 origidx = sb_coreidx (sbh);
1015 cc = sb_setcore (sbh, SB_CC, 0);
1020 case BCM4328_CHIP_ID:
1021 sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq);
1023 case BCM5354_CHIP_ID:
1024 sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq);
1026 case BCM4325_CHIP_ID:
1027 sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq);
1029 case BCM4312_CHIP_ID:
1030 sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq);
1033 PMU_MSG (("No PLL init done for chip %x rev %d pmurev %d\n",
1034 sbh->chip, sbh->chiprev, sbh->pmurev));
1038 /* Return to original core */
1039 sb_setcoreidx (sbh, origidx);
1042 uint32 BCMINITFN (sb_pmu_alp_clock) (sb_t * sbh, osl_t * osh)
1046 uint32 clock = ALP_CLOCK;
1048 ASSERT (sbh->cccaps & CC_CAP_PMU);
1050 /* Remember original core before switch to chipc */
1051 origidx = sb_coreidx (sbh);
1052 cc = sb_setcore (sbh, SB_CC, 0);
1057 case BCM4328_CHIP_ID:
1058 clock = sb_pmu0_alpclk0 (sbh, osh, cc);
1060 case BCM5354_CHIP_ID:
1061 clock = sb_pmu0_alpclk0 (sbh, osh, cc);
1063 case BCM4325_CHIP_ID:
1064 clock = sb_pmu1_alpclk0 (sbh, osh, cc);
1066 case BCM4312_CHIP_ID:
1067 clock = sb_pmu1_alpclk0 (sbh, osh, cc);
1069 clock = 20000 * 1000;
1072 PMU_MSG (("No ALP clock specified "
1073 "for chip %x rev %d pmurev %d, using default %d Hz\n",
1074 sbh->chip, sbh->chiprev, sbh->pmurev, clock));
1078 /* Return to original core */
1079 sb_setcoreidx (sbh, origidx);
1083 uint BCMINITFN (sb_pmu_cpu_clock) (sb_t * sbh, osl_t * osh)
1087 uint32 clock = HT_CLOCK;
1089 ASSERT (sbh->cccaps & CC_CAP_PMU);
1091 /* Remember original core before switch to chipc */
1092 origidx = sb_coreidx (sbh);
1093 cc = sb_setcore (sbh, SB_CC, 0);
1098 case BCM4328_CHIP_ID:
1099 clock = sb_pmu0_cpuclk0 (sbh, osh, cc);
1101 case BCM5354_CHIP_ID:
1102 clock = sb_pmu0_cpuclk0 (sbh, osh, cc);
1104 case BCM4325_CHIP_ID:
1105 clock = sb_pmu1_cpuclk0 (sbh, osh, cc);
1107 case BCM4312_CHIP_ID:
1108 clock = sb_pmu1_cpuclk0 (sbh, osh, cc);
1111 PMU_MSG (("No CPU clock specified "
1112 "for chip %x rev %d pmurev %d, using default %d Hz\n",
1113 sbh->chip, sbh->chiprev, sbh->pmurev, clock));
1117 /* Return to original core */
1118 sb_setcoreidx (sbh, origidx);
1122 void BCMINITFN (sb_pmu_init) (sb_t * sbh, osl_t * osh)
1127 ASSERT (sbh->cccaps & CC_CAP_PMU);
1129 /* Remember original core before switch to chipc */
1130 origidx = sb_coreidx (sbh);
1131 cc = sb_setcore (sbh, SB_CC, 0);
1134 if (sbh->pmurev >= 1)
1136 if (sbh->chip == BCM4325_CHIP_ID && sbh->chiprev <= 1)
1137 AND_REG (osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
1139 OR_REG (osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT);
1142 /* Return to original core */
1143 sb_setcoreidx (sbh, origidx);
1146 void BCMINITFN (sb_pmu_otp_power) (sb_t * sbh, osl_t * osh, bool on)
1151 ASSERT (sbh->cccaps & CC_CAP_PMU);
1153 /* Remember original core before switch to chipc */
1154 origidx = sb_coreidx (sbh);
1155 cc = sb_setcore (sbh, SB_CC, 0);
1160 case BCM4325_CHIP_ID:
1163 OR_REG (osh, &cc->min_res_mask, PMURES_BIT (RES4325_LNLDO2_PU));
1164 if (sbh->boardflags & BFL_BUCKBOOST)
1165 AND_REG (osh, &cc->min_res_mask,
1166 ~PMURES_BIT (RES4325_BUCK_BOOST_PWM));
1171 if (sbh->boardflags & BFL_BUCKBOOST)
1172 OR_REG (osh, &cc->min_res_mask,
1173 PMURES_BIT (RES4325_BUCK_BOOST_PWM));
1174 AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4325_LNLDO2_PU));
1181 /* Return to original core */
1182 sb_setcoreidx (sbh, origidx);
1186 sb_pmu_rcal (sb_t * sbh, osl_t * osh)
1191 ASSERT (sbh->cccaps & CC_CAP_PMU);
1193 /* Remember original core before switch to chipc */
1194 origidx = sb_coreidx (sbh);
1195 cc = sb_setcore (sbh, SB_CC, 0);
1200 case BCM4325_CHIP_ID:
1206 W_REG (osh, &cc->chipcontrol_addr, 1);
1207 AND_REG (osh, &cc->chipcontrol_data, ~0x04);
1208 OR_REG (osh, &cc->chipcontrol_data, 0x04);
1210 /* Wait for completion */
1211 SPINWAIT (0 == (R_REG (osh, &cc->chipstatus) & 0x08),
1213 ASSERT (R_REG (osh, &cc->chipstatus) & 0x08);
1215 /* Drop the LSB to convert from 5 bit code to 4 bit code */
1216 rcal_code = (uint8) (R_REG (osh, &cc->chipstatus) >> 5) & 0x0f;
1217 PMU_MSG (("RCal completed, status 0x%x, code 0x%x\n",
1218 R_REG (osh, &cc->chipstatus), rcal_code));
1220 /* Write RCal code into pmu_vreg_ctrl[32:29] */
1221 W_REG (osh, &cc->regcontrol_addr, 0);
1222 val = R_REG (osh, &cc->regcontrol_data) & ~((uint32) 0x07 << 29);
1223 val |= (uint32) (rcal_code & 0x07) << 29;
1224 W_REG (osh, &cc->regcontrol_data, val);
1225 W_REG (osh, &cc->regcontrol_addr, 1);
1226 val = R_REG (osh, &cc->regcontrol_data) & ~(uint32) 0x01;
1227 val |= (uint32) ((rcal_code >> 3) & 0x01);
1228 W_REG (osh, &cc->regcontrol_data, val);
1230 /* Write RCal code into pmu_chip_ctrl[33:30] */
1231 W_REG (osh, &cc->chipcontrol_addr, 0);
1232 val = R_REG (osh, &cc->chipcontrol_data) & ~((uint32) 0x03 << 30);
1233 val |= (uint32) (rcal_code & 0x03) << 30;
1234 W_REG (osh, &cc->chipcontrol_data, val);
1235 W_REG (osh, &cc->chipcontrol_addr, 1);
1236 val = R_REG (osh, &cc->chipcontrol_data) & ~(uint32) 0x03;
1237 val |= (uint32) ((rcal_code >> 2) & 0x03);
1238 W_REG (osh, &cc->chipcontrol_data, val);
1240 /* Set override in pmu_chip_ctrl[29] */
1241 W_REG (osh, &cc->chipcontrol_addr, 0);
1242 OR_REG (osh, &cc->chipcontrol_data, (0x01 << 29));
1244 /* Power off RCal block */
1245 W_REG (osh, &cc->chipcontrol_addr, 1);
1246 AND_REG (osh, &cc->chipcontrol_data, ~0x04);
1254 /* Return to original core */
1255 sb_setcoreidx (sbh, origidx);