1/* 2 * Misc utility routines for accessing PMU corerev specific features 3 * of the SiliconBackplane-based Broadcom chips. 4 * 5 * Copyright 2007, Broadcom Corporation 6 * All Rights Reserved. 7 * 8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 12 * $Id: hndpmu.c,v 1.1.1.1 2008/10/15 03:31:34 james26_jang Exp $ 13 */ 14 15#include <typedefs.h> 16#include <bcmdefs.h> 17#include <osl.h> 18#include <bcmutils.h> 19#include <sbutils.h> 20#include <bcmdevs.h> 21#include <sbconfig.h> 22#include <sbchipc.h> 23#include <hndpmu.h> 24 25/* debug/trace */ 26#define PMU_ERROR(args) 27 28#define PMU_MSG(args) 29 30/* PMU & control */ 31/* PMU rev 0 pll control for BCM4328 and BCM5354 */ 32static void sb_pmu0_pllinit0(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal); 33static uint32 sb_pmu0_alpclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc); 34static uint32 sb_pmu0_cpuclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc); 35 36#if defined(BCM4325) || defined(BCM4312) 37/* PMU rev 0 pll control for BCM4325 BCM4329 */ 38static void sb_pmu1_pllinit0(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal); 39static uint32 sb_pmu1_cpuclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc); 40static uint32 sb_pmu1_alpclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc); 41#endif 42 43/* Setup switcher voltage */ 44void 45BCMINITFN(sb_pmu_set_switcher_voltage)(sb_t *sbh, osl_t *osh, 46 uint8 bb_voltage, uint8 rf_voltage) 47{ 48 chipcregs_t *cc; 49 uint origidx; 50 51 ASSERT(sbh->cccaps & CC_CAP_PMU); 52 53 /* Remember original core before switch to chipc */ 54 origidx = sb_coreidx(sbh); 55 cc = sb_setcore(sbh, SB_CC, 0); 56 ASSERT(cc); 57 58 W_REG(osh, &cc->regcontrol_addr, 0x01); 59 W_REG(osh, &cc->regcontrol_data, (uint32)(bb_voltage & 0x1f) << 22); 60 61 W_REG(osh, &cc->regcontrol_addr, 0x00); 62 W_REG(osh, &cc->regcontrol_data, (uint32)(rf_voltage & 0x1f) << 14); 63 64 /* Return to original core */ 65 sb_setcoreidx(sbh, origidx); 66} 67 68void 69sb_pmu_set_ldo_voltage(sb_t *sbh, osl_t *osh, uint8 ldo, uint8 voltage) 70{ 71 uint8 sr_cntl_shift, rc_shift, shift, mask; 72 uint32 addr; 73 74 ASSERT(sbh->cccaps & CC_CAP_PMU); 75 76 switch (sbh->chip) { 77 case BCM4328_CHIP_ID: 78 case BCM5354_CHIP_ID: 79 switch (ldo) { 80 case SET_LDO_VOLTAGE_LDO1: 81 addr = 2; 82 sr_cntl_shift = 8; 83 rc_shift = 17; 84 mask = 0xf; 85 break; 86 case SET_LDO_VOLTAGE_LDO2: 87 addr = 3; 88 sr_cntl_shift = 0; 89 rc_shift = 1; 90 mask = 0xf; 91 break; 92 case SET_LDO_VOLTAGE_LDO3: 93 addr = 3; 94 sr_cntl_shift = 0; 95 rc_shift = 9; 96 mask = 0xf; 97 break; 98 case SET_LDO_VOLTAGE_PAREF: 99 addr = 3; 100 sr_cntl_shift = 0; 101 rc_shift = 17; 102 mask = 0x3f; 103 break; 104 default: 105 ASSERT(FALSE); 106 return; 107 } 108 break; 109#if defined(BCM4312) 110 case BCM4312_CHIP_ID: 111 switch (ldo) { 112 case SET_LDO_VOLTAGE_PAREF: 113 addr = 0; 114 sr_cntl_shift = 0; 115 rc_shift = 21; 116 mask = 0x3f; 117 break; 118 default: 119 ASSERT(FALSE); 120 return; 121 } 122 break; 123#endif /* defined(BCM4312) */ 124 default: 125 ASSERT(FALSE); 126 return; 127 } 128 129 shift = sr_cntl_shift + rc_shift; 130 131 sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr), 132 ~0, addr); 133 sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data), 134 mask << shift, (voltage & mask) << shift); 135} 136 137void 138sb_pmu_paref_ldo_enable(sb_t *sbh, osl_t *osh, bool enable) 139{ 140 uint ldo = 0; 141 142 ASSERT(sbh->cccaps & CC_CAP_PMU); 143 144 switch (sbh->chip) { 145#if defined(BCM4328) 146 case BCM4328_CHIP_ID: 147 ldo = RES4328_PA_REF_LDO; 148 break; 149#endif /* defined(BCM4328) */ 150 case BCM5354_CHIP_ID: 151 ldo = RES5354_PA_REF_LDO; 152 break; 153#if defined(BCM4312) 154 case BCM4312_CHIP_ID: 155 ldo = RES4312_PA_REF_LDO; 156 break; 157#endif /* defined(BCM4312) */ 158 default: 159 return; 160 } 161 162 sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 163 PMURES_BIT(ldo), enable ? PMURES_BIT(ldo) : 0); 164} 165 166uint16 167BCMINITFN(sb_pmu_fast_pwrup_delay)(sb_t *sbh, osl_t *osh) 168{ 169 uint16 delay = PMU_MAX_TRANSITION_DLY; 170 171 ASSERT(sbh->cccaps & CC_CAP_PMU); 172 173 switch (sbh->chip) { 174#if defined(BCM4328) 175 case BCM4328_CHIP_ID: 176 delay = 7000; 177 break; 178#endif /* BCM4328 */ 179 180#if defined(BCM4325) || defined(BCM4312) 181 case BCM4325_CHIP_ID: 182 case BCM4312_CHIP_ID: 183#ifdef BCMQT 184 delay = 70; 185#else 186 delay = 2800; 187#endif 188 break; 189#endif /* BCM4325 || BCM4312 */ 190 191 default: 192 PMU_MSG(("No PMU fast power up delay specified " 193 "for chip %x rev %d, using default %d us\n", 194 sbh->chip, sbh->chiprev, delay)); 195 break; 196 } 197 198 return delay; 199} 200 201uint32 202BCMINITFN(sb_pmu_force_ilp)(sb_t *sbh, osl_t *osh, bool force) 203{ 204 chipcregs_t *cc; 205 uint origidx; 206 uint32 oldpmucontrol; 207 208 ASSERT(sbh->cccaps & CC_CAP_PMU); 209 210 /* Remember original core before switch to chipc */ 211 origidx = sb_coreidx(sbh); 212 cc = sb_setcore(sbh, SB_CC, 0); 213 ASSERT(cc); 214 215 oldpmucontrol = R_REG(osh, &cc->pmucontrol); 216 if (force) 217 W_REG(osh, &cc->pmucontrol, oldpmucontrol & 218 ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); 219 else 220 W_REG(osh, &cc->pmucontrol, oldpmucontrol | 221 (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); 222 223 /* Return to original core */ 224 sb_setcoreidx(sbh, origidx); 225 226 return oldpmucontrol; 227} 228 229/* Setup min/max resources and up/down timers */ 230typedef struct { 231 uint8 resnum; 232 uint16 updown; 233} pmu_res_updown_t; 234 235typedef struct { 236 uint8 resnum; 237 int8 action; /* 0 - set, 1 - add, -1 - remove */ 238 uint32 depend_mask; 239} pmu_res_depend_t; 240 241#if defined(BCM4328) 242static const pmu_res_updown_t BCMINITDATA(bcm4328a0_res_updown)[] = { 243 { RES4328_EXT_SWITCHER_PWM, 0x0101 }, 244 { RES4328_BB_SWITCHER_PWM, 0x1f01 }, 245 { RES4328_BB_SWITCHER_BURST, 0x010f }, 246 { RES4328_BB_EXT_SWITCHER_BURST, 0x0101 }, 247 { RES4328_ILP_REQUEST, 0x0202 }, 248 { RES4328_RADIO_SWITCHER_PWM, 0x0f01 }, 249 { RES4328_RADIO_SWITCHER_BURST, 0x0f01 }, 250 { RES4328_ROM_SWITCH, 0x0101 }, 251 { RES4328_PA_REF_LDO, 0x0f01 }, 252 { RES4328_RADIO_LDO, 0x0f01 }, 253 { RES4328_AFE_LDO, 0x0f01 }, 254 { RES4328_PLL_LDO, 0x0f01 }, 255 { RES4328_BG_FILTBYP, 0x0101 }, 256 { RES4328_TX_FILTBYP, 0x0101 }, 257 { RES4328_RX_FILTBYP, 0x0101 }, 258 { RES4328_XTAL_PU, 0x0101 }, 259 { RES4328_XTAL_EN, 0xa001 }, 260 { RES4328_BB_PLL_FILTBYP, 0x0101 }, 261 { RES4328_RF_PLL_FILTBYP, 0x0101 }, 262 { RES4328_BB_PLL_PU, 0x0701 } 263}; 264 265static const pmu_res_depend_t BCMINITDATA(bcm4328a0_res_depend)[] = { 266 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */ 267 { 268 RES4328_ILP_REQUEST, 0, 269 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | 270 PMURES_BIT(RES4328_BB_SWITCHER_PWM) 271 } 272}; 273#endif /* BCM4328 */ 274 275#if defined(BCM4325) 276#ifdef BCMQT /* for power save on slow QT/small beacon interval */ 277static const pmu_res_updown_t BCMINITDATA(bcm4325a0_res_updown_qt)[] = { 278 { RES4325_HT_AVAIL, 0x0300 }, 279 { RES4325_BBPLL_PWRSW_PU, 0x0101 }, 280 { RES4325_RFPLL_PWRSW_PU, 0x0101 }, 281 { RES4325_ALP_AVAIL, 0x0100 }, 282 { RES4325_XTAL_PU, 0x1000 }, 283 { RES4325_LNLDO1_PU, 0x0800 }, 284 { RES4325_CLDO_CBUCK_PWM, 0x0101 }, 285 { RES4325_CBUCK_PWM, 0x0803 } 286}; 287#else 288static const pmu_res_updown_t BCMINITDATA(bcm4325a0_res_updown)[] = { 289 { RES4325_XTAL_PU, 0x1501 } 290}; 291#endif /* !BCMQT */ 292 293static const pmu_res_depend_t BCMINITDATA(bcm4325a0_res_depend)[] = { 294 /* Adjust HT Avail resource dependencies */ 295 { 296 RES4325_HT_AVAIL, 1, 297 PMURES_BIT(RES4325_RX_PWRSW_PU) | PMURES_BIT(RES4325_TX_PWRSW_PU) | 298 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU) 299 } 300}; 301#endif /* BCM4325 */ 302 303void 304BCMINITFN(sb_pmu_res_init)(sb_t *sbh, osl_t *osh) 305{ 306 chipcregs_t *cc; 307 uint origidx; 308 const pmu_res_updown_t *pmu_res_updown_table = NULL; 309 int pmu_res_updown_table_sz = 0; 310 const pmu_res_depend_t *pmu_res_depend_table = NULL; 311 int pmu_res_depend_table_sz = 0; 312 uint32 min_mask = 0, max_mask = 0; 313 314 ASSERT(sbh->cccaps & CC_CAP_PMU); 315 316 /* Remember original core before switch to chipc */ 317 origidx = sb_coreidx(sbh); 318 cc = sb_setcore(sbh, SB_CC, 0); 319 ASSERT(cc); 320 321 switch (sbh->chip) { 322#if defined(BCM4328) 323 case BCM4328_CHIP_ID: 324 /* Down to ILP request excluding ROM */ 325 min_mask = PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | 326 PMURES_BIT(RES4328_BB_SWITCHER_PWM) | 327 PMURES_BIT(RES4328_XTAL_EN); 328 /* Allow (but don't require) PLL to turn on */ 329 max_mask = 0xfffff; 330 pmu_res_updown_table = bcm4328a0_res_updown; 331 pmu_res_updown_table_sz = ARRAYSIZE(bcm4328a0_res_updown); 332 pmu_res_depend_table = bcm4328a0_res_depend; 333 pmu_res_depend_table_sz = ARRAYSIZE(bcm4328a0_res_depend); 334 break; 335#endif /* BCM4328 */ 336#if defined(BCM4312) 337 case BCM4312_CHIP_ID: 338 /* keep default 339 * min_mask = 0xcbb; max_mask = 0x7ffff; 340 * pmu_res_updown_table_sz = 0; 341 * pmu_res_depend_table_sz = 0; 342 */ 343 break; 344#endif /* BCM4312 */ 345 case BCM5354_CHIP_ID: 346 /* Allow (but don't require) PLL to turn on */ 347 max_mask = 0xfffff; 348 break; 349 350#if defined(BCM4325) 351 case BCM4325_CHIP_ID: 352 /* Leave OTP powered up and power it down later. */ 353 min_mask = 354 PMURES_BIT(RES4325_CBUCK_BURST) | 355 PMURES_BIT(RES4325_LNLDO2_PU); 356 if (((sbh->chipst & CST4325_PMUTOP_2B_MASK) >> 357 CST4325_PMUTOP_2B_SHIFT) == 1) 358 min_mask |= PMURES_BIT(RES4325_CLDO_CBUCK_BURST); 359 /* Allow (but don't require) PLL to turn on */ 360 max_mask = 0x3fffff; 361#ifdef BCMQT 362 pmu_res_updown_table = bcm4325a0_res_updown_qt; 363 pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown_qt); 364#else 365 pmu_res_updown_table = bcm4325a0_res_updown; 366 pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown); 367 pmu_res_depend_table = bcm4325a0_res_depend; 368 pmu_res_depend_table_sz = ARRAYSIZE(bcm4325a0_res_depend); 369#endif 370 break; 371#endif /* BCM4325 */ 372 373 default: 374 break; 375 } 376 377 /* Program up/down timers */ 378 while (pmu_res_updown_table_sz--) { 379 ASSERT(pmu_res_updown_table); 380 W_REG(osh, &cc->res_table_sel, 381 pmu_res_updown_table[pmu_res_updown_table_sz].resnum); 382 W_REG(osh, &cc->res_updn_timer, 383 pmu_res_updown_table[pmu_res_updown_table_sz].updown); 384 } 385 386 /* Program resource dependencies table */ 387 while (pmu_res_depend_table_sz--) { 388 ASSERT(pmu_res_depend_table); 389 W_REG(osh, &cc->res_table_sel, 390 pmu_res_depend_table[pmu_res_depend_table_sz].resnum); 391 switch (pmu_res_depend_table[pmu_res_depend_table_sz].action) { 392 case 0: 393 W_REG(osh, &cc->res_dep_mask, 394 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 395 break; 396 case 1: 397 OR_REG(osh, &cc->res_dep_mask, 398 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 399 break; 400 case -1: 401 AND_REG(osh, &cc->res_dep_mask, 402 ~pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 403 break; 404 default: 405 ASSERT(0); 406 break; 407 } 408 } 409 410 /* program min resource mask */ 411 if (min_mask) { 412 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask)); 413 W_REG(osh, &cc->min_res_mask, min_mask); 414 } 415 /* program max resource mask */ 416 if (max_mask) { 417 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask)); 418 W_REG(osh, &cc->max_res_mask, max_mask); 419 } 420 421 /* Return to original core */ 422 sb_setcoreidx(sbh, origidx); 423} 424 425/* setup pll and query clock speed */ 426typedef struct { 427 uint16 freq; 428 uint8 xf; 429 uint8 wbint; 430 uint32 wbfrac; 431} pmu0_xtaltab0_t; 432 433/* the following table is based on 880Mhz Fvco */ 434#define PMU0_PLL0_FVCO 880000 /* Fvco 880Mhz */ 435static const pmu0_xtaltab0_t BCMINITDATA(pmu0_xtaltab0)[] = { 436 { 12000, 1, 73, 349525 }, 437 { 13000, 2, 67, 725937 }, 438 { 14400, 3, 61, 116508 }, 439 { 15360, 4, 57, 305834 }, 440 { 16200, 5, 54, 336579 }, 441 { 16800, 6, 52, 399457 }, 442 { 19200, 7, 45, 873813 }, 443 { 19800, 8, 44, 466033 }, 444 { 20000, 9, 44, 0 }, 445 { 25000, 10, 70, 419430 }, 446 { 26000, 11, 67, 725937 }, 447 { 30000, 12, 58, 699050 }, 448 { 38400, 13, 45, 873813 }, 449 { 40000, 14, 45, 0 }, 450 { 0, 0, 0, 0 } 451}; 452 453#ifdef BCMUSBDEV 454#define PMU0_XTAL0_DEFAULT 11 455#else 456#define PMU0_XTAL0_DEFAULT 8 457#endif 458 459#if defined(BCM4328) 460#ifdef BCMUSBDEV 461/* 462 * Set new backplane PLL clock frequency 463 */ 464static void 465BCMINITFN(sb_pmu0_sbclk4328)(sb_t *sbh, int freq) 466{ 467 uint32 tmp, oldmax, oldmin, origidx; 468 chipcregs_t *cc; 469 470 /* Remember original core before switch to chipc */ 471 origidx = sb_coreidx(sbh); 472 cc = sb_setcore(sbh, SB_CC, 0); 473 ASSERT(cc); 474 475 /* Set new backplane PLL clock */ 476 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 477 tmp = R_REG(osh, &cc->pllcontrol_data); 478 tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK); 479 tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT; 480 W_REG(osh, &cc->pllcontrol_data, tmp); 481 482 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */ 483 /* Disable PLL */ 484 oldmin = R_REG(osh, &cc->min_res_mask); 485 oldmax = R_REG(osh, &cc->max_res_mask); 486 W_REG(osh, &cc->min_res_mask, oldmin & ~PMURES_BIT(RES4328_BB_PLL_PU)); 487 W_REG(osh, &cc->max_res_mask, oldmax & ~PMURES_BIT(RES4328_BB_PLL_PU)); 488 489 /* It takes over several hundred usec to re-enable the PLL since the 490 * sequencer state machines run on ILP clock. Set delay at 450us to be safe. 491 * 492 * Be sure PLL is powered down first before re-enabling it. 493 */ 494 495 OSL_DELAY(PLL_DELAY); 496 SPINWAIT((R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)), PLL_DELAY*3); 497 498 if (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)) { 499 /* If BB_PLL not powered down yet, new backplane PLL clock 500 * may not take effect. 501 * 502 * Still early during bootup so no serial output here. 503 */ 504 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n")); 505 ASSERT(!(R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU))); 506 } 507 508 /* Enable PLL */ 509 W_REG(osh, &cc->max_res_mask, oldmax); 510 511 /* Return to original core */ 512 sb_setcoreidx(sbh, origidx); 513} 514#endif /* BCMUSBDEV */ 515#endif /* BCM4328 */ 516 517/* Set up PLL registers in the PMU as per the crystal speed. 518 * Uses xtalfreq variable, or passed-in default. 519 */ 520static void 521BCMINITFN(sb_pmu0_pllinit0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal) 522{ 523 uint32 tmp; 524 const pmu0_xtaltab0_t *xt; 525 526 if ((sb_chip(sbh) == BCM5354_CHIP_ID) && (xtal == 0)) { 527 /* 5354 has xtal freq of 25MHz */ 528 xtal = 25000; 529 } 530 531 /* Find the frequency in the table */ 532 for (xt = pmu0_xtaltab0; xt->freq; xt ++) 533 if (xt->freq == xtal) 534 break; 535 if (xt->freq == 0) 536 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; 537 538 PMU_MSG(("XTAL %d (%d)\n", xtal, xt->xf)); 539 540 /* Check current PLL state */ 541 tmp = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 542 PCTL_XTALFREQ_SHIFT; 543 if (tmp == xt->xf) { 544 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 545 (xt->freq / 1000), (xt->freq % 1000))); 546 547#if defined(BCM4328) 548#ifdef BCMUSBDEV 549 if (sbh->chip == BCM4328_CHIP_ID) 550 sb_pmu0_sbclk4328(sbh, PMU0_PLL0_PC0_DIV_ARM_88MHZ); 551#endif 552#endif /* BCM4328 */ 553 return; 554 } 555 556 if (tmp) { 557 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", 558 (xt->freq / 1000), (xt->freq % 1000), 559 (pmu0_xtaltab0[tmp-1].freq / 1000), (pmu0_xtaltab0[tmp-1].freq % 1000))); 560 } else { 561 PMU_MSG(("Programming PLL for %d.%d MHz\n", (xt->freq / 1000), 562 (xt->freq % 1000))); 563 } 564 565 /* Make sure the PLL is off */ 566 switch (sbh->chip) { 567#if defined(BCM4328) 568 case BCM4328_CHIP_ID: 569 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU)); 570 AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU)); 571 break; 572#endif 573 case BCM5354_CHIP_ID: 574 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU)); 575 AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU)); 576 break; 577 default: 578 ASSERT(0); 579 } 580 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL, 581 PMU_MAX_TRANSITION_DLY); 582 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL)); 583 584 PMU_MSG(("Done masking\n")); 585 586 /* Write PDIV in pllcontrol[0] */ 587 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 588 tmp = R_REG(osh, &cc->pllcontrol_data); 589 if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ) 590 tmp |= PMU0_PLL0_PC0_PDIV_MASK; 591 else 592 tmp &= ~PMU0_PLL0_PC0_PDIV_MASK; 593 W_REG(osh, &cc->pllcontrol_data, tmp); 594 595 /* Write WILD in pllcontrol[1] */ 596 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1); 597 tmp = R_REG(osh, &cc->pllcontrol_data); 598 tmp = ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) | 599 (((xt->wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & 600 PMU0_PLL0_PC1_WILD_INT_MASK) | 601 ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) & 602 PMU0_PLL0_PC1_WILD_FRAC_MASK))); 603 if (xt->wbfrac == 0) 604 tmp |= PMU0_PLL0_PC1_STOP_MOD; 605 else 606 tmp &= ~PMU0_PLL0_PC1_STOP_MOD; 607 W_REG(osh, &cc->pllcontrol_data, tmp); 608 609 /* Write WILD in pllcontrol[2] */ 610 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2); 611 tmp = R_REG(osh, &cc->pllcontrol_data); 612 tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) | 613 ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) & 614 PMU0_PLL0_PC2_WILD_INT_MASK)); 615 W_REG(osh, &cc->pllcontrol_data, tmp); 616 617 PMU_MSG(("Done pll\n")); 618 619 /* Write XtalFreq. Set the divisor also. */ 620 tmp = R_REG(osh, &cc->pmucontrol); 621 tmp = ((tmp & ~PCTL_ILP_DIV_MASK) | 622 (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & 623 PCTL_ILP_DIV_MASK)); 624 tmp = ((tmp & ~PCTL_XTALFREQ_MASK) | 625 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK)); 626 W_REG(osh, &cc->pmucontrol, tmp); 627} 628 629static uint32 630BCMINITFN(sb_pmu0_alpclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc) 631{ 632 const pmu0_xtaltab0_t *xt; 633 uint32 xf; 634 635 /* Find the frequency in the table */ 636 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 637 PCTL_XTALFREQ_SHIFT; 638 for (xt = pmu0_xtaltab0; xt->freq; xt++) 639 if (xt->xf == xf) 640 break; 641 if (xt->freq == 0) 642 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; 643 644 return xt->freq * 1000; 645} 646 647static uint32 648BCMINITFN(sb_pmu0_cpuclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc) 649{ 650 const pmu0_xtaltab0_t *xt; 651 uint32 xf, tmp, divarm; 652 653 if (sb_chip(sbh) == BCM5354_CHIP_ID) { 654 /* 5354 gets sb clock of 120MHz from main pll */ 655 //return 120000000; 656 return 100000000; 657 } 658 659 /* Find the xtal frequency in the table */ 660 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 661 PCTL_XTALFREQ_SHIFT; 662 for (xt = pmu0_xtaltab0; xt->freq; xt++) 663 if (xt->xf == xf) 664 break; 665 if (xt->freq == 0) 666 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; 667 668 /* Read divarm from pllcontrol[0] */ 669 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 670 tmp = R_REG(osh, &cc->pllcontrol_data); 671 divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT; 672 673 674 /* Return ARM/SB clock */ 675 return PMU0_PLL0_FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000; 676} 677 678/* PMU corerev 1 pll programming for BCM4325 */ 679#if defined(BCM4325) || defined(BCM4312) 680/* setup pll and query clock speed */ 681typedef struct { 682 uint16 fref; 683 uint8 xf; 684 uint8 p1div; 685 uint8 p2div; 686 uint8 ndiv_int; 687 uint32 ndiv_frac; 688} pmu1_xtaltab0_t; 689 690/* the following table is based on 880Mhz Fvco */ 691#define PMU1_PLL0_FVCO 880000 /* Fvco 880Mhz */ 692static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0)[] = { 693 {12000, 1, 3, 22, 0x9, 0xFFFFEF}, 694 {13000, 2, 1, 6, 0xb, 0x483483}, 695 {14400, 3, 1, 10, 0xa, 0x1C71C7}, 696 {15360, 4, 1, 5, 0xb, 0x755555}, 697 {16200, 5, 1, 10, 0x5, 0x6E9E06}, 698 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, 699 {19200, 7, 1, 9, 0x5, 0x17B425}, 700 {19800, 8, 1, 11, 0x4, 0xA57EB}, 701 {20000, 9, 1, 11, 0x4, 0x0}, 702 {24000, 10, 3, 11, 0xa, 0x0}, 703 {25000, 11, 5, 16, 0xb, 0x0}, 704 {26000, 12, 1, 2, 0x10, 0xEC4EC4}, 705 {30000, 13, 3, 8, 0xb, 0x0}, 706 {38400, 14, 1, 5, 0x4, 0x955555}, 707 {40000, 15, 1, 2, 0xb, 0}, 708 {0, 0, 0, 0, 0, 0} 709}; 710 711/* Default to 15360Khz crystal */ 712#define PMU1_XTAL0_DEFAULT 3 713 714static uint32 715BCMINITFN(sb_pmu1_alpclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc) 716{ 717 const pmu1_xtaltab0_t *xt; 718 uint32 xf; 719 720 /* Find the frequency in the table */ 721 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 722 PCTL_XTALFREQ_SHIFT; 723 for (xt = pmu1_xtaltab0; xt->fref; xt++) 724 if (xt->xf == xf) 725 break; 726 if (xt->fref == 0) 727 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT]; 728 729 return xt->fref * 1000; 730} 731 732/* Set up PLL registers in the PMU as per the crystal speed. 733 * Uses xtalfreq variable, or passed-in default. 734 */ 735static void 736BCMINITFN(sb_pmu1_pllinit0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal) 737{ 738 const pmu1_xtaltab0_t *xt; 739 uint32 tmp; 740 uint32 buf_strength = 0; 741 742 /* 4312: assume default works */ 743 if (sbh->chip == BCM4312_CHIP_ID) 744 return; 745 746 /* Find the frequency in the table */ 747 for (xt = pmu1_xtaltab0; xt->fref; xt++) 748 if (xt->fref == xtal) 749 break; 750 if (xt->fref == 0) 751 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT]; 752 753 PMU_MSG(("XTAL %d (%d)\n", xtal, xt->xf)); 754 755 /* Check current PLL state */ 756 if (((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 757 PCTL_XTALFREQ_SHIFT) == xt->xf) { 758 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 759 (xt->fref / 1000), (xt->fref % 1000))); 760 return; 761 } 762 763 PMU_MSG(("Programming PLL for %d.%d MHz\n", (xt->fref / 1000), 764 (xt->fref % 1000))); 765 766 /* Make sure the PLL is off */ 767 switch (sbh->chip) { 768#if defined(BCM4325) 769 case BCM4325_CHIP_ID: 770 AND_REG(osh, &cc->min_res_mask, 771 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL))); 772 AND_REG(osh, &cc->max_res_mask, 773 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL))); 774 775 /* Change the BBPLL drive strength to 2 for all channels */ 776 buf_strength = 0x222222; 777 break; 778#endif 779 default: 780 ASSERT(0); 781 } 782 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 783 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 784 785 PMU_MSG(("Done masking\n")); 786 787 /* Write p1div and p2div to pllcontrol[0] */ 788 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 789 tmp = R_REG(osh, &cc->pllcontrol_data) & 790 ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK); 791 tmp |= ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | 792 ((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK); 793 W_REG(osh, &cc->pllcontrol_data, tmp); 794 795 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ 796 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 797 tmp = R_REG(osh, &cc->pllcontrol_data) & 798 ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK); 799 tmp |= ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK) | 800 ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK); 801 W_REG(osh, &cc->pllcontrol_data, tmp); 802 803 /* Write ndiv_frac to pllcontrol[3] */ 804 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 805 tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; 806 tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) & 807 PMU1_PLL0_PC3_NDIV_FRAC_MASK); 808 W_REG(osh, &cc->pllcontrol_data, tmp); 809 810 if (buf_strength) { 811 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength)); 812 813 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 814 tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; 815 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT); 816 W_REG(osh, &cc->pllcontrol_data, tmp); 817 } 818 819 PMU_MSG(("Done pll\n")); 820 821 /* Write XtalFreq. Set the divisor also. */ 822 tmp = R_REG(osh, &cc->pmucontrol) & 823 ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); 824 tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & 825 PCTL_ILP_DIV_MASK) | 826 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); 827 W_REG(osh, &cc->pmucontrol, tmp); 828} 829 830 831static uint32 832BCMINITFN(sb_pmu1_cpuclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc) 833{ 834 const pmu1_xtaltab0_t *xt; 835 uint32 xf, tmp, m1div; 836 837 /* Find the xtal frequency in the table */ 838 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 839 PCTL_XTALFREQ_SHIFT; 840 for (xt = pmu1_xtaltab0; xt->fref; xt++) 841 if (xt->xf == xf) 842 break; 843 if (xt->fref == 0) 844 xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT]; 845 846 /* Read m1div from pllcontrol[1] */ 847 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 848 tmp = R_REG(osh, &cc->pllcontrol_data); 849 m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; 850 851 852 /* Return ARM/SB clock */ 853 return PMU1_PLL0_FVCO / m1div * 1000; 854} 855#endif 856 857void 858BCMINITFN(sb_pmu_pll_init)(sb_t *sbh, osl_t *osh, uint xtalfreq) 859{ 860 chipcregs_t *cc; 861 uint origidx; 862 863 ASSERT(sbh->cccaps & CC_CAP_PMU); 864 865 /* Remember original core before switch to chipc */ 866 origidx = sb_coreidx(sbh); 867 cc = sb_setcore(sbh, SB_CC, 0); 868 ASSERT(cc); 869 870 switch (sbh->chip) { 871#if defined(BCM4328) 872 case BCM4328_CHIP_ID: 873 sb_pmu0_pllinit0(sbh, osh, cc, xtalfreq); 874 break; 875#endif 876 case BCM5354_CHIP_ID: 877 sb_pmu0_pllinit0(sbh, osh, cc, xtalfreq); 878 break; 879#if defined(BCM4325) 880 case BCM4325_CHIP_ID: 881 sb_pmu1_pllinit0(sbh, osh, cc, xtalfreq); 882 break; 883#endif 884#if defined(BCM4312) 885 case BCM4312_CHIP_ID: 886 sb_pmu1_pllinit0(sbh, osh, cc, xtalfreq); 887 break; 888#endif 889 default: 890 PMU_MSG(("No PLL init done for chip %x rev %d pmurev %d\n", 891 sbh->chip, sbh->chiprev, sbh->pmurev)); 892 break; 893 } 894 895 /* Return to original core */ 896 sb_setcoreidx(sbh, origidx); 897} 898 899uint32 900BCMINITFN(sb_pmu_alp_clock)(sb_t *sbh, osl_t *osh) 901{ 902 chipcregs_t *cc; 903 uint origidx; 904 uint32 clock = ALP_CLOCK; 905 906 ASSERT(sbh->cccaps & CC_CAP_PMU); 907 908 /* Remember original core before switch to chipc */ 909 origidx = sb_coreidx(sbh); 910 cc = sb_setcore(sbh, SB_CC, 0); 911 ASSERT(cc); 912 913 switch (sbh->chip) { 914#if defined(BCM4328) 915 case BCM4328_CHIP_ID: 916 clock = sb_pmu0_alpclk0(sbh, osh, cc); 917 break; 918#endif 919 case BCM5354_CHIP_ID: 920 clock = sb_pmu0_alpclk0(sbh, osh, cc); 921 break; 922#if defined(BCM4325) 923 case BCM4325_CHIP_ID: 924 clock = sb_pmu1_alpclk0(sbh, osh, cc); 925 break; 926#endif 927#if defined(BCM4312) 928 case BCM4312_CHIP_ID: 929 clock = sb_pmu1_alpclk0(sbh, osh, cc); 930 /* always 20Mhz */ 931 clock = 20000 * 1000; 932 break; 933#endif 934 default: 935 PMU_MSG(("No ALP clock specified " 936 "for chip %x rev %d pmurev %d, using default %d Hz\n", 937 sbh->chip, sbh->chiprev, sbh->pmurev, clock)); 938 break; 939 } 940 941 /* Return to original core */ 942 sb_setcoreidx(sbh, origidx); 943 return clock; 944} 945 946uint 947BCMINITFN(sb_pmu_cpu_clock)(sb_t *sbh, osl_t *osh) 948{ 949 chipcregs_t *cc; 950 uint origidx; 951 uint32 clock = HT_CLOCK; 952 953 ASSERT(sbh->cccaps & CC_CAP_PMU); 954 955 /* Remember original core before switch to chipc */ 956 origidx = sb_coreidx(sbh); 957 cc = sb_setcore(sbh, SB_CC, 0); 958 ASSERT(cc); 959 960 switch (sbh->chip) { 961#if defined(BCM4328) 962 case BCM4328_CHIP_ID: 963 clock = sb_pmu0_cpuclk0(sbh, osh, cc); 964 break; 965#endif 966 case BCM5354_CHIP_ID: 967 clock = sb_pmu0_cpuclk0(sbh, osh, cc); 968 break; 969#if defined(BCM4325) 970 case BCM4325_CHIP_ID: 971 clock = sb_pmu1_cpuclk0(sbh, osh, cc); 972 break; 973#endif 974#if defined(BCM4312) 975 case BCM4312_CHIP_ID: 976 clock = sb_pmu1_cpuclk0(sbh, osh, cc); 977 break; 978#endif 979 default: 980 PMU_MSG(("No CPU clock specified " 981 "for chip %x rev %d pmurev %d, using default %d Hz\n", 982 sbh->chip, sbh->chiprev, sbh->pmurev, clock)); 983 break; 984 } 985 986 /* Return to original core */ 987 sb_setcoreidx(sbh, origidx); 988 return clock; 989} 990 991void 992BCMINITFN(sb_pmu_init)(sb_t *sbh, osl_t *osh) 993{ 994 chipcregs_t *cc; 995 uint origidx; 996 997 ASSERT(sbh->cccaps & CC_CAP_PMU); 998 999 /* Remember original core before switch to chipc */ 1000 origidx = sb_coreidx(sbh); 1001 cc = sb_setcore(sbh, SB_CC, 0); 1002 ASSERT(cc); 1003 1004 if (sbh->pmurev >= 1) { 1005#if defined(BCM4325) 1006 if (sbh->chip == BCM4325_CHIP_ID && sbh->chiprev <= 1) 1007 AND_REG(osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); 1008 else 1009#endif /* BCM4325 */ 1010 OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT); 1011 } 1012 1013 /* Return to original core */ 1014 sb_setcoreidx(sbh, origidx); 1015} 1016 1017void 1018BCMINITFN(sb_pmu_otp_power)(sb_t *sbh, osl_t *osh, bool on) 1019{ 1020 chipcregs_t *cc; 1021 uint origidx; 1022 1023 ASSERT(sbh->cccaps & CC_CAP_PMU); 1024 1025 /* Remember original core before switch to chipc */ 1026 origidx = sb_coreidx(sbh); 1027 cc = sb_setcore(sbh, SB_CC, 0); 1028 ASSERT(cc); 1029 1030 switch (sbh->chip) { 1031#if defined(BCM4325) 1032 case BCM4325_CHIP_ID: 1033 if (on) { 1034 OR_REG(osh, &cc->min_res_mask, PMURES_BIT(RES4325_LNLDO2_PU)); 1035 if (sbh->boardflags & BFL_BUCKBOOST) 1036 AND_REG(osh, &cc->min_res_mask, 1037 ~PMURES_BIT(RES4325_BUCK_BOOST_PWM)); 1038 OSL_DELAY(500); 1039 } 1040 else { 1041 if (sbh->boardflags & BFL_BUCKBOOST) 1042 OR_REG(osh, &cc->min_res_mask, PMURES_BIT(RES4325_BUCK_BOOST_PWM)); 1043 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES4325_LNLDO2_PU)); 1044 } 1045 break; 1046#endif /* BCM4325 */ 1047 default: 1048 break; 1049 } 1050 1051 /* Return to original core */ 1052 sb_setcoreidx(sbh, origidx); 1053} 1054 1055void 1056sb_pmu_rcal(sb_t *sbh, osl_t *osh) 1057{ 1058 chipcregs_t *cc; 1059 uint origidx; 1060 1061 ASSERT(sbh->cccaps & CC_CAP_PMU); 1062 1063 /* Remember original core before switch to chipc */ 1064 origidx = sb_coreidx(sbh); 1065 cc = sb_setcore(sbh, SB_CC, 0); 1066 ASSERT(cc); 1067 1068 switch (sbh->chip) { 1069#if defined(BCM4325) 1070 case BCM4325_CHIP_ID: 1071 { 1072 uint8 rcal_code; 1073 uint32 val; 1074 1075 /* Kick RCal */ 1076 W_REG(osh, &cc->chipcontrol_addr, 1); 1077 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 1078 OR_REG(osh, &cc->chipcontrol_data, 0x04); 1079 1080 /* Wait for completion */ 1081 SPINWAIT(0 == (R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000); 1082 ASSERT(R_REG(osh, &cc->chipstatus) & 0x08); 1083 1084 /* Drop the LSB to convert from 5 bit code to 4 bit code */ 1085 rcal_code = (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f; 1086 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", 1087 R_REG(osh, &cc->chipstatus), rcal_code)); 1088 1089 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 1090 W_REG(osh, &cc->regcontrol_addr, 0); 1091 val = R_REG(osh, &cc->regcontrol_data) & ~((uint32)0x07 << 29); 1092 val |= (uint32)(rcal_code & 0x07) << 29; 1093 W_REG(osh, &cc->regcontrol_data, val); 1094 W_REG(osh, &cc->regcontrol_addr, 1); 1095 val = R_REG(osh, &cc->regcontrol_data) & ~(uint32)0x01; 1096 val |= (uint32)((rcal_code >> 3) & 0x01); 1097 W_REG(osh, &cc->regcontrol_data, val); 1098 1099 /* Write RCal code into pmu_chip_ctrl[33:30] */ 1100 W_REG(osh, &cc->chipcontrol_addr, 0); 1101 val = R_REG(osh, &cc->chipcontrol_data) & ~((uint32)0x03 << 30); 1102 val |= (uint32)(rcal_code & 0x03) << 30; 1103 W_REG(osh, &cc->chipcontrol_data, val); 1104 W_REG(osh, &cc->chipcontrol_addr, 1); 1105 val = R_REG(osh, &cc->chipcontrol_data) & ~(uint32)0x03; 1106 val |= (uint32)((rcal_code >> 2) & 0x03); 1107 W_REG(osh, &cc->chipcontrol_data, val); 1108 1109 /* Set override in pmu_chip_ctrl[29] */ 1110 W_REG(osh, &cc->chipcontrol_addr, 0); 1111 OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29)); 1112 1113 /* Power off RCal block */ 1114 W_REG(osh, &cc->chipcontrol_addr, 1); 1115 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 1116 1117 break; 1118 } 1119#endif /* BCM4325 */ 1120 default: 1121 break; 1122 } 1123 1124 /* Return to original core */ 1125 sb_setcoreidx(sbh, origidx); 1126} 1127