2 * Misc utility routines for accessing PMU corerev specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright (C) 2009, 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.
13 * $Id: hndpmu.c,v 1.121.2.37 2009/10/13 02:32:49 Exp $
26 #define PMU_ERROR(args)
30 /* To check in verbose debugging messages not intended
31 * to be on except on private builds.
33 #define PMU_NONE(args)
35 /* PLL controls/clocks */
36 static void si_pmu0_pllinit0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
);
37 static void si_pmu1_pllinit0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
);
38 static uint32
si_pmu0_alpclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
39 static uint32
si_pmu0_cpuclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
40 static uint32
si_pmu1_cpuclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
41 static uint32
si_pmu1_alpclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
44 static bool si_pmu_res_depfltr_bb(si_t
*sih
);
45 static bool si_pmu_res_depfltr_nbb(si_t
*sih
);
46 static bool si_pmu_res_depfltr_ncb(si_t
*sih
);
47 static bool si_pmu_res_depfltr_paldo(si_t
*sih
);
48 static bool si_pmu_res_depfltr_npaldo(si_t
*sih
);
49 static uint32
si_pmu_res_deps(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 rsrcs
, bool all
);
50 static uint
si_pmu_res_uptime(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint8 rsrc
);
52 static void si_pmu_res_masks(si_t
*sih
, uint32
*pmin
, uint32
*pmax
);
54 /* Read/write a chipcontrol reg */
56 si_pmu_chipcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
58 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol_addr
), ~0, reg
);
59 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol_data
), mask
, val
);
63 #define FVCO_880 880000 /* 880MHz */
64 #define FVCO_1760 1760000 /* 1760MHz */
65 #define FVCO_1440 1440000 /* 1440MHz */
69 si_pmu_pllupd(si_t
*sih
)
71 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pmucontrol
),
72 PCTL_PLL_PLLCTL_UPD
, PCTL_PLL_PLLCTL_UPD
);
74 /* Read/write a pllcontrol reg */
76 si_pmu_pllcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
78 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pllcontrol_addr
), ~0, reg
);
79 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pllcontrol_data
), mask
, val
);
81 /* Setup switcher voltage */
83 BCMINITFN(si_pmu_set_switcher_voltage
)(si_t
*sih
, osl_t
*osh
,
84 uint8 bb_voltage
, uint8 rf_voltage
)
89 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
91 /* Remember original core before switch to chipc */
92 origidx
= si_coreidx(sih
);
93 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
96 W_REG(osh
, &cc
->regcontrol_addr
, 0x01);
97 W_REG(osh
, &cc
->regcontrol_data
, (uint32
)(bb_voltage
& 0x1f) << 22);
99 W_REG(osh
, &cc
->regcontrol_addr
, 0x00);
100 W_REG(osh
, &cc
->regcontrol_data
, (uint32
)(rf_voltage
& 0x1f) << 14);
102 /* Return to original core */
103 si_setcoreidx(sih
, origidx
);
107 BCMINITFN(si_pmu_set_ldo_voltage
)(si_t
*sih
, osl_t
*osh
, uint8 ldo
, uint8 voltage
)
109 uint8 sr_cntl_shift
= 0, rc_shift
= 0, shift
= 0, mask
= 0;
112 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
114 switch (CHIPID(sih
->chip
)) {
115 case BCM4328_CHIP_ID
:
116 case BCM5354_CHIP_ID
:
118 case SET_LDO_VOLTAGE_LDO1
:
124 case SET_LDO_VOLTAGE_LDO2
:
129 case SET_LDO_VOLTAGE_LDO3
:
134 case SET_LDO_VOLTAGE_PAREF
:
144 case BCM4312_CHIP_ID
:
146 case SET_LDO_VOLTAGE_PAREF
:
156 case BCM4325_CHIP_ID
:
158 case SET_LDO_VOLTAGE_CLDO_PWM
:
163 case SET_LDO_VOLTAGE_CBUCK_PWM
:
167 /* Bit 116 & 119 are inverted in CLB for opt 2b */
168 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
169 CST4325_PMUTOP_2B_SHIFT
) == 1)
182 shift
= sr_cntl_shift
+ rc_shift
;
184 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, regcontrol_addr
),
186 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, regcontrol_data
),
187 mask
<< shift
, (voltage
& mask
) << shift
);
191 si_pmu_paref_ldo_enable(si_t
*sih
, osl_t
*osh
, bool enable
)
195 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
197 switch (CHIPID(sih
->chip
)) {
198 case BCM4328_CHIP_ID
:
199 ldo
= RES4328_PA_REF_LDO
;
201 case BCM5354_CHIP_ID
:
202 ldo
= RES5354_PA_REF_LDO
;
204 case BCM4312_CHIP_ID
:
205 ldo
= RES4312_PA_REF_LDO
;
211 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, min_res_mask
),
212 PMURES_BIT(ldo
), enable
? PMURES_BIT(ldo
) : 0);
215 /* d11 slow to fast clock transition time in slow clock cycles */
216 #define D11SCC_SLOW2FAST_TRANSITION 2
219 BCMINITFN(si_pmu_fast_pwrup_delay
)(si_t
*sih
, osl_t
*osh
)
221 uint delay
= PMU_MAX_TRANSITION_DLY
;
225 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
227 /* Remember original core before switch to chipc */
228 origidx
= si_coreidx(sih
);
229 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
232 switch (CHIPID(sih
->chip
)) {
233 case BCM4328_CHIP_ID
:
236 case BCM4325_CHIP_ID
:
240 uint32 ilp
= si_ilp_clock(sih
);
241 delay
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4325_HT_AVAIL
) +
242 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
245 case BCM4312_CHIP_ID
:
246 case BCM4322_CHIP_ID
:
247 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
248 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
249 case BCM43224_CHIP_ID
:
250 case BCM43225_CHIP_ID
:
251 case BCM43421_CHIP_ID
:
252 case BCM4342_CHIP_ID
:
256 case BCM4319_CHIP_ID
:
257 delay
= ISSIM_ENAB(sih
) ? 70 : 3700;
264 PMU_MSG(("si_pmu_fast_pwrup_delay: chip %s rev %d delay %d\n",
265 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, delay
));
267 /* Return to original core */
268 si_setcoreidx(sih
, origidx
);
270 return (uint16
)delay
;
274 BCMINITFN(si_pmu_force_ilp
)(si_t
*sih
, osl_t
*osh
, bool force
)
278 uint32 oldpmucontrol
;
280 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
282 /* Remember original core before switch to chipc */
283 origidx
= si_coreidx(sih
);
284 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
287 oldpmucontrol
= R_REG(osh
, &cc
->pmucontrol
);
289 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
&
290 ~(PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
292 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
|
293 (PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
295 /* Return to original core */
296 si_setcoreidx(sih
, origidx
);
298 return oldpmucontrol
;
301 /* Setup resource up/down timers */
307 /* Change resource dependancies masks */
309 uint32 res_mask
; /* resources (chip specific) */
310 int8 action
; /* action */
311 uint32 depend_mask
; /* changes to the dependancies mask */
312 bool (*filter
)(si_t
*sih
); /* action is taken when filter is NULL or return TRUE */
315 /* Resource dependancies mask change action */
316 #define RES_DEPEND_SET 0 /* Override the dependancies mask */
317 #define RES_DEPEND_ADD 1 /* Add to the dependancies mask */
318 #define RES_DEPEND_REMOVE -1 /* Remove from the dependancies mask */
320 static const pmu_res_updown_t
BCMINITDATA(bcm4328a0_res_updown
)[] = {
321 { RES4328_EXT_SWITCHER_PWM
, 0x0101 },
322 { RES4328_BB_SWITCHER_PWM
, 0x1f01 },
323 { RES4328_BB_SWITCHER_BURST
, 0x010f },
324 { RES4328_BB_EXT_SWITCHER_BURST
, 0x0101 },
325 { RES4328_ILP_REQUEST
, 0x0202 },
326 { RES4328_RADIO_SWITCHER_PWM
, 0x0f01 },
327 { RES4328_RADIO_SWITCHER_BURST
, 0x0f01 },
328 { RES4328_ROM_SWITCH
, 0x0101 },
329 { RES4328_PA_REF_LDO
, 0x0f01 },
330 { RES4328_RADIO_LDO
, 0x0f01 },
331 { RES4328_AFE_LDO
, 0x0f01 },
332 { RES4328_PLL_LDO
, 0x0f01 },
333 { RES4328_BG_FILTBYP
, 0x0101 },
334 { RES4328_TX_FILTBYP
, 0x0101 },
335 { RES4328_RX_FILTBYP
, 0x0101 },
336 { RES4328_XTAL_PU
, 0x0101 },
337 { RES4328_XTAL_EN
, 0xa001 },
338 { RES4328_BB_PLL_FILTBYP
, 0x0101 },
339 { RES4328_RF_PLL_FILTBYP
, 0x0101 },
340 { RES4328_BB_PLL_PU
, 0x0701 }
343 static const pmu_res_depend_t
BCMINITDATA(bcm4328a0_res_depend
)[] = {
344 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
346 PMURES_BIT(RES4328_ILP_REQUEST
),
348 PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) | PMURES_BIT(RES4328_BB_SWITCHER_PWM
),
353 static const pmu_res_updown_t
BCMINITDATA(bcm4325a0_res_updown_qt
)[] = {
354 { RES4325_HT_AVAIL
, 0x0300 },
355 { RES4325_BBPLL_PWRSW_PU
, 0x0101 },
356 { RES4325_RFPLL_PWRSW_PU
, 0x0101 },
357 { RES4325_ALP_AVAIL
, 0x0100 },
358 { RES4325_XTAL_PU
, 0x1000 },
359 { RES4325_LNLDO1_PU
, 0x0800 },
360 { RES4325_CLDO_CBUCK_PWM
, 0x0101 },
361 { RES4325_CBUCK_PWM
, 0x0803 }
364 static const pmu_res_updown_t
BCMINITDATA(bcm4325a0_res_updown
)[] = {
365 { RES4325_XTAL_PU
, 0x1501 }
368 static const pmu_res_depend_t
BCMINITDATA(bcm4325a0_res_depend
)[] = {
369 /* Adjust LNLDO2 PU resource dependencies - remove BB BURST if power topology
370 * does not use BB to provide LNLDO2 voltage.
373 PMURES_BIT(RES4325_LNLDO2_PU
),
375 PMURES_BIT(RES4325_BUCK_BOOST_BURST
),
376 si_pmu_res_depfltr_nbb
378 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
380 PMURES_BIT(RES4325_ALP_AVAIL
) | PMURES_BIT(RES4325_HT_AVAIL
),
382 PMURES_BIT(RES4325_BUCK_BOOST_BURST
) | PMURES_BIT(RES4325_BUCK_BOOST_PWM
),
383 si_pmu_res_depfltr_bb
385 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
387 PMURES_BIT(RES4325_HT_AVAIL
),
389 PMURES_BIT(RES4325_RX_PWRSW_PU
) | PMURES_BIT(RES4325_TX_PWRSW_PU
) |
390 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
),
393 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
395 PMURES_BIT(RES4325_ILP_REQUEST
) | PMURES_BIT(RES4325_ABUCK_BURST
) |
396 PMURES_BIT(RES4325_ABUCK_PWM
) | PMURES_BIT(RES4325_LNLDO1_PU
) |
397 PMURES_BIT(RES4325_LNLDO4_PU
) | PMURES_BIT(RES4325_XTAL_PU
) |
398 PMURES_BIT(RES4325_ALP_AVAIL
) | PMURES_BIT(RES4325_RX_PWRSW_PU
) |
399 PMURES_BIT(RES4325_TX_PWRSW_PU
) | PMURES_BIT(RES4325_RFPLL_PWRSW_PU
) |
400 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
) |
401 PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
),
403 PMURES_BIT(RES4325B0_CBUCK_LPOM
) | PMURES_BIT(RES4325B0_CBUCK_BURST
) |
404 PMURES_BIT(RES4325B0_CBUCK_PWM
),
405 si_pmu_res_depfltr_ncb
410 static const pmu_res_updown_t
BCMINITDATA(bcm4319a0_res_updown_qt
)[] = {
411 { RES4319_HT_AVAIL
, 0x0101 },
412 { RES4319_XTAL_PU
, 0x0100 },
413 { RES4319_LNLDO1_PU
, 0x0100 },
414 { RES4319_PALDO_PU
, 0x0100 },
415 { RES4319_CLDO_PU
, 0x0100 },
416 { RES4319_CBUCK_PWM
, 0x0100 },
417 { RES4319_CBUCK_BURST
, 0x0100 },
418 { RES4319_CBUCK_LPOM
, 0x0100 }
421 static const pmu_res_updown_t
BCMINITDATA(bcm4319a0_res_updown
)[] = {
422 { RES4319_XTAL_PU
, 0x3f01 }
425 static const pmu_res_depend_t
BCMINITDATA(bcm4319a0_res_depend
)[] = {
426 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
428 PMURES_BIT(RES4319_OTP_PU
),
430 PMURES_BIT(RES4319_PALDO_PU
),
431 si_pmu_res_depfltr_npaldo
433 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
435 PMURES_BIT(RES4319_HT_AVAIL
),
437 PMURES_BIT(RES4319_PALDO_PU
),
438 si_pmu_res_depfltr_paldo
440 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
442 PMURES_BIT(RES4319_HT_AVAIL
),
444 PMURES_BIT(RES4319_RX_PWRSW_PU
) | PMURES_BIT(RES4319_TX_PWRSW_PU
) |
445 PMURES_BIT(RES4319_RFPLL_PWRSW_PU
) |
446 PMURES_BIT(RES4319_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4319_AFE_PWRSW_PU
),
451 /* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
453 BCMINITFN(si_pmu_res_depfltr_bb
)(si_t
*sih
)
455 return (sih
->boardflags
& BFL_BUCKBOOST
) != 0;
458 /* TRUE if the power topology doesn't use the buck boost */
460 BCMINITFN(si_pmu_res_depfltr_nbb
)(si_t
*sih
)
462 return (sih
->boardflags
& BFL_BUCKBOOST
) == 0;
465 /* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
467 BCMINITFN(si_pmu_res_depfltr_ncb
)(si_t
*sih
)
469 if (CHIPID(sih
->chip
) == BCM4325_CHIP_ID
)
470 return (sih
->chiprev
>= 2) && ((sih
->boardflags
& BFL_NOCBUCK
) != 0);
471 return ((sih
->boardflags
& BFL_NOCBUCK
) != 0);
475 /* TRUE if the power topology uses the PALDO */
477 BCMINITFN(si_pmu_res_depfltr_paldo
)(si_t
*sih
)
479 return (sih
->boardflags
& BFL_PALDO
) != 0;
482 /* TRUE if the power topology doesn't use the PALDO */
484 BCMINITFN(si_pmu_res_depfltr_npaldo
)(si_t
*sih
)
486 return (sih
->boardflags
& BFL_PALDO
) == 0;
490 #define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
491 sih->boardtype == BCM94325BGABU_BOARD)
493 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
495 si_pmu_res_masks(si_t
*sih
, uint32
*pmin
, uint32
*pmax
)
497 uint32 min_mask
= 0, max_mask
= 0;
502 rsrcs
= (sih
->pmucaps
& PCAP_RC_MASK
) >> PCAP_RC_SHIFT
;
504 /* determine min/max rsrc masks */
505 switch (CHIPID(sih
->chip
)) {
506 case BCM4328_CHIP_ID
:
507 /* Down to ILP request */
508 min_mask
= PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) |
509 PMURES_BIT(RES4328_BB_SWITCHER_PWM
) |
510 PMURES_BIT(RES4328_XTAL_EN
);
511 /* Allow (but don't require) PLL to turn on */
514 case BCM5354_CHIP_ID
:
515 /* Allow (but don't require) PLL to turn on */
518 case BCM4325_CHIP_ID
:
519 /* Leave OTP powered up and power it down later when there is no one needs it */
520 if (sih
->chiprev
< 2) {
521 min_mask
= PMURES_BIT(RES4325_CBUCK_BURST
) |
522 PMURES_BIT(RES4325_LNLDO2_PU
);
523 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
524 CST4325_PMUTOP_2B_SHIFT
) == 1)
525 min_mask
|= PMURES_BIT(RES4325_CLDO_CBUCK_BURST
);
527 /* Power down the OTP as well and everything we need from it are cacehed */
529 if (!(sih
->boardflags
& BFL_NOCBUCK
))
530 min_mask
= PMURES_BIT(RES4325B0_CBUCK_LPOM
);
531 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
532 CST4325_PMUTOP_2B_SHIFT
) == 1)
533 min_mask
|= PMURES_BIT(RES4325B0_CLDO_PU
);
535 /* Leave buck boost on in burst mode for certain boards */
536 if ((sih
->boardflags
& BFL_BUCKBOOST
) && (BCM94325_BBVDDIOSD_BOARDS(sih
)))
537 min_mask
|= PMURES_BIT(RES4325_BUCK_BOOST_BURST
);
538 /* Allow all resources to be turned on upon requests */
539 max_mask
= ~(~0 << rsrcs
);
541 case BCM4312_CHIP_ID
:
542 /* default min_mask = 0x80000cbb is wrong */
546 * pmu_res_updown_table_sz = 0;
547 * pmu_res_depend_table_sz = 0;
550 case BCM4322_CHIP_ID
:
551 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
552 case BCM4342_CHIP_ID
:
553 if (sih
->chiprev
< 2) {
554 /* request ALP(can skip for A1) */
555 min_mask
= PMURES_BIT(RES4322_RF_LDO
) |
556 PMURES_BIT(RES4322_XTAL_PU
) |
557 PMURES_BIT(RES4322_ALP_AVAIL
);
559 min_mask
+= PMURES_BIT(RES4322_SI_PLL_ON
) |
560 PMURES_BIT(RES4322_HT_SI_AVAIL
) |
561 PMURES_BIT(RES4322_PHY_PLL_ON
) |
562 PMURES_BIT(RES4322_OTP_PU
) |
563 PMURES_BIT(RES4322_HT_PHY_AVAIL
);
568 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
569 case BCM43224_CHIP_ID
:
570 case BCM43225_CHIP_ID
:
571 case BCM43421_CHIP_ID
:
575 case BCM4319_CHIP_ID
:
577 /* Initialize to ResInitMode2 for bootloader */
578 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
579 PMURES_BIT(RES4319_CBUCK_BURST
) |
580 PMURES_BIT(RES4319_CBUCK_PWM
) |
581 PMURES_BIT(RES4319_CLDO_PU
) |
582 PMURES_BIT(RES4319_PALDO_PU
) |
583 PMURES_BIT(RES4319_LNLDO1_PU
) |
584 PMURES_BIT(RES4319_OTP_PU
) |
585 PMURES_BIT(RES4319_XTAL_PU
) |
586 PMURES_BIT(RES4319_ALP_AVAIL
) |
587 PMURES_BIT(RES4319_RFPLL_PWRSW_PU
);
589 /* We only need a few resources to be kept on all the time */
590 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
591 PMURES_BIT(RES4319_CLDO_PU
);
592 #endif /* CONFIG_XIP */
593 /* Allow everything else to be turned on upon requests */
594 max_mask
= ~(~0 << rsrcs
);
601 /* Apply nvram override to min mask */
602 if ((val
= getvar(NULL
, "rmin")) != NULL
) {
603 PMU_MSG(("Applying rmin=%s to min_mask\n", val
));
604 min_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
606 /* Apply nvram override to max mask */
607 if ((val
= getvar(NULL
, "rmax")) != NULL
) {
608 PMU_MSG(("Applying rmax=%s to max_mask\n", val
));
609 max_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
616 /* initialize PMU resources */
618 BCMINITFN(si_pmu_res_init
)(si_t
*sih
, osl_t
*osh
)
622 const pmu_res_updown_t
*pmu_res_updown_table
= NULL
;
623 uint pmu_res_updown_table_sz
= 0;
624 const pmu_res_depend_t
*pmu_res_depend_table
= NULL
;
625 uint pmu_res_depend_table_sz
= 0;
626 uint32 min_mask
= 0, max_mask
= 0;
630 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
632 /* Remember original core before switch to chipc */
633 origidx
= si_coreidx(sih
);
634 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
637 switch (CHIPID(sih
->chip
)) {
638 case BCM4328_CHIP_ID
:
639 pmu_res_updown_table
= bcm4328a0_res_updown
;
640 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4328a0_res_updown
);
641 pmu_res_depend_table
= bcm4328a0_res_depend
;
642 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4328a0_res_depend
);
644 case BCM4325_CHIP_ID
:
645 /* Optimize resources up/down timers */
646 if (ISSIM_ENAB(sih
)) {
647 pmu_res_updown_table
= bcm4325a0_res_updown_qt
;
648 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown_qt
);
650 pmu_res_updown_table
= bcm4325a0_res_updown
;
651 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown
);
653 /* Optimize resources dependancies */
654 pmu_res_depend_table
= bcm4325a0_res_depend
;
655 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4325a0_res_depend
);
657 case BCM4319_CHIP_ID
:
658 /* Optimize resources up/down timers */
659 if (ISSIM_ENAB(sih
)) {
660 pmu_res_updown_table
= bcm4319a0_res_updown_qt
;
661 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4319a0_res_updown_qt
);
664 pmu_res_updown_table
= bcm4319a0_res_updown
;
665 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4319a0_res_updown
);
667 /* Optimize resources dependancies masks */
668 pmu_res_depend_table
= bcm4319a0_res_depend
;
669 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4319a0_res_depend
);
677 rsrcs
= (sih
->pmucaps
& PCAP_RC_MASK
) >> PCAP_RC_SHIFT
;
679 /* Program up/down timers */
680 while (pmu_res_updown_table_sz
--) {
681 ASSERT(pmu_res_updown_table
!= NULL
);
682 PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
683 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
,
684 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
));
685 W_REG(osh
, &cc
->res_table_sel
,
686 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
);
687 W_REG(osh
, &cc
->res_updn_timer
,
688 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
);
690 /* Apply nvram overrides to up/down timers */
691 for (i
= 0; i
< rsrcs
; i
++) {
692 snprintf(name
, sizeof(name
), "r%dt", i
);
693 if ((val
= getvar(NULL
, name
)) == NULL
)
695 PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name
, val
, i
));
696 W_REG(osh
, &cc
->res_table_sel
, (uint32
)i
);
697 W_REG(osh
, &cc
->res_updn_timer
, (uint32
)bcm_strtoul(val
, NULL
, 0));
700 /* Program resource dependencies table */
701 while (pmu_res_depend_table_sz
--) {
702 ASSERT(pmu_res_depend_table
!= NULL
);
703 if (pmu_res_depend_table
[pmu_res_depend_table_sz
].filter
!= NULL
&&
704 !(pmu_res_depend_table
[pmu_res_depend_table_sz
].filter
)(sih
))
706 for (i
= 0; i
< rsrcs
; i
++) {
707 if ((pmu_res_depend_table
[pmu_res_depend_table_sz
].res_mask
&
710 W_REG(osh
, &cc
->res_table_sel
, i
);
711 switch (pmu_res_depend_table
[pmu_res_depend_table_sz
].action
) {
713 PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i
,
714 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
));
715 W_REG(osh
, &cc
->res_dep_mask
,
716 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
719 PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n",
720 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
, i
));
721 OR_REG(osh
, &cc
->res_dep_mask
,
722 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
724 case RES_DEPEND_REMOVE
:
725 PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n",
726 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
, i
));
727 AND_REG(osh
, &cc
->res_dep_mask
,
728 ~pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
736 /* Apply nvram overrides to dependancies masks */
737 for (i
= 0; i
< rsrcs
; i
++) {
738 snprintf(name
, sizeof(name
), "r%dd", i
);
739 if ((val
= getvar(NULL
, name
)) == NULL
)
741 PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name
, val
, i
));
742 W_REG(osh
, &cc
->res_table_sel
, (uint32
)i
);
743 W_REG(osh
, &cc
->res_dep_mask
, (uint32
)bcm_strtoul(val
, NULL
, 0));
746 /* Determine min/max rsrc masks */
747 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
749 /* Program min resource mask */
751 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask
));
752 W_REG(osh
, &cc
->min_res_mask
, min_mask
);
754 /* Program max resource mask */
756 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask
));
757 W_REG(osh
, &cc
->max_res_mask
, max_mask
);
760 /* Return to original core */
761 si_setcoreidx(sih
, origidx
);
764 /* setup pll and query clock speed */
772 /* the following table is based on 880Mhz fvco */
773 static const pmu0_xtaltab0_t
BCMINITDATA(pmu0_xtaltab0
)[] = {
774 { 12000, 1, 73, 349525 },
775 { 13000, 2, 67, 725937 },
776 { 14400, 3, 61, 116508 },
777 { 15360, 4, 57, 305834 },
778 { 16200, 5, 54, 336579 },
779 { 16800, 6, 52, 399457 },
780 { 19200, 7, 45, 873813 },
781 { 19800, 8, 44, 466033 },
783 { 25000, 10, 70, 419430 },
784 { 26000, 11, 67, 725937 },
785 { 30000, 12, 58, 699050 },
786 { 38400, 13, 45, 873813 },
787 { 40000, 14, 45, 0 },
792 #define PMU0_XTAL0_DEFAULT 11
794 #define PMU0_XTAL0_DEFAULT 8
799 * Set new backplane PLL clock frequency
802 BCMINITFN(si_pmu0_sbclk4328
)(si_t
*sih
, int freq
)
804 uint32 tmp
, oldmax
, oldmin
, origidx
;
807 /* Remember original core before switch to chipc */
808 origidx
= si_coreidx(sih
);
809 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
812 /* Set new backplane PLL clock */
813 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
814 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
815 tmp
&= ~(PMU0_PLL0_PC0_DIV_ARM_MASK
);
816 tmp
|= freq
<< PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
817 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
819 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
821 oldmin
= R_REG(osh
, &cc
->min_res_mask
);
822 oldmax
= R_REG(osh
, &cc
->max_res_mask
);
823 W_REG(osh
, &cc
->min_res_mask
, oldmin
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
824 W_REG(osh
, &cc
->max_res_mask
, oldmax
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
826 /* It takes over several hundred usec to re-enable the PLL since the
827 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
829 * Be sure PLL is powered down first before re-enabling it.
832 OSL_DELAY(PLL_DELAY
);
833 SPINWAIT((R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)), PLL_DELAY
*3);
834 if (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)) {
835 /* If BB_PLL not powered down yet, new backplane PLL clock
836 * may not take effect.
838 * Still early during bootup so no serial output here.
840 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n"));
841 ASSERT(!(R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)));
845 W_REG(osh
, &cc
->max_res_mask
, oldmax
);
847 /* Return to original core */
848 si_setcoreidx(sih
, origidx
);
850 #endif /* BCMUSBDEV */
852 /* Set up PLL registers in the PMU as per the crystal speed.
853 * Uses xtalfreq variable, or passed-in default.
856 BCMINITFN(si_pmu0_pllinit0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
859 const pmu0_xtaltab0_t
*xt
;
861 /* Find the frequency in the table */
862 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
863 if (xt
->freq
== xtal
)
866 xt
= &pmu0_xtaltab0
[PMU0_XTAL0_DEFAULT
];
868 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal
/ 1000, xtal
% 1000, xt
->xf
));
870 /* Check current PLL state */
871 tmp
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
874 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
875 xt
->freq
/ 1000, xt
->freq
% 1000));
877 if (CHIPID(sih
->chip
) == BCM4328_CHIP_ID
)
878 si_pmu0_sbclk4328(sih
, PMU0_PLL0_PC0_DIV_ARM_88MHZ
);
879 #endif /* BCMUSBDEV */
884 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
885 xt
->freq
/ 1000, xt
->freq
% 1000,
886 pmu0_xtaltab0
[tmp
-1].freq
/ 1000, pmu0_xtaltab0
[tmp
-1].freq
% 1000));
888 PMU_MSG(("Programming PLL for %d.%d MHz\n",
889 xt
->freq
/ 1000, xt
->freq
% 1000));
892 /* Make sure the PLL is off */
893 switch (CHIPID(sih
->chip
)) {
894 case BCM4328_CHIP_ID
:
895 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
896 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
898 case BCM5354_CHIP_ID
:
899 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
900 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
905 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
906 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
));
908 PMU_MSG(("Done masking\n"));
910 /* Write PDIV in pllcontrol[0] */
911 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
912 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
913 if (xt
->freq
>= PMU0_PLL0_PC0_PDIV_FREQ
)
914 tmp
|= PMU0_PLL0_PC0_PDIV_MASK
;
916 tmp
&= ~PMU0_PLL0_PC0_PDIV_MASK
;
917 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
919 /* Write WILD in pllcontrol[1] */
920 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL1
);
921 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
922 tmp
= ((tmp
& ~(PMU0_PLL0_PC1_WILD_INT_MASK
| PMU0_PLL0_PC1_WILD_FRAC_MASK
)) |
923 (((xt
->wbint
<< PMU0_PLL0_PC1_WILD_INT_SHIFT
) &
924 PMU0_PLL0_PC1_WILD_INT_MASK
) |
925 ((xt
->wbfrac
<< PMU0_PLL0_PC1_WILD_FRAC_SHIFT
) &
926 PMU0_PLL0_PC1_WILD_FRAC_MASK
)));
928 tmp
|= PMU0_PLL0_PC1_STOP_MOD
;
930 tmp
&= ~PMU0_PLL0_PC1_STOP_MOD
;
931 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
933 /* Write WILD in pllcontrol[2] */
934 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL2
);
935 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
936 tmp
= ((tmp
& ~PMU0_PLL0_PC2_WILD_INT_MASK
) |
937 ((xt
->wbint
>> PMU0_PLL0_PC2_WILD_INT_SHIFT
) &
938 PMU0_PLL0_PC2_WILD_INT_MASK
));
939 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
941 PMU_MSG(("Done pll\n"));
943 /* Write XtalFreq. Set the divisor also. */
944 tmp
= R_REG(osh
, &cc
->pmucontrol
);
945 tmp
= ((tmp
& ~PCTL_ILP_DIV_MASK
) |
946 (((((xt
->freq
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) & PCTL_ILP_DIV_MASK
));
947 tmp
= ((tmp
& ~PCTL_XTALFREQ_MASK
) |
948 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
));
949 W_REG(osh
, &cc
->pmucontrol
, tmp
);
952 /* query alp/xtal clock frequency */
954 BCMINITFN(si_pmu0_alpclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
956 const pmu0_xtaltab0_t
*xt
;
959 /* Find the frequency in the table */
960 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
962 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
965 /* PLL must be configured before */
968 return xt
->freq
* 1000;
971 /* query CPU clock frequency */
973 BCMINITFN(si_pmu0_cpuclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
976 uint32 FVCO
= FVCO_880
;
978 /* Read divarm from pllcontrol[0] */
979 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
980 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
981 divarm
= (tmp
& PMU0_PLL0_PC0_DIV_ARM_MASK
) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
984 /* Return ARM/SB clock */
985 return FVCO
/ (divarm
+ PMU0_PLL0_PC0_DIV_ARM_BASE
) * 1000;
988 /* setup pll and query clock speed */
998 /* the following table is based on 880Mhz fvco */
999 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_880
)[] = {
1000 {12000, 1, 3, 22, 0x9, 0xFFFFEF},
1001 {13000, 2, 1, 6, 0xb, 0x483483},
1002 {14400, 3, 1, 10, 0xa, 0x1C71C7},
1003 {15360, 4, 1, 5, 0xb, 0x755555},
1004 {16200, 5, 1, 10, 0x5, 0x6E9E06},
1005 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
1006 {19200, 7, 1, 9, 0x5, 0x17B425},
1007 {19800, 8, 1, 11, 0x4, 0xA57EB},
1008 {20000, 9, 1, 11, 0x4, 0x0},
1009 {24000, 10, 3, 11, 0xa, 0x0},
1010 {25000, 11, 5, 16, 0xb, 0x0},
1011 {26000, 12, 1, 2, 0x10, 0xEC4EC4},
1012 {30000, 13, 3, 8, 0xb, 0x0},
1013 {38400, 14, 1, 2, 0xb, 0x755555},
1014 {40000, 15, 1, 2, 0xb, 0},
1018 #define PMU1_XTALTAB0_880_12000K 0
1019 #define PMU1_XTALTAB0_880_13000K 1
1020 #define PMU1_XTALTAB0_880_14400K 2
1021 #define PMU1_XTALTAB0_880_15360K 3
1022 #define PMU1_XTALTAB0_880_16200K 4
1023 #define PMU1_XTALTAB0_880_16800K 5
1024 #define PMU1_XTALTAB0_880_19200K 6
1025 #define PMU1_XTALTAB0_880_19800K 7
1026 #define PMU1_XTALTAB0_880_20000K 8
1027 #define PMU1_XTALTAB0_880_24000K 9
1028 #define PMU1_XTALTAB0_880_25000K 10
1029 #define PMU1_XTALTAB0_880_26000K 11
1030 #define PMU1_XTALTAB0_880_30000K 12
1031 #define PMU1_XTALTAB0_880_38400K 13
1032 #define PMU1_XTALTAB0_880_40000K 14
1034 /* the following table is based on 1760Mhz fvco */
1035 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_1760
)[] = {
1036 {12000, 1, 3, 44, 0x9, 0xFFFFEF},
1037 {13000, 2, 1, 12, 0xb, 0x483483},
1038 {14400, 3, 1, 20, 0xa, 0x1C71C7},
1039 {15360, 4, 1, 10, 0xb, 0x755555},
1040 {16200, 5, 1, 20, 0x5, 0x6E9E06},
1041 {16800, 6, 1, 20, 0x5, 0x3Cf3Cf},
1042 {19200, 7, 1, 18, 0x5, 0x17B425},
1043 {19800, 8, 1, 22, 0x4, 0xA57EB},
1044 {20000, 9, 1, 22, 0x4, 0x0},
1045 {24000, 10, 3, 22, 0xa, 0x0},
1046 {25000, 11, 5, 32, 0xb, 0x0},
1047 {26000, 12, 1, 4, 0x10, 0xEC4EC4},
1048 {30000, 13, 3, 16, 0xb, 0x0},
1049 {38400, 14, 1, 10, 0x4, 0x955555},
1050 {40000, 15, 1, 4, 0xb, 0},
1055 #define PMU1_XTALTAB0_1760_12000K 0
1056 #define PMU1_XTALTAB0_1760_13000K 1
1057 #define PMU1_XTALTAB0_1760_14400K 2
1058 #define PMU1_XTALTAB0_1760_15360K 3
1059 #define PMU1_XTALTAB0_1760_16200K 4
1060 #define PMU1_XTALTAB0_1760_16800K 5
1061 #define PMU1_XTALTAB0_1760_19200K 6
1062 #define PMU1_XTALTAB0_1760_19800K 7
1063 #define PMU1_XTALTAB0_1760_20000K 8
1064 #define PMU1_XTALTAB0_1760_24000K 9
1065 #define PMU1_XTALTAB0_1760_25000K 10
1066 #define PMU1_XTALTAB0_1760_26000K 11
1067 #define PMU1_XTALTAB0_1760_30000K 12
1068 #define PMU1_XTALTAB0_1760_38400K 13
1069 #define PMU1_XTALTAB0_1760_40000K 14
1071 /* the following table is based on 1440Mhz fvco */
1072 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_1440
)[] = {
1073 {12000, 1, 3, 44, 0x9, 0xFFFFEF},
1074 {13000, 2, 1, 12, 0xb, 0x483483},
1075 {14400, 3, 1, 20, 0xa, 0x1C71C7},
1076 {15360, 4, 1, 10, 0xb, 0x755555},
1077 {16200, 5, 1, 20, 0x5, 0x6E9E06},
1078 {16800, 6, 1, 20, 0x5, 0x3Cf3Cf},
1079 {19200, 7, 1, 18, 0x5, 0x17B425},
1080 {19800, 8, 1, 22, 0x4, 0xA57EB},
1081 {20000, 9, 1, 22, 0x4, 0x0},
1082 {24000, 10, 1, 1, 0x3c, 0x0},
1083 {25000, 11, 5, 32, 0xb, 0x0},
1084 {26000, 12, 1, 4, 0x10, 0xEC4EC4},
1085 {30000, 13, 1, 1, 0x30, 0x0},
1086 {38400, 14, 1, 10, 0x4, 0x955555},
1087 {40000, 15, 1, 4, 0xb, 0},
1088 {48000, 16, 2, 1, 0x3c, 0x0},
1093 #define PMU1_XTALTAB0_1440_12000K 0
1094 #define PMU1_XTALTAB0_1440_13000K 1
1095 #define PMU1_XTALTAB0_1440_14400K 2
1096 #define PMU1_XTALTAB0_1440_15360K 3
1097 #define PMU1_XTALTAB0_1440_16200K 4
1098 #define PMU1_XTALTAB0_1440_16800K 5
1099 #define PMU1_XTALTAB0_1440_19200K 6
1100 #define PMU1_XTALTAB0_1440_19800K 7
1101 #define PMU1_XTALTAB0_1440_20000K 8
1102 #define PMU1_XTALTAB0_1440_24000K 9
1103 #define PMU1_XTALTAB0_1440_25000K 10
1104 #define PMU1_XTALTAB0_1440_26000K 11
1105 #define PMU1_XTALTAB0_1440_30000K 12
1106 #define PMU1_XTALTAB0_1440_38400K 13
1107 #define PMU1_XTALTAB0_1440_40000K 14
1109 #define XTAL_FREQ_24000MHZ 24000
1110 #define XTAL_FREQ_30000MHZ 30000
1111 #define XTAL_FREQ_48000MHZ 48000
1113 /* select xtal table for each chip */
1114 static const pmu1_xtaltab0_t
*
1115 BCMINITFN(si_pmu1_xtaltab0
)(si_t
*sih
)
1118 switch (CHIPID(sih
->chip
)) {
1119 case BCM4325_CHIP_ID
:
1120 return pmu1_xtaltab0_880
;
1121 case BCM4319_CHIP_ID
:
1122 return pmu1_xtaltab0_1440
;
1124 PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1131 /* select default xtal frequency for each chip */
1132 static const pmu1_xtaltab0_t
*
1133 BCMINITFN(si_pmu1_xtaldef0
)(si_t
*sih
)
1136 switch (CHIPID(sih
->chip
)) {
1137 case BCM4325_CHIP_ID
:
1138 /* Default to 26000Khz */
1139 return &pmu1_xtaltab0_880
[PMU1_XTALTAB0_880_26000K
];
1140 case BCM4319_CHIP_ID
:
1141 /* Default to 30000Khz */
1142 return &pmu1_xtaltab0_1440
[PMU1_XTALTAB0_1440_30000K
];
1144 PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1151 /* select default pll fvco for each chip */
1153 BCMINITFN(si_pmu1_pllfvco0
)(si_t
*sih
)
1156 switch (CHIPID(sih
->chip
)) {
1157 case BCM4325_CHIP_ID
:
1159 case BCM4319_CHIP_ID
:
1162 PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1169 /* query alp/xtal clock frequency */
1171 BCMINITFN(si_pmu1_alpclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1173 const pmu1_xtaltab0_t
*xt
;
1176 /* Find the frequency in the table */
1177 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1178 PCTL_XTALFREQ_SHIFT
;
1179 for (xt
= si_pmu1_xtaltab0(sih
); xt
!= NULL
&& xt
->fref
!= 0; xt
++)
1182 /* Could not find it so assign a default value */
1183 if (xt
== NULL
|| xt
->fref
== 0)
1184 xt
= si_pmu1_xtaldef0(sih
);
1185 ASSERT(xt
!= NULL
&& xt
->fref
!= 0);
1187 return xt
->fref
* 1000;
1190 /* Set up PLL registers in the PMU as per the crystal speed.
1191 * XtalFreq field in pmucontrol register being 0 indicates the PLL
1192 * is not programmed and the h/w default is assumed to work, in which
1193 * case the xtal frequency is unknown to the s/w so we need to call
1194 * si_pmu1_xtaldef0() wherever it is needed to return a default value.
1197 BCMINITFN(si_pmu1_pllinit0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
1199 const pmu1_xtaltab0_t
*xt
;
1201 uint32 buf_strength
= 0;
1202 uint8 ndiv_mode
= 1;
1204 /* Use h/w default PLL config */
1206 PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
1210 /* Find the frequency in the table */
1211 for (xt
= si_pmu1_xtaltab0(sih
); xt
!= NULL
&& xt
->fref
!= 0; xt
++)
1212 if (xt
->fref
== xtal
)
1215 /* Check current PLL state, bail out if it has been programmed or
1216 * we don't know how to program it.
1218 if (xt
== NULL
|| xt
->fref
== 0) {
1219 PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n",
1220 xtal
/ 1000, xtal
% 1000));
1223 if (((R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1224 PCTL_XTALFREQ_SHIFT
) == xt
->xf
) {
1225 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
1226 xt
->fref
/ 1000, xt
->fref
% 1000));
1230 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal
/ 1000, xtal
% 1000, xt
->xf
));
1231 PMU_MSG(("Programming PLL for %d.%d MHz\n", xt
->fref
/ 1000, xt
->fref
% 1000));
1233 switch (CHIPID(sih
->chip
)) {
1234 case BCM4325_CHIP_ID
:
1235 /* Change the BBPLL drive strength to 2 for all channels */
1236 buf_strength
= 0x222222;
1237 if (sih
->pmurev
>= 2)
1239 /* Make sure the PLL is off */
1240 AND_REG(osh
, &cc
->min_res_mask
,
1241 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
1242 AND_REG(osh
, &cc
->max_res_mask
,
1243 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
1244 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1245 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1247 case BCM4319_CHIP_ID
:
1248 /* Change the BBPLL drive strength to 2 for all channels */
1249 buf_strength
= 0x222222;
1250 /* Make sure the PLL is off */
1251 /* WAR65104: Disable the HT_AVAIL resource first and then
1252 * after a delay (more than downtime for HT_AVAIL) remove the
1253 * BBPLL resource; backplane clock moves to ALP from HT.
1255 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4319_HT_AVAIL
)));
1256 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4319_HT_AVAIL
)));
1259 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU
)));
1260 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU
)));
1263 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1264 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1265 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
1267 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1273 PMU_MSG(("Done masking\n"));
1275 /* Write p1div and p2div to pllcontrol[0] */
1276 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
1277 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
1278 ~(PMU1_PLL0_PC0_P1DIV_MASK
| PMU1_PLL0_PC0_P2DIV_MASK
);
1279 tmp
|= ((xt
->p1div
<< PMU1_PLL0_PC0_P1DIV_SHIFT
) & PMU1_PLL0_PC0_P1DIV_MASK
) |
1280 ((xt
->p2div
<< PMU1_PLL0_PC0_P2DIV_SHIFT
) & PMU1_PLL0_PC0_P2DIV_MASK
);
1281 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1283 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
))
1284 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MFB
;
1285 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1286 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
1287 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
1288 ~(PMU1_PLL0_PC2_NDIV_INT_MASK
| PMU1_PLL0_PC2_NDIV_MODE_MASK
);
1289 tmp
|= ((xt
->ndiv_int
<< PMU1_PLL0_PC2_NDIV_INT_SHIFT
) & PMU1_PLL0_PC2_NDIV_INT_MASK
) |
1290 ((ndiv_mode
<< PMU1_PLL0_PC2_NDIV_MODE_SHIFT
) & PMU1_PLL0_PC2_NDIV_MODE_MASK
);
1291 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1293 /* Write ndiv_frac to pllcontrol[3] */
1294 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
1295 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK
;
1296 tmp
|= ((xt
->ndiv_frac
<< PMU1_PLL0_PC3_NDIV_FRAC_SHIFT
) &
1297 PMU1_PLL0_PC3_NDIV_FRAC_MASK
);
1298 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1300 /* Write clock driving strength to pllcontrol[5] */
1302 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength
));
1304 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
1305 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC5_CLK_DRV_MASK
;
1306 tmp
|= (buf_strength
<< PMU1_PLL0_PC5_CLK_DRV_SHIFT
);
1307 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1310 PMU_MSG(("Done pll\n"));
1312 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1315 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) && (xt
->fref
!= XTAL_FREQ_30000MHZ
)) {
1316 W_REG(osh
, &cc
->chipcontrol_addr
, PMU1_PLL0_CHIPCTL2
);
1317 tmp
= R_REG(osh
, &cc
->chipcontrol_data
) & ~CCTL_4319USB_XTAL_SEL_MASK
;
1318 if (xt
->fref
== XTAL_FREQ_24000MHZ
) {
1319 tmp
|= (CCTL_4319USB_24MHZ_PLL_SEL
<< CCTL_4319USB_XTAL_SEL_SHIFT
);
1320 } else if (xt
->fref
== XTAL_FREQ_48000MHZ
) {
1321 tmp
|= (CCTL_4319USB_48MHZ_PLL_SEL
<< CCTL_4319USB_XTAL_SEL_SHIFT
);
1323 W_REG(osh
, &cc
->chipcontrol_data
, tmp
);
1326 /* Flush deferred pll control registers writes */
1327 if (sih
->pmurev
>= 2)
1328 OR_REG(osh
, &cc
->pmucontrol
, PCTL_PLL_PLLCTL_UPD
);
1330 /* Write XtalFreq. Set the divisor also. */
1331 tmp
= R_REG(osh
, &cc
->pmucontrol
) &
1332 ~(PCTL_ILP_DIV_MASK
| PCTL_XTALFREQ_MASK
);
1333 tmp
|= (((((xt
->fref
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) &
1334 PCTL_ILP_DIV_MASK
) |
1335 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
);
1338 W_REG(osh
, &cc
->pmucontrol
, tmp
);
1341 /* query the CPU clock frequency */
1343 BCMINITFN(si_pmu1_cpuclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1346 uint32 FVCO
= si_pmu1_pllfvco0(sih
);
1348 /* Read m1div from pllcontrol[1] */
1349 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
1350 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1351 m1div
= (tmp
& PMU1_PLL0_PC1_M1DIV_MASK
) >> PMU1_PLL0_PC1_M1DIV_SHIFT
;
1354 /* Return ARM/SB clock */
1355 return FVCO
/ m1div
* 1000;
1358 /* initialize PLL */
1360 BCMINITFN(si_pmu_pll_init
)(si_t
*sih
, osl_t
*osh
, uint xtalfreq
)
1365 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1367 /* Remember original core before switch to chipc */
1368 origidx
= si_coreidx(sih
);
1369 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1372 switch (CHIPID(sih
->chip
)) {
1373 case BCM4328_CHIP_ID
:
1374 si_pmu0_pllinit0(sih
, osh
, cc
, xtalfreq
);
1376 case BCM5354_CHIP_ID
:
1379 si_pmu0_pllinit0(sih
, osh
, cc
, xtalfreq
);
1381 case BCM4325_CHIP_ID
:
1382 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
1384 case BCM4312_CHIP_ID
:
1385 /* assume default works */
1387 case BCM4322_CHIP_ID
:
1388 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
1389 case BCM4342_CHIP_ID
:
1391 if (sih
->chiprev
== 0) {
1392 uint32 minmask
, maxmask
;
1394 minmask
= R_REG(osh
, &cc
->min_res_mask
);
1395 maxmask
= R_REG(osh
, &cc
->max_res_mask
);
1397 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
1398 /* Have to remove HT Avail request before powering off PLL */
1399 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
1400 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
1401 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1402 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
1403 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
1405 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1408 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_SI_PLL_PLLCTL
);
1409 W_REG(osh
, &cc
->pllcontrol_data
, 0x380005c0);
1413 W_REG(osh
, &cc
->max_res_mask
, maxmask
);
1415 W_REG(osh
, &cc
->min_res_mask
, minmask
);
1421 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
1422 case BCM43224_CHIP_ID
:
1423 case BCM43225_CHIP_ID
:
1424 case BCM43421_CHIP_ID
:
1428 case BCM4319_CHIP_ID
:
1429 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
1433 PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
1434 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
));
1438 /* Return to original core */
1439 si_setcoreidx(sih
, origidx
);
1442 /* query alp/xtal clock frequency */
1444 BCMINITFN(si_pmu_alp_clock
)(si_t
*sih
, osl_t
*osh
)
1448 uint32 clock
= ALP_CLOCK
;
1450 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1452 /* Remember original core before switch to chipc */
1453 origidx
= si_coreidx(sih
);
1454 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1457 switch (CHIPID(sih
->chip
)) {
1458 case BCM4328_CHIP_ID
:
1459 clock
= si_pmu0_alpclk0(sih
, osh
, cc
);
1461 case BCM5354_CHIP_ID
:
1462 clock
= si_pmu0_alpclk0(sih
, osh
, cc
);
1464 case BCM4325_CHIP_ID
:
1465 clock
= si_pmu1_alpclk0(sih
, osh
, cc
);
1467 case BCM4312_CHIP_ID
:
1468 case BCM4322_CHIP_ID
:
1469 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
1470 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
1471 case BCM43224_CHIP_ID
:
1472 case BCM43225_CHIP_ID
:
1473 case BCM43421_CHIP_ID
:
1474 case BCM4342_CHIP_ID
:
1475 case BCM4716_CHIP_ID
:
1476 case BCM4748_CHIP_ID
:
1477 case BCM47162_CHIP_ID
:
1479 clock
= 20000 * 1000;
1482 case BCM4319_CHIP_ID
:
1483 clock
= si_pmu1_alpclk0(sih
, osh
, cc
);
1486 PMU_MSG(("No ALP clock specified "
1487 "for chip %s rev %d pmurev %d, using default %d Hz\n",
1488 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
, clock
));
1492 /* Return to original core */
1493 si_setcoreidx(sih
, origidx
);
1497 /* Find the output of the "m" pll divider given pll controls that start with
1498 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
1501 BCMINITFN(si_pmu5_clock
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint pll0
, uint m
)
1503 uint32 tmp
, div
, ndiv
, p1
, p2
, fc
;
1505 if ((pll0
& 3) || (pll0
> PMU4716_MAINPLL_PLL0
)) {
1506 PMU_ERROR(("%s: Bad pll0: %d\n", __FUNCTION__
, pll0
));
1510 /* Strictly there is an m5 divider, but I'm not sure we use it */
1511 if ((m
== 0) || (m
> 4)) {
1512 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__
, m
));
1516 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_P1P2_OFF
);
1517 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
1518 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1519 p1
= (tmp
& PMU5_PLL_P1_MASK
) >> PMU5_PLL_P1_SHIFT
;
1520 p2
= (tmp
& PMU5_PLL_P2_MASK
) >> PMU5_PLL_P2_SHIFT
;
1522 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_M14_OFF
);
1523 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
1524 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1525 div
= (tmp
>> ((m
- 1) * PMU5_PLL_MDIV_WIDTH
)) & PMU5_PLL_MDIV_MASK
;
1527 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_NM5_OFF
);
1528 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
1529 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1530 ndiv
= (tmp
& PMU5_PLL_NDIV_MASK
) >> PMU5_PLL_NDIV_SHIFT
;
1532 /* Do calculation in Mhz */
1533 fc
= si_pmu_alp_clock(sih
, osh
) / 1000000;
1534 fc
= (p1
* ndiv
* fc
) / p2
;
1536 PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
1537 __FUNCTION__
, p1
, p2
, ndiv
, ndiv
, m
, div
, fc
, fc
/ div
));
1539 /* Return clock in Hertz */
1540 return ((fc
/ div
) * 1000000);
1543 /* query backplane clock frequency */
1544 /* For designs that feed the same clock to both backplane
1545 * and CPU just return the CPU clock speed.
1548 BCMINITFN(si_pmu_si_clock
)(si_t
*sih
, osl_t
*osh
)
1552 uint32 clock
= HT_CLOCK
;
1554 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1556 /* Remember original core before switch to chipc */
1557 origidx
= si_coreidx(sih
);
1558 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1561 switch (CHIPID(sih
->chip
)) {
1562 case BCM4328_CHIP_ID
:
1563 clock
= si_pmu0_cpuclk0(sih
, osh
, cc
);
1565 case BCM5354_CHIP_ID
:
1568 case BCM4325_CHIP_ID
:
1569 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
1571 case BCM4322_CHIP_ID
:
1572 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
1573 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
1574 case BCM43224_CHIP_ID
:
1575 case BCM43225_CHIP_ID
:
1576 case BCM43421_CHIP_ID
:
1577 case BCM4342_CHIP_ID
:
1578 /* 96MHz backplane clock */
1579 clock
= 96000 * 1000;
1581 case BCM4716_CHIP_ID
:
1582 case BCM4748_CHIP_ID
:
1583 case BCM47162_CHIP_ID
:
1584 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU4716_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
1587 case BCM4319_CHIP_ID
:
1588 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
1592 PMU_MSG(("No backplane clock specified "
1593 "for chip %s rev %d pmurev %d, using default %d Hz\n",
1594 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
, clock
));
1598 /* Return to original core */
1599 si_setcoreidx(sih
, origidx
);
1603 /* query CPU clock frequency */
1605 BCMINITFN(si_pmu_cpu_clock
)(si_t
*sih
, osl_t
*osh
)
1611 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1613 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
1614 if (sih
->chip
== BCM5354_CHIP_ID
)
1617 if (((sih
->pmurev
== 5) || (sih
->pmurev
== 6) ||
1618 (sih
->pmurev
== 7)) && (CHIPID(sih
->chip
) != BCM4319_CHIP_ID
)) {
1619 uint pll
= PMU4716_MAINPLL_PLL0
;
1621 /* Remember original core before switch to chipc */
1622 origidx
= si_coreidx(sih
);
1623 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1626 clock
= si_pmu5_clock(sih
, osh
, cc
, pll
, PMU5_MAINPLL_CPU
);
1628 /* Return to original core */
1629 si_setcoreidx(sih
, origidx
);
1631 clock
= si_pmu_si_clock(sih
, osh
);
1636 /* query Memroy clock frequency */
1638 BCMINITFN(si_pmu_mem_clock
)(si_t
*sih
, osl_t
*osh
)
1644 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1646 if ((sih
->pmurev
== 5) || (sih
->pmurev
== 6) ||
1647 (sih
->pmurev
== 7)) {
1648 uint pll
= PMU4716_MAINPLL_PLL0
;
1650 /* Remember original core before switch to chipc */
1651 origidx
= si_coreidx(sih
);
1652 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1655 clock
= si_pmu5_clock(sih
, osh
, cc
, pll
, PMU5_MAINPLL_MEM
);
1657 /* Return to original core */
1658 si_setcoreidx(sih
, origidx
);
1660 clock
= si_pmu_si_clock(sih
, osh
);
1665 /* query ILP clock frequency */
1666 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */
1668 BCMINITFN(si_pmu_ilp_clock
)(si_t
*sih
, osl_t
*osh
)
1670 static uint32 ilpcycles_per_sec
= 0;
1672 if (ISSIM_ENAB(sih
))
1675 if (ilpcycles_per_sec
== 0) {
1676 uint32 start
, end
, delta
;
1677 uint32 origidx
= si_coreidx(sih
);
1678 chipcregs_t
*cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1680 start
= R_REG(osh
, &cc
->pmutimer
);
1681 OSL_DELAY(ILP_CALC_DUR
* 1000);
1682 end
= R_REG(osh
, &cc
->pmutimer
);
1683 delta
= end
>= start
? end
- start
: ~0 - start
+ 1 + end
;
1684 ilpcycles_per_sec
= delta
* (1000 / ILP_CALC_DUR
);
1685 si_setcoreidx(sih
, origidx
);
1688 return ilpcycles_per_sec
;
1691 /* SDIO Pad drive strength to select value mappings */
1693 uint8 strength
; /* Pad Drive Strength in mA */
1694 uint8 sel
; /* Chip-specific select value */
1695 } sdiod_drive_str_t
;
1697 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
1698 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab1
)[] = {
1704 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
1705 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab2
)[] = {
1714 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
1717 BCMINITFN(si_sdiod_drive_strength_init
)(si_t
*sih
, osl_t
*osh
, uint drivestrength
)
1720 uint origidx
, intr_val
;
1721 sdiod_drive_str_t
*str_tab
= NULL
;
1722 uint32 str_mask
= 0;
1723 uint32 str_shift
= 0;
1725 if (!(sih
->cccaps
& CC_CAP_PMU
)) {
1729 /* Remember original core before switch to chipc */
1730 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
1732 switch (SDIOD_DRVSTR_KEY(sih
->chip
, sih
->pmurev
)) {
1733 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 1):
1734 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab1
;
1735 str_mask
= 0x30000000;
1738 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 2):
1739 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 3):
1740 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab2
;
1741 str_mask
= 0x00003800;
1746 PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
1747 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
));
1752 if (str_tab
!= NULL
) {
1753 uint32 drivestrength_sel
= 0;
1754 uint32 cc_data_temp
;
1757 for (i
= 0; str_tab
[i
].strength
!= 0; i
++) {
1758 if (drivestrength
>= str_tab
[i
].strength
) {
1759 drivestrength_sel
= str_tab
[i
].sel
;
1764 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
1765 cc_data_temp
= R_REG(osh
, &cc
->chipcontrol_data
);
1766 cc_data_temp
&= ~str_mask
;
1767 drivestrength_sel
<<= str_shift
;
1768 cc_data_temp
|= drivestrength_sel
;
1769 W_REG(osh
, &cc
->chipcontrol_data
, cc_data_temp
);
1771 PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
1772 drivestrength
, cc_data_temp
));
1775 /* Return to original core */
1776 si_restore_core(sih
, origidx
, intr_val
);
1779 /* initialize PMU */
1781 BCMINITFN(si_pmu_init
)(si_t
*sih
, osl_t
*osh
)
1786 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1788 /* Remember original core before switch to chipc */
1789 origidx
= si_coreidx(sih
);
1790 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1793 if (sih
->pmurev
== 1)
1794 AND_REG(osh
, &cc
->pmucontrol
, ~PCTL_NOILP_ON_WAIT
);
1795 else if (sih
->pmurev
>= 2)
1796 OR_REG(osh
, &cc
->pmucontrol
, PCTL_NOILP_ON_WAIT
);
1798 /* Return to original core */
1799 si_setcoreidx(sih
, origidx
);
1802 /* Return up time in ILP cycles for the given resource. */
1804 BCMINITFN(si_pmu_res_uptime
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint8 rsrc
)
1807 uint up
, i
, dup
, dmax
;
1808 uint32 min_mask
= 0, max_mask
= 0;
1810 /* uptime of resource 'rsrc' */
1811 W_REG(osh
, &cc
->res_table_sel
, rsrc
);
1812 up
= (R_REG(osh
, &cc
->res_updn_timer
) >> 8) & 0xff;
1814 /* direct dependancies of resource 'rsrc' */
1815 deps
= si_pmu_res_deps(sih
, osh
, cc
, PMURES_BIT(rsrc
), FALSE
);
1816 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
1817 if (!(deps
& PMURES_BIT(i
)))
1819 deps
&= ~si_pmu_res_deps(sih
, osh
, cc
, PMURES_BIT(i
), TRUE
);
1821 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
1824 /* max uptime of direct dependancies */
1826 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
1827 if (!(deps
& PMURES_BIT(i
)))
1829 dup
= si_pmu_res_uptime(sih
, osh
, cc
, (uint8
)i
);
1834 PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n",
1835 rsrc
, up
, deps
, dmax
));
1837 return up
+ dmax
+ PMURES_UP_TRANSITION
;
1840 /* Return dependancies (direct or all/indirect) for the given resources */
1842 si_pmu_res_deps(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 rsrcs
, bool all
)
1847 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
1848 if (!(rsrcs
& PMURES_BIT(i
)))
1850 W_REG(osh
, &cc
->res_table_sel
, i
);
1851 deps
|= R_REG(osh
, &cc
->res_dep_mask
);
1854 return !all
? deps
: (deps
? (deps
| si_pmu_res_deps(sih
, osh
, cc
, deps
, TRUE
)) : 0);
1857 /* power up/down OTP through PMU resources if PMU has that bit
1858 * 1. update chipc chipstatus reg
1859 * 2. refresh newly updated OTP content
1862 si_pmu_otp_power(si_t
*sih
, osl_t
*osh
, bool on
)
1866 uint32 rsrcs
= 0; /* rsrcs to turn on/off OTP power */
1868 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1870 #if !defined(WLTEST)
1871 /* Don't do anything if OTP is disabled */
1872 if (si_is_otp_disabled(sih
)) {
1873 PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
1878 /* Remember original core before switch to chipc */
1879 origidx
= si_coreidx(sih
);
1880 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1883 switch (CHIPID(sih
->chip
)) {
1884 case BCM4322_CHIP_ID
:
1885 case BCM43221_CHIP_ID
:
1886 case BCM43231_CHIP_ID
:
1887 case BCM4342_CHIP_ID
:
1888 rsrcs
= PMURES_BIT(RES4322_OTP_PU
);
1890 case BCM4325_CHIP_ID
:
1891 rsrcs
= PMURES_BIT(RES4325_LNLDO2_PU
);
1893 case BCM4319_CHIP_ID
:
1894 rsrcs
= PMURES_BIT(RES4319_OTP_PU
);
1904 /* Figure out the dependancies (exclude min_res_mask) */
1905 uint32 deps
= si_pmu_res_deps(sih
, osh
, cc
, rsrcs
, TRUE
);
1906 uint32 min_mask
= 0, max_mask
= 0;
1907 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
1909 /* Turn on/off the power */
1911 PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", rsrcs
| deps
));
1912 OR_REG(osh
, &cc
->min_res_mask
, (rsrcs
| deps
));
1913 SPINWAIT(!(R_REG(osh
, &cc
->res_state
) & rsrcs
), PMU_MAX_TRANSITION_DLY
);
1914 ASSERT(R_REG(osh
, &cc
->res_state
) & rsrcs
);
1917 PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", rsrcs
| deps
));
1918 AND_REG(osh
, &cc
->min_res_mask
, ~(rsrcs
| deps
));
1921 SPINWAIT((((otps
= R_REG(osh
, &cc
->otpstatus
)) & OTPS_READY
) !=
1922 (on
? OTPS_READY
: 0)), 100);
1923 ASSERT((otps
& OTPS_READY
) == (on
? OTPS_READY
: 0));
1924 if ((otps
& OTPS_READY
) != (on
? OTPS_READY
: 0))
1925 PMU_MSG(("OTP ready bit not %s after wait\n", (on
? "ON" : "OFF")));
1928 /* Return to original core */
1929 si_setcoreidx(sih
, origidx
);
1933 si_pmu_rcal(si_t
*sih
, osl_t
*osh
)
1937 uint rcal_done
, BT_out_of_reset
;
1939 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1941 /* Remember original core before switch to chipc */
1942 origidx
= si_coreidx(sih
);
1943 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1946 switch (CHIPID(sih
->chip
)) {
1947 case BCM4325_CHIP_ID
: {
1952 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
1954 /* Power Down RCAL Block */
1955 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
1957 /* Check if RCAL is already done by BT */
1958 rcal_done
= ((R_REG(osh
, &cc
->chipstatus
)) & 0x8) >> 3;
1960 /* If RCAL already done, note that BT is out of reset */
1961 if (rcal_done
== 1) {
1962 BT_out_of_reset
= 1;
1964 BT_out_of_reset
= 0;
1967 /* Power Up RCAL block */
1968 OR_REG(osh
, &cc
->chipcontrol_data
, 0x04);
1970 /* Wait for completion */
1971 SPINWAIT(0 == (R_REG(osh
, &cc
->chipstatus
) & 0x08), 10 * 1000 * 1000);
1972 ASSERT(R_REG(osh
, &cc
->chipstatus
) & 0x08);
1974 if (BT_out_of_reset
) {
1977 /* Drop the LSB to convert from 5 bit code to 4 bit code */
1978 rcal_code
= (uint8
)(R_REG(osh
, &cc
->chipstatus
) >> 5) & 0x0f;
1981 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
1982 R_REG(osh
, &cc
->chipstatus
), rcal_code
));
1984 /* Write RCal code into pmu_vreg_ctrl[32:29] */
1985 W_REG(osh
, &cc
->regcontrol_addr
, 0);
1986 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~((uint32
)0x07 << 29);
1987 val
|= (uint32
)(rcal_code
& 0x07) << 29;
1988 W_REG(osh
, &cc
->regcontrol_data
, val
);
1989 W_REG(osh
, &cc
->regcontrol_addr
, 1);
1990 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~(uint32
)0x01;
1991 val
|= (uint32
)((rcal_code
>> 3) & 0x01);
1992 W_REG(osh
, &cc
->regcontrol_data
, val
);
1994 /* Write RCal code into pmu_chip_ctrl[33:30] */
1995 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
1996 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~((uint32
)0x03 << 30);
1997 val
|= (uint32
)(rcal_code
& 0x03) << 30;
1998 W_REG(osh
, &cc
->chipcontrol_data
, val
);
1999 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
2000 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~(uint32
)0x03;
2001 val
|= (uint32
)((rcal_code
>> 2) & 0x03);
2002 W_REG(osh
, &cc
->chipcontrol_data
, val
);
2004 /* Set override in pmu_chip_ctrl[29] */
2005 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
2006 OR_REG(osh
, &cc
->chipcontrol_data
, (0x01 << 29));
2008 /* Power off RCal block */
2009 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
2010 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
2018 /* Return to original core */
2019 si_setcoreidx(sih
, origidx
);
2023 si_pmu_spuravoid(si_t
*sih
, osl_t
*osh
, bool spuravoid
)
2026 uint origidx
, intr_val
;
2029 /* Remember original core before switch to chipc */
2030 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
2033 switch (CHIPID(sih
->chip
)) {
2034 case BCM43224_CHIP_ID
:
2035 case BCM43225_CHIP_ID
:
2036 case BCM43421_CHIP_ID
:
2038 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2039 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500010);
2040 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2041 W_REG(osh
, &cc
->pllcontrol_data
, 0x000C0C06);
2042 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2043 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
2044 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2045 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
2046 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2047 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
2048 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2049 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
2051 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2052 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100010);
2053 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2054 W_REG(osh
, &cc
->pllcontrol_data
, 0x000c0c06);
2055 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2056 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
2057 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2058 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
2059 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2060 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
2061 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2062 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
2067 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2069 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2070 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500008);
2071 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2072 W_REG(osh
, &cc
->pllcontrol_data
, 0x0C000C06);
2073 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2074 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
2075 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2076 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
2077 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2078 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
2079 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2080 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
2082 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2083 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100008);
2084 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2085 W_REG(osh
, &cc
->pllcontrol_data
, 0x0c000c06);
2086 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2087 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
2088 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2089 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
2090 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2091 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
2092 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2093 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888855);
2100 case BCM4716_CHIP_ID
:
2101 case BCM4748_CHIP_ID
:
2102 case BCM47162_CHIP_ID
:
2104 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2105 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500060);
2106 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2107 W_REG(osh
, &cc
->pllcontrol_data
, 0x080C0C06);
2108 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2109 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600000);
2110 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2111 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
2112 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2113 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E924);
2114 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2115 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
2117 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2118 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100060);
2119 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2120 W_REG(osh
, &cc
->pllcontrol_data
, 0x080c0c06);
2121 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2122 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000000);
2123 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2124 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
2125 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2126 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
2127 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2128 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
2134 case BCM4322_CHIP_ID
:
2135 case BCM43221_CHIP_ID
:
2136 case BCM43231_CHIP_ID
:
2137 case BCM4342_CHIP_ID
:
2138 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2139 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100070);
2140 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2141 W_REG(osh
, &cc
->pllcontrol_data
, 0x1014140a);
2142 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2143 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888854);
2145 if (spuravoid
) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
2146 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2147 W_REG(osh
, &cc
->pllcontrol_data
, 0x05201828);
2148 } else { /* enable 40/80/160Mhz clock mode */
2149 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2150 W_REG(osh
, &cc
->pllcontrol_data
, 0x05001828);
2155 case BCM4319_CHIP_ID
:
2156 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2157 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100070);
2158 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2159 W_REG(osh
, &cc
->pllcontrol_data
, 0x1014140a);
2160 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2161 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888854);
2163 if (spuravoid
) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
2164 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2165 W_REG(osh
, &cc
->pllcontrol_data
, 0x05201828);
2166 } else { /* enable 40/80/160Mhz clock mode */
2167 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2168 W_REG(osh
, &cc
->pllcontrol_data
, 0x05001828);
2172 PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n",
2173 __FUNCTION__
, bcm_chipname(sih
->chip
, chn
, 8)));
2177 tmp
|= R_REG(osh
, &cc
->pmucontrol
);
2178 W_REG(osh
, &cc
->pmucontrol
, tmp
);
2180 /* Return to original core */
2181 si_restore_core(sih
, origidx
, intr_val
);
2185 si_pmu_gband_spurwar(si_t
*sih
, osl_t
*osh
)
2188 uint origidx
, intr_val
;
2189 uint32 cc_clk_ctl_st
;
2190 uint32 minmask
, maxmask
;
2192 if (CHIPID(sih
->chip
) == BCM43222_CHIP_ID
) {
2193 /* Remember original core before switch to chipc */
2194 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
2197 /* Remove force HT and HT Avail Request from chipc core */
2198 cc_clk_ctl_st
= R_REG(osh
, &cc
->clk_ctl_st
);
2199 AND_REG(osh
, &cc
->clk_ctl_st
, ~(CCS_FORCEHT
| CCS_HTAREQ
));
2201 minmask
= R_REG(osh
, &cc
->min_res_mask
);
2202 maxmask
= R_REG(osh
, &cc
->max_res_mask
);
2204 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
2205 /* Have to remove HT Avail request before powering off PLL */
2206 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
2207 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
2208 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2209 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
2210 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
2212 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2214 /* Change backplane clock speed from 96 MHz to 80 MHz */
2215 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_PLL_PLLCTL2
);
2216 W_REG(osh
, &cc
->pllcontrol_data
, (R_REG(osh
, &cc
->pllcontrol_data
) &
2217 ~(PMU2_PLL_PC2_M6DIV_MASK
)) |
2218 (0xc << PMU2_PLL_PC2_M6DIV_SHIFT
));
2220 /* Reduce the driver strengths of the phyclk160, adcclk80, and phyck80
2221 * clocks from 0x8 to 0x1
2223 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_PLL_PLLCTL5
);
2224 W_REG(osh
, &cc
->pllcontrol_data
, (R_REG(osh
, &cc
->pllcontrol_data
) &
2225 ~(PMU2_PLL_PC5_CLKDRIVE_CH1_MASK
|
2226 PMU2_PLL_PC5_CLKDRIVE_CH2_MASK
|
2227 PMU2_PLL_PC5_CLKDRIVE_CH3_MASK
|
2228 PMU2_PLL_PC5_CLKDRIVE_CH4_MASK
)) |
2229 ((1 << PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT
) |
2230 (1 << PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT
) |
2231 (1 << PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT
) |
2232 (1 << PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT
)));
2234 W_REG(osh
, &cc
->pmucontrol
, R_REG(osh
, &cc
->pmucontrol
) | PCTL_PLL_PLLCTL_UPD
);
2236 /* Restore min_res_mask and max_res_mask */
2238 W_REG(osh
, &cc
->max_res_mask
, maxmask
);
2240 W_REG(osh
, &cc
->min_res_mask
, minmask
);
2242 /* Make sure the PLL is on. Spinwait until the HTAvail is True */
2243 SPINWAIT(~(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
), PMU_MAX_TRANSITION_DLY
);
2244 ASSERT((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2246 /* Restore force HT and HT Avail Request on the chipc core */
2247 W_REG(osh
, &cc
->clk_ctl_st
, cc_clk_ctl_st
);
2249 /* Return to original core */
2250 si_restore_core(sih
, origidx
, intr_val
);
2255 si_pmu_is_otp_powered(si_t
*sih
, osl_t
*osh
)
2261 /* Retrieve OTP region info */
2262 idx
= si_coreidx(sih
);
2263 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2266 switch (CHIPID(sih
->chip
)) {
2267 case BCM4322_CHIP_ID
:
2268 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
2269 case BCM4342_CHIP_ID
:
2270 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4322_OTP_PU
)) != 0;
2272 case BCM4325_CHIP_ID
:
2273 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4325_LNLDO2_PU
)) != 0;
2275 case BCM4319_CHIP_ID
:
2276 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4319_OTP_PU
)) != 0;
2279 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
2280 * Use OTP_INIT command to reset/refresh state.
2282 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2283 case BCM43224_CHIP_ID
:
2284 case BCM43225_CHIP_ID
:
2285 case BCM43421_CHIP_ID
:
2291 si_setcoreidx(sih
, idx
);
2295 /* initialize PMU chip controls */
2297 BCMINITFN(si_pmu_chip_init
)(si_t
*sih
, osl_t
*osh
)
2299 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2302 /* initialize PMU switch/regulators */
2304 BCMINITFN(si_pmu_swreg_init
)(si_t
*sih
, osl_t
*osh
)
2306 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2308 switch (CHIPID(sih
->chip
)) {
2309 case BCM4325_CHIP_ID
:
2310 if ((sih
->chiprev
>= 3) &&
2311 (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
2312 CST4325_PMUTOP_2B_SHIFT
) == 1)) {
2313 /* Bump CLDO PWM output voltage to 1.25V */
2314 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_PWM
, 0xf);
2315 /* Bump CBUCK PWM output voltage to 1.5V */
2316 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_PWM
, 0xb);
2324 /* Wait for a particular clock level to be on the backplane */
2326 si_pmu_waitforclk_on_backplane(si_t
*sih
, osl_t
*osh
, uint32 clk
, uint32 delay
)
2331 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2333 /* Remember original core before switch to chipc */
2334 origidx
= si_coreidx(sih
);
2335 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2339 SPINWAIT(((R_REG(osh
, &cc
->pmustatus
) & clk
) != clk
), delay
);
2341 /* Return to original core */
2342 si_setcoreidx(sih
, origidx
);
2344 return (R_REG(osh
, &cc
->pmustatus
) & clk
);