1/* 2 * Misc utility routines for accessing PMU corerev specific features 3 * of the SiliconBackplane-based Broadcom chips. 4 * 5 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 6 * 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. 10 * 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. 18 * 19 * $Id: hndpmu.c,v 1.234.2.35 2011-02-11 21:35:40 Exp $ 20 */ 21 22#include <typedefs.h> 23#include <bcmdefs.h> 24#include <osl.h> 25#include <bcmutils.h> 26#include <siutils.h> 27#include <bcmdevs.h> 28#include <hndsoc.h> 29#include <sbchipc.h> 30#include <hndpmu.h> 31 32#define PMU_ERROR(args) 33 34#define PMU_MSG(args) 35 36/* To check in verbose debugging messages not intended 37 * to be on except on private builds. 38 */ 39#define PMU_NONE(args) 40 41/* PLL controls/clocks */ 42static void si_pmu0_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal); 43static uint32 si_pmu0_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 44#if !defined(_CFE_) || defined(CFG_WL) 45static uint32 si_pmu0_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 46static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal); 47static uint32 si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 48static uint32 si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 49 50/* PMU resources */ 51static bool si_pmu_res_depfltr_bb(si_t *sih); 52static bool si_pmu_res_depfltr_ncb(si_t *sih); 53static bool si_pmu_res_depfltr_paldo(si_t *sih); 54static bool si_pmu_res_depfltr_npaldo(si_t *sih); 55static uint32 si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs, bool all); 56static uint si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 rsrc); 57static void si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax); 58static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, uint8 spuravoid); 59 60void si_pmu_set_4330_plldivs(si_t *sih, uint8 dacrate); 61#endif /* !_CFE_ || CFG_WL */ 62 63/* FVCO frequency */ 64#define FVCO_880 880000 /* 880MHz */ 65#define FVCO_1760 1760000 /* 1760MHz */ 66#define FVCO_1440 1440000 /* 1440MHz */ 67#define FVCO_960 960000 /* 960MHz */ 68 69/* Read/write a chipcontrol reg */ 70uint32 71si_pmu_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 72{ 73 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr), ~0, reg); 74 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_data), mask, val); 75} 76 77/* Read/write a regcontrol reg */ 78uint32 79si_pmu_regcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 80{ 81 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr), ~0, reg); 82 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data), mask, val); 83} 84 85/* Read/write a pllcontrol reg */ 86uint32 87si_pmu_pllcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 88{ 89 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pllcontrol_addr), ~0, reg); 90 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pllcontrol_data), mask, val); 91} 92 93/* PMU PLL update */ 94void 95si_pmu_pllupd(si_t *sih) 96{ 97 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmucontrol), 98 PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); 99} 100 101/* PMU PLL reset */ 102void 103si_pmu_pllreset(si_t *sih) 104{ 105 uint32 res_mask = 0; 106 chipcregs_t *cc; 107 uint origidx; 108 109 /* Remember original core before switch to chipc */ 110 origidx = si_coreidx(sih); 111 cc = si_setcoreidx(sih, SI_CC_IDX); 112 ASSERT(cc != NULL); 113 114 res_mask = PMURES_BIT(RES4330_BBPLL_PWRSW_PU) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL) | 115 PMURES_BIT(RES4330_HT_AVAIL); 116 117 AND_REG(si_osh(sih), &cc->min_res_mask, ~(res_mask)); 118 AND_REG(si_osh(sih), &cc->max_res_mask, ~(res_mask)); 119 OR_REG(si_osh(sih), &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 120 OR_REG(si_osh(sih), &cc->max_res_mask, res_mask); 121 122 /* Return to original core */ 123 si_setcoreidx(sih, origidx); 124} 125 126/* Setup switcher voltage */ 127void 128BCMATTACHFN(si_pmu_set_switcher_voltage)(si_t *sih, osl_t *osh, 129 uint8 bb_voltage, uint8 rf_voltage) 130{ 131 chipcregs_t *cc; 132 uint origidx; 133 134 ASSERT(sih->cccaps & CC_CAP_PMU); 135 136 /* Remember original core before switch to chipc */ 137 origidx = si_coreidx(sih); 138 cc = si_setcoreidx(sih, SI_CC_IDX); 139 ASSERT(cc != NULL); 140 141 W_REG(osh, &cc->regcontrol_addr, 0x01); 142 W_REG(osh, &cc->regcontrol_data, (uint32)(bb_voltage & 0x1f) << 22); 143 144 W_REG(osh, &cc->regcontrol_addr, 0x00); 145 W_REG(osh, &cc->regcontrol_data, (uint32)(rf_voltage & 0x1f) << 14); 146 147 /* Return to original core */ 148 si_setcoreidx(sih, origidx); 149} 150 151void 152BCMATTACHFN(si_pmu_set_ldo_voltage)(si_t *sih, osl_t *osh, uint8 ldo, uint8 voltage) 153{ 154 uint8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; 155 uint8 addr = 0; 156 157 ASSERT(sih->cccaps & CC_CAP_PMU); 158 159 switch (CHIPID(sih->chip)) { 160 case BCM4328_CHIP_ID: 161 case BCM5354_CHIP_ID: 162 switch (ldo) { 163 case SET_LDO_VOLTAGE_LDO1: 164 addr = 2; 165 sr_cntl_shift = 8; 166 rc_shift = 17; 167 mask = 0xf; 168 break; 169 case SET_LDO_VOLTAGE_LDO2: 170 addr = 3; 171 rc_shift = 1; 172 mask = 0xf; 173 break; 174 case SET_LDO_VOLTAGE_LDO3: 175 addr = 3; 176 rc_shift = 9; 177 mask = 0xf; 178 break; 179 case SET_LDO_VOLTAGE_PAREF: 180 addr = 3; 181 rc_shift = 17; 182 mask = 0x3f; 183 break; 184 default: 185 ASSERT(FALSE); 186 return; 187 } 188 break; 189 case BCM4312_CHIP_ID: 190 switch (ldo) { 191 case SET_LDO_VOLTAGE_PAREF: 192 addr = 0; 193 rc_shift = 21; 194 mask = 0x3f; 195 break; 196 default: 197 ASSERT(FALSE); 198 return; 199 } 200 break; 201 case BCM4325_CHIP_ID: 202 switch (ldo) { 203 case SET_LDO_VOLTAGE_CLDO_PWM: 204 addr = 5; 205 rc_shift = 9; 206 mask = 0xf; 207 break; 208 case SET_LDO_VOLTAGE_CLDO_BURST: 209 addr = 5; 210 rc_shift = 13; 211 mask = 0xf; 212 break; 213 case SET_LDO_VOLTAGE_CBUCK_PWM: 214 addr = 3; 215 rc_shift = 20; 216 mask = 0x1f; 217 /* Bit 116 & 119 are inverted in CLB for opt 2b */ 218 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> 219 CST4325_PMUTOP_2B_SHIFT) == 1) 220 voltage ^= 0x9; 221 break; 222 case SET_LDO_VOLTAGE_CBUCK_BURST: 223 addr = 3; 224 rc_shift = 25; 225 mask = 0x1f; 226 /* Bit 121 & 124 are inverted in CLB for opt 2b */ 227 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> 228 CST4325_PMUTOP_2B_SHIFT) == 1) 229 voltage ^= 0x9; 230 break; 231 case SET_LDO_VOLTAGE_LNLDO1: 232 addr = 5; 233 rc_shift = 17; 234 mask = 0x1f; 235 break; 236 case SET_LDO_VOLTAGE_LNLDO2_SEL: 237 addr = 6; 238 rc_shift = 0; 239 mask = 0x1; 240 break; 241 default: 242 ASSERT(FALSE); 243 return; 244 } 245 break; 246 case BCM4336_CHIP_ID: 247 switch (ldo) { 248 case SET_LDO_VOLTAGE_CLDO_PWM: 249 addr = 4; 250 rc_shift = 1; 251 mask = 0xf; 252 break; 253 case SET_LDO_VOLTAGE_CLDO_BURST: 254 addr = 4; 255 rc_shift = 5; 256 mask = 0xf; 257 break; 258 case SET_LDO_VOLTAGE_LNLDO1: 259 addr = 4; 260 rc_shift = 17; 261 mask = 0xf; 262 break; 263 default: 264 ASSERT(FALSE); 265 return; 266 } 267 break; 268 case BCM4330_CHIP_ID: 269 switch (ldo) { 270 case SET_LDO_VOLTAGE_CBUCK_PWM: 271 addr = 3; 272 rc_shift = 0; 273 mask = 0x1f; 274 break; 275 default: 276 ASSERT(FALSE); 277 break; 278 } 279 break; 280 case BCM4331_CHIP_ID: 281 switch (ldo) { 282 case SET_LDO_VOLTAGE_PAREF: 283 addr = 1; 284 rc_shift = 0; 285 mask = 0xf; 286 break; 287 default: 288 ASSERT(FALSE); 289 break; 290 } 291 break; 292 default: 293 ASSERT(FALSE); 294 return; 295 } 296 297 shift = sr_cntl_shift + rc_shift; 298 299 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr), 300 ~0, addr); 301 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data), 302 mask << shift, (voltage & mask) << shift); 303} 304 305void 306si_pmu_paref_ldo_enable(si_t *sih, osl_t *osh, bool enable) 307{ 308 uint ldo = 0; 309 310 ASSERT(sih->cccaps & CC_CAP_PMU); 311 312 switch (CHIPID(sih->chip)) { 313 case BCM4328_CHIP_ID: 314 ldo = RES4328_PA_REF_LDO; 315 break; 316 case BCM5354_CHIP_ID: 317 ldo = RES5354_PA_REF_LDO; 318 break; 319 case BCM4312_CHIP_ID: 320 ldo = RES4312_PA_REF_LDO; 321 break; 322 default: 323 return; 324 } 325 326 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 327 PMURES_BIT(ldo), enable ? PMURES_BIT(ldo) : 0); 328} 329 330#if !defined(_CFE_) || defined(CFG_WL) 331/* d11 slow to fast clock transition time in slow clock cycles */ 332#define D11SCC_SLOW2FAST_TRANSITION 2 333 334uint16 335BCMINITFN(si_pmu_fast_pwrup_delay)(si_t *sih, osl_t *osh) 336{ 337 uint delay = PMU_MAX_TRANSITION_DLY; 338 chipcregs_t *cc; 339 uint origidx; 340 341 ASSERT(sih->cccaps & CC_CAP_PMU); 342 343 /* Remember original core before switch to chipc */ 344 origidx = si_coreidx(sih); 345 cc = si_setcoreidx(sih, SI_CC_IDX); 346 ASSERT(cc != NULL); 347 348 switch (CHIPID(sih->chip)) { 349 case BCM4312_CHIP_ID: 350 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 351 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 352 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43420_CHIP_ID: 353 case BCM43421_CHIP_ID: 354 case BCM43226_CHIP_ID: 355 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 356 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: 357 case BCM4331_CHIP_ID: 358 case BCM43431_CHIP_ID: 359 case BCM43227_CHIP_ID: 360 case BCM43228_CHIP_ID: 361 case BCM43428_CHIP_ID: 362 case BCM6362_CHIP_ID: 363 case BCM4342_CHIP_ID: 364 case BCM4313_CHIP_ID: 365 delay = ISSIM_ENAB(sih) ? 70 : 3700; 366 break; 367 case BCM4328_CHIP_ID: 368 delay = 7000; 369 break; 370 case BCM4325_CHIP_ID: 371 if (ISSIM_ENAB(sih)) 372 delay = 70; 373 else { 374 uint32 ilp = si_ilp_clock(sih); 375 delay = (si_pmu_res_uptime(sih, osh, cc, RES4325_HT_AVAIL) + 376 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 377 delay = (11 * delay) / 10; 378 } 379 break; 380 case BCM4329_CHIP_ID: 381 if (ISSIM_ENAB(sih)) 382 delay = 70; 383 else { 384 uint32 ilp = si_ilp_clock(sih); 385 delay = (si_pmu_res_uptime(sih, osh, cc, RES4329_HT_AVAIL) + 386 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 387 delay = (11 * delay) / 10; 388 } 389 break; 390 case BCM4315_CHIP_ID: 391 if (ISSIM_ENAB(sih)) 392 delay = 70; 393 else { 394 uint32 ilp = si_ilp_clock(sih); 395 delay = (si_pmu_res_uptime(sih, osh, cc, RES4315_HT_AVAIL) + 396 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 397 delay = (11 * delay) / 10; 398 } 399 break; 400 case BCM4319_CHIP_ID: 401 if (ISSIM_ENAB(sih)) 402 delay = 70; 403 else { 404#ifdef BCMUSBDEV 405 /* For USB HT is always available, even durring IEEE PS, 406 * so need minimal delay 407 */ 408 delay = 100; 409#else /* BCMUSBDEV */ 410 /* For SDIO, total delay in getting HT available */ 411 /* Adjusted for uptime XTAL=672us, HTAVail=128us */ 412 uint32 ilp = si_ilp_clock(sih); 413 delay = si_pmu_res_uptime(sih, osh, cc, RES4319_HT_AVAIL); 414 PMU_MSG(("si_ilp_clock (Hz): %u delay (ilp clks): %u\n", ilp, delay)); 415 delay = (delay + D11SCC_SLOW2FAST_TRANSITION) * (1000000 / ilp); 416 PMU_MSG(("delay (us): %u\n", delay)); 417 delay = (11 * delay) / 10; 418 PMU_MSG(("delay (us): %u\n", delay)); 419 /* VDDIO_RF por delay = 3.4ms */ 420 if (delay < 3400) delay = 3400; 421#endif /* BCMUSBDEV */ 422 } 423 break; 424 case BCM4336_CHIP_ID: 425 if (ISSIM_ENAB(sih)) 426 delay = 70; 427 else { 428 uint32 ilp = si_ilp_clock(sih); 429 delay = (si_pmu_res_uptime(sih, osh, cc, RES4336_HT_AVAIL) + 430 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 431 delay = (11 * delay) / 10; 432 } 433 break; 434 case BCM4330_CHIP_ID: 435 if (ISSIM_ENAB(sih)) 436 delay = 70; 437 else { 438 uint32 ilp = si_ilp_clock(sih); 439 delay = (si_pmu_res_uptime(sih, osh, cc, RES4330_HT_AVAIL) + 440 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 441 delay = (11 * delay) / 10; 442 } 443 break; 444 default: 445 break; 446 } 447 448 /* PMU_MSG(("si_pmu_fast_pwrup_delay: chip %s rev %d delay %d\n", 449 * bcm_chipname(sih->chip, chn, 8), sih->chiprev, delay)); 450 */ 451 452 /* Return to original core */ 453 si_setcoreidx(sih, origidx); 454 455 return (uint16)delay; 456} 457#endif /* !_CFE_ || CFG_WL */ 458 459uint32 460BCMATTACHFN(si_pmu_force_ilp)(si_t *sih, osl_t *osh, bool force) 461{ 462 chipcregs_t *cc; 463 uint origidx; 464 uint32 oldpmucontrol; 465 466 ASSERT(sih->cccaps & CC_CAP_PMU); 467 468 /* Remember original core before switch to chipc */ 469 origidx = si_coreidx(sih); 470 cc = si_setcoreidx(sih, SI_CC_IDX); 471 ASSERT(cc != NULL); 472 473 oldpmucontrol = R_REG(osh, &cc->pmucontrol); 474 if (force) 475 W_REG(osh, &cc->pmucontrol, oldpmucontrol & 476 ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); 477 else 478 W_REG(osh, &cc->pmucontrol, oldpmucontrol | 479 (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); 480 481 /* Return to original core */ 482 si_setcoreidx(sih, origidx); 483 484 return oldpmucontrol; 485} 486 487/* Setup resource up/down timers */ 488typedef struct { 489 uint8 resnum; 490 uint16 updown; 491} pmu_res_updown_t; 492 493/* Change resource dependancies masks */ 494typedef struct { 495 uint32 res_mask; /* resources (chip specific) */ 496 int8 action; /* action */ 497 uint32 depend_mask; /* changes to the dependancies mask */ 498 bool (*filter)(si_t *sih); /* action is taken when filter is NULL or return TRUE */ 499} pmu_res_depend_t; 500 501/* Resource dependancies mask change action */ 502#define RES_DEPEND_SET 0 /* Override the dependancies mask */ 503#define RES_DEPEND_ADD 1 /* Add to the dependancies mask */ 504#define RES_DEPEND_REMOVE -1 /* Remove from the dependancies mask */ 505 506#if !defined(_CFE_) || defined(CFG_WL) 507static const pmu_res_updown_t BCMATTACHDATA(bcm4328a0_res_updown)[] = { 508 { RES4328_EXT_SWITCHER_PWM, 0x0101 }, 509 { RES4328_BB_SWITCHER_PWM, 0x1f01 }, 510 { RES4328_BB_SWITCHER_BURST, 0x010f }, 511 { RES4328_BB_EXT_SWITCHER_BURST, 0x0101 }, 512 { RES4328_ILP_REQUEST, 0x0202 }, 513 { RES4328_RADIO_SWITCHER_PWM, 0x0f01 }, 514 { RES4328_RADIO_SWITCHER_BURST, 0x0f01 }, 515 { RES4328_ROM_SWITCH, 0x0101 }, 516 { RES4328_PA_REF_LDO, 0x0f01 }, 517 { RES4328_RADIO_LDO, 0x0f01 }, 518 { RES4328_AFE_LDO, 0x0f01 }, 519 { RES4328_PLL_LDO, 0x0f01 }, 520 { RES4328_BG_FILTBYP, 0x0101 }, 521 { RES4328_TX_FILTBYP, 0x0101 }, 522 { RES4328_RX_FILTBYP, 0x0101 }, 523 { RES4328_XTAL_PU, 0x0101 }, 524 { RES4328_XTAL_EN, 0xa001 }, 525 { RES4328_BB_PLL_FILTBYP, 0x0101 }, 526 { RES4328_RF_PLL_FILTBYP, 0x0101 }, 527 { RES4328_BB_PLL_PU, 0x0701 } 528}; 529 530static const pmu_res_depend_t BCMATTACHDATA(bcm4328a0_res_depend)[] = { 531 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */ 532 { 533 PMURES_BIT(RES4328_ILP_REQUEST), 534 RES_DEPEND_SET, 535 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | PMURES_BIT(RES4328_BB_SWITCHER_PWM), 536 NULL 537 } 538}; 539 540static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown_qt)[] = { 541 { RES4325_HT_AVAIL, 0x0300 }, 542 { RES4325_BBPLL_PWRSW_PU, 0x0101 }, 543 { RES4325_RFPLL_PWRSW_PU, 0x0101 }, 544 { RES4325_ALP_AVAIL, 0x0100 }, 545 { RES4325_XTAL_PU, 0x1000 }, 546 { RES4325_LNLDO1_PU, 0x0800 }, 547 { RES4325_CLDO_CBUCK_PWM, 0x0101 }, 548 { RES4325_CBUCK_PWM, 0x0803 } 549}; 550 551static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown)[] = { 552 { RES4325_XTAL_PU, 0x1501 } 553}; 554 555static const pmu_res_depend_t BCMATTACHDATA(bcm4325a0_res_depend)[] = { 556 /* Adjust OTP PU resource dependencies - remove BB BURST */ 557 { 558 PMURES_BIT(RES4325_OTP_PU), 559 RES_DEPEND_REMOVE, 560 PMURES_BIT(RES4325_BUCK_BOOST_BURST), 561 NULL 562 }, 563 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */ 564 { 565 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL), 566 RES_DEPEND_ADD, 567 PMURES_BIT(RES4325_BUCK_BOOST_BURST) | PMURES_BIT(RES4325_BUCK_BOOST_PWM), 568 si_pmu_res_depfltr_bb 569 }, 570 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 571 { 572 PMURES_BIT(RES4325_HT_AVAIL), 573 RES_DEPEND_ADD, 574 PMURES_BIT(RES4325_RX_PWRSW_PU) | PMURES_BIT(RES4325_TX_PWRSW_PU) | 575 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU), 576 NULL 577 }, 578 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */ 579 { 580 PMURES_BIT(RES4325_ILP_REQUEST) | PMURES_BIT(RES4325_ABUCK_BURST) | 581 PMURES_BIT(RES4325_ABUCK_PWM) | PMURES_BIT(RES4325_LNLDO1_PU) | 582 PMURES_BIT(RES4325C1_LNLDO2_PU) | PMURES_BIT(RES4325_XTAL_PU) | 583 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_RX_PWRSW_PU) | 584 PMURES_BIT(RES4325_TX_PWRSW_PU) | PMURES_BIT(RES4325_RFPLL_PWRSW_PU) | 585 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU) | 586 PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL), 587 RES_DEPEND_REMOVE, 588 PMURES_BIT(RES4325B0_CBUCK_LPOM) | PMURES_BIT(RES4325B0_CBUCK_BURST) | 589 PMURES_BIT(RES4325B0_CBUCK_PWM), 590 si_pmu_res_depfltr_ncb 591 } 592}; 593 594static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown_qt)[] = { 595 { RES4315_HT_AVAIL, 0x0101 }, 596 { RES4315_XTAL_PU, 0x0100 }, 597 { RES4315_LNLDO1_PU, 0x0100 }, 598 { RES4315_PALDO_PU, 0x0100 }, 599 { RES4315_CLDO_PU, 0x0100 }, 600 { RES4315_CBUCK_PWM, 0x0100 }, 601 { RES4315_CBUCK_BURST, 0x0100 }, 602 { RES4315_CBUCK_LPOM, 0x0100 } 603}; 604 605static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown)[] = { 606 { RES4315_XTAL_PU, 0x2501 } 607}; 608 609static const pmu_res_depend_t BCMATTACHDATA(bcm4315a0_res_depend)[] = { 610 /* Adjust OTP PU resource dependencies - not need PALDO unless write */ 611 { 612 PMURES_BIT(RES4315_OTP_PU), 613 RES_DEPEND_REMOVE, 614 PMURES_BIT(RES4315_PALDO_PU), 615 si_pmu_res_depfltr_npaldo 616 }, 617 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */ 618 { 619 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL), 620 RES_DEPEND_ADD, 621 PMURES_BIT(RES4315_PALDO_PU), 622 si_pmu_res_depfltr_paldo 623 }, 624 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 625 { 626 PMURES_BIT(RES4315_HT_AVAIL), 627 RES_DEPEND_ADD, 628 PMURES_BIT(RES4315_RX_PWRSW_PU) | PMURES_BIT(RES4315_TX_PWRSW_PU) | 629 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | PMURES_BIT(RES4315_AFE_PWRSW_PU), 630 NULL 631 }, 632 /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */ 633 { 634 PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) | 635 PMURES_BIT(RES4315_LNLDO1_PU) | PMURES_BIT(RES4315_OTP_PU) | 636 PMURES_BIT(RES4315_LNLDO2_PU) | PMURES_BIT(RES4315_XTAL_PU) | 637 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_RX_PWRSW_PU) | 638 PMURES_BIT(RES4315_TX_PWRSW_PU) | PMURES_BIT(RES4315_RFPLL_PWRSW_PU) | 639 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | PMURES_BIT(RES4315_AFE_PWRSW_PU) | 640 PMURES_BIT(RES4315_BBPLL_PWRSW_PU) | PMURES_BIT(RES4315_HT_AVAIL), 641 RES_DEPEND_REMOVE, 642 PMURES_BIT(RES4315_CBUCK_LPOM) | PMURES_BIT(RES4315_CBUCK_BURST) | 643 PMURES_BIT(RES4315_CBUCK_PWM), 644 si_pmu_res_depfltr_ncb 645 } 646}; 647 648static const pmu_res_updown_t BCMATTACHDATA(bcm4329_res_updown)[] = { 649 { RES4329_XTAL_PU, 0x1501 }, 650 { RES4329_PALDO_PU, 0x3501 } 651}; 652 653static const pmu_res_depend_t BCMATTACHDATA(bcm4329_res_depend)[] = { 654 /* Make lnldo1 independant of CBUCK_PWM and CBUCK_BURST */ 655 { 656 PMURES_BIT(RES4329_LNLDO1_PU), 657 RES_DEPEND_REMOVE, 658 PMURES_BIT(RES4329_CBUCK_PWM) | PMURES_BIT(RES4329_CBUCK_BURST), 659 NULL 660 }, 661 { 662 PMURES_BIT(RES4329_CBUCK_BURST), 663 RES_DEPEND_ADD, 664 PMURES_BIT(RES4329_CBUCK_LPOM) | PMURES_BIT(RES4329_PALDO_PU), 665 NULL 666 }, 667 { 668 PMURES_BIT(RES4329_BBPLL_PWRSW_PU), 669 RES_DEPEND_ADD, 670 PMURES_BIT(RES4329_RX_PWRSW_PU) | PMURES_BIT(RES4329_TX_PWRSW_PU) | 671 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | PMURES_BIT(RES4329_AFE_PWRSW_PU), 672 NULL 673 }, 674 /* Adjust HT Avail resource dependencies */ 675 { 676 PMURES_BIT(RES4329_HT_AVAIL), 677 RES_DEPEND_ADD, 678 PMURES_BIT(RES4329_PALDO_PU) | 679 PMURES_BIT(RES4329_RX_PWRSW_PU) | PMURES_BIT(RES4329_TX_PWRSW_PU) | 680 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | PMURES_BIT(RES4329_AFE_PWRSW_PU), 681 NULL 682 } 683}; 684 685static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown_qt)[] = { 686 { RES4319_HT_AVAIL, 0x0101 }, 687 { RES4319_XTAL_PU, 0x0100 }, 688 { RES4319_LNLDO1_PU, 0x0100 }, 689 { RES4319_PALDO_PU, 0x0100 }, 690 { RES4319_CLDO_PU, 0x0100 }, 691 { RES4319_CBUCK_PWM, 0x0100 }, 692 { RES4319_CBUCK_BURST, 0x0100 }, 693 { RES4319_CBUCK_LPOM, 0x0100 } 694}; 695 696static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown)[] = { 697 { RES4319_XTAL_PU, 0x3f01 } 698}; 699 700static const pmu_res_depend_t BCMATTACHDATA(bcm4319a0_res_depend)[] = { 701 /* Adjust OTP PU resource dependencies - not need PALDO unless write */ 702 { 703 PMURES_BIT(RES4319_OTP_PU), 704 RES_DEPEND_REMOVE, 705 PMURES_BIT(RES4319_PALDO_PU), 706 si_pmu_res_depfltr_npaldo 707 }, 708 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */ 709 { 710 PMURES_BIT(RES4319_HT_AVAIL), 711 RES_DEPEND_ADD, 712 PMURES_BIT(RES4319_PALDO_PU), 713 si_pmu_res_depfltr_paldo 714 }, 715 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 716 { 717 PMURES_BIT(RES4319_HT_AVAIL), 718 RES_DEPEND_ADD, 719 PMURES_BIT(RES4319_RX_PWRSW_PU) | PMURES_BIT(RES4319_TX_PWRSW_PU) | 720 PMURES_BIT(RES4319_RFPLL_PWRSW_PU) | 721 PMURES_BIT(RES4319_LOGEN_PWRSW_PU) | PMURES_BIT(RES4319_AFE_PWRSW_PU), 722 NULL 723 } 724}; 725 726static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown_qt)[] = { 727 { RES4336_HT_AVAIL, 0x0101 }, 728 { RES4336_XTAL_PU, 0x0100 }, 729 { RES4336_CLDO_PU, 0x0100 }, 730 { RES4336_CBUCK_PWM, 0x0100 }, 731 { RES4336_CBUCK_BURST, 0x0100 }, 732 { RES4336_CBUCK_LPOM, 0x0100 } 733}; 734 735static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown)[] = { 736 { RES4336_HT_AVAIL, 0x0D01} 737}; 738 739static const pmu_res_depend_t BCMATTACHDATA(bcm4336a0_res_depend)[] = { 740 /* Just a dummy entry for now */ 741 { 742 PMURES_BIT(RES4336_RSVD), 743 RES_DEPEND_ADD, 744 0, 745 NULL 746 } 747}; 748 749static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown_qt)[] = { 750 { RES4330_HT_AVAIL, 0x0101 }, 751 { RES4330_XTAL_PU, 0x0100 }, 752 { RES4330_CLDO_PU, 0x0100 }, 753 { RES4330_CBUCK_PWM, 0x0100 }, 754 { RES4330_CBUCK_BURST, 0x0100 }, 755 { RES4330_CBUCK_LPOM, 0x0100 } 756}; 757 758static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown)[] = { 759 { RES4330_HT_AVAIL, 0x0e02} 760}; 761 762static const pmu_res_depend_t BCMATTACHDATA(bcm4330a0_res_depend)[] = { 763 /* Just a dummy entry for now */ 764 { 765 PMURES_BIT(RES4330_HT_AVAIL), 766 RES_DEPEND_ADD, 767 0, 768 NULL 769 } 770}; 771 772/* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */ 773static bool 774BCMATTACHFN(si_pmu_res_depfltr_bb)(si_t *sih) 775{ 776 return (sih->boardflags & BFL_BUCKBOOST) != 0; 777} 778 779/* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */ 780static bool 781BCMATTACHFN(si_pmu_res_depfltr_ncb)(si_t *sih) 782{ 783 if (CHIPID(sih->chip) == BCM4325_CHIP_ID) 784 return (CHIPREV(sih->chiprev) >= 2) && ((sih->boardflags & BFL_NOCBUCK) != 0); 785 return ((sih->boardflags & BFL_NOCBUCK) != 0); 786} 787 788/* TRUE if the power topology uses the PALDO */ 789static bool 790BCMATTACHFN(si_pmu_res_depfltr_paldo)(si_t *sih) 791{ 792 return (sih->boardflags & BFL_PALDO) != 0; 793} 794 795/* TRUE if the power topology doesn't use the PALDO */ 796static bool 797BCMATTACHFN(si_pmu_res_depfltr_npaldo)(si_t *sih) 798{ 799 return (sih->boardflags & BFL_PALDO) == 0; 800} 801 802#define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \ 803 sih->boardtype == BCM94325BGABU_BOARD) 804 805/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */ 806static void 807si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax) 808{ 809 uint32 min_mask = 0, max_mask = 0; 810 uint rsrcs; 811 char *val; 812 813 /* # resources */ 814 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; 815 816 /* determine min/max rsrc masks */ 817 switch (CHIPID(sih->chip)) { 818 case BCM4328_CHIP_ID: 819 /* Down to ILP request */ 820 min_mask = PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | 821 PMURES_BIT(RES4328_BB_SWITCHER_PWM) | 822 PMURES_BIT(RES4328_XTAL_EN); 823 /* Allow (but don't require) PLL to turn on */ 824 max_mask = 0xfffff; 825 break; 826 case BCM5354_CHIP_ID: 827 /* Allow (but don't require) PLL to turn on */ 828 max_mask = 0xfffff; 829 break; 830 case BCM4325_CHIP_ID: 831 ASSERT(CHIPREV(sih->chiprev) >= 2); 832 /* Minimum rsrcs to work in sleep mode */ 833 if (!(sih->boardflags & BFL_NOCBUCK)) 834 min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM); 835 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> 836 CST4325_PMUTOP_2B_SHIFT) == 1) 837 min_mask |= PMURES_BIT(RES4325B0_CLDO_PU); 838 if (!si_is_otp_disabled(sih)) 839 min_mask |= PMURES_BIT(RES4325_OTP_PU); 840 /* Leave buck boost on in burst mode for certain boards */ 841 if ((sih->boardflags & BFL_BUCKBOOST) && (BCM94325_BBVDDIOSD_BOARDS(sih))) 842 min_mask |= PMURES_BIT(RES4325_BUCK_BOOST_BURST); 843 /* Allow all resources to be turned on upon requests */ 844 max_mask = ~(~0 << rsrcs); 845 break; 846 case BCM4312_CHIP_ID: 847 /* default min_mask = 0x80000cbb is wrong */ 848 min_mask = 0xcbb; 849 /* 850 * max_mask = 0x7fff; 851 * pmu_res_updown_table_sz = 0; 852 * pmu_res_depend_table_sz = 0; 853 */ 854 break; 855 case BCM4322_CHIP_ID: 856 case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 857 case BCM4342_CHIP_ID: 858 if (CHIPREV(sih->chiprev) < 2) { 859 /* request ALP(can skip for A1) */ 860 min_mask = PMURES_BIT(RES4322_RF_LDO) | 861 PMURES_BIT(RES4322_XTAL_PU) | 862 PMURES_BIT(RES4322_ALP_AVAIL); 863 if (BUSTYPE(sih->bustype) == SI_BUS) { 864 min_mask += PMURES_BIT(RES4322_SI_PLL_ON) | 865 PMURES_BIT(RES4322_HT_SI_AVAIL) | 866 PMURES_BIT(RES4322_PHY_PLL_ON) | 867 PMURES_BIT(RES4322_OTP_PU) | 868 PMURES_BIT(RES4322_HT_PHY_AVAIL); 869 max_mask = 0x1ff; 870 } 871 } 872 break; 873 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 874 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 875 case BCM43226_CHIP_ID: case BCM43420_CHIP_ID: 876 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 877 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: 878 case BCM4331_CHIP_ID: case BCM43431_CHIP_ID: 879 case BCM6362_CHIP_ID: 880 /* use chip default */ 881 break; 882 883 case BCM4329_CHIP_ID: 884 885 /* Down to save the power. */ 886 if (CHIPREV(sih->chiprev) >= 0x2) { 887 min_mask = PMURES_BIT(RES4329_CBUCK_LPOM) | 888 PMURES_BIT(RES4329_LNLDO1_PU) | PMURES_BIT(RES4329_CLDO_PU); 889 } else { 890 min_mask = PMURES_BIT(RES4329_CBUCK_LPOM) | PMURES_BIT(RES4329_CLDO_PU); 891 } 892 if (!si_is_otp_disabled(sih)) 893 min_mask |= PMURES_BIT(RES4329_OTP_PU); 894 /* Allow (but don't require) PLL to turn on */ 895 max_mask = 0x3ff63e; 896 897 break; 898 case BCM4315_CHIP_ID: 899 /* We only need a few resources to be kept on all the time */ 900 if (!(sih->boardflags & BFL_NOCBUCK)) 901 min_mask = PMURES_BIT(RES4315_CBUCK_LPOM); 902 min_mask |= PMURES_BIT(RES4315_CLDO_PU); 903 /* Allow everything else to be turned on upon requests */ 904 max_mask = ~(~0 << rsrcs); 905 break; 906 case BCM4319_CHIP_ID: 907#ifdef BCM_BOOTLOADER 908 /* Initialize to ResInitMode3 for bootloader */ 909 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | 910 PMURES_BIT(RES4319_CBUCK_BURST) | 911 PMURES_BIT(RES4319_CBUCK_PWM) | 912 PMURES_BIT(RES4319_CLDO_PU) | 913 PMURES_BIT(RES4319_PALDO_PU) | 914 PMURES_BIT(RES4319_LNLDO1_PU) | 915 PMURES_BIT(RES4319_XTAL_PU) | 916 PMURES_BIT(RES4319_ALP_AVAIL) | 917 PMURES_BIT(RES4319_RFPLL_PWRSW_PU) | 918 PMURES_BIT(RES4319_BBPLL_PWRSW_PU) | 919 PMURES_BIT(RES4319_HT_AVAIL); 920#else 921 /* We only need a few resources to be kept on all the time */ 922#ifdef BCMUSBDEV 923 /* For USB HT is always available, even durring IEEE PS, so RF switches are 924 * made independent of HT Avail and are by default on, but can be made off 925 * during IEEE PS by ucode (and then on) 926 */ 927 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | 928 PMURES_BIT(RES4319_CLDO_PU) | 929 PMURES_BIT(RES4319_RX_PWRSW_PU) | PMURES_BIT(RES4319_TX_PWRSW_PU) | 930 PMURES_BIT(RES4319_LOGEN_PWRSW_PU) | PMURES_BIT(RES4319_AFE_PWRSW_PU); 931#else 932 /* For SDIO RF switches are automatically made on off along with HT */ 933 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | 934 PMURES_BIT(RES4319_CLDO_PU); 935#endif 936#endif /* BCM_BOOTLOADER */ 937 938 /* Allow everything else to be turned on upon requests */ 939 max_mask = ~(~0 << rsrcs); 940 break; 941 case BCM4336_CHIP_ID: 942 /* Down to save the power. */ 943 min_mask = PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU) | 944 PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU) | 945 PMURES_BIT(RES4336_DIS_INT_RESET_PD); 946 /* Allow (but don't require) PLL to turn on */ 947 max_mask = 0x1ffffff; 948 break; 949 950 case BCM4330_CHIP_ID: 951 /* Down to save the power. */ 952 min_mask = PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU) | 953 PMURES_BIT(RES4330_DIS_INT_RESET_PD) | PMURES_BIT(RES4330_LDO3P3_PU) | 954 PMURES_BIT(RES4330_OTP_PU); 955 /* Allow (but don't require) PLL to turn on */ 956 max_mask = 0xfffffff; 957 break; 958 959 case BCM4313_CHIP_ID: 960 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) | 961 PMURES_BIT(RES4313_XTAL_PU_RSRC) | 962 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) | 963 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC); 964 max_mask = 0xffff; 965 break; 966 default: 967 break; 968 } 969 970 /* Apply nvram override to min mask */ 971 if ((val = getvar(NULL, "rmin")) != NULL) { 972 PMU_MSG(("Applying rmin=%s to min_mask\n", val)); 973 min_mask = (uint32)bcm_strtoul(val, NULL, 0); 974 } 975 /* Apply nvram override to max mask */ 976 if ((val = getvar(NULL, "rmax")) != NULL) { 977 PMU_MSG(("Applying rmax=%s to max_mask\n", val)); 978 max_mask = (uint32)bcm_strtoul(val, NULL, 0); 979 } 980 981 *pmin = min_mask; 982 *pmax = max_mask; 983} 984#endif /* !_CFE_ || CFG_WL */ 985 986/* initialize PMU resources */ 987void 988BCMATTACHFN(si_pmu_res_init)(si_t *sih, osl_t *osh) 989{ 990#if !defined(_CFE_) || defined(CFG_WL) 991 chipcregs_t *cc; 992 uint origidx; 993 const pmu_res_updown_t *pmu_res_updown_table = NULL; 994 uint pmu_res_updown_table_sz = 0; 995 const pmu_res_depend_t *pmu_res_depend_table = NULL; 996 uint pmu_res_depend_table_sz = 0; 997 uint32 min_mask = 0, max_mask = 0; 998 char name[8], *val; 999 uint i, rsrcs; 1000 1001 ASSERT(sih->cccaps & CC_CAP_PMU); 1002 1003 /* Remember original core before switch to chipc */ 1004 origidx = si_coreidx(sih); 1005 cc = si_setcoreidx(sih, SI_CC_IDX); 1006 ASSERT(cc != NULL); 1007 1008 switch (CHIPID(sih->chip)) { 1009 case BCM4328_CHIP_ID: 1010 pmu_res_updown_table = bcm4328a0_res_updown; 1011 pmu_res_updown_table_sz = ARRAYSIZE(bcm4328a0_res_updown); 1012 pmu_res_depend_table = bcm4328a0_res_depend; 1013 pmu_res_depend_table_sz = ARRAYSIZE(bcm4328a0_res_depend); 1014 break; 1015 case BCM4325_CHIP_ID: 1016 /* Optimize resources up/down timers */ 1017 if (ISSIM_ENAB(sih)) { 1018 pmu_res_updown_table = bcm4325a0_res_updown_qt; 1019 pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown_qt); 1020 } else { 1021 pmu_res_updown_table = bcm4325a0_res_updown; 1022 pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown); 1023 } 1024 /* Optimize resources dependancies */ 1025 pmu_res_depend_table = bcm4325a0_res_depend; 1026 pmu_res_depend_table_sz = ARRAYSIZE(bcm4325a0_res_depend); 1027 break; 1028 case BCM4315_CHIP_ID: 1029 /* Optimize resources up/down timers */ 1030 if (ISSIM_ENAB(sih)) { 1031 pmu_res_updown_table = bcm4315a0_res_updown_qt; 1032 pmu_res_updown_table_sz = ARRAYSIZE(bcm4315a0_res_updown_qt); 1033 } 1034 else { 1035 pmu_res_updown_table = bcm4315a0_res_updown; 1036 pmu_res_updown_table_sz = ARRAYSIZE(bcm4315a0_res_updown); 1037 } 1038 /* Optimize resources dependancies masks */ 1039 pmu_res_depend_table = bcm4315a0_res_depend; 1040 pmu_res_depend_table_sz = ARRAYSIZE(bcm4315a0_res_depend); 1041 break; 1042 case BCM4329_CHIP_ID: 1043 /* Optimize resources up/down timers */ 1044 if (ISSIM_ENAB(sih)) { 1045 pmu_res_updown_table = NULL; 1046 pmu_res_updown_table_sz = 0; 1047 } else { 1048 pmu_res_updown_table = bcm4329_res_updown; 1049 pmu_res_updown_table_sz = ARRAYSIZE(bcm4329_res_updown); 1050 } 1051 /* Optimize resources dependencies */ 1052 pmu_res_depend_table = bcm4329_res_depend; 1053 pmu_res_depend_table_sz = ARRAYSIZE(bcm4329_res_depend); 1054 break; 1055 1056 case BCM4319_CHIP_ID: 1057 /* Optimize resources up/down timers */ 1058 if (ISSIM_ENAB(sih)) { 1059 pmu_res_updown_table = bcm4319a0_res_updown_qt; 1060 pmu_res_updown_table_sz = ARRAYSIZE(bcm4319a0_res_updown_qt); 1061 } 1062 else { 1063 pmu_res_updown_table = bcm4319a0_res_updown; 1064 pmu_res_updown_table_sz = ARRAYSIZE(bcm4319a0_res_updown); 1065 } 1066 /* Optimize resources dependancies masks */ 1067 pmu_res_depend_table = bcm4319a0_res_depend; 1068 pmu_res_depend_table_sz = ARRAYSIZE(bcm4319a0_res_depend); 1069 break; 1070 1071 case BCM4336_CHIP_ID: 1072 /* Optimize resources up/down timers */ 1073 if (ISSIM_ENAB(sih)) { 1074 pmu_res_updown_table = bcm4336a0_res_updown_qt; 1075 pmu_res_updown_table_sz = ARRAYSIZE(bcm4336a0_res_updown_qt); 1076 } 1077 else { 1078 pmu_res_updown_table = bcm4336a0_res_updown; 1079 pmu_res_updown_table_sz = ARRAYSIZE(bcm4336a0_res_updown); 1080 } 1081 /* Optimize resources dependancies masks */ 1082 pmu_res_depend_table = bcm4336a0_res_depend; 1083 pmu_res_depend_table_sz = ARRAYSIZE(bcm4336a0_res_depend); 1084 break; 1085 1086 case BCM4330_CHIP_ID: 1087 /* Optimize resources up/down timers */ 1088 if (ISSIM_ENAB(sih)) { 1089 pmu_res_updown_table = bcm4330a0_res_updown_qt; 1090 pmu_res_updown_table_sz = ARRAYSIZE(bcm4330a0_res_updown_qt); 1091 } 1092 else { 1093 pmu_res_updown_table = bcm4330a0_res_updown; 1094 pmu_res_updown_table_sz = ARRAYSIZE(bcm4330a0_res_updown); 1095 } 1096 /* Optimize resources dependancies masks */ 1097 pmu_res_depend_table = bcm4330a0_res_depend; 1098 pmu_res_depend_table_sz = ARRAYSIZE(bcm4330a0_res_depend); 1099 break; 1100 default: 1101 break; 1102 } 1103 1104 /* # resources */ 1105 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; 1106 1107 /* Program up/down timers */ 1108 while (pmu_res_updown_table_sz--) { 1109 ASSERT(pmu_res_updown_table != NULL); 1110 PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n", 1111 pmu_res_updown_table[pmu_res_updown_table_sz].resnum, 1112 pmu_res_updown_table[pmu_res_updown_table_sz].updown)); 1113 W_REG(osh, &cc->res_table_sel, 1114 pmu_res_updown_table[pmu_res_updown_table_sz].resnum); 1115 W_REG(osh, &cc->res_updn_timer, 1116 pmu_res_updown_table[pmu_res_updown_table_sz].updown); 1117 } 1118 /* Apply nvram overrides to up/down timers */ 1119 for (i = 0; i < rsrcs; i ++) { 1120 snprintf(name, sizeof(name), "r%dt", i); 1121 if ((val = getvar(NULL, name)) == NULL) 1122 continue; 1123 PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, val, i)); 1124 W_REG(osh, &cc->res_table_sel, (uint32)i); 1125 W_REG(osh, &cc->res_updn_timer, (uint32)bcm_strtoul(val, NULL, 0)); 1126 } 1127 1128 /* Program resource dependencies table */ 1129 while (pmu_res_depend_table_sz--) { 1130 ASSERT(pmu_res_depend_table != NULL); 1131 if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL && 1132 !(pmu_res_depend_table[pmu_res_depend_table_sz].filter)(sih)) 1133 continue; 1134 for (i = 0; i < rsrcs; i ++) { 1135 if ((pmu_res_depend_table[pmu_res_depend_table_sz].res_mask & 1136 PMURES_BIT(i)) == 0) 1137 continue; 1138 W_REG(osh, &cc->res_table_sel, i); 1139 switch (pmu_res_depend_table[pmu_res_depend_table_sz].action) { 1140 case RES_DEPEND_SET: 1141 PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, 1142 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask)); 1143 W_REG(osh, &cc->res_dep_mask, 1144 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 1145 break; 1146 case RES_DEPEND_ADD: 1147 PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", 1148 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); 1149 OR_REG(osh, &cc->res_dep_mask, 1150 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 1151 break; 1152 case RES_DEPEND_REMOVE: 1153 PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", 1154 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); 1155 AND_REG(osh, &cc->res_dep_mask, 1156 ~pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 1157 break; 1158 default: 1159 ASSERT(0); 1160 break; 1161 } 1162 } 1163 } 1164 /* Apply nvram overrides to dependancies masks */ 1165 for (i = 0; i < rsrcs; i ++) { 1166 snprintf(name, sizeof(name), "r%dd", i); 1167 if ((val = getvar(NULL, name)) == NULL) 1168 continue; 1169 PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, i)); 1170 W_REG(osh, &cc->res_table_sel, (uint32)i); 1171 W_REG(osh, &cc->res_dep_mask, (uint32)bcm_strtoul(val, NULL, 0)); 1172 } 1173 1174 /* Determine min/max rsrc masks */ 1175 si_pmu_res_masks(sih, &min_mask, &max_mask); 1176 1177 /* It is required to program max_mask first and then min_mask */ 1178#ifdef BCM_BOOTLOADER 1179 if (CHIPID(sih->chip) == BCM4319_CHIP_ID) { 1180 min_mask |= R_REG(osh, &cc->min_res_mask); 1181 max_mask |= R_REG(osh, &cc->max_res_mask); 1182 } 1183#endif /* BCM_BOOTLOADER */ 1184 1185 /* Program max resource mask */ 1186#ifdef BCM_BOOTLOADER 1187 /* Apply nvram override to max mask */ 1188 if ((val = getvar(NULL, "brmax")) != NULL) { 1189 PMU_MSG(("Applying brmax=%s to max_res_mask\n", val)); 1190 max_mask = (uint32)bcm_strtoul(val, NULL, 0); 1191 } 1192#endif /* BCM_BOOTLOADER */ 1193 1194 if (max_mask) { 1195 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask)); 1196 W_REG(osh, &cc->max_res_mask, max_mask); 1197 } 1198 1199 /* Program min resource mask */ 1200#ifdef BCM_BOOTLOADER 1201 /* Apply nvram override to min mask */ 1202 if ((val = getvar(NULL, "brmin")) != NULL) { 1203 PMU_MSG(("Applying brmin=%s to min_res_mask\n", val)); 1204 min_mask = (uint32)bcm_strtoul(val, NULL, 0); 1205 } 1206#endif /* BCM_BOOTLOADER */ 1207 1208 if (min_mask) { 1209 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask)); 1210 W_REG(osh, &cc->min_res_mask, min_mask); 1211 } 1212 1213 /* Add some delay; allow resources to come up and settle. */ 1214 OSL_DELAY(2000); 1215 1216 /* Return to original core */ 1217 si_setcoreidx(sih, origidx); 1218 1219#endif /* !_CFE_ || CFG_WL */ 1220} 1221/* WAR for 4319 swctrl tri-state issue */ 1222void 1223si_pmu_res_4319_swctrl_war(si_t *sih, osl_t *osh, bool enable) 1224{ 1225 uint32 min_mask; 1226 chipcregs_t *cc; 1227 uint origidx; 1228 ASSERT(sih->cccaps & CC_CAP_PMU); 1229 1230 /* Remember original core before switch to chipc */ 1231 origidx = si_coreidx(sih); 1232 cc = si_setcoreidx(sih, SI_CC_IDX); 1233 ASSERT(cc != NULL); 1234 min_mask = R_REG(osh, &cc->min_res_mask); 1235 if (enable) 1236 W_REG(osh, &cc->min_res_mask, 1237 min_mask | PMURES_BIT(RES4319_PALDO_PU)); 1238 else 1239 W_REG(osh, &cc->min_res_mask, 1240 min_mask & ~PMURES_BIT(RES4319_PALDO_PU)); 1241 1242 /* Return to original core */ 1243 si_setcoreidx(sih, origidx); 1244} 1245 1246/* setup pll and query clock speed */ 1247typedef struct { 1248 uint16 freq; 1249 uint8 xf; 1250 uint8 wbint; 1251 uint32 wbfrac; 1252} pmu0_xtaltab0_t; 1253 1254/* the following table is based on 880Mhz fvco */ 1255static const pmu0_xtaltab0_t BCMINITDATA(pmu0_xtaltab0)[] = { 1256 { 12000, 1, 73, 349525 }, 1257 { 13000, 2, 67, 725937 }, 1258 { 14400, 3, 61, 116508 }, 1259 { 15360, 4, 57, 305834 }, 1260 { 16200, 5, 54, 336579 }, 1261 { 16800, 6, 52, 399457 }, 1262 { 19200, 7, 45, 873813 }, 1263 { 19800, 8, 44, 466033 }, 1264 { 20000, 9, 44, 0 }, 1265 { 25000, 10, 70, 419430 }, 1266 { 26000, 11, 67, 725937 }, 1267 { 30000, 12, 58, 699050 }, 1268 { 38400, 13, 45, 873813 }, 1269 { 40000, 14, 45, 0 }, 1270 { 0, 0, 0, 0 } 1271}; 1272 1273#ifdef BCMUSBDEV 1274#define PMU0_XTAL0_DEFAULT 11 1275#else 1276#define PMU0_XTAL0_DEFAULT 8 1277#endif 1278 1279#ifdef BCMUSBDEV 1280/* 1281 * Set new backplane PLL clock frequency 1282 */ 1283static void 1284BCMATTACHFN(si_pmu0_sbclk4328)(si_t *sih, int freq) 1285{ 1286 uint32 tmp, oldmax, oldmin, origidx; 1287 chipcregs_t *cc; 1288 1289 /* Remember original core before switch to chipc */ 1290 origidx = si_coreidx(sih); 1291 cc = si_setcoreidx(sih, SI_CC_IDX); 1292 ASSERT(cc); 1293 1294 /* Set new backplane PLL clock */ 1295 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 1296 tmp = R_REG(osh, &cc->pllcontrol_data); 1297 tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK); 1298 tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT; 1299 W_REG(osh, &cc->pllcontrol_data, tmp); 1300 1301 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */ 1302 /* Disable PLL */ 1303 oldmin = R_REG(osh, &cc->min_res_mask); 1304 oldmax = R_REG(osh, &cc->max_res_mask); 1305 W_REG(osh, &cc->min_res_mask, oldmin & ~PMURES_BIT(RES4328_BB_PLL_PU)); 1306 W_REG(osh, &cc->max_res_mask, oldmax & ~PMURES_BIT(RES4328_BB_PLL_PU)); 1307 1308 /* It takes over several hundred usec to re-enable the PLL since the 1309 * sequencer state machines run on ILP clock. Set delay at 450us to be safe. 1310 * 1311 * Be sure PLL is powered down first before re-enabling it. 1312 */ 1313 1314 OSL_DELAY(PLL_DELAY); 1315 SPINWAIT((R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)), PLL_DELAY*3); 1316 if (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)) { 1317 /* If BB_PLL not powered down yet, new backplane PLL clock 1318 * may not take effect. 1319 * 1320 * Still early during bootup so no serial output here. 1321 */ 1322 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n")); 1323 ASSERT(!(R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU))); 1324 } 1325 1326 /* Enable PLL */ 1327 W_REG(osh, &cc->max_res_mask, oldmax); 1328 1329 /* Return to original core */ 1330 si_setcoreidx(sih, origidx); 1331} 1332#endif /* BCMUSBDEV */ 1333 1334/* Set up PLL registers in the PMU as per the crystal speed. 1335 * Uses xtalfreq variable, or passed-in default. 1336 */ 1337static void 1338BCMATTACHFN(si_pmu0_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal) 1339{ 1340 uint32 tmp; 1341 const pmu0_xtaltab0_t *xt; 1342 1343 /* Find the frequency in the table */ 1344 for (xt = pmu0_xtaltab0; xt->freq; xt ++) 1345 if (xt->freq == xtal) 1346 break; 1347 if (xt->freq == 0) 1348 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; 1349 1350 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); 1351 1352 /* Check current PLL state */ 1353 tmp = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 1354 PCTL_XTALFREQ_SHIFT; 1355 if (tmp == xt->xf) { 1356 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 1357 xt->freq / 1000, xt->freq % 1000)); 1358#ifdef BCMUSBDEV 1359 if (CHIPID(sih->chip) == BCM4328_CHIP_ID) 1360 si_pmu0_sbclk4328(sih, PMU0_PLL0_PC0_DIV_ARM_88MHZ); 1361#endif /* BCMUSBDEV */ 1362 return; 1363 } 1364 1365 if (tmp) { 1366 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", 1367 xt->freq / 1000, xt->freq % 1000, 1368 pmu0_xtaltab0[tmp-1].freq / 1000, pmu0_xtaltab0[tmp-1].freq % 1000)); 1369 } else { 1370 PMU_MSG(("Programming PLL for %d.%d MHz\n", 1371 xt->freq / 1000, xt->freq % 1000)); 1372 } 1373 1374 /* Make sure the PLL is off */ 1375 switch (CHIPID(sih->chip)) { 1376 case BCM4328_CHIP_ID: 1377 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU)); 1378 AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU)); 1379 break; 1380 case BCM5354_CHIP_ID: 1381 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU)); 1382 AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU)); 1383 break; 1384 default: 1385 ASSERT(0); 1386 } 1387 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1388 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL)); 1389 1390 PMU_MSG(("Done masking\n")); 1391 1392 /* Write PDIV in pllcontrol[0] */ 1393 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 1394 tmp = R_REG(osh, &cc->pllcontrol_data); 1395 if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ) 1396 tmp |= PMU0_PLL0_PC0_PDIV_MASK; 1397 else 1398 tmp &= ~PMU0_PLL0_PC0_PDIV_MASK; 1399 W_REG(osh, &cc->pllcontrol_data, tmp); 1400 1401 /* Write WILD in pllcontrol[1] */ 1402 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1); 1403 tmp = R_REG(osh, &cc->pllcontrol_data); 1404 tmp = ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) | 1405 (((xt->wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & 1406 PMU0_PLL0_PC1_WILD_INT_MASK) | 1407 ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) & 1408 PMU0_PLL0_PC1_WILD_FRAC_MASK))); 1409 if (xt->wbfrac == 0) 1410 tmp |= PMU0_PLL0_PC1_STOP_MOD; 1411 else 1412 tmp &= ~PMU0_PLL0_PC1_STOP_MOD; 1413 W_REG(osh, &cc->pllcontrol_data, tmp); 1414 1415 /* Write WILD in pllcontrol[2] */ 1416 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2); 1417 tmp = R_REG(osh, &cc->pllcontrol_data); 1418 tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) | 1419 ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) & 1420 PMU0_PLL0_PC2_WILD_INT_MASK)); 1421 W_REG(osh, &cc->pllcontrol_data, tmp); 1422 1423 PMU_MSG(("Done pll\n")); 1424 1425 /* Write XtalFreq. Set the divisor also. */ 1426 tmp = R_REG(osh, &cc->pmucontrol); 1427 tmp = ((tmp & ~PCTL_ILP_DIV_MASK) | 1428 (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & PCTL_ILP_DIV_MASK)); 1429 tmp = ((tmp & ~PCTL_XTALFREQ_MASK) | 1430 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK)); 1431 W_REG(osh, &cc->pmucontrol, tmp); 1432} 1433 1434/* query alp/xtal clock frequency */ 1435static uint32 1436BCMINITFN(si_pmu0_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 1437{ 1438 const pmu0_xtaltab0_t *xt; 1439 uint32 xf; 1440 1441 /* Find the frequency in the table */ 1442 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 1443 PCTL_XTALFREQ_SHIFT; 1444 for (xt = pmu0_xtaltab0; xt->freq; xt++) 1445 if (xt->xf == xf) 1446 break; 1447 /* PLL must be configured before */ 1448 ASSERT(xt->freq); 1449 1450 return xt->freq * 1000; 1451} 1452 1453#if !defined(_CFE_) || defined(CFG_WL) 1454/* query CPU clock frequency */ 1455static uint32 1456BCMINITFN(si_pmu0_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 1457{ 1458 uint32 tmp, divarm; 1459 uint32 FVCO = FVCO_880; 1460 1461 /* Read divarm from pllcontrol[0] */ 1462 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 1463 tmp = R_REG(osh, &cc->pllcontrol_data); 1464 divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT; 1465 1466 1467 /* Return ARM/SB clock */ 1468 return FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000; 1469} 1470 1471uint 1472si_pll_minresmask_reset(si_t *sih, osl_t *osh) 1473{ 1474 chipcregs_t *cc; 1475 uint origidx; 1476 uint err = BCME_OK; 1477 /* Remember original core before switch to chipc */ 1478 origidx = si_coreidx(sih); 1479 cc = si_setcoreidx(sih, SI_CC_IDX); 1480 ASSERT(cc != NULL); 1481 1482 switch (CHIPID(sih->chip)) { 1483 case BCM4313_CHIP_ID: 1484 /* write to min_res_mask 0x200d : clear min_rsrc_mask */ 1485 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 1486 OSL_DELAY(100); 1487 /* write to max_res_mask 0xBFFF: clear max_rsrc_mask */ 1488 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 1489 OSL_DELAY(100); 1490 /* write to max_res_mask 0xFFFF :set max_rsrc_mask */ 1491 OR_REG(osh, &cc->max_res_mask, (PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 1492 1493 break; 1494 default: 1495 PMU_ERROR(("%s: PLL reset not supported\n", __FUNCTION__)); 1496 err = BCME_UNSUPPORTED; 1497 break; 1498 } 1499 /* Return to original core */ 1500 si_setcoreidx(sih, origidx); 1501 return err; 1502} 1503 1504/* setup pll and query clock speed */ 1505typedef struct { 1506 uint16 fref; 1507 uint8 xf; 1508 uint8 p1div; 1509 uint8 p2div; 1510 uint8 ndiv_int; 1511 uint32 ndiv_frac; 1512} pmu1_xtaltab0_t; 1513 1514static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880_4329)[] = { 1515 {12000, 1, 3, 22, 0x9, 0xFFFFEF}, 1516 {13000, 2, 1, 6, 0xb, 0x483483}, 1517 {14400, 3, 1, 10, 0xa, 0x1C71C7}, 1518 {15360, 4, 1, 5, 0xb, 0x755555}, 1519 {16200, 5, 1, 10, 0x5, 0x6E9E06}, 1520 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, 1521 {19200, 7, 1, 4, 0xb, 0x755555}, 1522 {19800, 8, 1, 11, 0x4, 0xA57EB}, 1523 {20000, 9, 1, 11, 0x4, 0x0}, 1524 {24000, 10, 3, 11, 0xa, 0x0}, 1525 {25000, 11, 5, 16, 0xb, 0x0}, 1526 {26000, 12, 1, 1, 0x21, 0xD89D89}, 1527 {30000, 13, 3, 8, 0xb, 0x0}, 1528 {37400, 14, 3, 1, 0x46, 0x969696}, 1529 {38400, 15, 1, 1, 0x16, 0xEAAAAA}, 1530 {40000, 16, 1, 2, 0xb, 0}, 1531 {0, 0, 0, 0, 0, 0} 1532}; 1533 1534/* the following table is based on 880Mhz fvco */ 1535static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880)[] = { 1536 {12000, 1, 3, 22, 0x9, 0xFFFFEF}, 1537 {13000, 2, 1, 6, 0xb, 0x483483}, 1538 {14400, 3, 1, 10, 0xa, 0x1C71C7}, 1539 {15360, 4, 1, 5, 0xb, 0x755555}, 1540 {16200, 5, 1, 10, 0x5, 0x6E9E06}, 1541 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, 1542 {19200, 7, 1, 4, 0xb, 0x755555}, 1543 {19800, 8, 1, 11, 0x4, 0xA57EB}, 1544 {20000, 9, 1, 11, 0x4, 0x0}, 1545 {24000, 10, 3, 11, 0xa, 0x0}, 1546 {25000, 11, 5, 16, 0xb, 0x0}, 1547 {26000, 12, 1, 2, 0x10, 0xEC4EC4}, 1548 {30000, 13, 3, 8, 0xb, 0x0}, 1549 {33600, 14, 1, 2, 0xd, 0x186186}, 1550 {38400, 15, 1, 2, 0xb, 0x755555}, 1551 {40000, 16, 1, 2, 0xb, 0}, 1552 {0, 0, 0, 0, 0, 0} 1553}; 1554 1555#define PMU1_XTALTAB0_880_12000K 0 1556#define PMU1_XTALTAB0_880_13000K 1 1557#define PMU1_XTALTAB0_880_14400K 2 1558#define PMU1_XTALTAB0_880_15360K 3 1559#define PMU1_XTALTAB0_880_16200K 4 1560#define PMU1_XTALTAB0_880_16800K 5 1561#define PMU1_XTALTAB0_880_19200K 6 1562#define PMU1_XTALTAB0_880_19800K 7 1563#define PMU1_XTALTAB0_880_20000K 8 1564#define PMU1_XTALTAB0_880_24000K 9 1565#define PMU1_XTALTAB0_880_25000K 10 1566#define PMU1_XTALTAB0_880_26000K 11 1567#define PMU1_XTALTAB0_880_30000K 12 1568#define PMU1_XTALTAB0_880_37400K 13 1569#define PMU1_XTALTAB0_880_38400K 14 1570#define PMU1_XTALTAB0_880_40000K 15 1571 1572/* the following table is based on 1760Mhz fvco */ 1573static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1760)[] = { 1574 {12000, 1, 3, 44, 0x9, 0xFFFFEF}, 1575 {13000, 2, 1, 12, 0xb, 0x483483}, 1576 {14400, 3, 1, 20, 0xa, 0x1C71C7}, 1577 {15360, 4, 1, 10, 0xb, 0x755555}, 1578 {16200, 5, 1, 20, 0x5, 0x6E9E06}, 1579 {16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, 1580 {19200, 7, 1, 18, 0x5, 0x17B425}, 1581 {19800, 8, 1, 22, 0x4, 0xA57EB}, 1582 {20000, 9, 1, 22, 0x4, 0x0}, 1583 {24000, 10, 3, 22, 0xa, 0x0}, 1584 {25000, 11, 5, 32, 0xb, 0x0}, 1585 {26000, 12, 1, 4, 0x10, 0xEC4EC4}, 1586 {30000, 13, 3, 16, 0xb, 0x0}, 1587 {38400, 14, 1, 10, 0x4, 0x955555}, 1588 {40000, 15, 1, 4, 0xb, 0}, 1589 {0, 0, 0, 0, 0, 0} 1590}; 1591 1592/* table index */ 1593#define PMU1_XTALTAB0_1760_12000K 0 1594#define PMU1_XTALTAB0_1760_13000K 1 1595#define PMU1_XTALTAB0_1760_14400K 2 1596#define PMU1_XTALTAB0_1760_15360K 3 1597#define PMU1_XTALTAB0_1760_16200K 4 1598#define PMU1_XTALTAB0_1760_16800K 5 1599#define PMU1_XTALTAB0_1760_19200K 6 1600#define PMU1_XTALTAB0_1760_19800K 7 1601#define PMU1_XTALTAB0_1760_20000K 8 1602#define PMU1_XTALTAB0_1760_24000K 9 1603#define PMU1_XTALTAB0_1760_25000K 10 1604#define PMU1_XTALTAB0_1760_26000K 11 1605#define PMU1_XTALTAB0_1760_30000K 12 1606#define PMU1_XTALTAB0_1760_38400K 13 1607#define PMU1_XTALTAB0_1760_40000K 14 1608 1609/* the following table is based on 1440Mhz fvco */ 1610static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1440)[] = { 1611 {12000, 1, 1, 1, 0x78, 0x0 }, 1612 {13000, 2, 1, 1, 0x6E, 0xC4EC4E}, 1613 {14400, 3, 1, 1, 0x64, 0x0 }, 1614 {15360, 4, 1, 1, 0x5D, 0xC00000}, 1615 {16200, 5, 1, 1, 0x58, 0xE38E38}, 1616 {16800, 6, 1, 1, 0x55, 0xB6DB6D}, 1617 {19200, 7, 1, 1, 0x4B, 0 }, 1618 {19800, 8, 1, 1, 0x48, 0xBA2E8B}, 1619 {20000, 9, 1, 1, 0x48, 0x0 }, 1620 {25000, 10, 1, 1, 0x39, 0x999999}, 1621 {26000, 11, 1, 1, 0x37, 0x627627}, 1622 {30000, 12, 1, 1, 0x30, 0x0 }, 1623 {37400, 13, 2, 1, 0x4D, 0x15E76 }, 1624 {38400, 13, 2, 1, 0x4B, 0x0 }, 1625 {40000, 14, 2, 1, 0x48, 0x0 }, 1626 {48000, 15, 2, 1, 0x3c, 0x0 }, 1627 {0, 0, 0, 0, 0, 0} 1628}; 1629 1630/* table index */ 1631#define PMU1_XTALTAB0_1440_12000K 0 1632#define PMU1_XTALTAB0_1440_13000K 1 1633#define PMU1_XTALTAB0_1440_14400K 2 1634#define PMU1_XTALTAB0_1440_15360K 3 1635#define PMU1_XTALTAB0_1440_16200K 4 1636#define PMU1_XTALTAB0_1440_16800K 5 1637#define PMU1_XTALTAB0_1440_19200K 6 1638#define PMU1_XTALTAB0_1440_19800K 7 1639#define PMU1_XTALTAB0_1440_20000K 8 1640#define PMU1_XTALTAB0_1440_25000K 9 1641#define PMU1_XTALTAB0_1440_26000K 10 1642#define PMU1_XTALTAB0_1440_30000K 11 1643#define PMU1_XTALTAB0_1440_37400K 12 1644#define PMU1_XTALTAB0_1440_38400K 13 1645#define PMU1_XTALTAB0_1440_40000K 14 1646#define PMU1_XTALTAB0_1440_48000K 15 1647 1648#define XTAL_FREQ_24000MHZ 24000 1649#define XTAL_FREQ_30000MHZ 30000 1650#define XTAL_FREQ_37400MHZ 37400 1651#define XTAL_FREQ_48000MHZ 48000 1652 1653static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_960)[] = { 1654 {12000, 1, 1, 1, 0x50, 0x0 }, 1655 {13000, 2, 1, 1, 0x49, 0xD89D89}, 1656 {14400, 3, 1, 1, 0x42, 0xAAAAAA}, 1657 {15360, 4, 1, 1, 0x3E, 0x800000}, 1658 {16200, 5, 1, 1, 0x39, 0x425ED0}, 1659 {16800, 6, 1, 1, 0x39, 0x249249}, 1660 {19200, 7, 1, 1, 0x32, 0x0 }, 1661 {19800, 8, 1, 1, 0x30, 0x7C1F07}, 1662 {20000, 9, 1, 1, 0x30, 0x0 }, 1663 {25000, 10, 1, 1, 0x26, 0x666666}, 1664 {26000, 11, 1, 1, 0x24, 0xEC4EC4}, 1665 {30000, 12, 1, 1, 0x20, 0x0 }, 1666 {37400, 13, 2, 1, 0x33, 0x563EF9}, 1667 {38400, 14, 2, 1, 0x32, 0x0 }, 1668 {40000, 15, 2, 1, 0x30, 0x0 }, 1669 {48000, 16, 2, 1, 0x28, 0x0 }, 1670 {0, 0, 0, 0, 0, 0 } 1671}; 1672 1673/* table index */ 1674#define PMU1_XTALTAB0_960_12000K 0 1675#define PMU1_XTALTAB0_960_13000K 1 1676#define PMU1_XTALTAB0_960_14400K 2 1677#define PMU1_XTALTAB0_960_15360K 3 1678#define PMU1_XTALTAB0_960_16200K 4 1679#define PMU1_XTALTAB0_960_16800K 5 1680#define PMU1_XTALTAB0_960_19200K 6 1681#define PMU1_XTALTAB0_960_19800K 7 1682#define PMU1_XTALTAB0_960_20000K 8 1683#define PMU1_XTALTAB0_960_25000K 9 1684#define PMU1_XTALTAB0_960_26000K 10 1685#define PMU1_XTALTAB0_960_30000K 11 1686#define PMU1_XTALTAB0_960_37400K 12 1687#define PMU1_XTALTAB0_960_38400K 13 1688#define PMU1_XTALTAB0_960_40000K 14 1689#define PMU1_XTALTAB0_960_48000K 15 1690 1691/* select xtal table for each chip */ 1692static const pmu1_xtaltab0_t * 1693BCMINITFN(si_pmu1_xtaltab0)(si_t *sih) 1694{ 1695 switch (CHIPID(sih->chip)) { 1696 case BCM4325_CHIP_ID: 1697 return pmu1_xtaltab0_880; 1698 case BCM4329_CHIP_ID: 1699 return pmu1_xtaltab0_880_4329; 1700 case BCM4315_CHIP_ID: 1701 return pmu1_xtaltab0_1760; 1702 case BCM4319_CHIP_ID: 1703 return pmu1_xtaltab0_1440; 1704 case BCM4336_CHIP_ID: 1705 return pmu1_xtaltab0_960; 1706 case BCM4330_CHIP_ID: 1707 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 1708 return pmu1_xtaltab0_960; 1709 else 1710 return pmu1_xtaltab0_1440; 1711 default: 1712 PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 1713 break; 1714 } 1715 ASSERT(0); 1716 return NULL; 1717} 1718 1719/* select default xtal frequency for each chip */ 1720static const pmu1_xtaltab0_t * 1721BCMINITFN(si_pmu1_xtaldef0)(si_t *sih) 1722{ 1723 1724 switch (CHIPID(sih->chip)) { 1725 case BCM4325_CHIP_ID: 1726 /* Default to 26000Khz */ 1727 return &pmu1_xtaltab0_880[PMU1_XTALTAB0_880_26000K]; 1728 case BCM4329_CHIP_ID: 1729 /* Default to 38400Khz */ 1730 return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]; 1731 case BCM4315_CHIP_ID: 1732#ifdef BCMUSBDEV 1733 /* Default to 30000Khz */ 1734 return &pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_30000K]; 1735#else 1736 /* Default to 26000Khz */ 1737 return &pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_26000K]; 1738#endif 1739 case BCM4319_CHIP_ID: 1740 /* Default to 30000Khz */ 1741 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K]; 1742 case BCM4336_CHIP_ID: 1743 /* Default to 26000Khz */ 1744 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K]; 1745 case BCM4330_CHIP_ID: 1746 /* Default to 37400Khz */ 1747 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 1748 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]; 1749 else 1750 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]; 1751 default: 1752 PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 1753 break; 1754 } 1755 ASSERT(0); 1756 return NULL; 1757} 1758 1759/* select default pll fvco for each chip */ 1760static uint32 1761BCMINITFN(si_pmu1_pllfvco0)(si_t *sih) 1762{ 1763 1764 switch (CHIPID(sih->chip)) { 1765 case BCM4325_CHIP_ID: 1766 return FVCO_880; 1767 case BCM4329_CHIP_ID: 1768 return FVCO_880; 1769 case BCM4315_CHIP_ID: 1770 return FVCO_1760; 1771 case BCM4319_CHIP_ID: 1772 return FVCO_1440; 1773 case BCM4336_CHIP_ID: 1774 return FVCO_960; 1775 case BCM4330_CHIP_ID: 1776 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 1777 return FVCO_960; 1778 else 1779 return FVCO_1440; 1780 default: 1781 PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 1782 break; 1783 } 1784 ASSERT(0); 1785 return 0; 1786} 1787 1788/* query alp/xtal clock frequency */ 1789static uint32 1790BCMINITFN(si_pmu1_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 1791{ 1792 const pmu1_xtaltab0_t *xt; 1793 uint32 xf; 1794 1795 /* Find the frequency in the table */ 1796 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 1797 PCTL_XTALFREQ_SHIFT; 1798 for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++) 1799 if (xt->xf == xf) 1800 break; 1801 /* Could not find it so assign a default value */ 1802 if (xt == NULL || xt->fref == 0) 1803 xt = si_pmu1_xtaldef0(sih); 1804 ASSERT(xt != NULL && xt->fref != 0); 1805 1806 return xt->fref * 1000; 1807} 1808#endif /* !_CFE_ || CFG_WL */ 1809 1810void 1811si_pmu_minresmask_htavail_set(si_t *sih, osl_t *osh, bool set_clear) 1812{ 1813 chipcregs_t *cc; 1814 uint origidx; 1815 /* Remember original core before switch to chipc */ 1816 origidx = si_coreidx(sih); 1817 cc = si_setcoreidx(sih, SI_CC_IDX); 1818 ASSERT(cc != NULL); 1819 1820 if (!set_clear) { 1821 switch (CHIPID(sih->chip)) { 1822 case BCM4313_CHIP_ID: 1823 if ((cc->min_res_mask) & (PMURES_BIT(RES4313_HT_AVAIL_RSRC))) 1824 AND_REG(osh, &cc->min_res_mask, 1825 ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 1826 break; 1827 default: 1828 break; 1829 } 1830 } 1831 1832 /* Return to original core */ 1833 si_setcoreidx(sih, origidx); 1834} 1835 1836#if !defined(_CFE_) || defined(CFG_WL) 1837/* Set up PLL registers in the PMU as per the crystal speed. 1838 * XtalFreq field in pmucontrol register being 0 indicates the PLL 1839 * is not programmed and the h/w default is assumed to work, in which 1840 * case the xtal frequency is unknown to the s/w so we need to call 1841 * si_pmu1_xtaldef0() wherever it is needed to return a default value. 1842 */ 1843static void 1844BCMATTACHFN(si_pmu1_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal) 1845{ 1846 const pmu1_xtaltab0_t *xt; 1847 uint32 tmp; 1848 uint32 buf_strength = 0; 1849 uint8 ndiv_mode = 1; 1850 uint32 FVCO = si_pmu1_pllfvco0(sih); 1851 uint8 dacrate; 1852 1853 FVCO = FVCO/1000; 1854 1855 /* Use h/w default PLL config */ 1856 if (xtal == 0) { 1857 PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n")); 1858 return; 1859 } 1860 1861 /* Find the frequency in the table */ 1862 for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++) 1863 if (xt->fref == xtal) 1864 break; 1865 1866 /* Check current PLL state, bail out if it has been programmed or 1867 * we don't know how to program it. 1868 */ 1869 if (xt == NULL || xt->fref == 0) { 1870 PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", 1871 xtal / 1000, xtal % 1000)); 1872 return; 1873 } 1874 /* for 4319 bootloader already programs the PLL but bootloader does not program the 1875 PLL4 and PLL5. So Skip this check for 4319 1876 */ 1877 if ((((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 1878 PCTL_XTALFREQ_SHIFT) == xt->xf) && 1879 !((CHIPID(sih->chip) == BCM4319_CHIP_ID) || (CHIPID(sih->chip) == BCM4330_CHIP_ID))) 1880 { 1881 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 1882 xt->fref / 1000, xt->fref % 1000)); 1883 return; 1884 } 1885 1886 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); 1887 PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000)); 1888 1889 switch (CHIPID(sih->chip)) { 1890 case BCM4325_CHIP_ID: 1891 /* Change the BBPLL drive strength to 2 for all channels */ 1892 buf_strength = 0x222222; 1893 /* Make sure the PLL is off */ 1894 AND_REG(osh, &cc->min_res_mask, 1895 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL))); 1896 AND_REG(osh, &cc->max_res_mask, 1897 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL))); 1898 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1899 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 1900 break; 1901 case BCM4329_CHIP_ID: 1902 /* Change the BBPLL drive strength to 8 for all channels */ 1903 buf_strength = 0x888888; 1904 AND_REG(osh, &cc->min_res_mask, 1905 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL))); 1906 AND_REG(osh, &cc->max_res_mask, 1907 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL))); 1908 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1909 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 1910 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 1911 if (xt->fref == 38400) 1912 tmp = 0x200024C0; 1913 else if (xt->fref == 37400) 1914 tmp = 0x20004500; 1915 else if (xt->fref == 26000) 1916 tmp = 0x200024C0; 1917 else 1918 tmp = 0x200005C0; /* Chip Dflt Settings */ 1919 W_REG(osh, &cc->pllcontrol_data, tmp); 1920 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 1921 tmp = R_REG(osh, &cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK; 1922 if ((xt->fref == 38400) || (xt->fref == 37400) || (xt->fref == 26000)) 1923 tmp |= 0x15; 1924 else 1925 tmp |= 0x25; /* Chip Dflt Settings */ 1926 W_REG(osh, &cc->pllcontrol_data, tmp); 1927 break; 1928 case BCM4315_CHIP_ID: 1929 /* Change the BBPLL drive strength to 2 for all channels */ 1930 buf_strength = 0x222222; 1931 /* Make sure the PLL is off */ 1932 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4315_HT_AVAIL))); 1933 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4315_HT_AVAIL))); 1934 OSL_DELAY(100); 1935 1936 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU))); 1937 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU))); 1938 OSL_DELAY(100); 1939 1940 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1941 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 1942 break; 1943 1944 case BCM4319_CHIP_ID: 1945 /* Change the BBPLL drive strength to 2 for all channels */ 1946 buf_strength = 0x222222; 1947 1948 /* Make sure the PLL is off */ 1949 /* WAR65104: Disable the HT_AVAIL resource first and then 1950 * after a delay (more than downtime for HT_AVAIL) remove the 1951 * BBPLL resource; backplane clock moves to ALP from HT. 1952 */ 1953 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4319_HT_AVAIL))); 1954 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4319_HT_AVAIL))); 1955 1956 OSL_DELAY(100); 1957 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 1958 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 1959 1960 OSL_DELAY(100); 1961 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1962 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 1963 break; 1964 1965 case BCM4336_CHIP_ID: 1966 AND_REG(osh, &cc->min_res_mask, 1967 ~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 1968 AND_REG(osh, &cc->max_res_mask, 1969 ~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 1970 OSL_DELAY(100); 1971 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1972 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 1973 break; 1974 1975 case BCM4330_CHIP_ID: 1976 AND_REG(osh, &cc->min_res_mask, 1977 ~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 1978 AND_REG(osh, &cc->max_res_mask, 1979 ~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 1980 OSL_DELAY(100); 1981 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 1982 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 1983 break; 1984 1985 default: 1986 ASSERT(0); 1987 } 1988 1989 PMU_MSG(("Done masking\n")); 1990 1991 /* Write p1div and p2div to pllcontrol[0] */ 1992 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 1993 tmp = R_REG(osh, &cc->pllcontrol_data) & 1994 ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK); 1995 tmp |= ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | 1996 ((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK); 1997 1998 if (CHIPID(sih->chip) == BCM4319_CHIP_ID) { 1999 tmp &= ~(PMU1_PLL0_PC0_BYPASS_SDMOD_MASK); 2000 if (!(xt->ndiv_frac)) 2001 tmp |= (1<<(PMU1_PLL0_PC0_BYPASS_SDMOD_SHIFT)); 2002 else 2003 tmp |= (0<<(PMU1_PLL0_PC0_BYPASS_SDMOD_SHIFT)); 2004 } 2005 2006 W_REG(osh, &cc->pllcontrol_data, tmp); 2007 2008 if ((CHIPID(sih->chip) == BCM4330_CHIP_ID)) { 2009 if (CHIPREV(sih->chiprev) < 2) 2010 dacrate = 160; 2011 else { 2012 if (!(dacrate = (uint8)getintvar(NULL, "dacrate2g"))) 2013 dacrate = 80; 2014 } 2015 si_pmu_set_4330_plldivs(sih, dacrate); 2016 } 2017 2018 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (CHIPREV(sih->chiprev) == 0)) { 2019 2020 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 2021 tmp = R_REG(osh, &cc->pllcontrol_data); 2022 tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK); 2023 tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL; 2024 W_REG(osh, &cc->pllcontrol_data, tmp); 2025 } 2026 if ((CHIPID(sih->chip) == BCM4336_CHIP_ID) || 2027 (CHIPID(sih->chip) == BCM4330_CHIP_ID)) 2028 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB; 2029 else 2030 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH; 2031 2032 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID)) { 2033 if (!(xt->ndiv_frac)) 2034 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_INT; 2035 else 2036 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB; 2037#ifdef BCMQT 2038 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 2039 tmp = 0x120F1010; 2040 W_REG(osh, &cc->pllcontrol_data, tmp); 2041#endif 2042 } 2043 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ 2044 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 2045 tmp = R_REG(osh, &cc->pllcontrol_data) & 2046 ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK); 2047 tmp |= ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK) | 2048 ((ndiv_mode << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK); 2049 W_REG(osh, &cc->pllcontrol_data, tmp); 2050 2051 /* Write ndiv_frac to pllcontrol[3] */ 2052 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 2053 tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; 2054 tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) & 2055 PMU1_PLL0_PC3_NDIV_FRAC_MASK); 2056 W_REG(osh, &cc->pllcontrol_data, tmp); 2057 2058 /* Writing to pllcontrol[4] */ 2059 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID)) { 2060 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 2061 if (!(xt->ndiv_frac)) 2062 tmp = 0x200005c0; 2063 else 2064 tmp = 0x202C2820; 2065 2066 tmp &= ~(PMU1_PLL0_PC4_KVCO_XS_MASK); 2067 2068 if (FVCO < 1600) 2069 tmp |= (4<<PMU1_PLL0_PC4_KVCO_XS_SHIFT); 2070 else 2071 tmp |= (7<<PMU1_PLL0_PC4_KVCO_XS_SHIFT); 2072 2073 W_REG(osh, &cc->pllcontrol_data, tmp); 2074 } 2075 2076 /* Write clock driving strength to pllcontrol[5] */ 2077 if (buf_strength) { 2078 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength)); 2079 2080 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 2081 tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; 2082 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT); 2083 2084 if (CHIPID(sih->chip) == BCM4319_CHIP_ID) { 2085 tmp &= ~(PMU1_PLL0_PC5_VCO_RNG_MASK | PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK); 2086 if (!(xt->ndiv_frac)) 2087 tmp |= (0x25<<(PMU1_PLL0_PC5_PLL_CTRL_37_32_SHIFT)); 2088 else 2089 tmp |= (0x15<<(PMU1_PLL0_PC5_PLL_CTRL_37_32_SHIFT)); 2090 2091 if (FVCO < 1600) 2092 tmp |= (0x0<<(PMU1_PLL0_PC5_VCO_RNG_SHIFT)); 2093 else 2094 tmp |= (0x1<<(PMU1_PLL0_PC5_VCO_RNG_SHIFT)); 2095 } 2096 W_REG(osh, &cc->pllcontrol_data, tmp); 2097 } 2098 2099 PMU_MSG(("Done pll\n")); 2100 2101 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs 2102 * to be updated. 2103 */ 2104 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && (xt->fref != XTAL_FREQ_30000MHZ)) { 2105 W_REG(osh, &cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2); 2106 tmp = R_REG(osh, &cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK; 2107 if (xt->fref == XTAL_FREQ_24000MHZ) { 2108 tmp |= (CCTL_4319USB_24MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT); 2109 } else if (xt->fref == XTAL_FREQ_48000MHZ) { 2110 tmp |= (CCTL_4319USB_48MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT); 2111 } 2112 W_REG(osh, &cc->chipcontrol_data, tmp); 2113 } 2114 2115 /* Flush deferred pll control registers writes */ 2116 if (sih->pmurev >= 2) 2117 OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 2118 2119 /* Write XtalFreq. Set the divisor also. */ 2120 tmp = R_REG(osh, &cc->pmucontrol) & 2121 ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); 2122 tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & 2123 PCTL_ILP_DIV_MASK) | 2124 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); 2125 2126 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && CHIPREV(sih->chiprev) == 0) { 2127 /* clear the htstretch before clearing HTReqEn */ 2128 AND_REG(osh, &cc->clkstretch, ~CSTRETCH_HT); 2129 tmp &= ~PCTL_HT_REQ_EN; 2130 } 2131 2132 W_REG(osh, &cc->pmucontrol, tmp); 2133} 2134 2135/* query the CPU clock frequency */ 2136static uint32 2137BCMINITFN(si_pmu1_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 2138{ 2139 uint32 tmp, m1div; 2140 uint32 FVCO = si_pmu1_pllfvco0(sih); 2141 2142 /* Read m1div from pllcontrol[1] */ 2143 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 2144 tmp = R_REG(osh, &cc->pllcontrol_data); 2145 m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; 2146 2147 2148 /* Return ARM/SB clock */ 2149 return FVCO / m1div * 1000; 2150} 2151#endif /* !_CFE_ || CFG_WL */ 2152 2153/* initialize PLL */ 2154void 2155BCMATTACHFN(si_pmu_pll_init)(si_t *sih, osl_t *osh, uint xtalfreq) 2156{ 2157 chipcregs_t *cc; 2158 uint origidx; 2159 2160 ASSERT(sih->cccaps & CC_CAP_PMU); 2161 2162 /* Remember original core before switch to chipc */ 2163 origidx = si_coreidx(sih); 2164 cc = si_setcoreidx(sih, SI_CC_IDX); 2165 ASSERT(cc != NULL); 2166 2167 switch (CHIPID(sih->chip)) { 2168 case BCM5354_CHIP_ID: 2169 if (xtalfreq == 0) 2170 xtalfreq = 25000; 2171 si_pmu0_pllinit0(sih, osh, cc, xtalfreq); 2172 break; 2173#if !defined(_CFE_) || defined(CFG_WL) 2174 case BCM4328_CHIP_ID: 2175 si_pmu0_pllinit0(sih, osh, cc, xtalfreq); 2176 break; 2177 case BCM4325_CHIP_ID: 2178 si_pmu1_pllinit0(sih, osh, cc, xtalfreq); 2179 break; 2180 case BCM4329_CHIP_ID: 2181 if (xtalfreq == 0) 2182 xtalfreq = 38400; 2183 si_pmu1_pllinit0(sih, osh, cc, xtalfreq); 2184 break; 2185 case BCM4312_CHIP_ID: 2186 /* assume default works */ 2187 break; 2188 case BCM4322_CHIP_ID: 2189 case BCM43221_CHIP_ID: 2190 case BCM43231_CHIP_ID: 2191 case BCM4342_CHIP_ID: { 2192 if (CHIPREV(sih->chiprev) == 0) { 2193 uint32 minmask, maxmask; 2194 2195 minmask = R_REG(osh, &cc->min_res_mask); 2196 maxmask = R_REG(osh, &cc->max_res_mask); 2197 2198 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */ 2199 /* Have to remove HT Avail request before powering off PLL */ 2200 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 2201 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 2202 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 2203 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 2204 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 2205 OSL_DELAY(1000); 2206 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 2207 2208 2209 W_REG(osh, &cc->pllcontrol_addr, PMU2_SI_PLL_PLLCTL); 2210 W_REG(osh, &cc->pllcontrol_data, 0x380005c0); 2211 2212 2213 OSL_DELAY(100); 2214 W_REG(osh, &cc->max_res_mask, maxmask); 2215 OSL_DELAY(100); 2216 W_REG(osh, &cc->min_res_mask, minmask); 2217 OSL_DELAY(100); 2218 } 2219 2220 break; 2221 } 2222 case BCM4313_CHIP_ID: 2223 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 2224 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43420_CHIP_ID: 2225 case BCM43421_CHIP_ID: 2226 case BCM43226_CHIP_ID: 2227 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 2228 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: 2229 case BCM4331_CHIP_ID: case BCM43431_CHIP_ID: 2230 case BCM43227_CHIP_ID: 2231 case BCM43228_CHIP_ID: 2232 case BCM43428_CHIP_ID: 2233 case BCM6362_CHIP_ID: 2234 break; 2235 case BCM4315_CHIP_ID: 2236 case BCM4319_CHIP_ID: 2237 case BCM4336_CHIP_ID: 2238 case BCM4330_CHIP_ID: 2239 si_pmu1_pllinit0(sih, osh, cc, xtalfreq); 2240 break; 2241#endif /* !_CFE_ || CFG_WL */ 2242 default: 2243 PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n", 2244 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); 2245 break; 2246 } 2247 2248#ifdef BCMDBG_FORCEHT 2249 OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT); 2250#endif 2251 2252 /* Return to original core */ 2253 si_setcoreidx(sih, origidx); 2254} 2255 2256/* query alp/xtal clock frequency */ 2257uint32 2258BCMINITFN(si_pmu_alp_clock)(si_t *sih, osl_t *osh) 2259{ 2260 chipcregs_t *cc; 2261 uint origidx; 2262 uint32 clock = ALP_CLOCK; 2263 2264 ASSERT(sih->cccaps & CC_CAP_PMU); 2265 2266 /* Remember original core before switch to chipc */ 2267 origidx = si_coreidx(sih); 2268 cc = si_setcoreidx(sih, SI_CC_IDX); 2269 ASSERT(cc != NULL); 2270 2271 switch (CHIPID(sih->chip)) { 2272 case BCM4328_CHIP_ID: 2273 clock = si_pmu0_alpclk0(sih, osh, cc); 2274 break; 2275 case BCM5354_CHIP_ID: 2276 clock = si_pmu0_alpclk0(sih, osh, cc); 2277 break; 2278#if !defined(_CFE_) || defined(CFG_WL) 2279 case BCM4325_CHIP_ID: 2280 case BCM4329_CHIP_ID: 2281 case BCM4315_CHIP_ID: 2282 case BCM4319_CHIP_ID: 2283 case BCM4336_CHIP_ID: 2284 case BCM4330_CHIP_ID: 2285 clock = si_pmu1_alpclk0(sih, osh, cc); 2286 break; 2287#endif /* !_CFE_ || CFG_WL */ 2288 case BCM4312_CHIP_ID: 2289 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 2290 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 2291 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43420_CHIP_ID: 2292 case BCM43421_CHIP_ID: 2293 case BCM43226_CHIP_ID: 2294 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 2295 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: 2296 case BCM4331_CHIP_ID: case BCM43431_CHIP_ID: 2297 case BCM43227_CHIP_ID: 2298 case BCM43228_CHIP_ID: 2299 case BCM43428_CHIP_ID: 2300 case BCM6362_CHIP_ID: 2301 case BCM4342_CHIP_ID: 2302 case BCM4716_CHIP_ID: 2303 case BCM4748_CHIP_ID: 2304 case BCM47162_CHIP_ID: 2305 case BCM4313_CHIP_ID: 2306 case BCM5357_CHIP_ID: 2307 case BCM4749_CHIP_ID: 2308 case BCM53572_CHIP_ID: 2309 /* always 20Mhz */ 2310 clock = 20000 * 1000; 2311 break; 2312 case BCM5356_CHIP_ID: 2313 case BCM4706_CHIP_ID: 2314 /* always 25Mhz */ 2315 clock = 25000 * 1000; 2316 break; 2317 default: 2318 PMU_MSG(("No ALP clock specified " 2319 "for chip %s rev %d pmurev %d, using default %d Hz\n", 2320 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev, clock)); 2321 break; 2322 } 2323 2324 /* Return to original core */ 2325 si_setcoreidx(sih, origidx); 2326 return clock; 2327} 2328 2329/* Find the output of the "m" pll divider given pll controls that start with 2330 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. 2331 */ 2332static uint32 2333BCMINITFN(si_pmu5_clock)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, uint m) 2334{ 2335 uint32 tmp, div, ndiv, p1, p2, fc; 2336 2337 if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) { 2338 PMU_ERROR(("%s: Bad pll0: %d\n", __FUNCTION__, pll0)); 2339 return 0; 2340 } 2341 2342 2343 /* Strictly there is an m5 divider, but I'm not sure we use it */ 2344 if ((m == 0) || (m > 4)) { 2345 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__, m)); 2346 return 0; 2347 } 2348 2349 if ((CHIPID(sih->chip) == BCM5357_CHIP_ID) || 2350 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) { 2351 /* Detect failure in clock setting */ 2352 if ((R_REG(osh, &cc->chipstatus) & 0x40000) != 0) { 2353 return (133 * 1000000); 2354 } 2355 } 2356 2357 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF); 2358 (void)R_REG(osh, &cc->pllcontrol_addr); 2359 tmp = R_REG(osh, &cc->pllcontrol_data); 2360 p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT; 2361 p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT; 2362 2363 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF); 2364 (void)R_REG(osh, &cc->pllcontrol_addr); 2365 tmp = R_REG(osh, &cc->pllcontrol_data); 2366 div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK; 2367 2368 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF); 2369 (void)R_REG(osh, &cc->pllcontrol_addr); 2370 tmp = R_REG(osh, &cc->pllcontrol_data); 2371 ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT; 2372 2373 /* Do calculation in Mhz */ 2374 fc = si_pmu_alp_clock(sih, osh) / 1000000; 2375 fc = (p1 * ndiv * fc) / p2; 2376 2377 PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n", 2378 __FUNCTION__, p1, p2, ndiv, ndiv, m, div, fc, fc / div)); 2379 2380 /* Return clock in Hertz */ 2381 return ((fc / div) * 1000000); 2382} 2383 2384static uint32 2385BCMINITFN(si_4706_pmu_clock)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, uint m) 2386{ 2387 uint32 w; 2388 uint32 clock; 2389 2390 /* Strictly there is an m5 divider, but I'm not sure we use it */ 2391 if ((m == 0) || (m > 4)) { 2392 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__, m)); 2393 return 0; 2394 } 2395 2396 /* Get N divider to determine CPU clock */ 2397 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU6_4706_PROCPLL_OFF); 2398 w = (R_REG(NULL, &cc->pllcontrol_data) & PMU6_4706_PROC_NDIV_INT_MASK) >> 2399 PMU6_4706_PROC_NDIV_INT_SHIFT; 2400 /* Fixed reference clock 25MHz and m = 2 */ 2401 clock = w * 25000000 / 2; 2402 if (m == PMU5_MAINPLL_MEM) 2403 clock = clock / 2; 2404 else if (m == PMU5_MAINPLL_SI) 2405 clock = clock / 4; 2406 2407 return clock; 2408} 2409 2410/* query backplane clock frequency */ 2411/* For designs that feed the same clock to both backplane 2412 * and CPU just return the CPU clock speed. 2413 */ 2414uint32 2415BCMINITFN(si_pmu_si_clock)(si_t *sih, osl_t *osh) 2416{ 2417 chipcregs_t *cc; 2418 uint origidx; 2419 uint32 clock = HT_CLOCK; 2420 2421 ASSERT(sih->cccaps & CC_CAP_PMU); 2422 2423 /* Remember original core before switch to chipc */ 2424 origidx = si_coreidx(sih); 2425 cc = si_setcoreidx(sih, SI_CC_IDX); 2426 ASSERT(cc != NULL); 2427 2428 switch (CHIPID(sih->chip)) { 2429#if !defined(_CFE_) || defined(CFG_WL) 2430 case BCM4328_CHIP_ID: 2431 clock = si_pmu0_cpuclk0(sih, osh, cc); 2432 break; 2433 case BCM4325_CHIP_ID: 2434 clock = si_pmu1_cpuclk0(sih, osh, cc); 2435 break; 2436 case BCM4322_CHIP_ID: 2437 case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 2438 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 2439 case BCM43224_CHIP_ID: case BCM43420_CHIP_ID: 2440 case BCM43225_CHIP_ID: 2441 case BCM43421_CHIP_ID: 2442 case BCM43226_CHIP_ID: 2443 case BCM4331_CHIP_ID: case BCM43431_CHIP_ID: 2444 case BCM6362_CHIP_ID: 2445 case BCM4342_CHIP_ID: 2446 /* 96MHz backplane clock */ 2447 clock = 96000 * 1000; 2448 break; 2449 case BCM4329_CHIP_ID: 2450 if (CHIPREV(sih->chiprev) == 0) 2451 clock = 38400 * 1000; 2452 else 2453 clock = si_pmu1_cpuclk0(sih, osh, cc); 2454 break; 2455 case BCM4315_CHIP_ID: 2456 case BCM4319_CHIP_ID: 2457 case BCM4336_CHIP_ID: 2458 case BCM4330_CHIP_ID: 2459 clock = si_pmu1_cpuclk0(sih, osh, cc); 2460 break; 2461 case BCM4313_CHIP_ID: 2462 /* 80MHz backplane clock */ 2463 clock = 80000 * 1000; 2464 break; 2465 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 2466 case BCM43234_CHIP_ID: 2467 clock = (cc->chipstatus & CST43236_BP_CLK) ? (120000 * 1000) : (96000 * 1000); 2468 break; 2469 case BCM43237_CHIP_ID: 2470 clock = (cc->chipstatus & CST43237_BP_CLK) ? (96000 * 1000) : (80000 * 1000); 2471 break; 2472#endif /* !_CFE_ || CFG_WL */ 2473 case BCM5354_CHIP_ID: 2474 clock = 120000000; 2475 break; 2476 case BCM4716_CHIP_ID: 2477 case BCM4748_CHIP_ID: 2478 case BCM47162_CHIP_ID: 2479 clock = si_pmu5_clock(sih, osh, cc, PMU4716_MAINPLL_PLL0, PMU5_MAINPLL_SI); 2480 break; 2481 case BCM5356_CHIP_ID: 2482 clock = si_pmu5_clock(sih, osh, cc, PMU5356_MAINPLL_PLL0, PMU5_MAINPLL_SI); 2483 break; 2484 case BCM5357_CHIP_ID: 2485 case BCM4749_CHIP_ID: 2486 clock = si_pmu5_clock(sih, osh, cc, PMU5357_MAINPLL_PLL0, PMU5_MAINPLL_SI); 2487 break; 2488 case BCM4706_CHIP_ID: 2489 clock = si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_SI); 2490 break; 2491 case BCM53572_CHIP_ID: 2492 clock = 75000000; 2493 break; 2494 default: 2495 PMU_MSG(("No backplane clock specified " 2496 "for chip %s rev %d pmurev %d, using default %d Hz\n", 2497 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev, clock)); 2498 break; 2499 } 2500 2501 /* Return to original core */ 2502 si_setcoreidx(sih, origidx); 2503 return clock; 2504} 2505 2506/* query CPU clock frequency */ 2507uint32 2508BCMINITFN(si_pmu_cpu_clock)(si_t *sih, osl_t *osh) 2509{ 2510 chipcregs_t *cc; 2511 uint origidx; 2512 uint32 clock; 2513 2514 ASSERT(sih->cccaps & CC_CAP_PMU); 2515 2516 /* 5354 chip uses a non programmable PLL of frequency 240MHz */ 2517 if (CHIPID(sih->chip) == BCM5354_CHIP_ID) 2518 return 240000000; 2519 2520 if (CHIPID(sih->chip) == BCM53572_CHIP_ID) 2521 return 300000000; 2522 2523 if ((sih->pmurev >= 5) && 2524 !((CHIPID(sih->chip) == BCM4329_CHIP_ID) || 2525 (CHIPID(sih->chip) == BCM4319_CHIP_ID) || 2526 (CHIPID(sih->chip) == BCM43234_CHIP_ID) || 2527 (CHIPID(sih->chip) == BCM43235_CHIP_ID) || 2528 (CHIPID(sih->chip) == BCM43236_CHIP_ID) || 2529 (CHIPID(sih->chip) == BCM43237_CHIP_ID) || 2530 (CHIPID(sih->chip) == BCM43238_CHIP_ID) || 2531 (CHIPID(sih->chip) == BCM4336_CHIP_ID) || 2532 (CHIPID(sih->chip) == BCM4330_CHIP_ID))) { 2533 uint pll; 2534 2535 switch (CHIPID(sih->chip)) { 2536 case BCM5356_CHIP_ID: 2537 pll = PMU5356_MAINPLL_PLL0; 2538 break; 2539 case BCM5357_CHIP_ID: 2540 case BCM4749_CHIP_ID: 2541 pll = PMU5357_MAINPLL_PLL0; 2542 break; 2543 default: 2544 pll = PMU4716_MAINPLL_PLL0; 2545 break; 2546 } 2547 2548 /* Remember original core before switch to chipc */ 2549 origidx = si_coreidx(sih); 2550 cc = si_setcoreidx(sih, SI_CC_IDX); 2551 ASSERT(cc != NULL); 2552 2553 if (CHIPID(sih->chip) == BCM4706_CHIP_ID) 2554 clock = si_4706_pmu_clock(sih, osh, cc, 2555 PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); 2556 else 2557 clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_CPU); 2558 2559 /* Return to original core */ 2560 si_setcoreidx(sih, origidx); 2561 } else 2562 clock = si_pmu_si_clock(sih, osh); 2563 2564 return clock; 2565} 2566 2567/* query memory clock frequency */ 2568uint32 2569BCMINITFN(si_pmu_mem_clock)(si_t *sih, osl_t *osh) 2570{ 2571 chipcregs_t *cc; 2572 uint origidx; 2573 uint32 clock; 2574 2575 ASSERT(sih->cccaps & CC_CAP_PMU); 2576 2577 if (CHIPID(sih->chip) == BCM53572_CHIP_ID) 2578 return 150000000; 2579 2580 if ((sih->pmurev >= 5) && 2581 !((CHIPID(sih->chip) == BCM4329_CHIP_ID) || 2582 (CHIPID(sih->chip) == BCM4319_CHIP_ID) || 2583 (CHIPID(sih->chip) == BCM4330_CHIP_ID) || 2584 (CHIPID(sih->chip) == BCM4336_CHIP_ID) || 2585 (CHIPID(sih->chip) == BCM43234_CHIP_ID) || 2586 (CHIPID(sih->chip) == BCM43235_CHIP_ID) || 2587 (CHIPID(sih->chip) == BCM43236_CHIP_ID) || 2588 (CHIPID(sih->chip) == BCM43237_CHIP_ID) || 2589 (CHIPID(sih->chip) == BCM43238_CHIP_ID) || 2590 0)) { 2591 uint pll; 2592 2593 switch (CHIPID(sih->chip)) { 2594 case BCM5356_CHIP_ID: 2595 pll = PMU5356_MAINPLL_PLL0; 2596 break; 2597 case BCM5357_CHIP_ID: 2598 case BCM4749_CHIP_ID: 2599 pll = PMU5357_MAINPLL_PLL0; 2600 break; 2601 default: 2602 pll = PMU4716_MAINPLL_PLL0; 2603 break; 2604 } 2605 2606 /* Remember original core before switch to chipc */ 2607 origidx = si_coreidx(sih); 2608 cc = si_setcoreidx(sih, SI_CC_IDX); 2609 ASSERT(cc != NULL); 2610 2611 if (CHIPID(sih->chip) == BCM4706_CHIP_ID) 2612 clock = si_4706_pmu_clock(sih, osh, cc, 2613 PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_MEM); 2614 else 2615 clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_MEM); 2616 2617 /* Return to original core */ 2618 si_setcoreidx(sih, origidx); 2619 } else { 2620 clock = si_pmu_si_clock(sih, osh); 2621 } 2622 2623 return clock; 2624} 2625 2626/* Measure ILP clock frequency */ 2627#define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */ 2628 2629static uint32 ilpcycles_per_sec = 0; 2630 2631uint32 2632BCMINITFN(si_pmu_ilp_clock)(si_t *sih, osl_t *osh) 2633{ 2634 if (ISSIM_ENAB(sih)) 2635 return ILP_CLOCK; 2636 2637 if (ilpcycles_per_sec == 0) { 2638 uint32 start, end, delta; 2639 uint32 origidx = si_coreidx(sih); 2640 chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX); 2641 ASSERT(cc != NULL); 2642 start = R_REG(osh, &cc->pmutimer); 2643 OSL_DELAY(ILP_CALC_DUR * 1000); 2644 end = R_REG(osh, &cc->pmutimer); 2645 delta = end - start; 2646 ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); 2647 si_setcoreidx(sih, origidx); 2648 } 2649 2650 return ilpcycles_per_sec; 2651} 2652 2653/* SDIO Pad drive strength to select value mappings */ 2654typedef struct { 2655 uint8 strength; /* Pad Drive Strength in mA */ 2656 uint8 sel; /* Chip-specific select value */ 2657} sdiod_drive_str_t; 2658 2659/* SDIO Drive Strength to sel value table for PMU Rev 1 */ 2660static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab1)[] = { 2661 {4, 0x2}, 2662 {2, 0x3}, 2663 {1, 0x0}, 2664 {0, 0x0} }; 2665 2666/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ 2667static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab2)[] = { 2668 {12, 0x7}, 2669 {10, 0x6}, 2670 {8, 0x5}, 2671 {6, 0x4}, 2672 {4, 0x2}, 2673 {2, 0x1}, 2674 {0, 0x0} }; 2675 2676/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ 2677static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab3)[] = { 2678 {32, 0x7}, 2679 {26, 0x6}, 2680 {22, 0x5}, 2681 {16, 0x4}, 2682 {12, 0x3}, 2683 {8, 0x2}, 2684 {4, 0x1}, 2685 {0, 0x0} }; 2686 2687#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 2688 2689void 2690BCMINITFN(si_sdiod_drive_strength_init)(si_t *sih, osl_t *osh, uint32 drivestrength) 2691{ 2692 chipcregs_t *cc; 2693 uint origidx, intr_val = 0; 2694 sdiod_drive_str_t *str_tab = NULL; 2695 uint32 str_mask = 0; 2696 uint32 str_shift = 0; 2697 2698 if (!(sih->cccaps & CC_CAP_PMU)) { 2699 return; 2700 } 2701 2702 /* Remember original core before switch to chipc */ 2703 cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 2704 2705 switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { 2706 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): 2707 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; 2708 str_mask = 0x30000000; 2709 str_shift = 28; 2710 break; 2711 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): 2712 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): 2713 case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4): 2714 case SDIOD_DRVSTR_KEY(BCM4319_CHIP_ID, 7): 2715 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; 2716 str_mask = 0x00003800; 2717 str_shift = 11; 2718 break; 2719 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): 2720 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab3; 2721 str_mask = 0x00003800; 2722 str_shift = 11; 2723 break; 2724 2725 default: 2726 PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", 2727 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); 2728 2729 break; 2730 } 2731 2732 if (str_tab != NULL) { 2733 uint32 drivestrength_sel = 0; 2734 uint32 cc_data_temp; 2735 int i; 2736 2737 for (i = 0; str_tab[i].strength != 0; i ++) { 2738 if (drivestrength >= str_tab[i].strength) { 2739 drivestrength_sel = str_tab[i].sel; 2740 break; 2741 } 2742 } 2743 2744 W_REG(osh, &cc->chipcontrol_addr, 1); 2745 cc_data_temp = R_REG(osh, &cc->chipcontrol_data); 2746 cc_data_temp &= ~str_mask; 2747 drivestrength_sel <<= str_shift; 2748 cc_data_temp |= drivestrength_sel; 2749 W_REG(osh, &cc->chipcontrol_data, cc_data_temp); 2750 2751 PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n", 2752 drivestrength, cc_data_temp)); 2753 } 2754 2755 /* Return to original core */ 2756 si_restore_core(sih, origidx, intr_val); 2757} 2758 2759/* initialize PMU */ 2760void 2761BCMATTACHFN(si_pmu_init)(si_t *sih, osl_t *osh) 2762{ 2763 chipcregs_t *cc; 2764 uint origidx; 2765 2766 ASSERT(sih->cccaps & CC_CAP_PMU); 2767 2768 /* Remember original core before switch to chipc */ 2769 origidx = si_coreidx(sih); 2770 cc = si_setcoreidx(sih, SI_CC_IDX); 2771 ASSERT(cc != NULL); 2772 2773 if (sih->pmurev == 1) 2774 AND_REG(osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); 2775 else if (sih->pmurev >= 2) 2776 OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT); 2777 2778#if !defined(_CFE_) || defined(CFG_WL) 2779 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 2)) { 2780 /* Fix for 4329b0 bad LPOM state. */ 2781 W_REG(osh, &cc->regcontrol_addr, 2); 2782 OR_REG(osh, &cc->regcontrol_data, 0x100); 2783 2784 W_REG(osh, &cc->regcontrol_addr, 3); 2785 OR_REG(osh, &cc->regcontrol_data, 0x4); 2786 } 2787 2788 if (CHIPID(sih->chip) == BCM4319_CHIP_ID) { 2789 /* Limiting the PALDO spike during init time */ 2790 si_pmu_regcontrol(sih, 2, 0x00000007, 0x00000005); 2791 } 2792#endif /* !_CFE_ || CFG_WL */ 2793 2794 /* Return to original core */ 2795 si_setcoreidx(sih, origidx); 2796} 2797 2798#if !defined(_CFE_) || defined(CFG_WL) 2799/* Return up time in ILP cycles for the given resource. */ 2800static uint 2801BCMINITFN(si_pmu_res_uptime)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 rsrc) 2802{ 2803 uint32 deps; 2804 uint up, i, dup, dmax; 2805 uint32 min_mask = 0, max_mask = 0; 2806 2807 /* uptime of resource 'rsrc' */ 2808 W_REG(osh, &cc->res_table_sel, rsrc); 2809 up = (R_REG(osh, &cc->res_updn_timer) >> 8) & 0xff; 2810 2811 /* direct dependancies of resource 'rsrc' */ 2812 deps = si_pmu_res_deps(sih, osh, cc, PMURES_BIT(rsrc), FALSE); 2813 for (i = 0; i <= PMURES_MAX_RESNUM; i ++) { 2814 if (!(deps & PMURES_BIT(i))) 2815 continue; 2816 deps &= ~si_pmu_res_deps(sih, osh, cc, PMURES_BIT(i), TRUE); 2817 } 2818 si_pmu_res_masks(sih, &min_mask, &max_mask); 2819 deps &= ~min_mask; 2820 2821 /* max uptime of direct dependancies */ 2822 dmax = 0; 2823 for (i = 0; i <= PMURES_MAX_RESNUM; i ++) { 2824 if (!(deps & PMURES_BIT(i))) 2825 continue; 2826 dup = si_pmu_res_uptime(sih, osh, cc, (uint8)i); 2827 if (dmax < dup) 2828 dmax = dup; 2829 } 2830 2831 PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n", 2832 rsrc, up, deps, dmax)); 2833 2834 return up + dmax + PMURES_UP_TRANSITION; 2835} 2836 2837/* Return dependancies (direct or all/indirect) for the given resources */ 2838static uint32 2839si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs, bool all) 2840{ 2841 uint32 deps = 0; 2842 uint32 i; 2843 2844 for (i = 0; i <= PMURES_MAX_RESNUM; i ++) { 2845 if (!(rsrcs & PMURES_BIT(i))) 2846 continue; 2847 W_REG(osh, &cc->res_table_sel, i); 2848 deps |= R_REG(osh, &cc->res_dep_mask); 2849 } 2850 2851 return !all ? deps : (deps ? (deps | si_pmu_res_deps(sih, osh, cc, deps, TRUE)) : 0); 2852} 2853 2854/* power up/down OTP through PMU resources */ 2855void 2856si_pmu_otp_power(si_t *sih, osl_t *osh, bool on) 2857{ 2858 chipcregs_t *cc; 2859 uint origidx; 2860 uint32 rsrcs = 0; /* rsrcs to turn on/off OTP power */ 2861 2862 ASSERT(sih->cccaps & CC_CAP_PMU); 2863 2864 /* Don't do anything if OTP is disabled */ 2865 if (si_is_otp_disabled(sih)) { 2866 PMU_MSG(("si_pmu_otp_power: OTP is disabled\n")); 2867 return; 2868 } 2869 2870 /* Remember original core before switch to chipc */ 2871 origidx = si_coreidx(sih); 2872 cc = si_setcoreidx(sih, SI_CC_IDX); 2873 ASSERT(cc != NULL); 2874 2875 switch (CHIPID(sih->chip)) { 2876 case BCM4322_CHIP_ID: 2877 case BCM43221_CHIP_ID: 2878 case BCM43231_CHIP_ID: 2879 case BCM4342_CHIP_ID: 2880 rsrcs = PMURES_BIT(RES4322_OTP_PU); 2881 break; 2882 case BCM4325_CHIP_ID: 2883 rsrcs = PMURES_BIT(RES4325_OTP_PU); 2884 break; 2885 case BCM4315_CHIP_ID: 2886 rsrcs = PMURES_BIT(RES4315_OTP_PU); 2887 break; 2888 case BCM4329_CHIP_ID: 2889 rsrcs = PMURES_BIT(RES4329_OTP_PU); 2890 break; 2891 case BCM4319_CHIP_ID: 2892 rsrcs = PMURES_BIT(RES4319_OTP_PU); 2893 break; 2894 case BCM4336_CHIP_ID: 2895 rsrcs = PMURES_BIT(RES4336_OTP_PU); 2896 break; 2897 case BCM4330_CHIP_ID: 2898 rsrcs = PMURES_BIT(RES4330_OTP_PU); 2899 break; 2900 default: 2901 break; 2902 } 2903 2904 if (rsrcs != 0) { 2905 uint32 otps; 2906 2907 /* Figure out the dependancies (exclude min_res_mask) */ 2908 uint32 deps = si_pmu_res_deps(sih, osh, cc, rsrcs, TRUE); 2909 uint32 min_mask = 0, max_mask = 0; 2910 si_pmu_res_masks(sih, &min_mask, &max_mask); 2911 deps &= ~min_mask; 2912 /* Turn on/off the power */ 2913 if (on) { 2914 PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", rsrcs | deps)); 2915 OR_REG(osh, &cc->min_res_mask, (rsrcs | deps)); 2916 OSL_DELAY(1000); 2917 SPINWAIT(!(R_REG(osh, &cc->res_state) & rsrcs), PMU_MAX_TRANSITION_DLY); 2918 ASSERT(R_REG(osh, &cc->res_state) & rsrcs); 2919 } 2920 else { 2921 PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", rsrcs | deps)); 2922 AND_REG(osh, &cc->min_res_mask, ~(rsrcs | deps)); 2923 } 2924 2925 SPINWAIT((((otps = R_REG(osh, &cc->otpstatus)) & OTPS_READY) != 2926 (on ? OTPS_READY : 0)), 100); 2927 ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0)); 2928 if ((otps & OTPS_READY) != (on ? OTPS_READY : 0)) 2929 PMU_MSG(("OTP ready bit not %s after wait\n", (on ? "ON" : "OFF"))); 2930 } 2931 2932 /* Return to original core */ 2933 si_setcoreidx(sih, origidx); 2934} 2935 2936void 2937si_pmu_rcal(si_t *sih, osl_t *osh) 2938{ 2939 chipcregs_t *cc; 2940 uint origidx; 2941 uint rcal_done, BT_out_of_reset; 2942 2943 ASSERT(sih->cccaps & CC_CAP_PMU); 2944 2945 /* Remember original core before switch to chipc */ 2946 origidx = si_coreidx(sih); 2947 cc = si_setcoreidx(sih, SI_CC_IDX); 2948 ASSERT(cc != NULL); 2949 2950 switch (CHIPID(sih->chip)) { 2951 case BCM4325_CHIP_ID: { 2952 uint8 rcal_code; 2953 uint32 val; 2954 2955 /* Kick RCal */ 2956 W_REG(osh, &cc->chipcontrol_addr, 1); 2957 2958 /* Power Down RCAL Block */ 2959 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 2960 2961 /* Check if RCAL is already done by BT */ 2962 rcal_done = ((R_REG(osh, &cc->chipstatus)) & 0x8) >> 3; 2963 2964 /* If RCAL already done, note that BT is out of reset */ 2965 if (rcal_done == 1) { 2966 BT_out_of_reset = 1; 2967 } else { 2968 BT_out_of_reset = 0; 2969 } 2970 2971 /* Power Up RCAL block */ 2972 OR_REG(osh, &cc->chipcontrol_data, 0x04); 2973 2974 /* Wait for completion */ 2975 SPINWAIT(0 == (R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000); 2976 ASSERT(R_REG(osh, &cc->chipstatus) & 0x08); 2977 2978 if (BT_out_of_reset) { 2979 rcal_code = 0x6; 2980 } else { 2981 /* Drop the LSB to convert from 5 bit code to 4 bit code */ 2982 rcal_code = (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f; 2983 } 2984 2985 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", 2986 R_REG(osh, &cc->chipstatus), rcal_code)); 2987 2988 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 2989 W_REG(osh, &cc->regcontrol_addr, 0); 2990 val = R_REG(osh, &cc->regcontrol_data) & ~((uint32)0x07 << 29); 2991 val |= (uint32)(rcal_code & 0x07) << 29; 2992 W_REG(osh, &cc->regcontrol_data, val); 2993 W_REG(osh, &cc->regcontrol_addr, 1); 2994 val = R_REG(osh, &cc->regcontrol_data) & ~(uint32)0x01; 2995 val |= (uint32)((rcal_code >> 3) & 0x01); 2996 W_REG(osh, &cc->regcontrol_data, val); 2997 2998 /* Write RCal code into pmu_chip_ctrl[33:30] */ 2999 W_REG(osh, &cc->chipcontrol_addr, 0); 3000 val = R_REG(osh, &cc->chipcontrol_data) & ~((uint32)0x03 << 30); 3001 val |= (uint32)(rcal_code & 0x03) << 30; 3002 W_REG(osh, &cc->chipcontrol_data, val); 3003 W_REG(osh, &cc->chipcontrol_addr, 1); 3004 val = R_REG(osh, &cc->chipcontrol_data) & ~(uint32)0x03; 3005 val |= (uint32)((rcal_code >> 2) & 0x03); 3006 W_REG(osh, &cc->chipcontrol_data, val); 3007 3008 /* Set override in pmu_chip_ctrl[29] */ 3009 W_REG(osh, &cc->chipcontrol_addr, 0); 3010 OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29)); 3011 3012 /* Power off RCal block */ 3013 W_REG(osh, &cc->chipcontrol_addr, 1); 3014 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 3015 3016 break; 3017 } 3018 case BCM4329_CHIP_ID: { 3019 uint8 rcal_code; 3020 uint32 val; 3021 3022 /* Kick RCal */ 3023 W_REG(osh, &cc->chipcontrol_addr, 1); 3024 3025 /* Power Down RCAL Block */ 3026 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 3027 3028 /* Power Up RCAL block */ 3029 OR_REG(osh, &cc->chipcontrol_data, 0x04); 3030 3031 /* Wait for completion */ 3032 SPINWAIT(0 == (R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000); 3033 ASSERT(R_REG(osh, &cc->chipstatus) & 0x08); 3034 3035 /* Drop the LSB to convert from 5 bit code to 4 bit code */ 3036 rcal_code = (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f; 3037 3038 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", 3039 R_REG(osh, &cc->chipstatus), rcal_code)); 3040 3041 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 3042 W_REG(osh, &cc->regcontrol_addr, 0); 3043 val = R_REG(osh, &cc->regcontrol_data) & ~((uint32)0x07 << 29); 3044 val |= (uint32)(rcal_code & 0x07) << 29; 3045 W_REG(osh, &cc->regcontrol_data, val); 3046 W_REG(osh, &cc->regcontrol_addr, 1); 3047 val = R_REG(osh, &cc->regcontrol_data) & ~(uint32)0x01; 3048 val |= (uint32)((rcal_code >> 3) & 0x01); 3049 W_REG(osh, &cc->regcontrol_data, val); 3050 3051 /* Write RCal code into pmu_chip_ctrl[33:30] */ 3052 W_REG(osh, &cc->chipcontrol_addr, 0); 3053 val = R_REG(osh, &cc->chipcontrol_data) & ~((uint32)0x03 << 30); 3054 val |= (uint32)(rcal_code & 0x03) << 30; 3055 W_REG(osh, &cc->chipcontrol_data, val); 3056 W_REG(osh, &cc->chipcontrol_addr, 1); 3057 val = R_REG(osh, &cc->chipcontrol_data) & ~(uint32)0x03; 3058 val |= (uint32)((rcal_code >> 2) & 0x03); 3059 W_REG(osh, &cc->chipcontrol_data, val); 3060 3061 /* Set override in pmu_chip_ctrl[29] */ 3062 W_REG(osh, &cc->chipcontrol_addr, 0); 3063 OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29)); 3064 3065 /* Power off RCal block */ 3066 W_REG(osh, &cc->chipcontrol_addr, 1); 3067 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 3068 3069 break; 3070 } 3071 default: 3072 break; 3073 } 3074 3075 /* Return to original core */ 3076 si_setcoreidx(sih, origidx); 3077} 3078 3079void 3080si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid) 3081{ 3082 chipcregs_t *cc; 3083 uint origidx, intr_val; 3084 uint32 tmp = 0; 3085 3086 /* Remember original core before switch to chipc */ 3087 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 3088 ASSERT(cc != NULL); 3089 3090 /* force the HT off */ 3091 if (CHIPID(sih->chip) == BCM4336_CHIP_ID) { 3092 tmp = R_REG(osh, &cc->max_res_mask); 3093 tmp &= ~RES4336_HT_AVAIL; 3094 W_REG(osh, &cc->max_res_mask, tmp); 3095 /* wait for the ht to really go away */ 3096 SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == 0), 10000); 3097 ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == 0); 3098 } 3099 3100 /* update the pll changes */ 3101 si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid); 3102 3103 /* enable HT back on */ 3104 if (CHIPID(sih->chip) == BCM4336_CHIP_ID) { 3105 tmp = R_REG(osh, &cc->max_res_mask); 3106 tmp |= RES4336_HT_AVAIL; 3107 W_REG(osh, &cc->max_res_mask, tmp); 3108 } 3109 3110 /* Return to original core */ 3111 si_restore_core(sih, origidx, intr_val); 3112} 3113 3114static void 3115si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, uint8 spuravoid) 3116{ 3117 uint32 tmp = 0; 3118 uint8 phypll_offset = 0; 3119 uint8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5}; 3120 uint8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc}; 3121 3122 switch (CHIPID(sih->chip)) { 3123 case BCM5357_CHIP_ID: case BCM4749_CHIP_ID: 3124 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 3125 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: 3126 case BCM6362_CHIP_ID: case BCM53572_CHIP_ID: 3127 3128 if ((CHIPID(sih->chip) == BCM6362_CHIP_ID) && (sih->chiprev == 0)) { 3129 /* 6362a0 (same clks as 4322[4-6]) */ 3130 if (spuravoid == 1) { 3131 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3132 W_REG(osh, &cc->pllcontrol_data, 0x11500010); 3133 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3134 W_REG(osh, &cc->pllcontrol_data, 0x000C0C06); 3135 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3136 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 3137 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3138 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3139 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3140 W_REG(osh, &cc->pllcontrol_data, 0x2001E920); 3141 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3142 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3143 } else { 3144 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3145 W_REG(osh, &cc->pllcontrol_data, 0x11100010); 3146 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3147 W_REG(osh, &cc->pllcontrol_data, 0x000c0c06); 3148 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3149 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 3150 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3151 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3152 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3153 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 3154 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3155 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3156 } 3157 3158 } else { 3159 /* 5357[ab]0, 43236[ab]0, and 6362b0 */ 3160 3161 /* BCM5357 needs to touch PLL1_PLLCTL[02],so offset PLL0_PLLCTL[02] by 6 */ 3162 phypll_offset = ((CHIPID(sih->chip) == BCM5357_CHIP_ID) || 3163 (CHIPID(sih->chip) == BCM4749_CHIP_ID) || 3164 (CHIPID(sih->chip) == BCM53572_CHIP_ID)) ? 6 : 0; 3165 3166 /* RMW only the P1 divider */ 3167 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0 + phypll_offset); 3168 tmp = R_REG(osh, &cc->pllcontrol_data); 3169 tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK)); 3170 tmp |= (bcm5357_bcm43236_p1div[spuravoid] << PMU1_PLL0_PC0_P1DIV_SHIFT); 3171 W_REG(osh, &cc->pllcontrol_data, tmp); 3172 3173 /* RMW only the int feedback divider */ 3174 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2 + phypll_offset); 3175 tmp = R_REG(osh, &cc->pllcontrol_data); 3176 tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK); 3177 tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << PMU1_PLL0_PC2_NDIV_INT_SHIFT; 3178 W_REG(osh, &cc->pllcontrol_data, tmp); 3179 } 3180 3181 tmp = 1 << 10; 3182 break; 3183 3184 case BCM4331_CHIP_ID: 3185 case BCM43431_CHIP_ID: 3186 if (ISSIM_ENAB(sih)) { 3187 if (spuravoid == 2) { 3188 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3189 W_REG(osh, &cc->pllcontrol_data, 0x00000002); 3190 } else if (spuravoid == 1) { 3191 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3192 W_REG(osh, &cc->pllcontrol_data, 0x00000001); 3193 } else { 3194 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3195 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3196 } 3197 } else { 3198 if (spuravoid == 2) { 3199 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3200 W_REG(osh, &cc->pllcontrol_data, 0x11500014); 3201 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3202 W_REG(osh, &cc->pllcontrol_data, 0x0FC00a08); 3203 } else if (spuravoid == 1) { 3204 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3205 W_REG(osh, &cc->pllcontrol_data, 0x11500014); 3206 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3207 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 3208 } else { 3209 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3210 W_REG(osh, &cc->pllcontrol_data, 0x11100014); 3211 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3212 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 3213 } 3214 } 3215 tmp = 1 << 10; 3216 break; 3217 3218 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 3219 case BCM43226_CHIP_ID: 3220 if (spuravoid == 1) { 3221 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3222 W_REG(osh, &cc->pllcontrol_data, 0x11500010); 3223 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3224 W_REG(osh, &cc->pllcontrol_data, 0x000C0C06); 3225 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3226 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 3227 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3228 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3229 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3230 W_REG(osh, &cc->pllcontrol_data, 0x2001E920); 3231 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3232 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3233 } else { 3234 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3235 W_REG(osh, &cc->pllcontrol_data, 0x11100010); 3236 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3237 W_REG(osh, &cc->pllcontrol_data, 0x000c0c06); 3238 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3239 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 3240 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3241 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3242 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3243 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 3244 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3245 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3246 } 3247 tmp = 1 << 10; 3248 break; 3249 3250 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 3251 case BCM43420_CHIP_ID: 3252 if (spuravoid == 1) { 3253 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3254 W_REG(osh, &cc->pllcontrol_data, 0x11500008); 3255 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3256 W_REG(osh, &cc->pllcontrol_data, 0x0C000C06); 3257 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3258 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 3259 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3260 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3261 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3262 W_REG(osh, &cc->pllcontrol_data, 0x2001E920); 3263 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3264 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3265 } else { 3266 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3267 W_REG(osh, &cc->pllcontrol_data, 0x11100008); 3268 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3269 W_REG(osh, &cc->pllcontrol_data, 0x0c000c06); 3270 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3271 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 3272 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3273 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3274 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3275 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 3276 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3277 W_REG(osh, &cc->pllcontrol_data, 0x88888855); 3278 } 3279 3280 tmp = 1 << 10; 3281 break; 3282 3283 case BCM4716_CHIP_ID: 3284 case BCM4748_CHIP_ID: 3285 case BCM47162_CHIP_ID: 3286 if (spuravoid == 1) { 3287 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3288 W_REG(osh, &cc->pllcontrol_data, 0x11500060); 3289 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3290 W_REG(osh, &cc->pllcontrol_data, 0x080C0C06); 3291 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3292 W_REG(osh, &cc->pllcontrol_data, 0x0F600000); 3293 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3294 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3295 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3296 W_REG(osh, &cc->pllcontrol_data, 0x2001E924); 3297 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3298 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3299 } else { 3300 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3301 W_REG(osh, &cc->pllcontrol_data, 0x11100060); 3302 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3303 W_REG(osh, &cc->pllcontrol_data, 0x080c0c06); 3304 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3305 W_REG(osh, &cc->pllcontrol_data, 0x03000000); 3306 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3307 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3308 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3309 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 3310 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3311 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3312 } 3313 3314 tmp = 3 << 9; 3315 break; 3316 3317 case BCM4322_CHIP_ID: 3318 case BCM43221_CHIP_ID: 3319 case BCM43231_CHIP_ID: 3320 case BCM4342_CHIP_ID: 3321 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3322 W_REG(osh, &cc->pllcontrol_data, 0x11100070); 3323 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3324 W_REG(osh, &cc->pllcontrol_data, 0x1014140a); 3325 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3326 W_REG(osh, &cc->pllcontrol_data, 0x88888854); 3327 3328 if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */ 3329 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3330 W_REG(osh, &cc->pllcontrol_data, 0x05201828); 3331 } else { /* enable 40/80/160Mhz clock mode */ 3332 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3333 W_REG(osh, &cc->pllcontrol_data, 0x05001828); 3334 } 3335 3336 tmp = 1 << 10; 3337 break; 3338 case BCM4319_CHIP_ID: 3339 break; 3340 case BCM4336_CHIP_ID: 3341 /* Looks like these are only for default xtal freq 26MHz */ 3342 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3343 W_REG(osh, &cc->pllcontrol_data, 0x02100020); 3344 3345 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3346 W_REG(osh, &cc->pllcontrol_data, 0x0C0C0C0C); 3347 3348 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3349 W_REG(osh, &cc->pllcontrol_data, 0x01240C0C); 3350 3351 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3352 W_REG(osh, &cc->pllcontrol_data, 0x202C2820); 3353 3354 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3355 W_REG(osh, &cc->pllcontrol_data, 0x88888825); 3356 3357 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3358 if (spuravoid == 1) { 3359 W_REG(osh, &cc->pllcontrol_data, 0x00EC4EC4); 3360 } else { 3361 W_REG(osh, &cc->pllcontrol_data, 0x00762762); 3362 } 3363 3364 tmp = PCTL_PLL_PLLCTL_UPD; 3365 break; 3366 case BCM43227_CHIP_ID: 3367 case BCM43228_CHIP_ID: 3368 case BCM43428_CHIP_ID: 3369 /* LCNXN */ 3370 /* PLL Settings for spur avoidance on/off mode, no on2 support for 43228A0 */ 3371 if (spuravoid == 1) { 3372 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3373 W_REG(osh, &cc->pllcontrol_data, 0x01100014); 3374 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3375 W_REG(osh, &cc->pllcontrol_data, 0x040C0C06); 3376 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3377 W_REG(osh, &cc->pllcontrol_data, 0x03140A08); 3378 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3379 W_REG(osh, &cc->pllcontrol_data, 0x00333333); 3380 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3381 W_REG(osh, &cc->pllcontrol_data, 0x202C2820); 3382 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3383 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3384 } else { 3385 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 3386 W_REG(osh, &cc->pllcontrol_data, 0x11100014); 3387 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 3388 W_REG(osh, &cc->pllcontrol_data, 0x040c0c06); 3389 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 3390 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 3391 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 3392 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 3393 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 3394 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 3395 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 3396 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 3397 } 3398 tmp = 1 << 10; 3399 break; 3400 default: 3401 PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n", 3402 __FUNCTION__, bcm_chipname(sih->chip, chn, 8))); 3403 break; 3404 } 3405 3406 tmp |= R_REG(osh, &cc->pmucontrol); 3407 W_REG(osh, &cc->pmucontrol, tmp); 3408} 3409 3410void 3411si_pmu_gband_spurwar(si_t *sih, osl_t *osh) 3412{ 3413 chipcregs_t *cc; 3414 uint origidx, intr_val; 3415 uint32 cc_clk_ctl_st; 3416 uint32 minmask, maxmask; 3417 3418 if ((CHIPID(sih->chip) == BCM43222_CHIP_ID) || 3419 (CHIPID(sih->chip) == BCM43420_CHIP_ID)) { 3420 /* Remember original core before switch to chipc */ 3421 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 3422 ASSERT(cc != NULL); 3423 3424 /* Remove force HT and HT Avail Request from chipc core */ 3425 cc_clk_ctl_st = R_REG(osh, &cc->clk_ctl_st); 3426 AND_REG(osh, &cc->clk_ctl_st, ~(CCS_FORCEHT | CCS_HTAREQ)); 3427 3428 minmask = R_REG(osh, &cc->min_res_mask); 3429 maxmask = R_REG(osh, &cc->max_res_mask); 3430 3431 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */ 3432 /* Have to remove HT Avail request before powering off PLL */ 3433 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 3434 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 3435 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 3436 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 3437 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 3438 OSL_DELAY(150); 3439 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 3440 3441 /* Change backplane clock speed from 96 MHz to 80 MHz */ 3442 W_REG(osh, &cc->pllcontrol_addr, PMU2_PLL_PLLCTL2); 3443 W_REG(osh, &cc->pllcontrol_data, (R_REG(osh, &cc->pllcontrol_data) & 3444 ~(PMU2_PLL_PC2_M6DIV_MASK)) | 3445 (0xc << PMU2_PLL_PC2_M6DIV_SHIFT)); 3446 3447 /* Reduce the driver strengths of the phyclk160, adcclk80, and phyck80 3448 * clocks from 0x8 to 0x1 3449 */ 3450 W_REG(osh, &cc->pllcontrol_addr, PMU2_PLL_PLLCTL5); 3451 W_REG(osh, &cc->pllcontrol_data, (R_REG(osh, &cc->pllcontrol_data) & 3452 ~(PMU2_PLL_PC5_CLKDRIVE_CH1_MASK | 3453 PMU2_PLL_PC5_CLKDRIVE_CH2_MASK | 3454 PMU2_PLL_PC5_CLKDRIVE_CH3_MASK | 3455 PMU2_PLL_PC5_CLKDRIVE_CH4_MASK)) | 3456 ((1 << PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT) | 3457 (1 << PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT) | 3458 (1 << PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT) | 3459 (1 << PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT))); 3460 3461 W_REG(osh, &cc->pmucontrol, R_REG(osh, &cc->pmucontrol) | PCTL_PLL_PLLCTL_UPD); 3462 3463 /* Restore min_res_mask and max_res_mask */ 3464 OSL_DELAY(100); 3465 W_REG(osh, &cc->max_res_mask, maxmask); 3466 OSL_DELAY(100); 3467 W_REG(osh, &cc->min_res_mask, minmask); 3468 OSL_DELAY(100); 3469 /* Make sure the PLL is on. Spinwait until the HTAvail is True */ 3470 SPINWAIT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY); 3471 ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 3472 3473 /* Restore force HT and HT Avail Request on the chipc core */ 3474 W_REG(osh, &cc->clk_ctl_st, cc_clk_ctl_st); 3475 3476 /* Return to original core */ 3477 si_restore_core(sih, origidx, intr_val); 3478 } 3479} 3480 3481bool 3482si_pmu_is_otp_powered(si_t *sih, osl_t *osh) 3483{ 3484 uint idx; 3485 chipcregs_t *cc; 3486 bool st; 3487 3488 /* Remember original core before switch to chipc */ 3489 idx = si_coreidx(sih); 3490 cc = si_setcoreidx(sih, SI_CC_IDX); 3491 ASSERT(cc != NULL); 3492 3493 switch (CHIPID(sih->chip)) { 3494 case BCM4322_CHIP_ID: 3495 case BCM43221_CHIP_ID: 3496 case BCM43231_CHIP_ID: 3497 case BCM4342_CHIP_ID: 3498 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4322_OTP_PU)) != 0; 3499 break; 3500 case BCM4325_CHIP_ID: 3501 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4325_OTP_PU)) != 0; 3502 break; 3503 case BCM4329_CHIP_ID: 3504 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4329_OTP_PU)) != 0; 3505 break; 3506 case BCM4315_CHIP_ID: 3507 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4315_OTP_PU)) != 0; 3508 break; 3509 case BCM4319_CHIP_ID: 3510 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4319_OTP_PU)) != 0; 3511 break; 3512 case BCM4336_CHIP_ID: 3513 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4336_OTP_PU)) != 0; 3514 break; 3515 case BCM4330_CHIP_ID: 3516 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4330_OTP_PU)) != 0; 3517 break; 3518 3519 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on. 3520 * Use OTP_INIT command to reset/refresh state. 3521 */ 3522 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 3523 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 3524 case BCM43236_CHIP_ID: case BCM43235_CHIP_ID: case BCM43238_CHIP_ID: 3525 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: case BCM43420_CHIP_ID: 3526 case BCM4331_CHIP_ID: case BCM43431_CHIP_ID: 3527 st = TRUE; 3528 break; 3529 default: 3530 st = TRUE; 3531 break; 3532 } 3533 3534 /* Return to original core */ 3535 si_setcoreidx(sih, idx); 3536 return st; 3537} 3538#endif /* !_CFE_ || CFG_WL */ 3539 3540void 3541#if defined(WLTEST) 3542si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable) 3543#else 3544BCMATTACHFN(si_pmu_sprom_enable)(si_t *sih, osl_t *osh, bool enable) 3545#endif 3546{ 3547 chipcregs_t *cc; 3548 uint origidx; 3549 3550 /* Remember original core before switch to chipc */ 3551 origidx = si_coreidx(sih); 3552 cc = si_setcoreidx(sih, SI_CC_IDX); 3553 ASSERT(cc != NULL); 3554 3555 switch (CHIPID(sih->chip)) { 3556 case BCM4315_CHIP_ID: 3557 if (CHIPREV(sih->chiprev) < 1) 3558 break; 3559 if (sih->chipst & CST4315_SPROM_SEL) { 3560 uint32 val; 3561 W_REG(osh, &cc->chipcontrol_addr, 0); 3562 val = R_REG(osh, &cc->chipcontrol_data); 3563 if (enable) 3564 val &= ~0x80000000; 3565 else 3566 val |= 0x80000000; 3567 W_REG(osh, &cc->chipcontrol_data, val); 3568 } 3569 break; 3570 default: 3571 break; 3572 } 3573 3574 /* Return to original core */ 3575 si_setcoreidx(sih, origidx); 3576} 3577 3578bool 3579#if defined(WLTEST) 3580si_pmu_is_sprom_enabled(si_t *sih, osl_t *osh) 3581#else 3582BCMATTACHFN(si_pmu_is_sprom_enabled)(si_t *sih, osl_t *osh) 3583#endif 3584{ 3585 chipcregs_t *cc; 3586 uint origidx; 3587 bool enable = TRUE; 3588 3589 /* Remember original core before switch to chipc */ 3590 origidx = si_coreidx(sih); 3591 cc = si_setcoreidx(sih, SI_CC_IDX); 3592 ASSERT(cc != NULL); 3593 3594 switch (CHIPID(sih->chip)) { 3595 case BCM4315_CHIP_ID: 3596 if (CHIPREV(sih->chiprev) < 1) 3597 break; 3598 if (!(sih->chipst & CST4315_SPROM_SEL)) 3599 break; 3600 W_REG(osh, &cc->chipcontrol_addr, 0); 3601 if (R_REG(osh, &cc->chipcontrol_data) & 0x80000000) 3602 enable = FALSE; 3603 break; 3604 default: 3605 break; 3606 } 3607 3608 /* Return to original core */ 3609 si_setcoreidx(sih, origidx); 3610 return enable; 3611} 3612 3613/* initialize PMU chip controls and other chip level stuff */ 3614void 3615BCMATTACHFN(si_pmu_chip_init)(si_t *sih, osl_t *osh) 3616{ 3617 uint origidx; 3618 3619 ASSERT(sih->cccaps & CC_CAP_PMU); 3620 3621#ifdef CHIPC_UART_ALWAYS_ON 3622 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), CCS_FORCEALP, CCS_FORCEALP); 3623#endif /* CHIPC_UART_ALWAYS_ON */ 3624 3625#ifndef CONFIG_XIP 3626 /* Gate off SPROM clock and chip select signals */ 3627 si_pmu_sprom_enable(sih, osh, FALSE); 3628#endif 3629 3630 /* Remember original core */ 3631 origidx = si_coreidx(sih); 3632 3633#if !defined(_CFE_) || defined(CFG_WL) 3634 /* Misc. chip control, has nothing to do with PMU */ 3635 switch (CHIPID(sih->chip)) { 3636 case BCM4315_CHIP_ID: 3637#ifdef BCMUSBDEV 3638 si_setcore(sih, PCMCIA_CORE_ID, 0); 3639 si_core_disable(sih, 0); 3640#endif 3641 break; 3642 case BCM4319_CHIP_ID: 3643 /* No support for external LPO, so power it down */ 3644 si_pmu_chipcontrol(sih, 0, (1<<28), (0<<28)); 3645 break; 3646 default: 3647 break; 3648 } 3649#endif /* !_CFE_ || CFG_WL */ 3650 3651 /* Return to original core */ 3652 si_setcoreidx(sih, origidx); 3653} 3654 3655/* initialize PMU switch/regulators */ 3656void 3657BCMATTACHFN(si_pmu_swreg_init)(si_t *sih, osl_t *osh) 3658{ 3659#if !defined(_CFE_) || defined(CFG_WL) 3660 ASSERT(sih->cccaps & CC_CAP_PMU); 3661 3662 switch (CHIPID(sih->chip)) { 3663 case BCM4325_CHIP_ID: 3664 if (CHIPREV(sih->chiprev) < 3) 3665 break; 3666 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> CST4325_PMUTOP_2B_SHIFT) == 1) { 3667 /* Bump CLDO PWM output voltage to 1.25V */ 3668 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xf); 3669 /* Bump CLDO BURST output voltage to 1.25V */ 3670 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, 0xf); 3671 } 3672 /* Bump CBUCK PWM output voltage to 1.5V */ 3673 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb); 3674 /* Bump CBUCK BURST output voltage to 1.5V */ 3675 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb); 3676 /* Bump LNLDO1 output voltage to 1.25V */ 3677 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0x1); 3678 /* Select LNLDO2 output voltage to 2.5V */ 3679 if (sih->boardflags & BFL_LNLDO2_2P5) 3680 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO2_SEL, 0x1); 3681 break; 3682 case BCM4315_CHIP_ID: { 3683 uint32 val; 3684 chipcregs_t *cc; 3685 uint origidx; 3686 3687 if (CHIPREV(sih->chiprev) != 2) 3688 break; 3689 3690 /* Remember original core before switch to chipc */ 3691 origidx = si_coreidx(sih); 3692 cc = si_setcoreidx(sih, SI_CC_IDX); 3693 ASSERT(cc != NULL); 3694 3695 W_REG(osh, &cc->regcontrol_addr, 4); 3696 val = R_REG(osh, &cc->regcontrol_data); 3697 val |= (uint32)(1 << 16); 3698 W_REG(osh, &cc->regcontrol_data, val); 3699 3700 /* Return to original core */ 3701 si_setcoreidx(sih, origidx); 3702 break; 3703 } 3704 case BCM4336_CHIP_ID: 3705 /* Reduce CLDO PWM output voltage to 1.2V */ 3706 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); 3707 /* Reduce CLDO BURST output voltage to 1.2V */ 3708 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, 0xe); 3709 /* Reduce LNLDO1 output voltage to 1.2V */ 3710 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0xe); 3711 if (CHIPREV(sih->chiprev) == 0) 3712 si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); 3713 break; 3714 3715 case BCM4330_CHIP_ID: 3716 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ 3717 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0); 3718 break; 3719 default: 3720 break; 3721 } 3722#endif /* !_CFE_ || CFG_WL */ 3723} 3724 3725void 3726si_pmu_radio_enable(si_t *sih, bool enable) 3727{ 3728 ASSERT(sih->cccaps & CC_CAP_PMU); 3729 3730 switch (CHIPID(sih->chip)) { 3731 case BCM4325_CHIP_ID: 3732 if (sih->boardflags & BFL_FASTPWR) 3733 break; 3734 3735 if ((sih->boardflags & BFL_BUCKBOOST)) { 3736 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 3737 PMURES_BIT(RES4325_BUCK_BOOST_BURST), 3738 enable ? PMURES_BIT(RES4325_BUCK_BOOST_BURST) : 0); 3739 } 3740 3741 if (enable) { 3742 OSL_DELAY(100 * 1000); 3743 } 3744 break; 3745 case BCM4319_CHIP_ID: 3746 if (enable) 3747 si_write_wrapperreg(sih, AI_OOBSELOUTB74, (uint32)0x868584); 3748 else 3749 si_write_wrapperreg(sih, AI_OOBSELOUTB74, (uint32)0x060584); 3750 break; 3751 } 3752} 3753 3754/* Wait for a particular clock level to be on the backplane */ 3755uint32 3756si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, uint32 clk, uint32 delay) 3757{ 3758 chipcregs_t *cc; 3759 uint origidx; 3760 3761 ASSERT(sih->cccaps & CC_CAP_PMU); 3762 3763 /* Remember original core before switch to chipc */ 3764 origidx = si_coreidx(sih); 3765 cc = si_setcoreidx(sih, SI_CC_IDX); 3766 ASSERT(cc != NULL); 3767 3768 if (delay) 3769 SPINWAIT(((R_REG(osh, &cc->pmustatus) & clk) != clk), delay); 3770 3771 /* Return to original core */ 3772 si_setcoreidx(sih, origidx); 3773 3774 return (R_REG(osh, &cc->pmustatus) & clk); 3775} 3776 3777/* 3778 * Measures the ALP clock frequency in KHz. Returns 0 if not possible. 3779 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal. 3780 */ 3781 3782#define EXT_ILP_HZ 32768 3783 3784uint32 3785BCMATTACHFN(si_pmu_measure_alpclk)(si_t *sih, osl_t *osh) 3786{ 3787 chipcregs_t *cc; 3788 uint origidx; 3789 uint32 alp_khz; 3790 3791 if (sih->pmurev < 10) 3792 return 0; 3793 3794 ASSERT(sih->cccaps & CC_CAP_PMU); 3795 3796 /* Remember original core before switch to chipc */ 3797 origidx = si_coreidx(sih); 3798 cc = si_setcoreidx(sih, SI_CC_IDX); 3799 ASSERT(cc != NULL); 3800 3801 if (R_REG(osh, &cc->pmustatus) & PST_EXTLPOAVAIL) { 3802 uint32 ilp_ctr, alp_hz; 3803 3804 /* Enable the reg to measure the freq, in case disabled before */ 3805 W_REG(osh, &cc->pmu_xtalfreq, 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); 3806 3807 /* Delay for well over 4 ILP clocks */ 3808 OSL_DELAY(1000); 3809 3810 /* Read the latched number of ALP ticks per 4 ILP ticks */ 3811 ilp_ctr = R_REG(osh, &cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; 3812 3813 /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */ 3814 W_REG(osh, &cc->pmu_xtalfreq, 0); 3815 3816 /* Calculate ALP frequency */ 3817 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; 3818 3819 /* Round to nearest 100KHz, and at the same time convert to KHz */ 3820 alp_khz = (alp_hz + 50000) / 100000 * 100; 3821 } else 3822 alp_khz = 0; 3823 3824 /* Return to original core */ 3825 si_setcoreidx(sih, origidx); 3826 3827 return alp_khz; 3828} 3829 3830#if !defined(_CFE_) || defined(CFG_WL) 3831void 3832si_pmu_set_4330_plldivs(si_t *sih, uint8 dacrate) 3833{ 3834 uint32 FVCO = si_pmu1_pllfvco0(sih)/1000; 3835 uint32 m1div, m2div, m3div, m4div, m5div, m6div; 3836 uint32 pllc1, pllc2; 3837 3838 m2div = m3div = m4div = m6div = FVCO/80; 3839 3840 m5div = FVCO/dacrate; 3841 3842 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 3843 m1div = FVCO/80; 3844 else 3845 m1div = FVCO/90; 3846 pllc1 = (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div << PMU1_PLL0_PC1_M2DIV_SHIFT) | 3847 (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div << PMU1_PLL0_PC1_M4DIV_SHIFT); 3848 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1); 3849 3850 pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, 0, 0); 3851 pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK); 3852 pllc2 |= ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) | (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT)); 3853 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2); 3854} 3855#endif /* !_CFE_ || CFG_WL */ 3856