2 * Misc utility routines for accessing PMU corerev specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * $Id: hndpmu.c,v 1.234.2.35 2011-02-11 21:35:40 Exp $
33 #define PMU_ERROR(args) printf args
35 #define PMU_ERROR(args)
36 #endif /* BCMDBG_ERR */
39 #define PMU_MSG(args) printf args
44 /* To check in verbose debugging messages not intended
45 * to be on except on private builds.
47 #define PMU_NONE(args)
49 /* PLL controls/clocks */
50 static void si_pmu0_pllinit0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
);
51 static uint32
si_pmu0_alpclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
52 #if !defined(_CFE_) || defined(CFG_WL)
53 static uint32
si_pmu0_cpuclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
54 static void si_pmu1_pllinit0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
);
55 static uint32
si_pmu1_cpuclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
56 static uint32
si_pmu1_alpclk0(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
);
59 static bool si_pmu_res_depfltr_bb(si_t
*sih
);
60 static bool si_pmu_res_depfltr_ncb(si_t
*sih
);
61 static bool si_pmu_res_depfltr_paldo(si_t
*sih
);
62 static bool si_pmu_res_depfltr_npaldo(si_t
*sih
);
63 static uint32
si_pmu_res_deps(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 rsrcs
, bool all
);
64 static uint
si_pmu_res_uptime(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint8 rsrc
);
65 static void si_pmu_res_masks(si_t
*sih
, uint32
*pmin
, uint32
*pmax
);
66 static void si_pmu_spuravoid_pllupdate(si_t
*sih
, chipcregs_t
*cc
, osl_t
*osh
, uint8 spuravoid
);
68 void si_pmu_set_4330_plldivs(si_t
*sih
, uint8 dacrate
);
69 #endif /* !_CFE_ || CFG_WL */
72 #define FVCO_880 880000 /* 880MHz */
73 #define FVCO_1760 1760000 /* 1760MHz */
74 #define FVCO_1440 1440000 /* 1440MHz */
75 #define FVCO_960 960000 /* 960MHz */
77 /* Read/write a chipcontrol reg */
79 si_pmu_chipcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
81 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol_addr
), ~0, reg
);
82 return si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol_data
), mask
, val
);
85 /* Read/write a regcontrol reg */
87 si_pmu_regcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
89 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, regcontrol_addr
), ~0, reg
);
90 return si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, regcontrol_data
), mask
, val
);
93 /* Read/write a pllcontrol reg */
95 si_pmu_pllcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
97 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pllcontrol_addr
), ~0, reg
);
98 return si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pllcontrol_data
), mask
, val
);
103 si_pmu_pllupd(si_t
*sih
)
105 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pmucontrol
),
106 PCTL_PLL_PLLCTL_UPD
, PCTL_PLL_PLLCTL_UPD
);
111 si_pmu_pllreset(si_t
*sih
)
117 /* Remember original core before switch to chipc */
118 origidx
= si_coreidx(sih
);
119 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
122 res_mask
= PMURES_BIT(RES4330_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL
) |
123 PMURES_BIT(RES4330_HT_AVAIL
);
125 AND_REG(si_osh(sih
), &cc
->min_res_mask
, ~(res_mask
));
126 AND_REG(si_osh(sih
), &cc
->max_res_mask
, ~(res_mask
));
127 OR_REG(si_osh(sih
), &cc
->pmucontrol
, PCTL_PLL_PLLCTL_UPD
);
128 OR_REG(si_osh(sih
), &cc
->max_res_mask
, res_mask
);
130 /* Return to original core */
131 si_setcoreidx(sih
, origidx
);
134 /* Setup switcher voltage */
136 BCMATTACHFN(si_pmu_set_switcher_voltage
)(si_t
*sih
, osl_t
*osh
,
137 uint8 bb_voltage
, uint8 rf_voltage
)
142 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
144 /* Remember original core before switch to chipc */
145 origidx
= si_coreidx(sih
);
146 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
149 W_REG(osh
, &cc
->regcontrol_addr
, 0x01);
150 W_REG(osh
, &cc
->regcontrol_data
, (uint32
)(bb_voltage
& 0x1f) << 22);
152 W_REG(osh
, &cc
->regcontrol_addr
, 0x00);
153 W_REG(osh
, &cc
->regcontrol_data
, (uint32
)(rf_voltage
& 0x1f) << 14);
155 /* Return to original core */
156 si_setcoreidx(sih
, origidx
);
160 BCMATTACHFN(si_pmu_set_ldo_voltage
)(si_t
*sih
, osl_t
*osh
, uint8 ldo
, uint8 voltage
)
162 uint8 sr_cntl_shift
= 0, rc_shift
= 0, shift
= 0, mask
= 0;
165 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
167 switch (CHIPID(sih
->chip
)) {
168 case BCM4328_CHIP_ID
:
169 case BCM5354_CHIP_ID
:
171 case SET_LDO_VOLTAGE_LDO1
:
177 case SET_LDO_VOLTAGE_LDO2
:
182 case SET_LDO_VOLTAGE_LDO3
:
187 case SET_LDO_VOLTAGE_PAREF
:
197 case BCM4312_CHIP_ID
:
199 case SET_LDO_VOLTAGE_PAREF
:
209 case BCM4325_CHIP_ID
:
211 case SET_LDO_VOLTAGE_CLDO_PWM
:
216 case SET_LDO_VOLTAGE_CLDO_BURST
:
221 case SET_LDO_VOLTAGE_CBUCK_PWM
:
225 /* Bit 116 & 119 are inverted in CLB for opt 2b */
226 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
227 CST4325_PMUTOP_2B_SHIFT
) == 1)
230 case SET_LDO_VOLTAGE_CBUCK_BURST
:
234 /* Bit 121 & 124 are inverted in CLB for opt 2b */
235 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
236 CST4325_PMUTOP_2B_SHIFT
) == 1)
239 case SET_LDO_VOLTAGE_LNLDO1
:
244 case SET_LDO_VOLTAGE_LNLDO2_SEL
:
254 case BCM4336_CHIP_ID
:
256 case SET_LDO_VOLTAGE_CLDO_PWM
:
261 case SET_LDO_VOLTAGE_CLDO_BURST
:
266 case SET_LDO_VOLTAGE_LNLDO1
:
276 case BCM4330_CHIP_ID
:
278 case SET_LDO_VOLTAGE_CBUCK_PWM
:
288 case BCM4331_CHIP_ID
:
290 case SET_LDO_VOLTAGE_PAREF
:
305 shift
= sr_cntl_shift
+ rc_shift
;
307 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, regcontrol_addr
),
309 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, regcontrol_data
),
310 mask
<< shift
, (voltage
& mask
) << shift
);
314 si_pmu_paref_ldo_enable(si_t
*sih
, osl_t
*osh
, bool enable
)
318 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
320 switch (CHIPID(sih
->chip
)) {
321 case BCM4328_CHIP_ID
:
322 ldo
= RES4328_PA_REF_LDO
;
324 case BCM5354_CHIP_ID
:
325 ldo
= RES5354_PA_REF_LDO
;
327 case BCM4312_CHIP_ID
:
328 ldo
= RES4312_PA_REF_LDO
;
334 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, min_res_mask
),
335 PMURES_BIT(ldo
), enable
? PMURES_BIT(ldo
) : 0);
338 #if !defined(_CFE_) || defined(CFG_WL)
339 /* d11 slow to fast clock transition time in slow clock cycles */
340 #define D11SCC_SLOW2FAST_TRANSITION 2
343 BCMINITFN(si_pmu_fast_pwrup_delay
)(si_t
*sih
, osl_t
*osh
)
345 uint delay
= PMU_MAX_TRANSITION_DLY
;
351 chn
[0] = 0; /* to suppress compile error */
354 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
356 /* Remember original core before switch to chipc */
357 origidx
= si_coreidx(sih
);
358 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
361 switch (CHIPID(sih
->chip
)) {
362 case BCM4312_CHIP_ID
:
363 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
364 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
365 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43420_CHIP_ID
:
366 case BCM43421_CHIP_ID
:
367 case BCM43226_CHIP_ID
:
368 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
369 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
370 case BCM4331_CHIP_ID
:
371 case BCM43431_CHIP_ID
:
372 case BCM43227_CHIP_ID
:
373 case BCM43228_CHIP_ID
:
374 case BCM43428_CHIP_ID
:
375 case BCM6362_CHIP_ID
:
376 case BCM4342_CHIP_ID
:
377 case BCM4313_CHIP_ID
:
378 delay
= ISSIM_ENAB(sih
) ? 70 : 3700;
380 case BCM4328_CHIP_ID
:
383 case BCM4325_CHIP_ID
:
387 uint32 ilp
= si_ilp_clock(sih
);
388 delay
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4325_HT_AVAIL
) +
389 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
390 delay
= (11 * delay
) / 10;
393 case BCM4329_CHIP_ID
:
397 uint32 ilp
= si_ilp_clock(sih
);
398 delay
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4329_HT_AVAIL
) +
399 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
400 delay
= (11 * delay
) / 10;
403 case BCM4315_CHIP_ID
:
407 uint32 ilp
= si_ilp_clock(sih
);
408 delay
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4315_HT_AVAIL
) +
409 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
410 delay
= (11 * delay
) / 10;
413 case BCM4319_CHIP_ID
:
418 /* For USB HT is always available, even durring IEEE PS,
419 * so need minimal delay
422 #else /* BCMUSBDEV */
423 /* For SDIO, total delay in getting HT available */
424 /* Adjusted for uptime XTAL=672us, HTAVail=128us */
425 uint32 ilp
= si_ilp_clock(sih
);
426 delay
= si_pmu_res_uptime(sih
, osh
, cc
, RES4319_HT_AVAIL
);
427 PMU_MSG(("si_ilp_clock (Hz): %u delay (ilp clks): %u\n", ilp
, delay
));
428 delay
= (delay
+ D11SCC_SLOW2FAST_TRANSITION
) * (1000000 / ilp
);
429 PMU_MSG(("delay (us): %u\n", delay
));
430 delay
= (11 * delay
) / 10;
431 PMU_MSG(("delay (us): %u\n", delay
));
432 /* VDDIO_RF por delay = 3.4ms */
433 if (delay
< 3400) delay
= 3400;
434 #endif /* BCMUSBDEV */
437 case BCM4336_CHIP_ID
:
441 uint32 ilp
= si_ilp_clock(sih
);
442 delay
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4336_HT_AVAIL
) +
443 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
444 delay
= (11 * delay
) / 10;
447 case BCM4330_CHIP_ID
:
451 uint32 ilp
= si_ilp_clock(sih
);
452 delay
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4330_HT_AVAIL
) +
453 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
454 delay
= (11 * delay
) / 10;
461 /* PMU_MSG(("si_pmu_fast_pwrup_delay: chip %s rev %d delay %d\n",
462 * bcm_chipname(sih->chip, chn, 8), sih->chiprev, delay));
465 /* Return to original core */
466 si_setcoreidx(sih
, origidx
);
468 return (uint16
)delay
;
470 #endif /* !_CFE_ || CFG_WL */
473 BCMATTACHFN(si_pmu_force_ilp
)(si_t
*sih
, osl_t
*osh
, bool force
)
477 uint32 oldpmucontrol
;
479 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
481 /* Remember original core before switch to chipc */
482 origidx
= si_coreidx(sih
);
483 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
486 oldpmucontrol
= R_REG(osh
, &cc
->pmucontrol
);
488 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
&
489 ~(PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
491 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
|
492 (PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
494 /* Return to original core */
495 si_setcoreidx(sih
, origidx
);
497 return oldpmucontrol
;
500 /* Setup resource up/down timers */
506 /* Change resource dependancies masks */
508 uint32 res_mask
; /* resources (chip specific) */
509 int8 action
; /* action */
510 uint32 depend_mask
; /* changes to the dependancies mask */
511 bool (*filter
)(si_t
*sih
); /* action is taken when filter is NULL or return TRUE */
514 /* Resource dependancies mask change action */
515 #define RES_DEPEND_SET 0 /* Override the dependancies mask */
516 #define RES_DEPEND_ADD 1 /* Add to the dependancies mask */
517 #define RES_DEPEND_REMOVE -1 /* Remove from the dependancies mask */
519 #if !defined(_CFE_) || defined(CFG_WL)
520 static const pmu_res_updown_t
BCMATTACHDATA(bcm4328a0_res_updown
)[] = {
521 { RES4328_EXT_SWITCHER_PWM
, 0x0101 },
522 { RES4328_BB_SWITCHER_PWM
, 0x1f01 },
523 { RES4328_BB_SWITCHER_BURST
, 0x010f },
524 { RES4328_BB_EXT_SWITCHER_BURST
, 0x0101 },
525 { RES4328_ILP_REQUEST
, 0x0202 },
526 { RES4328_RADIO_SWITCHER_PWM
, 0x0f01 },
527 { RES4328_RADIO_SWITCHER_BURST
, 0x0f01 },
528 { RES4328_ROM_SWITCH
, 0x0101 },
529 { RES4328_PA_REF_LDO
, 0x0f01 },
530 { RES4328_RADIO_LDO
, 0x0f01 },
531 { RES4328_AFE_LDO
, 0x0f01 },
532 { RES4328_PLL_LDO
, 0x0f01 },
533 { RES4328_BG_FILTBYP
, 0x0101 },
534 { RES4328_TX_FILTBYP
, 0x0101 },
535 { RES4328_RX_FILTBYP
, 0x0101 },
536 { RES4328_XTAL_PU
, 0x0101 },
537 { RES4328_XTAL_EN
, 0xa001 },
538 { RES4328_BB_PLL_FILTBYP
, 0x0101 },
539 { RES4328_RF_PLL_FILTBYP
, 0x0101 },
540 { RES4328_BB_PLL_PU
, 0x0701 }
543 static const pmu_res_depend_t
BCMATTACHDATA(bcm4328a0_res_depend
)[] = {
544 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
546 PMURES_BIT(RES4328_ILP_REQUEST
),
548 PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) | PMURES_BIT(RES4328_BB_SWITCHER_PWM
),
553 static const pmu_res_updown_t
BCMATTACHDATA(bcm4325a0_res_updown_qt
)[] = {
554 { RES4325_HT_AVAIL
, 0x0300 },
555 { RES4325_BBPLL_PWRSW_PU
, 0x0101 },
556 { RES4325_RFPLL_PWRSW_PU
, 0x0101 },
557 { RES4325_ALP_AVAIL
, 0x0100 },
558 { RES4325_XTAL_PU
, 0x1000 },
559 { RES4325_LNLDO1_PU
, 0x0800 },
560 { RES4325_CLDO_CBUCK_PWM
, 0x0101 },
561 { RES4325_CBUCK_PWM
, 0x0803 }
564 static const pmu_res_updown_t
BCMATTACHDATA(bcm4325a0_res_updown
)[] = {
565 { RES4325_XTAL_PU
, 0x1501 }
568 static const pmu_res_depend_t
BCMATTACHDATA(bcm4325a0_res_depend
)[] = {
569 /* Adjust OTP PU resource dependencies - remove BB BURST */
571 PMURES_BIT(RES4325_OTP_PU
),
573 PMURES_BIT(RES4325_BUCK_BOOST_BURST
),
576 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
578 PMURES_BIT(RES4325_ALP_AVAIL
) | PMURES_BIT(RES4325_HT_AVAIL
),
580 PMURES_BIT(RES4325_BUCK_BOOST_BURST
) | PMURES_BIT(RES4325_BUCK_BOOST_PWM
),
581 si_pmu_res_depfltr_bb
583 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
585 PMURES_BIT(RES4325_HT_AVAIL
),
587 PMURES_BIT(RES4325_RX_PWRSW_PU
) | PMURES_BIT(RES4325_TX_PWRSW_PU
) |
588 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
),
591 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
593 PMURES_BIT(RES4325_ILP_REQUEST
) | PMURES_BIT(RES4325_ABUCK_BURST
) |
594 PMURES_BIT(RES4325_ABUCK_PWM
) | PMURES_BIT(RES4325_LNLDO1_PU
) |
595 PMURES_BIT(RES4325C1_LNLDO2_PU
) | PMURES_BIT(RES4325_XTAL_PU
) |
596 PMURES_BIT(RES4325_ALP_AVAIL
) | PMURES_BIT(RES4325_RX_PWRSW_PU
) |
597 PMURES_BIT(RES4325_TX_PWRSW_PU
) | PMURES_BIT(RES4325_RFPLL_PWRSW_PU
) |
598 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
) |
599 PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
),
601 PMURES_BIT(RES4325B0_CBUCK_LPOM
) | PMURES_BIT(RES4325B0_CBUCK_BURST
) |
602 PMURES_BIT(RES4325B0_CBUCK_PWM
),
603 si_pmu_res_depfltr_ncb
607 static const pmu_res_updown_t
BCMATTACHDATA(bcm4315a0_res_updown_qt
)[] = {
608 { RES4315_HT_AVAIL
, 0x0101 },
609 { RES4315_XTAL_PU
, 0x0100 },
610 { RES4315_LNLDO1_PU
, 0x0100 },
611 { RES4315_PALDO_PU
, 0x0100 },
612 { RES4315_CLDO_PU
, 0x0100 },
613 { RES4315_CBUCK_PWM
, 0x0100 },
614 { RES4315_CBUCK_BURST
, 0x0100 },
615 { RES4315_CBUCK_LPOM
, 0x0100 }
618 static const pmu_res_updown_t
BCMATTACHDATA(bcm4315a0_res_updown
)[] = {
619 { RES4315_XTAL_PU
, 0x2501 }
622 static const pmu_res_depend_t
BCMATTACHDATA(bcm4315a0_res_depend
)[] = {
623 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
625 PMURES_BIT(RES4315_OTP_PU
),
627 PMURES_BIT(RES4315_PALDO_PU
),
628 si_pmu_res_depfltr_npaldo
630 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
632 PMURES_BIT(RES4315_ALP_AVAIL
) | PMURES_BIT(RES4315_HT_AVAIL
),
634 PMURES_BIT(RES4315_PALDO_PU
),
635 si_pmu_res_depfltr_paldo
637 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
639 PMURES_BIT(RES4315_HT_AVAIL
),
641 PMURES_BIT(RES4315_RX_PWRSW_PU
) | PMURES_BIT(RES4315_TX_PWRSW_PU
) |
642 PMURES_BIT(RES4315_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4315_AFE_PWRSW_PU
),
645 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
647 PMURES_BIT(RES4315_CLDO_PU
) | PMURES_BIT(RES4315_ILP_REQUEST
) |
648 PMURES_BIT(RES4315_LNLDO1_PU
) | PMURES_BIT(RES4315_OTP_PU
) |
649 PMURES_BIT(RES4315_LNLDO2_PU
) | PMURES_BIT(RES4315_XTAL_PU
) |
650 PMURES_BIT(RES4315_ALP_AVAIL
) | PMURES_BIT(RES4315_RX_PWRSW_PU
) |
651 PMURES_BIT(RES4315_TX_PWRSW_PU
) | PMURES_BIT(RES4315_RFPLL_PWRSW_PU
) |
652 PMURES_BIT(RES4315_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4315_AFE_PWRSW_PU
) |
653 PMURES_BIT(RES4315_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4315_HT_AVAIL
),
655 PMURES_BIT(RES4315_CBUCK_LPOM
) | PMURES_BIT(RES4315_CBUCK_BURST
) |
656 PMURES_BIT(RES4315_CBUCK_PWM
),
657 si_pmu_res_depfltr_ncb
661 static const pmu_res_updown_t
BCMATTACHDATA(bcm4329_res_updown
)[] = {
662 { RES4329_XTAL_PU
, 0x1501 },
663 { RES4329_PALDO_PU
, 0x3501 }
666 static const pmu_res_depend_t
BCMATTACHDATA(bcm4329_res_depend
)[] = {
667 /* Make lnldo1 independant of CBUCK_PWM and CBUCK_BURST */
669 PMURES_BIT(RES4329_LNLDO1_PU
),
671 PMURES_BIT(RES4329_CBUCK_PWM
) | PMURES_BIT(RES4329_CBUCK_BURST
),
675 PMURES_BIT(RES4329_CBUCK_BURST
),
677 PMURES_BIT(RES4329_CBUCK_LPOM
) | PMURES_BIT(RES4329_PALDO_PU
),
681 PMURES_BIT(RES4329_BBPLL_PWRSW_PU
),
683 PMURES_BIT(RES4329_RX_PWRSW_PU
) | PMURES_BIT(RES4329_TX_PWRSW_PU
) |
684 PMURES_BIT(RES4329_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4329_AFE_PWRSW_PU
),
687 /* Adjust HT Avail resource dependencies */
689 PMURES_BIT(RES4329_HT_AVAIL
),
691 PMURES_BIT(RES4329_PALDO_PU
) |
692 PMURES_BIT(RES4329_RX_PWRSW_PU
) | PMURES_BIT(RES4329_TX_PWRSW_PU
) |
693 PMURES_BIT(RES4329_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4329_AFE_PWRSW_PU
),
698 static const pmu_res_updown_t
BCMATTACHDATA(bcm4319a0_res_updown_qt
)[] = {
699 { RES4319_HT_AVAIL
, 0x0101 },
700 { RES4319_XTAL_PU
, 0x0100 },
701 { RES4319_LNLDO1_PU
, 0x0100 },
702 { RES4319_PALDO_PU
, 0x0100 },
703 { RES4319_CLDO_PU
, 0x0100 },
704 { RES4319_CBUCK_PWM
, 0x0100 },
705 { RES4319_CBUCK_BURST
, 0x0100 },
706 { RES4319_CBUCK_LPOM
, 0x0100 }
709 static const pmu_res_updown_t
BCMATTACHDATA(bcm4319a0_res_updown
)[] = {
710 { RES4319_XTAL_PU
, 0x3f01 }
713 static const pmu_res_depend_t
BCMATTACHDATA(bcm4319a0_res_depend
)[] = {
714 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
716 PMURES_BIT(RES4319_OTP_PU
),
718 PMURES_BIT(RES4319_PALDO_PU
),
719 si_pmu_res_depfltr_npaldo
721 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
723 PMURES_BIT(RES4319_HT_AVAIL
),
725 PMURES_BIT(RES4319_PALDO_PU
),
726 si_pmu_res_depfltr_paldo
728 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
730 PMURES_BIT(RES4319_HT_AVAIL
),
732 PMURES_BIT(RES4319_RX_PWRSW_PU
) | PMURES_BIT(RES4319_TX_PWRSW_PU
) |
733 PMURES_BIT(RES4319_RFPLL_PWRSW_PU
) |
734 PMURES_BIT(RES4319_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4319_AFE_PWRSW_PU
),
739 static const pmu_res_updown_t
BCMATTACHDATA(bcm4336a0_res_updown_qt
)[] = {
740 { RES4336_HT_AVAIL
, 0x0101 },
741 { RES4336_XTAL_PU
, 0x0100 },
742 { RES4336_CLDO_PU
, 0x0100 },
743 { RES4336_CBUCK_PWM
, 0x0100 },
744 { RES4336_CBUCK_BURST
, 0x0100 },
745 { RES4336_CBUCK_LPOM
, 0x0100 }
748 static const pmu_res_updown_t
BCMATTACHDATA(bcm4336a0_res_updown
)[] = {
749 { RES4336_HT_AVAIL
, 0x0D01}
752 static const pmu_res_depend_t
BCMATTACHDATA(bcm4336a0_res_depend
)[] = {
753 /* Just a dummy entry for now */
755 PMURES_BIT(RES4336_RSVD
),
762 static const pmu_res_updown_t
BCMATTACHDATA(bcm4330a0_res_updown_qt
)[] = {
763 { RES4330_HT_AVAIL
, 0x0101 },
764 { RES4330_XTAL_PU
, 0x0100 },
765 { RES4330_CLDO_PU
, 0x0100 },
766 { RES4330_CBUCK_PWM
, 0x0100 },
767 { RES4330_CBUCK_BURST
, 0x0100 },
768 { RES4330_CBUCK_LPOM
, 0x0100 }
771 static const pmu_res_updown_t
BCMATTACHDATA(bcm4330a0_res_updown
)[] = {
772 { RES4330_HT_AVAIL
, 0x0e02}
775 static const pmu_res_depend_t
BCMATTACHDATA(bcm4330a0_res_depend
)[] = {
776 /* Just a dummy entry for now */
778 PMURES_BIT(RES4330_HT_AVAIL
),
785 /* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
787 BCMATTACHFN(si_pmu_res_depfltr_bb
)(si_t
*sih
)
789 return (sih
->boardflags
& BFL_BUCKBOOST
) != 0;
792 /* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
794 BCMATTACHFN(si_pmu_res_depfltr_ncb
)(si_t
*sih
)
796 if (CHIPID(sih
->chip
) == BCM4325_CHIP_ID
)
797 return (CHIPREV(sih
->chiprev
) >= 2) && ((sih
->boardflags
& BFL_NOCBUCK
) != 0);
798 return ((sih
->boardflags
& BFL_NOCBUCK
) != 0);
801 /* TRUE if the power topology uses the PALDO */
803 BCMATTACHFN(si_pmu_res_depfltr_paldo
)(si_t
*sih
)
805 return (sih
->boardflags
& BFL_PALDO
) != 0;
808 /* TRUE if the power topology doesn't use the PALDO */
810 BCMATTACHFN(si_pmu_res_depfltr_npaldo
)(si_t
*sih
)
812 return (sih
->boardflags
& BFL_PALDO
) == 0;
815 #define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
816 sih->boardtype == BCM94325BGABU_BOARD)
818 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
820 si_pmu_res_masks(si_t
*sih
, uint32
*pmin
, uint32
*pmax
)
822 uint32 min_mask
= 0, max_mask
= 0;
827 rsrcs
= (sih
->pmucaps
& PCAP_RC_MASK
) >> PCAP_RC_SHIFT
;
829 /* determine min/max rsrc masks */
830 switch (CHIPID(sih
->chip
)) {
831 case BCM4328_CHIP_ID
:
832 /* Down to ILP request */
833 min_mask
= PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) |
834 PMURES_BIT(RES4328_BB_SWITCHER_PWM
) |
835 PMURES_BIT(RES4328_XTAL_EN
);
836 /* Allow (but don't require) PLL to turn on */
839 case BCM5354_CHIP_ID
:
840 /* Allow (but don't require) PLL to turn on */
843 case BCM4325_CHIP_ID
:
844 ASSERT(CHIPREV(sih
->chiprev
) >= 2);
845 /* Minimum rsrcs to work in sleep mode */
846 if (!(sih
->boardflags
& BFL_NOCBUCK
))
847 min_mask
|= PMURES_BIT(RES4325B0_CBUCK_LPOM
);
848 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
849 CST4325_PMUTOP_2B_SHIFT
) == 1)
850 min_mask
|= PMURES_BIT(RES4325B0_CLDO_PU
);
851 if (!si_is_otp_disabled(sih
))
852 min_mask
|= PMURES_BIT(RES4325_OTP_PU
);
853 /* Leave buck boost on in burst mode for certain boards */
854 if ((sih
->boardflags
& BFL_BUCKBOOST
) && (BCM94325_BBVDDIOSD_BOARDS(sih
)))
855 min_mask
|= PMURES_BIT(RES4325_BUCK_BOOST_BURST
);
856 /* Allow all resources to be turned on upon requests */
857 max_mask
= ~(~0 << rsrcs
);
859 case BCM4312_CHIP_ID
:
860 /* default min_mask = 0x80000cbb is wrong */
864 * pmu_res_updown_table_sz = 0;
865 * pmu_res_depend_table_sz = 0;
868 case BCM4322_CHIP_ID
:
869 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
870 case BCM4342_CHIP_ID
:
871 if (CHIPREV(sih
->chiprev
) < 2) {
872 /* request ALP(can skip for A1) */
873 min_mask
= PMURES_BIT(RES4322_RF_LDO
) |
874 PMURES_BIT(RES4322_XTAL_PU
) |
875 PMURES_BIT(RES4322_ALP_AVAIL
);
876 if (BUSTYPE(sih
->bustype
) == SI_BUS
) {
877 min_mask
+= PMURES_BIT(RES4322_SI_PLL_ON
) |
878 PMURES_BIT(RES4322_HT_SI_AVAIL
) |
879 PMURES_BIT(RES4322_PHY_PLL_ON
) |
880 PMURES_BIT(RES4322_OTP_PU
) |
881 PMURES_BIT(RES4322_HT_PHY_AVAIL
);
886 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
887 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
888 case BCM43226_CHIP_ID
: case BCM43420_CHIP_ID
:
889 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
890 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
891 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
892 case BCM6362_CHIP_ID
:
893 /* use chip default */
896 case BCM4329_CHIP_ID
:
898 /* Down to save the power. */
899 if (CHIPREV(sih
->chiprev
) >= 0x2) {
900 min_mask
= PMURES_BIT(RES4329_CBUCK_LPOM
) |
901 PMURES_BIT(RES4329_LNLDO1_PU
) | PMURES_BIT(RES4329_CLDO_PU
);
903 min_mask
= PMURES_BIT(RES4329_CBUCK_LPOM
) | PMURES_BIT(RES4329_CLDO_PU
);
905 if (!si_is_otp_disabled(sih
))
906 min_mask
|= PMURES_BIT(RES4329_OTP_PU
);
907 /* Allow (but don't require) PLL to turn on */
911 case BCM4315_CHIP_ID
:
912 /* We only need a few resources to be kept on all the time */
913 if (!(sih
->boardflags
& BFL_NOCBUCK
))
914 min_mask
= PMURES_BIT(RES4315_CBUCK_LPOM
);
915 min_mask
|= PMURES_BIT(RES4315_CLDO_PU
);
916 /* Allow everything else to be turned on upon requests */
917 max_mask
= ~(~0 << rsrcs
);
919 case BCM4319_CHIP_ID
:
920 #ifdef BCM_BOOTLOADER
921 /* Initialize to ResInitMode3 for bootloader */
922 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
923 PMURES_BIT(RES4319_CBUCK_BURST
) |
924 PMURES_BIT(RES4319_CBUCK_PWM
) |
925 PMURES_BIT(RES4319_CLDO_PU
) |
926 PMURES_BIT(RES4319_PALDO_PU
) |
927 PMURES_BIT(RES4319_LNLDO1_PU
) |
928 PMURES_BIT(RES4319_XTAL_PU
) |
929 PMURES_BIT(RES4319_ALP_AVAIL
) |
930 PMURES_BIT(RES4319_RFPLL_PWRSW_PU
) |
931 PMURES_BIT(RES4319_BBPLL_PWRSW_PU
) |
932 PMURES_BIT(RES4319_HT_AVAIL
);
934 /* We only need a few resources to be kept on all the time */
936 /* For USB HT is always available, even durring IEEE PS, so RF switches are
937 * made independent of HT Avail and are by default on, but can be made off
938 * during IEEE PS by ucode (and then on)
940 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
941 PMURES_BIT(RES4319_CLDO_PU
) |
942 PMURES_BIT(RES4319_RX_PWRSW_PU
) | PMURES_BIT(RES4319_TX_PWRSW_PU
) |
943 PMURES_BIT(RES4319_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4319_AFE_PWRSW_PU
);
945 /* For SDIO RF switches are automatically made on off along with HT */
946 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
947 PMURES_BIT(RES4319_CLDO_PU
);
949 #endif /* BCM_BOOTLOADER */
951 /* Allow everything else to be turned on upon requests */
952 max_mask
= ~(~0 << rsrcs
);
954 case BCM4336_CHIP_ID
:
955 /* Down to save the power. */
956 min_mask
= PMURES_BIT(RES4336_CBUCK_LPOM
) | PMURES_BIT(RES4336_CLDO_PU
) |
957 PMURES_BIT(RES4336_LDO3P3_PU
) | PMURES_BIT(RES4336_OTP_PU
) |
958 PMURES_BIT(RES4336_DIS_INT_RESET_PD
);
959 /* Allow (but don't require) PLL to turn on */
960 max_mask
= 0x1ffffff;
963 case BCM4330_CHIP_ID
:
964 /* Down to save the power. */
965 min_mask
= PMURES_BIT(RES4330_CBUCK_LPOM
) | PMURES_BIT(RES4330_CLDO_PU
) |
966 PMURES_BIT(RES4330_DIS_INT_RESET_PD
) | PMURES_BIT(RES4330_LDO3P3_PU
) |
967 PMURES_BIT(RES4330_OTP_PU
);
968 /* Allow (but don't require) PLL to turn on */
969 max_mask
= 0xfffffff;
972 case BCM4313_CHIP_ID
:
973 min_mask
= PMURES_BIT(RES4313_BB_PU_RSRC
) |
974 PMURES_BIT(RES4313_XTAL_PU_RSRC
) |
975 PMURES_BIT(RES4313_ALP_AVAIL_RSRC
) |
976 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC
);
983 /* Apply nvram override to min mask */
984 if ((val
= getvar(NULL
, "rmin")) != NULL
) {
985 PMU_MSG(("Applying rmin=%s to min_mask\n", val
));
986 min_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
988 /* Apply nvram override to max mask */
989 if ((val
= getvar(NULL
, "rmax")) != NULL
) {
990 PMU_MSG(("Applying rmax=%s to max_mask\n", val
));
991 max_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
997 #endif /* !_CFE_ || CFG_WL */
999 /* initialize PMU resources */
1001 BCMATTACHFN(si_pmu_res_init
)(si_t
*sih
, osl_t
*osh
)
1003 #if !defined(_CFE_) || defined(CFG_WL)
1006 const pmu_res_updown_t
*pmu_res_updown_table
= NULL
;
1007 uint pmu_res_updown_table_sz
= 0;
1008 const pmu_res_depend_t
*pmu_res_depend_table
= NULL
;
1009 uint pmu_res_depend_table_sz
= 0;
1010 uint32 min_mask
= 0, max_mask
= 0;
1014 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1016 /* Remember original core before switch to chipc */
1017 origidx
= si_coreidx(sih
);
1018 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1021 switch (CHIPID(sih
->chip
)) {
1022 case BCM4328_CHIP_ID
:
1023 pmu_res_updown_table
= bcm4328a0_res_updown
;
1024 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4328a0_res_updown
);
1025 pmu_res_depend_table
= bcm4328a0_res_depend
;
1026 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4328a0_res_depend
);
1028 case BCM4325_CHIP_ID
:
1029 /* Optimize resources up/down timers */
1030 if (ISSIM_ENAB(sih
)) {
1031 pmu_res_updown_table
= bcm4325a0_res_updown_qt
;
1032 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown_qt
);
1034 pmu_res_updown_table
= bcm4325a0_res_updown
;
1035 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown
);
1037 /* Optimize resources dependancies */
1038 pmu_res_depend_table
= bcm4325a0_res_depend
;
1039 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4325a0_res_depend
);
1041 case BCM4315_CHIP_ID
:
1042 /* Optimize resources up/down timers */
1043 if (ISSIM_ENAB(sih
)) {
1044 pmu_res_updown_table
= bcm4315a0_res_updown_qt
;
1045 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4315a0_res_updown_qt
);
1048 pmu_res_updown_table
= bcm4315a0_res_updown
;
1049 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4315a0_res_updown
);
1051 /* Optimize resources dependancies masks */
1052 pmu_res_depend_table
= bcm4315a0_res_depend
;
1053 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4315a0_res_depend
);
1055 case BCM4329_CHIP_ID
:
1056 /* Optimize resources up/down timers */
1057 if (ISSIM_ENAB(sih
)) {
1058 pmu_res_updown_table
= NULL
;
1059 pmu_res_updown_table_sz
= 0;
1061 pmu_res_updown_table
= bcm4329_res_updown
;
1062 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4329_res_updown
);
1064 /* Optimize resources dependencies */
1065 pmu_res_depend_table
= bcm4329_res_depend
;
1066 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4329_res_depend
);
1069 case BCM4319_CHIP_ID
:
1070 /* Optimize resources up/down timers */
1071 if (ISSIM_ENAB(sih
)) {
1072 pmu_res_updown_table
= bcm4319a0_res_updown_qt
;
1073 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4319a0_res_updown_qt
);
1076 pmu_res_updown_table
= bcm4319a0_res_updown
;
1077 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4319a0_res_updown
);
1079 /* Optimize resources dependancies masks */
1080 pmu_res_depend_table
= bcm4319a0_res_depend
;
1081 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4319a0_res_depend
);
1084 case BCM4336_CHIP_ID
:
1085 /* Optimize resources up/down timers */
1086 if (ISSIM_ENAB(sih
)) {
1087 pmu_res_updown_table
= bcm4336a0_res_updown_qt
;
1088 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4336a0_res_updown_qt
);
1091 pmu_res_updown_table
= bcm4336a0_res_updown
;
1092 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4336a0_res_updown
);
1094 /* Optimize resources dependancies masks */
1095 pmu_res_depend_table
= bcm4336a0_res_depend
;
1096 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4336a0_res_depend
);
1099 case BCM4330_CHIP_ID
:
1100 /* Optimize resources up/down timers */
1101 if (ISSIM_ENAB(sih
)) {
1102 pmu_res_updown_table
= bcm4330a0_res_updown_qt
;
1103 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4330a0_res_updown_qt
);
1106 pmu_res_updown_table
= bcm4330a0_res_updown
;
1107 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4330a0_res_updown
);
1109 /* Optimize resources dependancies masks */
1110 pmu_res_depend_table
= bcm4330a0_res_depend
;
1111 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4330a0_res_depend
);
1118 rsrcs
= (sih
->pmucaps
& PCAP_RC_MASK
) >> PCAP_RC_SHIFT
;
1120 /* Program up/down timers */
1121 while (pmu_res_updown_table_sz
--) {
1122 ASSERT(pmu_res_updown_table
!= NULL
);
1123 PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
1124 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
,
1125 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
));
1126 W_REG(osh
, &cc
->res_table_sel
,
1127 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
);
1128 W_REG(osh
, &cc
->res_updn_timer
,
1129 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
);
1131 /* Apply nvram overrides to up/down timers */
1132 for (i
= 0; i
< rsrcs
; i
++) {
1133 snprintf(name
, sizeof(name
), "r%dt", i
);
1134 if ((val
= getvar(NULL
, name
)) == NULL
)
1136 PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name
, val
, i
));
1137 W_REG(osh
, &cc
->res_table_sel
, (uint32
)i
);
1138 W_REG(osh
, &cc
->res_updn_timer
, (uint32
)bcm_strtoul(val
, NULL
, 0));
1141 /* Program resource dependencies table */
1142 while (pmu_res_depend_table_sz
--) {
1143 ASSERT(pmu_res_depend_table
!= NULL
);
1144 if (pmu_res_depend_table
[pmu_res_depend_table_sz
].filter
!= NULL
&&
1145 !(pmu_res_depend_table
[pmu_res_depend_table_sz
].filter
)(sih
))
1147 for (i
= 0; i
< rsrcs
; i
++) {
1148 if ((pmu_res_depend_table
[pmu_res_depend_table_sz
].res_mask
&
1149 PMURES_BIT(i
)) == 0)
1151 W_REG(osh
, &cc
->res_table_sel
, i
);
1152 switch (pmu_res_depend_table
[pmu_res_depend_table_sz
].action
) {
1153 case RES_DEPEND_SET
:
1154 PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i
,
1155 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
));
1156 W_REG(osh
, &cc
->res_dep_mask
,
1157 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
1159 case RES_DEPEND_ADD
:
1160 PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n",
1161 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
, i
));
1162 OR_REG(osh
, &cc
->res_dep_mask
,
1163 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
1165 case RES_DEPEND_REMOVE
:
1166 PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n",
1167 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
, i
));
1168 AND_REG(osh
, &cc
->res_dep_mask
,
1169 ~pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
1177 /* Apply nvram overrides to dependancies masks */
1178 for (i
= 0; i
< rsrcs
; i
++) {
1179 snprintf(name
, sizeof(name
), "r%dd", i
);
1180 if ((val
= getvar(NULL
, name
)) == NULL
)
1182 PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name
, val
, i
));
1183 W_REG(osh
, &cc
->res_table_sel
, (uint32
)i
);
1184 W_REG(osh
, &cc
->res_dep_mask
, (uint32
)bcm_strtoul(val
, NULL
, 0));
1187 /* Determine min/max rsrc masks */
1188 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
1190 /* It is required to program max_mask first and then min_mask */
1191 #ifdef BCM_BOOTLOADER
1192 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
1193 min_mask
|= R_REG(osh
, &cc
->min_res_mask
);
1194 max_mask
|= R_REG(osh
, &cc
->max_res_mask
);
1196 #endif /* BCM_BOOTLOADER */
1198 /* Program max resource mask */
1199 #ifdef BCM_BOOTLOADER
1200 /* Apply nvram override to max mask */
1201 if ((val
= getvar(NULL
, "brmax")) != NULL
) {
1202 PMU_MSG(("Applying brmax=%s to max_res_mask\n", val
));
1203 max_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
1205 #endif /* BCM_BOOTLOADER */
1208 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask
));
1209 W_REG(osh
, &cc
->max_res_mask
, max_mask
);
1212 /* Program min resource mask */
1213 #ifdef BCM_BOOTLOADER
1214 /* Apply nvram override to min mask */
1215 if ((val
= getvar(NULL
, "brmin")) != NULL
) {
1216 PMU_MSG(("Applying brmin=%s to min_res_mask\n", val
));
1217 min_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
1219 #endif /* BCM_BOOTLOADER */
1222 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask
));
1223 W_REG(osh
, &cc
->min_res_mask
, min_mask
);
1226 /* Add some delay; allow resources to come up and settle. */
1229 /* Return to original core */
1230 si_setcoreidx(sih
, origidx
);
1232 #endif /* !_CFE_ || CFG_WL */
1234 /* WAR for 4319 swctrl tri-state issue */
1236 si_pmu_res_4319_swctrl_war(si_t
*sih
, osl_t
*osh
, bool enable
)
1241 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1243 /* Remember original core before switch to chipc */
1244 origidx
= si_coreidx(sih
);
1245 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1247 min_mask
= R_REG(osh
, &cc
->min_res_mask
);
1249 W_REG(osh
, &cc
->min_res_mask
,
1250 min_mask
| PMURES_BIT(RES4319_PALDO_PU
));
1252 W_REG(osh
, &cc
->min_res_mask
,
1253 min_mask
& ~PMURES_BIT(RES4319_PALDO_PU
));
1255 /* Return to original core */
1256 si_setcoreidx(sih
, origidx
);
1259 /* setup pll and query clock speed */
1267 /* the following table is based on 880Mhz fvco */
1268 static const pmu0_xtaltab0_t
BCMINITDATA(pmu0_xtaltab0
)[] = {
1269 { 12000, 1, 73, 349525 },
1270 { 13000, 2, 67, 725937 },
1271 { 14400, 3, 61, 116508 },
1272 { 15360, 4, 57, 305834 },
1273 { 16200, 5, 54, 336579 },
1274 { 16800, 6, 52, 399457 },
1275 { 19200, 7, 45, 873813 },
1276 { 19800, 8, 44, 466033 },
1277 { 20000, 9, 44, 0 },
1278 { 25000, 10, 70, 419430 },
1279 { 26000, 11, 67, 725937 },
1280 { 30000, 12, 58, 699050 },
1281 { 38400, 13, 45, 873813 },
1282 { 40000, 14, 45, 0 },
1287 #define PMU0_XTAL0_DEFAULT 11
1289 #define PMU0_XTAL0_DEFAULT 8
1294 * Set new backplane PLL clock frequency
1297 BCMATTACHFN(si_pmu0_sbclk4328
)(si_t
*sih
, int freq
)
1299 uint32 tmp
, oldmax
, oldmin
, origidx
;
1302 /* Remember original core before switch to chipc */
1303 origidx
= si_coreidx(sih
);
1304 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1307 /* Set new backplane PLL clock */
1308 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
1309 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1310 tmp
&= ~(PMU0_PLL0_PC0_DIV_ARM_MASK
);
1311 tmp
|= freq
<< PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
1312 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1314 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
1316 oldmin
= R_REG(osh
, &cc
->min_res_mask
);
1317 oldmax
= R_REG(osh
, &cc
->max_res_mask
);
1318 W_REG(osh
, &cc
->min_res_mask
, oldmin
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
1319 W_REG(osh
, &cc
->max_res_mask
, oldmax
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
1321 /* It takes over several hundred usec to re-enable the PLL since the
1322 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
1324 * Be sure PLL is powered down first before re-enabling it.
1327 OSL_DELAY(PLL_DELAY
);
1328 SPINWAIT((R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)), PLL_DELAY
*3);
1329 if (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)) {
1330 /* If BB_PLL not powered down yet, new backplane PLL clock
1331 * may not take effect.
1333 * Still early during bootup so no serial output here.
1335 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n"));
1336 ASSERT(!(R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)));
1340 W_REG(osh
, &cc
->max_res_mask
, oldmax
);
1342 /* Return to original core */
1343 si_setcoreidx(sih
, origidx
);
1345 #endif /* BCMUSBDEV */
1347 /* Set up PLL registers in the PMU as per the crystal speed.
1348 * Uses xtalfreq variable, or passed-in default.
1351 BCMATTACHFN(si_pmu0_pllinit0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
1354 const pmu0_xtaltab0_t
*xt
;
1356 /* Find the frequency in the table */
1357 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
1358 if (xt
->freq
== xtal
)
1361 xt
= &pmu0_xtaltab0
[PMU0_XTAL0_DEFAULT
];
1363 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal
/ 1000, xtal
% 1000, xt
->xf
));
1365 /* Check current PLL state */
1366 tmp
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1367 PCTL_XTALFREQ_SHIFT
;
1368 if (tmp
== xt
->xf
) {
1369 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
1370 xt
->freq
/ 1000, xt
->freq
% 1000));
1372 if (CHIPID(sih
->chip
) == BCM4328_CHIP_ID
)
1373 si_pmu0_sbclk4328(sih
, PMU0_PLL0_PC0_DIV_ARM_88MHZ
);
1374 #endif /* BCMUSBDEV */
1379 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
1380 xt
->freq
/ 1000, xt
->freq
% 1000,
1381 pmu0_xtaltab0
[tmp
-1].freq
/ 1000, pmu0_xtaltab0
[tmp
-1].freq
% 1000));
1383 PMU_MSG(("Programming PLL for %d.%d MHz\n",
1384 xt
->freq
/ 1000, xt
->freq
% 1000));
1387 /* Make sure the PLL is off */
1388 switch (CHIPID(sih
->chip
)) {
1389 case BCM4328_CHIP_ID
:
1390 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
1391 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
1393 case BCM5354_CHIP_ID
:
1394 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
1395 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
1400 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1401 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
));
1403 PMU_MSG(("Done masking\n"));
1405 /* Write PDIV in pllcontrol[0] */
1406 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
1407 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1408 if (xt
->freq
>= PMU0_PLL0_PC0_PDIV_FREQ
)
1409 tmp
|= PMU0_PLL0_PC0_PDIV_MASK
;
1411 tmp
&= ~PMU0_PLL0_PC0_PDIV_MASK
;
1412 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1414 /* Write WILD in pllcontrol[1] */
1415 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL1
);
1416 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1417 tmp
= ((tmp
& ~(PMU0_PLL0_PC1_WILD_INT_MASK
| PMU0_PLL0_PC1_WILD_FRAC_MASK
)) |
1418 (((xt
->wbint
<< PMU0_PLL0_PC1_WILD_INT_SHIFT
) &
1419 PMU0_PLL0_PC1_WILD_INT_MASK
) |
1420 ((xt
->wbfrac
<< PMU0_PLL0_PC1_WILD_FRAC_SHIFT
) &
1421 PMU0_PLL0_PC1_WILD_FRAC_MASK
)));
1422 if (xt
->wbfrac
== 0)
1423 tmp
|= PMU0_PLL0_PC1_STOP_MOD
;
1425 tmp
&= ~PMU0_PLL0_PC1_STOP_MOD
;
1426 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1428 /* Write WILD in pllcontrol[2] */
1429 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL2
);
1430 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1431 tmp
= ((tmp
& ~PMU0_PLL0_PC2_WILD_INT_MASK
) |
1432 ((xt
->wbint
>> PMU0_PLL0_PC2_WILD_INT_SHIFT
) &
1433 PMU0_PLL0_PC2_WILD_INT_MASK
));
1434 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1436 PMU_MSG(("Done pll\n"));
1438 /* Write XtalFreq. Set the divisor also. */
1439 tmp
= R_REG(osh
, &cc
->pmucontrol
);
1440 tmp
= ((tmp
& ~PCTL_ILP_DIV_MASK
) |
1441 (((((xt
->freq
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) & PCTL_ILP_DIV_MASK
));
1442 tmp
= ((tmp
& ~PCTL_XTALFREQ_MASK
) |
1443 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
));
1444 W_REG(osh
, &cc
->pmucontrol
, tmp
);
1447 /* query alp/xtal clock frequency */
1449 BCMINITFN(si_pmu0_alpclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1451 const pmu0_xtaltab0_t
*xt
;
1454 /* Find the frequency in the table */
1455 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1456 PCTL_XTALFREQ_SHIFT
;
1457 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
1460 /* PLL must be configured before */
1463 return xt
->freq
* 1000;
1466 #if !defined(_CFE_) || defined(CFG_WL)
1467 /* query CPU clock frequency */
1469 BCMINITFN(si_pmu0_cpuclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1473 uint32 pdiv
, wbint
, wbfrac
, fvco
;
1476 uint32 FVCO
= FVCO_880
;
1478 /* Read divarm from pllcontrol[0] */
1479 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
1480 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1481 divarm
= (tmp
& PMU0_PLL0_PC0_DIV_ARM_MASK
) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
1484 /* Calculate fvco based on xtal freq, pdiv, and wild */
1485 pdiv
= tmp
& PMU0_PLL0_PC0_PDIV_MASK
;
1487 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL1
);
1488 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1489 wbfrac
= (tmp
& PMU0_PLL0_PC1_WILD_FRAC_MASK
) >> PMU0_PLL0_PC1_WILD_FRAC_SHIFT
;
1490 wbint
= (tmp
& PMU0_PLL0_PC1_WILD_INT_MASK
) >> PMU0_PLL0_PC1_WILD_INT_SHIFT
;
1492 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL2
);
1493 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1494 wbint
+= (tmp
& PMU0_PLL0_PC2_WILD_INT_MASK
) << PMU0_PLL0_PC2_WILD_INT_SHIFT
;
1496 freq
= si_pmu0_alpclk0(sih
, osh
, cc
) / 1000;
1498 fvco
= (freq
* wbint
) << 8;
1499 fvco
+= (freq
* (wbfrac
>> 10)) >> 2;
1500 fvco
+= (freq
* (wbfrac
& 0x3ff)) >> 10;
1506 PMU_MSG(("si_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
1507 wbint
, wbfrac
, fvco
));
1512 /* Return ARM/SB clock */
1513 return FVCO
/ (divarm
+ PMU0_PLL0_PC0_DIV_ARM_BASE
) * 1000;
1517 si_pll_minresmask_reset(si_t
*sih
, osl_t
*osh
)
1522 /* Remember original core before switch to chipc */
1523 origidx
= si_coreidx(sih
);
1524 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1527 switch (CHIPID(sih
->chip
)) {
1528 case BCM4313_CHIP_ID
:
1529 /* write to min_res_mask 0x200d : clear min_rsrc_mask */
1530 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1532 /* write to max_res_mask 0xBFFF: clear max_rsrc_mask */
1533 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1535 /* write to max_res_mask 0xFFFF :set max_rsrc_mask */
1536 OR_REG(osh
, &cc
->max_res_mask
, (PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1540 PMU_ERROR(("%s: PLL reset not supported\n", __FUNCTION__
));
1541 err
= BCME_UNSUPPORTED
;
1544 /* Return to original core */
1545 si_setcoreidx(sih
, origidx
);
1549 /* setup pll and query clock speed */
1559 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_880_4329
)[] = {
1560 {12000, 1, 3, 22, 0x9, 0xFFFFEF},
1561 {13000, 2, 1, 6, 0xb, 0x483483},
1562 {14400, 3, 1, 10, 0xa, 0x1C71C7},
1563 {15360, 4, 1, 5, 0xb, 0x755555},
1564 {16200, 5, 1, 10, 0x5, 0x6E9E06},
1565 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
1566 {19200, 7, 1, 4, 0xb, 0x755555},
1567 {19800, 8, 1, 11, 0x4, 0xA57EB},
1568 {20000, 9, 1, 11, 0x4, 0x0},
1569 {24000, 10, 3, 11, 0xa, 0x0},
1570 {25000, 11, 5, 16, 0xb, 0x0},
1571 {26000, 12, 1, 1, 0x21, 0xD89D89},
1572 {30000, 13, 3, 8, 0xb, 0x0},
1573 {37400, 14, 3, 1, 0x46, 0x969696},
1574 {38400, 15, 1, 1, 0x16, 0xEAAAAA},
1575 {40000, 16, 1, 2, 0xb, 0},
1579 /* the following table is based on 880Mhz fvco */
1580 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_880
)[] = {
1581 {12000, 1, 3, 22, 0x9, 0xFFFFEF},
1582 {13000, 2, 1, 6, 0xb, 0x483483},
1583 {14400, 3, 1, 10, 0xa, 0x1C71C7},
1584 {15360, 4, 1, 5, 0xb, 0x755555},
1585 {16200, 5, 1, 10, 0x5, 0x6E9E06},
1586 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
1587 {19200, 7, 1, 4, 0xb, 0x755555},
1588 {19800, 8, 1, 11, 0x4, 0xA57EB},
1589 {20000, 9, 1, 11, 0x4, 0x0},
1590 {24000, 10, 3, 11, 0xa, 0x0},
1591 {25000, 11, 5, 16, 0xb, 0x0},
1592 {26000, 12, 1, 2, 0x10, 0xEC4EC4},
1593 {30000, 13, 3, 8, 0xb, 0x0},
1594 {33600, 14, 1, 2, 0xd, 0x186186},
1595 {38400, 15, 1, 2, 0xb, 0x755555},
1596 {40000, 16, 1, 2, 0xb, 0},
1600 #define PMU1_XTALTAB0_880_12000K 0
1601 #define PMU1_XTALTAB0_880_13000K 1
1602 #define PMU1_XTALTAB0_880_14400K 2
1603 #define PMU1_XTALTAB0_880_15360K 3
1604 #define PMU1_XTALTAB0_880_16200K 4
1605 #define PMU1_XTALTAB0_880_16800K 5
1606 #define PMU1_XTALTAB0_880_19200K 6
1607 #define PMU1_XTALTAB0_880_19800K 7
1608 #define PMU1_XTALTAB0_880_20000K 8
1609 #define PMU1_XTALTAB0_880_24000K 9
1610 #define PMU1_XTALTAB0_880_25000K 10
1611 #define PMU1_XTALTAB0_880_26000K 11
1612 #define PMU1_XTALTAB0_880_30000K 12
1613 #define PMU1_XTALTAB0_880_37400K 13
1614 #define PMU1_XTALTAB0_880_38400K 14
1615 #define PMU1_XTALTAB0_880_40000K 15
1617 /* the following table is based on 1760Mhz fvco */
1618 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_1760
)[] = {
1619 {12000, 1, 3, 44, 0x9, 0xFFFFEF},
1620 {13000, 2, 1, 12, 0xb, 0x483483},
1621 {14400, 3, 1, 20, 0xa, 0x1C71C7},
1622 {15360, 4, 1, 10, 0xb, 0x755555},
1623 {16200, 5, 1, 20, 0x5, 0x6E9E06},
1624 {16800, 6, 1, 20, 0x5, 0x3Cf3Cf},
1625 {19200, 7, 1, 18, 0x5, 0x17B425},
1626 {19800, 8, 1, 22, 0x4, 0xA57EB},
1627 {20000, 9, 1, 22, 0x4, 0x0},
1628 {24000, 10, 3, 22, 0xa, 0x0},
1629 {25000, 11, 5, 32, 0xb, 0x0},
1630 {26000, 12, 1, 4, 0x10, 0xEC4EC4},
1631 {30000, 13, 3, 16, 0xb, 0x0},
1632 {38400, 14, 1, 10, 0x4, 0x955555},
1633 {40000, 15, 1, 4, 0xb, 0},
1638 #define PMU1_XTALTAB0_1760_12000K 0
1639 #define PMU1_XTALTAB0_1760_13000K 1
1640 #define PMU1_XTALTAB0_1760_14400K 2
1641 #define PMU1_XTALTAB0_1760_15360K 3
1642 #define PMU1_XTALTAB0_1760_16200K 4
1643 #define PMU1_XTALTAB0_1760_16800K 5
1644 #define PMU1_XTALTAB0_1760_19200K 6
1645 #define PMU1_XTALTAB0_1760_19800K 7
1646 #define PMU1_XTALTAB0_1760_20000K 8
1647 #define PMU1_XTALTAB0_1760_24000K 9
1648 #define PMU1_XTALTAB0_1760_25000K 10
1649 #define PMU1_XTALTAB0_1760_26000K 11
1650 #define PMU1_XTALTAB0_1760_30000K 12
1651 #define PMU1_XTALTAB0_1760_38400K 13
1652 #define PMU1_XTALTAB0_1760_40000K 14
1654 /* the following table is based on 1440Mhz fvco */
1655 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_1440
)[] = {
1656 {12000, 1, 1, 1, 0x78, 0x0 },
1657 {13000, 2, 1, 1, 0x6E, 0xC4EC4E},
1658 {14400, 3, 1, 1, 0x64, 0x0 },
1659 {15360, 4, 1, 1, 0x5D, 0xC00000},
1660 {16200, 5, 1, 1, 0x58, 0xE38E38},
1661 {16800, 6, 1, 1, 0x55, 0xB6DB6D},
1662 {19200, 7, 1, 1, 0x4B, 0 },
1663 {19800, 8, 1, 1, 0x48, 0xBA2E8B},
1664 {20000, 9, 1, 1, 0x48, 0x0 },
1665 {25000, 10, 1, 1, 0x39, 0x999999},
1666 {26000, 11, 1, 1, 0x37, 0x627627},
1667 {30000, 12, 1, 1, 0x30, 0x0 },
1668 {37400, 13, 2, 1, 0x4D, 0x15E76 },
1669 {38400, 13, 2, 1, 0x4B, 0x0 },
1670 {40000, 14, 2, 1, 0x48, 0x0 },
1671 {48000, 15, 2, 1, 0x3c, 0x0 },
1676 #define PMU1_XTALTAB0_1440_12000K 0
1677 #define PMU1_XTALTAB0_1440_13000K 1
1678 #define PMU1_XTALTAB0_1440_14400K 2
1679 #define PMU1_XTALTAB0_1440_15360K 3
1680 #define PMU1_XTALTAB0_1440_16200K 4
1681 #define PMU1_XTALTAB0_1440_16800K 5
1682 #define PMU1_XTALTAB0_1440_19200K 6
1683 #define PMU1_XTALTAB0_1440_19800K 7
1684 #define PMU1_XTALTAB0_1440_20000K 8
1685 #define PMU1_XTALTAB0_1440_25000K 9
1686 #define PMU1_XTALTAB0_1440_26000K 10
1687 #define PMU1_XTALTAB0_1440_30000K 11
1688 #define PMU1_XTALTAB0_1440_37400K 12
1689 #define PMU1_XTALTAB0_1440_38400K 13
1690 #define PMU1_XTALTAB0_1440_40000K 14
1691 #define PMU1_XTALTAB0_1440_48000K 15
1693 #define XTAL_FREQ_24000MHZ 24000
1694 #define XTAL_FREQ_30000MHZ 30000
1695 #define XTAL_FREQ_37400MHZ 37400
1696 #define XTAL_FREQ_48000MHZ 48000
1698 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_960
)[] = {
1699 {12000, 1, 1, 1, 0x50, 0x0 },
1700 {13000, 2, 1, 1, 0x49, 0xD89D89},
1701 {14400, 3, 1, 1, 0x42, 0xAAAAAA},
1702 {15360, 4, 1, 1, 0x3E, 0x800000},
1703 {16200, 5, 1, 1, 0x39, 0x425ED0},
1704 {16800, 6, 1, 1, 0x39, 0x249249},
1705 {19200, 7, 1, 1, 0x32, 0x0 },
1706 {19800, 8, 1, 1, 0x30, 0x7C1F07},
1707 {20000, 9, 1, 1, 0x30, 0x0 },
1708 {25000, 10, 1, 1, 0x26, 0x666666},
1709 {26000, 11, 1, 1, 0x24, 0xEC4EC4},
1710 {30000, 12, 1, 1, 0x20, 0x0 },
1711 {37400, 13, 2, 1, 0x33, 0x563EF9},
1712 {38400, 14, 2, 1, 0x32, 0x0 },
1713 {40000, 15, 2, 1, 0x30, 0x0 },
1714 {48000, 16, 2, 1, 0x28, 0x0 },
1719 #define PMU1_XTALTAB0_960_12000K 0
1720 #define PMU1_XTALTAB0_960_13000K 1
1721 #define PMU1_XTALTAB0_960_14400K 2
1722 #define PMU1_XTALTAB0_960_15360K 3
1723 #define PMU1_XTALTAB0_960_16200K 4
1724 #define PMU1_XTALTAB0_960_16800K 5
1725 #define PMU1_XTALTAB0_960_19200K 6
1726 #define PMU1_XTALTAB0_960_19800K 7
1727 #define PMU1_XTALTAB0_960_20000K 8
1728 #define PMU1_XTALTAB0_960_25000K 9
1729 #define PMU1_XTALTAB0_960_26000K 10
1730 #define PMU1_XTALTAB0_960_30000K 11
1731 #define PMU1_XTALTAB0_960_37400K 12
1732 #define PMU1_XTALTAB0_960_38400K 13
1733 #define PMU1_XTALTAB0_960_40000K 14
1734 #define PMU1_XTALTAB0_960_48000K 15
1736 /* select xtal table for each chip */
1737 static const pmu1_xtaltab0_t
*
1738 BCMINITFN(si_pmu1_xtaltab0
)(si_t
*sih
)
1743 switch (CHIPID(sih
->chip
)) {
1744 case BCM4325_CHIP_ID
:
1745 return pmu1_xtaltab0_880
;
1746 case BCM4329_CHIP_ID
:
1747 return pmu1_xtaltab0_880_4329
;
1748 case BCM4315_CHIP_ID
:
1749 return pmu1_xtaltab0_1760
;
1750 case BCM4319_CHIP_ID
:
1751 return pmu1_xtaltab0_1440
;
1752 case BCM4336_CHIP_ID
:
1753 return pmu1_xtaltab0_960
;
1754 case BCM4330_CHIP_ID
:
1755 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
1756 return pmu1_xtaltab0_960
;
1758 return pmu1_xtaltab0_1440
;
1760 PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1767 /* select default xtal frequency for each chip */
1768 static const pmu1_xtaltab0_t
*
1769 BCMINITFN(si_pmu1_xtaldef0
)(si_t
*sih
)
1775 switch (CHIPID(sih
->chip
)) {
1776 case BCM4325_CHIP_ID
:
1777 /* Default to 26000Khz */
1778 return &pmu1_xtaltab0_880
[PMU1_XTALTAB0_880_26000K
];
1779 case BCM4329_CHIP_ID
:
1780 /* Default to 38400Khz */
1781 return &pmu1_xtaltab0_880_4329
[PMU1_XTALTAB0_880_38400K
];
1782 case BCM4315_CHIP_ID
:
1784 /* Default to 30000Khz */
1785 return &pmu1_xtaltab0_1760
[PMU1_XTALTAB0_1760_30000K
];
1787 /* Default to 26000Khz */
1788 return &pmu1_xtaltab0_1760
[PMU1_XTALTAB0_1760_26000K
];
1790 case BCM4319_CHIP_ID
:
1791 /* Default to 30000Khz */
1792 return &pmu1_xtaltab0_1440
[PMU1_XTALTAB0_1440_30000K
];
1793 case BCM4336_CHIP_ID
:
1794 /* Default to 26000Khz */
1795 return &pmu1_xtaltab0_960
[PMU1_XTALTAB0_960_26000K
];
1796 case BCM4330_CHIP_ID
:
1797 /* Default to 37400Khz */
1798 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
1799 return &pmu1_xtaltab0_960
[PMU1_XTALTAB0_960_37400K
];
1801 return &pmu1_xtaltab0_1440
[PMU1_XTALTAB0_1440_37400K
];
1803 PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1810 /* select default pll fvco for each chip */
1812 BCMINITFN(si_pmu1_pllfvco0
)(si_t
*sih
)
1818 switch (CHIPID(sih
->chip
)) {
1819 case BCM4325_CHIP_ID
:
1821 case BCM4329_CHIP_ID
:
1823 case BCM4315_CHIP_ID
:
1825 case BCM4319_CHIP_ID
:
1827 case BCM4336_CHIP_ID
:
1829 case BCM4330_CHIP_ID
:
1830 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
1835 PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1842 /* query alp/xtal clock frequency */
1844 BCMINITFN(si_pmu1_alpclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1846 const pmu1_xtaltab0_t
*xt
;
1849 /* Find the frequency in the table */
1850 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1851 PCTL_XTALFREQ_SHIFT
;
1852 for (xt
= si_pmu1_xtaltab0(sih
); xt
!= NULL
&& xt
->fref
!= 0; xt
++)
1855 /* Could not find it so assign a default value */
1856 if (xt
== NULL
|| xt
->fref
== 0)
1857 xt
= si_pmu1_xtaldef0(sih
);
1858 ASSERT(xt
!= NULL
&& xt
->fref
!= 0);
1860 return xt
->fref
* 1000;
1862 #endif /* !_CFE_ || CFG_WL */
1865 si_pmu_minresmask_htavail_set(si_t
*sih
, osl_t
*osh
, bool set_clear
)
1869 /* Remember original core before switch to chipc */
1870 origidx
= si_coreidx(sih
);
1871 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1875 switch (CHIPID(sih
->chip
)) {
1876 case BCM4313_CHIP_ID
:
1877 if ((cc
->min_res_mask
) & (PMURES_BIT(RES4313_HT_AVAIL_RSRC
)))
1878 AND_REG(osh
, &cc
->min_res_mask
,
1879 ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1886 /* Return to original core */
1887 si_setcoreidx(sih
, origidx
);
1890 #if !defined(_CFE_) || defined(CFG_WL)
1891 /* Set up PLL registers in the PMU as per the crystal speed.
1892 * XtalFreq field in pmucontrol register being 0 indicates the PLL
1893 * is not programmed and the h/w default is assumed to work, in which
1894 * case the xtal frequency is unknown to the s/w so we need to call
1895 * si_pmu1_xtaldef0() wherever it is needed to return a default value.
1898 BCMATTACHFN(si_pmu1_pllinit0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
1900 const pmu1_xtaltab0_t
*xt
;
1902 uint32 buf_strength
= 0;
1903 uint8 ndiv_mode
= 1;
1904 uint32 FVCO
= si_pmu1_pllfvco0(sih
);
1909 /* Use h/w default PLL config */
1911 PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
1915 /* Find the frequency in the table */
1916 for (xt
= si_pmu1_xtaltab0(sih
); xt
!= NULL
&& xt
->fref
!= 0; xt
++)
1917 if (xt
->fref
== xtal
)
1920 /* Check current PLL state, bail out if it has been programmed or
1921 * we don't know how to program it.
1923 if (xt
== NULL
|| xt
->fref
== 0) {
1924 PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n",
1925 xtal
/ 1000, xtal
% 1000));
1928 /* for 4319 bootloader already programs the PLL but bootloader does not program the
1929 PLL4 and PLL5. So Skip this check for 4319
1931 if ((((R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1932 PCTL_XTALFREQ_SHIFT
) == xt
->xf
) &&
1933 !((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) || (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
)))
1935 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
1936 xt
->fref
/ 1000, xt
->fref
% 1000));
1940 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal
/ 1000, xtal
% 1000, xt
->xf
));
1941 PMU_MSG(("Programming PLL for %d.%d MHz\n", xt
->fref
/ 1000, xt
->fref
% 1000));
1943 switch (CHIPID(sih
->chip
)) {
1944 case BCM4325_CHIP_ID
:
1945 /* Change the BBPLL drive strength to 2 for all channels */
1946 buf_strength
= 0x222222;
1947 /* Make sure the PLL is off */
1948 AND_REG(osh
, &cc
->min_res_mask
,
1949 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
1950 AND_REG(osh
, &cc
->max_res_mask
,
1951 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
1952 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1953 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1955 case BCM4329_CHIP_ID
:
1956 /* Change the BBPLL drive strength to 8 for all channels */
1957 buf_strength
= 0x888888;
1958 AND_REG(osh
, &cc
->min_res_mask
,
1959 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4329_HT_AVAIL
)));
1960 AND_REG(osh
, &cc
->max_res_mask
,
1961 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4329_HT_AVAIL
)));
1962 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1963 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1964 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
1965 if (xt
->fref
== 38400)
1967 else if (xt
->fref
== 37400)
1969 else if (xt
->fref
== 26000)
1972 tmp
= 0x200005C0; /* Chip Dflt Settings */
1973 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1974 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
1975 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & PMU1_PLL0_PC5_CLK_DRV_MASK
;
1976 if ((xt
->fref
== 38400) || (xt
->fref
== 37400) || (xt
->fref
== 26000))
1979 tmp
|= 0x25; /* Chip Dflt Settings */
1980 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1982 case BCM4315_CHIP_ID
:
1983 /* Change the BBPLL drive strength to 2 for all channels */
1984 buf_strength
= 0x222222;
1985 /* Make sure the PLL is off */
1986 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4315_HT_AVAIL
)));
1987 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4315_HT_AVAIL
)));
1990 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU
)));
1991 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU
)));
1994 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1995 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1998 case BCM4319_CHIP_ID
:
1999 /* Change the BBPLL drive strength to 2 for all channels */
2000 buf_strength
= 0x222222;
2002 /* Make sure the PLL is off */
2003 /* WAR65104: Disable the HT_AVAIL resource first and then
2004 * after a delay (more than downtime for HT_AVAIL) remove the
2005 * BBPLL resource; backplane clock moves to ALP from HT.
2007 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4319_HT_AVAIL
)));
2008 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4319_HT_AVAIL
)));
2011 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU
)));
2012 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU
)));
2015 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2016 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2019 case BCM4336_CHIP_ID
:
2020 AND_REG(osh
, &cc
->min_res_mask
,
2021 ~(PMURES_BIT(RES4336_HT_AVAIL
) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL
)));
2022 AND_REG(osh
, &cc
->max_res_mask
,
2023 ~(PMURES_BIT(RES4336_HT_AVAIL
) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL
)));
2025 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2026 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2029 case BCM4330_CHIP_ID
:
2030 AND_REG(osh
, &cc
->min_res_mask
,
2031 ~(PMURES_BIT(RES4330_HT_AVAIL
) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL
)));
2032 AND_REG(osh
, &cc
->max_res_mask
,
2033 ~(PMURES_BIT(RES4330_HT_AVAIL
) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL
)));
2035 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2036 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2043 PMU_MSG(("Done masking\n"));
2045 /* Write p1div and p2div to pllcontrol[0] */
2046 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2047 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
2048 ~(PMU1_PLL0_PC0_P1DIV_MASK
| PMU1_PLL0_PC0_P2DIV_MASK
);
2049 tmp
|= ((xt
->p1div
<< PMU1_PLL0_PC0_P1DIV_SHIFT
) & PMU1_PLL0_PC0_P1DIV_MASK
) |
2050 ((xt
->p2div
<< PMU1_PLL0_PC0_P2DIV_SHIFT
) & PMU1_PLL0_PC0_P2DIV_MASK
);
2052 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
2053 tmp
&= ~(PMU1_PLL0_PC0_BYPASS_SDMOD_MASK
);
2054 if (!(xt
->ndiv_frac
))
2055 tmp
|= (1<<(PMU1_PLL0_PC0_BYPASS_SDMOD_SHIFT
));
2057 tmp
|= (0<<(PMU1_PLL0_PC0_BYPASS_SDMOD_SHIFT
));
2060 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2062 if ((CHIPID(sih
->chip
) == BCM4330_CHIP_ID
)) {
2063 if (CHIPREV(sih
->chiprev
) < 2)
2066 if (!(dacrate
= (uint8
)getintvar(NULL
, "dacrate2g")))
2069 si_pmu_set_4330_plldivs(sih
, dacrate
);
2072 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && (CHIPREV(sih
->chiprev
) == 0)) {
2074 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2075 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2076 tmp
= tmp
& (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK
);
2077 tmp
= tmp
| DOT11MAC_880MHZ_CLK_DIVISOR_VAL
;
2078 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2080 if ((CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) ||
2081 (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
))
2082 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MFB
;
2084 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MASH
;
2086 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
)) {
2087 if (!(xt
->ndiv_frac
))
2088 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_INT
;
2090 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MFB
;
2092 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2094 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2097 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
2098 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2099 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
2100 ~(PMU1_PLL0_PC2_NDIV_INT_MASK
| PMU1_PLL0_PC2_NDIV_MODE_MASK
);
2101 tmp
|= ((xt
->ndiv_int
<< PMU1_PLL0_PC2_NDIV_INT_SHIFT
) & PMU1_PLL0_PC2_NDIV_INT_MASK
) |
2102 ((ndiv_mode
<< PMU1_PLL0_PC2_NDIV_MODE_SHIFT
) & PMU1_PLL0_PC2_NDIV_MODE_MASK
);
2103 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2105 /* Write ndiv_frac to pllcontrol[3] */
2106 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2107 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK
;
2108 tmp
|= ((xt
->ndiv_frac
<< PMU1_PLL0_PC3_NDIV_FRAC_SHIFT
) &
2109 PMU1_PLL0_PC3_NDIV_FRAC_MASK
);
2110 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2112 /* Writing to pllcontrol[4] */
2113 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
)) {
2114 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2115 if (!(xt
->ndiv_frac
))
2120 tmp
&= ~(PMU1_PLL0_PC4_KVCO_XS_MASK
);
2123 tmp
|= (4<<PMU1_PLL0_PC4_KVCO_XS_SHIFT
);
2125 tmp
|= (7<<PMU1_PLL0_PC4_KVCO_XS_SHIFT
);
2127 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2130 /* Write clock driving strength to pllcontrol[5] */
2132 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength
));
2134 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2135 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC5_CLK_DRV_MASK
;
2136 tmp
|= (buf_strength
<< PMU1_PLL0_PC5_CLK_DRV_SHIFT
);
2138 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
2139 tmp
&= ~(PMU1_PLL0_PC5_VCO_RNG_MASK
| PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK
);
2140 if (!(xt
->ndiv_frac
))
2141 tmp
|= (0x25<<(PMU1_PLL0_PC5_PLL_CTRL_37_32_SHIFT
));
2143 tmp
|= (0x15<<(PMU1_PLL0_PC5_PLL_CTRL_37_32_SHIFT
));
2146 tmp
|= (0x0<<(PMU1_PLL0_PC5_VCO_RNG_SHIFT
));
2148 tmp
|= (0x1<<(PMU1_PLL0_PC5_VCO_RNG_SHIFT
));
2150 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2153 PMU_MSG(("Done pll\n"));
2155 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
2158 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) && (xt
->fref
!= XTAL_FREQ_30000MHZ
)) {
2159 W_REG(osh
, &cc
->chipcontrol_addr
, PMU1_PLL0_CHIPCTL2
);
2160 tmp
= R_REG(osh
, &cc
->chipcontrol_data
) & ~CCTL_4319USB_XTAL_SEL_MASK
;
2161 if (xt
->fref
== XTAL_FREQ_24000MHZ
) {
2162 tmp
|= (CCTL_4319USB_24MHZ_PLL_SEL
<< CCTL_4319USB_XTAL_SEL_SHIFT
);
2163 } else if (xt
->fref
== XTAL_FREQ_48000MHZ
) {
2164 tmp
|= (CCTL_4319USB_48MHZ_PLL_SEL
<< CCTL_4319USB_XTAL_SEL_SHIFT
);
2166 W_REG(osh
, &cc
->chipcontrol_data
, tmp
);
2169 /* Flush deferred pll control registers writes */
2170 if (sih
->pmurev
>= 2)
2171 OR_REG(osh
, &cc
->pmucontrol
, PCTL_PLL_PLLCTL_UPD
);
2173 /* Write XtalFreq. Set the divisor also. */
2174 tmp
= R_REG(osh
, &cc
->pmucontrol
) &
2175 ~(PCTL_ILP_DIV_MASK
| PCTL_XTALFREQ_MASK
);
2176 tmp
|= (((((xt
->fref
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) &
2177 PCTL_ILP_DIV_MASK
) |
2178 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
);
2180 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && CHIPREV(sih
->chiprev
) == 0) {
2181 /* clear the htstretch before clearing HTReqEn */
2182 AND_REG(osh
, &cc
->clkstretch
, ~CSTRETCH_HT
);
2183 tmp
&= ~PCTL_HT_REQ_EN
;
2186 W_REG(osh
, &cc
->pmucontrol
, tmp
);
2189 /* query the CPU clock frequency */
2191 BCMINITFN(si_pmu1_cpuclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
2195 uint32 ndiv_int
, ndiv_frac
, p2div
, p1div
, fvco
;
2198 uint32 FVCO
= si_pmu1_pllfvco0(sih
);
2200 /* Read m1div from pllcontrol[1] */
2201 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2202 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2203 m1div
= (tmp
& PMU1_PLL0_PC1_M1DIV_MASK
) >> PMU1_PLL0_PC1_M1DIV_SHIFT
;
2206 /* Read p2div/p1div from pllcontrol[0] */
2207 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2208 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2209 p2div
= (tmp
& PMU1_PLL0_PC0_P2DIV_MASK
) >> PMU1_PLL0_PC0_P2DIV_SHIFT
;
2210 p1div
= (tmp
& PMU1_PLL0_PC0_P1DIV_MASK
) >> PMU1_PLL0_PC0_P1DIV_SHIFT
;
2212 /* Calculate fvco based on xtal freq and ndiv and pdiv */
2213 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2214 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2215 ndiv_int
= (tmp
& PMU1_PLL0_PC2_NDIV_INT_MASK
) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT
;
2217 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2218 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2219 ndiv_frac
= (tmp
& PMU1_PLL0_PC3_NDIV_FRAC_MASK
) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT
;
2221 fref
= si_pmu1_alpclk0(sih
, osh
, cc
) / 1000;
2223 fvco
= (fref
* ndiv_int
) << 8;
2224 fvco
+= (fref
* (ndiv_frac
>> 12)) >> 4;
2225 fvco
+= (fref
* (ndiv_frac
& 0xfff)) >> 12;
2232 PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n",
2233 ndiv_int
, ndiv_frac
, p2div
, p1div
, fvco
));
2238 /* Return ARM/SB clock */
2239 return FVCO
/ m1div
* 1000;
2241 #endif /* !_CFE_ || CFG_WL */
2243 /* initialize PLL */
2245 BCMATTACHFN(si_pmu_pll_init
)(si_t
*sih
, osl_t
*osh
, uint xtalfreq
)
2253 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2255 /* Remember original core before switch to chipc */
2256 origidx
= si_coreidx(sih
);
2257 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2260 switch (CHIPID(sih
->chip
)) {
2261 case BCM5354_CHIP_ID
:
2264 si_pmu0_pllinit0(sih
, osh
, cc
, xtalfreq
);
2266 #if !defined(_CFE_) || defined(CFG_WL)
2267 case BCM4328_CHIP_ID
:
2268 si_pmu0_pllinit0(sih
, osh
, cc
, xtalfreq
);
2270 case BCM4325_CHIP_ID
:
2271 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
2273 case BCM4329_CHIP_ID
:
2276 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
2278 case BCM4312_CHIP_ID
:
2279 /* assume default works */
2281 case BCM4322_CHIP_ID
:
2282 case BCM43221_CHIP_ID
:
2283 case BCM43231_CHIP_ID
:
2284 case BCM4342_CHIP_ID
: {
2285 if (CHIPREV(sih
->chiprev
) == 0) {
2286 uint32 minmask
, maxmask
;
2288 minmask
= R_REG(osh
, &cc
->min_res_mask
);
2289 maxmask
= R_REG(osh
, &cc
->max_res_mask
);
2291 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
2292 /* Have to remove HT Avail request before powering off PLL */
2293 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
2294 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
2295 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2296 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
2297 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
2299 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2302 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_SI_PLL_PLLCTL
);
2303 W_REG(osh
, &cc
->pllcontrol_data
, 0x380005c0);
2307 W_REG(osh
, &cc
->max_res_mask
, maxmask
);
2309 W_REG(osh
, &cc
->min_res_mask
, minmask
);
2315 case BCM4313_CHIP_ID
:
2316 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2317 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43420_CHIP_ID
:
2318 case BCM43421_CHIP_ID
:
2319 case BCM43226_CHIP_ID
:
2320 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
2321 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
2322 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
2323 case BCM43227_CHIP_ID
:
2324 case BCM43228_CHIP_ID
:
2325 case BCM43428_CHIP_ID
:
2326 case BCM6362_CHIP_ID
:
2328 case BCM4315_CHIP_ID
:
2329 case BCM4319_CHIP_ID
:
2330 case BCM4336_CHIP_ID
:
2331 case BCM4330_CHIP_ID
:
2332 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
2334 #endif /* !_CFE_ || CFG_WL */
2336 PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
2337 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
));
2341 #ifdef BCMDBG_FORCEHT
2342 OR_REG(osh
, &cc
->clk_ctl_st
, CCS_FORCEHT
);
2345 /* Return to original core */
2346 si_setcoreidx(sih
, origidx
);
2349 /* query alp/xtal clock frequency */
2351 BCMINITFN(si_pmu_alp_clock
)(si_t
*sih
, osl_t
*osh
)
2355 uint32 clock
= ALP_CLOCK
;
2360 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2362 /* Remember original core before switch to chipc */
2363 origidx
= si_coreidx(sih
);
2364 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2367 switch (CHIPID(sih
->chip
)) {
2368 case BCM4328_CHIP_ID
:
2369 clock
= si_pmu0_alpclk0(sih
, osh
, cc
);
2371 case BCM5354_CHIP_ID
:
2372 clock
= si_pmu0_alpclk0(sih
, osh
, cc
);
2374 #if !defined(_CFE_) || defined(CFG_WL)
2375 case BCM4325_CHIP_ID
:
2376 case BCM4329_CHIP_ID
:
2377 case BCM4315_CHIP_ID
:
2378 case BCM4319_CHIP_ID
:
2379 case BCM4336_CHIP_ID
:
2380 case BCM4330_CHIP_ID
:
2381 clock
= si_pmu1_alpclk0(sih
, osh
, cc
);
2383 #endif /* !_CFE_ || CFG_WL */
2384 case BCM4312_CHIP_ID
:
2385 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
2386 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2387 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43420_CHIP_ID
:
2388 case BCM43421_CHIP_ID
:
2389 case BCM43226_CHIP_ID
:
2390 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
2391 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
2392 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
2393 case BCM43227_CHIP_ID
:
2394 case BCM43228_CHIP_ID
:
2395 case BCM43428_CHIP_ID
:
2396 case BCM6362_CHIP_ID
:
2397 case BCM4342_CHIP_ID
:
2398 case BCM4716_CHIP_ID
:
2399 case BCM4748_CHIP_ID
:
2400 case BCM47162_CHIP_ID
:
2401 case BCM4313_CHIP_ID
:
2402 case BCM5357_CHIP_ID
:
2403 case BCM4749_CHIP_ID
:
2404 case BCM53572_CHIP_ID
:
2406 clock
= 20000 * 1000;
2408 case BCM5356_CHIP_ID
:
2409 case BCM4706_CHIP_ID
:
2411 clock
= 25000 * 1000;
2414 PMU_MSG(("No ALP clock specified "
2415 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2416 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
, clock
));
2420 /* Return to original core */
2421 si_setcoreidx(sih
, origidx
);
2425 /* Find the output of the "m" pll divider given pll controls that start with
2426 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
2429 BCMINITFN(si_pmu5_clock
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint pll0
, uint m
)
2431 uint32 tmp
, div
, ndiv
, p1
, p2
, fc
;
2433 if ((pll0
& 3) || (pll0
> PMU4716_MAINPLL_PLL0
)) {
2434 PMU_ERROR(("%s: Bad pll0: %d\n", __FUNCTION__
, pll0
));
2439 /* Strictly there is an m5 divider, but I'm not sure we use it */
2440 if ((m
== 0) || (m
> 4)) {
2441 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__
, m
));
2445 if ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
2446 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) {
2447 /* Detect failure in clock setting */
2448 if ((R_REG(osh
, &cc
->chipstatus
) & 0x40000) != 0) {
2449 return (133 * 1000000);
2453 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_P1P2_OFF
);
2454 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
2455 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2456 p1
= (tmp
& PMU5_PLL_P1_MASK
) >> PMU5_PLL_P1_SHIFT
;
2457 p2
= (tmp
& PMU5_PLL_P2_MASK
) >> PMU5_PLL_P2_SHIFT
;
2459 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_M14_OFF
);
2460 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
2461 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2462 div
= (tmp
>> ((m
- 1) * PMU5_PLL_MDIV_WIDTH
)) & PMU5_PLL_MDIV_MASK
;
2464 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_NM5_OFF
);
2465 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
2466 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2467 ndiv
= (tmp
& PMU5_PLL_NDIV_MASK
) >> PMU5_PLL_NDIV_SHIFT
;
2469 /* Do calculation in Mhz */
2470 fc
= si_pmu_alp_clock(sih
, osh
) / 1000000;
2471 fc
= (p1
* ndiv
* fc
) / p2
;
2473 PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
2474 __FUNCTION__
, p1
, p2
, ndiv
, ndiv
, m
, div
, fc
, fc
/ div
));
2476 /* Return clock in Hertz */
2477 return ((fc
/ div
) * 1000000);
2481 BCMINITFN(si_4706_pmu_clock
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint pll0
, uint m
)
2486 /* Strictly there is an m5 divider, but I'm not sure we use it */
2487 if ((m
== 0) || (m
> 4)) {
2488 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__
, m
));
2492 /* Get N divider to determine CPU clock */
2493 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU6_4706_PROCPLL_OFF
);
2494 w
= (R_REG(NULL
, &cc
->pllcontrol_data
) & PMU6_4706_PROC_NDIV_INT_MASK
) >>
2495 PMU6_4706_PROC_NDIV_INT_SHIFT
;
2496 /* Fixed reference clock 25MHz and m = 2 */
2497 clock
= w
* 25000000 / 2;
2498 if (m
== PMU5_MAINPLL_MEM
)
2500 else if (m
== PMU5_MAINPLL_SI
)
2506 /* query backplane clock frequency */
2507 /* For designs that feed the same clock to both backplane
2508 * and CPU just return the CPU clock speed.
2511 BCMINITFN(si_pmu_si_clock
)(si_t
*sih
, osl_t
*osh
)
2515 uint32 clock
= HT_CLOCK
;
2520 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2522 /* Remember original core before switch to chipc */
2523 origidx
= si_coreidx(sih
);
2524 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2527 switch (CHIPID(sih
->chip
)) {
2528 #if !defined(_CFE_) || defined(CFG_WL)
2529 case BCM4328_CHIP_ID
:
2530 clock
= si_pmu0_cpuclk0(sih
, osh
, cc
);
2532 case BCM4325_CHIP_ID
:
2533 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
2535 case BCM4322_CHIP_ID
:
2536 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
2537 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2538 case BCM43224_CHIP_ID
: case BCM43420_CHIP_ID
:
2539 case BCM43225_CHIP_ID
:
2540 case BCM43421_CHIP_ID
:
2541 case BCM43226_CHIP_ID
:
2542 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
2543 case BCM6362_CHIP_ID
:
2544 case BCM4342_CHIP_ID
:
2545 /* 96MHz backplane clock */
2546 clock
= 96000 * 1000;
2548 case BCM4329_CHIP_ID
:
2549 if (CHIPREV(sih
->chiprev
) == 0)
2550 clock
= 38400 * 1000;
2552 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
2554 case BCM4315_CHIP_ID
:
2555 case BCM4319_CHIP_ID
:
2556 case BCM4336_CHIP_ID
:
2557 case BCM4330_CHIP_ID
:
2558 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
2560 case BCM4313_CHIP_ID
:
2561 /* 80MHz backplane clock */
2562 clock
= 80000 * 1000;
2564 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
2565 case BCM43234_CHIP_ID
:
2566 clock
= (cc
->chipstatus
& CST43236_BP_CLK
) ? (120000 * 1000) : (96000 * 1000);
2568 case BCM43237_CHIP_ID
:
2569 clock
= (cc
->chipstatus
& CST43237_BP_CLK
) ? (96000 * 1000) : (80000 * 1000);
2571 #endif /* !_CFE_ || CFG_WL */
2572 case BCM5354_CHIP_ID
:
2575 case BCM4716_CHIP_ID
:
2576 case BCM4748_CHIP_ID
:
2577 case BCM47162_CHIP_ID
:
2578 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU4716_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2580 case BCM5356_CHIP_ID
:
2581 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU5356_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2583 case BCM5357_CHIP_ID
:
2584 case BCM4749_CHIP_ID
:
2585 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU5357_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2587 case BCM4706_CHIP_ID
:
2588 clock
= si_4706_pmu_clock(sih
, osh
, cc
, PMU4706_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2590 case BCM53572_CHIP_ID
:
2594 PMU_MSG(("No backplane clock specified "
2595 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2596 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
, clock
));
2600 /* Return to original core */
2601 si_setcoreidx(sih
, origidx
);
2605 /* query CPU clock frequency */
2607 BCMINITFN(si_pmu_cpu_clock
)(si_t
*sih
, osl_t
*osh
)
2613 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2615 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
2616 if (CHIPID(sih
->chip
) == BCM5354_CHIP_ID
)
2619 if (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
)
2622 if ((sih
->pmurev
>= 5) &&
2623 !((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) ||
2624 (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) ||
2625 (CHIPID(sih
->chip
) == BCM43234_CHIP_ID
) ||
2626 (CHIPID(sih
->chip
) == BCM43235_CHIP_ID
) ||
2627 (CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
2628 (CHIPID(sih
->chip
) == BCM43237_CHIP_ID
) ||
2629 (CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) ||
2630 (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) ||
2631 (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
))) {
2634 switch (CHIPID(sih
->chip
)) {
2635 case BCM5356_CHIP_ID
:
2636 pll
= PMU5356_MAINPLL_PLL0
;
2638 case BCM5357_CHIP_ID
:
2639 case BCM4749_CHIP_ID
:
2640 pll
= PMU5357_MAINPLL_PLL0
;
2643 pll
= PMU4716_MAINPLL_PLL0
;
2647 /* Remember original core before switch to chipc */
2648 origidx
= si_coreidx(sih
);
2649 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2652 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
2653 clock
= si_4706_pmu_clock(sih
, osh
, cc
,
2654 PMU4706_MAINPLL_PLL0
, PMU5_MAINPLL_CPU
);
2656 clock
= si_pmu5_clock(sih
, osh
, cc
, pll
, PMU5_MAINPLL_CPU
);
2658 /* Return to original core */
2659 si_setcoreidx(sih
, origidx
);
2661 clock
= si_pmu_si_clock(sih
, osh
);
2666 /* query memory clock frequency */
2668 BCMINITFN(si_pmu_mem_clock
)(si_t
*sih
, osl_t
*osh
)
2674 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2676 if (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
)
2679 if ((sih
->pmurev
>= 5) &&
2680 !((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) ||
2681 (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) ||
2682 (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
) ||
2683 (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) ||
2684 (CHIPID(sih
->chip
) == BCM43234_CHIP_ID
) ||
2685 (CHIPID(sih
->chip
) == BCM43235_CHIP_ID
) ||
2686 (CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
2687 (CHIPID(sih
->chip
) == BCM43237_CHIP_ID
) ||
2688 (CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) ||
2692 switch (CHIPID(sih
->chip
)) {
2693 case BCM5356_CHIP_ID
:
2694 pll
= PMU5356_MAINPLL_PLL0
;
2696 case BCM5357_CHIP_ID
:
2697 case BCM4749_CHIP_ID
:
2698 pll
= PMU5357_MAINPLL_PLL0
;
2701 pll
= PMU4716_MAINPLL_PLL0
;
2705 /* Remember original core before switch to chipc */
2706 origidx
= si_coreidx(sih
);
2707 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2710 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
2711 clock
= si_4706_pmu_clock(sih
, osh
, cc
,
2712 PMU4706_MAINPLL_PLL0
, PMU5_MAINPLL_MEM
);
2714 clock
= si_pmu5_clock(sih
, osh
, cc
, pll
, PMU5_MAINPLL_MEM
);
2716 /* Return to original core */
2717 si_setcoreidx(sih
, origidx
);
2719 clock
= si_pmu_si_clock(sih
, osh
);
2725 /* Measure ILP clock frequency */
2726 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */
2728 static uint32 ilpcycles_per_sec
= 0;
2731 BCMINITFN(si_pmu_ilp_clock
)(si_t
*sih
, osl_t
*osh
)
2733 if (ISSIM_ENAB(sih
))
2736 if (ilpcycles_per_sec
== 0) {
2737 uint32 start
, end
, delta
;
2738 uint32 origidx
= si_coreidx(sih
);
2739 chipcregs_t
*cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2741 start
= R_REG(osh
, &cc
->pmutimer
);
2742 OSL_DELAY(ILP_CALC_DUR
* 1000);
2743 end
= R_REG(osh
, &cc
->pmutimer
);
2744 delta
= end
- start
;
2745 ilpcycles_per_sec
= delta
* (1000 / ILP_CALC_DUR
);
2746 si_setcoreidx(sih
, origidx
);
2749 return ilpcycles_per_sec
;
2752 /* SDIO Pad drive strength to select value mappings */
2754 uint8 strength
; /* Pad Drive Strength in mA */
2755 uint8 sel
; /* Chip-specific select value */
2756 } sdiod_drive_str_t
;
2758 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
2759 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab1
)[] = {
2765 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
2766 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab2
)[] = {
2775 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
2776 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab3
)[] = {
2786 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
2789 BCMINITFN(si_sdiod_drive_strength_init
)(si_t
*sih
, osl_t
*osh
, uint32 drivestrength
)
2792 uint origidx
, intr_val
= 0;
2793 sdiod_drive_str_t
*str_tab
= NULL
;
2794 uint32 str_mask
= 0;
2795 uint32 str_shift
= 0;
2800 if (!(sih
->cccaps
& CC_CAP_PMU
)) {
2804 /* Remember original core before switch to chipc */
2805 cc
= (chipcregs_t
*) si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
2807 switch (SDIOD_DRVSTR_KEY(sih
->chip
, sih
->pmurev
)) {
2808 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 1):
2809 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab1
;
2810 str_mask
= 0x30000000;
2813 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 2):
2814 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 3):
2815 case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID
, 4):
2816 case SDIOD_DRVSTR_KEY(BCM4319_CHIP_ID
, 7):
2817 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab2
;
2818 str_mask
= 0x00003800;
2821 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID
, 8):
2822 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab3
;
2823 str_mask
= 0x00003800;
2828 PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
2829 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
));
2834 if (str_tab
!= NULL
) {
2835 uint32 drivestrength_sel
= 0;
2836 uint32 cc_data_temp
;
2839 for (i
= 0; str_tab
[i
].strength
!= 0; i
++) {
2840 if (drivestrength
>= str_tab
[i
].strength
) {
2841 drivestrength_sel
= str_tab
[i
].sel
;
2846 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
2847 cc_data_temp
= R_REG(osh
, &cc
->chipcontrol_data
);
2848 cc_data_temp
&= ~str_mask
;
2849 drivestrength_sel
<<= str_shift
;
2850 cc_data_temp
|= drivestrength_sel
;
2851 W_REG(osh
, &cc
->chipcontrol_data
, cc_data_temp
);
2853 PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
2854 drivestrength
, cc_data_temp
));
2857 /* Return to original core */
2858 si_restore_core(sih
, origidx
, intr_val
);
2861 /* initialize PMU */
2863 BCMATTACHFN(si_pmu_init
)(si_t
*sih
, osl_t
*osh
)
2868 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2870 /* Remember original core before switch to chipc */
2871 origidx
= si_coreidx(sih
);
2872 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2875 if (sih
->pmurev
== 1)
2876 AND_REG(osh
, &cc
->pmucontrol
, ~PCTL_NOILP_ON_WAIT
);
2877 else if (sih
->pmurev
>= 2)
2878 OR_REG(osh
, &cc
->pmucontrol
, PCTL_NOILP_ON_WAIT
);
2880 #if !defined(_CFE_) || defined(CFG_WL)
2881 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && (sih
->chiprev
== 2)) {
2882 /* Fix for 4329b0 bad LPOM state. */
2883 W_REG(osh
, &cc
->regcontrol_addr
, 2);
2884 OR_REG(osh
, &cc
->regcontrol_data
, 0x100);
2886 W_REG(osh
, &cc
->regcontrol_addr
, 3);
2887 OR_REG(osh
, &cc
->regcontrol_data
, 0x4);
2890 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
2891 /* Limiting the PALDO spike during init time */
2892 si_pmu_regcontrol(sih
, 2, 0x00000007, 0x00000005);
2894 #endif /* !_CFE_ || CFG_WL */
2896 /* Return to original core */
2897 si_setcoreidx(sih
, origidx
);
2900 #if !defined(_CFE_) || defined(CFG_WL)
2901 /* Return up time in ILP cycles for the given resource. */
2903 BCMINITFN(si_pmu_res_uptime
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint8 rsrc
)
2906 uint up
, i
, dup
, dmax
;
2907 uint32 min_mask
= 0, max_mask
= 0;
2909 /* uptime of resource 'rsrc' */
2910 W_REG(osh
, &cc
->res_table_sel
, rsrc
);
2911 up
= (R_REG(osh
, &cc
->res_updn_timer
) >> 8) & 0xff;
2913 /* direct dependancies of resource 'rsrc' */
2914 deps
= si_pmu_res_deps(sih
, osh
, cc
, PMURES_BIT(rsrc
), FALSE
);
2915 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
2916 if (!(deps
& PMURES_BIT(i
)))
2918 deps
&= ~si_pmu_res_deps(sih
, osh
, cc
, PMURES_BIT(i
), TRUE
);
2920 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
2923 /* max uptime of direct dependancies */
2925 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
2926 if (!(deps
& PMURES_BIT(i
)))
2928 dup
= si_pmu_res_uptime(sih
, osh
, cc
, (uint8
)i
);
2933 PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n",
2934 rsrc
, up
, deps
, dmax
));
2936 return up
+ dmax
+ PMURES_UP_TRANSITION
;
2939 /* Return dependancies (direct or all/indirect) for the given resources */
2941 si_pmu_res_deps(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 rsrcs
, bool all
)
2946 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
2947 if (!(rsrcs
& PMURES_BIT(i
)))
2949 W_REG(osh
, &cc
->res_table_sel
, i
);
2950 deps
|= R_REG(osh
, &cc
->res_dep_mask
);
2953 return !all
? deps
: (deps
? (deps
| si_pmu_res_deps(sih
, osh
, cc
, deps
, TRUE
)) : 0);
2956 /* power up/down OTP through PMU resources */
2958 si_pmu_otp_power(si_t
*sih
, osl_t
*osh
, bool on
)
2962 uint32 rsrcs
= 0; /* rsrcs to turn on/off OTP power */
2964 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2966 /* Don't do anything if OTP is disabled */
2967 if (si_is_otp_disabled(sih
)) {
2968 PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
2972 /* Remember original core before switch to chipc */
2973 origidx
= si_coreidx(sih
);
2974 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2977 switch (CHIPID(sih
->chip
)) {
2978 case BCM4322_CHIP_ID
:
2979 case BCM43221_CHIP_ID
:
2980 case BCM43231_CHIP_ID
:
2981 case BCM4342_CHIP_ID
:
2982 rsrcs
= PMURES_BIT(RES4322_OTP_PU
);
2984 case BCM4325_CHIP_ID
:
2985 rsrcs
= PMURES_BIT(RES4325_OTP_PU
);
2987 case BCM4315_CHIP_ID
:
2988 rsrcs
= PMURES_BIT(RES4315_OTP_PU
);
2990 case BCM4329_CHIP_ID
:
2991 rsrcs
= PMURES_BIT(RES4329_OTP_PU
);
2993 case BCM4319_CHIP_ID
:
2994 rsrcs
= PMURES_BIT(RES4319_OTP_PU
);
2996 case BCM4336_CHIP_ID
:
2997 rsrcs
= PMURES_BIT(RES4336_OTP_PU
);
2999 case BCM4330_CHIP_ID
:
3000 rsrcs
= PMURES_BIT(RES4330_OTP_PU
);
3009 /* Figure out the dependancies (exclude min_res_mask) */
3010 uint32 deps
= si_pmu_res_deps(sih
, osh
, cc
, rsrcs
, TRUE
);
3011 uint32 min_mask
= 0, max_mask
= 0;
3012 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
3014 /* Turn on/off the power */
3016 PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", rsrcs
| deps
));
3017 OR_REG(osh
, &cc
->min_res_mask
, (rsrcs
| deps
));
3019 SPINWAIT(!(R_REG(osh
, &cc
->res_state
) & rsrcs
), PMU_MAX_TRANSITION_DLY
);
3020 ASSERT(R_REG(osh
, &cc
->res_state
) & rsrcs
);
3023 PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", rsrcs
| deps
));
3024 AND_REG(osh
, &cc
->min_res_mask
, ~(rsrcs
| deps
));
3027 SPINWAIT((((otps
= R_REG(osh
, &cc
->otpstatus
)) & OTPS_READY
) !=
3028 (on
? OTPS_READY
: 0)), 100);
3029 ASSERT((otps
& OTPS_READY
) == (on
? OTPS_READY
: 0));
3030 if ((otps
& OTPS_READY
) != (on
? OTPS_READY
: 0))
3031 PMU_MSG(("OTP ready bit not %s after wait\n", (on
? "ON" : "OFF")));
3034 /* Return to original core */
3035 si_setcoreidx(sih
, origidx
);
3039 si_pmu_rcal(si_t
*sih
, osl_t
*osh
)
3043 uint rcal_done
, BT_out_of_reset
;
3045 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3047 /* Remember original core before switch to chipc */
3048 origidx
= si_coreidx(sih
);
3049 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3052 switch (CHIPID(sih
->chip
)) {
3053 case BCM4325_CHIP_ID
: {
3058 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3060 /* Power Down RCAL Block */
3061 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3063 /* Check if RCAL is already done by BT */
3064 rcal_done
= ((R_REG(osh
, &cc
->chipstatus
)) & 0x8) >> 3;
3066 /* If RCAL already done, note that BT is out of reset */
3067 if (rcal_done
== 1) {
3068 BT_out_of_reset
= 1;
3070 BT_out_of_reset
= 0;
3073 /* Power Up RCAL block */
3074 OR_REG(osh
, &cc
->chipcontrol_data
, 0x04);
3076 /* Wait for completion */
3077 SPINWAIT(0 == (R_REG(osh
, &cc
->chipstatus
) & 0x08), 10 * 1000 * 1000);
3078 ASSERT(R_REG(osh
, &cc
->chipstatus
) & 0x08);
3080 if (BT_out_of_reset
) {
3083 /* Drop the LSB to convert from 5 bit code to 4 bit code */
3084 rcal_code
= (uint8
)(R_REG(osh
, &cc
->chipstatus
) >> 5) & 0x0f;
3087 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
3088 R_REG(osh
, &cc
->chipstatus
), rcal_code
));
3090 /* Write RCal code into pmu_vreg_ctrl[32:29] */
3091 W_REG(osh
, &cc
->regcontrol_addr
, 0);
3092 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~((uint32
)0x07 << 29);
3093 val
|= (uint32
)(rcal_code
& 0x07) << 29;
3094 W_REG(osh
, &cc
->regcontrol_data
, val
);
3095 W_REG(osh
, &cc
->regcontrol_addr
, 1);
3096 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~(uint32
)0x01;
3097 val
|= (uint32
)((rcal_code
>> 3) & 0x01);
3098 W_REG(osh
, &cc
->regcontrol_data
, val
);
3100 /* Write RCal code into pmu_chip_ctrl[33:30] */
3101 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3102 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~((uint32
)0x03 << 30);
3103 val
|= (uint32
)(rcal_code
& 0x03) << 30;
3104 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3105 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3106 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~(uint32
)0x03;
3107 val
|= (uint32
)((rcal_code
>> 2) & 0x03);
3108 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3110 /* Set override in pmu_chip_ctrl[29] */
3111 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3112 OR_REG(osh
, &cc
->chipcontrol_data
, (0x01 << 29));
3114 /* Power off RCal block */
3115 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3116 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3120 case BCM4329_CHIP_ID
: {
3125 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3127 /* Power Down RCAL Block */
3128 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3130 /* Power Up RCAL block */
3131 OR_REG(osh
, &cc
->chipcontrol_data
, 0x04);
3133 /* Wait for completion */
3134 SPINWAIT(0 == (R_REG(osh
, &cc
->chipstatus
) & 0x08), 10 * 1000 * 1000);
3135 ASSERT(R_REG(osh
, &cc
->chipstatus
) & 0x08);
3137 /* Drop the LSB to convert from 5 bit code to 4 bit code */
3138 rcal_code
= (uint8
)(R_REG(osh
, &cc
->chipstatus
) >> 5) & 0x0f;
3140 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
3141 R_REG(osh
, &cc
->chipstatus
), rcal_code
));
3143 /* Write RCal code into pmu_vreg_ctrl[32:29] */
3144 W_REG(osh
, &cc
->regcontrol_addr
, 0);
3145 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~((uint32
)0x07 << 29);
3146 val
|= (uint32
)(rcal_code
& 0x07) << 29;
3147 W_REG(osh
, &cc
->regcontrol_data
, val
);
3148 W_REG(osh
, &cc
->regcontrol_addr
, 1);
3149 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~(uint32
)0x01;
3150 val
|= (uint32
)((rcal_code
>> 3) & 0x01);
3151 W_REG(osh
, &cc
->regcontrol_data
, val
);
3153 /* Write RCal code into pmu_chip_ctrl[33:30] */
3154 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3155 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~((uint32
)0x03 << 30);
3156 val
|= (uint32
)(rcal_code
& 0x03) << 30;
3157 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3158 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3159 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~(uint32
)0x03;
3160 val
|= (uint32
)((rcal_code
>> 2) & 0x03);
3161 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3163 /* Set override in pmu_chip_ctrl[29] */
3164 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3165 OR_REG(osh
, &cc
->chipcontrol_data
, (0x01 << 29));
3167 /* Power off RCal block */
3168 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3169 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3177 /* Return to original core */
3178 si_setcoreidx(sih
, origidx
);
3182 si_pmu_spuravoid(si_t
*sih
, osl_t
*osh
, uint8 spuravoid
)
3185 uint origidx
, intr_val
;
3188 /* Remember original core before switch to chipc */
3189 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
3192 /* force the HT off */
3193 if (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) {
3194 tmp
= R_REG(osh
, &cc
->max_res_mask
);
3195 tmp
&= ~RES4336_HT_AVAIL
;
3196 W_REG(osh
, &cc
->max_res_mask
, tmp
);
3197 /* wait for the ht to really go away */
3198 SPINWAIT(((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
) == 0), 10000);
3199 ASSERT((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
) == 0);
3202 /* update the pll changes */
3203 si_pmu_spuravoid_pllupdate(sih
, cc
, osh
, spuravoid
);
3205 /* enable HT back on */
3206 if (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) {
3207 tmp
= R_REG(osh
, &cc
->max_res_mask
);
3208 tmp
|= RES4336_HT_AVAIL
;
3209 W_REG(osh
, &cc
->max_res_mask
, tmp
);
3212 /* Return to original core */
3213 si_restore_core(sih
, origidx
, intr_val
);
3217 si_pmu_spuravoid_pllupdate(si_t
*sih
, chipcregs_t
*cc
, osl_t
*osh
, uint8 spuravoid
)
3220 uint8 phypll_offset
= 0;
3221 uint8 bcm5357_bcm43236_p1div
[] = {0x1, 0x5, 0x5};
3222 uint8 bcm5357_bcm43236_ndiv
[] = {0x30, 0xf6, 0xfc};
3227 switch (CHIPID(sih
->chip
)) {
3228 case BCM5357_CHIP_ID
: case BCM4749_CHIP_ID
:
3229 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
3230 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
3231 case BCM6362_CHIP_ID
: case BCM53572_CHIP_ID
:
3233 if ((CHIPID(sih
->chip
) == BCM6362_CHIP_ID
) && (sih
->chiprev
== 0)) {
3234 /* 6362a0 (same clks as 4322[4-6]) */
3235 if (spuravoid
== 1) {
3236 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3237 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500010);
3238 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3239 W_REG(osh
, &cc
->pllcontrol_data
, 0x000C0C06);
3240 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3241 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3242 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3243 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3244 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3245 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
3246 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3247 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3249 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3250 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100010);
3251 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3252 W_REG(osh
, &cc
->pllcontrol_data
, 0x000c0c06);
3253 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3254 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3255 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3256 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3257 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3258 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3259 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3260 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3264 /* 5357[ab]0, 43236[ab]0, and 6362b0 */
3266 /* BCM5357 needs to touch PLL1_PLLCTL[02],so offset PLL0_PLLCTL[02] by 6 */
3267 phypll_offset
= ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
3268 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
) ||
3269 (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
)) ? 6 : 0;
3271 /* RMW only the P1 divider */
3272 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
+ phypll_offset
);
3273 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
3274 tmp
&= (~(PMU1_PLL0_PC0_P1DIV_MASK
));
3275 tmp
|= (bcm5357_bcm43236_p1div
[spuravoid
] << PMU1_PLL0_PC0_P1DIV_SHIFT
);
3276 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
3278 /* RMW only the int feedback divider */
3279 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
+ phypll_offset
);
3280 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
3281 tmp
&= ~(PMU1_PLL0_PC2_NDIV_INT_MASK
);
3282 tmp
|= (bcm5357_bcm43236_ndiv
[spuravoid
]) << PMU1_PLL0_PC2_NDIV_INT_SHIFT
;
3283 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
3289 case BCM4331_CHIP_ID
:
3290 case BCM43431_CHIP_ID
:
3291 if (ISSIM_ENAB(sih
)) {
3292 if (spuravoid
== 2) {
3293 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3294 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000002);
3295 } else if (spuravoid
== 1) {
3296 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3297 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000001);
3299 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3300 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3303 if (spuravoid
== 2) {
3304 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3305 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500014);
3306 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3307 W_REG(osh
, &cc
->pllcontrol_data
, 0x0FC00a08);
3308 } else if (spuravoid
== 1) {
3309 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3310 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500014);
3311 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3312 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3314 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3315 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100014);
3316 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3317 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3323 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
3324 case BCM43226_CHIP_ID
:
3325 if (spuravoid
== 1) {
3326 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3327 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500010);
3328 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3329 W_REG(osh
, &cc
->pllcontrol_data
, 0x000C0C06);
3330 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3331 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3332 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3333 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3334 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3335 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
3336 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3337 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3339 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3340 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100010);
3341 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3342 W_REG(osh
, &cc
->pllcontrol_data
, 0x000c0c06);
3343 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3344 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3345 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3346 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3347 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3348 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3349 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3350 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3355 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
3356 case BCM43420_CHIP_ID
:
3357 if (spuravoid
== 1) {
3358 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3359 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500008);
3360 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3361 W_REG(osh
, &cc
->pllcontrol_data
, 0x0C000C06);
3362 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3363 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3364 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3365 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3366 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3367 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
3368 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3369 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3371 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3372 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100008);
3373 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3374 W_REG(osh
, &cc
->pllcontrol_data
, 0x0c000c06);
3375 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3376 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3377 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3378 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3379 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3380 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3381 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3382 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888855);
3388 case BCM4716_CHIP_ID
:
3389 case BCM4748_CHIP_ID
:
3390 case BCM47162_CHIP_ID
:
3391 if (spuravoid
== 1) {
3392 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3393 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500060);
3394 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3395 W_REG(osh
, &cc
->pllcontrol_data
, 0x080C0C06);
3396 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3397 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600000);
3398 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3399 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3400 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3401 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E924);
3402 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3403 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3405 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3406 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100060);
3407 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3408 W_REG(osh
, &cc
->pllcontrol_data
, 0x080c0c06);
3409 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3410 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000000);
3411 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3412 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3413 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3414 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3415 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3416 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3422 case BCM4322_CHIP_ID
:
3423 case BCM43221_CHIP_ID
:
3424 case BCM43231_CHIP_ID
:
3425 case BCM4342_CHIP_ID
:
3426 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3427 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100070);
3428 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3429 W_REG(osh
, &cc
->pllcontrol_data
, 0x1014140a);
3430 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3431 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888854);
3433 if (spuravoid
== 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
3434 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3435 W_REG(osh
, &cc
->pllcontrol_data
, 0x05201828);
3436 } else { /* enable 40/80/160Mhz clock mode */
3437 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3438 W_REG(osh
, &cc
->pllcontrol_data
, 0x05001828);
3443 case BCM4319_CHIP_ID
:
3445 case BCM4336_CHIP_ID
:
3446 /* Looks like these are only for default xtal freq 26MHz */
3447 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3448 W_REG(osh
, &cc
->pllcontrol_data
, 0x02100020);
3450 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3451 W_REG(osh
, &cc
->pllcontrol_data
, 0x0C0C0C0C);
3453 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3454 W_REG(osh
, &cc
->pllcontrol_data
, 0x01240C0C);
3456 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3457 W_REG(osh
, &cc
->pllcontrol_data
, 0x202C2820);
3459 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3460 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888825);
3462 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3463 if (spuravoid
== 1) {
3464 W_REG(osh
, &cc
->pllcontrol_data
, 0x00EC4EC4);
3466 W_REG(osh
, &cc
->pllcontrol_data
, 0x00762762);
3469 tmp
= PCTL_PLL_PLLCTL_UPD
;
3471 case BCM43227_CHIP_ID
:
3472 case BCM43228_CHIP_ID
:
3473 case BCM43428_CHIP_ID
:
3475 /* PLL Settings for spur avoidance on/off mode, no on2 support for 43228A0 */
3476 if (spuravoid
== 1) {
3477 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3478 W_REG(osh
, &cc
->pllcontrol_data
, 0x01100014);
3479 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3480 W_REG(osh
, &cc
->pllcontrol_data
, 0x040C0C06);
3481 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3482 W_REG(osh
, &cc
->pllcontrol_data
, 0x03140A08);
3483 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3484 W_REG(osh
, &cc
->pllcontrol_data
, 0x00333333);
3485 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3486 W_REG(osh
, &cc
->pllcontrol_data
, 0x202C2820);
3487 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3488 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3490 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3491 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100014);
3492 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3493 W_REG(osh
, &cc
->pllcontrol_data
, 0x040c0c06);
3494 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3495 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3496 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3497 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3498 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3499 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3500 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3501 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3506 PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n",
3507 __FUNCTION__
, bcm_chipname(sih
->chip
, chn
, 8)));
3511 tmp
|= R_REG(osh
, &cc
->pmucontrol
);
3512 W_REG(osh
, &cc
->pmucontrol
, tmp
);
3516 si_pmu_gband_spurwar(si_t
*sih
, osl_t
*osh
)
3519 uint origidx
, intr_val
;
3520 uint32 cc_clk_ctl_st
;
3521 uint32 minmask
, maxmask
;
3523 if ((CHIPID(sih
->chip
) == BCM43222_CHIP_ID
) ||
3524 (CHIPID(sih
->chip
) == BCM43420_CHIP_ID
)) {
3525 /* Remember original core before switch to chipc */
3526 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
3529 /* Remove force HT and HT Avail Request from chipc core */
3530 cc_clk_ctl_st
= R_REG(osh
, &cc
->clk_ctl_st
);
3531 AND_REG(osh
, &cc
->clk_ctl_st
, ~(CCS_FORCEHT
| CCS_HTAREQ
));
3533 minmask
= R_REG(osh
, &cc
->min_res_mask
);
3534 maxmask
= R_REG(osh
, &cc
->max_res_mask
);
3536 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
3537 /* Have to remove HT Avail request before powering off PLL */
3538 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
3539 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
3540 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
3541 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
3542 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
3544 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
3546 /* Change backplane clock speed from 96 MHz to 80 MHz */
3547 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_PLL_PLLCTL2
);
3548 W_REG(osh
, &cc
->pllcontrol_data
, (R_REG(osh
, &cc
->pllcontrol_data
) &
3549 ~(PMU2_PLL_PC2_M6DIV_MASK
)) |
3550 (0xc << PMU2_PLL_PC2_M6DIV_SHIFT
));
3552 /* Reduce the driver strengths of the phyclk160, adcclk80, and phyck80
3553 * clocks from 0x8 to 0x1
3555 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_PLL_PLLCTL5
);
3556 W_REG(osh
, &cc
->pllcontrol_data
, (R_REG(osh
, &cc
->pllcontrol_data
) &
3557 ~(PMU2_PLL_PC5_CLKDRIVE_CH1_MASK
|
3558 PMU2_PLL_PC5_CLKDRIVE_CH2_MASK
|
3559 PMU2_PLL_PC5_CLKDRIVE_CH3_MASK
|
3560 PMU2_PLL_PC5_CLKDRIVE_CH4_MASK
)) |
3561 ((1 << PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT
) |
3562 (1 << PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT
) |
3563 (1 << PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT
) |
3564 (1 << PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT
)));
3566 W_REG(osh
, &cc
->pmucontrol
, R_REG(osh
, &cc
->pmucontrol
) | PCTL_PLL_PLLCTL_UPD
);
3568 /* Restore min_res_mask and max_res_mask */
3570 W_REG(osh
, &cc
->max_res_mask
, maxmask
);
3572 W_REG(osh
, &cc
->min_res_mask
, minmask
);
3574 /* Make sure the PLL is on. Spinwait until the HTAvail is True */
3575 SPINWAIT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
), PMU_MAX_TRANSITION_DLY
);
3576 ASSERT((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
3578 /* Restore force HT and HT Avail Request on the chipc core */
3579 W_REG(osh
, &cc
->clk_ctl_st
, cc_clk_ctl_st
);
3581 /* Return to original core */
3582 si_restore_core(sih
, origidx
, intr_val
);
3587 si_pmu_is_otp_powered(si_t
*sih
, osl_t
*osh
)
3593 /* Remember original core before switch to chipc */
3594 idx
= si_coreidx(sih
);
3595 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3598 switch (CHIPID(sih
->chip
)) {
3599 case BCM4322_CHIP_ID
:
3600 case BCM43221_CHIP_ID
:
3601 case BCM43231_CHIP_ID
:
3602 case BCM4342_CHIP_ID
:
3603 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4322_OTP_PU
)) != 0;
3605 case BCM4325_CHIP_ID
:
3606 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4325_OTP_PU
)) != 0;
3608 case BCM4329_CHIP_ID
:
3609 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4329_OTP_PU
)) != 0;
3611 case BCM4315_CHIP_ID
:
3612 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4315_OTP_PU
)) != 0;
3614 case BCM4319_CHIP_ID
:
3615 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4319_OTP_PU
)) != 0;
3617 case BCM4336_CHIP_ID
:
3618 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4336_OTP_PU
)) != 0;
3620 case BCM4330_CHIP_ID
:
3621 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4330_OTP_PU
)) != 0;
3624 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
3625 * Use OTP_INIT command to reset/refresh state.
3627 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
3628 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
3629 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
3630 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
: case BCM43420_CHIP_ID
:
3631 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
3639 /* Return to original core */
3640 si_setcoreidx(sih
, idx
);
3643 #endif /* !_CFE_ || CFG_WL */
3646 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
3647 si_pmu_sprom_enable(si_t
*sih
, osl_t
*osh
, bool enable
)
3649 BCMATTACHFN(si_pmu_sprom_enable
)(si_t
*sih
, osl_t
*osh
, bool enable
)
3655 /* Remember original core before switch to chipc */
3656 origidx
= si_coreidx(sih
);
3657 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3660 switch (CHIPID(sih
->chip
)) {
3661 case BCM4315_CHIP_ID
:
3662 if (CHIPREV(sih
->chiprev
) < 1)
3664 if (sih
->chipst
& CST4315_SPROM_SEL
) {
3666 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3667 val
= R_REG(osh
, &cc
->chipcontrol_data
);
3672 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3679 /* Return to original core */
3680 si_setcoreidx(sih
, origidx
);
3684 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
3685 si_pmu_is_sprom_enabled(si_t
*sih
, osl_t
*osh
)
3687 BCMATTACHFN(si_pmu_is_sprom_enabled
)(si_t
*sih
, osl_t
*osh
)
3694 /* Remember original core before switch to chipc */
3695 origidx
= si_coreidx(sih
);
3696 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3699 switch (CHIPID(sih
->chip
)) {
3700 case BCM4315_CHIP_ID
:
3701 if (CHIPREV(sih
->chiprev
) < 1)
3703 if (!(sih
->chipst
& CST4315_SPROM_SEL
))
3705 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3706 if (R_REG(osh
, &cc
->chipcontrol_data
) & 0x80000000)
3713 /* Return to original core */
3714 si_setcoreidx(sih
, origidx
);
3718 /* initialize PMU chip controls and other chip level stuff */
3720 BCMATTACHFN(si_pmu_chip_init
)(si_t
*sih
, osl_t
*osh
)
3724 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3726 #ifdef CHIPC_UART_ALWAYS_ON
3727 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, clk_ctl_st
), CCS_FORCEALP
, CCS_FORCEALP
);
3728 #endif /* CHIPC_UART_ALWAYS_ON */
3731 /* Gate off SPROM clock and chip select signals */
3732 si_pmu_sprom_enable(sih
, osh
, FALSE
);
3735 /* Remember original core */
3736 origidx
= si_coreidx(sih
);
3738 #if !defined(_CFE_) || defined(CFG_WL)
3739 /* Misc. chip control, has nothing to do with PMU */
3740 switch (CHIPID(sih
->chip
)) {
3741 case BCM4315_CHIP_ID
:
3743 si_setcore(sih
, PCMCIA_CORE_ID
, 0);
3744 si_core_disable(sih
, 0);
3747 case BCM4319_CHIP_ID
:
3748 /* No support for external LPO, so power it down */
3749 si_pmu_chipcontrol(sih
, 0, (1<<28), (0<<28));
3754 #endif /* !_CFE_ || CFG_WL */
3756 /* Return to original core */
3757 si_setcoreidx(sih
, origidx
);
3760 /* initialize PMU switch/regulators */
3762 BCMATTACHFN(si_pmu_swreg_init
)(si_t
*sih
, osl_t
*osh
)
3764 #if !defined(_CFE_) || defined(CFG_WL)
3765 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3767 switch (CHIPID(sih
->chip
)) {
3768 case BCM4325_CHIP_ID
:
3769 if (CHIPREV(sih
->chiprev
) < 3)
3771 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >> CST4325_PMUTOP_2B_SHIFT
) == 1) {
3772 /* Bump CLDO PWM output voltage to 1.25V */
3773 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_PWM
, 0xf);
3774 /* Bump CLDO BURST output voltage to 1.25V */
3775 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_BURST
, 0xf);
3777 /* Bump CBUCK PWM output voltage to 1.5V */
3778 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_PWM
, 0xb);
3779 /* Bump CBUCK BURST output voltage to 1.5V */
3780 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_BURST
, 0xb);
3781 /* Bump LNLDO1 output voltage to 1.25V */
3782 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_LNLDO1
, 0x1);
3783 /* Select LNLDO2 output voltage to 2.5V */
3784 if (sih
->boardflags
& BFL_LNLDO2_2P5
)
3785 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_LNLDO2_SEL
, 0x1);
3787 case BCM4315_CHIP_ID
: {
3792 if (CHIPREV(sih
->chiprev
) != 2)
3795 /* Remember original core before switch to chipc */
3796 origidx
= si_coreidx(sih
);
3797 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3800 W_REG(osh
, &cc
->regcontrol_addr
, 4);
3801 val
= R_REG(osh
, &cc
->regcontrol_data
);
3802 val
|= (uint32
)(1 << 16);
3803 W_REG(osh
, &cc
->regcontrol_data
, val
);
3805 /* Return to original core */
3806 si_setcoreidx(sih
, origidx
);
3809 case BCM4336_CHIP_ID
:
3810 /* Reduce CLDO PWM output voltage to 1.2V */
3811 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_PWM
, 0xe);
3812 /* Reduce CLDO BURST output voltage to 1.2V */
3813 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_BURST
, 0xe);
3814 /* Reduce LNLDO1 output voltage to 1.2V */
3815 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_LNLDO1
, 0xe);
3816 if (CHIPREV(sih
->chiprev
) == 0)
3817 si_pmu_regcontrol(sih
, 2, 0x400000, 0x400000);
3820 case BCM4330_CHIP_ID
:
3821 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
3822 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_PWM
, 0);
3827 #endif /* !_CFE_ || CFG_WL */
3831 si_pmu_radio_enable(si_t
*sih
, bool enable
)
3833 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3835 switch (CHIPID(sih
->chip
)) {
3836 case BCM4325_CHIP_ID
:
3837 if (sih
->boardflags
& BFL_FASTPWR
)
3840 if ((sih
->boardflags
& BFL_BUCKBOOST
)) {
3841 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, min_res_mask
),
3842 PMURES_BIT(RES4325_BUCK_BOOST_BURST
),
3843 enable
? PMURES_BIT(RES4325_BUCK_BOOST_BURST
) : 0);
3847 OSL_DELAY(100 * 1000);
3850 case BCM4319_CHIP_ID
:
3852 si_write_wrapperreg(sih
, AI_OOBSELOUTB74
, (uint32
)0x868584);
3854 si_write_wrapperreg(sih
, AI_OOBSELOUTB74
, (uint32
)0x060584);
3859 /* Wait for a particular clock level to be on the backplane */
3861 si_pmu_waitforclk_on_backplane(si_t
*sih
, osl_t
*osh
, uint32 clk
, uint32 delay
)
3866 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3868 /* Remember original core before switch to chipc */
3869 origidx
= si_coreidx(sih
);
3870 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3874 SPINWAIT(((R_REG(osh
, &cc
->pmustatus
) & clk
) != clk
), delay
);
3876 /* Return to original core */
3877 si_setcoreidx(sih
, origidx
);
3879 return (R_REG(osh
, &cc
->pmustatus
) & clk
);
3883 * Measures the ALP clock frequency in KHz. Returns 0 if not possible.
3884 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
3887 #define EXT_ILP_HZ 32768
3890 BCMATTACHFN(si_pmu_measure_alpclk
)(si_t
*sih
, osl_t
*osh
)
3896 if (sih
->pmurev
< 10)
3899 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3901 /* Remember original core before switch to chipc */
3902 origidx
= si_coreidx(sih
);
3903 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3906 if (R_REG(osh
, &cc
->pmustatus
) & PST_EXTLPOAVAIL
) {
3907 uint32 ilp_ctr
, alp_hz
;
3909 /* Enable the reg to measure the freq, in case disabled before */
3910 W_REG(osh
, &cc
->pmu_xtalfreq
, 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT
);
3912 /* Delay for well over 4 ILP clocks */
3915 /* Read the latched number of ALP ticks per 4 ILP ticks */
3916 ilp_ctr
= R_REG(osh
, &cc
->pmu_xtalfreq
) & PMU_XTALFREQ_REG_ILPCTR_MASK
;
3918 /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
3919 W_REG(osh
, &cc
->pmu_xtalfreq
, 0);
3921 /* Calculate ALP frequency */
3922 alp_hz
= (ilp_ctr
* EXT_ILP_HZ
) / 4;
3924 /* Round to nearest 100KHz, and at the same time convert to KHz */
3925 alp_khz
= (alp_hz
+ 50000) / 100000 * 100;
3929 /* Return to original core */
3930 si_setcoreidx(sih
, origidx
);
3935 #if !defined(_CFE_) || defined(CFG_WL)
3937 si_pmu_set_4330_plldivs(si_t
*sih
, uint8 dacrate
)
3939 uint32 FVCO
= si_pmu1_pllfvco0(sih
)/1000;
3940 uint32 m1div
, m2div
, m3div
, m4div
, m5div
, m6div
;
3941 uint32 pllc1
, pllc2
;
3943 m2div
= m3div
= m4div
= m6div
= FVCO
/80;
3945 m5div
= FVCO
/dacrate
;
3947 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
3951 pllc1
= (m1div
<< PMU1_PLL0_PC1_M1DIV_SHIFT
) | (m2div
<< PMU1_PLL0_PC1_M2DIV_SHIFT
) |
3952 (m3div
<< PMU1_PLL0_PC1_M3DIV_SHIFT
) | (m4div
<< PMU1_PLL0_PC1_M4DIV_SHIFT
);
3953 si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL1
, ~0, pllc1
);
3955 pllc2
= si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL2
, 0, 0);
3956 pllc2
&= ~(PMU1_PLL0_PC2_M5DIV_MASK
| PMU1_PLL0_PC2_M6DIV_MASK
);
3957 pllc2
|= ((m5div
<< PMU1_PLL0_PC2_M5DIV_SHIFT
) | (m6div
<< PMU1_PLL0_PC2_M6DIV_SHIFT
));
3958 si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL2
, ~0, pllc2
);
3960 #endif /* !_CFE_ || CFG_WL */