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.
26 #define PMU_ERROR(args)
31 #if defined(CONFIG_BCM4328) || defined(CONFIG_BCM5354)
32 /* PMU rev 0 pll control for BCM4328 and BCM5354 */
33 static void sb_pmu0_pllinit0(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
);
34 static uint32
sb_pmu0_alpclk0(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
);
35 static uint32
sb_pmu0_cpuclk0(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
);
37 #if defined(CONFIG_BCM4325) || defined(CONFIG_BCM4312)
38 /* PMU rev 0 pll control for BCM4325 BCM4329 */
39 static void sb_pmu1_pllinit0(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
);
40 static uint32
sb_pmu1_cpuclk0(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
);
41 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
);
78 #if defined(CONFIG_BCM4328) || defined(CONFIG_BCM5354)
82 case SET_LDO_VOLTAGE_LDO1
:
88 case SET_LDO_VOLTAGE_LDO2
:
94 case SET_LDO_VOLTAGE_LDO3
:
100 case SET_LDO_VOLTAGE_PAREF
:
111 #endif /* defined(CONFIG_BCM4328) || defined(CONFIG_BCM5354) */
112 #if defined(CONFIG_BCM4312)
113 case BCM4312_CHIP_ID
:
115 case SET_LDO_VOLTAGE_PAREF
:
126 #endif /* defined(CONFIG_BCM4312) */
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
);
148 #if defined(CONFIG_BCM4328)
149 case BCM4328_CHIP_ID
:
150 ldo
= RES4328_PA_REF_LDO
;
152 #endif /* defined(CONFIG_BCM4328) */
153 #if defined(CONFIG_BCM5354)
154 case BCM5354_CHIP_ID
:
155 ldo
= RES5354_PA_REF_LDO
;
157 #endif /* defined(CONFIG_BCM5354) */
158 #if defined(CONFIG_BCM4312)
159 case BCM4312_CHIP_ID
:
160 ldo
= RES4312_PA_REF_LDO
;
162 #endif /* defined(CONFIG_BCM5354) */
167 sb_corereg(sbh
, SB_CC_IDX
, OFFSETOF(chipcregs_t
, min_res_mask
),
168 PMURES_BIT(ldo
), enable
? PMURES_BIT(ldo
) : 0);
172 BCMINITFN(sb_pmu_fast_pwrup_delay
)(sb_t
*sbh
, osl_t
*osh
)
174 uint16 delay
= PMU_MAX_TRANSITION_DLY
;
176 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
179 #if defined(CONFIG_BCM4328)
180 case BCM4328_CHIP_ID
:
185 #if defined(CONFIG_BCM4325) || defined(CONFIG_BCM4312)
186 case BCM4325_CHIP_ID
:
187 case BCM4312_CHIP_ID
:
194 #endif /* BCM4325 || BCM4312 */
197 PMU_MSG(("No PMU fast power up delay specified "
198 "for chip %x rev %d, using default %d us\n",
199 sbh
->chip
, sbh
->chiprev
, delay
));
207 BCMINITFN(sb_pmu_force_ilp
)(sb_t
*sbh
, osl_t
*osh
, bool force
)
211 uint32 oldpmucontrol
;
213 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
215 /* Remember original core before switch to chipc */
216 origidx
= sb_coreidx(sbh
);
217 cc
= sb_setcore(sbh
, SB_CC
, 0);
220 oldpmucontrol
= R_REG(osh
, &cc
->pmucontrol
);
222 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
&
223 ~(PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
225 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
|
226 (PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
228 /* Return to original core */
229 sb_setcoreidx(sbh
, origidx
);
231 return oldpmucontrol
;
234 /* Setup min/max resources and up/down timers */
242 int8 action
; /* 0 - set, 1 - add, -1 - remove */
246 #if defined(CONFIG_BCM4328)
247 static const pmu_res_updown_t
BCMINITDATA(bcm4328a0_res_updown
)[] = {
248 { RES4328_EXT_SWITCHER_PWM
, 0x0101 },
249 { RES4328_BB_SWITCHER_PWM
, 0x1f01 },
250 { RES4328_BB_SWITCHER_BURST
, 0x010f },
251 { RES4328_BB_EXT_SWITCHER_BURST
, 0x0101 },
252 { RES4328_ILP_REQUEST
, 0x0202 },
253 { RES4328_RADIO_SWITCHER_PWM
, 0x0f01 },
254 { RES4328_RADIO_SWITCHER_BURST
, 0x0f01 },
255 { RES4328_ROM_SWITCH
, 0x0101 },
256 { RES4328_PA_REF_LDO
, 0x0f01 },
257 { RES4328_RADIO_LDO
, 0x0f01 },
258 { RES4328_AFE_LDO
, 0x0f01 },
259 { RES4328_PLL_LDO
, 0x0f01 },
260 { RES4328_BG_FILTBYP
, 0x0101 },
261 { RES4328_TX_FILTBYP
, 0x0101 },
262 { RES4328_RX_FILTBYP
, 0x0101 },
263 { RES4328_XTAL_PU
, 0x0101 },
264 { RES4328_XTAL_EN
, 0xa001 },
265 { RES4328_BB_PLL_FILTBYP
, 0x0101 },
266 { RES4328_RF_PLL_FILTBYP
, 0x0101 },
267 { RES4328_BB_PLL_PU
, 0x0701 }
270 static const pmu_res_depend_t
BCMINITDATA(bcm4328a0_res_depend
)[] = {
271 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
273 RES4328_ILP_REQUEST
, 0,
274 PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) |
275 PMURES_BIT(RES4328_BB_SWITCHER_PWM
)
280 #if defined(CONFIG_BCM4325)
281 #ifdef BCMQT /* for power save on slow QT/small beacon interval */
282 static const pmu_res_updown_t
BCMINITDATA(bcm4325a0_res_updown_qt
)[] = {
283 { RES4325_HT_AVAIL
, 0x0300 },
284 { RES4325_BBPLL_PWRSW_PU
, 0x0101 },
285 { RES4325_RFPLL_PWRSW_PU
, 0x0101 },
286 { RES4325_ALP_AVAIL
, 0x0100 },
287 { RES4325_XTAL_PU
, 0x1000 },
288 { RES4325_LNLDO1_PU
, 0x0800 },
289 { RES4325_CLDO_CBUCK_PWM
, 0x0101 },
290 { RES4325_CBUCK_PWM
, 0x0803 }
293 static const pmu_res_updown_t
BCMINITDATA(bcm4325a0_res_updown
)[] = {
294 { RES4325_XTAL_PU
, 0x1501 }
298 static const pmu_res_depend_t
BCMINITDATA(bcm4325a0_res_depend
)[] = {
299 /* Adjust HT Avail resource dependencies */
302 PMURES_BIT(RES4325_RX_PWRSW_PU
) | PMURES_BIT(RES4325_TX_PWRSW_PU
) |
303 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
)
309 BCMINITFN(sb_pmu_res_init
)(sb_t
*sbh
, osl_t
*osh
)
313 const pmu_res_updown_t
*pmu_res_updown_table
= NULL
;
314 int pmu_res_updown_table_sz
= 0;
315 const pmu_res_depend_t
*pmu_res_depend_table
= NULL
;
316 int pmu_res_depend_table_sz
= 0;
317 uint32 min_mask
= 0, max_mask
= 0;
319 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
321 /* Remember original core before switch to chipc */
322 origidx
= sb_coreidx(sbh
);
323 cc
= sb_setcore(sbh
, SB_CC
, 0);
327 #if defined(CONFIG_BCM4328)
328 case BCM4328_CHIP_ID
:
329 /* Down to ILP request excluding ROM */
330 min_mask
= PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) |
331 PMURES_BIT(RES4328_BB_SWITCHER_PWM
) |
332 PMURES_BIT(RES4328_XTAL_EN
);
335 min_mask
|= PMURES_BIT(RES4328_ROM_SWITCH
);
337 /* Allow (but don't require) PLL to turn on */
339 pmu_res_updown_table
= bcm4328a0_res_updown
;
340 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4328a0_res_updown
);
341 pmu_res_depend_table
= bcm4328a0_res_depend
;
342 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4328a0_res_depend
);
345 #if defined(CONFIG_BCM4312)
346 case BCM4312_CHIP_ID
:
348 * min_mask = 0xcbb; max_mask = 0x7ffff;
349 * pmu_res_updown_table_sz = 0;
350 * pmu_res_depend_table_sz = 0;
354 #if defined(CONFIG_BCM5354)
355 case BCM5354_CHIP_ID
:
356 /* Allow (but don't require) PLL to turn on */
361 #if defined(CONFIG_BCM4325)
362 case BCM4325_CHIP_ID
:
363 /* Leave OTP powered up and power it down later. */
365 PMURES_BIT(RES4325_CBUCK_BURST
) |
366 PMURES_BIT(RES4325_LNLDO2_PU
);
367 if (((sbh
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
368 CST4325_PMUTOP_2B_SHIFT
) == 1)
369 min_mask
|= PMURES_BIT(RES4325_CLDO_CBUCK_BURST
);
370 /* Allow (but don't require) PLL to turn on */
373 pmu_res_updown_table
= bcm4325a0_res_updown_qt
;
374 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown_qt
);
376 pmu_res_updown_table
= bcm4325a0_res_updown
;
377 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown
);
378 pmu_res_depend_table
= bcm4325a0_res_depend
;
379 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4325a0_res_depend
);
388 /* Program up/down timers */
389 while (pmu_res_updown_table_sz
--) {
390 ASSERT(pmu_res_updown_table
);
391 W_REG(osh
, &cc
->res_table_sel
,
392 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
);
393 W_REG(osh
, &cc
->res_updn_timer
,
394 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
);
397 /* Program resource dependencies table */
398 while (pmu_res_depend_table_sz
--) {
399 ASSERT(pmu_res_depend_table
);
400 W_REG(osh
, &cc
->res_table_sel
,
401 pmu_res_depend_table
[pmu_res_depend_table_sz
].resnum
);
402 switch (pmu_res_depend_table
[pmu_res_depend_table_sz
].action
) {
404 W_REG(osh
, &cc
->res_dep_mask
,
405 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
408 OR_REG(osh
, &cc
->res_dep_mask
,
409 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
412 AND_REG(osh
, &cc
->res_dep_mask
,
413 ~pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
421 /* program min resource mask */
423 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask
));
424 W_REG(osh
, &cc
->min_res_mask
, min_mask
);
426 /* program max resource mask */
428 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask
));
429 W_REG(osh
, &cc
->max_res_mask
, max_mask
);
432 /* Return to original core */
433 sb_setcoreidx(sbh
, origidx
);
436 #if defined(CONFIG_BCM4328) || defined(CONFIG_BCM5354)
437 /* setup pll and query clock speed */
445 /* the following table is based on 880Mhz Fvco */
446 #define PMU0_PLL0_FVCO 880000 /* Fvco 880Mhz */
447 static const pmu0_xtaltab0_t
BCMINITDATA(pmu0_xtaltab0
)[] = {
448 { 12000, 1, 73, 349525 },
449 { 13000, 2, 67, 725937 },
450 { 14400, 3, 61, 116508 },
451 { 15360, 4, 57, 305834 },
452 { 16200, 5, 54, 336579 },
453 { 16800, 6, 52, 399457 },
454 { 19200, 7, 45, 873813 },
455 { 19800, 8, 44, 466033 },
457 { 25000, 10, 70, 419430 },
458 { 26000, 11, 67, 725937 },
459 { 30000, 12, 58, 699050 },
460 { 38400, 13, 45, 873813 },
461 { 40000, 14, 45, 0 },
466 #define PMU0_XTAL0_DEFAULT 11
468 #define PMU0_XTAL0_DEFAULT 8
471 #if defined(CONFIG_BCM4328)
474 * Set new backplane PLL clock frequency
477 BCMINITFN(sb_pmu0_sbclk4328
)(sb_t
*sbh
, int freq
)
479 uint32 tmp
, oldmax
, oldmin
, origidx
;
482 /* Remember original core before switch to chipc */
483 origidx
= sb_coreidx(sbh
);
484 cc
= sb_setcore(sbh
, SB_CC
, 0);
487 /* Set new backplane PLL clock */
488 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
489 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
490 tmp
&= ~(PMU0_PLL0_PC0_DIV_ARM_MASK
);
491 tmp
|= freq
<< PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
492 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
494 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
496 oldmin
= R_REG(osh
, &cc
->min_res_mask
);
497 oldmax
= R_REG(osh
, &cc
->max_res_mask
);
498 W_REG(osh
, &cc
->min_res_mask
, oldmin
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
499 W_REG(osh
, &cc
->max_res_mask
, oldmax
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
501 /* It takes over several hundred usec to re-enable the PLL since the
502 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
504 * Be sure PLL is powered down first before re-enabling it.
507 OSL_DELAY(PLL_DELAY
);
508 SPINWAIT((R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)), PLL_DELAY
*3);
510 if (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)) {
511 /* If BB_PLL not powered down yet, new backplane PLL clock
512 * may not take effect.
514 * Still early during bootup so no serial output here.
516 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n"));
517 ASSERT(!(R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)));
521 W_REG(osh
, &cc
->max_res_mask
, oldmax
);
523 /* Return to original core */
524 sb_setcoreidx(sbh
, origidx
);
526 #endif /* BCMUSBDEV */
529 /* Set up PLL registers in the PMU as per the crystal speed.
530 * Uses xtalfreq variable, or passed-in default.
533 BCMINITFN(sb_pmu0_pllinit0
)(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
536 const pmu0_xtaltab0_t
*xt
;
538 if ((sb_chip(sbh
) == BCM5354_CHIP_ID
) && (xtal
== 0)) {
539 /* 5354 has xtal freq of 25MHz */
543 /* Find the frequency in the table */
544 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
545 if (xt
->freq
== xtal
)
548 xt
= &pmu0_xtaltab0
[PMU0_XTAL0_DEFAULT
];
550 PMU_MSG(("XTAL %d (%d)\n", xtal
, xt
->xf
));
552 /* Check current PLL state */
553 tmp
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
556 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
557 (xt
->freq
/ 1000), (xt
->freq
% 1000)));
559 #if defined(CONFIG_BCM4328)
561 if (sbh
->chip
== BCM4328_CHIP_ID
)
562 sb_pmu0_sbclk4328(sbh
, PMU0_PLL0_PC0_DIV_ARM_88MHZ
);
569 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
570 (xt
->freq
/ 1000), (xt
->freq
% 1000),
571 (pmu0_xtaltab0
[tmp
-1].freq
/ 1000), (pmu0_xtaltab0
[tmp
-1].freq
% 1000)));
573 PMU_MSG(("Programming PLL for %d.%d MHz\n", (xt
->freq
/ 1000),
577 /* Make sure the PLL is off */
579 #if defined(CONFIG_BCM4328)
580 case BCM4328_CHIP_ID
:
581 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
582 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
585 #if defined(CONFIG_BCM5354)
586 case BCM5354_CHIP_ID
:
587 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
588 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
594 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
,
595 PMU_MAX_TRANSITION_DLY
);
596 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
));
598 PMU_MSG(("Done masking\n"));
600 /* Write PDIV in pllcontrol[0] */
601 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
602 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
603 if (xt
->freq
>= PMU0_PLL0_PC0_PDIV_FREQ
)
604 tmp
|= PMU0_PLL0_PC0_PDIV_MASK
;
606 tmp
&= ~PMU0_PLL0_PC0_PDIV_MASK
;
607 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
609 /* Write WILD in pllcontrol[1] */
610 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL1
);
611 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
612 tmp
= ((tmp
& ~(PMU0_PLL0_PC1_WILD_INT_MASK
| PMU0_PLL0_PC1_WILD_FRAC_MASK
)) |
613 (((xt
->wbint
<< PMU0_PLL0_PC1_WILD_INT_SHIFT
) &
614 PMU0_PLL0_PC1_WILD_INT_MASK
) |
615 ((xt
->wbfrac
<< PMU0_PLL0_PC1_WILD_FRAC_SHIFT
) &
616 PMU0_PLL0_PC1_WILD_FRAC_MASK
)));
618 tmp
|= PMU0_PLL0_PC1_STOP_MOD
;
620 tmp
&= ~PMU0_PLL0_PC1_STOP_MOD
;
621 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
623 /* Write WILD in pllcontrol[2] */
624 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL2
);
625 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
626 tmp
= ((tmp
& ~PMU0_PLL0_PC2_WILD_INT_MASK
) |
627 ((xt
->wbint
>> PMU0_PLL0_PC2_WILD_INT_SHIFT
) &
628 PMU0_PLL0_PC2_WILD_INT_MASK
));
629 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
631 PMU_MSG(("Done pll\n"));
633 /* Write XtalFreq. Set the divisor also. */
634 tmp
= R_REG(osh
, &cc
->pmucontrol
);
635 tmp
= ((tmp
& ~PCTL_ILP_DIV_MASK
) |
636 (((((xt
->freq
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) &
638 tmp
= ((tmp
& ~PCTL_XTALFREQ_MASK
) |
639 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
));
640 W_REG(osh
, &cc
->pmucontrol
, tmp
);
644 BCMINITFN(sb_pmu0_alpclk0
)(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
)
646 const pmu0_xtaltab0_t
*xt
;
649 /* Find the frequency in the table */
650 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
652 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
656 xt
= &pmu0_xtaltab0
[PMU0_XTAL0_DEFAULT
];
658 return xt
->freq
* 1000;
662 BCMINITFN(sb_pmu0_cpuclk0
)(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
)
664 const pmu0_xtaltab0_t
*xt
;
665 uint32 xf
, tmp
, divarm
;
667 if (sb_chip(sbh
) == BCM5354_CHIP_ID
) {
668 /* 5354 gets sb clock of 120MHz from main pll */
672 /* Find the xtal frequency in the table */
673 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
675 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
679 xt
= &pmu0_xtaltab0
[PMU0_XTAL0_DEFAULT
];
681 /* Read divarm from pllcontrol[0] */
682 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
683 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
684 divarm
= (tmp
& PMU0_PLL0_PC0_DIV_ARM_MASK
) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
687 /* Return ARM/SB clock */
688 return PMU0_PLL0_FVCO
/ (divarm
+ PMU0_PLL0_PC0_DIV_ARM_BASE
) * 1000;
690 #endif /* BCM4328 || BCM5354 */
692 /* PMU corerev 1 pll programming for BCM4325 */
693 #if defined(CONFIG_BCM4325) || defined(CONFIG_BCM4312)
694 /* setup pll and query clock speed */
704 /* the following table is based on 880Mhz Fvco */
705 #define PMU1_PLL0_FVCO 880000 /* Fvco 880Mhz */
706 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0
)[] = {
707 {12000, 1, 3, 22, 0x9, 0xFFFFEF},
708 {13000, 2, 1, 6, 0xb, 0x483483},
709 {14400, 3, 1, 10, 0xa, 0x1C71C7},
710 {15360, 4, 1, 5, 0xb, 0x755555},
711 {16200, 5, 1, 10, 0x5, 0x6E9E06},
712 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
713 {19200, 7, 1, 9, 0x5, 0x17B425},
714 {19800, 8, 1, 11, 0x4, 0xA57EB},
715 {20000, 9, 1, 11, 0x4, 0x0},
716 {24000, 10, 3, 11, 0xa, 0x0},
717 {25000, 11, 5, 16, 0xb, 0x0},
718 {26000, 12, 1, 2, 0x10, 0xEC4EC4},
719 {30000, 13, 3, 8, 0xb, 0x0},
720 {38400, 14, 1, 5, 0x4, 0x955555},
721 {40000, 15, 1, 2, 0xb, 0},
725 /* Default to 15360Khz crystal */
726 #define PMU1_XTAL0_DEFAULT 3
729 BCMINITFN(sb_pmu1_alpclk0
)(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
)
731 const pmu1_xtaltab0_t
*xt
;
734 /* Find the frequency in the table */
735 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
737 for (xt
= pmu1_xtaltab0
; xt
->fref
; xt
++)
741 xt
= &pmu1_xtaltab0
[PMU1_XTAL0_DEFAULT
];
743 return xt
->fref
* 1000;
746 /* Set up PLL registers in the PMU as per the crystal speed.
747 * Uses xtalfreq variable, or passed-in default.
750 BCMINITFN(sb_pmu1_pllinit0
)(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
752 const pmu1_xtaltab0_t
*xt
;
754 uint32 buf_strength
= 0;
756 /* 4312: assume default works */
757 if (sbh
->chip
== BCM4312_CHIP_ID
)
760 /* Find the frequency in the table */
761 for (xt
= pmu1_xtaltab0
; xt
->fref
; xt
++)
762 if (xt
->fref
== xtal
)
765 xt
= &pmu1_xtaltab0
[PMU1_XTAL0_DEFAULT
];
767 PMU_MSG(("XTAL %d (%d)\n", xtal
, xt
->xf
));
769 /* Check current PLL state */
770 if (((R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
771 PCTL_XTALFREQ_SHIFT
) == xt
->xf
) {
772 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
773 (xt
->fref
/ 1000), (xt
->fref
% 1000)));
777 PMU_MSG(("Programming PLL for %d.%d MHz\n", (xt
->fref
/ 1000),
780 /* Make sure the PLL is off */
782 #if defined(CONFIG_BCM4325)
783 case BCM4325_CHIP_ID
:
784 AND_REG(osh
, &cc
->min_res_mask
,
785 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
786 AND_REG(osh
, &cc
->max_res_mask
,
787 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
789 /* Change the BBPLL drive strength to 2 for all channels */
790 buf_strength
= 0x222222;
796 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
797 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
799 PMU_MSG(("Done masking\n"));
801 /* Write p1div and p2div to pllcontrol[0] */
802 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
803 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
804 ~(PMU1_PLL0_PC0_P1DIV_MASK
| PMU1_PLL0_PC0_P2DIV_MASK
);
805 tmp
|= ((xt
->p1div
<< PMU1_PLL0_PC0_P1DIV_SHIFT
) & PMU1_PLL0_PC0_P1DIV_MASK
) |
806 ((xt
->p2div
<< PMU1_PLL0_PC0_P2DIV_SHIFT
) & PMU1_PLL0_PC0_P2DIV_MASK
);
807 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
809 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
810 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
811 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
812 ~(PMU1_PLL0_PC2_NDIV_INT_MASK
| PMU1_PLL0_PC2_NDIV_MODE_MASK
);
813 tmp
|= ((xt
->ndiv_int
<< PMU1_PLL0_PC2_NDIV_INT_SHIFT
) & PMU1_PLL0_PC2_NDIV_INT_MASK
) |
814 ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT
) & PMU1_PLL0_PC2_NDIV_MODE_MASK
);
815 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
817 /* Write ndiv_frac to pllcontrol[3] */
818 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
819 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK
;
820 tmp
|= ((xt
->ndiv_frac
<< PMU1_PLL0_PC3_NDIV_FRAC_SHIFT
) &
821 PMU1_PLL0_PC3_NDIV_FRAC_MASK
);
822 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
825 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength
));
827 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
828 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC5_CLK_DRV_MASK
;
829 tmp
|= (buf_strength
<< PMU1_PLL0_PC5_CLK_DRV_SHIFT
);
830 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
833 PMU_MSG(("Done pll\n"));
835 /* Write XtalFreq. Set the divisor also. */
836 tmp
= R_REG(osh
, &cc
->pmucontrol
) &
837 ~(PCTL_ILP_DIV_MASK
| PCTL_XTALFREQ_MASK
);
838 tmp
|= (((((xt
->fref
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) &
840 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
);
841 W_REG(osh
, &cc
->pmucontrol
, tmp
);
846 BCMINITFN(sb_pmu1_cpuclk0
)(sb_t
*sbh
, osl_t
*osh
, chipcregs_t
*cc
)
848 const pmu1_xtaltab0_t
*xt
;
849 uint32 xf
, tmp
, m1div
;
851 /* Find the xtal frequency in the table */
852 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
854 for (xt
= pmu1_xtaltab0
; xt
->fref
; xt
++)
858 xt
= &pmu1_xtaltab0
[PMU1_XTAL0_DEFAULT
];
860 /* Read m1div from pllcontrol[1] */
861 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
862 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
863 m1div
= (tmp
& PMU1_PLL0_PC1_M1DIV_MASK
) >> PMU1_PLL0_PC1_M1DIV_SHIFT
;
866 /* Return ARM/SB clock */
867 return PMU1_PLL0_FVCO
/ m1div
* 1000;
872 BCMINITFN(sb_pmu_pll_init
)(sb_t
*sbh
, osl_t
*osh
, uint xtalfreq
)
877 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
879 /* Remember original core before switch to chipc */
880 origidx
= sb_coreidx(sbh
);
881 cc
= sb_setcore(sbh
, SB_CC
, 0);
885 #if defined(CONFIG_BCM4328)
886 case BCM4328_CHIP_ID
:
887 sb_pmu0_pllinit0(sbh
, osh
, cc
, xtalfreq
);
890 #if defined(CONFIG_BCM5354)
891 case BCM5354_CHIP_ID
:
892 sb_pmu0_pllinit0(sbh
, osh
, cc
, xtalfreq
);
895 #if defined(CONFIG_BCM4325)
896 case BCM4325_CHIP_ID
:
897 sb_pmu1_pllinit0(sbh
, osh
, cc
, xtalfreq
);
900 #if defined(CONFIG_BCM4312)
901 case BCM4312_CHIP_ID
:
902 sb_pmu1_pllinit0(sbh
, osh
, cc
, xtalfreq
);
906 PMU_MSG(("No PLL init done for chip %x rev %d pmurev %d\n",
907 sbh
->chip
, sbh
->chiprev
, sbh
->pmurev
));
911 /* Return to original core */
912 sb_setcoreidx(sbh
, origidx
);
916 BCMINITFN(sb_pmu_alp_clock
)(sb_t
*sbh
, osl_t
*osh
)
920 uint32 clock
= ALP_CLOCK
;
922 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
924 /* Remember original core before switch to chipc */
925 origidx
= sb_coreidx(sbh
);
926 cc
= sb_setcore(sbh
, SB_CC
, 0);
930 #if defined(CONFIG_BCM4328)
931 case BCM4328_CHIP_ID
:
932 clock
= sb_pmu0_alpclk0(sbh
, osh
, cc
);
935 #if defined(CONFIG_BCM5354)
936 case BCM5354_CHIP_ID
:
937 clock
= sb_pmu0_alpclk0(sbh
, osh
, cc
);
940 #if defined(CONFIG_BCM4325)
941 case BCM4325_CHIP_ID
:
942 clock
= sb_pmu1_alpclk0(sbh
, osh
, cc
);
945 #if defined(CONFIG_BCM4312)
946 case BCM4312_CHIP_ID
:
947 clock
= sb_pmu1_alpclk0(sbh
, osh
, cc
);
949 clock
= 20000 * 1000;
953 PMU_MSG(("No ALP clock specified "
954 "for chip %x rev %d pmurev %d, using default %d Hz\n",
955 sbh
->chip
, sbh
->chiprev
, sbh
->pmurev
, clock
));
959 /* Return to original core */
960 sb_setcoreidx(sbh
, origidx
);
965 BCMINITFN(sb_pmu_cpu_clock
)(sb_t
*sbh
, osl_t
*osh
)
969 uint32 clock
= HT_CLOCK
;
971 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
973 /* Remember original core before switch to chipc */
974 origidx
= sb_coreidx(sbh
);
975 cc
= sb_setcore(sbh
, SB_CC
, 0);
979 #if defined(CONFIG_BCM4328)
980 case BCM4328_CHIP_ID
:
981 clock
= sb_pmu0_cpuclk0(sbh
, osh
, cc
);
984 #if defined(CONFIG_BCM5354)
985 case BCM5354_CHIP_ID
:
986 clock
= sb_pmu0_cpuclk0(sbh
, osh
, cc
);
989 #if defined(CONFIG_BCM4325)
990 case BCM4325_CHIP_ID
:
991 clock
= sb_pmu1_cpuclk0(sbh
, osh
, cc
);
994 #if defined(CONFIG_BCM4312)
995 case BCM4312_CHIP_ID
:
996 clock
= sb_pmu1_cpuclk0(sbh
, osh
, cc
);
1000 PMU_MSG(("No CPU clock specified "
1001 "for chip %x rev %d pmurev %d, using default %d Hz\n",
1002 sbh
->chip
, sbh
->chiprev
, sbh
->pmurev
, clock
));
1006 /* Return to original core */
1007 sb_setcoreidx(sbh
, origidx
);
1012 BCMINITFN(sb_pmu_init
)(sb_t
*sbh
, osl_t
*osh
)
1017 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
1019 /* Remember original core before switch to chipc */
1020 origidx
= sb_coreidx(sbh
);
1021 cc
= sb_setcore(sbh
, SB_CC
, 0);
1024 if (sbh
->pmurev
>= 1) {
1025 #if defined(CONFIG_BCM4325)
1026 if (sbh
->chip
== BCM4325_CHIP_ID
&& sbh
->chiprev
<= 1)
1027 AND_REG(osh
, &cc
->pmucontrol
, ~PCTL_NOILP_ON_WAIT
);
1029 #endif /* BCM4325 */
1030 OR_REG(osh
, &cc
->pmucontrol
, PCTL_NOILP_ON_WAIT
);
1033 /* Return to original core */
1034 sb_setcoreidx(sbh
, origidx
);
1038 BCMINITFN(sb_pmu_otp_power
)(sb_t
*sbh
, osl_t
*osh
, bool on
)
1043 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
1045 /* Remember original core before switch to chipc */
1046 origidx
= sb_coreidx(sbh
);
1047 cc
= sb_setcore(sbh
, SB_CC
, 0);
1050 switch (sbh
->chip
) {
1051 #if defined(CONFIG_BCM4325)
1052 case BCM4325_CHIP_ID
:
1054 OR_REG(osh
, &cc
->min_res_mask
, PMURES_BIT(RES4325_LNLDO2_PU
));
1055 if (sbh
->boardflags
& BFL_BUCKBOOST
)
1056 AND_REG(osh
, &cc
->min_res_mask
,
1057 ~PMURES_BIT(RES4325_BUCK_BOOST_PWM
));
1061 if (sbh
->boardflags
& BFL_BUCKBOOST
)
1062 OR_REG(osh
, &cc
->min_res_mask
, PMURES_BIT(RES4325_BUCK_BOOST_PWM
));
1063 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES4325_LNLDO2_PU
));
1066 #endif /* BCM4325 */
1071 /* Return to original core */
1072 sb_setcoreidx(sbh
, origidx
);
1076 sb_pmu_rcal(sb_t
*sbh
, osl_t
*osh
)
1081 ASSERT(sbh
->cccaps
& CC_CAP_PMU
);
1083 /* Remember original core before switch to chipc */
1084 origidx
= sb_coreidx(sbh
);
1085 cc
= sb_setcore(sbh
, SB_CC
, 0);
1088 switch (sbh
->chip
) {
1089 #if defined(CONFIG_BCM4325)
1090 case BCM4325_CHIP_ID
:
1096 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
1097 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
1098 OR_REG(osh
, &cc
->chipcontrol_data
, 0x04);
1100 /* Wait for completion */
1101 SPINWAIT(0 == (R_REG(osh
, &cc
->chipstatus
) & 0x08), 10 * 1000 * 1000);
1102 ASSERT(R_REG(osh
, &cc
->chipstatus
) & 0x08);
1104 /* Drop the LSB to convert from 5 bit code to 4 bit code */
1105 rcal_code
= (uint8
)(R_REG(osh
, &cc
->chipstatus
) >> 5) & 0x0f;
1106 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
1107 R_REG(osh
, &cc
->chipstatus
), rcal_code
));
1109 /* Write RCal code into pmu_vreg_ctrl[32:29] */
1110 W_REG(osh
, &cc
->regcontrol_addr
, 0);
1111 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~((uint32
)0x07 << 29);
1112 val
|= (uint32
)(rcal_code
& 0x07) << 29;
1113 W_REG(osh
, &cc
->regcontrol_data
, val
);
1114 W_REG(osh
, &cc
->regcontrol_addr
, 1);
1115 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~(uint32
)0x01;
1116 val
|= (uint32
)((rcal_code
>> 3) & 0x01);
1117 W_REG(osh
, &cc
->regcontrol_data
, val
);
1119 /* Write RCal code into pmu_chip_ctrl[33:30] */
1120 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
1121 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~((uint32
)0x03 << 30);
1122 val
|= (uint32
)(rcal_code
& 0x03) << 30;
1123 W_REG(osh
, &cc
->chipcontrol_data
, val
);
1124 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
1125 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~(uint32
)0x03;
1126 val
|= (uint32
)((rcal_code
>> 2) & 0x03);
1127 W_REG(osh
, &cc
->chipcontrol_data
, val
);
1129 /* Set override in pmu_chip_ctrl[29] */
1130 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
1131 OR_REG(osh
, &cc
->chipcontrol_data
, (0x01 << 29));
1133 /* Power off RCal block */
1134 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
1135 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
1139 #endif /* BCM4325 */
1144 /* Return to original core */
1145 sb_setcoreidx(sbh
, origidx
);