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_val
= 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 BCM43131_CHIP_ID
:
373 case BCM43227_CHIP_ID
:
374 case BCM43228_CHIP_ID
:
375 case BCM43428_CHIP_ID
:
376 case BCM6362_CHIP_ID
:
377 case BCM4342_CHIP_ID
:
378 case BCM4313_CHIP_ID
:
379 delay_val
= ISSIM_ENAB(sih
) ? 70 : 3700;
381 case BCM4328_CHIP_ID
:
384 case BCM4325_CHIP_ID
:
388 uint32 ilp
= si_ilp_clock(sih
);
389 delay_val
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4325_HT_AVAIL
) +
390 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
391 delay_val
= (11 * delay_val
) / 10;
394 case BCM4329_CHIP_ID
:
398 uint32 ilp
= si_ilp_clock(sih
);
399 delay_val
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4329_HT_AVAIL
) +
400 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
401 delay_val
= (11 * delay_val
) / 10;
404 case BCM4315_CHIP_ID
:
408 uint32 ilp
= si_ilp_clock(sih
);
409 delay_val
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4315_HT_AVAIL
) +
410 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
411 delay_val
= (11 * delay_val
) / 10;
414 case BCM4319_CHIP_ID
:
419 /* For USB HT is always available, even durring IEEE PS,
420 * so need minimal delay
423 #else /* BCMUSBDEV */
424 /* For SDIO, total delay in getting HT available */
425 /* Adjusted for uptime XTAL=672us, HTAVail=128us */
426 uint32 ilp
= si_ilp_clock(sih
);
427 delay_val
= si_pmu_res_uptime(sih
, osh
, cc
, RES4319_HT_AVAIL
);
428 PMU_MSG(("si_ilp_clock (Hz): %u delay (ilp clks): %u\n", ilp
, delay_val
));
429 delay_val
= (delay_val
+ D11SCC_SLOW2FAST_TRANSITION
) * (1000000 / ilp
);
430 PMU_MSG(("delay (us): %u\n", delay_val
));
431 delay_val
= (11 * delay_val
) / 10;
432 PMU_MSG(("delay (us): %u\n", delay_val
));
433 /* VDDIO_RF por delay = 3.4ms */
434 if (delay_val
< 3400) delay_val
= 3400;
435 #endif /* BCMUSBDEV */
438 case BCM4336_CHIP_ID
:
442 uint32 ilp
= si_ilp_clock(sih
);
443 delay_val
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4336_HT_AVAIL
) +
444 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
445 delay_val
= (11 * delay_val
) / 10;
448 case BCM4330_CHIP_ID
:
452 uint32 ilp
= si_ilp_clock(sih
);
453 delay_val
= (si_pmu_res_uptime(sih
, osh
, cc
, RES4330_HT_AVAIL
) +
454 D11SCC_SLOW2FAST_TRANSITION
) * ((1000000 + ilp
- 1) / ilp
);
455 delay_val
= (11 * delay_val
) / 10;
462 /* PMU_MSG(("si_pmu_fast_pwrup_delay: chip %s rev %d delay %d\n",
463 * bcm_chipname(sih->chip, chn, 8), sih->chiprev, delay));
466 /* Return to original core */
467 si_setcoreidx(sih
, origidx
);
469 return (uint16
)delay_val
;
471 #endif /* !_CFE_ || CFG_WL */
474 BCMATTACHFN(si_pmu_force_ilp
)(si_t
*sih
, osl_t
*osh
, bool force
)
478 uint32 oldpmucontrol
;
480 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
482 /* Remember original core before switch to chipc */
483 origidx
= si_coreidx(sih
);
484 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
487 oldpmucontrol
= R_REG(osh
, &cc
->pmucontrol
);
489 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
&
490 ~(PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
492 W_REG(osh
, &cc
->pmucontrol
, oldpmucontrol
|
493 (PCTL_HT_REQ_EN
| PCTL_ALP_REQ_EN
));
495 /* Return to original core */
496 si_setcoreidx(sih
, origidx
);
498 return oldpmucontrol
;
501 /* Setup resource up/down timers */
507 /* Change resource dependancies masks */
509 uint32 res_mask
; /* resources (chip specific) */
510 int8 action
; /* action */
511 uint32 depend_mask
; /* changes to the dependancies mask */
512 bool (*filter
)(si_t
*sih
); /* action is taken when filter is NULL or return TRUE */
515 /* Resource dependancies mask change action */
516 #define RES_DEPEND_SET 0 /* Override the dependancies mask */
517 #define RES_DEPEND_ADD 1 /* Add to the dependancies mask */
518 #define RES_DEPEND_REMOVE -1 /* Remove from the dependancies mask */
520 #if !defined(_CFE_) || defined(CFG_WL)
521 static const pmu_res_updown_t
BCMATTACHDATA(bcm4328a0_res_updown
)[] = {
522 { RES4328_EXT_SWITCHER_PWM
, 0x0101 },
523 { RES4328_BB_SWITCHER_PWM
, 0x1f01 },
524 { RES4328_BB_SWITCHER_BURST
, 0x010f },
525 { RES4328_BB_EXT_SWITCHER_BURST
, 0x0101 },
526 { RES4328_ILP_REQUEST
, 0x0202 },
527 { RES4328_RADIO_SWITCHER_PWM
, 0x0f01 },
528 { RES4328_RADIO_SWITCHER_BURST
, 0x0f01 },
529 { RES4328_ROM_SWITCH
, 0x0101 },
530 { RES4328_PA_REF_LDO
, 0x0f01 },
531 { RES4328_RADIO_LDO
, 0x0f01 },
532 { RES4328_AFE_LDO
, 0x0f01 },
533 { RES4328_PLL_LDO
, 0x0f01 },
534 { RES4328_BG_FILTBYP
, 0x0101 },
535 { RES4328_TX_FILTBYP
, 0x0101 },
536 { RES4328_RX_FILTBYP
, 0x0101 },
537 { RES4328_XTAL_PU
, 0x0101 },
538 { RES4328_XTAL_EN
, 0xa001 },
539 { RES4328_BB_PLL_FILTBYP
, 0x0101 },
540 { RES4328_RF_PLL_FILTBYP
, 0x0101 },
541 { RES4328_BB_PLL_PU
, 0x0701 }
544 static const pmu_res_depend_t
BCMATTACHDATA(bcm4328a0_res_depend
)[] = {
545 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
547 PMURES_BIT(RES4328_ILP_REQUEST
),
549 PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) | PMURES_BIT(RES4328_BB_SWITCHER_PWM
),
554 static const pmu_res_updown_t
BCMATTACHDATA(bcm4325a0_res_updown_qt
)[] = {
555 { RES4325_HT_AVAIL
, 0x0300 },
556 { RES4325_BBPLL_PWRSW_PU
, 0x0101 },
557 { RES4325_RFPLL_PWRSW_PU
, 0x0101 },
558 { RES4325_ALP_AVAIL
, 0x0100 },
559 { RES4325_XTAL_PU
, 0x1000 },
560 { RES4325_LNLDO1_PU
, 0x0800 },
561 { RES4325_CLDO_CBUCK_PWM
, 0x0101 },
562 { RES4325_CBUCK_PWM
, 0x0803 }
565 static const pmu_res_updown_t
BCMATTACHDATA(bcm4325a0_res_updown
)[] = {
566 { RES4325_XTAL_PU
, 0x1501 }
569 static const pmu_res_depend_t
BCMATTACHDATA(bcm4325a0_res_depend
)[] = {
570 /* Adjust OTP PU resource dependencies - remove BB BURST */
572 PMURES_BIT(RES4325_OTP_PU
),
574 PMURES_BIT(RES4325_BUCK_BOOST_BURST
),
577 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
579 PMURES_BIT(RES4325_ALP_AVAIL
) | PMURES_BIT(RES4325_HT_AVAIL
),
581 PMURES_BIT(RES4325_BUCK_BOOST_BURST
) | PMURES_BIT(RES4325_BUCK_BOOST_PWM
),
582 si_pmu_res_depfltr_bb
584 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
586 PMURES_BIT(RES4325_HT_AVAIL
),
588 PMURES_BIT(RES4325_RX_PWRSW_PU
) | PMURES_BIT(RES4325_TX_PWRSW_PU
) |
589 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
),
592 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
594 PMURES_BIT(RES4325_ILP_REQUEST
) | PMURES_BIT(RES4325_ABUCK_BURST
) |
595 PMURES_BIT(RES4325_ABUCK_PWM
) | PMURES_BIT(RES4325_LNLDO1_PU
) |
596 PMURES_BIT(RES4325C1_LNLDO2_PU
) | PMURES_BIT(RES4325_XTAL_PU
) |
597 PMURES_BIT(RES4325_ALP_AVAIL
) | PMURES_BIT(RES4325_RX_PWRSW_PU
) |
598 PMURES_BIT(RES4325_TX_PWRSW_PU
) | PMURES_BIT(RES4325_RFPLL_PWRSW_PU
) |
599 PMURES_BIT(RES4325_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4325_AFE_PWRSW_PU
) |
600 PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
),
602 PMURES_BIT(RES4325B0_CBUCK_LPOM
) | PMURES_BIT(RES4325B0_CBUCK_BURST
) |
603 PMURES_BIT(RES4325B0_CBUCK_PWM
),
604 si_pmu_res_depfltr_ncb
608 static const pmu_res_updown_t
BCMATTACHDATA(bcm4315a0_res_updown_qt
)[] = {
609 { RES4315_HT_AVAIL
, 0x0101 },
610 { RES4315_XTAL_PU
, 0x0100 },
611 { RES4315_LNLDO1_PU
, 0x0100 },
612 { RES4315_PALDO_PU
, 0x0100 },
613 { RES4315_CLDO_PU
, 0x0100 },
614 { RES4315_CBUCK_PWM
, 0x0100 },
615 { RES4315_CBUCK_BURST
, 0x0100 },
616 { RES4315_CBUCK_LPOM
, 0x0100 }
619 static const pmu_res_updown_t
BCMATTACHDATA(bcm4315a0_res_updown
)[] = {
620 { RES4315_XTAL_PU
, 0x2501 }
623 static const pmu_res_depend_t
BCMATTACHDATA(bcm4315a0_res_depend
)[] = {
624 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
626 PMURES_BIT(RES4315_OTP_PU
),
628 PMURES_BIT(RES4315_PALDO_PU
),
629 si_pmu_res_depfltr_npaldo
631 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
633 PMURES_BIT(RES4315_ALP_AVAIL
) | PMURES_BIT(RES4315_HT_AVAIL
),
635 PMURES_BIT(RES4315_PALDO_PU
),
636 si_pmu_res_depfltr_paldo
638 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
640 PMURES_BIT(RES4315_HT_AVAIL
),
642 PMURES_BIT(RES4315_RX_PWRSW_PU
) | PMURES_BIT(RES4315_TX_PWRSW_PU
) |
643 PMURES_BIT(RES4315_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4315_AFE_PWRSW_PU
),
646 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
648 PMURES_BIT(RES4315_CLDO_PU
) | PMURES_BIT(RES4315_ILP_REQUEST
) |
649 PMURES_BIT(RES4315_LNLDO1_PU
) | PMURES_BIT(RES4315_OTP_PU
) |
650 PMURES_BIT(RES4315_LNLDO2_PU
) | PMURES_BIT(RES4315_XTAL_PU
) |
651 PMURES_BIT(RES4315_ALP_AVAIL
) | PMURES_BIT(RES4315_RX_PWRSW_PU
) |
652 PMURES_BIT(RES4315_TX_PWRSW_PU
) | PMURES_BIT(RES4315_RFPLL_PWRSW_PU
) |
653 PMURES_BIT(RES4315_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4315_AFE_PWRSW_PU
) |
654 PMURES_BIT(RES4315_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4315_HT_AVAIL
),
656 PMURES_BIT(RES4315_CBUCK_LPOM
) | PMURES_BIT(RES4315_CBUCK_BURST
) |
657 PMURES_BIT(RES4315_CBUCK_PWM
),
658 si_pmu_res_depfltr_ncb
662 static const pmu_res_updown_t
BCMATTACHDATA(bcm4329_res_updown
)[] = {
663 { RES4329_XTAL_PU
, 0x1501 },
664 { RES4329_PALDO_PU
, 0x3501 }
667 static const pmu_res_depend_t
BCMATTACHDATA(bcm4329_res_depend
)[] = {
668 /* Make lnldo1 independant of CBUCK_PWM and CBUCK_BURST */
670 PMURES_BIT(RES4329_LNLDO1_PU
),
672 PMURES_BIT(RES4329_CBUCK_PWM
) | PMURES_BIT(RES4329_CBUCK_BURST
),
676 PMURES_BIT(RES4329_CBUCK_BURST
),
678 PMURES_BIT(RES4329_CBUCK_LPOM
) | PMURES_BIT(RES4329_PALDO_PU
),
682 PMURES_BIT(RES4329_BBPLL_PWRSW_PU
),
684 PMURES_BIT(RES4329_RX_PWRSW_PU
) | PMURES_BIT(RES4329_TX_PWRSW_PU
) |
685 PMURES_BIT(RES4329_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4329_AFE_PWRSW_PU
),
688 /* Adjust HT Avail resource dependencies */
690 PMURES_BIT(RES4329_HT_AVAIL
),
692 PMURES_BIT(RES4329_PALDO_PU
) |
693 PMURES_BIT(RES4329_RX_PWRSW_PU
) | PMURES_BIT(RES4329_TX_PWRSW_PU
) |
694 PMURES_BIT(RES4329_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4329_AFE_PWRSW_PU
),
699 static const pmu_res_updown_t
BCMATTACHDATA(bcm4319a0_res_updown_qt
)[] = {
700 { RES4319_HT_AVAIL
, 0x0101 },
701 { RES4319_XTAL_PU
, 0x0100 },
702 { RES4319_LNLDO1_PU
, 0x0100 },
703 { RES4319_PALDO_PU
, 0x0100 },
704 { RES4319_CLDO_PU
, 0x0100 },
705 { RES4319_CBUCK_PWM
, 0x0100 },
706 { RES4319_CBUCK_BURST
, 0x0100 },
707 { RES4319_CBUCK_LPOM
, 0x0100 }
710 static const pmu_res_updown_t
BCMATTACHDATA(bcm4319a0_res_updown
)[] = {
711 { RES4319_XTAL_PU
, 0x3f01 }
714 static const pmu_res_depend_t
BCMATTACHDATA(bcm4319a0_res_depend
)[] = {
715 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
717 PMURES_BIT(RES4319_OTP_PU
),
719 PMURES_BIT(RES4319_PALDO_PU
),
720 si_pmu_res_depfltr_npaldo
722 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
724 PMURES_BIT(RES4319_HT_AVAIL
),
726 PMURES_BIT(RES4319_PALDO_PU
),
727 si_pmu_res_depfltr_paldo
729 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
731 PMURES_BIT(RES4319_HT_AVAIL
),
733 PMURES_BIT(RES4319_RX_PWRSW_PU
) | PMURES_BIT(RES4319_TX_PWRSW_PU
) |
734 PMURES_BIT(RES4319_RFPLL_PWRSW_PU
) |
735 PMURES_BIT(RES4319_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4319_AFE_PWRSW_PU
),
740 static const pmu_res_updown_t
BCMATTACHDATA(bcm4336a0_res_updown_qt
)[] = {
741 { RES4336_HT_AVAIL
, 0x0101 },
742 { RES4336_XTAL_PU
, 0x0100 },
743 { RES4336_CLDO_PU
, 0x0100 },
744 { RES4336_CBUCK_PWM
, 0x0100 },
745 { RES4336_CBUCK_BURST
, 0x0100 },
746 { RES4336_CBUCK_LPOM
, 0x0100 }
749 static const pmu_res_updown_t
BCMATTACHDATA(bcm4336a0_res_updown
)[] = {
750 { RES4336_HT_AVAIL
, 0x0D01}
753 static const pmu_res_depend_t
BCMATTACHDATA(bcm4336a0_res_depend
)[] = {
754 /* Just a dummy entry for now */
756 PMURES_BIT(RES4336_RSVD
),
763 static const pmu_res_updown_t
BCMATTACHDATA(bcm4330a0_res_updown_qt
)[] = {
764 { RES4330_HT_AVAIL
, 0x0101 },
765 { RES4330_XTAL_PU
, 0x0100 },
766 { RES4330_CLDO_PU
, 0x0100 },
767 { RES4330_CBUCK_PWM
, 0x0100 },
768 { RES4330_CBUCK_BURST
, 0x0100 },
769 { RES4330_CBUCK_LPOM
, 0x0100 }
772 static const pmu_res_updown_t
BCMATTACHDATA(bcm4330a0_res_updown
)[] = {
773 { RES4330_HT_AVAIL
, 0x0e02}
776 static const pmu_res_depend_t
BCMATTACHDATA(bcm4330a0_res_depend
)[] = {
777 /* Just a dummy entry for now */
779 PMURES_BIT(RES4330_HT_AVAIL
),
786 /* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
788 BCMATTACHFN(si_pmu_res_depfltr_bb
)(si_t
*sih
)
790 return (sih
->boardflags
& BFL_BUCKBOOST
) != 0;
793 /* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
795 BCMATTACHFN(si_pmu_res_depfltr_ncb
)(si_t
*sih
)
797 if (CHIPID(sih
->chip
) == BCM4325_CHIP_ID
)
798 return (CHIPREV(sih
->chiprev
) >= 2) && ((sih
->boardflags
& BFL_NOCBUCK
) != 0);
799 return ((sih
->boardflags
& BFL_NOCBUCK
) != 0);
802 /* TRUE if the power topology uses the PALDO */
804 BCMATTACHFN(si_pmu_res_depfltr_paldo
)(si_t
*sih
)
806 return (sih
->boardflags
& BFL_PALDO
) != 0;
809 /* TRUE if the power topology doesn't use the PALDO */
811 BCMATTACHFN(si_pmu_res_depfltr_npaldo
)(si_t
*sih
)
813 return (sih
->boardflags
& BFL_PALDO
) == 0;
816 #define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
817 sih->boardtype == BCM94325BGABU_BOARD)
819 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
821 si_pmu_res_masks(si_t
*sih
, uint32
*pmin
, uint32
*pmax
)
823 uint32 min_mask
= 0, max_mask
= 0;
828 rsrcs
= (sih
->pmucaps
& PCAP_RC_MASK
) >> PCAP_RC_SHIFT
;
830 /* determine min/max rsrc masks */
831 switch (CHIPID(sih
->chip
)) {
832 case BCM4328_CHIP_ID
:
833 /* Down to ILP request */
834 min_mask
= PMURES_BIT(RES4328_EXT_SWITCHER_PWM
) |
835 PMURES_BIT(RES4328_BB_SWITCHER_PWM
) |
836 PMURES_BIT(RES4328_XTAL_EN
);
837 /* Allow (but don't require) PLL to turn on */
840 case BCM5354_CHIP_ID
:
841 /* Allow (but don't require) PLL to turn on */
844 case BCM4325_CHIP_ID
:
845 ASSERT(CHIPREV(sih
->chiprev
) >= 2);
846 /* Minimum rsrcs to work in sleep mode */
847 if (!(sih
->boardflags
& BFL_NOCBUCK
))
848 min_mask
|= PMURES_BIT(RES4325B0_CBUCK_LPOM
);
849 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >>
850 CST4325_PMUTOP_2B_SHIFT
) == 1)
851 min_mask
|= PMURES_BIT(RES4325B0_CLDO_PU
);
852 if (!si_is_otp_disabled(sih
))
853 min_mask
|= PMURES_BIT(RES4325_OTP_PU
);
854 /* Leave buck boost on in burst mode for certain boards */
855 if ((sih
->boardflags
& BFL_BUCKBOOST
) && (BCM94325_BBVDDIOSD_BOARDS(sih
)))
856 min_mask
|= PMURES_BIT(RES4325_BUCK_BOOST_BURST
);
857 /* Allow all resources to be turned on upon requests */
858 max_mask
= ~(~0 << rsrcs
);
860 case BCM4312_CHIP_ID
:
861 /* default min_mask = 0x80000cbb is wrong */
865 * pmu_res_updown_table_sz = 0;
866 * pmu_res_depend_table_sz = 0;
869 case BCM4322_CHIP_ID
:
870 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
871 case BCM4342_CHIP_ID
:
872 if (CHIPREV(sih
->chiprev
) < 2) {
873 /* request ALP(can skip for A1) */
874 min_mask
= PMURES_BIT(RES4322_RF_LDO
) |
875 PMURES_BIT(RES4322_XTAL_PU
) |
876 PMURES_BIT(RES4322_ALP_AVAIL
);
877 if (BUSTYPE(sih
->bustype
) == SI_BUS
) {
878 min_mask
+= PMURES_BIT(RES4322_SI_PLL_ON
) |
879 PMURES_BIT(RES4322_HT_SI_AVAIL
) |
880 PMURES_BIT(RES4322_PHY_PLL_ON
) |
881 PMURES_BIT(RES4322_OTP_PU
) |
882 PMURES_BIT(RES4322_HT_PHY_AVAIL
);
887 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
888 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
889 case BCM43226_CHIP_ID
: case BCM43420_CHIP_ID
:
890 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
891 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
892 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
893 case BCM6362_CHIP_ID
:
894 /* use chip default */
897 case BCM4329_CHIP_ID
:
899 /* Down to save the power. */
900 if (CHIPREV(sih
->chiprev
) >= 0x2) {
901 min_mask
= PMURES_BIT(RES4329_CBUCK_LPOM
) |
902 PMURES_BIT(RES4329_LNLDO1_PU
) | PMURES_BIT(RES4329_CLDO_PU
);
904 min_mask
= PMURES_BIT(RES4329_CBUCK_LPOM
) | PMURES_BIT(RES4329_CLDO_PU
);
906 if (!si_is_otp_disabled(sih
))
907 min_mask
|= PMURES_BIT(RES4329_OTP_PU
);
908 /* Allow (but don't require) PLL to turn on */
912 case BCM4315_CHIP_ID
:
913 /* We only need a few resources to be kept on all the time */
914 if (!(sih
->boardflags
& BFL_NOCBUCK
))
915 min_mask
= PMURES_BIT(RES4315_CBUCK_LPOM
);
916 min_mask
|= PMURES_BIT(RES4315_CLDO_PU
);
917 /* Allow everything else to be turned on upon requests */
918 max_mask
= ~(~0 << rsrcs
);
920 case BCM4319_CHIP_ID
:
921 #ifdef BCM_BOOTLOADER
922 /* Initialize to ResInitMode3 for bootloader */
923 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
924 PMURES_BIT(RES4319_CBUCK_BURST
) |
925 PMURES_BIT(RES4319_CBUCK_PWM
) |
926 PMURES_BIT(RES4319_CLDO_PU
) |
927 PMURES_BIT(RES4319_PALDO_PU
) |
928 PMURES_BIT(RES4319_LNLDO1_PU
) |
929 PMURES_BIT(RES4319_XTAL_PU
) |
930 PMURES_BIT(RES4319_ALP_AVAIL
) |
931 PMURES_BIT(RES4319_RFPLL_PWRSW_PU
) |
932 PMURES_BIT(RES4319_BBPLL_PWRSW_PU
) |
933 PMURES_BIT(RES4319_HT_AVAIL
);
935 /* We only need a few resources to be kept on all the time */
937 /* For USB HT is always available, even durring IEEE PS, so RF switches are
938 * made independent of HT Avail and are by default on, but can be made off
939 * during IEEE PS by ucode (and then on)
941 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
942 PMURES_BIT(RES4319_CLDO_PU
) |
943 PMURES_BIT(RES4319_RX_PWRSW_PU
) | PMURES_BIT(RES4319_TX_PWRSW_PU
) |
944 PMURES_BIT(RES4319_LOGEN_PWRSW_PU
) | PMURES_BIT(RES4319_AFE_PWRSW_PU
);
946 /* For SDIO RF switches are automatically made on off along with HT */
947 min_mask
= PMURES_BIT(RES4319_CBUCK_LPOM
) |
948 PMURES_BIT(RES4319_CLDO_PU
);
950 #endif /* BCM_BOOTLOADER */
952 /* Allow everything else to be turned on upon requests */
953 max_mask
= ~(~0 << rsrcs
);
955 case BCM4336_CHIP_ID
:
956 /* Down to save the power. */
957 min_mask
= PMURES_BIT(RES4336_CBUCK_LPOM
) | PMURES_BIT(RES4336_CLDO_PU
) |
958 PMURES_BIT(RES4336_LDO3P3_PU
) | PMURES_BIT(RES4336_OTP_PU
) |
959 PMURES_BIT(RES4336_DIS_INT_RESET_PD
);
960 /* Allow (but don't require) PLL to turn on */
961 max_mask
= 0x1ffffff;
964 case BCM4330_CHIP_ID
:
965 /* Down to save the power. */
966 min_mask
= PMURES_BIT(RES4330_CBUCK_LPOM
) | PMURES_BIT(RES4330_CLDO_PU
) |
967 PMURES_BIT(RES4330_DIS_INT_RESET_PD
) | PMURES_BIT(RES4330_LDO3P3_PU
) |
968 PMURES_BIT(RES4330_OTP_PU
);
969 /* Allow (but don't require) PLL to turn on */
970 max_mask
= 0xfffffff;
973 case BCM4313_CHIP_ID
:
974 min_mask
= PMURES_BIT(RES4313_BB_PU_RSRC
) |
975 PMURES_BIT(RES4313_XTAL_PU_RSRC
) |
976 PMURES_BIT(RES4313_ALP_AVAIL_RSRC
) |
977 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC
);
984 /* Apply nvram override to min mask */
985 if ((val
= getvar(NULL
, "rmin")) != NULL
) {
986 PMU_MSG(("Applying rmin=%s to min_mask\n", val
));
987 min_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
989 /* Apply nvram override to max mask */
990 if ((val
= getvar(NULL
, "rmax")) != NULL
) {
991 PMU_MSG(("Applying rmax=%s to max_mask\n", val
));
992 max_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
998 #endif /* !_CFE_ || CFG_WL */
1000 /* initialize PMU resources */
1002 BCMATTACHFN(si_pmu_res_init
)(si_t
*sih
, osl_t
*osh
)
1004 #if !defined(_CFE_) || defined(CFG_WL)
1007 const pmu_res_updown_t
*pmu_res_updown_table
= NULL
;
1008 uint pmu_res_updown_table_sz
= 0;
1009 const pmu_res_depend_t
*pmu_res_depend_table
= NULL
;
1010 uint pmu_res_depend_table_sz
= 0;
1011 uint32 min_mask
= 0, max_mask
= 0;
1015 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1017 /* Remember original core before switch to chipc */
1018 origidx
= si_coreidx(sih
);
1019 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1022 switch (CHIPID(sih
->chip
)) {
1023 case BCM4328_CHIP_ID
:
1024 pmu_res_updown_table
= bcm4328a0_res_updown
;
1025 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4328a0_res_updown
);
1026 pmu_res_depend_table
= bcm4328a0_res_depend
;
1027 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4328a0_res_depend
);
1029 case BCM4325_CHIP_ID
:
1030 /* Optimize resources up/down timers */
1031 if (ISSIM_ENAB(sih
)) {
1032 pmu_res_updown_table
= bcm4325a0_res_updown_qt
;
1033 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown_qt
);
1035 pmu_res_updown_table
= bcm4325a0_res_updown
;
1036 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4325a0_res_updown
);
1038 /* Optimize resources dependancies */
1039 pmu_res_depend_table
= bcm4325a0_res_depend
;
1040 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4325a0_res_depend
);
1042 case BCM4315_CHIP_ID
:
1043 /* Optimize resources up/down timers */
1044 if (ISSIM_ENAB(sih
)) {
1045 pmu_res_updown_table
= bcm4315a0_res_updown_qt
;
1046 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4315a0_res_updown_qt
);
1049 pmu_res_updown_table
= bcm4315a0_res_updown
;
1050 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4315a0_res_updown
);
1052 /* Optimize resources dependancies masks */
1053 pmu_res_depend_table
= bcm4315a0_res_depend
;
1054 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4315a0_res_depend
);
1056 case BCM4329_CHIP_ID
:
1057 /* Optimize resources up/down timers */
1058 if (ISSIM_ENAB(sih
)) {
1059 pmu_res_updown_table
= NULL
;
1060 pmu_res_updown_table_sz
= 0;
1062 pmu_res_updown_table
= bcm4329_res_updown
;
1063 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4329_res_updown
);
1065 /* Optimize resources dependencies */
1066 pmu_res_depend_table
= bcm4329_res_depend
;
1067 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4329_res_depend
);
1070 case BCM4319_CHIP_ID
:
1071 /* Optimize resources up/down timers */
1072 if (ISSIM_ENAB(sih
)) {
1073 pmu_res_updown_table
= bcm4319a0_res_updown_qt
;
1074 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4319a0_res_updown_qt
);
1077 pmu_res_updown_table
= bcm4319a0_res_updown
;
1078 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4319a0_res_updown
);
1080 /* Optimize resources dependancies masks */
1081 pmu_res_depend_table
= bcm4319a0_res_depend
;
1082 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4319a0_res_depend
);
1085 case BCM4336_CHIP_ID
:
1086 /* Optimize resources up/down timers */
1087 if (ISSIM_ENAB(sih
)) {
1088 pmu_res_updown_table
= bcm4336a0_res_updown_qt
;
1089 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4336a0_res_updown_qt
);
1092 pmu_res_updown_table
= bcm4336a0_res_updown
;
1093 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4336a0_res_updown
);
1095 /* Optimize resources dependancies masks */
1096 pmu_res_depend_table
= bcm4336a0_res_depend
;
1097 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4336a0_res_depend
);
1100 case BCM4330_CHIP_ID
:
1101 /* Optimize resources up/down timers */
1102 if (ISSIM_ENAB(sih
)) {
1103 pmu_res_updown_table
= bcm4330a0_res_updown_qt
;
1104 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4330a0_res_updown_qt
);
1107 pmu_res_updown_table
= bcm4330a0_res_updown
;
1108 pmu_res_updown_table_sz
= ARRAYSIZE(bcm4330a0_res_updown
);
1110 /* Optimize resources dependancies masks */
1111 pmu_res_depend_table
= bcm4330a0_res_depend
;
1112 pmu_res_depend_table_sz
= ARRAYSIZE(bcm4330a0_res_depend
);
1119 rsrcs
= (sih
->pmucaps
& PCAP_RC_MASK
) >> PCAP_RC_SHIFT
;
1121 /* Program up/down timers */
1122 while (pmu_res_updown_table_sz
--) {
1123 ASSERT(pmu_res_updown_table
!= NULL
);
1124 PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
1125 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
,
1126 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
));
1127 W_REG(osh
, &cc
->res_table_sel
,
1128 pmu_res_updown_table
[pmu_res_updown_table_sz
].resnum
);
1129 W_REG(osh
, &cc
->res_updn_timer
,
1130 pmu_res_updown_table
[pmu_res_updown_table_sz
].updown
);
1132 /* Apply nvram overrides to up/down timers */
1133 for (i
= 0; i
< rsrcs
; i
++) {
1134 snprintf(name
, sizeof(name
), "r%dt", i
);
1135 if ((val
= getvar(NULL
, name
)) == NULL
)
1137 PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name
, val
, i
));
1138 W_REG(osh
, &cc
->res_table_sel
, (uint32
)i
);
1139 W_REG(osh
, &cc
->res_updn_timer
, (uint32
)bcm_strtoul(val
, NULL
, 0));
1142 /* Program resource dependencies table */
1143 while (pmu_res_depend_table_sz
--) {
1144 ASSERT(pmu_res_depend_table
!= NULL
);
1145 if (pmu_res_depend_table
[pmu_res_depend_table_sz
].filter
!= NULL
&&
1146 !(pmu_res_depend_table
[pmu_res_depend_table_sz
].filter
)(sih
))
1148 for (i
= 0; i
< rsrcs
; i
++) {
1149 if ((pmu_res_depend_table
[pmu_res_depend_table_sz
].res_mask
&
1150 PMURES_BIT(i
)) == 0)
1152 W_REG(osh
, &cc
->res_table_sel
, i
);
1153 switch (pmu_res_depend_table
[pmu_res_depend_table_sz
].action
) {
1154 case RES_DEPEND_SET
:
1155 PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i
,
1156 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
));
1157 W_REG(osh
, &cc
->res_dep_mask
,
1158 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
1160 case RES_DEPEND_ADD
:
1161 PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n",
1162 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
, i
));
1163 OR_REG(osh
, &cc
->res_dep_mask
,
1164 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
1166 case RES_DEPEND_REMOVE
:
1167 PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n",
1168 pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
, i
));
1169 AND_REG(osh
, &cc
->res_dep_mask
,
1170 ~pmu_res_depend_table
[pmu_res_depend_table_sz
].depend_mask
);
1178 /* Apply nvram overrides to dependancies masks */
1179 for (i
= 0; i
< rsrcs
; i
++) {
1180 snprintf(name
, sizeof(name
), "r%dd", i
);
1181 if ((val
= getvar(NULL
, name
)) == NULL
)
1183 PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name
, val
, i
));
1184 W_REG(osh
, &cc
->res_table_sel
, (uint32
)i
);
1185 W_REG(osh
, &cc
->res_dep_mask
, (uint32
)bcm_strtoul(val
, NULL
, 0));
1188 /* Determine min/max rsrc masks */
1189 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
1191 /* It is required to program max_mask first and then min_mask */
1192 #ifdef BCM_BOOTLOADER
1193 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
1194 min_mask
|= R_REG(osh
, &cc
->min_res_mask
);
1195 max_mask
|= R_REG(osh
, &cc
->max_res_mask
);
1197 #endif /* BCM_BOOTLOADER */
1199 /* Program max resource mask */
1200 #ifdef BCM_BOOTLOADER
1201 /* Apply nvram override to max mask */
1202 if ((val
= getvar(NULL
, "brmax")) != NULL
) {
1203 PMU_MSG(("Applying brmax=%s to max_res_mask\n", val
));
1204 max_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
1206 #endif /* BCM_BOOTLOADER */
1209 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask
));
1210 W_REG(osh
, &cc
->max_res_mask
, max_mask
);
1213 /* Program min resource mask */
1214 #ifdef BCM_BOOTLOADER
1215 /* Apply nvram override to min mask */
1216 if ((val
= getvar(NULL
, "brmin")) != NULL
) {
1217 PMU_MSG(("Applying brmin=%s to min_res_mask\n", val
));
1218 min_mask
= (uint32
)bcm_strtoul(val
, NULL
, 0);
1220 #endif /* BCM_BOOTLOADER */
1223 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask
));
1224 W_REG(osh
, &cc
->min_res_mask
, min_mask
);
1227 /* Add some delay; allow resources to come up and settle. */
1230 /* Return to original core */
1231 si_setcoreidx(sih
, origidx
);
1233 #endif /* !_CFE_ || CFG_WL */
1235 /* WAR for 4319 swctrl tri-state issue */
1237 si_pmu_res_4319_swctrl_war(si_t
*sih
, osl_t
*osh
, bool enable
)
1242 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
1244 /* Remember original core before switch to chipc */
1245 origidx
= si_coreidx(sih
);
1246 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1248 min_mask
= R_REG(osh
, &cc
->min_res_mask
);
1250 W_REG(osh
, &cc
->min_res_mask
,
1251 min_mask
| PMURES_BIT(RES4319_PALDO_PU
));
1253 W_REG(osh
, &cc
->min_res_mask
,
1254 min_mask
& ~PMURES_BIT(RES4319_PALDO_PU
));
1256 /* Return to original core */
1257 si_setcoreidx(sih
, origidx
);
1260 /* setup pll and query clock speed */
1268 /* the following table is based on 880Mhz fvco */
1269 static const pmu0_xtaltab0_t
BCMINITDATA(pmu0_xtaltab0
)[] = {
1270 { 12000, 1, 73, 349525 },
1271 { 13000, 2, 67, 725937 },
1272 { 14400, 3, 61, 116508 },
1273 { 15360, 4, 57, 305834 },
1274 { 16200, 5, 54, 336579 },
1275 { 16800, 6, 52, 399457 },
1276 { 19200, 7, 45, 873813 },
1277 { 19800, 8, 44, 466033 },
1278 { 20000, 9, 44, 0 },
1279 { 25000, 10, 70, 419430 },
1280 { 26000, 11, 67, 725937 },
1281 { 30000, 12, 58, 699050 },
1282 { 38400, 13, 45, 873813 },
1283 { 40000, 14, 45, 0 },
1288 #define PMU0_XTAL0_DEFAULT 11
1290 #define PMU0_XTAL0_DEFAULT 8
1295 * Set new backplane PLL clock frequency
1298 BCMATTACHFN(si_pmu0_sbclk4328
)(si_t
*sih
, int freq
)
1300 uint32 tmp
, oldmax
, oldmin
, origidx
;
1303 /* Remember original core before switch to chipc */
1304 origidx
= si_coreidx(sih
);
1305 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1308 /* Set new backplane PLL clock */
1309 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
1310 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1311 tmp
&= ~(PMU0_PLL0_PC0_DIV_ARM_MASK
);
1312 tmp
|= freq
<< PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
1313 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1315 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
1317 oldmin
= R_REG(osh
, &cc
->min_res_mask
);
1318 oldmax
= R_REG(osh
, &cc
->max_res_mask
);
1319 W_REG(osh
, &cc
->min_res_mask
, oldmin
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
1320 W_REG(osh
, &cc
->max_res_mask
, oldmax
& ~PMURES_BIT(RES4328_BB_PLL_PU
));
1322 /* It takes over several hundred usec to re-enable the PLL since the
1323 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
1325 * Be sure PLL is powered down first before re-enabling it.
1328 OSL_DELAY(PLL_DELAY
);
1329 SPINWAIT((R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)), PLL_DELAY
*3);
1330 if (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)) {
1331 /* If BB_PLL not powered down yet, new backplane PLL clock
1332 * may not take effect.
1334 * Still early during bootup so no serial output here.
1336 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n"));
1337 ASSERT(!(R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4328_BB_PLL_PU
)));
1341 W_REG(osh
, &cc
->max_res_mask
, oldmax
);
1343 /* Return to original core */
1344 si_setcoreidx(sih
, origidx
);
1346 #endif /* BCMUSBDEV */
1348 /* Set up PLL registers in the PMU as per the crystal speed.
1349 * Uses xtalfreq variable, or passed-in default.
1352 BCMATTACHFN(si_pmu0_pllinit0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
1355 const pmu0_xtaltab0_t
*xt
;
1357 /* Find the frequency in the table */
1358 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
1359 if (xt
->freq
== xtal
)
1362 xt
= &pmu0_xtaltab0
[PMU0_XTAL0_DEFAULT
];
1364 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal
/ 1000, xtal
% 1000, xt
->xf
));
1366 /* Check current PLL state */
1367 tmp
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1368 PCTL_XTALFREQ_SHIFT
;
1369 if (tmp
== xt
->xf
) {
1370 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
1371 xt
->freq
/ 1000, xt
->freq
% 1000));
1373 if (CHIPID(sih
->chip
) == BCM4328_CHIP_ID
)
1374 si_pmu0_sbclk4328(sih
, PMU0_PLL0_PC0_DIV_ARM_88MHZ
);
1375 #endif /* BCMUSBDEV */
1380 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
1381 xt
->freq
/ 1000, xt
->freq
% 1000,
1382 pmu0_xtaltab0
[tmp
-1].freq
/ 1000, pmu0_xtaltab0
[tmp
-1].freq
% 1000));
1384 PMU_MSG(("Programming PLL for %d.%d MHz\n",
1385 xt
->freq
/ 1000, xt
->freq
% 1000));
1388 /* Make sure the PLL is off */
1389 switch (CHIPID(sih
->chip
)) {
1390 case BCM4328_CHIP_ID
:
1391 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
1392 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES4328_BB_PLL_PU
));
1394 case BCM5354_CHIP_ID
:
1395 AND_REG(osh
, &cc
->min_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
1396 AND_REG(osh
, &cc
->max_res_mask
, ~PMURES_BIT(RES5354_BB_PLL_PU
));
1401 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1402 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS0_HTAVAIL
));
1404 PMU_MSG(("Done masking\n"));
1406 /* Write PDIV in pllcontrol[0] */
1407 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
1408 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1409 if (xt
->freq
>= PMU0_PLL0_PC0_PDIV_FREQ
)
1410 tmp
|= PMU0_PLL0_PC0_PDIV_MASK
;
1412 tmp
&= ~PMU0_PLL0_PC0_PDIV_MASK
;
1413 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1415 /* Write WILD in pllcontrol[1] */
1416 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL1
);
1417 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1418 tmp
= ((tmp
& ~(PMU0_PLL0_PC1_WILD_INT_MASK
| PMU0_PLL0_PC1_WILD_FRAC_MASK
)) |
1419 (((xt
->wbint
<< PMU0_PLL0_PC1_WILD_INT_SHIFT
) &
1420 PMU0_PLL0_PC1_WILD_INT_MASK
) |
1421 ((xt
->wbfrac
<< PMU0_PLL0_PC1_WILD_FRAC_SHIFT
) &
1422 PMU0_PLL0_PC1_WILD_FRAC_MASK
)));
1423 if (xt
->wbfrac
== 0)
1424 tmp
|= PMU0_PLL0_PC1_STOP_MOD
;
1426 tmp
&= ~PMU0_PLL0_PC1_STOP_MOD
;
1427 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1429 /* Write WILD in pllcontrol[2] */
1430 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL2
);
1431 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1432 tmp
= ((tmp
& ~PMU0_PLL0_PC2_WILD_INT_MASK
) |
1433 ((xt
->wbint
>> PMU0_PLL0_PC2_WILD_INT_SHIFT
) &
1434 PMU0_PLL0_PC2_WILD_INT_MASK
));
1435 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1437 PMU_MSG(("Done pll\n"));
1439 /* Write XtalFreq. Set the divisor also. */
1440 tmp
= R_REG(osh
, &cc
->pmucontrol
);
1441 tmp
= ((tmp
& ~PCTL_ILP_DIV_MASK
) |
1442 (((((xt
->freq
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) & PCTL_ILP_DIV_MASK
));
1443 tmp
= ((tmp
& ~PCTL_XTALFREQ_MASK
) |
1444 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
));
1445 W_REG(osh
, &cc
->pmucontrol
, tmp
);
1448 /* query alp/xtal clock frequency */
1450 BCMINITFN(si_pmu0_alpclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1452 const pmu0_xtaltab0_t
*xt
;
1455 /* Find the frequency in the table */
1456 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1457 PCTL_XTALFREQ_SHIFT
;
1458 for (xt
= pmu0_xtaltab0
; xt
->freq
; xt
++)
1461 /* PLL must be configured before */
1464 return xt
->freq
* 1000;
1467 #if !defined(_CFE_) || defined(CFG_WL)
1468 /* query CPU clock frequency */
1470 BCMINITFN(si_pmu0_cpuclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1474 uint32 pdiv
, wbint
, wbfrac
, fvco
;
1477 uint32 FVCO
= FVCO_880
;
1479 /* Read divarm from pllcontrol[0] */
1480 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL0
);
1481 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1482 divarm
= (tmp
& PMU0_PLL0_PC0_DIV_ARM_MASK
) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT
;
1485 /* Calculate fvco based on xtal freq, pdiv, and wild */
1486 pdiv
= tmp
& PMU0_PLL0_PC0_PDIV_MASK
;
1488 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL1
);
1489 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1490 wbfrac
= (tmp
& PMU0_PLL0_PC1_WILD_FRAC_MASK
) >> PMU0_PLL0_PC1_WILD_FRAC_SHIFT
;
1491 wbint
= (tmp
& PMU0_PLL0_PC1_WILD_INT_MASK
) >> PMU0_PLL0_PC1_WILD_INT_SHIFT
;
1493 W_REG(osh
, &cc
->pllcontrol_addr
, PMU0_PLL0_PLLCTL2
);
1494 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
1495 wbint
+= (tmp
& PMU0_PLL0_PC2_WILD_INT_MASK
) << PMU0_PLL0_PC2_WILD_INT_SHIFT
;
1497 freq
= si_pmu0_alpclk0(sih
, osh
, cc
) / 1000;
1499 fvco
= (freq
* wbint
) << 8;
1500 fvco
+= (freq
* (wbfrac
>> 10)) >> 2;
1501 fvco
+= (freq
* (wbfrac
& 0x3ff)) >> 10;
1507 PMU_MSG(("si_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
1508 wbint
, wbfrac
, fvco
));
1513 /* Return ARM/SB clock */
1514 return FVCO
/ (divarm
+ PMU0_PLL0_PC0_DIV_ARM_BASE
) * 1000;
1518 si_pll_minresmask_reset(si_t
*sih
, osl_t
*osh
)
1523 /* Remember original core before switch to chipc */
1524 origidx
= si_coreidx(sih
);
1525 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1528 switch (CHIPID(sih
->chip
)) {
1529 case BCM4313_CHIP_ID
:
1530 /* write to min_res_mask 0x200d : clear min_rsrc_mask */
1531 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1533 /* write to max_res_mask 0xBFFF: clear max_rsrc_mask */
1534 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1536 /* write to max_res_mask 0xFFFF :set max_rsrc_mask */
1537 OR_REG(osh
, &cc
->max_res_mask
, (PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1541 PMU_ERROR(("%s: PLL reset not supported\n", __FUNCTION__
));
1542 err
= BCME_UNSUPPORTED
;
1545 /* Return to original core */
1546 si_setcoreidx(sih
, origidx
);
1550 /* setup pll and query clock speed */
1560 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_880_4329
)[] = {
1561 {12000, 1, 3, 22, 0x9, 0xFFFFEF},
1562 {13000, 2, 1, 6, 0xb, 0x483483},
1563 {14400, 3, 1, 10, 0xa, 0x1C71C7},
1564 {15360, 4, 1, 5, 0xb, 0x755555},
1565 {16200, 5, 1, 10, 0x5, 0x6E9E06},
1566 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
1567 {19200, 7, 1, 4, 0xb, 0x755555},
1568 {19800, 8, 1, 11, 0x4, 0xA57EB},
1569 {20000, 9, 1, 11, 0x4, 0x0},
1570 {24000, 10, 3, 11, 0xa, 0x0},
1571 {25000, 11, 5, 16, 0xb, 0x0},
1572 {26000, 12, 1, 1, 0x21, 0xD89D89},
1573 {30000, 13, 3, 8, 0xb, 0x0},
1574 {37400, 14, 3, 1, 0x46, 0x969696},
1575 {38400, 15, 1, 1, 0x16, 0xEAAAAA},
1576 {40000, 16, 1, 2, 0xb, 0},
1580 /* the following table is based on 880Mhz fvco */
1581 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_880
)[] = {
1582 {12000, 1, 3, 22, 0x9, 0xFFFFEF},
1583 {13000, 2, 1, 6, 0xb, 0x483483},
1584 {14400, 3, 1, 10, 0xa, 0x1C71C7},
1585 {15360, 4, 1, 5, 0xb, 0x755555},
1586 {16200, 5, 1, 10, 0x5, 0x6E9E06},
1587 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
1588 {19200, 7, 1, 4, 0xb, 0x755555},
1589 {19800, 8, 1, 11, 0x4, 0xA57EB},
1590 {20000, 9, 1, 11, 0x4, 0x0},
1591 {24000, 10, 3, 11, 0xa, 0x0},
1592 {25000, 11, 5, 16, 0xb, 0x0},
1593 {26000, 12, 1, 2, 0x10, 0xEC4EC4},
1594 {30000, 13, 3, 8, 0xb, 0x0},
1595 {33600, 14, 1, 2, 0xd, 0x186186},
1596 {38400, 15, 1, 2, 0xb, 0x755555},
1597 {40000, 16, 1, 2, 0xb, 0},
1601 #define PMU1_XTALTAB0_880_12000K 0
1602 #define PMU1_XTALTAB0_880_13000K 1
1603 #define PMU1_XTALTAB0_880_14400K 2
1604 #define PMU1_XTALTAB0_880_15360K 3
1605 #define PMU1_XTALTAB0_880_16200K 4
1606 #define PMU1_XTALTAB0_880_16800K 5
1607 #define PMU1_XTALTAB0_880_19200K 6
1608 #define PMU1_XTALTAB0_880_19800K 7
1609 #define PMU1_XTALTAB0_880_20000K 8
1610 #define PMU1_XTALTAB0_880_24000K 9
1611 #define PMU1_XTALTAB0_880_25000K 10
1612 #define PMU1_XTALTAB0_880_26000K 11
1613 #define PMU1_XTALTAB0_880_30000K 12
1614 #define PMU1_XTALTAB0_880_37400K 13
1615 #define PMU1_XTALTAB0_880_38400K 14
1616 #define PMU1_XTALTAB0_880_40000K 15
1618 /* the following table is based on 1760Mhz fvco */
1619 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_1760
)[] = {
1620 {12000, 1, 3, 44, 0x9, 0xFFFFEF},
1621 {13000, 2, 1, 12, 0xb, 0x483483},
1622 {14400, 3, 1, 20, 0xa, 0x1C71C7},
1623 {15360, 4, 1, 10, 0xb, 0x755555},
1624 {16200, 5, 1, 20, 0x5, 0x6E9E06},
1625 {16800, 6, 1, 20, 0x5, 0x3Cf3Cf},
1626 {19200, 7, 1, 18, 0x5, 0x17B425},
1627 {19800, 8, 1, 22, 0x4, 0xA57EB},
1628 {20000, 9, 1, 22, 0x4, 0x0},
1629 {24000, 10, 3, 22, 0xa, 0x0},
1630 {25000, 11, 5, 32, 0xb, 0x0},
1631 {26000, 12, 1, 4, 0x10, 0xEC4EC4},
1632 {30000, 13, 3, 16, 0xb, 0x0},
1633 {38400, 14, 1, 10, 0x4, 0x955555},
1634 {40000, 15, 1, 4, 0xb, 0},
1639 #define PMU1_XTALTAB0_1760_12000K 0
1640 #define PMU1_XTALTAB0_1760_13000K 1
1641 #define PMU1_XTALTAB0_1760_14400K 2
1642 #define PMU1_XTALTAB0_1760_15360K 3
1643 #define PMU1_XTALTAB0_1760_16200K 4
1644 #define PMU1_XTALTAB0_1760_16800K 5
1645 #define PMU1_XTALTAB0_1760_19200K 6
1646 #define PMU1_XTALTAB0_1760_19800K 7
1647 #define PMU1_XTALTAB0_1760_20000K 8
1648 #define PMU1_XTALTAB0_1760_24000K 9
1649 #define PMU1_XTALTAB0_1760_25000K 10
1650 #define PMU1_XTALTAB0_1760_26000K 11
1651 #define PMU1_XTALTAB0_1760_30000K 12
1652 #define PMU1_XTALTAB0_1760_38400K 13
1653 #define PMU1_XTALTAB0_1760_40000K 14
1655 /* the following table is based on 1440Mhz fvco */
1656 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_1440
)[] = {
1657 {12000, 1, 1, 1, 0x78, 0x0 },
1658 {13000, 2, 1, 1, 0x6E, 0xC4EC4E},
1659 {14400, 3, 1, 1, 0x64, 0x0 },
1660 {15360, 4, 1, 1, 0x5D, 0xC00000},
1661 {16200, 5, 1, 1, 0x58, 0xE38E38},
1662 {16800, 6, 1, 1, 0x55, 0xB6DB6D},
1663 {19200, 7, 1, 1, 0x4B, 0 },
1664 {19800, 8, 1, 1, 0x48, 0xBA2E8B},
1665 {20000, 9, 1, 1, 0x48, 0x0 },
1666 {25000, 10, 1, 1, 0x39, 0x999999},
1667 {26000, 11, 1, 1, 0x37, 0x627627},
1668 {30000, 12, 1, 1, 0x30, 0x0 },
1669 {37400, 13, 2, 1, 0x4D, 0x15E76 },
1670 {38400, 13, 2, 1, 0x4B, 0x0 },
1671 {40000, 14, 2, 1, 0x48, 0x0 },
1672 {48000, 15, 2, 1, 0x3c, 0x0 },
1677 #define PMU1_XTALTAB0_1440_12000K 0
1678 #define PMU1_XTALTAB0_1440_13000K 1
1679 #define PMU1_XTALTAB0_1440_14400K 2
1680 #define PMU1_XTALTAB0_1440_15360K 3
1681 #define PMU1_XTALTAB0_1440_16200K 4
1682 #define PMU1_XTALTAB0_1440_16800K 5
1683 #define PMU1_XTALTAB0_1440_19200K 6
1684 #define PMU1_XTALTAB0_1440_19800K 7
1685 #define PMU1_XTALTAB0_1440_20000K 8
1686 #define PMU1_XTALTAB0_1440_25000K 9
1687 #define PMU1_XTALTAB0_1440_26000K 10
1688 #define PMU1_XTALTAB0_1440_30000K 11
1689 #define PMU1_XTALTAB0_1440_37400K 12
1690 #define PMU1_XTALTAB0_1440_38400K 13
1691 #define PMU1_XTALTAB0_1440_40000K 14
1692 #define PMU1_XTALTAB0_1440_48000K 15
1694 #define XTAL_FREQ_24000MHZ 24000
1695 #define XTAL_FREQ_30000MHZ 30000
1696 #define XTAL_FREQ_37400MHZ 37400
1697 #define XTAL_FREQ_48000MHZ 48000
1699 static const pmu1_xtaltab0_t
BCMINITDATA(pmu1_xtaltab0_960
)[] = {
1700 {12000, 1, 1, 1, 0x50, 0x0 },
1701 {13000, 2, 1, 1, 0x49, 0xD89D89},
1702 {14400, 3, 1, 1, 0x42, 0xAAAAAA},
1703 {15360, 4, 1, 1, 0x3E, 0x800000},
1704 {16200, 5, 1, 1, 0x39, 0x425ED0},
1705 {16800, 6, 1, 1, 0x39, 0x249249},
1706 {19200, 7, 1, 1, 0x32, 0x0 },
1707 {19800, 8, 1, 1, 0x30, 0x7C1F07},
1708 {20000, 9, 1, 1, 0x30, 0x0 },
1709 {25000, 10, 1, 1, 0x26, 0x666666},
1710 {26000, 11, 1, 1, 0x24, 0xEC4EC4},
1711 {30000, 12, 1, 1, 0x20, 0x0 },
1712 {37400, 13, 2, 1, 0x33, 0x563EF9},
1713 {38400, 14, 2, 1, 0x32, 0x0 },
1714 {40000, 15, 2, 1, 0x30, 0x0 },
1715 {48000, 16, 2, 1, 0x28, 0x0 },
1720 #define PMU1_XTALTAB0_960_12000K 0
1721 #define PMU1_XTALTAB0_960_13000K 1
1722 #define PMU1_XTALTAB0_960_14400K 2
1723 #define PMU1_XTALTAB0_960_15360K 3
1724 #define PMU1_XTALTAB0_960_16200K 4
1725 #define PMU1_XTALTAB0_960_16800K 5
1726 #define PMU1_XTALTAB0_960_19200K 6
1727 #define PMU1_XTALTAB0_960_19800K 7
1728 #define PMU1_XTALTAB0_960_20000K 8
1729 #define PMU1_XTALTAB0_960_25000K 9
1730 #define PMU1_XTALTAB0_960_26000K 10
1731 #define PMU1_XTALTAB0_960_30000K 11
1732 #define PMU1_XTALTAB0_960_37400K 12
1733 #define PMU1_XTALTAB0_960_38400K 13
1734 #define PMU1_XTALTAB0_960_40000K 14
1735 #define PMU1_XTALTAB0_960_48000K 15
1737 /* select xtal table for each chip */
1738 static const pmu1_xtaltab0_t
*
1739 BCMINITFN(si_pmu1_xtaltab0
)(si_t
*sih
)
1744 switch (CHIPID(sih
->chip
)) {
1745 case BCM4325_CHIP_ID
:
1746 return pmu1_xtaltab0_880
;
1747 case BCM4329_CHIP_ID
:
1748 return pmu1_xtaltab0_880_4329
;
1749 case BCM4315_CHIP_ID
:
1750 return pmu1_xtaltab0_1760
;
1751 case BCM4319_CHIP_ID
:
1752 return pmu1_xtaltab0_1440
;
1753 case BCM4336_CHIP_ID
:
1754 return pmu1_xtaltab0_960
;
1755 case BCM4330_CHIP_ID
:
1756 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
1757 return pmu1_xtaltab0_960
;
1759 return pmu1_xtaltab0_1440
;
1761 PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1768 /* select default xtal frequency for each chip */
1769 static const pmu1_xtaltab0_t
*
1770 BCMINITFN(si_pmu1_xtaldef0
)(si_t
*sih
)
1776 switch (CHIPID(sih
->chip
)) {
1777 case BCM4325_CHIP_ID
:
1778 /* Default to 26000Khz */
1779 return &pmu1_xtaltab0_880
[PMU1_XTALTAB0_880_26000K
];
1780 case BCM4329_CHIP_ID
:
1781 /* Default to 38400Khz */
1782 return &pmu1_xtaltab0_880_4329
[PMU1_XTALTAB0_880_38400K
];
1783 case BCM4315_CHIP_ID
:
1785 /* Default to 30000Khz */
1786 return &pmu1_xtaltab0_1760
[PMU1_XTALTAB0_1760_30000K
];
1788 /* Default to 26000Khz */
1789 return &pmu1_xtaltab0_1760
[PMU1_XTALTAB0_1760_26000K
];
1791 case BCM4319_CHIP_ID
:
1792 /* Default to 30000Khz */
1793 return &pmu1_xtaltab0_1440
[PMU1_XTALTAB0_1440_30000K
];
1794 case BCM4336_CHIP_ID
:
1795 /* Default to 26000Khz */
1796 return &pmu1_xtaltab0_960
[PMU1_XTALTAB0_960_26000K
];
1797 case BCM4330_CHIP_ID
:
1798 /* Default to 37400Khz */
1799 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
1800 return &pmu1_xtaltab0_960
[PMU1_XTALTAB0_960_37400K
];
1802 return &pmu1_xtaltab0_1440
[PMU1_XTALTAB0_1440_37400K
];
1804 PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1811 /* select default pll fvco for each chip */
1813 BCMINITFN(si_pmu1_pllfvco0
)(si_t
*sih
)
1819 switch (CHIPID(sih
->chip
)) {
1820 case BCM4325_CHIP_ID
:
1822 case BCM4329_CHIP_ID
:
1824 case BCM4315_CHIP_ID
:
1826 case BCM4319_CHIP_ID
:
1828 case BCM4336_CHIP_ID
:
1830 case BCM4330_CHIP_ID
:
1831 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
1836 PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih
->chip
, chn
, 8)));
1843 /* query alp/xtal clock frequency */
1845 BCMINITFN(si_pmu1_alpclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
1847 const pmu1_xtaltab0_t
*xt
;
1850 /* Find the frequency in the table */
1851 xf
= (R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1852 PCTL_XTALFREQ_SHIFT
;
1853 for (xt
= si_pmu1_xtaltab0(sih
); xt
!= NULL
&& xt
->fref
!= 0; xt
++)
1856 /* Could not find it so assign a default value */
1857 if (xt
== NULL
|| xt
->fref
== 0)
1858 xt
= si_pmu1_xtaldef0(sih
);
1859 ASSERT(xt
!= NULL
&& xt
->fref
!= 0);
1861 return xt
->fref
* 1000;
1863 #endif /* !_CFE_ || CFG_WL */
1866 si_pmu_minresmask_htavail_set(si_t
*sih
, osl_t
*osh
, bool set_clear
)
1870 /* Remember original core before switch to chipc */
1871 origidx
= si_coreidx(sih
);
1872 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
1876 switch (CHIPID(sih
->chip
)) {
1877 case BCM4313_CHIP_ID
:
1878 if ((cc
->min_res_mask
) & (PMURES_BIT(RES4313_HT_AVAIL_RSRC
)))
1879 AND_REG(osh
, &cc
->min_res_mask
,
1880 ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC
)));
1887 /* Return to original core */
1888 si_setcoreidx(sih
, origidx
);
1891 #if !defined(_CFE_) || defined(CFG_WL)
1892 /* Set up PLL registers in the PMU as per the crystal speed.
1893 * XtalFreq field in pmucontrol register being 0 indicates the PLL
1894 * is not programmed and the h/w default is assumed to work, in which
1895 * case the xtal frequency is unknown to the s/w so we need to call
1896 * si_pmu1_xtaldef0() wherever it is needed to return a default value.
1899 BCMATTACHFN(si_pmu1_pllinit0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 xtal
)
1901 const pmu1_xtaltab0_t
*xt
;
1903 uint32 buf_strength
= 0;
1904 uint8 ndiv_mode
= 1;
1905 uint32 FVCO
= si_pmu1_pllfvco0(sih
);
1910 /* Use h/w default PLL config */
1912 PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
1916 /* Find the frequency in the table */
1917 for (xt
= si_pmu1_xtaltab0(sih
); xt
!= NULL
&& xt
->fref
!= 0; xt
++)
1918 if (xt
->fref
== xtal
)
1921 /* Check current PLL state, bail out if it has been programmed or
1922 * we don't know how to program it.
1924 if (xt
== NULL
|| xt
->fref
== 0) {
1925 PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n",
1926 xtal
/ 1000, xtal
% 1000));
1929 /* for 4319 bootloader already programs the PLL but bootloader does not program the
1930 PLL4 and PLL5. So Skip this check for 4319
1932 if ((((R_REG(osh
, &cc
->pmucontrol
) & PCTL_XTALFREQ_MASK
) >>
1933 PCTL_XTALFREQ_SHIFT
) == xt
->xf
) &&
1934 !((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) || (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
)))
1936 PMU_MSG(("PLL already programmed for %d.%d MHz\n",
1937 xt
->fref
/ 1000, xt
->fref
% 1000));
1941 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal
/ 1000, xtal
% 1000, xt
->xf
));
1942 PMU_MSG(("Programming PLL for %d.%d MHz\n", xt
->fref
/ 1000, xt
->fref
% 1000));
1944 switch (CHIPID(sih
->chip
)) {
1945 case BCM4325_CHIP_ID
:
1946 /* Change the BBPLL drive strength to 2 for all channels */
1947 buf_strength
= 0x222222;
1948 /* Make sure the PLL is off */
1949 AND_REG(osh
, &cc
->min_res_mask
,
1950 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
1951 AND_REG(osh
, &cc
->max_res_mask
,
1952 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4325_HT_AVAIL
)));
1953 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1954 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1956 case BCM4329_CHIP_ID
:
1957 /* Change the BBPLL drive strength to 8 for all channels */
1958 buf_strength
= 0x888888;
1959 AND_REG(osh
, &cc
->min_res_mask
,
1960 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4329_HT_AVAIL
)));
1961 AND_REG(osh
, &cc
->max_res_mask
,
1962 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU
) | PMURES_BIT(RES4329_HT_AVAIL
)));
1963 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1964 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1965 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
1966 if (xt
->fref
== 38400)
1968 else if (xt
->fref
== 37400)
1970 else if (xt
->fref
== 26000)
1973 tmp
= 0x200005C0; /* Chip Dflt Settings */
1974 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1975 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
1976 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & PMU1_PLL0_PC5_CLK_DRV_MASK
;
1977 if ((xt
->fref
== 38400) || (xt
->fref
== 37400) || (xt
->fref
== 26000))
1980 tmp
|= 0x25; /* Chip Dflt Settings */
1981 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1983 case BCM4315_CHIP_ID
:
1984 /* Change the BBPLL drive strength to 2 for all channels */
1985 buf_strength
= 0x222222;
1986 /* Make sure the PLL is off */
1987 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4315_HT_AVAIL
)));
1988 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4315_HT_AVAIL
)));
1991 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU
)));
1992 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU
)));
1995 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
1996 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
1999 case BCM4319_CHIP_ID
:
2000 /* Change the BBPLL drive strength to 2 for all channels */
2001 buf_strength
= 0x222222;
2003 /* Make sure the PLL is off */
2004 /* WAR65104: Disable the HT_AVAIL resource first and then
2005 * after a delay (more than downtime for HT_AVAIL) remove the
2006 * BBPLL resource; backplane clock moves to ALP from HT.
2008 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4319_HT_AVAIL
)));
2009 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4319_HT_AVAIL
)));
2012 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU
)));
2013 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU
)));
2016 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2017 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2020 case BCM4336_CHIP_ID
:
2021 AND_REG(osh
, &cc
->min_res_mask
,
2022 ~(PMURES_BIT(RES4336_HT_AVAIL
) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL
)));
2023 AND_REG(osh
, &cc
->max_res_mask
,
2024 ~(PMURES_BIT(RES4336_HT_AVAIL
) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL
)));
2026 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2027 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2030 case BCM4330_CHIP_ID
:
2031 AND_REG(osh
, &cc
->min_res_mask
,
2032 ~(PMURES_BIT(RES4330_HT_AVAIL
) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL
)));
2033 AND_REG(osh
, &cc
->max_res_mask
,
2034 ~(PMURES_BIT(RES4330_HT_AVAIL
) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL
)));
2036 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2037 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2044 PMU_MSG(("Done masking\n"));
2046 /* Write p1div and p2div to pllcontrol[0] */
2047 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2048 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
2049 ~(PMU1_PLL0_PC0_P1DIV_MASK
| PMU1_PLL0_PC0_P2DIV_MASK
);
2050 tmp
|= ((xt
->p1div
<< PMU1_PLL0_PC0_P1DIV_SHIFT
) & PMU1_PLL0_PC0_P1DIV_MASK
) |
2051 ((xt
->p2div
<< PMU1_PLL0_PC0_P2DIV_SHIFT
) & PMU1_PLL0_PC0_P2DIV_MASK
);
2053 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
2054 tmp
&= ~(PMU1_PLL0_PC0_BYPASS_SDMOD_MASK
);
2055 if (!(xt
->ndiv_frac
))
2056 tmp
|= (1<<(PMU1_PLL0_PC0_BYPASS_SDMOD_SHIFT
));
2058 tmp
|= (0<<(PMU1_PLL0_PC0_BYPASS_SDMOD_SHIFT
));
2061 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2063 if ((CHIPID(sih
->chip
) == BCM4330_CHIP_ID
)) {
2064 if (CHIPREV(sih
->chiprev
) < 2)
2067 if (!(dacrate
= (uint8
)getintvar(NULL
, "dacrate2g")))
2070 si_pmu_set_4330_plldivs(sih
, dacrate
);
2073 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && (CHIPREV(sih
->chiprev
) == 0)) {
2075 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2076 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2077 tmp
= tmp
& (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK
);
2078 tmp
= tmp
| DOT11MAC_880MHZ_CLK_DIVISOR_VAL
;
2079 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2081 if ((CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) ||
2082 (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
))
2083 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MFB
;
2085 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MASH
;
2087 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
)) {
2088 if (!(xt
->ndiv_frac
))
2089 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_INT
;
2091 ndiv_mode
= PMU1_PLL0_PC2_NDIV_MODE_MFB
;
2093 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2095 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2098 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
2099 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2100 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) &
2101 ~(PMU1_PLL0_PC2_NDIV_INT_MASK
| PMU1_PLL0_PC2_NDIV_MODE_MASK
);
2102 tmp
|= ((xt
->ndiv_int
<< PMU1_PLL0_PC2_NDIV_INT_SHIFT
) & PMU1_PLL0_PC2_NDIV_INT_MASK
) |
2103 ((ndiv_mode
<< PMU1_PLL0_PC2_NDIV_MODE_SHIFT
) & PMU1_PLL0_PC2_NDIV_MODE_MASK
);
2104 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2106 /* Write ndiv_frac to pllcontrol[3] */
2107 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2108 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK
;
2109 tmp
|= ((xt
->ndiv_frac
<< PMU1_PLL0_PC3_NDIV_FRAC_SHIFT
) &
2110 PMU1_PLL0_PC3_NDIV_FRAC_MASK
);
2111 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2113 /* Writing to pllcontrol[4] */
2114 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
)) {
2115 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
2116 if (!(xt
->ndiv_frac
))
2121 tmp
&= ~(PMU1_PLL0_PC4_KVCO_XS_MASK
);
2124 tmp
|= (4<<PMU1_PLL0_PC4_KVCO_XS_SHIFT
);
2126 tmp
|= (7<<PMU1_PLL0_PC4_KVCO_XS_SHIFT
);
2128 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2131 /* Write clock driving strength to pllcontrol[5] */
2133 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength
));
2135 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
2136 tmp
= R_REG(osh
, &cc
->pllcontrol_data
) & ~PMU1_PLL0_PC5_CLK_DRV_MASK
;
2137 tmp
|= (buf_strength
<< PMU1_PLL0_PC5_CLK_DRV_SHIFT
);
2139 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
2140 tmp
&= ~(PMU1_PLL0_PC5_VCO_RNG_MASK
| PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK
);
2141 if (!(xt
->ndiv_frac
))
2142 tmp
|= (0x25<<(PMU1_PLL0_PC5_PLL_CTRL_37_32_SHIFT
));
2144 tmp
|= (0x15<<(PMU1_PLL0_PC5_PLL_CTRL_37_32_SHIFT
));
2147 tmp
|= (0x0<<(PMU1_PLL0_PC5_VCO_RNG_SHIFT
));
2149 tmp
|= (0x1<<(PMU1_PLL0_PC5_VCO_RNG_SHIFT
));
2151 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
2154 PMU_MSG(("Done pll\n"));
2156 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
2159 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) && (xt
->fref
!= XTAL_FREQ_30000MHZ
)) {
2160 W_REG(osh
, &cc
->chipcontrol_addr
, PMU1_PLL0_CHIPCTL2
);
2161 tmp
= R_REG(osh
, &cc
->chipcontrol_data
) & ~CCTL_4319USB_XTAL_SEL_MASK
;
2162 if (xt
->fref
== XTAL_FREQ_24000MHZ
) {
2163 tmp
|= (CCTL_4319USB_24MHZ_PLL_SEL
<< CCTL_4319USB_XTAL_SEL_SHIFT
);
2164 } else if (xt
->fref
== XTAL_FREQ_48000MHZ
) {
2165 tmp
|= (CCTL_4319USB_48MHZ_PLL_SEL
<< CCTL_4319USB_XTAL_SEL_SHIFT
);
2167 W_REG(osh
, &cc
->chipcontrol_data
, tmp
);
2170 /* Flush deferred pll control registers writes */
2171 if (sih
->pmurev
>= 2)
2172 OR_REG(osh
, &cc
->pmucontrol
, PCTL_PLL_PLLCTL_UPD
);
2174 /* Write XtalFreq. Set the divisor also. */
2175 tmp
= R_REG(osh
, &cc
->pmucontrol
) &
2176 ~(PCTL_ILP_DIV_MASK
| PCTL_XTALFREQ_MASK
);
2177 tmp
|= (((((xt
->fref
+ 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT
) &
2178 PCTL_ILP_DIV_MASK
) |
2179 ((xt
->xf
<< PCTL_XTALFREQ_SHIFT
) & PCTL_XTALFREQ_MASK
);
2181 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && CHIPREV(sih
->chiprev
) == 0) {
2182 /* clear the htstretch before clearing HTReqEn */
2183 AND_REG(osh
, &cc
->clkstretch
, ~CSTRETCH_HT
);
2184 tmp
&= ~PCTL_HT_REQ_EN
;
2187 W_REG(osh
, &cc
->pmucontrol
, tmp
);
2190 /* query the CPU clock frequency */
2192 BCMINITFN(si_pmu1_cpuclk0
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
)
2196 uint32 ndiv_int
, ndiv_frac
, p2div
, p1div
, fvco
;
2199 uint32 FVCO
= si_pmu1_pllfvco0(sih
);
2201 /* Read m1div from pllcontrol[1] */
2202 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
2203 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2204 m1div
= (tmp
& PMU1_PLL0_PC1_M1DIV_MASK
) >> PMU1_PLL0_PC1_M1DIV_SHIFT
;
2207 /* Read p2div/p1div from pllcontrol[0] */
2208 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
2209 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2210 p2div
= (tmp
& PMU1_PLL0_PC0_P2DIV_MASK
) >> PMU1_PLL0_PC0_P2DIV_SHIFT
;
2211 p1div
= (tmp
& PMU1_PLL0_PC0_P1DIV_MASK
) >> PMU1_PLL0_PC0_P1DIV_SHIFT
;
2213 /* Calculate fvco based on xtal freq and ndiv and pdiv */
2214 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
2215 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2216 ndiv_int
= (tmp
& PMU1_PLL0_PC2_NDIV_INT_MASK
) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT
;
2218 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
2219 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2220 ndiv_frac
= (tmp
& PMU1_PLL0_PC3_NDIV_FRAC_MASK
) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT
;
2222 fref
= si_pmu1_alpclk0(sih
, osh
, cc
) / 1000;
2224 fvco
= (fref
* ndiv_int
) << 8;
2225 fvco
+= (fref
* (ndiv_frac
>> 12)) >> 4;
2226 fvco
+= (fref
* (ndiv_frac
& 0xfff)) >> 12;
2233 PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n",
2234 ndiv_int
, ndiv_frac
, p2div
, p1div
, fvco
));
2239 /* Return ARM/SB clock */
2240 return FVCO
/ m1div
* 1000;
2242 #endif /* !_CFE_ || CFG_WL */
2244 /* initialize PLL */
2246 BCMATTACHFN(si_pmu_pll_init
)(si_t
*sih
, osl_t
*osh
, uint xtalfreq
)
2254 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2256 /* Remember original core before switch to chipc */
2257 origidx
= si_coreidx(sih
);
2258 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2261 switch (CHIPID(sih
->chip
)) {
2262 case BCM5354_CHIP_ID
:
2265 si_pmu0_pllinit0(sih
, osh
, cc
, xtalfreq
);
2267 #if !defined(_CFE_) || defined(CFG_WL)
2268 case BCM4328_CHIP_ID
:
2269 si_pmu0_pllinit0(sih
, osh
, cc
, xtalfreq
);
2271 case BCM4325_CHIP_ID
:
2272 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
2274 case BCM4329_CHIP_ID
:
2277 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
2279 case BCM4312_CHIP_ID
:
2280 /* assume default works */
2282 case BCM4322_CHIP_ID
:
2283 case BCM43221_CHIP_ID
:
2284 case BCM43231_CHIP_ID
:
2285 case BCM4342_CHIP_ID
: {
2286 if (CHIPREV(sih
->chiprev
) == 0) {
2287 uint32 minmask
, maxmask
;
2289 minmask
= R_REG(osh
, &cc
->min_res_mask
);
2290 maxmask
= R_REG(osh
, &cc
->max_res_mask
);
2292 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
2293 /* Have to remove HT Avail request before powering off PLL */
2294 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
2295 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
2296 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
2297 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
2298 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
2300 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
2303 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_SI_PLL_PLLCTL
);
2304 W_REG(osh
, &cc
->pllcontrol_data
, 0x380005c0);
2308 W_REG(osh
, &cc
->max_res_mask
, maxmask
);
2310 W_REG(osh
, &cc
->min_res_mask
, minmask
);
2316 case BCM4313_CHIP_ID
:
2317 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2318 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43420_CHIP_ID
:
2319 case BCM43421_CHIP_ID
:
2320 case BCM43226_CHIP_ID
:
2321 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
2322 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
2323 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
2324 case BCM43131_CHIP_ID
:
2325 case BCM43227_CHIP_ID
:
2326 case BCM43228_CHIP_ID
:
2327 case BCM43428_CHIP_ID
:
2328 case BCM6362_CHIP_ID
:
2330 case BCM4315_CHIP_ID
:
2331 case BCM4319_CHIP_ID
:
2332 case BCM4336_CHIP_ID
:
2333 case BCM4330_CHIP_ID
:
2334 si_pmu1_pllinit0(sih
, osh
, cc
, xtalfreq
);
2336 #endif /* !_CFE_ || CFG_WL */
2338 PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
2339 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
));
2343 #ifdef BCMDBG_FORCEHT
2344 OR_REG(osh
, &cc
->clk_ctl_st
, CCS_FORCEHT
);
2347 /* Return to original core */
2348 si_setcoreidx(sih
, origidx
);
2351 /* query alp/xtal clock frequency */
2353 BCMINITFN(si_pmu_alp_clock
)(si_t
*sih
, osl_t
*osh
)
2357 uint32 clock
= ALP_CLOCK
;
2362 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2364 /* Remember original core before switch to chipc */
2365 origidx
= si_coreidx(sih
);
2366 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2369 switch (CHIPID(sih
->chip
)) {
2370 case BCM4328_CHIP_ID
:
2371 clock
= si_pmu0_alpclk0(sih
, osh
, cc
);
2373 case BCM5354_CHIP_ID
:
2374 clock
= si_pmu0_alpclk0(sih
, osh
, cc
);
2376 #if !defined(_CFE_) || defined(CFG_WL)
2377 case BCM4325_CHIP_ID
:
2378 case BCM4329_CHIP_ID
:
2379 case BCM4315_CHIP_ID
:
2380 case BCM4319_CHIP_ID
:
2381 case BCM4336_CHIP_ID
:
2382 case BCM4330_CHIP_ID
:
2383 clock
= si_pmu1_alpclk0(sih
, osh
, cc
);
2385 #endif /* !_CFE_ || CFG_WL */
2386 case BCM4312_CHIP_ID
:
2387 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
2388 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2389 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43420_CHIP_ID
:
2390 case BCM43421_CHIP_ID
:
2391 case BCM43226_CHIP_ID
:
2392 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
2393 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
2394 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
2395 case BCM43131_CHIP_ID
:
2396 case BCM43227_CHIP_ID
:
2397 case BCM43228_CHIP_ID
:
2398 case BCM43428_CHIP_ID
:
2399 case BCM6362_CHIP_ID
:
2400 case BCM4342_CHIP_ID
:
2401 case BCM4716_CHIP_ID
:
2402 case BCM4748_CHIP_ID
:
2403 case BCM47162_CHIP_ID
:
2404 case BCM4313_CHIP_ID
:
2405 case BCM5357_CHIP_ID
:
2406 case BCM4749_CHIP_ID
:
2407 case BCM53572_CHIP_ID
:
2409 clock
= 20000 * 1000;
2411 case BCM5356_CHIP_ID
:
2412 case BCM4706_CHIP_ID
:
2414 clock
= 25000 * 1000;
2417 PMU_MSG(("No ALP clock specified "
2418 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2419 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
, clock
));
2423 /* Return to original core */
2424 si_setcoreidx(sih
, origidx
);
2428 /* Find the output of the "m" pll divider given pll controls that start with
2429 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
2432 BCMINITFN(si_pmu5_clock
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint pll0
, uint m
)
2434 uint32 tmp
, div
, ndiv
, p1
, p2
, fc
;
2436 if ((pll0
& 3) || (pll0
> PMU4716_MAINPLL_PLL0
)) {
2437 PMU_ERROR(("%s: Bad pll0: %d\n", __FUNCTION__
, pll0
));
2442 /* Strictly there is an m5 divider, but I'm not sure we use it */
2443 if ((m
== 0) || (m
> 4)) {
2444 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__
, m
));
2448 if ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
2449 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) {
2450 /* Detect failure in clock setting */
2451 if ((R_REG(osh
, &cc
->chipstatus
) & 0x40000) != 0) {
2452 return (133 * 1000000);
2456 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_P1P2_OFF
);
2457 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
2458 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2459 p1
= (tmp
& PMU5_PLL_P1_MASK
) >> PMU5_PLL_P1_SHIFT
;
2460 p2
= (tmp
& PMU5_PLL_P2_MASK
) >> PMU5_PLL_P2_SHIFT
;
2462 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_M14_OFF
);
2463 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
2464 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2465 div
= (tmp
>> ((m
- 1) * PMU5_PLL_MDIV_WIDTH
)) & PMU5_PLL_MDIV_MASK
;
2467 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU5_PLL_NM5_OFF
);
2468 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
2469 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
2470 ndiv
= (tmp
& PMU5_PLL_NDIV_MASK
) >> PMU5_PLL_NDIV_SHIFT
;
2472 /* Do calculation in Mhz */
2473 fc
= si_pmu_alp_clock(sih
, osh
) / 1000000;
2474 fc
= (p1
* ndiv
* fc
) / p2
;
2476 PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
2477 __FUNCTION__
, p1
, p2
, ndiv
, ndiv
, m
, div
, fc
, fc
/ div
));
2479 /* Return clock in Hertz */
2480 return ((fc
/ div
) * 1000000);
2484 BCMINITFN(si_4706_pmu_clock
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint pll0
, uint m
)
2486 uint32 w
, ndiv
, p1div
, p2div
;
2489 /* Strictly there is an m5 divider, but I'm not sure we use it */
2490 if ((m
== 0) || (m
> 4)) {
2491 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__
, m
));
2495 /* Get N, P1 and P2 dividers to determine CPU clock */
2496 W_REG(osh
, &cc
->pllcontrol_addr
, pll0
+ PMU6_4706_PROCPLL_OFF
);
2497 w
= R_REG(NULL
, &cc
->pllcontrol_data
);
2498 ndiv
= (w
& PMU6_4706_PROC_NDIV_INT_MASK
) >> PMU6_4706_PROC_NDIV_INT_SHIFT
;
2499 p1div
= (w
& PMU6_4706_PROC_P1DIV_MASK
) >> PMU6_4706_PROC_P1DIV_SHIFT
;
2500 p2div
= (w
& PMU6_4706_PROC_P2DIV_MASK
) >> PMU6_4706_PROC_P2DIV_SHIFT
;
2501 /* Fixed reference clock 25MHz and m = 2 */
2502 clock
= (25000000 / 2) * ndiv
* p2div
/ p1div
;
2503 if (m
== PMU5_MAINPLL_MEM
)
2505 else if (m
== PMU5_MAINPLL_SI
)
2511 /* query backplane clock frequency */
2512 /* For designs that feed the same clock to both backplane
2513 * and CPU just return the CPU clock speed.
2516 BCMINITFN(si_pmu_si_clock
)(si_t
*sih
, osl_t
*osh
)
2520 uint32 clock
= HT_CLOCK
;
2525 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2527 /* Remember original core before switch to chipc */
2528 origidx
= si_coreidx(sih
);
2529 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2532 switch (CHIPID(sih
->chip
)) {
2533 #if !defined(_CFE_) || defined(CFG_WL)
2534 case BCM4328_CHIP_ID
:
2535 clock
= si_pmu0_cpuclk0(sih
, osh
, cc
);
2537 case BCM4325_CHIP_ID
:
2538 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
2540 case BCM4322_CHIP_ID
:
2541 case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
2542 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
2543 case BCM43224_CHIP_ID
: case BCM43420_CHIP_ID
:
2544 case BCM43225_CHIP_ID
:
2545 case BCM43421_CHIP_ID
:
2546 case BCM43226_CHIP_ID
:
2547 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
2548 case BCM6362_CHIP_ID
:
2549 case BCM4342_CHIP_ID
:
2550 /* 96MHz backplane clock */
2551 clock
= 96000 * 1000;
2553 case BCM4329_CHIP_ID
:
2554 if (CHIPREV(sih
->chiprev
) == 0)
2555 clock
= 38400 * 1000;
2557 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
2559 case BCM4315_CHIP_ID
:
2560 case BCM4319_CHIP_ID
:
2561 case BCM4336_CHIP_ID
:
2562 case BCM4330_CHIP_ID
:
2563 clock
= si_pmu1_cpuclk0(sih
, osh
, cc
);
2565 case BCM4313_CHIP_ID
:
2566 /* 80MHz backplane clock */
2567 clock
= 80000 * 1000;
2569 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
2570 case BCM43234_CHIP_ID
:
2571 clock
= (cc
->chipstatus
& CST43236_BP_CLK
) ? (120000 * 1000) : (96000 * 1000);
2573 case BCM43237_CHIP_ID
:
2574 clock
= (cc
->chipstatus
& CST43237_BP_CLK
) ? (96000 * 1000) : (80000 * 1000);
2576 #endif /* !_CFE_ || CFG_WL */
2577 case BCM5354_CHIP_ID
:
2580 case BCM4716_CHIP_ID
:
2581 case BCM4748_CHIP_ID
:
2582 case BCM47162_CHIP_ID
:
2583 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU4716_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2585 case BCM5356_CHIP_ID
:
2586 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU5356_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2588 case BCM5357_CHIP_ID
:
2589 case BCM4749_CHIP_ID
:
2590 clock
= si_pmu5_clock(sih
, osh
, cc
, PMU5357_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2592 case BCM4706_CHIP_ID
:
2593 clock
= si_4706_pmu_clock(sih
, osh
, cc
, PMU4706_MAINPLL_PLL0
, PMU5_MAINPLL_SI
);
2595 case BCM53572_CHIP_ID
:
2599 PMU_MSG(("No backplane clock specified "
2600 "for chip %s rev %d pmurev %d, using default %d Hz\n",
2601 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
, clock
));
2605 /* Return to original core */
2606 si_setcoreidx(sih
, origidx
);
2610 /* query CPU clock frequency */
2612 BCMINITFN(si_pmu_cpu_clock
)(si_t
*sih
, osl_t
*osh
)
2618 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2620 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
2621 if (CHIPID(sih
->chip
) == BCM5354_CHIP_ID
)
2624 if (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
)
2627 if ((sih
->pmurev
>= 5) &&
2628 !((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) ||
2629 (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) ||
2630 (CHIPID(sih
->chip
) == BCM43234_CHIP_ID
) ||
2631 (CHIPID(sih
->chip
) == BCM43235_CHIP_ID
) ||
2632 (CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
2633 (CHIPID(sih
->chip
) == BCM43237_CHIP_ID
) ||
2634 (CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) ||
2635 (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) ||
2636 (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
))) {
2639 switch (CHIPID(sih
->chip
)) {
2640 case BCM5356_CHIP_ID
:
2641 pll
= PMU5356_MAINPLL_PLL0
;
2643 case BCM5357_CHIP_ID
:
2644 case BCM4749_CHIP_ID
:
2645 pll
= PMU5357_MAINPLL_PLL0
;
2648 pll
= PMU4716_MAINPLL_PLL0
;
2652 /* Remember original core before switch to chipc */
2653 origidx
= si_coreidx(sih
);
2654 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2657 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
2658 clock
= si_4706_pmu_clock(sih
, osh
, cc
,
2659 PMU4706_MAINPLL_PLL0
, PMU5_MAINPLL_CPU
);
2661 clock
= si_pmu5_clock(sih
, osh
, cc
, pll
, PMU5_MAINPLL_CPU
);
2663 /* Return to original core */
2664 si_setcoreidx(sih
, origidx
);
2666 clock
= si_pmu_si_clock(sih
, osh
);
2671 /* query memory clock frequency */
2673 BCMINITFN(si_pmu_mem_clock
)(si_t
*sih
, osl_t
*osh
)
2679 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2681 if (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
)
2684 if ((sih
->pmurev
>= 5) &&
2685 !((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) ||
2686 (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) ||
2687 (CHIPID(sih
->chip
) == BCM4330_CHIP_ID
) ||
2688 (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) ||
2689 (CHIPID(sih
->chip
) == BCM43234_CHIP_ID
) ||
2690 (CHIPID(sih
->chip
) == BCM43235_CHIP_ID
) ||
2691 (CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
2692 (CHIPID(sih
->chip
) == BCM43237_CHIP_ID
) ||
2693 (CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) ||
2697 switch (CHIPID(sih
->chip
)) {
2698 case BCM5356_CHIP_ID
:
2699 pll
= PMU5356_MAINPLL_PLL0
;
2701 case BCM5357_CHIP_ID
:
2702 case BCM4749_CHIP_ID
:
2703 pll
= PMU5357_MAINPLL_PLL0
;
2706 pll
= PMU4716_MAINPLL_PLL0
;
2710 /* Remember original core before switch to chipc */
2711 origidx
= si_coreidx(sih
);
2712 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2715 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
2716 clock
= si_4706_pmu_clock(sih
, osh
, cc
,
2717 PMU4706_MAINPLL_PLL0
, PMU5_MAINPLL_MEM
);
2719 clock
= si_pmu5_clock(sih
, osh
, cc
, pll
, PMU5_MAINPLL_MEM
);
2721 /* Return to original core */
2722 si_setcoreidx(sih
, origidx
);
2724 clock
= si_pmu_si_clock(sih
, osh
);
2730 /* Measure ILP clock frequency */
2731 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */
2733 static uint32 ilpcycles_per_sec
= 0;
2736 BCMINITFN(si_pmu_ilp_clock
)(si_t
*sih
, osl_t
*osh
)
2738 if (ISSIM_ENAB(sih
))
2741 if (ilpcycles_per_sec
== 0) {
2742 uint32 start
, end
, delta
;
2743 uint32 origidx
= si_coreidx(sih
);
2744 chipcregs_t
*cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2746 start
= R_REG(osh
, &cc
->pmutimer
);
2747 OSL_DELAY(ILP_CALC_DUR
* 1000);
2748 end
= R_REG(osh
, &cc
->pmutimer
);
2749 delta
= end
- start
;
2750 ilpcycles_per_sec
= delta
* (1000 / ILP_CALC_DUR
);
2751 si_setcoreidx(sih
, origidx
);
2754 return ilpcycles_per_sec
;
2757 /* SDIO Pad drive strength to select value mappings */
2759 uint8 strength
; /* Pad Drive Strength in mA */
2760 uint8 sel
; /* Chip-specific select value */
2761 } sdiod_drive_str_t
;
2763 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
2764 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab1
)[] = {
2770 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
2771 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab2
)[] = {
2780 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
2781 static const sdiod_drive_str_t
BCMINITDATA(sdiod_drive_strength_tab3
)[] = {
2791 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
2794 BCMINITFN(si_sdiod_drive_strength_init
)(si_t
*sih
, osl_t
*osh
, uint32 drivestrength
)
2797 uint origidx
, intr_val
= 0;
2798 sdiod_drive_str_t
*str_tab
= NULL
;
2799 uint32 str_mask
= 0;
2800 uint32 str_shift
= 0;
2805 if (!(sih
->cccaps
& CC_CAP_PMU
)) {
2809 /* Remember original core before switch to chipc */
2810 cc
= (chipcregs_t
*) si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
2812 switch (SDIOD_DRVSTR_KEY(sih
->chip
, sih
->pmurev
)) {
2813 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 1):
2814 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab1
;
2815 str_mask
= 0x30000000;
2818 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 2):
2819 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID
, 3):
2820 case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID
, 4):
2821 case SDIOD_DRVSTR_KEY(BCM4319_CHIP_ID
, 7):
2822 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab2
;
2823 str_mask
= 0x00003800;
2826 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID
, 8):
2827 str_tab
= (sdiod_drive_str_t
*)&sdiod_drive_strength_tab3
;
2828 str_mask
= 0x00003800;
2833 PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
2834 bcm_chipname(sih
->chip
, chn
, 8), sih
->chiprev
, sih
->pmurev
));
2839 if (str_tab
!= NULL
) {
2840 uint32 drivestrength_sel
= 0;
2841 uint32 cc_data_temp
;
2844 for (i
= 0; str_tab
[i
].strength
!= 0; i
++) {
2845 if (drivestrength
>= str_tab
[i
].strength
) {
2846 drivestrength_sel
= str_tab
[i
].sel
;
2851 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
2852 cc_data_temp
= R_REG(osh
, &cc
->chipcontrol_data
);
2853 cc_data_temp
&= ~str_mask
;
2854 drivestrength_sel
<<= str_shift
;
2855 cc_data_temp
|= drivestrength_sel
;
2856 W_REG(osh
, &cc
->chipcontrol_data
, cc_data_temp
);
2858 PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
2859 drivestrength
, cc_data_temp
));
2862 /* Return to original core */
2863 si_restore_core(sih
, origidx
, intr_val
);
2866 /* initialize PMU */
2868 BCMATTACHFN(si_pmu_init
)(si_t
*sih
, osl_t
*osh
)
2873 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2875 /* Remember original core before switch to chipc */
2876 origidx
= si_coreidx(sih
);
2877 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2880 if (sih
->pmurev
== 1)
2881 AND_REG(osh
, &cc
->pmucontrol
, ~PCTL_NOILP_ON_WAIT
);
2882 else if (sih
->pmurev
>= 2)
2883 OR_REG(osh
, &cc
->pmucontrol
, PCTL_NOILP_ON_WAIT
);
2885 #if !defined(_CFE_) || defined(CFG_WL)
2886 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && (sih
->chiprev
== 2)) {
2887 /* Fix for 4329b0 bad LPOM state. */
2888 W_REG(osh
, &cc
->regcontrol_addr
, 2);
2889 OR_REG(osh
, &cc
->regcontrol_data
, 0x100);
2891 W_REG(osh
, &cc
->regcontrol_addr
, 3);
2892 OR_REG(osh
, &cc
->regcontrol_data
, 0x4);
2895 if (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) {
2896 /* Limiting the PALDO spike during init time */
2897 si_pmu_regcontrol(sih
, 2, 0x00000007, 0x00000005);
2899 #endif /* !_CFE_ || CFG_WL */
2901 /* Return to original core */
2902 si_setcoreidx(sih
, origidx
);
2905 #if !defined(_CFE_) || defined(CFG_WL)
2906 /* Return up time in ILP cycles for the given resource. */
2908 BCMINITFN(si_pmu_res_uptime
)(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint8 rsrc
)
2911 uint up
, i
, dup
, dmax
;
2912 uint32 min_mask
= 0, max_mask
= 0;
2914 /* uptime of resource 'rsrc' */
2915 W_REG(osh
, &cc
->res_table_sel
, rsrc
);
2916 up
= (R_REG(osh
, &cc
->res_updn_timer
) >> 8) & 0xff;
2918 /* direct dependancies of resource 'rsrc' */
2919 deps
= si_pmu_res_deps(sih
, osh
, cc
, PMURES_BIT(rsrc
), FALSE
);
2920 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
2921 if (!(deps
& PMURES_BIT(i
)))
2923 deps
&= ~si_pmu_res_deps(sih
, osh
, cc
, PMURES_BIT(i
), TRUE
);
2925 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
2928 /* max uptime of direct dependancies */
2930 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
2931 if (!(deps
& PMURES_BIT(i
)))
2933 dup
= si_pmu_res_uptime(sih
, osh
, cc
, (uint8
)i
);
2938 PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n",
2939 rsrc
, up
, deps
, dmax
));
2941 return up
+ dmax
+ PMURES_UP_TRANSITION
;
2944 /* Return dependancies (direct or all/indirect) for the given resources */
2946 si_pmu_res_deps(si_t
*sih
, osl_t
*osh
, chipcregs_t
*cc
, uint32 rsrcs
, bool all
)
2951 for (i
= 0; i
<= PMURES_MAX_RESNUM
; i
++) {
2952 if (!(rsrcs
& PMURES_BIT(i
)))
2954 W_REG(osh
, &cc
->res_table_sel
, i
);
2955 deps
|= R_REG(osh
, &cc
->res_dep_mask
);
2958 return !all
? deps
: (deps
? (deps
| si_pmu_res_deps(sih
, osh
, cc
, deps
, TRUE
)) : 0);
2961 /* power up/down OTP through PMU resources */
2963 si_pmu_otp_power(si_t
*sih
, osl_t
*osh
, bool on
)
2967 uint32 rsrcs
= 0; /* rsrcs to turn on/off OTP power */
2969 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
2971 /* Don't do anything if OTP is disabled */
2972 if (si_is_otp_disabled(sih
)) {
2973 PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
2977 /* Remember original core before switch to chipc */
2978 origidx
= si_coreidx(sih
);
2979 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2982 switch (CHIPID(sih
->chip
)) {
2983 case BCM4322_CHIP_ID
:
2984 case BCM43221_CHIP_ID
:
2985 case BCM43231_CHIP_ID
:
2986 case BCM4342_CHIP_ID
:
2987 rsrcs
= PMURES_BIT(RES4322_OTP_PU
);
2989 case BCM4325_CHIP_ID
:
2990 rsrcs
= PMURES_BIT(RES4325_OTP_PU
);
2992 case BCM4315_CHIP_ID
:
2993 rsrcs
= PMURES_BIT(RES4315_OTP_PU
);
2995 case BCM4329_CHIP_ID
:
2996 rsrcs
= PMURES_BIT(RES4329_OTP_PU
);
2998 case BCM4319_CHIP_ID
:
2999 rsrcs
= PMURES_BIT(RES4319_OTP_PU
);
3001 case BCM4336_CHIP_ID
:
3002 rsrcs
= PMURES_BIT(RES4336_OTP_PU
);
3004 case BCM4330_CHIP_ID
:
3005 rsrcs
= PMURES_BIT(RES4330_OTP_PU
);
3014 /* Figure out the dependancies (exclude min_res_mask) */
3015 uint32 deps
= si_pmu_res_deps(sih
, osh
, cc
, rsrcs
, TRUE
);
3016 uint32 min_mask
= 0, max_mask
= 0;
3017 si_pmu_res_masks(sih
, &min_mask
, &max_mask
);
3019 /* Turn on/off the power */
3021 PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", rsrcs
| deps
));
3022 OR_REG(osh
, &cc
->min_res_mask
, (rsrcs
| deps
));
3024 SPINWAIT(!(R_REG(osh
, &cc
->res_state
) & rsrcs
), PMU_MAX_TRANSITION_DLY
);
3025 ASSERT(R_REG(osh
, &cc
->res_state
) & rsrcs
);
3028 PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", rsrcs
| deps
));
3029 AND_REG(osh
, &cc
->min_res_mask
, ~(rsrcs
| deps
));
3032 SPINWAIT((((otps
= R_REG(osh
, &cc
->otpstatus
)) & OTPS_READY
) !=
3033 (on
? OTPS_READY
: 0)), 100);
3034 ASSERT((otps
& OTPS_READY
) == (on
? OTPS_READY
: 0));
3035 if ((otps
& OTPS_READY
) != (on
? OTPS_READY
: 0))
3036 PMU_MSG(("OTP ready bit not %s after wait\n", (on
? "ON" : "OFF")));
3039 /* Return to original core */
3040 si_setcoreidx(sih
, origidx
);
3044 si_pmu_rcal(si_t
*sih
, osl_t
*osh
)
3048 uint rcal_done
, BT_out_of_reset
;
3050 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3052 /* Remember original core before switch to chipc */
3053 origidx
= si_coreidx(sih
);
3054 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3057 switch (CHIPID(sih
->chip
)) {
3058 case BCM4325_CHIP_ID
: {
3063 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3065 /* Power Down RCAL Block */
3066 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3068 /* Check if RCAL is already done by BT */
3069 rcal_done
= ((R_REG(osh
, &cc
->chipstatus
)) & 0x8) >> 3;
3071 /* If RCAL already done, note that BT is out of reset */
3072 if (rcal_done
== 1) {
3073 BT_out_of_reset
= 1;
3075 BT_out_of_reset
= 0;
3078 /* Power Up RCAL block */
3079 OR_REG(osh
, &cc
->chipcontrol_data
, 0x04);
3081 /* Wait for completion */
3082 SPINWAIT(0 == (R_REG(osh
, &cc
->chipstatus
) & 0x08), 10 * 1000 * 1000);
3083 ASSERT(R_REG(osh
, &cc
->chipstatus
) & 0x08);
3085 if (BT_out_of_reset
) {
3088 /* Drop the LSB to convert from 5 bit code to 4 bit code */
3089 rcal_code
= (uint8
)(R_REG(osh
, &cc
->chipstatus
) >> 5) & 0x0f;
3092 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
3093 R_REG(osh
, &cc
->chipstatus
), rcal_code
));
3095 /* Write RCal code into pmu_vreg_ctrl[32:29] */
3096 W_REG(osh
, &cc
->regcontrol_addr
, 0);
3097 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~((uint32
)0x07 << 29);
3098 val
|= (uint32
)(rcal_code
& 0x07) << 29;
3099 W_REG(osh
, &cc
->regcontrol_data
, val
);
3100 W_REG(osh
, &cc
->regcontrol_addr
, 1);
3101 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~(uint32
)0x01;
3102 val
|= (uint32
)((rcal_code
>> 3) & 0x01);
3103 W_REG(osh
, &cc
->regcontrol_data
, val
);
3105 /* Write RCal code into pmu_chip_ctrl[33:30] */
3106 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3107 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~((uint32
)0x03 << 30);
3108 val
|= (uint32
)(rcal_code
& 0x03) << 30;
3109 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3110 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3111 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~(uint32
)0x03;
3112 val
|= (uint32
)((rcal_code
>> 2) & 0x03);
3113 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3115 /* Set override in pmu_chip_ctrl[29] */
3116 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3117 OR_REG(osh
, &cc
->chipcontrol_data
, (0x01 << 29));
3119 /* Power off RCal block */
3120 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3121 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3125 case BCM4329_CHIP_ID
: {
3130 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3132 /* Power Down RCAL Block */
3133 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3135 /* Power Up RCAL block */
3136 OR_REG(osh
, &cc
->chipcontrol_data
, 0x04);
3138 /* Wait for completion */
3139 SPINWAIT(0 == (R_REG(osh
, &cc
->chipstatus
) & 0x08), 10 * 1000 * 1000);
3140 ASSERT(R_REG(osh
, &cc
->chipstatus
) & 0x08);
3142 /* Drop the LSB to convert from 5 bit code to 4 bit code */
3143 rcal_code
= (uint8
)(R_REG(osh
, &cc
->chipstatus
) >> 5) & 0x0f;
3145 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
3146 R_REG(osh
, &cc
->chipstatus
), rcal_code
));
3148 /* Write RCal code into pmu_vreg_ctrl[32:29] */
3149 W_REG(osh
, &cc
->regcontrol_addr
, 0);
3150 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~((uint32
)0x07 << 29);
3151 val
|= (uint32
)(rcal_code
& 0x07) << 29;
3152 W_REG(osh
, &cc
->regcontrol_data
, val
);
3153 W_REG(osh
, &cc
->regcontrol_addr
, 1);
3154 val
= R_REG(osh
, &cc
->regcontrol_data
) & ~(uint32
)0x01;
3155 val
|= (uint32
)((rcal_code
>> 3) & 0x01);
3156 W_REG(osh
, &cc
->regcontrol_data
, val
);
3158 /* Write RCal code into pmu_chip_ctrl[33:30] */
3159 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3160 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~((uint32
)0x03 << 30);
3161 val
|= (uint32
)(rcal_code
& 0x03) << 30;
3162 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3163 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3164 val
= R_REG(osh
, &cc
->chipcontrol_data
) & ~(uint32
)0x03;
3165 val
|= (uint32
)((rcal_code
>> 2) & 0x03);
3166 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3168 /* Set override in pmu_chip_ctrl[29] */
3169 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3170 OR_REG(osh
, &cc
->chipcontrol_data
, (0x01 << 29));
3172 /* Power off RCal block */
3173 W_REG(osh
, &cc
->chipcontrol_addr
, 1);
3174 AND_REG(osh
, &cc
->chipcontrol_data
, ~0x04);
3182 /* Return to original core */
3183 si_setcoreidx(sih
, origidx
);
3187 si_pmu_spuravoid(si_t
*sih
, osl_t
*osh
, uint8 spuravoid
)
3190 uint origidx
, intr_val
;
3193 /* Remember original core before switch to chipc */
3194 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
3197 /* force the HT off */
3198 if (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) {
3199 tmp
= R_REG(osh
, &cc
->max_res_mask
);
3200 tmp
&= ~RES4336_HT_AVAIL
;
3201 W_REG(osh
, &cc
->max_res_mask
, tmp
);
3202 /* wait for the ht to really go away */
3203 SPINWAIT(((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
) == 0), 10000);
3204 ASSERT((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
) == 0);
3207 /* update the pll changes */
3208 si_pmu_spuravoid_pllupdate(sih
, cc
, osh
, spuravoid
);
3210 /* enable HT back on */
3211 if (CHIPID(sih
->chip
) == BCM4336_CHIP_ID
) {
3212 tmp
= R_REG(osh
, &cc
->max_res_mask
);
3213 tmp
|= RES4336_HT_AVAIL
;
3214 W_REG(osh
, &cc
->max_res_mask
, tmp
);
3217 /* Return to original core */
3218 si_restore_core(sih
, origidx
, intr_val
);
3222 si_pmu_spuravoid_pllupdate(si_t
*sih
, chipcregs_t
*cc
, osl_t
*osh
, uint8 spuravoid
)
3225 uint8 phypll_offset
= 0;
3226 uint8 bcm5357_bcm43236_p1div
[] = {0x1, 0x5, 0x5};
3227 uint8 bcm5357_bcm43236_ndiv
[] = {0x30, 0xf6, 0xfc};
3232 switch (CHIPID(sih
->chip
)) {
3233 case BCM5357_CHIP_ID
: case BCM4749_CHIP_ID
:
3234 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
3235 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
3236 case BCM6362_CHIP_ID
: case BCM53572_CHIP_ID
:
3238 if ((CHIPID(sih
->chip
) == BCM6362_CHIP_ID
) && (sih
->chiprev
== 0)) {
3239 /* 6362a0 (same clks as 4322[4-6]) */
3240 if (spuravoid
== 1) {
3241 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3242 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500010);
3243 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3244 W_REG(osh
, &cc
->pllcontrol_data
, 0x000C0C06);
3245 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3246 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3247 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3248 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3249 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3250 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
3251 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3252 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3254 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3255 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100010);
3256 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3257 W_REG(osh
, &cc
->pllcontrol_data
, 0x000c0c06);
3258 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3259 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3260 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3261 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3262 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3263 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3264 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3265 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3269 /* 5357[ab]0, 43236[ab]0, and 6362b0 */
3271 /* BCM5357 needs to touch PLL1_PLLCTL[02],so offset PLL0_PLLCTL[02] by 6 */
3272 phypll_offset
= ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
3273 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
) ||
3274 (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
)) ? 6 : 0;
3276 /* RMW only the P1 divider */
3277 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
+ phypll_offset
);
3278 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
3279 tmp
&= (~(PMU1_PLL0_PC0_P1DIV_MASK
));
3280 tmp
|= (bcm5357_bcm43236_p1div
[spuravoid
] << PMU1_PLL0_PC0_P1DIV_SHIFT
);
3281 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
3283 /* RMW only the int feedback divider */
3284 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
+ phypll_offset
);
3285 tmp
= R_REG(osh
, &cc
->pllcontrol_data
);
3286 tmp
&= ~(PMU1_PLL0_PC2_NDIV_INT_MASK
);
3287 tmp
|= (bcm5357_bcm43236_ndiv
[spuravoid
]) << PMU1_PLL0_PC2_NDIV_INT_SHIFT
;
3288 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
3294 case BCM4331_CHIP_ID
:
3295 case BCM43431_CHIP_ID
:
3296 if (ISSIM_ENAB(sih
)) {
3297 if (spuravoid
== 2) {
3298 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3299 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000002);
3300 } else if (spuravoid
== 1) {
3301 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3302 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000001);
3304 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3305 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3308 if (spuravoid
== 2) {
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
, 0x0FC00a08);
3313 } else if (spuravoid
== 1) {
3314 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3315 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500014);
3316 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3317 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3319 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3320 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100014);
3321 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3322 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3328 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
3329 case BCM43226_CHIP_ID
:
3330 if (spuravoid
== 1) {
3331 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3332 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500010);
3333 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3334 W_REG(osh
, &cc
->pllcontrol_data
, 0x000C0C06);
3335 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3336 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3337 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3338 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3339 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3340 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
3341 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3342 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3344 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3345 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100010);
3346 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3347 W_REG(osh
, &cc
->pllcontrol_data
, 0x000c0c06);
3348 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3349 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3350 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3351 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3352 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3353 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3354 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3355 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3360 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
3361 case BCM43420_CHIP_ID
:
3362 if (spuravoid
== 1) {
3363 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3364 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500008);
3365 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3366 W_REG(osh
, &cc
->pllcontrol_data
, 0x0C000C06);
3367 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3368 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600a08);
3369 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3370 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3371 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3372 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E920);
3373 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3374 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3376 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3377 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100008);
3378 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3379 W_REG(osh
, &cc
->pllcontrol_data
, 0x0c000c06);
3380 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3381 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3382 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3383 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3384 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3385 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3386 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3387 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888855);
3393 case BCM4716_CHIP_ID
:
3394 case BCM4748_CHIP_ID
:
3395 case BCM47162_CHIP_ID
:
3396 if (spuravoid
== 1) {
3397 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3398 W_REG(osh
, &cc
->pllcontrol_data
, 0x11500060);
3399 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3400 W_REG(osh
, &cc
->pllcontrol_data
, 0x080C0C06);
3401 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3402 W_REG(osh
, &cc
->pllcontrol_data
, 0x0F600000);
3403 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3404 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3405 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3406 W_REG(osh
, &cc
->pllcontrol_data
, 0x2001E924);
3407 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3408 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3410 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3411 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100060);
3412 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3413 W_REG(osh
, &cc
->pllcontrol_data
, 0x080c0c06);
3414 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3415 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000000);
3416 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3417 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3418 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3419 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3420 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3421 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3427 case BCM4322_CHIP_ID
:
3428 case BCM43221_CHIP_ID
:
3429 case BCM43231_CHIP_ID
:
3430 case BCM4342_CHIP_ID
:
3431 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3432 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100070);
3433 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3434 W_REG(osh
, &cc
->pllcontrol_data
, 0x1014140a);
3435 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3436 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888854);
3438 if (spuravoid
== 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
3439 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3440 W_REG(osh
, &cc
->pllcontrol_data
, 0x05201828);
3441 } else { /* enable 40/80/160Mhz clock mode */
3442 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3443 W_REG(osh
, &cc
->pllcontrol_data
, 0x05001828);
3448 case BCM4319_CHIP_ID
:
3450 case BCM4336_CHIP_ID
:
3451 /* Looks like these are only for default xtal freq 26MHz */
3452 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3453 W_REG(osh
, &cc
->pllcontrol_data
, 0x02100020);
3455 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3456 W_REG(osh
, &cc
->pllcontrol_data
, 0x0C0C0C0C);
3458 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3459 W_REG(osh
, &cc
->pllcontrol_data
, 0x01240C0C);
3461 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3462 W_REG(osh
, &cc
->pllcontrol_data
, 0x202C2820);
3464 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3465 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888825);
3467 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3468 if (spuravoid
== 1) {
3469 W_REG(osh
, &cc
->pllcontrol_data
, 0x00EC4EC4);
3471 W_REG(osh
, &cc
->pllcontrol_data
, 0x00762762);
3474 tmp
= PCTL_PLL_PLLCTL_UPD
;
3476 case BCM43131_CHIP_ID
:
3477 case BCM43227_CHIP_ID
:
3478 case BCM43228_CHIP_ID
:
3479 case BCM43428_CHIP_ID
:
3481 /* PLL Settings for spur avoidance on/off mode, no on2 support for 43228A0 */
3482 if (spuravoid
== 1) {
3483 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3484 W_REG(osh
, &cc
->pllcontrol_data
, 0x01100014);
3485 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3486 W_REG(osh
, &cc
->pllcontrol_data
, 0x040C0C06);
3487 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3488 W_REG(osh
, &cc
->pllcontrol_data
, 0x03140A08);
3489 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3490 W_REG(osh
, &cc
->pllcontrol_data
, 0x00333333);
3491 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3492 W_REG(osh
, &cc
->pllcontrol_data
, 0x202C2820);
3493 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3494 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3496 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL0
);
3497 W_REG(osh
, &cc
->pllcontrol_data
, 0x11100014);
3498 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL1
);
3499 W_REG(osh
, &cc
->pllcontrol_data
, 0x040c0c06);
3500 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL2
);
3501 W_REG(osh
, &cc
->pllcontrol_data
, 0x03000a08);
3502 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL3
);
3503 W_REG(osh
, &cc
->pllcontrol_data
, 0x00000000);
3504 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL4
);
3505 W_REG(osh
, &cc
->pllcontrol_data
, 0x200005c0);
3506 W_REG(osh
, &cc
->pllcontrol_addr
, PMU1_PLL0_PLLCTL5
);
3507 W_REG(osh
, &cc
->pllcontrol_data
, 0x88888815);
3512 PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n",
3513 __FUNCTION__
, bcm_chipname(sih
->chip
, chn
, 8)));
3517 tmp
|= R_REG(osh
, &cc
->pmucontrol
);
3518 W_REG(osh
, &cc
->pmucontrol
, tmp
);
3522 si_pmu_gband_spurwar(si_t
*sih
, osl_t
*osh
)
3525 uint origidx
, intr_val
;
3526 uint32 cc_clk_ctl_st
;
3527 uint32 minmask
, maxmask
;
3529 if ((CHIPID(sih
->chip
) == BCM43222_CHIP_ID
) ||
3530 (CHIPID(sih
->chip
) == BCM43420_CHIP_ID
)) {
3531 /* Remember original core before switch to chipc */
3532 cc
= (chipcregs_t
*)si_switch_core(sih
, CC_CORE_ID
, &origidx
, &intr_val
);
3535 /* Remove force HT and HT Avail Request from chipc core */
3536 cc_clk_ctl_st
= R_REG(osh
, &cc
->clk_ctl_st
);
3537 AND_REG(osh
, &cc
->clk_ctl_st
, ~(CCS_FORCEHT
| CCS_HTAREQ
));
3539 minmask
= R_REG(osh
, &cc
->min_res_mask
);
3540 maxmask
= R_REG(osh
, &cc
->max_res_mask
);
3542 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
3543 /* Have to remove HT Avail request before powering off PLL */
3544 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
3545 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_HT_SI_AVAIL
)));
3546 SPINWAIT(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
, PMU_MAX_TRANSITION_DLY
);
3547 AND_REG(osh
, &cc
->min_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
3548 AND_REG(osh
, &cc
->max_res_mask
, ~(PMURES_BIT(RES4322_SI_PLL_ON
)));
3550 ASSERT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
3552 /* Change backplane clock speed from 96 MHz to 80 MHz */
3553 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_PLL_PLLCTL2
);
3554 W_REG(osh
, &cc
->pllcontrol_data
, (R_REG(osh
, &cc
->pllcontrol_data
) &
3555 ~(PMU2_PLL_PC2_M6DIV_MASK
)) |
3556 (0xc << PMU2_PLL_PC2_M6DIV_SHIFT
));
3558 /* Reduce the driver strengths of the phyclk160, adcclk80, and phyck80
3559 * clocks from 0x8 to 0x1
3561 W_REG(osh
, &cc
->pllcontrol_addr
, PMU2_PLL_PLLCTL5
);
3562 W_REG(osh
, &cc
->pllcontrol_data
, (R_REG(osh
, &cc
->pllcontrol_data
) &
3563 ~(PMU2_PLL_PC5_CLKDRIVE_CH1_MASK
|
3564 PMU2_PLL_PC5_CLKDRIVE_CH2_MASK
|
3565 PMU2_PLL_PC5_CLKDRIVE_CH3_MASK
|
3566 PMU2_PLL_PC5_CLKDRIVE_CH4_MASK
)) |
3567 ((1 << PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT
) |
3568 (1 << PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT
) |
3569 (1 << PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT
) |
3570 (1 << PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT
)));
3572 W_REG(osh
, &cc
->pmucontrol
, R_REG(osh
, &cc
->pmucontrol
) | PCTL_PLL_PLLCTL_UPD
);
3574 /* Restore min_res_mask and max_res_mask */
3576 W_REG(osh
, &cc
->max_res_mask
, maxmask
);
3578 W_REG(osh
, &cc
->min_res_mask
, minmask
);
3580 /* Make sure the PLL is on. Spinwait until the HTAvail is True */
3581 SPINWAIT(!(R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
), PMU_MAX_TRANSITION_DLY
);
3582 ASSERT((R_REG(osh
, &cc
->clk_ctl_st
) & CCS_HTAVAIL
));
3584 /* Restore force HT and HT Avail Request on the chipc core */
3585 W_REG(osh
, &cc
->clk_ctl_st
, cc_clk_ctl_st
);
3587 /* Return to original core */
3588 si_restore_core(sih
, origidx
, intr_val
);
3593 si_pmu_is_otp_powered(si_t
*sih
, osl_t
*osh
)
3599 /* Remember original core before switch to chipc */
3600 idx
= si_coreidx(sih
);
3601 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3604 switch (CHIPID(sih
->chip
)) {
3605 case BCM4322_CHIP_ID
:
3606 case BCM43221_CHIP_ID
:
3607 case BCM43231_CHIP_ID
:
3608 case BCM4342_CHIP_ID
:
3609 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4322_OTP_PU
)) != 0;
3611 case BCM4325_CHIP_ID
:
3612 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4325_OTP_PU
)) != 0;
3614 case BCM4329_CHIP_ID
:
3615 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4329_OTP_PU
)) != 0;
3617 case BCM4315_CHIP_ID
:
3618 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4315_OTP_PU
)) != 0;
3620 case BCM4319_CHIP_ID
:
3621 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4319_OTP_PU
)) != 0;
3623 case BCM4336_CHIP_ID
:
3624 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4336_OTP_PU
)) != 0;
3626 case BCM4330_CHIP_ID
:
3627 st
= (R_REG(osh
, &cc
->res_state
) & PMURES_BIT(RES4330_OTP_PU
)) != 0;
3630 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
3631 * Use OTP_INIT command to reset/refresh state.
3633 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
3634 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
3635 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
3636 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
: case BCM43420_CHIP_ID
:
3637 case BCM4331_CHIP_ID
: case BCM43431_CHIP_ID
:
3645 /* Return to original core */
3646 si_setcoreidx(sih
, idx
);
3649 #endif /* !_CFE_ || CFG_WL */
3652 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
3653 si_pmu_sprom_enable(si_t
*sih
, osl_t
*osh
, bool enable
)
3655 BCMATTACHFN(si_pmu_sprom_enable
)(si_t
*sih
, osl_t
*osh
, bool enable
)
3661 /* Remember original core before switch to chipc */
3662 origidx
= si_coreidx(sih
);
3663 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3666 switch (CHIPID(sih
->chip
)) {
3667 case BCM4315_CHIP_ID
:
3668 if (CHIPREV(sih
->chiprev
) < 1)
3670 if (sih
->chipst
& CST4315_SPROM_SEL
) {
3672 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3673 val
= R_REG(osh
, &cc
->chipcontrol_data
);
3678 W_REG(osh
, &cc
->chipcontrol_data
, val
);
3685 /* Return to original core */
3686 si_setcoreidx(sih
, origidx
);
3690 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
3691 si_pmu_is_sprom_enabled(si_t
*sih
, osl_t
*osh
)
3693 BCMATTACHFN(si_pmu_is_sprom_enabled
)(si_t
*sih
, osl_t
*osh
)
3700 /* Remember original core before switch to chipc */
3701 origidx
= si_coreidx(sih
);
3702 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3705 switch (CHIPID(sih
->chip
)) {
3706 case BCM4315_CHIP_ID
:
3707 if (CHIPREV(sih
->chiprev
) < 1)
3709 if (!(sih
->chipst
& CST4315_SPROM_SEL
))
3711 W_REG(osh
, &cc
->chipcontrol_addr
, 0);
3712 if (R_REG(osh
, &cc
->chipcontrol_data
) & 0x80000000)
3719 /* Return to original core */
3720 si_setcoreidx(sih
, origidx
);
3724 /* initialize PMU chip controls and other chip level stuff */
3726 BCMATTACHFN(si_pmu_chip_init
)(si_t
*sih
, osl_t
*osh
)
3730 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3732 #ifdef CHIPC_UART_ALWAYS_ON
3733 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, clk_ctl_st
), CCS_FORCEALP
, CCS_FORCEALP
);
3734 #endif /* CHIPC_UART_ALWAYS_ON */
3737 /* Gate off SPROM clock and chip select signals */
3738 si_pmu_sprom_enable(sih
, osh
, FALSE
);
3741 /* Remember original core */
3742 origidx
= si_coreidx(sih
);
3744 #if !defined(_CFE_) || defined(CFG_WL)
3745 /* Misc. chip control, has nothing to do with PMU */
3746 switch (CHIPID(sih
->chip
)) {
3747 case BCM4315_CHIP_ID
:
3749 si_setcore(sih
, PCMCIA_CORE_ID
, 0);
3750 si_core_disable(sih
, 0);
3753 case BCM4319_CHIP_ID
:
3754 /* No support for external LPO, so power it down */
3755 si_pmu_chipcontrol(sih
, 0, (1<<28), (0<<28));
3760 #endif /* !_CFE_ || CFG_WL */
3762 /* Return to original core */
3763 si_setcoreidx(sih
, origidx
);
3766 /* initialize PMU switch/regulators */
3768 BCMATTACHFN(si_pmu_swreg_init
)(si_t
*sih
, osl_t
*osh
)
3770 #if !defined(_CFE_) || defined(CFG_WL)
3771 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3773 switch (CHIPID(sih
->chip
)) {
3774 case BCM4325_CHIP_ID
:
3775 if (CHIPREV(sih
->chiprev
) < 3)
3777 if (((sih
->chipst
& CST4325_PMUTOP_2B_MASK
) >> CST4325_PMUTOP_2B_SHIFT
) == 1) {
3778 /* Bump CLDO PWM output voltage to 1.25V */
3779 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_PWM
, 0xf);
3780 /* Bump CLDO BURST output voltage to 1.25V */
3781 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_BURST
, 0xf);
3783 /* Bump CBUCK PWM output voltage to 1.5V */
3784 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_PWM
, 0xb);
3785 /* Bump CBUCK BURST output voltage to 1.5V */
3786 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_BURST
, 0xb);
3787 /* Bump LNLDO1 output voltage to 1.25V */
3788 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_LNLDO1
, 0x1);
3789 /* Select LNLDO2 output voltage to 2.5V */
3790 if (sih
->boardflags
& BFL_LNLDO2_2P5
)
3791 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_LNLDO2_SEL
, 0x1);
3793 case BCM4315_CHIP_ID
: {
3798 if (CHIPREV(sih
->chiprev
) != 2)
3801 /* Remember original core before switch to chipc */
3802 origidx
= si_coreidx(sih
);
3803 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3806 W_REG(osh
, &cc
->regcontrol_addr
, 4);
3807 val
= R_REG(osh
, &cc
->regcontrol_data
);
3808 val
|= (uint32
)(1 << 16);
3809 W_REG(osh
, &cc
->regcontrol_data
, val
);
3811 /* Return to original core */
3812 si_setcoreidx(sih
, origidx
);
3815 case BCM4336_CHIP_ID
:
3816 /* Reduce CLDO PWM output voltage to 1.2V */
3817 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_PWM
, 0xe);
3818 /* Reduce CLDO BURST output voltage to 1.2V */
3819 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CLDO_BURST
, 0xe);
3820 /* Reduce LNLDO1 output voltage to 1.2V */
3821 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_LNLDO1
, 0xe);
3822 if (CHIPREV(sih
->chiprev
) == 0)
3823 si_pmu_regcontrol(sih
, 2, 0x400000, 0x400000);
3826 case BCM4330_CHIP_ID
:
3827 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
3828 si_pmu_set_ldo_voltage(sih
, osh
, SET_LDO_VOLTAGE_CBUCK_PWM
, 0);
3833 #endif /* !_CFE_ || CFG_WL */
3837 si_pmu_radio_enable(si_t
*sih
, bool enable
)
3839 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3841 switch (CHIPID(sih
->chip
)) {
3842 case BCM4325_CHIP_ID
:
3843 if (sih
->boardflags
& BFL_FASTPWR
)
3846 if ((sih
->boardflags
& BFL_BUCKBOOST
)) {
3847 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, min_res_mask
),
3848 PMURES_BIT(RES4325_BUCK_BOOST_BURST
),
3849 enable
? PMURES_BIT(RES4325_BUCK_BOOST_BURST
) : 0);
3853 OSL_DELAY(100 * 1000);
3856 case BCM4319_CHIP_ID
:
3858 si_write_wrapperreg(sih
, AI_OOBSELOUTB74
, (uint32
)0x868584);
3860 si_write_wrapperreg(sih
, AI_OOBSELOUTB74
, (uint32
)0x060584);
3865 /* Wait for a particular clock level to be on the backplane */
3867 si_pmu_waitforclk_on_backplane(si_t
*sih
, osl_t
*osh
, uint32 clk
, uint32 delay_val
)
3872 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3874 /* Remember original core before switch to chipc */
3875 origidx
= si_coreidx(sih
);
3876 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3880 SPINWAIT(((R_REG(osh
, &cc
->pmustatus
) & clk
) != clk
), delay_val
);
3882 /* Return to original core */
3883 si_setcoreidx(sih
, origidx
);
3885 return (R_REG(osh
, &cc
->pmustatus
) & clk
);
3889 * Measures the ALP clock frequency in KHz. Returns 0 if not possible.
3890 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
3893 #define EXT_ILP_HZ 32768
3896 BCMATTACHFN(si_pmu_measure_alpclk
)(si_t
*sih
, osl_t
*osh
)
3902 if (sih
->pmurev
< 10)
3905 ASSERT(sih
->cccaps
& CC_CAP_PMU
);
3907 /* Remember original core before switch to chipc */
3908 origidx
= si_coreidx(sih
);
3909 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3912 if (R_REG(osh
, &cc
->pmustatus
) & PST_EXTLPOAVAIL
) {
3913 uint32 ilp_ctr
, alp_hz
;
3915 /* Enable the reg to measure the freq, in case disabled before */
3916 W_REG(osh
, &cc
->pmu_xtalfreq
, 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT
);
3918 /* Delay for well over 4 ILP clocks */
3921 /* Read the latched number of ALP ticks per 4 ILP ticks */
3922 ilp_ctr
= R_REG(osh
, &cc
->pmu_xtalfreq
) & PMU_XTALFREQ_REG_ILPCTR_MASK
;
3924 /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
3925 W_REG(osh
, &cc
->pmu_xtalfreq
, 0);
3927 /* Calculate ALP frequency */
3928 alp_hz
= (ilp_ctr
* EXT_ILP_HZ
) / 4;
3930 /* Round to nearest 100KHz, and at the same time convert to KHz */
3931 alp_khz
= (alp_hz
+ 50000) / 100000 * 100;
3935 /* Return to original core */
3936 si_setcoreidx(sih
, origidx
);
3941 #if !defined(_CFE_) || defined(CFG_WL)
3943 si_pmu_set_4330_plldivs(si_t
*sih
, uint8 dacrate
)
3945 uint32 FVCO
= si_pmu1_pllfvco0(sih
)/1000;
3946 uint32 m1div
, m2div
, m3div
, m4div
, m5div
, m6div
;
3947 uint32 pllc1
, pllc2
;
3949 m2div
= m3div
= m4div
= m6div
= FVCO
/80;
3951 m5div
= FVCO
/dacrate
;
3953 if (CST4330_CHIPMODE_SDIOD(sih
->chipst
))
3957 pllc1
= (m1div
<< PMU1_PLL0_PC1_M1DIV_SHIFT
) | (m2div
<< PMU1_PLL0_PC1_M2DIV_SHIFT
) |
3958 (m3div
<< PMU1_PLL0_PC1_M3DIV_SHIFT
) | (m4div
<< PMU1_PLL0_PC1_M4DIV_SHIFT
);
3959 si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL1
, ~0, pllc1
);
3961 pllc2
= si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL2
, 0, 0);
3962 pllc2
&= ~(PMU1_PLL0_PC2_M5DIV_MASK
| PMU1_PLL0_PC2_M6DIV_MASK
);
3963 pllc2
|= ((m5div
<< PMU1_PLL0_PC2_M5DIV_SHIFT
) | (m6div
<< PMU1_PLL0_PC2_M6DIV_SHIFT
));
3964 si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL2
, ~0, pllc2
);
3966 #endif /* !_CFE_ || CFG_WL */