1/* 2 * Misc utility routines for accessing PMU corerev specific features 3 * of the SiliconBackplane-based Broadcom chips. 4 * 5 * Copyright (C) 2013, 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 407964 2013-06-16 03:22:18Z $ 20 */ 21 22/* 23 * Note: this file contains PLL/FLL related functions. A chip can contain multiple PLLs/FLLs. 24 * However, in the context of this file the baseband ('BB') PLL/FLL is referred to. 25 * 26 * Throughout this code, the prefixes 'pmu0_', 'pmu1_' and 'pmu2_' are used. 27 * They refer to different revisions of the PMU (which is at revision 18 @ Apr 25, 2012) 28 * pmu1_ marks the transition from PLL to ADFLL (Digital Frequency Locked Loop). It supports 29 * fractional frequency generation. pmu2_ does not support fractional frequency generation. 30 */ 31 32#include <bcm_cfg.h> 33#include <typedefs.h> 34#include <bcmdefs.h> 35#include <osl.h> 36#include <bcmutils.h> 37#include <siutils.h> 38#include <bcmdevs.h> 39#include <hndsoc.h> 40#include <sbchipc.h> 41#include <hndpmu.h> 42#if defined(SAVERESTORE) 43#include <saverestore.h> 44#endif 45 46#define PMU_ERROR(args) 47 48#define PMU_MSG(args) 49 50/* To check in verbose debugging messages not intended 51 * to be on except on private builds. 52 */ 53#define PMU_NONE(args) 54 55/* 56 * Following globals are used to store NVRAM data after reclaim. It would have 57 * been better to use additional fields in si_t instead, but unfortunately 58 * si_t (=si_pub) is the first field in si_info_t (not as a pointer, but the 59 * entire structure is included). Therefore any change to si_t would change the 60 * offsets of fields in si_info_t and as such break ROMmed code that uses it. 61 */ 62static uint32 nvram_min_mask; 63static bool min_mask_valid = FALSE; 64static uint32 nvram_max_mask; 65static bool max_mask_valid = FALSE; 66 67/* PLL controls/clocks */ 68static void si_pmu0_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal); 69static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal); 70static void si_pmu1_pllinit1(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal); 71static void si_pmu2_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal); 72static void si_pmu_pll_off(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 *min_mask, 73 uint32 *max_mask, uint32 *clk_ctl_st); 74static void si_pmu_pll_off_isdone(si_t *sih, osl_t *osh, chipcregs_t *cc); 75static void si_pmu_pll_on(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 min_mask, 76 uint32 max_mask, uint32 clk_ctl_st); 77void si_pmu_otp_pllcontrol(si_t *sih, osl_t *osh); 78void si_pmu_otp_regcontrol(si_t *sih, osl_t *osh); 79void si_pmu_otp_chipcontrol(si_t *sih, osl_t *osh); 80uint32 si_pmu_def_alp_clock(si_t *sih, osl_t *osh); 81bool si_pmu_update_pllcontrol(si_t *sih, osl_t *osh, uint32 xtal, bool update_required); 82static uint32 si_pmu_htclk_mask(si_t *sih); 83 84static uint32 si_pmu0_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 85static uint32 si_pmu0_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 86static uint32 si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 87static uint32 si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 88static uint32 si_pmu2_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 89static uint32 si_pmu2_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); 90 91/* PMU resources */ 92static bool si_pmu_res_depfltr_bb(si_t *sih); 93static bool si_pmu_res_depfltr_ncb(si_t *sih); 94static bool si_pmu_res_depfltr_paldo(si_t *sih); 95static bool si_pmu_res_depfltr_npaldo(si_t *sih); 96static uint32 si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs, bool all); 97static uint si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 rsrc); 98static void si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax); 99static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, uint8 spuravoid); 100 101void si_pmu_set_4330_plldivs(si_t *sih, uint8 dacrate); 102static int8 si_pmu_cbuckout_to_vreg_ctrl(si_t *sih, uint16 cbuck_mv); 103 104void *g_si_pmutmr_lock_arg = NULL; 105si_pmu_callback_t g_si_pmutmr_lock_cb = NULL, g_si_pmutmr_unlock_cb = NULL; 106 107/* FVCO frequency */ 108#define FVCO_880 880000 /* 880MHz */ 109#define FVCO_1760 1760000 /* 1760MHz */ 110#define FVCO_1440 1440000 /* 1440MHz */ 111#define FVCO_960 960000 /* 960MHz */ 112#define FVCO_963 963000 /* 963MHz */ 113 114#define LPO_SEL_TIMEOUT 1000 115/* 116 * access to indirect register interfaces 117 */ 118 119/** Read/write a chipcontrol reg */ 120uint32 121si_pmu_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 122{ 123 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr), ~0, reg); 124 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_data), mask, val); 125} 126 127/** Read/write a regcontrol reg */ 128uint32 129si_pmu_regcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 130{ 131 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr), ~0, reg); 132 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data), mask, val); 133} 134 135/** Read/write a pllcontrol reg */ 136uint32 137si_pmu_pllcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 138{ 139 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pllcontrol_addr), ~0, reg); 140 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pllcontrol_data), mask, val); 141} 142 143/** 144 * The chip has one or more PLLs/FLLs (e.g. baseband PLL, USB PHY PLL). The settings of each PLL are 145 * contained within one or more 'PLL control' registers. Since the PLL hardware requires that 146 * changes for one PLL are committed at once, the PMU has a provision for 'updating' all PLL control 147 * registers at once. 148 * 149 * When software wants to change the any PLL parameters, it withdraws requests for that PLL clock, 150 * updates the PLL control registers being careful not to alter any control signals for the other 151 * PLLs, and then writes a 1 to PMUCtl.PllCtnlUpdate to commit the changes. Best usage model would 152 * be bring PLL down then update the PLL control register. 153 */ 154void 155si_pmu_pllupd(si_t *sih) 156{ 157 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmucontrol), 158 PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); 159} 160 161/* This function is not called in at least trunk nor PHOENIX2_BRANCH_6_10. Dead code? */ 162/** PMU PLL reset */ 163void 164si_pmu_pllreset(si_t *sih) 165{ 166 chipcregs_t *cc; 167 uint origidx; 168 osl_t *osh; 169 uint32 max_res_mask, min_res_mask, clk_ctl_st; 170 171 if (!si_pmu_htclk_mask(sih)) 172 return; 173 174 osh = si_osh(sih); 175 /* Remember original core before switch to chipc */ 176 origidx = si_coreidx(sih); 177 cc = si_setcoreidx(sih, SI_CC_IDX); 178 ASSERT(cc != NULL); 179 180 si_pmu_pll_off(sih, osh, cc, &min_res_mask, &max_res_mask, &clk_ctl_st); 181 182 OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 183 si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st); 184 185 /* Return to original core */ 186 si_setcoreidx(sih, origidx); 187} 188 189/* The check for OTP parameters for the PLL control registers is done and if found the 190 * registers are updated accordingly. 191 */ 192 193void 194BCMATTACHFN(si_pmu_otp_pllcontrol)(si_t *sih, osl_t *osh) 195{ 196 char name[16]; 197 const char *otp_val; 198 uint8 i; 199 uint32 val; 200 uint8 pll_ctrlcnt = 0; 201 202 chipcregs_t *cc; 203 uint origidx; 204 205 if (sih->pmurev >= 5) { 206 pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT; 207 } 208 else { 209 pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT; 210 } 211 212 /* Remember original core before switch to chipc */ 213 origidx = si_coreidx(sih); 214 cc = si_setcoreidx(sih, SI_CC_IDX); 215 ASSERT(cc != NULL); 216 217 for (i = 0; i < pll_ctrlcnt; i++) { 218 snprintf(name, sizeof(name), "pll%d", i); 219 if ((otp_val = getvar(NULL, name)) == NULL) 220 continue; 221 222 val = (uint32)bcm_strtoul(otp_val, NULL, 0); 223 W_REG(osh, &cc->pllcontrol_addr, i); 224 W_REG(osh, &cc->pllcontrol_data, val); 225 } 226 /* Return to original core */ 227 si_setcoreidx(sih, origidx); 228} 229 230/** 231 * The check for OTP parameters for the Voltage Regulator registers is done and if found the 232 * registers are updated accordingly. 233 */ 234void 235BCMATTACHFN(si_pmu_otp_regcontrol)(si_t *sih, osl_t *osh) 236{ 237 char name[16]; 238 const char *otp_val; 239 uint8 i; 240 uint32 val; 241 uint8 vreg_ctrlcnt = 0; 242 243 chipcregs_t *cc; 244 uint origidx; 245 246 if (sih->pmurev >= 5) { 247 vreg_ctrlcnt = (sih->pmucaps & PCAP5_VC_MASK) >> PCAP5_VC_SHIFT; 248 } 249 else { 250 vreg_ctrlcnt = (sih->pmucaps & PCAP_VC_MASK) >> PCAP_VC_SHIFT; 251 } 252 253 /* Remember original core before switch to chipc */ 254 origidx = si_coreidx(sih); 255 cc = si_setcoreidx(sih, SI_CC_IDX); 256 ASSERT(cc != NULL); 257 258 for (i = 0; i < vreg_ctrlcnt; i++) { 259 snprintf(name, sizeof(name), "reg%d", i); 260 if ((otp_val = getvar(NULL, name)) == NULL) 261 continue; 262 263 val = (uint32)bcm_strtoul(otp_val, NULL, 0); 264 W_REG(osh, &cc->regcontrol_addr, i); 265 W_REG(osh, &cc->regcontrol_data, val); 266 } 267 /* Return to original core */ 268 si_setcoreidx(sih, origidx); 269} 270 271/** 272 * The check for OTP parameters for the chip control registers is done and if found the 273 * registers are updated accordingly. 274 */ 275void 276BCMATTACHFN(si_pmu_otp_chipcontrol)(si_t *sih, osl_t *osh) 277{ 278 uint origidx; 279 uint32 val, cc_ctrlcnt, i; 280 char name[16]; 281 const char *otp_val; 282 chipcregs_t *cc; 283 284 /* Remember original core before switch to chipc */ 285 origidx = si_coreidx(sih); 286 cc = si_setcoreidx(sih, SI_CC_IDX); 287 ASSERT(cc != NULL); 288 289 if (sih->pmurev >= 5) { 290 cc_ctrlcnt = (sih->pmucaps & PCAP5_CC_MASK) >> PCAP5_CC_SHIFT; 291 } 292 else { 293 cc_ctrlcnt = (sih->pmucaps & PCAP_CC_MASK) >> PCAP_CC_SHIFT; 294 } 295 296 for (i = 0; i < cc_ctrlcnt; i++) { 297 snprintf(name, sizeof(name), "chipc%d", i); 298 if ((otp_val = getvar(NULL, name)) == NULL) 299 continue; 300 301 val = (uint32)bcm_strtoul(otp_val, NULL, 0); 302 W_REG(osh, &cc->chipcontrol_addr, i); 303 W_REG(osh, &cc->chipcontrol_data, val); 304 } 305 306 /* Return to original core */ 307 si_setcoreidx(sih, origidx); 308} 309 310/** Setup switcher voltage */ 311void 312BCMATTACHFN(si_pmu_set_switcher_voltage)(si_t *sih, osl_t *osh, 313 uint8 bb_voltage, uint8 rf_voltage) 314{ 315 chipcregs_t *cc; 316 uint origidx; 317 318 ASSERT(sih->cccaps & CC_CAP_PMU); 319 320 /* Remember original core before switch to chipc */ 321 origidx = si_coreidx(sih); 322 cc = si_setcoreidx(sih, SI_CC_IDX); 323 ASSERT(cc != NULL); 324 325 W_REG(osh, &cc->regcontrol_addr, 0x01); 326 W_REG(osh, &cc->regcontrol_data, (uint32)(bb_voltage & 0x1f) << 22); 327 328 W_REG(osh, &cc->regcontrol_addr, 0x00); 329 W_REG(osh, &cc->regcontrol_data, (uint32)(rf_voltage & 0x1f) << 14); 330 331 /* Return to original core */ 332 si_setcoreidx(sih, origidx); 333} 334 335/** 336 * A chip contains one or more LDOs (Low Drop Out regulators). During chip bringup, it can turn out 337 * that the default (POR) voltage of a regulator is not right or optimal. 338 * This function is called only by si_pmu_swreg_init() for specific chips 339 */ 340void 341BCMATTACHFN(si_pmu_set_ldo_voltage)(si_t *sih, osl_t *osh, uint8 ldo, uint8 voltage) 342{ 343 uint8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; 344 uint8 addr = 0; 345 346 ASSERT(sih->cccaps & CC_CAP_PMU); 347 348 switch (CHIPID(sih->chip)) { 349 case BCM4328_CHIP_ID: 350 case BCM5354_CHIP_ID: 351 switch (ldo) { 352 case SET_LDO_VOLTAGE_LDO1: 353 addr = 2; 354 sr_cntl_shift = 8; 355 rc_shift = 17; 356 mask = 0xf; 357 break; 358 case SET_LDO_VOLTAGE_LDO2: 359 addr = 3; 360 rc_shift = 1; 361 mask = 0xf; 362 break; 363 case SET_LDO_VOLTAGE_LDO3: 364 addr = 3; 365 rc_shift = 9; 366 mask = 0xf; 367 break; 368 case SET_LDO_VOLTAGE_PAREF: 369 addr = 3; 370 rc_shift = 17; 371 mask = 0x3f; 372 break; 373 default: 374 ASSERT(FALSE); 375 return; 376 } 377 break; 378 case BCM4312_CHIP_ID: 379 switch (ldo) { 380 case SET_LDO_VOLTAGE_PAREF: 381 addr = 0; 382 rc_shift = 21; 383 mask = 0x3f; 384 break; 385 default: 386 ASSERT(FALSE); 387 return; 388 } 389 break; 390 case BCM4325_CHIP_ID: 391 switch (ldo) { 392 case SET_LDO_VOLTAGE_CLDO_PWM: 393 addr = 5; 394 rc_shift = 9; 395 mask = 0xf; 396 break; 397 case SET_LDO_VOLTAGE_CLDO_BURST: 398 addr = 5; 399 rc_shift = 13; 400 mask = 0xf; 401 break; 402 case SET_LDO_VOLTAGE_CBUCK_PWM: 403 addr = 3; 404 rc_shift = 20; 405 mask = 0x1f; 406 /* Bit 116 & 119 are inverted in CLB for opt 2b */ 407 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> 408 CST4325_PMUTOP_2B_SHIFT) == 1) 409 voltage ^= 0x9; 410 break; 411 case SET_LDO_VOLTAGE_CBUCK_BURST: 412 addr = 3; 413 rc_shift = 25; 414 mask = 0x1f; 415 /* Bit 121 & 124 are inverted in CLB for opt 2b */ 416 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> 417 CST4325_PMUTOP_2B_SHIFT) == 1) 418 voltage ^= 0x9; 419 break; 420 case SET_LDO_VOLTAGE_LNLDO1: 421 addr = 5; 422 rc_shift = 17; 423 mask = 0x1f; 424 break; 425 case SET_LDO_VOLTAGE_LNLDO2_SEL: 426 addr = 6; 427 rc_shift = 0; 428 mask = 0x1; 429 break; 430 default: 431 ASSERT(FALSE); 432 return; 433 } 434 break; 435 case BCM4336_CHIP_ID: 436 case BCM43362_CHIP_ID: 437 switch (ldo) { 438 case SET_LDO_VOLTAGE_CLDO_PWM: 439 addr = 4; 440 rc_shift = 1; 441 mask = 0xf; 442 break; 443 case SET_LDO_VOLTAGE_CLDO_BURST: 444 addr = 4; 445 rc_shift = 5; 446 mask = 0xf; 447 break; 448 case SET_LDO_VOLTAGE_LNLDO1: 449 addr = 4; 450 rc_shift = 17; 451 mask = 0xf; 452 break; 453 case SET_LDO_VOLTAGE_CBUCK_PWM: 454 addr = 3; 455 rc_shift = 0; 456 mask = 0x1f; 457 break; 458 case SET_LDO_VOLTAGE_CBUCK_BURST: 459 addr = 3; 460 rc_shift = 5; 461 mask = 0x1f; 462 break; 463 case SET_LNLDO_PWERUP_LATCH_CTRL: 464 addr = 2; 465 rc_shift = 17; 466 mask = 0x3; 467 break; 468 default: 469 ASSERT(FALSE); 470 return; 471 } 472 break; 473 case BCM4330_CHIP_ID: 474 switch (ldo) { 475 case SET_LDO_VOLTAGE_CBUCK_PWM: 476 addr = 3; 477 rc_shift = 0; 478 mask = 0x1f; 479 break; 480 case SET_LDO_VOLTAGE_CBUCK_BURST: 481 addr = 3; 482 rc_shift = 5; 483 mask = 0x1f; 484 break; 485 default: 486 ASSERT(FALSE); 487 break; 488 } 489 break; 490 case BCM4331_CHIP_ID: 491 case BCM4360_CHIP_ID: 492 case BCM43460_CHIP_ID: 493 case BCM4352_CHIP_ID: 494 case BCM43431_CHIP_ID: 495 case BCM43526_CHIP_ID: 496 switch (ldo) { 497 case SET_LDO_VOLTAGE_PAREF: 498 addr = 1; 499 rc_shift = 0; 500 mask = 0xf; 501 break; 502 default: 503 ASSERT(FALSE); 504 break; 505 } 506 break; 507 case BCM4314_CHIP_ID: 508 switch (ldo) { 509 case SET_LDO_VOLTAGE_LDO2: 510 addr = 4; 511 rc_shift = 14; 512 mask = 0x7; 513 break; 514 default: 515 ASSERT(FALSE); 516 break; 517 } 518 break; 519 case BCM43143_CHIP_ID: 520 switch (ldo) { 521 case SET_LDO_VOLTAGE_CBUCK_PWM: 522 addr = 0; 523 rc_shift = 5; 524 mask = 0xf; 525 break; 526 case SET_LDO_VOLTAGE_CBUCK_BURST: 527 addr = 4; 528 rc_shift = 8; 529 mask = 0xf; 530 break; 531 case SET_LDO_VOLTAGE_LNLDO1: 532 addr = 4; 533 rc_shift = 14; 534 mask = 0x7; 535 break; 536 default: 537 ASSERT(FALSE); 538 break; 539 } 540 break; 541 default: 542 ASSERT(FALSE); 543 return; 544 } 545 546 shift = sr_cntl_shift + rc_shift; 547 548 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr), /* PMU VREG register */ 549 ~0, addr); 550 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data), 551 mask << shift, (voltage & mask) << shift); 552} /* si_pmu_set_ldo_voltage */ 553 554void 555si_pmu_paref_ldo_enable(si_t *sih, osl_t *osh, bool enable) 556{ 557 uint ldo = 0; 558 559 ASSERT(sih->cccaps & CC_CAP_PMU); 560 561 switch (CHIPID(sih->chip)) { 562 case BCM4328_CHIP_ID: 563 ldo = RES4328_PA_REF_LDO; 564 break; 565 case BCM5354_CHIP_ID: 566 ldo = RES5354_PA_REF_LDO; 567 break; 568 case BCM4312_CHIP_ID: 569 ldo = RES4312_PA_REF_LDO; 570 break; 571 default: 572 return; 573 } 574 575 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 576 PMURES_BIT(ldo), enable ? PMURES_BIT(ldo) : 0); 577} 578 579/* d11 slow to fast clock transition time in slow clock cycles */ 580#define D11SCC_SLOW2FAST_TRANSITION 2 581 582/** 583 * d11 core has a 'fastpwrup_dly' register that must be written to. 584 * This function returns d11 slow to fast clock transition time in [us] units. 585 * It does not write to the d11 core. 586 */ 587uint16 588BCMINITFN(si_pmu_fast_pwrup_delay)(si_t *sih, osl_t *osh) 589{ 590 uint pmudelay = PMU_MAX_TRANSITION_DLY; 591 chipcregs_t *cc; 592 uint origidx; 593 594 ASSERT(sih->cccaps & CC_CAP_PMU); 595 596 /* Remember original core before switch to chipc */ 597 origidx = si_coreidx(sih); 598 cc = si_setcoreidx(sih, SI_CC_IDX); 599 ASSERT(cc != NULL); 600 601 switch (CHIPID(sih->chip)) { 602 case BCM4312_CHIP_ID: 603 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 604 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 605 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43420_CHIP_ID: 606 case BCM43421_CHIP_ID: 607 case BCM43226_CHIP_ID: 608 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 609 case BCM43237_CHIP_ID: case BCM43239_CHIP_ID: 610 case BCM43234_CHIP_ID: 611 case BCM4331_CHIP_ID: 612 case BCM43431_CHIP_ID: 613 case BCM43131_CHIP_ID: 614 case BCM43217_CHIP_ID: 615 case BCM43227_CHIP_ID: 616 case BCM43228_CHIP_ID: 617 case BCM43428_CHIP_ID: 618 case BCM6362_CHIP_ID: 619 case BCM4342_CHIP_ID: 620 case BCM4313_CHIP_ID: 621 case BCM43460_CHIP_ID: 622 case BCM43526_CHIP_ID: 623 pmudelay = ISSIM_ENAB(sih) ? 70 : 3700; 624 break; 625 case BCM4360_CHIP_ID: 626 case BCM4352_CHIP_ID: 627 pmudelay = ISSIM_ENAB(sih) ? 70 : 1000; 628 break; 629 case BCM4328_CHIP_ID: 630 pmudelay = 7000; 631 break; 632 case BCM4325_CHIP_ID: 633 if (ISSIM_ENAB(sih)) 634 pmudelay = 70; 635 else { 636 uint32 ilp = si_ilp_clock(sih); 637 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4325_HT_AVAIL) + 638 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 639 pmudelay = (11 * pmudelay) / 10; 640 } 641 break; 642 case BCM4329_CHIP_ID: 643 if (ISSIM_ENAB(sih)) 644 pmudelay = 70; 645 else { 646 uint32 ilp = si_ilp_clock(sih); 647 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4329_HT_AVAIL) + 648 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 649 pmudelay = (11 * pmudelay) / 10; 650 } 651 break; 652 case BCM4315_CHIP_ID: 653 if (ISSIM_ENAB(sih)) 654 pmudelay = 70; 655 else { 656 uint32 ilp = si_ilp_clock(sih); 657 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4315_HT_AVAIL) + 658 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 659 pmudelay = (11 * pmudelay) / 10; 660 } 661 break; 662 case BCM4319_CHIP_ID: 663 pmudelay = ISSIM_ENAB(sih) ? 70 : 3700; 664 break; 665 case BCM4336_CHIP_ID: 666 case BCM43362_CHIP_ID: 667 if (ISSIM_ENAB(sih)) 668 pmudelay = 70; 669 else { 670 uint32 ilp = si_ilp_clock(sih); 671 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4336_HT_AVAIL) + 672 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 673 pmudelay = (11 * pmudelay) / 10; 674 } 675 break; 676 case BCM4330_CHIP_ID: 677 if (ISSIM_ENAB(sih)) 678 pmudelay = 70; 679 else { 680 uint32 ilp = si_ilp_clock(sih); 681 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4330_HT_AVAIL) + 682 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 683 pmudelay = (11 * pmudelay) / 10; 684 } 685 break; 686 case BCM4314_CHIP_ID: 687 case BCM43142_CHIP_ID: 688 /* FIX: TODO */ 689 if (ISSIM_ENAB(sih)) 690 pmudelay = 70; 691 else { 692 uint32 ilp = si_ilp_clock(sih); 693 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4314_HT_AVAIL) + 694 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 695 pmudelay = (11 * pmudelay) / 10; 696 } 697 break; 698 case BCM43143_CHIP_ID: 699 if (ISSIM_ENAB(sih)) 700 pmudelay = 70; 701 else { 702 /* Retrieve time by reading it out of the hardware */ 703 uint32 ilp = si_ilp_clock(sih); 704 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES43143_HT_AVAIL) + 705 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 706 pmudelay = (11 * pmudelay) / 10; 707 } 708 break; 709 case BCM4334_CHIP_ID: 710 /* FIX: TODO */ 711 if (ISSIM_ENAB(sih)) 712 pmudelay = 70; 713 else { 714 uint32 ilp = si_ilp_clock(sih); 715 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4334_HT_AVAIL) + 716 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 717 pmudelay = (11 * pmudelay) / 10; 718 } 719 break; 720 case BCM4335_CHIP_ID: 721 if (ISSIM_ENAB(sih)) 722 pmudelay = 70; 723 else { 724 uint32 ilp = si_ilp_clock(sih); 725 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4335_HT_AVAIL) + 726 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 727 /* Adding error margin of fixed 150usec instead of 10% */ 728 pmudelay = pmudelay + 150; 729 } 730 break; 731 case BCM4350_CHIP_ID: 732 if (ISSIM_ENAB(sih)) 733 pmudelay = 70; 734 else { 735 uint32 ilp = si_ilp_clock(sih); 736 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4350_HT_AVAIL) + 737 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 738 pmudelay = (11 * pmudelay) / 10; 739 } 740 break; 741 742 case BCM4324_CHIP_ID: 743 case BCM43242_CHIP_ID: 744 case BCM43243_CHIP_ID: 745 if (ISSIM_ENAB(sih)) 746 pmudelay = 70; 747 else { 748 uint32 ilp = si_ilp_clock(sih); 749 pmudelay = (si_pmu_res_uptime(sih, osh, cc, RES4324_HT_AVAIL) + 750 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); 751 pmudelay = (11 * pmudelay) / 10; 752 } 753 break; 754 default: 755 break; 756 } 757 758 /* Return to original core */ 759 si_setcoreidx(sih, origidx); 760 761 return (uint16)pmudelay; 762} /* si_pmu_fast_pwrup_delay */ 763 764uint32 765BCMATTACHFN(si_pmu_force_ilp)(si_t *sih, osl_t *osh, bool force) 766{ 767 chipcregs_t *cc; 768 uint origidx; 769 uint32 oldpmucontrol; 770 771 ASSERT(sih->cccaps & CC_CAP_PMU); 772 773 /* Remember original core before switch to chipc */ 774 origidx = si_coreidx(sih); 775 cc = si_setcoreidx(sih, SI_CC_IDX); 776 ASSERT(cc != NULL); 777 778 oldpmucontrol = R_REG(osh, &cc->pmucontrol); 779 if (force) 780 W_REG(osh, &cc->pmucontrol, oldpmucontrol & 781 ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); 782 else 783 W_REG(osh, &cc->pmucontrol, oldpmucontrol | 784 (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); 785 786 /* Return to original core */ 787 si_setcoreidx(sih, origidx); 788 789 return oldpmucontrol; 790} 791 792uint32 793BCMATTACHFN(si_pmu_enb_ht_req)(si_t *sih, osl_t *osh, bool enb) 794{ 795 chipcregs_t *cc; 796 uint origidx; 797 uint32 oldpmucontrol; 798 799 ASSERT(sih->cccaps & CC_CAP_PMU); 800 801 /* Remember original core before switch to chipc */ 802 origidx = si_coreidx(sih); 803 cc = si_setcoreidx(sih, SI_CC_IDX); 804 ASSERT(cc != NULL); 805 806 oldpmucontrol = R_REG(osh, &cc->pmucontrol); 807 if (enb) 808 W_REG(osh, &cc->pmucontrol, oldpmucontrol | PCTL_HT_REQ_EN); 809 else 810 W_REG(osh, &cc->pmucontrol, oldpmucontrol & ~PCTL_HT_REQ_EN); 811 812 /* Return to original core */ 813 si_setcoreidx(sih, origidx); 814 815 return oldpmucontrol; 816} 817 818/** 819 * During chip bringup, it can turn out that the 'hard wired' PMU dependencies are not fully 820 * correct, or that up/down time values can be optimized. The following data structures and arrays 821 * deal with that. 822 */ 823 824/* Setup resource up/down timers */ 825typedef struct { 826 uint8 resnum; 827 uint32 updown; 828} pmu_res_updown_t; 829 830/* Change resource dependencies masks */ 831typedef struct { 832 uint32 res_mask; /* resources (chip specific) */ 833 int8 action; /* action, e.g. RES_DEPEND_SET */ 834 uint32 depend_mask; /* changes to the dependencies mask */ 835 bool (*filter)(si_t *sih); /* action is taken when filter is NULL or return TRUE */ 836} pmu_res_depend_t; 837 838/* Resource dependencies mask change action */ 839#define RES_DEPEND_SET 0 /* Override the dependencies mask */ 840#define RES_DEPEND_ADD 1 /* Add to the dependencies mask */ 841#define RES_DEPEND_REMOVE -1 /* Remove from the dependencies mask */ 842 843static const pmu_res_updown_t BCMATTACHDATA(bcm4328a0_res_updown)[] = { 844 { RES4328_EXT_SWITCHER_PWM, 0x0101 }, 845 { RES4328_BB_SWITCHER_PWM, 0x1f01 }, 846 { RES4328_BB_SWITCHER_BURST, 0x010f }, 847 { RES4328_BB_EXT_SWITCHER_BURST, 0x0101 }, 848 { RES4328_ILP_REQUEST, 0x0202 }, 849 { RES4328_RADIO_SWITCHER_PWM, 0x0f01 }, 850 { RES4328_RADIO_SWITCHER_BURST, 0x0f01 }, 851 { RES4328_ROM_SWITCH, 0x0101 }, 852 { RES4328_PA_REF_LDO, 0x0f01 }, 853 { RES4328_RADIO_LDO, 0x0f01 }, 854 { RES4328_AFE_LDO, 0x0f01 }, 855 { RES4328_PLL_LDO, 0x0f01 }, 856 { RES4328_BG_FILTBYP, 0x0101 }, 857 { RES4328_TX_FILTBYP, 0x0101 }, 858 { RES4328_RX_FILTBYP, 0x0101 }, 859 { RES4328_XTAL_PU, 0x0101 }, 860 { RES4328_XTAL_EN, 0xa001 }, 861 { RES4328_BB_PLL_FILTBYP, 0x0101 }, 862 { RES4328_RF_PLL_FILTBYP, 0x0101 }, 863 { RES4328_BB_PLL_PU, 0x0701 } 864}; 865 866static const pmu_res_depend_t BCMATTACHDATA(bcm4328a0_res_depend)[] = { 867 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */ 868 { 869 PMURES_BIT(RES4328_ILP_REQUEST), 870 RES_DEPEND_SET, 871 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | PMURES_BIT(RES4328_BB_SWITCHER_PWM), 872 NULL 873 } 874}; 875 876static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown_qt)[] = { 877 { RES4325_HT_AVAIL, 0x0300 }, 878 { RES4325_BBPLL_PWRSW_PU, 0x0101 }, 879 { RES4325_RFPLL_PWRSW_PU, 0x0101 }, 880 { RES4325_ALP_AVAIL, 0x0100 }, 881 { RES4325_XTAL_PU, 0x1000 }, 882 { RES4325_LNLDO1_PU, 0x0800 }, 883 { RES4325_CLDO_CBUCK_PWM, 0x0101 }, 884 { RES4325_CBUCK_PWM, 0x0803 } 885}; 886 887static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown)[] = { 888 { RES4325_XTAL_PU, 0x1501 } 889}; 890 891static const pmu_res_depend_t BCMATTACHDATA(bcm4325a0_res_depend)[] = { 892 /* Adjust OTP PU resource dependencies - remove BB BURST */ 893 { 894 PMURES_BIT(RES4325_OTP_PU), 895 RES_DEPEND_REMOVE, 896 PMURES_BIT(RES4325_BUCK_BOOST_BURST), 897 NULL 898 }, 899 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */ 900 { 901 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL), 902 RES_DEPEND_ADD, 903 PMURES_BIT(RES4325_BUCK_BOOST_BURST) | PMURES_BIT(RES4325_BUCK_BOOST_PWM), 904 si_pmu_res_depfltr_bb 905 }, 906 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 907 { 908 PMURES_BIT(RES4325_HT_AVAIL), 909 RES_DEPEND_ADD, 910 PMURES_BIT(RES4325_RX_PWRSW_PU) | PMURES_BIT(RES4325_TX_PWRSW_PU) | 911 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU), 912 NULL 913 }, 914 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */ 915 { 916 PMURES_BIT(RES4325_ILP_REQUEST) | PMURES_BIT(RES4325_ABUCK_BURST) | 917 PMURES_BIT(RES4325_ABUCK_PWM) | PMURES_BIT(RES4325_LNLDO1_PU) | 918 PMURES_BIT(RES4325C1_LNLDO2_PU) | PMURES_BIT(RES4325_XTAL_PU) | 919 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_RX_PWRSW_PU) | 920 PMURES_BIT(RES4325_TX_PWRSW_PU) | PMURES_BIT(RES4325_RFPLL_PWRSW_PU) | 921 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU) | 922 PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL), 923 RES_DEPEND_REMOVE, 924 PMURES_BIT(RES4325B0_CBUCK_LPOM) | PMURES_BIT(RES4325B0_CBUCK_BURST) | 925 PMURES_BIT(RES4325B0_CBUCK_PWM), 926 si_pmu_res_depfltr_ncb 927 } 928}; 929 930static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown_qt)[] = { 931 { RES4315_HT_AVAIL, 0x0101 }, 932 { RES4315_XTAL_PU, 0x0100 }, 933 { RES4315_LNLDO1_PU, 0x0100 }, 934 { RES4315_PALDO_PU, 0x0100 }, 935 { RES4315_CLDO_PU, 0x0100 }, 936 { RES4315_CBUCK_PWM, 0x0100 }, 937 { RES4315_CBUCK_BURST, 0x0100 }, 938 { RES4315_CBUCK_LPOM, 0x0100 } 939}; 940 941static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown)[] = { 942 { RES4315_XTAL_PU, 0x2501 } 943}; 944 945static const pmu_res_depend_t BCMATTACHDATA(bcm4315a0_res_depend)[] = { 946 /* Adjust OTP PU resource dependencies - not need PALDO unless write */ 947 { 948 PMURES_BIT(RES4315_OTP_PU), 949 RES_DEPEND_REMOVE, 950 PMURES_BIT(RES4315_PALDO_PU), 951 si_pmu_res_depfltr_npaldo 952 }, 953 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */ 954 { 955 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL), 956 RES_DEPEND_ADD, 957 PMURES_BIT(RES4315_PALDO_PU), 958 si_pmu_res_depfltr_paldo 959 }, 960 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 961 { 962 PMURES_BIT(RES4315_HT_AVAIL), 963 RES_DEPEND_ADD, 964 PMURES_BIT(RES4315_RX_PWRSW_PU) | PMURES_BIT(RES4315_TX_PWRSW_PU) | 965 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | PMURES_BIT(RES4315_AFE_PWRSW_PU), 966 NULL 967 }, 968 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */ 969 { 970 PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) | 971 PMURES_BIT(RES4315_LNLDO1_PU) | PMURES_BIT(RES4315_OTP_PU) | 972 PMURES_BIT(RES4315_LNLDO2_PU) | PMURES_BIT(RES4315_XTAL_PU) | 973 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_RX_PWRSW_PU) | 974 PMURES_BIT(RES4315_TX_PWRSW_PU) | PMURES_BIT(RES4315_RFPLL_PWRSW_PU) | 975 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | PMURES_BIT(RES4315_AFE_PWRSW_PU) | 976 PMURES_BIT(RES4315_BBPLL_PWRSW_PU) | PMURES_BIT(RES4315_HT_AVAIL), 977 RES_DEPEND_REMOVE, 978 PMURES_BIT(RES4315_CBUCK_LPOM) | PMURES_BIT(RES4315_CBUCK_BURST) | 979 PMURES_BIT(RES4315_CBUCK_PWM), 980 si_pmu_res_depfltr_ncb 981 } 982}; 983 984static const pmu_res_updown_t BCMATTACHDATA(bcm4329_res_updown)[] = { 985 { RES4329_XTAL_PU, 0x3201 }, 986 { RES4329_PALDO_PU, 0x3501 } 987}; 988 989static const pmu_res_depend_t BCMATTACHDATA(bcm4329_res_depend)[] = { 990 /* Make lnldo1 independent of CBUCK_PWM and CBUCK_BURST */ 991 { 992 PMURES_BIT(RES4329_LNLDO1_PU), 993 RES_DEPEND_REMOVE, 994 PMURES_BIT(RES4329_CBUCK_PWM) | PMURES_BIT(RES4329_CBUCK_BURST), 995 NULL 996 }, 997 { 998 PMURES_BIT(RES4329_CBUCK_BURST), 999 RES_DEPEND_ADD, 1000 PMURES_BIT(RES4329_CBUCK_LPOM) | PMURES_BIT(RES4329_PALDO_PU), 1001 NULL 1002 }, 1003 { 1004 PMURES_BIT(RES4329_BBPLL_PWRSW_PU), 1005 RES_DEPEND_ADD, 1006 PMURES_BIT(RES4329_RX_PWRSW_PU) | PMURES_BIT(RES4329_TX_PWRSW_PU) | 1007 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | PMURES_BIT(RES4329_AFE_PWRSW_PU), 1008 NULL 1009 }, 1010 /* Adjust HT Avail resource dependencies */ 1011 { 1012 PMURES_BIT(RES4329_HT_AVAIL), 1013 RES_DEPEND_ADD, 1014 PMURES_BIT(RES4329_PALDO_PU) | 1015 PMURES_BIT(RES4329_RX_PWRSW_PU) | PMURES_BIT(RES4329_TX_PWRSW_PU) | 1016 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | PMURES_BIT(RES4329_AFE_PWRSW_PU), 1017 NULL 1018 } 1019}; 1020 1021static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown_qt)[] = { 1022 { RES4319_HT_AVAIL, 0x0101 }, 1023 { RES4319_XTAL_PU, 0x0100 }, 1024 { RES4319_LNLDO1_PU, 0x0100 }, 1025 { RES4319_PALDO_PU, 0x0100 }, 1026 { RES4319_CLDO_PU, 0x0100 }, 1027 { RES4319_CBUCK_PWM, 0x0100 }, 1028 { RES4319_CBUCK_BURST, 0x0100 }, 1029 { RES4319_CBUCK_LPOM, 0x0100 } 1030}; 1031 1032static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown)[] = { 1033 { RES4319_XTAL_PU, 0x3f01 } 1034}; 1035 1036static const pmu_res_depend_t BCMATTACHDATA(bcm4319a0_res_depend)[] = { 1037 /* Adjust OTP PU resource dependencies - not need PALDO unless write */ 1038 { 1039 PMURES_BIT(RES4319_OTP_PU), 1040 RES_DEPEND_REMOVE, 1041 PMURES_BIT(RES4319_PALDO_PU), 1042 si_pmu_res_depfltr_npaldo 1043 }, 1044 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */ 1045 { 1046 PMURES_BIT(RES4319_HT_AVAIL), 1047 RES_DEPEND_ADD, 1048 PMURES_BIT(RES4319_PALDO_PU), 1049 si_pmu_res_depfltr_paldo 1050 }, 1051 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 1052 { 1053 PMURES_BIT(RES4319_HT_AVAIL), 1054 RES_DEPEND_ADD, 1055 PMURES_BIT(RES4319_RX_PWRSW_PU) | PMURES_BIT(RES4319_TX_PWRSW_PU) | 1056 PMURES_BIT(RES4319_RFPLL_PWRSW_PU) | 1057 PMURES_BIT(RES4319_LOGEN_PWRSW_PU) | PMURES_BIT(RES4319_AFE_PWRSW_PU), 1058 NULL 1059 } 1060}; 1061 1062static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown_qt)[] = { 1063 { RES4336_HT_AVAIL, 0x0101 }, 1064 { RES4336_XTAL_PU, 0x0100 }, 1065 { RES4336_CLDO_PU, 0x0100 }, 1066 { RES4336_CBUCK_PWM, 0x0100 }, 1067 { RES4336_CBUCK_BURST, 0x0100 }, 1068 { RES4336_CBUCK_LPOM, 0x0100 } 1069}; 1070 1071static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown)[] = { 1072 { RES4336_HT_AVAIL, 0x0D01} 1073}; 1074 1075static const pmu_res_depend_t BCMATTACHDATA(bcm4336a0_res_depend)[] = { 1076 /* Just a dummy entry for now */ 1077 { 1078 PMURES_BIT(RES4336_RSVD), 1079 RES_DEPEND_ADD, 1080 0, 1081 NULL 1082 } 1083}; 1084 1085static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown_qt)[] = { 1086 { RES4330_HT_AVAIL, 0x0101 }, 1087 { RES4330_XTAL_PU, 0x0100 }, 1088 { RES4330_CLDO_PU, 0x0100 }, 1089 { RES4330_CBUCK_PWM, 0x0100 }, 1090 { RES4330_CBUCK_BURST, 0x0100 }, 1091 { RES4330_CBUCK_LPOM, 0x0100 } 1092}; 1093 1094static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown)[] = { 1095 { RES4330_HT_AVAIL, 0x0e02} 1096}; 1097 1098static const pmu_res_depend_t BCMATTACHDATA(bcm4330a0_res_depend)[] = { 1099 /* Just a dummy entry for now */ 1100 { 1101 PMURES_BIT(RES4330_HT_AVAIL), 1102 RES_DEPEND_ADD, 1103 0, 1104 NULL 1105 } 1106}; 1107 1108static const pmu_res_updown_t BCMATTACHDATA(bcm4334a0_res_updown_qt)[] = {{0, 0}}; 1109static const pmu_res_updown_t BCMATTACHDATA(bcm4334a0_res_updown)[] = {{0, 0}}; 1110static const pmu_res_depend_t BCMATTACHDATA(bcm4334a0_res_depend)[] = {{0, 0, 0, NULL}}; 1111 1112static const pmu_res_updown_t BCMATTACHDATA(bcm4324a0_res_updown_qt)[] = { 1113 {RES4324_SR_SAVE_RESTORE, 0x00320032} 1114}; 1115 1116static const pmu_res_updown_t BCMATTACHDATA(bcm4324a0_res_updown)[] = { 1117 {RES4324_SR_SAVE_RESTORE, 0x00020002}, 1118#ifdef BCMUSBDEV_ENABLED 1119 {RES4324_XTAL_PU, 0x007d0001} 1120#else 1121 {RES4324_XTAL_PU, 0x00120001} 1122#endif 1123}; 1124 1125static const pmu_res_updown_t BCMATTACHDATA(bcm4324b0_res_updown)[] = { 1126 {RES4324_SR_SAVE_RESTORE, 0x00050005}, 1127 {RES4324_XTAL_PU, 0x00120001} 1128}; 1129 1130static const pmu_res_updown_t BCMATTACHDATA(bcm4335_res_updown)[] = { 1131#if defined(PMU_OPT) 1132 {RES4335_LPLDO_PO, 0x00020002}, 1133 {RES4335_PMU_BG_PU, 0x00080000}, 1134 {RES4335_PMU_SLEEP, 0x001A0013}, 1135 {RES4335_RSVD_3, 0x00000000}, 1136 {RES4335_CBUCK_LPOM_PU, 0x00000000}, 1137 {RES4335_CBUCK_PFM_PU, 0x00000000}, 1138 {RES4335_RSVD_6, 0x00000000}, 1139 {RES4335_RSVD_7, 0x00000000}, 1140 {RES4335_LNLDO_PU, 0x00060000}, 1141 {RES4335_XTALLDO_PU, 0x000A0000}, 1142 {RES4335_LDO3P3_PU, 0x00080000}, 1143 {RES4335_OTP_PU, 0x00000000}, 1144 {RES4335_XTAL_PU, 0x00260000}, 1145 {RES4335_SR_CLK_START, 0x00020000}, 1146 {RES4335_LQ_AVAIL, 0x00000000}, 1147 {RES4335_LQ_START, 0x00020000}, 1148 {RES4335_RSVD_16, 0x001d0000}, 1149 {RES4335_WL_CORE_RDY, 0x00000001}, 1150 {RES4335_ILP_REQ, 0x00000000}, 1151 {RES4335_ALP_AVAIL, 0x00000000}, 1152 {RES4335_MINI_PMU, 0x00020000}, 1153 {RES4335_RADIO_PU, 0x00030000}, 1154 {RES4335_SR_CLK_STABLE, 0x00020000}, 1155 {RES4335_SR_SAVE_RESTORE, 0x00090009}, 1156 {RES4335_SR_PHY_PWRSW, 0x00130000}, 1157 {RES4335_SR_VDDM_PWRSW, 0x00130000}, 1158 {RES4335_SR_SUBCORE_PWRSW, 0x00130000}, 1159 {RES4335_SR_SLEEP, 0x00000000}, 1160 {RES4335_HT_START, 0x00020000}, 1161 {RES4335_HT_AVAIL, 0x00000000}, 1162 {RES4335_MACPHY_CLKAVAIL, 0x00000000} 1163#else 1164 {RES4335_XTAL_PU, 0x001F0002} 1165#endif /* defined (PMU_OPT) */ 1166}; 1167 1168#if defined(PMU_OPT_REV6) 1169static const pmu_res_depend_t BCMATTACHDATA(bcm4335c0_res_depend)[] = { 1170 { 1171 PMURES_BIT(RES4335_CBUCK_PFM_PU), 1172 RES_DEPEND_SET, 1173 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_LPLDO_PO) | 1174 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP), 1175 NULL 1176 }, 1177 { 1178 PMURES_BIT(RES4335_RSVD_6), 1179 RES_DEPEND_SET, 1180 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1181 PMURES_BIT(RES4335_PMU_SLEEP), 1182 NULL 1183 }, 1184 { 1185 PMURES_BIT(RES4335_LNLDO_PU), 1186 RES_DEPEND_SET, 1187 PMURES_BIT(RES4335_CBUCK_PFM_PU) | 1188 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_LPLDO_PO) | 1189 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP), 1190 NULL 1191 }, 1192 { 1193 PMURES_BIT(RES4335_XTALLDO_PU), 1194 RES_DEPEND_SET, 1195 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_LPLDO_PO) | 1196 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP), 1197 NULL 1198 }, 1199 { 1200 PMURES_BIT(RES4335_LDO3P3_PU), 1201 RES_DEPEND_SET, 1202 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1203 PMURES_BIT(RES4335_PMU_SLEEP), 1204 NULL 1205 }, 1206 { 1207 PMURES_BIT(RES4335_OTP_PU), 1208 RES_DEPEND_SET, 1209 PMURES_BIT(RES4335_LDO3P3_PU) | PMURES_BIT(RES4335_LPLDO_PO) | 1210 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP), 1211 NULL 1212 }, 1213 { 1214 PMURES_BIT(RES4335_XTAL_PU), 1215 RES_DEPEND_SET, 1216 PMURES_BIT(RES4335_XTALLDO_PU) | PMURES_BIT(RES4335_RSVD_6) | 1217 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1218 PMURES_BIT(RES4335_PMU_SLEEP), 1219 NULL 1220 }, 1221 { 1222 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_SR_CLK_STABLE), 1223 RES_DEPEND_SET, 1224 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1225 PMURES_BIT(RES4335_SR_VDDM_PWRSW) | PMURES_BIT(RES4335_RSVD_16) | 1226 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1227 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_LDO3P3_PU) | 1228 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1229 PMURES_BIT(RES4335_PMU_SLEEP), 1230 NULL 1231 }, 1232 { 1233 PMURES_BIT(RES4335_LQ_AVAIL), 1234 RES_DEPEND_SET, 1235 PMURES_BIT(RES4335_LQ_START) | PMURES_BIT(RES4335_WL_CORE_RDY) | 1236 PMURES_BIT(RES4335_SR_SLEEP) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1237 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_CLK_START) | 1238 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_LDO3P3_PU) | 1239 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1240 PMURES_BIT(RES4335_SR_VDDM_PWRSW) | PMURES_BIT(RES4335_RSVD_16) | 1241 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1242 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_RSVD_6) | 1243 PMURES_BIT(RES4335_XTALLDO_PU), 1244 NULL 1245 }, 1246 { 1247 PMURES_BIT(RES4335_LQ_START) | PMURES_BIT(RES4335_ILP_REQ) | 1248 PMURES_BIT(RES4335_ALP_AVAIL), 1249 RES_DEPEND_SET, 1250 PMURES_BIT(RES4335_XTALLDO_PU) | PMURES_BIT(RES4335_SR_SLEEP) | 1251 PMURES_BIT(RES4335_SR_SAVE_RESTORE) | PMURES_BIT(RES4335_SR_CLK_STABLE) | 1252 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_XTAL_PU) | 1253 PMURES_BIT(RES4335_LDO3P3_PU) | PMURES_BIT(RES4335_SR_PHY_PWRSW) | 1254 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1255 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_LPLDO_PO) | 1256 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP) | 1257 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_WL_CORE_RDY), 1258 NULL 1259 }, 1260 { 1261 PMURES_BIT(RES4335_RSVD_16), 1262 RES_DEPEND_SET, 1263 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1264 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_RSVD_6), 1265 NULL 1266 }, 1267 { 1268 PMURES_BIT(RES4335_WL_CORE_RDY), 1269 RES_DEPEND_SET, 1270 PMURES_BIT(RES4335_XTALLDO_PU) | PMURES_BIT(RES4335_SR_SLEEP) | 1271 PMURES_BIT(RES4335_SR_SAVE_RESTORE) | PMURES_BIT(RES4335_SR_CLK_STABLE) | 1272 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_XTAL_PU) | 1273 PMURES_BIT(RES4335_LDO3P3_PU) | PMURES_BIT(RES4335_SR_PHY_PWRSW) | 1274 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1275 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_LPLDO_PO) | 1276 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP) | 1277 PMURES_BIT(RES4335_RSVD_6), 1278 NULL 1279 }, 1280 { 1281 PMURES_BIT(RES4335_MINI_PMU), 1282 RES_DEPEND_SET, 1283 PMURES_BIT(RES4335_XTALLDO_PU) | PMURES_BIT(RES4335_RSVD_6) | 1284 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1285 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_XTAL_PU), 1286 NULL 1287 }, 1288 { 1289 PMURES_BIT(RES4335_RADIO_PU), 1290 RES_DEPEND_SET, 1291 PMURES_BIT(RES4335_XTALLDO_PU) | PMURES_BIT(RES4335_RSVD_6) | 1292 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1293 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_XTAL_PU) | 1294 PMURES_BIT(RES4335_MINI_PMU), 1295 NULL 1296 }, 1297 { 1298 PMURES_BIT(RES4335_SR_SAVE_RESTORE), 1299 RES_DEPEND_SET, 1300 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1301 PMURES_BIT(RES4335_SR_VDDM_PWRSW) | PMURES_BIT(RES4335_RSVD_16) | 1302 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1303 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_LDO3P3_PU) | 1304 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1305 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_SR_CLK_STABLE) | 1306 PMURES_BIT(RES4335_SR_CLK_START), 1307 NULL 1308 }, 1309 { 1310 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1311 PMURES_BIT(RES4335_SR_VDDM_PWRSW), 1312 RES_DEPEND_SET, 1313 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_LPLDO_PO) | 1314 PMURES_BIT(RES4335_PMU_BG_PU) | PMURES_BIT(RES4335_PMU_SLEEP) | 1315 PMURES_BIT(RES4335_RSVD_6), 1316 NULL 1317 }, 1318 { 1319 PMURES_BIT(RES4335_SR_SLEEP) | PMURES_BIT(RES4335_HT_START), 1320 RES_DEPEND_SET, 1321 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1322 PMURES_BIT(RES4335_SR_VDDM_PWRSW) | PMURES_BIT(RES4335_RSVD_16) | 1323 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1324 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_LDO3P3_PU) | 1325 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1326 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_SR_CLK_STABLE) | 1327 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_SR_SAVE_RESTORE), 1328 NULL 1329 }, 1330 { 1331 PMURES_BIT(RES4335_HT_AVAIL), 1332 RES_DEPEND_SET, 1333 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1334 PMURES_BIT(RES4335_SR_VDDM_PWRSW) | PMURES_BIT(RES4335_RSVD_16) | 1335 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1336 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_LDO3P3_PU) | 1337 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1338 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_SR_CLK_STABLE) | 1339 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1340 PMURES_BIT(RES4335_HT_START) | PMURES_BIT(RES4335_WL_CORE_RDY) | 1341 PMURES_BIT(RES4335_SR_SLEEP), 1342 NULL 1343 }, 1344 { 1345 PMURES_BIT(RES4335_MACPHY_CLKAVAIL), 1346 RES_DEPEND_SET, 1347 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1348 PMURES_BIT(RES4335_SR_VDDM_PWRSW) | PMURES_BIT(RES4335_RSVD_16) | 1349 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1350 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_LDO3P3_PU) | 1351 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1352 PMURES_BIT(RES4335_PMU_SLEEP) | PMURES_BIT(RES4335_SR_CLK_STABLE) | 1353 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1354 PMURES_BIT(RES4335_HT_START) | PMURES_BIT(RES4335_WL_CORE_RDY) | 1355 PMURES_BIT(RES4335_SR_SLEEP) | PMURES_BIT(RES4335_MINI_PMU) | 1356 PMURES_BIT(RES4335_RADIO_PU), 1357 NULL 1358 } 1359}; 1360#endif /* defined (PMU_OPT_REV6) */ 1361 1362static const pmu_res_depend_t BCMATTACHDATA(bcm4335b0_res_depend)[] = { 1363#if !defined(PMU_OPT) 1364 { 1365 PMURES_BIT(RES4335_ALP_AVAIL) | 1366 PMURES_BIT(RES4335_HT_START) | 1367 PMURES_BIT(RES4335_HT_AVAIL) | 1368 PMURES_BIT(RES4335_MACPHY_CLKAVAIL) | 1369 PMURES_BIT(RES4335_RADIO_PU), 1370 RES_DEPEND_ADD, 1371 PMURES_BIT(RES4335_OTP_PU) | PMURES_BIT(RES4335_LDO3P3_PU), 1372 NULL 1373 } 1374#else 1375 { 1376 PMURES_BIT(RES4335_CBUCK_PFM_PU), 1377 RES_DEPEND_SET, 1378 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1379 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1380 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1381 PMURES_BIT(RES4335_PMU_SLEEP), 1382 NULL 1383 }, 1384 { 1385 PMURES_BIT(RES4335_RSVD_6), 1386 RES_DEPEND_SET, 1387 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1388 PMURES_BIT(RES4335_PMU_SLEEP), 1389 NULL 1390 }, 1391 { 1392 PMURES_BIT(RES4335_LNLDO_PU), 1393 RES_DEPEND_SET, 1394 PMURES_BIT(RES4335_XTAL_PU) | 1395 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1396 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1397 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1398 PMURES_BIT(RES4335_PMU_SLEEP), 1399 NULL 1400 }, 1401 { 1402 PMURES_BIT(RES4335_XTALLDO_PU), 1403 RES_DEPEND_SET, 1404 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1405 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1406 PMURES_BIT(RES4335_PMU_SLEEP), 1407 NULL 1408 }, 1409 { 1410 PMURES_BIT(RES4335_LDO3P3_PU), 1411 RES_DEPEND_SET, 1412 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1413 PMURES_BIT(RES4335_PMU_SLEEP), 1414 NULL 1415 }, 1416 { 1417 PMURES_BIT(RES4335_OTP_PU), 1418 RES_DEPEND_SET, 1419 PMURES_BIT(RES4335_SR_PHY_PWRSW) | 1420 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1421 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1422 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_RSVD_16) | 1423 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_LDO3P3_PU) | 1424 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1425 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1426 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1427 PMURES_BIT(RES4335_PMU_SLEEP), 1428 NULL 1429 }, 1430 { 1431 PMURES_BIT(RES4335_XTAL_PU), 1432 RES_DEPEND_SET, 1433 PMURES_BIT(RES4335_XTALLDO_PU) | 1434 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1435 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1436 PMURES_BIT(RES4335_PMU_SLEEP), 1437 NULL 1438 }, 1439 { 1440 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_SR_CLK_STABLE), 1441 RES_DEPEND_SET, 1442 PMURES_BIT(RES4335_SR_PHY_PWRSW) | 1443 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1444 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_XTAL_PU) | 1445 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1446 PMURES_BIT(RES4335_RSVD_6) | 1447 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1448 PMURES_BIT(RES4335_PMU_SLEEP), 1449 NULL 1450 }, 1451 { 1452 PMURES_BIT(RES4335_LQ_AVAIL), 1453 RES_DEPEND_SET, 1454 PMURES_BIT(RES4335_SR_SLEEP) | 1455 PMURES_BIT(RES4335_LQ_START) | PMURES_BIT(RES4335_WL_CORE_RDY) | 1456 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_OTP_PU) | 1457 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1458 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1459 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_RSVD_16) | 1460 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_LDO3P3_PU) | 1461 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1462 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1463 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1464 PMURES_BIT(RES4335_PMU_SLEEP), 1465 NULL 1466 }, 1467 { 1468 PMURES_BIT(RES4335_LQ_START) | PMURES_BIT(RES4335_ILP_REQ) | 1469 PMURES_BIT(RES4335_ALP_AVAIL), 1470 RES_DEPEND_SET, 1471 PMURES_BIT(RES4335_SR_SLEEP) | PMURES_BIT(RES4335_WL_CORE_RDY) | 1472 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_OTP_PU) | 1473 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1474 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1475 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_RSVD_16) | 1476 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_LDO3P3_PU) | 1477 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1478 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1479 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1480 PMURES_BIT(RES4335_PMU_SLEEP), 1481 NULL 1482 }, 1483 { 1484 PMURES_BIT(RES4335_RSVD_16), 1485 RES_DEPEND_SET, 1486 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1487 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1488 PMURES_BIT(RES4335_PMU_SLEEP), 1489 NULL 1490 }, 1491 { 1492 PMURES_BIT(RES4335_WL_CORE_RDY), 1493 RES_DEPEND_SET, 1494 PMURES_BIT(RES4335_SR_SLEEP) | 1495 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_OTP_PU) | 1496 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1497 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1498 PMURES_BIT(RES4335_SR_CLK_START) | PMURES_BIT(RES4335_RSVD_16) | 1499 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_LDO3P3_PU) | 1500 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1501 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1502 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1503 PMURES_BIT(RES4335_PMU_SLEEP), 1504 NULL 1505 }, 1506 { 1507 PMURES_BIT(RES4335_MINI_PMU), 1508 RES_DEPEND_SET, 1509 PMURES_BIT(RES4335_XTAL_PU) | 1510 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1511 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1512 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1513 PMURES_BIT(RES4335_PMU_SLEEP), 1514 NULL 1515 }, 1516 { 1517 PMURES_BIT(RES4335_RADIO_PU), 1518 RES_DEPEND_SET, 1519 PMURES_BIT(RES4335_XTAL_PU) | PMURES_BIT(RES4335_MINI_PMU) | 1520 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1521 PMURES_BIT(RES4335_CBUCK_PFM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1522 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1523 PMURES_BIT(RES4335_PMU_SLEEP), 1524 NULL 1525 }, 1526 { 1527 PMURES_BIT(RES4335_SR_SAVE_RESTORE), 1528 RES_DEPEND_SET, 1529 PMURES_BIT(RES4335_SR_CLK_STABLE) | 1530 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_CLK_START) | 1531 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1532 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_XTAL_PU) | 1533 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1534 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_CBUCK_PFM_PU) | 1535 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1536 PMURES_BIT(RES4335_PMU_SLEEP), 1537 NULL 1538 }, 1539 { 1540 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | 1541 PMURES_BIT(RES4335_SR_VDDM_PWRSW), 1542 RES_DEPEND_SET, 1543 PMURES_BIT(RES4335_RSVD_16) | 1544 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_RSVD_6) | 1545 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1546 PMURES_BIT(RES4335_PMU_SLEEP), 1547 NULL 1548 }, 1549 { 1550 PMURES_BIT(RES4335_SR_SLEEP), 1551 RES_DEPEND_SET, 1552 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1553 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_CLK_START) | 1554 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1555 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_XTAL_PU) | 1556 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1557 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_CBUCK_PFM_PU) | 1558 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1559 PMURES_BIT(RES4335_PMU_SLEEP), 1560 NULL 1561 }, 1562 { 1563 PMURES_BIT(RES4335_HT_START), 1564 RES_DEPEND_SET, 1565 PMURES_BIT(RES4335_SR_SLEEP) | 1566 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1567 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_CLK_START) | 1568 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1569 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_XTAL_PU) | 1570 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1571 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_CBUCK_PFM_PU) | 1572 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1573 PMURES_BIT(RES4335_PMU_SLEEP), 1574 NULL 1575 }, 1576 { 1577 PMURES_BIT(RES4335_HT_AVAIL), 1578 RES_DEPEND_SET, 1579 PMURES_BIT(RES4335_SR_SLEEP) | PMURES_BIT(RES4335_HT_START) | 1580 PMURES_BIT(RES4335_LDO3P3_PU) | PMURES_BIT(RES4335_OTP_PU) | 1581 PMURES_BIT(RES4335_WL_CORE_RDY) | PMURES_BIT(RES4335_ALP_AVAIL) | 1582 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1583 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_CLK_START) | 1584 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1585 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_XTAL_PU) | 1586 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1587 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_CBUCK_PFM_PU) | 1588 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1589 PMURES_BIT(RES4335_PMU_SLEEP), 1590 NULL 1591 }, 1592 { 1593 PMURES_BIT(RES4335_MACPHY_CLKAVAIL), 1594 RES_DEPEND_SET, 1595 PMURES_BIT(RES4335_MINI_PMU) | PMURES_BIT(RES4335_RADIO_PU) | 1596 PMURES_BIT(RES4335_SR_SLEEP) | PMURES_BIT(RES4335_HT_START) | 1597 PMURES_BIT(RES4335_LDO3P3_PU) | PMURES_BIT(RES4335_OTP_PU) | 1598 PMURES_BIT(RES4335_WL_CORE_RDY) | PMURES_BIT(RES4335_ALP_AVAIL) | 1599 PMURES_BIT(RES4335_SR_CLK_STABLE) | PMURES_BIT(RES4335_SR_SAVE_RESTORE) | 1600 PMURES_BIT(RES4335_SR_PHY_PWRSW) | PMURES_BIT(RES4335_SR_CLK_START) | 1601 PMURES_BIT(RES4335_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4335_SR_VDDM_PWRSW) | 1602 PMURES_BIT(RES4335_RSVD_16) | PMURES_BIT(RES4335_XTAL_PU) | 1603 PMURES_BIT(RES4335_CBUCK_LPOM_PU) | PMURES_BIT(RES4335_XTALLDO_PU) | 1604 PMURES_BIT(RES4335_RSVD_6) | PMURES_BIT(RES4335_CBUCK_PFM_PU) | 1605 PMURES_BIT(RES4335_LPLDO_PO) | PMURES_BIT(RES4335_PMU_BG_PU) | 1606 PMURES_BIT(RES4335_PMU_SLEEP), 1607 NULL 1608 } 1609#endif /* !defined (PMU_OPT) */ 1610}; 1611 1612static const pmu_res_updown_t BCMATTACHDATA(bcm4350_res_updown)[] = { 1613#if defined(SAVERESTORE) && !defined(SAVERESTORE_DISABLED) 1614 {RES4350_SR_SAVE_RESTORE, 0x00190019}, 1615#endif /* SAVERESTORE && !SAVERESTORE_DISABLED */ 1616 1617 {RES4350_XTAL_PU, 0x001f0002}, 1618 {RES4350_LQ_AVAIL, 0x00010001}, 1619 {RES4350_LQ_START, 0x00010001}, 1620 {RES4350_WL_CORE_RDY, 0x00010001}, 1621 {RES4350_ALP_AVAIL, 0x00010001}, 1622 {RES4350_SR_CLK_STABLE, 0x00010001}, 1623 {RES4350_SR_SLEEP, 0x00010001}, 1624 {RES4350_HT_AVAIL, 0x00010001}, 1625 1626#ifndef SRFAST 1627 {RES4350_SR_PHY_PWRSW, 0x00120002}, 1628 {RES4350_SR_VDDM_PWRSW, 0x00120002}, 1629 {RES4350_SR_SUBCORE_PWRSW, 0x00120002}, 1630#else /* SRFAST */ 1631 {RES4350_PMU_SLEEP, 0x0012000f}, 1632 {RES4350_CBUCK_LPOM_PU, 0x00010001}, 1633 {RES4350_CBUCK_PFM_PU, 0x00010001}, 1634 {RES4350_COLD_START_WAIT, 0x00010001}, 1635 {RES4350_SR_PHY_PWRSW, 0x000e0002}, 1636 {RES4350_SR_VDDM_PWRSW, 0x000e0002}, 1637 {RES4350_SR_SUBCORE_PWRSW, 0x000e0002}, 1638#endif 1639}; 1640 1641static const pmu_res_depend_t BCMATTACHDATA(bcm4350_res_depend)[] = { 1642#ifdef SRFAST 1643 { 1644 PMURES_BIT(RES4350_COLD_START_WAIT) | 1645 PMURES_BIT(RES4350_WL_CORE_RDY) | 1646 PMURES_BIT(RES4350_SR_CLK_START) | 1647 PMURES_BIT(RES4350_HT_START) | 1648 PMURES_BIT(RES4350_HT_AVAIL), 1649 RES_DEPEND_REMOVE, 1650 PMURES_BIT(RES4350_LNLDO_PU), 1651 NULL 1652 }, 1653 { 1654 PMURES_BIT(RES4350_SR_CLK_STABLE) | 1655 PMURES_BIT(RES4350_SR_SAVE_RESTORE) | 1656 PMURES_BIT(RES4350_SR_PHY_PWRSW) | 1657 PMURES_BIT(RES4350_SR_VDDM_PWRSW) | 1658 PMURES_BIT(RES4350_SR_SUBCORE_PWRSW) | 1659 PMURES_BIT(RES4350_SR_SLEEP), 1660 RES_DEPEND_REMOVE, 1661 PMURES_BIT(RES4350_LNLDO_PU), 1662 NULL 1663 }, 1664 { 1665 PMURES_BIT(RES4350_XTALLDO_PU) | 1666 PMURES_BIT(RES4350_XTAL_PU), 1667 RES_DEPEND_REMOVE, 1668 PMURES_BIT(RES4350_COLD_START_WAIT) | PMURES_BIT(RES4350_LNLDO_PU), 1669 NULL 1670 }, 1671 { 1672 PMURES_BIT(RES4350_ALP_AVAIL), 1673 RES_DEPEND_REMOVE, 1674 PMURES_BIT(RES4350_LNLDO_PU) | PMURES_BIT(RES4350_LQ_AVAIL) | 1675 PMURES_BIT(RES4350_LQ_START), 1676 NULL 1677 }, 1678 { 1679 PMURES_BIT(RES4350_ALP_AVAIL) | 1680 PMURES_BIT(RES4350_MINI_PMU) | 1681 PMURES_BIT(RES4350_RADIO_PU) | 1682 PMURES_BIT(RES4350_SR_CLK_STABLE) | 1683 PMURES_BIT(RES4350_SR_SAVE_RESTORE) | 1684 PMURES_BIT(RES4350_SR_PHY_PWRSW) | 1685 PMURES_BIT(RES4350_SR_VDDM_PWRSW) | 1686 PMURES_BIT(RES4350_SR_SUBCORE_PWRSW) | 1687 PMURES_BIT(RES4350_SR_SLEEP) | 1688 PMURES_BIT(RES4350_HT_START) | 1689 PMURES_BIT(RES4350_HT_AVAIL) | 1690 PMURES_BIT(RES4350_MACPHY_CLKAVAIL), 1691 RES_DEPEND_REMOVE, 1692 PMURES_BIT(RES4350_LQ_AVAIL) | PMURES_BIT(RES4350_LQ_START), 1693 NULL 1694 }, 1695#else 1696 {0, 0, 0, NULL} 1697#endif /* SRFAST */ 1698}; 1699 1700 1701static const pmu_res_updown_t BCMATTACHDATA(bcm4360_res_updown)[] = { 1702 {RES4360_BBPLLPWRSW_PU, 0x00100001} 1703}; 1704 1705static const pmu_res_depend_t BCMATTACHDATA(bcm4324a0_res_depend)[] = { 1706 { 1707 PMURES_BIT(RES4324_SR_PHY_PWRSW) | PMURES_BIT(RES4324_SR_PHY_PIC), 1708 RES_DEPEND_SET, 1709 0x00000000, 1710 NULL 1711 }, 1712 { 1713 PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) | 1714 PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) | 1715 PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) | 1716 PMURES_BIT(RES4324_SR_SUBCORE_PIC) | PMURES_BIT(RES4324_SR_MEM_PM0) | 1717 PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1718 RES_DEPEND_ADD, 1719 PMURES_BIT(RES4324_LPLDO_PU) | PMURES_BIT(RES4324_RESET_PULLDN_DIS) | 1720 PMURES_BIT(RES4324_PMU_BG_PU) | PMURES_BIT(RES4324_HSIC_LDO_PU) | 1721 PMURES_BIT(RES4324_CBUCK_LPOM_PU) | PMURES_BIT(RES4324_CBUCK_PFM_PU) | 1722 PMURES_BIT(RES4324_CLDO_PU) | PMURES_BIT(RES4324_LPLDO2_LVM), 1723 NULL 1724 }, 1725 { 1726 PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) | 1727 PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) | 1728 PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1729 RES_DEPEND_ADD, 1730 PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) | 1731 PMURES_BIT(RES4324_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4324_SR_SUBCORE_PIC), 1732 NULL 1733 }, 1734 { 1735 PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) | 1736 PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) | 1737 PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) | 1738 PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1739 RES_DEPEND_ADD, 1740 PMURES_BIT(RES4324_LNLDO1_PU) | PMURES_BIT(RES4324_LNLDO2_PU) | 1741 PMURES_BIT(RES4324_BBPLL_PU) | PMURES_BIT(RES4324_LQ_AVAIL), 1742 NULL 1743 }, 1744 { 1745 PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) | 1746 PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) | 1747 PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) | 1748 PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1749 RES_DEPEND_ADD, 1750 PMURES_BIT(RES4324_SR_MEM_PM0), 1751 NULL 1752 }, 1753 { 1754 PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) | 1755 PMURES_BIT(RES4324_SR_MEM_PM0), 1756 RES_DEPEND_ADD, 1757 PMURES_BIT(RES4324_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4324_SR_SUBCORE_PIC), 1758 NULL 1759 }, 1760 { 1761 PMURES_BIT(RES4324_ILP_REQ) | PMURES_BIT(RES4324_ALP_AVAIL) | 1762 PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL) | 1763 PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1764 RES_DEPEND_ADD, 1765 PMURES_BIT(RES4324_WL_CORE_READY), 1766 NULL 1767 }, 1768 { 1769 PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) | 1770 PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1771 RES_DEPEND_ADD, 1772 PMURES_BIT(RES4324_LQ_AVAIL), 1773 NULL 1774 }, 1775 { 1776 PMURES_BIT(RES4324_SR_SAVE_RESTORE), 1777 RES_DEPEND_ADD, 1778 PMURES_BIT(RES4324_SR_CLK_STABLE), 1779 NULL 1780 }, 1781 { 1782 PMURES_BIT(RES4324_SR_SUBCORE_PIC), 1783 RES_DEPEND_ADD, 1784 PMURES_BIT(RES4324_SR_SUBCORE_PWRSW), 1785 NULL 1786 }, 1787 { 1788 PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL) | 1789 PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1790 RES_DEPEND_ADD, 1791 PMURES_BIT(RES4324_ALP_AVAIL), 1792 NULL 1793 }, 1794 { 1795 PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1796 RES_DEPEND_ADD, 1797 PMURES_BIT(RES4324_LDO3P3_PU) | PMURES_BIT(RES4324_PALDO_PU), 1798 NULL 1799 }, 1800 { 1801 PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1802 RES_DEPEND_ADD, 1803 PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL), 1804 NULL 1805 }, 1806 { 1807 PMURES_BIT(RES4324_ILP_REQ) | PMURES_BIT(RES4324_ALP_AVAIL) | 1808 PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL) | 1809 PMURES_BIT(RES4324_MACPHY_CLKAVAIL), 1810 RES_DEPEND_REMOVE, 1811 PMURES_BIT(RES4324_SR_PHY_PWRSW) | PMURES_BIT(RES4324_SR_PHY_PIC), 1812 NULL 1813 }, 1814 { 1815 PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) | 1816 PMURES_BIT(RES4324_SR_SUBCORE_PIC) | PMURES_BIT(RES4324_SR_MEM_PM0), 1817 RES_DEPEND_REMOVE, 1818 PMURES_BIT(RES4324_WL_CORE_READY), 1819 NULL 1820 }, 1821 { 1822 PMURES_BIT(RES4324_SR_SUBCORE_PIC) | PMURES_BIT(RES4324_SR_MEM_PM0), 1823 RES_DEPEND_REMOVE, 1824 PMURES_BIT(RES4324_LNLDO1_PU) | PMURES_BIT(RES4324_LNLDO2_PU) | 1825 PMURES_BIT(RES4324_BBPLL_PU) | PMURES_BIT(RES4324_LQ_AVAIL), 1826 NULL 1827 } 1828}; 1829 1830/* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */ 1831static bool 1832BCMATTACHFN(si_pmu_res_depfltr_bb)(si_t *sih) 1833{ 1834 return (sih->boardflags & BFL_BUCKBOOST) != 0; 1835} 1836 1837/* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */ 1838static bool 1839BCMATTACHFN(si_pmu_res_depfltr_ncb)(si_t *sih) 1840{ 1841 if (CHIPID(sih->chip) == BCM4325_CHIP_ID) 1842 return (CHIPREV(sih->chiprev) >= 2) && ((sih->boardflags & BFL_NOCBUCK) != 0); 1843 return ((sih->boardflags & BFL_NOCBUCK) != 0); 1844} 1845 1846/* TRUE if the power topology uses the PALDO */ 1847static bool 1848BCMATTACHFN(si_pmu_res_depfltr_paldo)(si_t *sih) 1849{ 1850 return (sih->boardflags & BFL_PALDO) != 0; 1851} 1852 1853/* TRUE if the power topology doesn't use the PALDO */ 1854static bool 1855BCMATTACHFN(si_pmu_res_depfltr_npaldo)(si_t *sih) 1856{ 1857 return (sih->boardflags & BFL_PALDO) == 0; 1858} 1859 1860#define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \ 1861 sih->boardtype == BCM94325BGABU_BOARD) 1862 1863/** 1864 * Determines min/max rsrc masks. Normally hardware contains these masks, and software reads the 1865 * masks from hardware. Note that masks are sometimes dependent on chip straps. 1866 */ 1867static void 1868si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax) 1869{ 1870 uint32 min_mask = 0, max_mask = 0; 1871 uint rsrcs; 1872 /* # resources */ 1873 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; 1874 1875 /* determine min/max rsrc masks */ 1876 switch (CHIPID(sih->chip)) { 1877 case BCM4328_CHIP_ID: 1878 /* Down to ILP request */ 1879 min_mask = PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | 1880 PMURES_BIT(RES4328_BB_SWITCHER_PWM) | 1881 PMURES_BIT(RES4328_XTAL_EN); 1882#ifdef BCMROMOFFLOAD 1883 min_mask |= PMURES_BIT(RES4328_ROM_SWITCH); 1884#endif 1885 /* Allow (but don't require) PLL to turn on */ 1886 max_mask = 0xfffff; 1887 break; 1888 case BCM5354_CHIP_ID: 1889 /* Allow (but don't require) PLL to turn on */ 1890 max_mask = 0xfffff; 1891 break; 1892 case BCM4325_CHIP_ID: 1893 ASSERT(CHIPREV(sih->chiprev) >= 2); 1894 /* Minimum rsrcs to work in sleep mode */ 1895 if (!(sih->boardflags & BFL_NOCBUCK)) 1896 min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM); 1897 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> 1898 CST4325_PMUTOP_2B_SHIFT) == 1) 1899 min_mask |= PMURES_BIT(RES4325B0_CLDO_PU); 1900 if (!si_is_otp_disabled(sih)) 1901 min_mask |= PMURES_BIT(RES4325_OTP_PU); 1902 /* Leave buck boost on in burst mode for certain boards */ 1903 if ((sih->boardflags & BFL_BUCKBOOST) && (BCM94325_BBVDDIOSD_BOARDS(sih))) 1904 min_mask |= PMURES_BIT(RES4325_BUCK_BOOST_BURST); 1905 /* Allow all resources to be turned on upon requests */ 1906 max_mask = ~(~0 << rsrcs); 1907 break; 1908 case BCM4312_CHIP_ID: 1909 /* default min_mask = 0x80000cbb is wrong */ 1910 min_mask = 0xcbb; 1911 /* 1912 * max_mask = 0x7fff; 1913 * pmu_res_updown_table_sz = 0; 1914 * pmu_res_depend_table_sz = 0; 1915 */ 1916 break; 1917 case BCM4322_CHIP_ID: 1918 case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 1919 case BCM4342_CHIP_ID: 1920 if (CHIPREV(sih->chiprev) < 2) { 1921 /* request ALP(can skip for A1) */ 1922 min_mask = PMURES_BIT(RES4322_RF_LDO) | 1923 PMURES_BIT(RES4322_XTAL_PU) | 1924 PMURES_BIT(RES4322_ALP_AVAIL); 1925 if (BUSTYPE(sih->bustype) == SI_BUS) { 1926 min_mask += PMURES_BIT(RES4322_SI_PLL_ON) | 1927 PMURES_BIT(RES4322_HT_SI_AVAIL) | 1928 PMURES_BIT(RES4322_PHY_PLL_ON) | 1929 PMURES_BIT(RES4322_OTP_PU) | 1930 PMURES_BIT(RES4322_HT_PHY_AVAIL); 1931 max_mask = 0x1ff; 1932 } 1933 } 1934 break; 1935 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 1936 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 1937 case BCM43226_CHIP_ID: case BCM43420_CHIP_ID: 1938 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 1939 case BCM43237_CHIP_ID: 1940 case BCM43234_CHIP_ID: 1941 case BCM4331_CHIP_ID: 1942 case BCM43431_CHIP_ID: 1943 case BCM6362_CHIP_ID: 1944 /* use chip default */ 1945 break; 1946 1947 case BCM4360_CHIP_ID: 1948 case BCM43460_CHIP_ID: 1949 case BCM4352_CHIP_ID: 1950 case BCM43526_CHIP_ID: 1951 if (CHIPREV(sih->chiprev) >= 0x3) { 1952 int cst_ht = CST4360_RSRC_INIT_MODE(sih->chipst) & 0x1; 1953 if (cst_ht == 0) 1954 max_mask = 0x1ff; 1955 } 1956 break; 1957 1958 1959 case BCM43143_CHIP_ID: 1960 max_mask = PMURES_BIT(RES43143_EXT_SWITCHER_PWM) | PMURES_BIT(RES43143_XTAL_PU) | 1961 PMURES_BIT(RES43143_ILP_REQUEST) | PMURES_BIT(RES43143_ALP_AVAIL) | 1962 PMURES_BIT(RES43143_WL_CORE_READY) | PMURES_BIT(RES43143_BBPLL_PWRSW_PU) | 1963 PMURES_BIT(RES43143_HT_AVAIL) | PMURES_BIT(RES43143_RADIO_PU) | 1964 PMURES_BIT(RES43143_MACPHY_CLK_AVAIL) | PMURES_BIT(RES43143_OTP_PU) | 1965 PMURES_BIT(RES43143_LQ_AVAIL); 1966 break; 1967 1968 case BCM4329_CHIP_ID: 1969 1970 /* Down to save the power. */ 1971 if (CHIPREV(sih->chiprev) >= 0x2) { 1972 min_mask = PMURES_BIT(RES4329_CBUCK_LPOM) | 1973 PMURES_BIT(RES4329_LNLDO1_PU) | PMURES_BIT(RES4329_CLDO_PU); 1974 } else { 1975 min_mask = PMURES_BIT(RES4329_CBUCK_LPOM) | PMURES_BIT(RES4329_CLDO_PU); 1976 } 1977 if (!si_is_otp_disabled(sih)) 1978 min_mask |= PMURES_BIT(RES4329_OTP_PU); 1979 /* Allow (but don't require) PLL to turn on */ 1980 max_mask = 0x3ff63e; 1981 1982 break; 1983 case BCM4315_CHIP_ID: 1984 /* We only need a few resources to be kept on all the time */ 1985 if (!(sih->boardflags & BFL_NOCBUCK)) 1986 min_mask = PMURES_BIT(RES4315_CBUCK_LPOM); 1987 min_mask |= PMURES_BIT(RES4315_CLDO_PU); 1988 /* Allow everything else to be turned on upon requests */ 1989 max_mask = ~(~0 << rsrcs); 1990 break; 1991 case BCM4319_CHIP_ID: 1992#ifdef CONFIG_XIP 1993 /* Initialize to ResInitMode2 for bootloader */ 1994 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | 1995 PMURES_BIT(RES4319_CBUCK_BURST) | 1996 PMURES_BIT(RES4319_CBUCK_PWM) | 1997 PMURES_BIT(RES4319_CLDO_PU) | 1998 PMURES_BIT(RES4319_PALDO_PU) | 1999 PMURES_BIT(RES4319_LNLDO1_PU) | 2000 PMURES_BIT(RES4319_OTP_PU) | 2001 PMURES_BIT(RES4319_XTAL_PU) | 2002 PMURES_BIT(RES4319_ALP_AVAIL) | 2003 PMURES_BIT(RES4319_RFPLL_PWRSW_PU); 2004#else 2005 /* We only need a few resources to be kept on all the time */ 2006 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | 2007 PMURES_BIT(RES4319_CLDO_PU); 2008#endif /* CONFIG_XIP */ 2009 2010 /* Allow everything else to be turned on upon requests */ 2011 max_mask = ~(~0 << rsrcs); 2012 break; 2013 case BCM4336_CHIP_ID: 2014 case BCM43362_CHIP_ID: 2015 /* Down to save the power. */ 2016 min_mask = PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU) | 2017 PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU) | 2018 PMURES_BIT(RES4336_DIS_INT_RESET_PD); 2019 /* Allow (but don't require) PLL to turn on */ 2020 max_mask = 0x1ffffff; 2021 break; 2022 2023 case BCM4330_CHIP_ID: 2024 /* Down to save the power. */ 2025 min_mask = PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU) | 2026 PMURES_BIT(RES4330_DIS_INT_RESET_PD) | PMURES_BIT(RES4330_LDO3P3_PU) | 2027 PMURES_BIT(RES4330_OTP_PU); 2028 /* Allow (but don't require) PLL to turn on */ 2029 max_mask = 0xfffffff; 2030 break; 2031 2032 case BCM4313_CHIP_ID: 2033 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) | 2034 PMURES_BIT(RES4313_XTAL_PU_RSRC) | 2035 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) | 2036 PMURES_BIT(RES4313_SYNTH_PWRSW_RSRC) | 2037 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC); 2038 max_mask = 0xffff; 2039 break; 2040 2041 case BCM43239_CHIP_ID: 2042 case BCM4324_CHIP_ID: 2043 min_mask = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 0, 0); 2044 /* Set the bits for all resources in the max mask except for the SR Engine */ 2045 max_mask = 0x7FFFFFFF; 2046 break; 2047 case BCM4335_CHIP_ID: 2048 /* Read the min_res_mask register. Set the mask to 0 as we need to only read. */ 2049 min_mask = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 0, 0); 2050 /* For 4335, min res mask is set to 1 after disabling power islanding */ 2051 /* Write a non-zero value in chipcontrol reg 3 */ 2052 si_pmu_chipcontrol(sih, 3, 0x1, 0x1); 2053 /* Set the bits for all resources in the max mask except for the SR Engine */ 2054 max_mask = 0x7FFFFFFF; 2055 break; 2056 2057 case BCM4350_CHIP_ID: 2058 /* JIRA: SWWLAN-27486 Power consumption optimization */ 2059 if (CST4350_IFC_MODE(sih->chipst) == CST4350_IFC_MODE_PCIE) { 2060 int L1substate = si_pcie_get_L1substate(sih); 2061 if (L1substate & 1) /* L1.2 is enabled */ 2062 min_mask = PMURES_BIT(RES4350_LPLDO_PU) | 2063 PMURES_BIT(RES4350_PMU_BG_PU) | 2064 PMURES_BIT(RES4350_PMU_SLEEP); 2065 else /* use chip default min resource mask */ 2066 min_mask = 0xfc22f77; 2067 } else { 2068 /* use chip default min resource mask */ 2069 min_mask = si_corereg(sih, SI_CC_IDX, 2070 OFFSETOF(chipcregs_t, min_res_mask), 0, 0); 2071 } 2072 2073#if defined(SAVERESTORE) 2074 /* min_mask is updated after SR code is downloaded to txfifo */ 2075 if (SR_ENAB() && sr_isenab(sih)) 2076 min_mask = PMURES_BIT(RES4350_LPLDO_PU); 2077#endif 2078 /* Set the bits for all resources in the max mask except for the SR Engine */ 2079 max_mask = 0x7FFFFFFF; 2080 break; 2081 2082 case BCM43242_CHIP_ID: 2083 case BCM43243_CHIP_ID: 2084 /* Read the min_res_mask register. Set the mask to 0 as we need to only read. */ 2085 min_mask = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 0, 0); 2086 2087 /* Set the bits for all resources in the max mask except for the SR Engine */ 2088 max_mask = (1 << rsrcs) - 1; 2089 break; 2090 2091 case BCM4314_CHIP_ID: 2092 /* set 4314 min mask to 0x3_f6ff -- ILP available (DozeMode) */ 2093 if ((sih->chippkg == BCM4314SDIO_PKG_ID) || 2094 (sih->chippkg == BCM4314SDIO_ARM_PKG_ID) || 2095 (sih->chippkg == BCM4314SDIO_FPBGA_PKG_ID)) { 2096 min_mask = PMURES_BIT(RES4314_LPLDO_PU) | 2097 PMURES_BIT(RES4314_PMU_SLEEP_DIS) | 2098 PMURES_BIT(RES4314_PMU_BG_PU) | 2099 PMURES_BIT(RES4314_CBUCK_LPOM_PU) | 2100 PMURES_BIT(RES4314_CBUCK_PFM_PU) | 2101 PMURES_BIT(RES4314_CLDO_PU) | 2102 PMURES_BIT(RES4314_OTP_PU); 2103 } else { 2104 min_mask = PMURES_BIT(RES4314_LPLDO_PU) | 2105 PMURES_BIT(RES4314_PMU_SLEEP_DIS) | 2106 PMURES_BIT(RES4314_PMU_BG_PU) | 2107 PMURES_BIT(RES4314_CBUCK_LPOM_PU) | 2108 PMURES_BIT(RES4314_CBUCK_PFM_PU) | 2109 PMURES_BIT(RES4314_CLDO_PU) | 2110 PMURES_BIT(RES4314_LPLDO2_LVM) | 2111 PMURES_BIT(RES4314_WL_PMU_PU) | 2112 PMURES_BIT(RES4314_LDO3P3_PU) | 2113 PMURES_BIT(RES4314_OTP_PU) | 2114 PMURES_BIT(RES4314_WL_PWRSW_PU) | 2115 PMURES_BIT(RES4314_LQ_AVAIL) | 2116 PMURES_BIT(RES4314_LOGIC_RET) | 2117 PMURES_BIT(RES4314_MEM_SLEEP) | 2118 PMURES_BIT(RES4314_MACPHY_RET) | 2119 PMURES_BIT(RES4314_WL_CORE_READY) | 2120 PMURES_BIT(RES4314_SYNTH_PWRSW_PU); 2121 } 2122 max_mask = 0x3FFFFFFF; 2123 break; 2124 case BCM43142_CHIP_ID: 2125 /* Only PCIe */ 2126 min_mask = PMURES_BIT(RES4314_LPLDO_PU) | 2127 PMURES_BIT(RES4314_PMU_SLEEP_DIS) | 2128 PMURES_BIT(RES4314_PMU_BG_PU) | 2129 PMURES_BIT(RES4314_CBUCK_LPOM_PU) | 2130 PMURES_BIT(RES4314_CBUCK_PFM_PU) | 2131 PMURES_BIT(RES4314_CLDO_PU) | 2132 PMURES_BIT(RES4314_LPLDO2_LVM) | 2133 PMURES_BIT(RES4314_WL_PMU_PU) | 2134 PMURES_BIT(RES4314_LDO3P3_PU) | 2135 PMURES_BIT(RES4314_OTP_PU) | 2136 PMURES_BIT(RES4314_WL_PWRSW_PU) | 2137 PMURES_BIT(RES4314_LQ_AVAIL) | 2138 PMURES_BIT(RES4314_LOGIC_RET) | 2139 PMURES_BIT(RES4314_MEM_SLEEP) | 2140 PMURES_BIT(RES4314_MACPHY_RET) | 2141 PMURES_BIT(RES4314_WL_CORE_READY); 2142 max_mask = 0x3FFFFFFF; 2143 break; 2144 case BCM4334_CHIP_ID: 2145 /* Use default for boot loader */ 2146#ifndef BCM_BOOTLOADER 2147 min_mask = PMURES_BIT(RES4334_LPLDO_PU) | PMURES_BIT(RES4334_RESET_PULLDN_DIS) | 2148 PMURES_BIT(RES4334_OTP_PU) | PMURES_BIT(RES4334_WL_CORE_READY); 2149#endif /* !BCM_BOOTLOADER */ 2150 2151 max_mask = 0x7FFFFFFF; 2152 break; 2153 2154 default: 2155 PMU_ERROR(("MIN and MAX mask is not programmed\n")); 2156 break; 2157 } 2158 2159 /* Apply nvram override to min mask */ 2160 if (min_mask_valid == TRUE) { 2161 PMU_MSG(("Applying rmin=%d to min_mask\n", nvram_min_mask)); 2162 min_mask = nvram_min_mask; 2163 } 2164 /* Apply nvram override to max mask */ 2165 if (max_mask_valid == TRUE) { 2166 PMU_MSG(("Applying rmax=%d to max_mask\n", nvram_max_mask)); 2167 max_mask = nvram_max_mask; 2168 } 2169 2170 *pmin = min_mask; 2171 *pmax = max_mask; 2172} /* si_pmu_res_masks */ 2173 2174/** Initialize PMU hardware resources. */ 2175void 2176BCMATTACHFN(si_pmu_res_init)(si_t *sih, osl_t *osh) 2177{ 2178#if !defined(_CFE_) && !defined(_CFEZ_) 2179 chipcregs_t *cc; 2180 uint origidx; 2181 const pmu_res_updown_t *pmu_res_updown_table = NULL; 2182 uint pmu_res_updown_table_sz = 0; 2183 const pmu_res_depend_t *pmu_res_depend_table = NULL; 2184 uint pmu_res_depend_table_sz = 0; 2185 uint32 min_mask = 0, max_mask = 0; 2186 char name[8]; 2187 const char *val; 2188 uint i, rsrcs; 2189 2190 ASSERT(sih->cccaps & CC_CAP_PMU); 2191 2192 /* Remember original core before switch to chipc */ 2193 origidx = si_coreidx(sih); 2194 cc = si_setcoreidx(sih, SI_CC_IDX); 2195 ASSERT(cc != NULL); 2196 2197 /* Cache nvram override to min mask */ 2198 if ((val = getvar(NULL, "rmin")) != NULL) { 2199 min_mask_valid = TRUE; 2200 nvram_min_mask = (uint32)bcm_strtoul(val, NULL, 0); 2201 } 2202 /* Cache nvram override to max mask */ 2203 if ((val = getvar(NULL, "rmax")) != NULL) { 2204 max_mask_valid = TRUE; 2205 nvram_max_mask = (uint32)bcm_strtoul(val, NULL, 0); 2206 } 2207 2208 /* 2209 * Hardware contains the resource updown and dependency tables. Only if a chip has a 2210 * hardware problem, software tables can be used to override hardware tables. 2211 */ 2212 switch (CHIPID(sih->chip)) { 2213 case BCM4328_CHIP_ID: 2214 pmu_res_updown_table = bcm4328a0_res_updown; 2215 pmu_res_updown_table_sz = ARRAYSIZE(bcm4328a0_res_updown); 2216 pmu_res_depend_table = bcm4328a0_res_depend; 2217 pmu_res_depend_table_sz = ARRAYSIZE(bcm4328a0_res_depend); 2218 break; 2219 case BCM4325_CHIP_ID: 2220 /* Optimize resources up/down timers */ 2221 if (ISSIM_ENAB(sih)) { 2222 pmu_res_updown_table = bcm4325a0_res_updown_qt; 2223 pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown_qt); 2224 } else { 2225 pmu_res_updown_table = bcm4325a0_res_updown; 2226 pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown); 2227 } 2228 /* Optimize resources dependencies */ 2229 pmu_res_depend_table = bcm4325a0_res_depend; 2230 pmu_res_depend_table_sz = ARRAYSIZE(bcm4325a0_res_depend); 2231 break; 2232 case BCM4315_CHIP_ID: 2233 /* Optimize resources up/down timers */ 2234 if (ISSIM_ENAB(sih)) { 2235 pmu_res_updown_table = bcm4315a0_res_updown_qt; 2236 pmu_res_updown_table_sz = ARRAYSIZE(bcm4315a0_res_updown_qt); 2237 } 2238 else { 2239 pmu_res_updown_table = bcm4315a0_res_updown; 2240 pmu_res_updown_table_sz = ARRAYSIZE(bcm4315a0_res_updown); 2241 } 2242 /* Optimize resources dependencies masks */ 2243 pmu_res_depend_table = bcm4315a0_res_depend; 2244 pmu_res_depend_table_sz = ARRAYSIZE(bcm4315a0_res_depend); 2245 break; 2246 case BCM4329_CHIP_ID: 2247 /* Optimize resources up/down timers */ 2248 if (ISSIM_ENAB(sih)) { 2249 pmu_res_updown_table = NULL; 2250 pmu_res_updown_table_sz = 0; 2251 } else { 2252 pmu_res_updown_table = bcm4329_res_updown; 2253 pmu_res_updown_table_sz = ARRAYSIZE(bcm4329_res_updown); 2254 } 2255 /* Optimize resources dependencies */ 2256 pmu_res_depend_table = bcm4329_res_depend; 2257 pmu_res_depend_table_sz = ARRAYSIZE(bcm4329_res_depend); 2258 break; 2259 2260 case BCM4319_CHIP_ID: 2261 /* Optimize resources up/down timers */ 2262 if (ISSIM_ENAB(sih)) { 2263 pmu_res_updown_table = bcm4319a0_res_updown_qt; 2264 pmu_res_updown_table_sz = ARRAYSIZE(bcm4319a0_res_updown_qt); 2265 } 2266 else { 2267 pmu_res_updown_table = bcm4319a0_res_updown; 2268 pmu_res_updown_table_sz = ARRAYSIZE(bcm4319a0_res_updown); 2269 } 2270 /* Optimize resources dependencies masks */ 2271 pmu_res_depend_table = bcm4319a0_res_depend; 2272 pmu_res_depend_table_sz = ARRAYSIZE(bcm4319a0_res_depend); 2273 break; 2274 2275 case BCM4336_CHIP_ID: 2276 case BCM43362_CHIP_ID: 2277 /* Optimize resources up/down timers */ 2278 if (ISSIM_ENAB(sih)) { 2279 pmu_res_updown_table = bcm4336a0_res_updown_qt; 2280 pmu_res_updown_table_sz = ARRAYSIZE(bcm4336a0_res_updown_qt); 2281 } 2282 else { 2283 pmu_res_updown_table = bcm4336a0_res_updown; 2284 pmu_res_updown_table_sz = ARRAYSIZE(bcm4336a0_res_updown); 2285 } 2286 /* Optimize resources dependencies masks */ 2287 pmu_res_depend_table = bcm4336a0_res_depend; 2288 pmu_res_depend_table_sz = ARRAYSIZE(bcm4336a0_res_depend); 2289 break; 2290 2291 case BCM4330_CHIP_ID: 2292 /* Optimize resources up/down timers */ 2293 if (ISSIM_ENAB(sih)) { 2294 pmu_res_updown_table = bcm4330a0_res_updown_qt; 2295 pmu_res_updown_table_sz = ARRAYSIZE(bcm4330a0_res_updown_qt); 2296 } 2297 else { 2298 pmu_res_updown_table = bcm4330a0_res_updown; 2299 pmu_res_updown_table_sz = ARRAYSIZE(bcm4330a0_res_updown); 2300 } 2301 /* Optimize resources dependencies masks */ 2302 pmu_res_depend_table = bcm4330a0_res_depend; 2303 pmu_res_depend_table_sz = ARRAYSIZE(bcm4330a0_res_depend); 2304 break; 2305 case BCM4314_CHIP_ID: 2306 /* Enable SDIO wake up */ 2307 if (!((sih->chippkg == BCM4314PCIE_ARM_PKG_ID) || 2308 (sih->chippkg == BCM4314PCIE_PKG_ID) || 2309 (sih->chippkg == BCM4314DEV_PKG_ID))) 2310 { 2311 uint32 tmp; 2312 W_REG(osh, &cc->chipcontrol_addr, PMU_CHIPCTL3); 2313 tmp = R_REG(osh, &cc->chipcontrol_data); 2314 tmp |= (1 << PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT); 2315 W_REG(osh, &cc->chipcontrol_data, tmp); 2316 } 2317 case BCM43142_CHIP_ID: 2318 case BCM4334_CHIP_ID: 2319 /* Optimize resources up/down timers */ 2320 if (ISSIM_ENAB(sih)) { 2321 pmu_res_updown_table = bcm4334a0_res_updown_qt; 2322 /* pmu_res_updown_table_sz = ARRAYSIZE(bcm4334a0_res_updown_qt); */ 2323 } 2324 else { 2325 pmu_res_updown_table = bcm4334a0_res_updown; 2326 /* pmu_res_updown_table_sz = ARRAYSIZE(bcm4334a0_res_updown); */ 2327 } 2328 /* Optimize resources dependencies masks */ 2329 pmu_res_depend_table = bcm4334a0_res_depend; 2330 /* pmu_res_depend_table_sz = ARRAYSIZE(bcm4334a0_res_depend); */ 2331 break; 2332 case BCM4324_CHIP_ID: 2333 case BCM43242_CHIP_ID: 2334 case BCM43243_CHIP_ID: 2335 /* Need to change the up down timer for SR qt */ 2336 if (ISSIM_ENAB(sih)) { 2337 pmu_res_updown_table = bcm4324a0_res_updown_qt; 2338 pmu_res_updown_table_sz = ARRAYSIZE(bcm4324a0_res_updown_qt); 2339 } else if ((CHIPID(sih->chip) == BCM4324_CHIP_ID) && (CHIPREV(sih->chiprev) <= 1)) { 2340 pmu_res_updown_table = bcm4324a0_res_updown; 2341 pmu_res_updown_table_sz = ARRAYSIZE(bcm4324a0_res_updown); 2342 } else { 2343 pmu_res_updown_table = bcm4324b0_res_updown; 2344 pmu_res_updown_table_sz = ARRAYSIZE(bcm4324b0_res_updown); 2345 } 2346 pmu_res_depend_table = bcm4324a0_res_depend; 2347 pmu_res_depend_table_sz = ARRAYSIZE(bcm4324a0_res_depend); 2348 break; 2349 case BCM4335_CHIP_ID: 2350 pmu_res_updown_table = bcm4335_res_updown; 2351 pmu_res_updown_table_sz = ARRAYSIZE(bcm4335_res_updown); 2352 pmu_res_depend_table = bcm4335b0_res_depend; 2353 pmu_res_depend_table_sz = ARRAYSIZE(bcm4335b0_res_depend); 2354#if defined(PMU_OPT_REV6) 2355 if ((CHIPREV(sih->chiprev) >= 2)) { 2356 pmu_res_depend_table = bcm4335c0_res_depend; 2357 pmu_res_depend_table_sz = ARRAYSIZE(bcm4335c0_res_depend); 2358 } 2359#endif 2360 break; 2361 case BCM4350_CHIP_ID: 2362 pmu_res_updown_table = bcm4350_res_updown; 2363 pmu_res_updown_table_sz = ARRAYSIZE(bcm4350_res_updown); 2364 pmu_res_depend_table = bcm4350_res_depend; 2365 pmu_res_depend_table_sz = ARRAYSIZE(bcm4350_res_depend); 2366 break; 2367 case BCM4360_CHIP_ID: 2368 case BCM4352_CHIP_ID: 2369 pmu_res_updown_table = bcm4360_res_updown; 2370 pmu_res_updown_table_sz = ARRAYSIZE(bcm4360_res_updown); 2371 break; 2372 case BCM43143_CHIP_ID: 2373 /* POR values for up/down and dependency tables are sufficient. */ 2374 /* fall through */ 2375 default: 2376 break; 2377 } 2378 2379 /* # resources */ 2380 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; 2381 2382 /* Program up/down timers */ 2383 while (pmu_res_updown_table_sz--) { 2384 ASSERT(pmu_res_updown_table != NULL); 2385 PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n", 2386 pmu_res_updown_table[pmu_res_updown_table_sz].resnum, 2387 pmu_res_updown_table[pmu_res_updown_table_sz].updown)); 2388 W_REG(osh, &cc->res_table_sel, 2389 pmu_res_updown_table[pmu_res_updown_table_sz].resnum); 2390 W_REG(osh, &cc->res_updn_timer, 2391 pmu_res_updown_table[pmu_res_updown_table_sz].updown); 2392 } 2393 /* Apply nvram overrides to up/down timers */ 2394 for (i = 0; i < rsrcs; i ++) { 2395 uint32 r_val; 2396 snprintf(name, sizeof(name), "r%dt", i); 2397 if ((val = getvar(NULL, name)) == NULL) 2398 continue; 2399 r_val = (uint32)bcm_strtoul(val, NULL, 0); 2400 /* PMUrev = 13, pmu resource updown times are 12 bits(0:11 DT, 16:27 UT) */ 2401 if (sih->pmurev >= 13) { 2402 if (r_val < (1 << 16)) { 2403 uint16 up_time = (r_val >> 8) & 0xFF; 2404 r_val &= 0xFF; 2405 r_val |= (up_time << 16); 2406 } 2407 } 2408 PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, val, i)); 2409 W_REG(osh, &cc->res_table_sel, (uint32)i); 2410 W_REG(osh, &cc->res_updn_timer, r_val); 2411 } 2412 2413 /* Program resource dependencies table */ 2414 while (pmu_res_depend_table_sz--) { 2415 ASSERT(pmu_res_depend_table != NULL); 2416 if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL && 2417 !(pmu_res_depend_table[pmu_res_depend_table_sz].filter)(sih)) 2418 continue; 2419 for (i = 0; i < rsrcs; i ++) { 2420 if ((pmu_res_depend_table[pmu_res_depend_table_sz].res_mask & 2421 PMURES_BIT(i)) == 0) 2422 continue; 2423 W_REG(osh, &cc->res_table_sel, i); 2424 switch (pmu_res_depend_table[pmu_res_depend_table_sz].action) { 2425 case RES_DEPEND_SET: 2426 PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, 2427 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask)); 2428 W_REG(osh, &cc->res_dep_mask, 2429 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 2430 break; 2431 case RES_DEPEND_ADD: 2432 PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", 2433 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); 2434 OR_REG(osh, &cc->res_dep_mask, 2435 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 2436 break; 2437 case RES_DEPEND_REMOVE: 2438 PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", 2439 pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); 2440 AND_REG(osh, &cc->res_dep_mask, 2441 ~pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); 2442 break; 2443 default: 2444 ASSERT(0); 2445 break; 2446 } 2447 } 2448 } 2449 /* Apply nvram overrides to dependencies masks */ 2450 for (i = 0; i < rsrcs; i ++) { 2451 snprintf(name, sizeof(name), "r%dd", i); 2452 if ((val = getvar(NULL, name)) == NULL) 2453 continue; 2454 PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, i)); 2455 W_REG(osh, &cc->res_table_sel, (uint32)i); 2456 W_REG(osh, &cc->res_dep_mask, (uint32)bcm_strtoul(val, NULL, 0)); 2457 } 2458 2459 /* Determine min/max rsrc masks */ 2460 si_pmu_res_masks(sih, &min_mask, &max_mask); 2461 2462 /* Add min mask dependencies */ 2463 min_mask |= si_pmu_res_deps(sih, osh, cc, min_mask, FALSE); 2464 2465 /* It is required to program max_mask first and then min_mask */ 2466#ifdef BCM_BOOTLOADER 2467 if (CHIPID(sih->chip) == BCM4319_CHIP_ID) { 2468 min_mask |= R_REG(osh, &cc->min_res_mask); 2469 max_mask |= R_REG(osh, &cc->max_res_mask); 2470 } 2471#endif /* BCM_BOOTLOADER */ 2472 2473#ifdef BCM_BOOTLOADER 2474 /* Apply nvram override to max mask */ 2475 if ((val = getvar(NULL, "brmax")) != NULL) { 2476 PMU_MSG(("Applying brmax=%s to max_res_mask\n", val)); 2477 max_mask = (uint32)bcm_strtoul(val, NULL, 0); 2478 } 2479 2480 /* Apply nvram override to min mask */ 2481 if ((val = getvar(NULL, "brmin")) != NULL) { 2482 PMU_MSG(("Applying brmin=%s to min_res_mask\n", val)); 2483 min_mask = (uint32)bcm_strtoul(val, NULL, 0); 2484 } 2485#endif /* BCM_BOOTLOADER */ 2486 2487#ifndef BCMPCIDEV 2488 if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) || (CHIPID(sih->chip) == BCM4352_CHIP_ID)) && 2489 (CHIPREV(sih->chiprev) < 4) && 2490 ((CST4360_RSRC_INIT_MODE(sih->chipst) & 1) == 0)) { 2491 /* BBPLL */ 2492 W_REG(osh, &cc->pllcontrol_addr, 6); 2493 W_REG(osh, &cc->pllcontrol_data, 0x09048560); 2494 /* AVB PLL */ 2495 W_REG(osh, &cc->pllcontrol_addr, 14); 2496 W_REG(osh, &cc->pllcontrol_data, 0x09048560); 2497 si_pmu_pllupd(sih); 2498 } 2499#endif /* BCMPCIDEV */ 2500 2501 if (max_mask) { 2502 /* Ensure there is no bit set in min_mask which is not set in max_mask */ 2503 max_mask |= min_mask; 2504 2505 /* First set the bits which change from 0 to 1 in max, then update the 2506 * min_mask register and then reset the bits which change from 1 to 0 2507 * in max. This is required as the bit in MAX should never go to 0 when 2508 * the corresponding bit in min is still 1. Similarly the bit in min cannot 2509 * be 1 when the corresponding bit in max is still 0. 2510 */ 2511 OR_REG(osh, &cc->max_res_mask, max_mask); 2512 } else { 2513 /* First set the bits which change from 0 to 1 in max, then update the 2514 * min_mask register and then reset the bits which change from 1 to 0 2515 * in max. This is required as the bit in MAX should never go to 0 when 2516 * the corresponding bit in min is still 1. Similarly the bit in min cannot 2517 * be 1 when the corresponding bit in max is still 0. 2518 */ 2519 if (min_mask) 2520 OR_REG(osh, &cc->max_res_mask, min_mask); 2521 } 2522 2523 /* Program min resource mask */ 2524 if (min_mask) { 2525 PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask)); 2526 W_REG(osh, &cc->min_res_mask, min_mask); 2527 } 2528 2529 /* Program max resource mask */ 2530 if (max_mask) { 2531 PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask)); 2532 W_REG(osh, &cc->max_res_mask, max_mask); 2533 } 2534 2535 /* Add some delay; allow resources to come up and settle. */ 2536 OSL_DELAY(2000); 2537 2538 /* Return to original core */ 2539 si_setcoreidx(sih, origidx); 2540#endif /* !_CFE_ && !_CFEZ_ */ 2541} /* si_pmu_res_init */ 2542 2543/* setup pll and query clock speed */ 2544typedef struct { 2545 uint16 freq; /* x-tal frequency in [hz] */ 2546 uint8 xf; /* x-tal index as contained in PMU control reg, see PMU programmers guide */ 2547 uint8 wbint; 2548 uint32 wbfrac; 2549} pmu0_xtaltab0_t; 2550 2551/* the following table is based on 880Mhz fvco */ 2552static const pmu0_xtaltab0_t BCMINITDATA(pmu0_xtaltab0)[] = { 2553 { 12000, 1, 73, 349525 }, 2554 { 13000, 2, 67, 725937 }, 2555 { 14400, 3, 61, 116508 }, 2556 { 15360, 4, 57, 305834 }, 2557 { 16200, 5, 54, 336579 }, 2558 { 16800, 6, 52, 399457 }, 2559 { 19200, 7, 45, 873813 }, 2560 { 19800, 8, 44, 466033 }, 2561 { 20000, 9, 44, 0 }, 2562 { 25000, 10, 70, 419430 }, 2563 { 26000, 11, 67, 725937 }, 2564 { 30000, 12, 58, 699050 }, 2565 { 38400, 13, 45, 873813 }, 2566 { 40000, 14, 45, 0 }, 2567 { 0, 0, 0, 0 } 2568}; 2569 2570#ifdef BCMUSBDEV 2571#define PMU0_XTAL0_DEFAULT 11 2572#else 2573#define PMU0_XTAL0_DEFAULT 8 2574#endif 2575 2576#ifdef BCMUSBDEV 2577/** 2578 * Set new backplane PLL clock frequency 2579 */ 2580static void 2581BCMATTACHFN(si_pmu0_sbclk4328)(si_t *sih, int freq) 2582{ 2583 uint32 tmp, oldmax, oldmin, origidx; 2584 chipcregs_t *cc; 2585 2586 /* Remember original core before switch to chipc */ 2587 origidx = si_coreidx(sih); 2588 cc = si_setcoreidx(sih, SI_CC_IDX); 2589 ASSERT(cc); 2590 2591 /* Set new backplane PLL clock */ 2592 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 2593 tmp = R_REG(osh, &cc->pllcontrol_data); 2594 tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK); 2595 tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT; 2596 W_REG(osh, &cc->pllcontrol_data, tmp); 2597 2598 /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */ 2599 /* Disable PLL */ 2600 oldmin = R_REG(osh, &cc->min_res_mask); 2601 oldmax = R_REG(osh, &cc->max_res_mask); 2602 W_REG(osh, &cc->min_res_mask, oldmin & ~PMURES_BIT(RES4328_BB_PLL_PU)); 2603 W_REG(osh, &cc->max_res_mask, oldmax & ~PMURES_BIT(RES4328_BB_PLL_PU)); 2604 2605 /* It takes over several hundred usec to re-enable the PLL since the 2606 * sequencer state machines run on ILP clock. Set delay at 450us to be safe. 2607 * 2608 * Be sure PLL is powered down first before re-enabling it. 2609 */ 2610 2611 OSL_DELAY(PLL_DELAY); 2612 SPINWAIT((R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)), PLL_DELAY*3); 2613 if (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)) { 2614 /* If BB_PLL not powered down yet, new backplane PLL clock 2615 * may not take effect. 2616 * 2617 * Still early during bootup so no serial output here. 2618 */ 2619 PMU_ERROR(("Fatal: BB_PLL not power down yet!\n")); 2620 ASSERT(!(R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU))); 2621 } 2622 2623 /* Enable PLL */ 2624 W_REG(osh, &cc->max_res_mask, oldmax); 2625 2626 /* Return to original core */ 2627 si_setcoreidx(sih, origidx); 2628} /* si_pmu0_sbclk4328 */ 2629#endif /* BCMUSBDEV */ 2630 2631/** 2632 * Set up PLL registers in the PMU as per the crystal speed. 2633 * Uses xtalfreq variable, or passed-in default. 2634 */ 2635static void 2636BCMATTACHFN(si_pmu0_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal) 2637{ 2638 uint32 tmp; 2639 const pmu0_xtaltab0_t *xt; 2640 2641 /* Find the frequency in the table */ 2642 for (xt = pmu0_xtaltab0; xt->freq; xt ++) 2643 if (xt->freq == xtal) 2644 break; 2645 if (xt->freq == 0) 2646 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; 2647 2648 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); 2649 2650 /* Check current PLL state */ 2651 tmp = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 2652 PCTL_XTALFREQ_SHIFT; 2653 if (tmp == xt->xf) { 2654 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 2655 xt->freq / 1000, xt->freq % 1000)); 2656#ifdef BCMUSBDEV 2657 if (CHIPID(sih->chip) == BCM4328_CHIP_ID) 2658 si_pmu0_sbclk4328(sih, PMU0_PLL0_PC0_DIV_ARM_88MHZ); 2659#endif /* BCMUSBDEV */ 2660 return; 2661 } 2662 2663 if (tmp) { 2664 PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", 2665 xt->freq / 1000, xt->freq % 1000, 2666 pmu0_xtaltab0[tmp-1].freq / 1000, pmu0_xtaltab0[tmp-1].freq % 1000)); 2667 } else { 2668 PMU_MSG(("Programming PLL for %d.%d MHz\n", 2669 xt->freq / 1000, xt->freq % 1000)); 2670 } 2671 2672 /* Make sure the PLL is off */ 2673 switch (CHIPID(sih->chip)) { 2674 case BCM4328_CHIP_ID: 2675 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU)); 2676 AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU)); 2677 break; 2678 case BCM5354_CHIP_ID: 2679 AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU)); 2680 AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU)); 2681 break; 2682 default: 2683 ASSERT(0); 2684 } 2685 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL, PMU_MAX_TRANSITION_DLY); 2686 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL)); 2687 2688 PMU_MSG(("Done masking\n")); 2689 2690 /* Write PDIV in pllcontrol[0] */ 2691 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 2692 tmp = R_REG(osh, &cc->pllcontrol_data); 2693 if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ) 2694 tmp |= PMU0_PLL0_PC0_PDIV_MASK; 2695 else 2696 tmp &= ~PMU0_PLL0_PC0_PDIV_MASK; 2697 W_REG(osh, &cc->pllcontrol_data, tmp); 2698 2699 /* Write WILD in pllcontrol[1] */ 2700 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1); 2701 tmp = R_REG(osh, &cc->pllcontrol_data); 2702 tmp = ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) | 2703 (((xt->wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & 2704 PMU0_PLL0_PC1_WILD_INT_MASK) | 2705 ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) & 2706 PMU0_PLL0_PC1_WILD_FRAC_MASK))); 2707 if (xt->wbfrac == 0) 2708 tmp |= PMU0_PLL0_PC1_STOP_MOD; 2709 else 2710 tmp &= ~PMU0_PLL0_PC1_STOP_MOD; 2711 W_REG(osh, &cc->pllcontrol_data, tmp); 2712 2713 /* Write WILD in pllcontrol[2] */ 2714 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2); 2715 tmp = R_REG(osh, &cc->pllcontrol_data); 2716 tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) | 2717 ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) & 2718 PMU0_PLL0_PC2_WILD_INT_MASK)); 2719 W_REG(osh, &cc->pllcontrol_data, tmp); 2720 2721 PMU_MSG(("Done pll\n")); 2722 2723 /* Write XtalFreq. Set the divisor also. */ 2724 tmp = R_REG(osh, &cc->pmucontrol); 2725 tmp = ((tmp & ~PCTL_ILP_DIV_MASK) | 2726 (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & PCTL_ILP_DIV_MASK)); 2727 tmp = ((tmp & ~PCTL_XTALFREQ_MASK) | 2728 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK)); 2729 W_REG(osh, &cc->pmucontrol, tmp); 2730} /* si_pmu0_pllinit0 */ 2731 2732/** query alp/xtal clock frequency */ 2733static uint32 2734BCMINITFN(si_pmu0_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 2735{ 2736 const pmu0_xtaltab0_t *xt; 2737 uint32 xf; 2738 2739 /* Find the frequency in the table */ 2740 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 2741 PCTL_XTALFREQ_SHIFT; 2742 for (xt = pmu0_xtaltab0; xt->freq; xt++) 2743 if (xt->xf == xf) 2744 break; 2745 /* PLL must be configured before */ 2746 ASSERT(xt->freq); 2747 2748 return xt->freq * 1000; 2749} 2750 2751/** query CPU clock frequency */ 2752static uint32 2753BCMINITFN(si_pmu0_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 2754{ 2755 uint32 tmp, divarm; 2756 uint32 FVCO = FVCO_880; 2757 2758 /* Read divarm from pllcontrol[0] */ 2759 W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); 2760 tmp = R_REG(osh, &cc->pllcontrol_data); 2761 divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT; 2762 2763 2764 /* Return ARM/SB clock */ 2765 return FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000; 2766} /* si_pmu0_cpuclk0 */ 2767 2768/* setup pll and query clock speed */ 2769typedef struct { 2770 uint16 fref; /* x-tal frequency in [hz] */ 2771 uint8 xf; /* x-tal index as contained in PMU control reg, see PMU programmers guide */ 2772 uint8 p1div; 2773 uint8 p2div; 2774 uint8 ndiv_int; 2775 uint32 ndiv_frac; 2776} pmu1_xtaltab0_t; 2777 2778static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880_4329)[] = { 2779 {12000, 1, 3, 22, 0x9, 0xFFFFEF}, 2780 {13000, 2, 1, 6, 0xb, 0x483483}, 2781 {14400, 3, 1, 10, 0xa, 0x1C71C7}, 2782 {15360, 4, 1, 5, 0xb, 0x755555}, 2783 {16200, 5, 1, 10, 0x5, 0x6E9E06}, 2784 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, 2785 {19200, 7, 1, 4, 0xb, 0x755555}, 2786 {19800, 8, 1, 11, 0x4, 0xA57EB}, 2787 {20000, 9, 1, 11, 0x4, 0x0}, 2788 {24000, 10, 3, 11, 0xa, 0x0}, 2789 {25000, 11, 5, 16, 0xb, 0x0}, 2790 {26000, 12, 1, 1, 0x21, 0xD89D89}, 2791 {30000, 13, 3, 8, 0xb, 0x0}, 2792 {37400, 14, 3, 1, 0x46, 0x969696}, 2793 {38400, 15, 1, 1, 0x16, 0xEAAAAA}, 2794 {40000, 16, 1, 2, 0xb, 0}, 2795 {0, 0, 0, 0, 0, 0} 2796}; 2797 2798/* the following table is based on 880Mhz fvco */ 2799static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880)[] = { 2800 {12000, 1, 3, 22, 0x9, 0xFFFFEF}, 2801 {13000, 2, 1, 6, 0xb, 0x483483}, 2802 {14400, 3, 1, 10, 0xa, 0x1C71C7}, 2803 {15360, 4, 1, 5, 0xb, 0x755555}, 2804 {16200, 5, 1, 10, 0x5, 0x6E9E06}, 2805 {16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, 2806 {19200, 7, 1, 4, 0xb, 0x755555}, 2807 {19800, 8, 1, 11, 0x4, 0xA57EB}, 2808 {20000, 9, 1, 11, 0x4, 0x0}, 2809 {24000, 10, 3, 11, 0xa, 0x0}, 2810 {25000, 11, 5, 16, 0xb, 0x0}, 2811 {26000, 12, 1, 2, 0x10, 0xEC4EC4}, 2812 {30000, 13, 3, 8, 0xb, 0x0}, 2813 {33600, 14, 1, 2, 0xd, 0x186186}, 2814 {38400, 15, 1, 2, 0xb, 0x755555}, 2815 {40000, 16, 1, 2, 0xb, 0}, 2816 {0, 0, 0, 0, 0, 0} 2817}; 2818 2819/* indices into pmu1_xtaltab0_880[] */ 2820#define PMU1_XTALTAB0_880_12000K 0 2821#define PMU1_XTALTAB0_880_13000K 1 2822#define PMU1_XTALTAB0_880_14400K 2 2823#define PMU1_XTALTAB0_880_15360K 3 2824#define PMU1_XTALTAB0_880_16200K 4 2825#define PMU1_XTALTAB0_880_16800K 5 2826#define PMU1_XTALTAB0_880_19200K 6 2827#define PMU1_XTALTAB0_880_19800K 7 2828#define PMU1_XTALTAB0_880_20000K 8 2829#define PMU1_XTALTAB0_880_24000K 9 2830#define PMU1_XTALTAB0_880_25000K 10 2831#define PMU1_XTALTAB0_880_26000K 11 2832#define PMU1_XTALTAB0_880_30000K 12 2833#define PMU1_XTALTAB0_880_37400K 13 2834#define PMU1_XTALTAB0_880_38400K 14 2835#define PMU1_XTALTAB0_880_40000K 15 2836 2837/* the following table is based on 1760Mhz fvco */ 2838static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1760)[] = { 2839 {12000, 1, 3, 44, 0x9, 0xFFFFEF}, 2840 {13000, 2, 1, 12, 0xb, 0x483483}, 2841 {14400, 3, 1, 20, 0xa, 0x1C71C7}, 2842 {15360, 4, 1, 10, 0xb, 0x755555}, 2843 {16200, 5, 1, 20, 0x5, 0x6E9E06}, 2844 {16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, 2845 {19200, 7, 1, 18, 0x5, 0x17B425}, 2846 {19800, 8, 1, 22, 0x4, 0xA57EB}, 2847 {20000, 9, 1, 22, 0x4, 0x0}, 2848 {24000, 10, 3, 22, 0xa, 0x0}, 2849 {25000, 11, 5, 32, 0xb, 0x0}, 2850 {26000, 12, 1, 4, 0x10, 0xEC4EC4}, 2851 {30000, 13, 3, 16, 0xb, 0x0}, 2852 {38400, 14, 1, 10, 0x4, 0x955555}, 2853 {40000, 15, 1, 4, 0xb, 0}, 2854 {0, 0, 0, 0, 0, 0} 2855}; 2856 2857/* indices into pmu1_xtaltab0_1760[] */ 2858#define PMU1_XTALTAB0_1760_12000K 0 2859#define PMU1_XTALTAB0_1760_13000K 1 2860#define PMU1_XTALTAB0_1760_14400K 2 2861#define PMU1_XTALTAB0_1760_15360K 3 2862#define PMU1_XTALTAB0_1760_16200K 4 2863#define PMU1_XTALTAB0_1760_16800K 5 2864#define PMU1_XTALTAB0_1760_19200K 6 2865#define PMU1_XTALTAB0_1760_19800K 7 2866#define PMU1_XTALTAB0_1760_20000K 8 2867#define PMU1_XTALTAB0_1760_24000K 9 2868#define PMU1_XTALTAB0_1760_25000K 10 2869#define PMU1_XTALTAB0_1760_26000K 11 2870#define PMU1_XTALTAB0_1760_30000K 12 2871#define PMU1_XTALTAB0_1760_38400K 13 2872#define PMU1_XTALTAB0_1760_40000K 14 2873 2874/* the following table is based on 1440Mhz fvco */ 2875static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1440)[] = { 2876 {12000, 1, 1, 1, 0x78, 0x0 }, 2877 {13000, 2, 1, 1, 0x6E, 0xC4EC4E}, 2878 {14400, 3, 1, 1, 0x64, 0x0 }, 2879 {15360, 4, 1, 1, 0x5D, 0xC00000}, 2880 {16200, 5, 1, 1, 0x58, 0xE38E38}, 2881 {16800, 6, 1, 1, 0x55, 0xB6DB6D}, 2882 {19200, 7, 1, 1, 0x4B, 0 }, 2883 {19800, 8, 1, 1, 0x48, 0xBA2E8B}, 2884 {20000, 9, 1, 1, 0x48, 0x0 }, 2885 {25000, 10, 1, 1, 0x39, 0x999999}, 2886 {26000, 11, 1, 1, 0x37, 0x627627}, 2887 {30000, 12, 1, 1, 0x30, 0x0 }, 2888 {37400, 13, 2, 1, 0x4D, 0x15E76 }, 2889 {38400, 13, 2, 1, 0x4B, 0x0 }, 2890 {40000, 14, 2, 1, 0x48, 0x0 }, 2891 {48000, 15, 2, 1, 0x3c, 0x0 }, 2892 {0, 0, 0, 0, 0, 0} 2893}; 2894 2895/* indices into pmu1_xtaltab0_1440[] */ 2896#define PMU1_XTALTAB0_1440_12000K 0 2897#define PMU1_XTALTAB0_1440_13000K 1 2898#define PMU1_XTALTAB0_1440_14400K 2 2899#define PMU1_XTALTAB0_1440_15360K 3 2900#define PMU1_XTALTAB0_1440_16200K 4 2901#define PMU1_XTALTAB0_1440_16800K 5 2902#define PMU1_XTALTAB0_1440_19200K 6 2903#define PMU1_XTALTAB0_1440_19800K 7 2904#define PMU1_XTALTAB0_1440_20000K 8 2905#define PMU1_XTALTAB0_1440_25000K 9 2906#define PMU1_XTALTAB0_1440_26000K 10 2907#define PMU1_XTALTAB0_1440_30000K 11 2908#define PMU1_XTALTAB0_1440_37400K 12 2909#define PMU1_XTALTAB0_1440_38400K 13 2910#define PMU1_XTALTAB0_1440_40000K 14 2911#define PMU1_XTALTAB0_1440_48000K 15 2912 2913#define XTAL_FREQ_24000MHZ 24000 2914#define XTAL_FREQ_30000MHZ 30000 2915#define XTAL_FREQ_37400MHZ 37400 2916#define XTAL_FREQ_48000MHZ 48000 2917 2918/* 'xf' values corresponding to the 'xf' definition in the PMU control register */ 2919enum xtaltab0_960 { 2920 XTALTAB0_960_12000K = 1, 2921 XTALTAB0_960_13000K, 2922 XTALTAB0_960_14400K, 2923 XTALTAB0_960_15360K, 2924 XTALTAB0_960_16200K, 2925 XTALTAB0_960_16800K, 2926 XTALTAB0_960_19200K, 2927 XTALTAB0_960_19800K, 2928 XTALTAB0_960_20000K, 2929 XTALTAB0_960_24000K, 2930 XTALTAB0_960_25000K, 2931 XTALTAB0_960_26000K, 2932 XTALTAB0_960_30000K, 2933 XTALTAB0_960_33600K, 2934 XTALTAB0_960_37400K, 2935 XTALTAB0_960_38400K, 2936 XTALTAB0_960_40000K, 2937 XTALTAB0_960_48000K, 2938 XTALTAB0_960_52000K 2939}; 2940 2941/** 2942 * given an x-tal frequency, this table specifies the PLL params to use to generate a 960Mhz output 2943 * clock. This output clock feeds the clock divider network. The defines of the form 2944 * PMU1_XTALTAB0_960_* index into this array. 2945 */ 2946static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_960)[] = { 2947/* fref xf p1div p2div ndiv_int ndiv_frac */ 2948 {12000, XTALTAB0_960_12000K, 1, 1, 0x50, 0x0 }, /* array index 0 */ 2949 {13000, XTALTAB0_960_13000K, 1, 1, 0x49, 0xD89D89}, 2950 {14400, XTALTAB0_960_14400K, 1, 1, 0x42, 0xAAAAAA}, 2951 {15360, XTALTAB0_960_15360K, 1, 1, 0x3E, 0x800000}, 2952 {16200, XTALTAB0_960_16200K, 1, 1, 0x3B, 0x425ED0}, 2953 {16800, XTALTAB0_960_16800K, 1, 1, 0x39, 0x249249}, 2954 {19200, XTALTAB0_960_19200K, 1, 1, 0x32, 0x0 }, 2955 {19800, XTALTAB0_960_19800K, 1, 1, 0x30, 0x7C1F07}, 2956 {20000, XTALTAB0_960_20000K, 1, 1, 0x30, 0x0 }, 2957 {24000, XTALTAB0_960_24000K, 1, 1, 0x28, 0x0 }, 2958 {25000, XTALTAB0_960_25000K, 1, 1, 0x26, 0x666666}, /* array index 10 */ 2959 {26000, XTALTAB0_960_26000K, 1, 1, 0x24, 0xEC4EC4}, 2960 {30000, XTALTAB0_960_30000K, 1, 1, 0x20, 0x0 }, 2961 {33600, XTALTAB0_960_33600K, 1, 1, 0x1C, 0x924924}, 2962 {37400, XTALTAB0_960_37400K, 2, 1, 0x33, 0x563EF9}, 2963 {38400, XTALTAB0_960_38400K, 2, 1, 0x32, 0x0 }, 2964 {40000, XTALTAB0_960_40000K, 2, 1, 0x30, 0x0 }, 2965 {48000, XTALTAB0_960_48000K, 2, 1, 0x28, 0x0 }, 2966 {52000, XTALTAB0_960_52000K, 2, 1, 0x24, 0xEC4EC4}, /* array index 18 */ 2967 {0, 0, 0, 0, 0, 0 } 2968}; 2969 2970/* Indices into array pmu1_xtaltab0_960[]. Keep array and these defines synchronized. */ 2971#define PMU1_XTALTAB0_960_12000K 0 2972#define PMU1_XTALTAB0_960_13000K 1 2973#define PMU1_XTALTAB0_960_14400K 2 2974#define PMU1_XTALTAB0_960_15360K 3 2975#define PMU1_XTALTAB0_960_16200K 4 2976#define PMU1_XTALTAB0_960_16800K 5 2977#define PMU1_XTALTAB0_960_19200K 6 2978#define PMU1_XTALTAB0_960_19800K 7 2979#define PMU1_XTALTAB0_960_20000K 8 2980#define PMU1_XTALTAB0_960_24000K 9 2981#define PMU1_XTALTAB0_960_25000K 10 2982#define PMU1_XTALTAB0_960_26000K 11 2983#define PMU1_XTALTAB0_960_30000K 12 2984#define PMU1_XTALTAB0_960_33600K 13 2985#define PMU1_XTALTAB0_960_37400K 14 2986#define PMU1_XTALTAB0_960_38400K 15 2987#define PMU1_XTALTAB0_960_40000K 16 2988#define PMU1_XTALTAB0_960_48000K 17 2989#define PMU1_XTALTAB0_960_52000K 18 2990 2991#define PMU15_XTALTAB0_12000K 0 2992#define PMU15_XTALTAB0_20000K 1 2993#define PMU15_XTALTAB0_26000K 2 2994#define PMU15_XTALTAB0_37400K 3 2995#define PMU15_XTALTAB0_52000K 4 2996#define PMU15_XTALTAB0_END 5 2997 2998/* For having the pllcontrol data (info) 2999 * The table with the values of the registers will have one - one mapping. 3000 */ 3001typedef struct { 3002 uint16 clock; /* x-tal frequency in [KHz] */ 3003 uint8 mode; /* spur mode */ 3004 uint8 xf; /* corresponds with xf bitfield in PMU control register */ 3005} pllctrl_data_t; 3006 3007/* ***************************** tables for 4335a0 *********************** */ 3008 3009#ifdef BCM_BOOTLOADER 3010/** 3011 * PLL control register table giving info about the xtal supported for 4335. 3012 * There should be a one to one mapping between pmu1_pllctrl_tab_4335_960mhz[] and this table. 3013 */ 3014static const pllctrl_data_t pmu1_xtaltab0_4335[] = { 3015 {12000, 0, XTALTAB0_960_12000K}, 3016 {13000, 0, XTALTAB0_960_13000K}, 3017 {14400, 0, XTALTAB0_960_14400K}, 3018 {15360, 0, XTALTAB0_960_15360K}, 3019 {16200, 0, XTALTAB0_960_16200K}, 3020 {16800, 0, XTALTAB0_960_16800K}, 3021 {19200, 0, XTALTAB0_960_19200K}, 3022 {19800, 0, XTALTAB0_960_19800K}, 3023 {20000, 0, XTALTAB0_960_20000K}, 3024 {24000, 0, XTALTAB0_960_24000K}, 3025 {25000, 0, XTALTAB0_960_25000K}, 3026 {26000, 0, XTALTAB0_960_26000K}, 3027 {30000, 0, XTALTAB0_960_30000K}, 3028 {33600, 0, XTALTAB0_960_33600K}, 3029 {37400, 0, XTALTAB0_960_37400K}, 3030 {38400, 0, XTALTAB0_960_38400K}, 3031 {40000, 0, XTALTAB0_960_40000K}, 3032 {48000, 0, XTALTAB0_960_48000K}, 3033 {52000, 0, XTALTAB0_960_52000K}, 3034}; 3035 3036/** 3037 * PLL control register values(all registers) for the xtal supported for 4335. 3038 * There should be a one to one mapping between pmu1_xtaltab0_4335[] and this table. 3039 */ 3040static const uint32 pmu1_pllctrl_tab_4335_960mhz[] = { 3041/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 */ 3042 0x50800000, 0x0C080803, 0x28010814, 0x61000000, 0x02600005, 0x0004FFFD, /* 12000 */ 3043 0x50800000, 0x0C080803, 0x24B10814, 0x40D89D89, 0x02600005, 0x00049D87, /* 13000 */ 3044 0x50800000, 0x0C080803, 0x21310814, 0x40AAAAAA, 0x02600005, 0x00042AA8, /* 14400 */ 3045 0x50800000, 0x0C080803, 0x1F310814, 0x40800000, 0x02600005, 0x0003E7FE, /* 15360 */ 3046 0x50800000, 0x0C080803, 0x1DB10814, 0x20425ED0, 0x02600005, 0x0003B424, /* 16200 */ 3047 0x50800000, 0x0C080803, 0x1CB10814, 0x20249249, 0x02600005, 0x00039247, /* 16800 */ 3048 0x50800000, 0x0C080803, 0x19010814, 0x01000000, 0x02600005, 0x00031FFE, /* 19200 */ 3049 0x50800000, 0x0C080803, 0x18310814, 0x007C1F07, 0x02600005, 0x000307C0, /* 19800 */ 3050 0x50800000, 0x0C080803, 0x18010814, 0x01000000, 0x02600005, 0x0002FFFE, /* 20000 */ 3051 0x50800000, 0x0C080803, 0x14010814, 0xC1000000, 0x02600004, 0x00027FFE, /* 24000 */ 3052 0x50800000, 0x0C080803, 0x13310814, 0xC0666666, 0x02600004, 0x00026665, /* 25000 */ 3053 0x50800000, 0x0C080803, 0x12310814, 0xC0EC4EC4, 0x02600004, 0x00024EC4, /* 26000 */ 3054 0x50800000, 0x0C080803, 0x10010814, 0xA1000000, 0x02600004, 0x0001FFFF, /* 30000 */ 3055 0x50800000, 0x0C080803, 0x0E310814, 0xA0924924, 0x02600004, 0x0001C923, /* 33600 */ 3056 0x50800000, 0x0C080803, 0x0CB10814, 0x80AB1F7C, 0x02600004, 0x00019AB1, /* 37400 */ 3057 0x50800000, 0x0C080803, 0x0C810814, 0x81000000, 0x02600004, 0x00018FFF, /* 38400 */ 3058 0x50800000, 0x0C080803, 0x0C010814, 0x81000000, 0x02600004, 0x00017FFF, /* 40000 */ 3059 0x50800000, 0x0C080803, 0x0A010814, 0x61000000, 0x02600004, 0x00013FFF, /* 48000 */ 3060 0x50800000, 0x0C080803, 0x09310814, 0x60762762, 0x02600004, 0x00012762, /* 52000 */ 3061}; 3062 3063#else /* BCM_BOOTLOADER */ 3064/** 3065 * PLL control register table giving info about the xtal supported for 4335. 3066 * There should be a one to one mapping between pmu1_pllctrl_tab_4335_968mhz[] and this table. 3067 */ 3068static const pllctrl_data_t pmu1_xtaltab0_4335_drv[] = { 3069 {37400, 0, XTALTAB0_960_37400K}, 3070 {40000, 0, XTALTAB0_960_40000K}, 3071}; 3072 3073 3074/** 3075 * PLL control register values(all registers) for the xtal supported for 4335. 3076 * There should be a one to one mapping between pmu1_xtaltab0_4335_drv[] and this table. 3077 */ 3078/* 3079 * This table corresponds to spur mode 8. This bbpll settings will be used for WLBGA Bx 3080 * as well as Cx 3081 */ 3082static const uint32 pmu1_pllctrl_tab_4335_968mhz[] = { 3083/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 */ 3084 0x50800000, 0x0A060803, 0x0CB10806, 0x80E1E1E2, 0x02600004, 0x00019AB1, /* 37400 KHz */ 3085 0x50800000, 0x0A060803, 0x0C310806, 0x80333333, 0x02600004, 0x00017FFF, /* 40000 KHz */ 3086}; 3087 3088/* This table corresponds to spur mode 2. This bbpll settings will be used for WLCSP B0 */ 3089static const uint32 pmu1_pllctrl_tab_4335_961mhz[] = { 3090/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 */ 3091 0x50800000, 0x0A060803, 0x0CB10806, 0x80B1F7C9, 0x02600004, 0x00019AB1, /* 37400 KHz */ 3092 0x50800000, 0x0A060803, 0x0C310806, 0x80066666, 0x02600004, 0x00017FFF, /* 40000 KHz */ 3093}; 3094 3095/* This table corresponds to spur mode 0. This bbpll settings will be used for WLCSP C0 */ 3096static const uint32 pmu1_pllctrl_tab_4335_963mhz[] = { 3097/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 */ 3098 0x50800000, 0x0A060803, 0x0CB10806, 0x80BFA863, 0x02600004, 0x00019AB1, /* 37400 KHz */ 3099 0x50800000, 0x0A060803, 0x0C310806, 0x80133333, 0x02600004, 0x00017FFF, /* 40000 KHz */ 3100}; 3101 3102#endif /* BCM_BOOTLOADER */ 3103 3104/* ************************ tables for 4335a0 END *********************** */ 3105 3106/* ***************************** tables for 43242a0 *********************** */ 3107 3108/** 3109 * PLL control register table giving info about the xtal supported for 43242 3110 * There should be a one to one mapping between pmu1_pllctrl_tab_43242A0[] 3111 * and pmu1_pllctrl_tab_43242A1[] and this table. 3112 */ 3113static const pllctrl_data_t BCMATTACHDATA(pmu1_xtaltab0_43242)[] = { 3114 {37400, 0, XTALTAB0_960_37400K}, 3115}; 3116 3117/* ************************ tables for 4324a02 END *********************** */ 3118 3119/* ***************************** tables for 4350a0 *********************** */ 3120 3121#define XTAL_DEFAULT_4350 37400 3122/** 3123 * PLL control register table giving info about the xtal supported for 4350 3124 * There should be a one to one mapping between pmu1_pllctrl_tab_4350_963mhz[] and this table. 3125 */ 3126static const pllctrl_data_t pmu1_xtaltab0_4350[] = { 3127/* clock mode xf */ 3128 {37400, 0, XTALTAB0_960_37400K}, 3129 {40000, 0, XTALTAB0_960_40000K}, 3130}; 3131 3132/** 3133 * PLL control register table giving info about the xtal supported for 4335. 3134 * There should be a one to one mapping between pmu1_pllctrl_tab_4335_963mhz[] and this table. 3135 */ 3136static const uint32 pmu1_pllctrl_tab_4350_963mhz[] = { 3137/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 PLL6 */ 3138 0x50800000, 0x18060603, 0x0cb10814, 0x80bfaa00, 0x02600004, 0x00019AB1, 0x04a6c181, 3139 0x50800000, 0x18060603, 0x0C310814, 0x00133333, 0x02600004, 0x00017FFF, 0x04a6c181 3140}; 3141/* ************************ tables for 4350a0 END *********************** */ 3142 3143/* PLL control register values(all registers) for the xtal supported for 43242. 3144 * There should be a one to one mapping for "pllctrl_data_t" and the table below. 3145 * only support 37.4M 3146 */ 3147static const uint32 BCMATTACHDATA(pmu1_pllctrl_tab_43242A0)[] = { 3148/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 */ 3149 0xA7400040, 0x10080A06, 0x0CB11408, 0x80AB1F7C, 0x02600004, 0x00A6C4D3, /* 37400 */ 3150}; 3151 3152static const uint32 BCMATTACHDATA(pmu1_pllctrl_tab_43242A1)[] = { 3153/* PLL 0 PLL 1 PLL 2 PLL 3 PLL 4 PLL 5 */ 3154 0xA7400040, 0x10080A06, 0x0CB11408, 0x80AB1F7C, 0x02600004, 0x00A6C191, /* 37400 */ 3155}; 3156 3157/* 4334/4314 ADFLL freq target params */ 3158typedef struct { 3159 uint16 fref; /* x-tal frequency in [hz] */ 3160 uint8 xf; /* x-tal index as given by PMU programmers guide */ 3161 uint32 freq_tgt; /* freq_target: N_divide_ratio bitfield in DFLL */ 3162} pmu2_xtaltab0_t; 3163 3164/** 3165 * If a DFLL clock of 480Mhz is desired, use this table to determine xf and freq_tgt for 3166 * a given x-tal frequency. 3167 */ 3168static const pmu2_xtaltab0_t BCMINITDATA(pmu2_xtaltab0_adfll_480)[] = { 3169 {12000, 1, 0x4FFFC}, 3170 {20000, 9, 0x2FFFD}, 3171 {26000, 11, 0x24EC3}, 3172 {37400, 13, 0x19AB1}, 3173 {52000, 17, 0x12761}, 3174 {0, 0, 0}, 3175}; 3176 3177static const pmu2_xtaltab0_t BCMINITDATA(pmu2_xtaltab0_adfll_492)[] = { 3178 {12000, 1, 0x51FFC}, 3179 {20000, 9, 0x31330}, 3180 {26000, 11, 0x25D88}, 3181 {37400, 13, 0x1A4F5}, 3182 {52000, 17, 0x12EC4}, 3183 {0, 0, 0} 3184}; 3185 3186static const pmu2_xtaltab0_t BCMINITDATA(pmu2_xtaltab0_adfll_485)[] = { 3187 {12000, 1, 0x50D52}, 3188 {20000, 9, 0x307FE}, 3189 {26000, 11, 0x254EA}, 3190 {37400, 13, 0x19EF8}, 3191 {52000, 17, 0x12A75}, 3192 {0, 0, 0} 3193}; 3194 3195/** returns xtal table for each chip */ 3196static const pmu1_xtaltab0_t * 3197BCMINITFN(si_pmu1_xtaltab0)(si_t *sih) 3198{ 3199 switch (CHIPID(sih->chip)) { 3200 case BCM4325_CHIP_ID: 3201 return pmu1_xtaltab0_880; 3202 case BCM4329_CHIP_ID: 3203 return pmu1_xtaltab0_880_4329; 3204 case BCM4315_CHIP_ID: 3205 return pmu1_xtaltab0_1760; 3206 case BCM4319_CHIP_ID: 3207 return pmu1_xtaltab0_1440; 3208 case BCM4336_CHIP_ID: 3209 case BCM43362_CHIP_ID: 3210 case BCM43239_CHIP_ID: 3211 case BCM4324_CHIP_ID: 3212 case BCM43242_CHIP_ID: 3213 case BCM43243_CHIP_ID: 3214 case BCM4335_CHIP_ID: 3215 case BCM4360_CHIP_ID: 3216 case BCM43460_CHIP_ID: 3217 case BCM43526_CHIP_ID: 3218 case BCM4352_CHIP_ID: 3219 case BCM4350_CHIP_ID: 3220 return pmu1_xtaltab0_960; 3221 case BCM4330_CHIP_ID: 3222 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 3223 return pmu1_xtaltab0_960; 3224 else 3225 return pmu1_xtaltab0_1440; 3226 default: 3227 PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 3228 break; 3229 } 3230 ASSERT(0); 3231 return NULL; 3232} /* si_pmu1_xtaltab0 */ 3233 3234/** returns chip specific PLL settings for default xtal frequency and VCO output frequency */ 3235static const pmu1_xtaltab0_t * 3236BCMINITFN(si_pmu1_xtaldef0)(si_t *sih) 3237{ 3238 3239 switch (CHIPID(sih->chip)) { 3240 case BCM4325_CHIP_ID: 3241 /* Default to 26000Khz */ 3242 return &pmu1_xtaltab0_880[PMU1_XTALTAB0_880_26000K]; 3243 case BCM4329_CHIP_ID: 3244 /* Default to 38400Khz */ 3245 return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]; 3246 case BCM4315_CHIP_ID: 3247#ifdef BCMUSBDEV 3248 /* Default to 30000Khz */ 3249 return &pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_30000K]; 3250#else 3251 /* Default to 26000Khz */ 3252 return &pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_26000K]; 3253#endif 3254 case BCM4319_CHIP_ID: 3255 /* Default to 30000Khz */ 3256 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K]; 3257 case BCM4336_CHIP_ID: 3258 case BCM43362_CHIP_ID: 3259 case BCM43239_CHIP_ID: 3260 /* Default to 26000Khz */ 3261 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K]; 3262 case BCM4324_CHIP_ID: 3263 case BCM43242_CHIP_ID: 3264 case BCM43243_CHIP_ID: 3265 case BCM4335_CHIP_ID: 3266 case BCM4360_CHIP_ID: 3267 case BCM43460_CHIP_ID: 3268 case BCM43526_CHIP_ID: 3269 case BCM4352_CHIP_ID: 3270 case BCM4350_CHIP_ID: 3271 /* Default to 37400Khz */ 3272 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]; 3273 3274 case BCM4330_CHIP_ID: 3275 /* Default to 37400Khz */ 3276 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 3277 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]; 3278 else 3279 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]; 3280 default: 3281 PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 3282 break; 3283 } 3284 ASSERT(0); 3285 return NULL; 3286} /* si_pmu1_xtaldef0 */ 3287 3288/** returns chip specific default pll fvco frequency */ 3289static uint32 3290BCMINITFN(si_pmu1_pllfvco0)(si_t *sih) 3291{ 3292 osl_t *osh; 3293 osh = si_osh(sih); 3294 3295 switch (CHIPID(sih->chip)) { 3296 case BCM4325_CHIP_ID: 3297 return FVCO_880; 3298 case BCM4329_CHIP_ID: 3299 return FVCO_880; 3300 case BCM4315_CHIP_ID: 3301 return FVCO_1760; 3302 case BCM4319_CHIP_ID: 3303 return FVCO_1440; 3304 case BCM4336_CHIP_ID: 3305 case BCM43362_CHIP_ID: 3306 case BCM43239_CHIP_ID: 3307 case BCM4324_CHIP_ID: 3308 case BCM43242_CHIP_ID: 3309 case BCM43243_CHIP_ID: 3310 case BCM4360_CHIP_ID: 3311 case BCM43460_CHIP_ID: 3312 case BCM43526_CHIP_ID: 3313 case BCM4352_CHIP_ID: 3314 return FVCO_960; 3315 3316 case BCM4350_CHIP_ID: 3317 return FVCO_963; 3318 case BCM4335_CHIP_ID: 3319 return (si_pmu_cal_fvco(sih, osh)); 3320 case BCM4330_CHIP_ID: 3321 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 3322 return FVCO_960; 3323 else 3324 return FVCO_1440; 3325 default: 3326 PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 3327 break; 3328 } 3329 ASSERT(0); 3330 return 0; 3331} /* si_pmu1_pllfvco0 */ 3332 3333/** query alp/xtal clock frequency */ 3334static uint32 3335BCMINITFN(si_pmu1_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 3336{ 3337 const pmu1_xtaltab0_t *xt; 3338 uint32 xf; 3339 3340 /* Find the frequency in the table */ 3341 xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 3342 PCTL_XTALFREQ_SHIFT; 3343 for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++) 3344 if (xt->xf == xf) 3345 break; 3346 /* Could not find it so assign a default value */ 3347 if (xt == NULL || xt->fref == 0) 3348 xt = si_pmu1_xtaldef0(sih); 3349 ASSERT(xt != NULL && xt->fref != 0); 3350 3351 return xt->fref * 1000; 3352} 3353 3354/** 3355 * Before the PLL is switched off, the HT clocks need to be deactivated, and reactivated 3356 * when the PLL is switched on again. 3357 * This function returns the chip specific HT clock resources (HT and MACPHY clocks). 3358 */ 3359static uint32 3360si_pmu_htclk_mask(si_t *sih) 3361{ 3362 uint32 ht_req = 0; 3363 3364 switch (CHIPID(sih->chip)) 3365 { 3366 case BCM43239_CHIP_ID: 3367 ht_req = PMURES_BIT(RES43239_HT_AVAIL) | 3368 PMURES_BIT(RES43239_MACPHY_CLKAVAIL); 3369 break; 3370 case BCM4324_CHIP_ID: 3371 case BCM43242_CHIP_ID: 3372 case BCM43243_CHIP_ID: 3373 ht_req = PMURES_BIT(RES4324_HT_AVAIL) | 3374 PMURES_BIT(RES4324_MACPHY_CLKAVAIL); 3375 break; 3376 case BCM4330_CHIP_ID: 3377 ht_req = PMURES_BIT(RES4330_BBPLL_PWRSW_PU) | 3378 PMURES_BIT(RES4330_MACPHY_CLKAVAIL) | PMURES_BIT(RES4330_HT_AVAIL); 3379 break; 3380 case BCM43362_CHIP_ID: 3381 case BCM4336_CHIP_ID: 3382 ht_req = PMURES_BIT(RES4336_BBPLL_PWRSW_PU) | 3383 PMURES_BIT(RES4336_MACPHY_CLKAVAIL) | PMURES_BIT(RES4336_HT_AVAIL); 3384 break; 3385 case BCM4334_CHIP_ID: 3386 ht_req = PMURES_BIT(RES4334_HT_AVAIL) | 3387 PMURES_BIT(RES4334_MACPHY_CLK_AVAIL); 3388 break; 3389 case BCM4335_CHIP_ID: 3390 ht_req = PMURES_BIT(RES4335_HT_AVAIL) | 3391 PMURES_BIT(RES4335_MACPHY_CLKAVAIL) | 3392 PMURES_BIT(RES4335_HT_START); 3393 break; 3394 case BCM4350_CHIP_ID: 3395 ht_req = PMURES_BIT(RES4350_HT_AVAIL) | 3396 PMURES_BIT(RES4350_MACPHY_CLKAVAIL) | 3397 PMURES_BIT(RES4350_HT_START); 3398 break; 3399 case BCM43143_CHIP_ID: 3400 ht_req = PMURES_BIT(RES43143_HT_AVAIL) | 3401 PMURES_BIT(RES43143_MACPHY_CLK_AVAIL); 3402 break; 3403 default: 3404 ASSERT(0); 3405 break; 3406 } 3407 return ht_req; 3408} /* si_pmu_htclk_mask */ 3409 3410void 3411si_pmu_minresmask_htavail_set(si_t *sih, osl_t *osh, bool set_clear) 3412{ 3413 chipcregs_t *cc; 3414 uint origidx; 3415 /* Remember original core before switch to chipc */ 3416 origidx = si_coreidx(sih); 3417 cc = si_setcoreidx(sih, SI_CC_IDX); 3418 ASSERT(cc != NULL); 3419 3420 if (!set_clear) { 3421 switch (CHIPID(sih->chip)) { 3422 case BCM4313_CHIP_ID: 3423 if ((cc->min_res_mask) & (PMURES_BIT(RES4313_HT_AVAIL_RSRC))) 3424 AND_REG(osh, &cc->min_res_mask, 3425 ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 3426 break; 3427 default: 3428 break; 3429 } 3430 } 3431 3432 /* Return to original core */ 3433 si_setcoreidx(sih, origidx); 3434} 3435 3436uint 3437si_pll_minresmask_reset(si_t *sih, osl_t *osh) 3438{ 3439 chipcregs_t *cc; 3440 uint origidx; 3441 uint err = BCME_OK; 3442 3443 /* Remember original core before switch to chipc */ 3444 origidx = si_coreidx(sih); 3445 cc = si_setcoreidx(sih, SI_CC_IDX); 3446 ASSERT(cc != NULL); 3447 3448 switch (CHIPID(sih->chip)) { 3449 case BCM4313_CHIP_ID: 3450 /* write to min_res_mask 0x200d : clear min_rsrc_mask */ 3451 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 3452 OSL_DELAY(100); 3453 /* write to max_res_mask 0xBFFF: clear max_rsrc_mask */ 3454 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 3455 OSL_DELAY(100); 3456 /* write to max_res_mask 0xFFFF :set max_rsrc_mask */ 3457 OR_REG(osh, &cc->max_res_mask, (PMURES_BIT(RES4313_HT_AVAIL_RSRC))); 3458 break; 3459 default: 3460 PMU_ERROR(("%s: PLL reset not supported\n", __FUNCTION__)); 3461 err = BCME_UNSUPPORTED; 3462 break; 3463 } 3464 /* Return to original core */ 3465 si_setcoreidx(sih, origidx); 3466 return err; 3467} 3468 3469uint32 3470BCMATTACHFN(si_pmu_def_alp_clock)(si_t *sih, osl_t *osh) 3471{ 3472 uint32 clock = ALP_CLOCK; 3473 3474 switch (CHIPID(sih->chip)) { 3475 case BCM4324_CHIP_ID: 3476 case BCM43242_CHIP_ID: 3477 case BCM43243_CHIP_ID: 3478 case BCM4335_CHIP_ID: 3479 case BCM4350_CHIP_ID: 3480 clock = 37400*1000; 3481 break; 3482 } 3483 return clock; 3484} 3485 3486/** 3487 * Given x-tal frequency and spur mode, writes the set of PLL registers with the entries in caller 3488 * provided array 'pllctrlreg_val'. Returns bitfield 'xf', corresponding to the 'xf' bitfield 3489 * in the PMU control register. 3490 * 3491 * 'xtal': xtal frequency in [KHz] 3492 * 'pllctrlreg_val' : set of PLL register values for this particular x-tal frequency 3493 * 3494 * Note: if cc is NULL, this function returns xf, without programming PLL registers. 3495 * This function is only called for pmu1_ type chips, perhaps we should rename it. 3496 */ 3497static uint8 3498BCMATTACHFN(si_pmu_pllctrlreg_update)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal, 3499 uint8 spur_mode, const pllctrl_data_t *pllctrlreg_update, uint32 array_size, 3500 const uint32 *pllctrlreg_val) 3501{ 3502 uint8 indx, reg_offset, xf = 0; 3503 uint8 pll_ctrlcnt = 0; 3504 3505 ASSERT(pllctrlreg_update); 3506 3507 if (sih->pmurev >= 5) { 3508 pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT; 3509 } else { 3510 pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT; 3511 } 3512 3513 /* Program the PLL control register if the xtal value matches with the table entry value */ 3514 for (indx = 0; indx < array_size; indx++) { 3515 /* If the entry does not match the xtal and spur_mode just continue the loop */ 3516 if (!((pllctrlreg_update[indx].clock == (uint16)xtal) && 3517 (pllctrlreg_update[indx].mode == spur_mode))) 3518 continue; 3519 /* 3520 * Don't program the PLL registers if register base is NULL. 3521 * If NULL just return the xref. 3522 */ 3523 if (cc) { 3524 for (reg_offset = 0; reg_offset < pll_ctrlcnt; reg_offset++) { 3525 W_REG(osh, &cc->pllcontrol_addr, reg_offset); 3526 W_REG(osh, &cc->pllcontrol_data, 3527 pllctrlreg_val[indx*pll_ctrlcnt + reg_offset]); 3528 } 3529 } 3530 xf = pllctrlreg_update[indx].xf; 3531 break; 3532 } 3533 return xf; 3534} /* si_pmu_pllctrlreg_update */ 3535 3536 3537/** 3538 * Chip-specific overrides to PLLCONTROL registers during init. If certain conditions (dependent on 3539 * x-tal frequency and current ALP frequency) are met, an update of the PLL is required. 3540 * 3541 * This takes less precedence over OTP PLLCONTROL overrides. 3542 * If update_required=FALSE, it returns TRUE if a update is about to occur. 3543 * No write happens. 3544 * 3545 * This function is only called for pmu1_ type chips, perhaps we should rename it. 3546 */ 3547bool 3548BCMATTACHFN(si_pmu_update_pllcontrol)(si_t *sih, osl_t *osh, uint32 xtal, bool update_required) 3549{ 3550 chipcregs_t *cc; 3551 uint origidx; 3552 bool write_en = FALSE; 3553 uint8 xf = 0; 3554 uint32 tmp; 3555 uint32 xtalfreq = 0; 3556 const pllctrl_data_t *pllctrlreg_update = NULL; 3557 uint32 array_size = 0; 3558 /* points at a set of PLL register values to write for a given x-tal frequency: */ 3559 const uint32 *pllctrlreg_val = NULL; 3560 3561 /* If there is OTP or NVRAM entry for xtalfreq, program the 3562 * PLL control register even if it is default xtal. 3563 */ 3564 xtalfreq = getintvar(NULL, "xtalfreq"); 3565 /* CASE1 */ 3566 if (xtalfreq) { 3567 write_en = TRUE; 3568 xtal = xtalfreq; 3569 } else { 3570 /* There is NO OTP value */ 3571 if (xtal) { 3572 /* CASE2: If the xtal value was calculated, program the PLL control 3573 * registers only if it is not default xtal value. 3574 */ 3575 if (xtal != (si_pmu_def_alp_clock(sih, osh)/1000)) 3576 write_en = TRUE; 3577 } else { 3578 /* CASE3: If the xtal obtained is "0", ie., clock is not measured, then 3579 * leave the PLL control register as it is but program the xf in 3580 * pmucontrol register with the default xtal value. 3581 */ 3582 xtal = si_pmu_def_alp_clock(sih, osh)/1000; 3583 } 3584 } 3585 3586 switch (CHIPID(sih->chip)) { 3587 case BCM43239_CHIP_ID: 3588#ifndef BCM_BOOTLOADER 3589 write_en = TRUE; 3590#endif 3591 break; 3592 3593 case BCM4335_CHIP_ID: 3594#ifdef BCM_BOOTLOADER 3595 pllctrlreg_update = pmu1_xtaltab0_4335; 3596 array_size = ARRAYSIZE(pmu1_xtaltab0_4335); 3597 pllctrlreg_val = pmu1_pllctrl_tab_4335_960mhz; 3598#else /* BCM_BOOTLOADER */ 3599 pllctrlreg_update = pmu1_xtaltab0_4335_drv; 3600 array_size = ARRAYSIZE(pmu1_xtaltab0_4335_drv); 3601 if (sih->chippkg == BCM4335_WLBGA_PKG_ID) { 3602 pllctrlreg_val = pmu1_pllctrl_tab_4335_968mhz; 3603 } else { 3604 if (CHIPREV(sih->chiprev) <= 1) { 3605 /* for 4335 Ax/Bx Chips */ 3606 pllctrlreg_val = pmu1_pllctrl_tab_4335_961mhz; 3607 } else if (CHIPREV(sih->chiprev) == 2) { 3608 /* for 4335 Cx chips */ 3609 pllctrlreg_val = pmu1_pllctrl_tab_4335_968mhz; 3610 } 3611 } 3612#endif /* BCM_BOOTLOADER */ 3613 3614#ifndef BCM_BOOTLOADER 3615 /* If PMU1_PLL0_PC2_MxxDIV_MASKxx have to change, 3616 * then set write_en to true. 3617 */ 3618 write_en = TRUE; 3619#endif 3620 break; 3621 3622 case BCM4350_CHIP_ID: 3623 pllctrlreg_update = pmu1_xtaltab0_4350; 3624 array_size = ARRAYSIZE(pmu1_xtaltab0_4350); 3625 pllctrlreg_val = pmu1_pllctrl_tab_4350_963mhz; 3626 3627 /* If PMU1_PLL0_PC2_MxxDIV_MASKxx have to change, 3628 * then set write_en to true. 3629 */ 3630#ifdef BCMUSB_NODISCONNECT 3631 write_en = FALSE; 3632#else 3633 write_en = TRUE; 3634#endif 3635#ifdef BCM_BOOTLOADER 3636 /* Bootloader need to change pll if it is not default 37.4M */ 3637 if (xtal == XTAL_DEFAULT_4350) 3638 write_en = FALSE; 3639#endif /* BCM_BOOTLOADER */ 3640 break; 3641 3642 case BCM43242_CHIP_ID: 3643 case BCM43243_CHIP_ID: 3644 pllctrlreg_update = pmu1_xtaltab0_43242; 3645 array_size = ARRAYSIZE(pmu1_xtaltab0_43242); 3646 if (CHIPREV(sih->chiprev) == 0) { 3647 pllctrlreg_val = pmu1_pllctrl_tab_43242A0; 3648 } else { 3649 pllctrlreg_val = pmu1_pllctrl_tab_43242A1; 3650 } 3651#ifndef BCM_BOOTLOADER 3652 write_en = TRUE; 3653#endif 3654 break; 3655 3656 /* FOR ANY FURTHER CHIPS, add a case here, define tables similar to 3657 * pmu1_xtaltab0_4324 & pmu1_pllctrl_tab_4324 based on resources 3658 * and assign. For loop below will take care of programming. 3659 */ 3660 default: 3661 /* write_en is FALSE in this case. So returns from the function */ 3662 write_en = FALSE; 3663 break; 3664 } 3665 3666 /* ** PROGRAM THE REGISTERS BASED ON ABOVE CONDITIONS */ 3667 /* Remember original core before switch to chipc */ 3668 origidx = si_coreidx(sih); 3669 cc = si_setcoreidx(sih, SI_CC_IDX); 3670 ASSERT(cc != NULL); 3671 3672 /* Check if the table has PLL control register values for the requested 3673 * xtal. NOTE THAT, THIS IS not DONE FOR 43239, 3674 * AS IT HAS ONLY ONE XTAL SUPPORT. 3675 */ 3676 if (!update_required && pllctrlreg_update) { 3677 /* Here the chipcommon register base is passed as NULL, so that we just get 3678 * the xf for the xtal being programmed but don't program the registers now 3679 * as the PLL is not yet turned OFF. 3680 */ 3681 xf = si_pmu_pllctrlreg_update(sih, osh, NULL, xtal, 0, pllctrlreg_update, 3682 array_size, pllctrlreg_val); 3683 3684 /* Program the PLL based on the xtal value. */ 3685 if (xf != 0) { 3686 /* Write XtalFreq. Set the divisor also. */ 3687 tmp = R_REG(osh, &cc->pmucontrol) & 3688 ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); 3689 tmp |= (((((xtal + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & 3690 PCTL_ILP_DIV_MASK) | 3691 ((xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); 3692 W_REG(osh, &cc->pmucontrol, tmp); 3693 } else { 3694 write_en = FALSE; 3695 printf("Invalid/Unsupported xtal value %d", xtal); 3696 } 3697 } 3698 3699 /* If its a check sequence or if there is nothing to write, return here */ 3700 if ((update_required == FALSE) || (write_en == FALSE)) { 3701 goto exit; 3702 } 3703 3704 /* Update the PLL control register based on the xtal used. */ 3705 if (pllctrlreg_val) { 3706 si_pmu_pllctrlreg_update(sih, osh, cc, xtal, 0, pllctrlreg_update, array_size, 3707 pllctrlreg_val); 3708 } 3709 3710 /* Chip specific changes to PLL Control registers is done here. */ 3711 switch (CHIPID(sih->chip)) { 3712 case BCM43239_CHIP_ID: 3713#ifndef BCM_BOOTLOADER 3714 /* 43239: Change backplane and dot11mac clock to 120Mhz */ 3715 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, 3716 (PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK), 3717 ((8 << PMU1_PLL0_PC2_M5DIV_SHIFT) | (8 << PMU1_PLL0_PC2_M6DIV_SHIFT))); 3718#endif 3719 break; 3720 case BCM4324_CHIP_ID: 3721#ifndef BCM_BOOTLOADER 3722 /* Change backplane clock (ARM input) to 137Mhz */ 3723 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, PMU1_PLL0_PC1_M2DIV_MASK, 3724 (7 << PMU1_PLL0_PC1_M2DIV_SHIFT)); 3725#endif 3726 break; 3727 case BCM43242_CHIP_ID: 3728 case BCM43243_CHIP_ID: 3729#ifndef BCM_BOOTLOADER 3730 /* Change backplane clock (ARM input) to 137Mhz */ 3731 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, PMU1_PLL0_PC1_M2DIV_MASK, 3732 (7 << PMU1_PLL0_PC1_M2DIV_SHIFT)); 3733#endif 3734 break; 3735 default: 3736 break; 3737 } 3738 3739exit: 3740 /* Return to original core */ 3741 si_setcoreidx(sih, origidx); 3742 3743 return write_en; 3744} /* si_pmu_update_pllcontrol */ 3745 3746int si_pmu_wait_for_steady_state(osl_t *osh, chipcregs_t *cc); 3747 3748uint32 3749si_pmu_get_pmutime_diff(osl_t *osh, chipcregs_t *cc, uint32 *prev); 3750 3751bool 3752si_pmu_wait_for_res_pending(osl_t *osh, chipcregs_t *cc, uint usec, 3753 bool cond, uint32 *elapsed_time); 3754 3755uint32 3756si_pmu_get_pmutimer(osl_t *osh, chipcregs_t *cc); 3757 3758/* PMU timer ticks once in 32uS */ 3759#define PMU_US_STEPS (32) 3760 3761uint32 3762si_pmu_get_pmutimer(osl_t *osh, chipcregs_t *cc) 3763{ 3764 uint32 start; 3765 start = R_REG(osh, &cc->pmutimer); 3766 if (start != R_REG(osh, &cc->pmutimer)) 3767 start = R_REG(osh, &cc->pmutimer); 3768 return (start); 3769} 3770 3771/* returns 3772 * a) diff between a 'prev' value of pmu timer and current value 3773 * b) the current pmutime value in 'prev' 3774 * So, 'prev' is an IO parameter. 3775 */ 3776uint32 3777si_pmu_get_pmutime_diff(osl_t *osh, chipcregs_t *cc, uint32 *prev) 3778{ 3779 uint32 pmutime_diff = 0, pmutime_val = 0; 3780 uint32 prev_val = *prev; 3781 3782 /* read current value */ 3783 pmutime_val = si_pmu_get_pmutimer(osh, cc); 3784 /* diff btween prev and current value, take on wraparound case as well. */ 3785 pmutime_diff = (pmutime_val >= prev_val) ? 3786 (pmutime_val - prev_val) : 3787 (~prev_val + pmutime_val + 1); 3788 *prev = pmutime_val; 3789 return pmutime_diff; 3790} 3791 3792/** wait for usec for the res_pending register to change. */ 3793/* 3794 NOTE: usec SHOULD be > 32uS 3795 if cond = TRUE, res_pending will be read until it becomes == 0; 3796 If cond = FALSE, res_pending will be read until it becomes != 0; 3797 returns TRUE if timedout. 3798 returns elapsed time in this loop in elapsed_time 3799*/ 3800bool 3801si_pmu_wait_for_res_pending(osl_t *osh, chipcregs_t *cc, uint usec, 3802 bool cond, uint32 *elapsed_time) 3803{ 3804 /* add 32uSec more */ 3805 uint countdown = usec; 3806 uint32 pmutime_prev = 0, pmutime_elapsed = 0, res_pend; 3807 bool pending = FALSE; 3808 3809 /* store current time */ 3810 pmutime_prev = si_pmu_get_pmutimer(osh, cc); 3811 while (1) { 3812 res_pend = R_REG(osh, &cc->res_pending); 3813 3814 /* based on the condition, check */ 3815 if (cond == TRUE) { 3816 if (res_pend == 0) break; 3817 } else { 3818 if (res_pend != 0) break; 3819 } 3820 3821 /* if required time over */ 3822 if ((pmutime_elapsed * PMU_US_STEPS) >= countdown) { 3823 /* timeout. so return as still pending */ 3824 pending = TRUE; 3825 break; 3826 } 3827 3828 /* get elapsed time after adding diff between prev and current 3829 * pmutimer value 3830 */ 3831 pmutime_elapsed += si_pmu_get_pmutime_diff(osh, cc, &pmutime_prev); 3832 } 3833 3834 *elapsed_time = pmutime_elapsed * PMU_US_STEPS; 3835 return pending; 3836} /* si_pmu_wait_for_res_pending */ 3837 3838/** 3839 * The algorithm for pending check is that, 3840 * step1: wait till (res_pending !=0) OR pmu_max_trans_timeout. 3841 * if max_trans_timeout, flag error and exit. 3842 * wait for 1 ILP clk [64uS] based on pmu timer, 3843 * polling to see if res_pending again goes high. 3844 * if res_pending again goes high, go back to step1. 3845 * Note: res_pending is checked repeatedly because, in between switching 3846 * of dependent 3847 * resources, res_pending resets to 0 for a short duration of time before 3848 * it becomes 1 again. 3849 * Note: return 0 is GOOD, 1 is BAD [mainly timeout]. 3850 */ 3851int si_pmu_wait_for_steady_state(osl_t *osh, chipcregs_t *cc) 3852{ 3853 int stat = 0; 3854 bool timedout = FALSE; 3855 uint32 elapsed = 0, pmutime_total_elapsed = 0; 3856 3857 while (1) { 3858 /* wait until all resources are settled down [till res_pending becomes 0] */ 3859 timedout = si_pmu_wait_for_res_pending(osh, cc, 3860 PMU_MAX_TRANSITION_DLY, TRUE, &elapsed); 3861 3862 if (timedout) { 3863 stat = 1; 3864 break; 3865 } 3866 3867 pmutime_total_elapsed += elapsed; 3868 /* wait to check if any resource comes back to non-zero indicating 3869 * that it pends again. The res_pending goes 0 for 1 ILP clock before 3870 * getting set for next resource in the sequence , so if res_pending 3871 * is 0 for more than 1 ILP clk it means nothing is pending 3872 * to indicate some pending dependency. 3873 */ 3874 timedout = si_pmu_wait_for_res_pending(osh, cc, 3875 64, FALSE, &elapsed); 3876 3877 pmutime_total_elapsed += elapsed; 3878 /* Here, we can also check timedout, but we make sure that, 3879 * we read the res_pending again. 3880 */ 3881 if (timedout) { 3882 stat = 0; 3883 break; 3884 } 3885 3886 /* Total wait time for all the waits above added should be 3887 * less than PMU_MAX_TRANSITION_DLY 3888 */ 3889 if (pmutime_total_elapsed >= PMU_MAX_TRANSITION_DLY) { 3890 /* timeout. so return as still pending */ 3891 stat = 1; 3892 break; 3893 } 3894 } 3895 return stat; 3896} /* si_pmu_wait_for_steady_state */ 3897 3898/** Turn Off the PLL - Required before setting the PLL registers */ 3899static void 3900si_pmu_pll_off(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 *min_mask, 3901uint32 *max_mask, uint32 *clk_ctl_st) 3902{ 3903 uint32 ht_req; 3904 3905 /* Save the original register values */ 3906 *min_mask = R_REG(osh, &cc->min_res_mask); 3907 *max_mask = R_REG(osh, &cc->max_res_mask); 3908 *clk_ctl_st = R_REG(osh, &cc->clk_ctl_st); 3909 ht_req = si_pmu_htclk_mask(sih); 3910 if (ht_req == 0) 3911 return; 3912 3913 if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) || 3914 (CHIPID(sih->chip) == BCM4350_CHIP_ID) || 3915 0) { 3916 /* slightly different way for 4335, but this could be applied for other chips also. 3917 * If HT_AVAIL is not set, wait to see if any resources are availing HT. 3918 */ 3919 if (((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL)) 3920 si_pmu_wait_for_steady_state(osh, cc); 3921 } else { 3922 OR_REG(osh, &cc->max_res_mask, ht_req); 3923 /* wait for HT to be ready before taking the HT away...HT could be coming up... */ 3924 SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL), 3925 PMU_MAX_TRANSITION_DLY); 3926 ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 3927 } 3928 3929 AND_REG(osh, &cc->min_res_mask, ~ht_req); 3930 AND_REG(osh, &cc->max_res_mask, ~ht_req); 3931 3932 SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == CCS_HTAVAIL), 3933 PMU_MAX_TRANSITION_DLY); 3934 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 3935 3936 OSL_DELAY(100); 3937} /* si_pmu_pll_off */ 3938 3939/* below function are for BBPLL parallel purpose */ 3940/** Turn Off the PLL - Required before setting the PLL registers */ 3941void 3942si_pmu_pll_off_PARR(si_t *sih, osl_t *osh, uint32 *min_mask, 3943uint32 *max_mask, uint32 *clk_ctl_st) 3944{ 3945 chipcregs_t *cc; 3946 uint origidx, intr_val; 3947 uint32 ht_req; 3948 3949 /* Remember original core before switch to chipc */ 3950 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 3951 ASSERT(cc != NULL); 3952 3953 /* Save the original register values */ 3954 *min_mask = R_REG(osh, &cc->min_res_mask); 3955 *max_mask = R_REG(osh, &cc->max_res_mask); 3956 *clk_ctl_st = R_REG(osh, &cc->clk_ctl_st); 3957 ht_req = si_pmu_htclk_mask(sih); 3958 if (ht_req == 0) 3959 return; 3960 3961 if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) || 3962 (CHIPID(sih->chip) == BCM4350_CHIP_ID) || 3963 0) { 3964 /* slightly different way for 4335, but this could be applied for other chips also. 3965 * If HT_AVAIL is not set, wait to see if any resources are availing HT. 3966 */ 3967 if (((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL)) 3968 si_pmu_wait_for_steady_state(osh, cc); 3969 } else { 3970 OR_REG(osh, &cc->max_res_mask, ht_req); 3971 /* wait for HT to be ready before taking the HT away...HT could be coming up... */ 3972 SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL), 3973 PMU_MAX_TRANSITION_DLY); 3974 ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 3975 } 3976 3977 AND_REG(osh, &cc->min_res_mask, ~ht_req); 3978 AND_REG(osh, &cc->max_res_mask, ~ht_req); 3979 3980 /* Return to original core */ 3981 si_restore_core(sih, origidx, intr_val); 3982} /* si_pmu_pll_off_PARR */ 3983 3984 3985static void 3986si_pmu_pll_off_isdone(si_t *sih, osl_t *osh, chipcregs_t *cc) 3987{ 3988 uint32 ht_req; 3989 ht_req = si_pmu_htclk_mask(sih); 3990 SPINWAIT(((R_REG(osh, &cc->res_state) & ht_req) != 0), 3991 PMU_MAX_TRANSITION_DLY); 3992 SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == CCS_HTAVAIL), 3993 PMU_MAX_TRANSITION_DLY); 3994 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 3995 3996} 3997 3998/* above function are for BBPLL parallel purpose */ 3999 4000/** Turn ON/restore the PLL based on the mask received */ 4001static void 4002si_pmu_pll_on(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 min_mask_mask, 4003 uint32 max_mask_mask, uint32 clk_ctl_st_mask) 4004{ 4005 uint32 ht_req; 4006 4007 ht_req = si_pmu_htclk_mask(sih); 4008 if (ht_req == 0) 4009 return; 4010 4011 max_mask_mask &= ht_req; 4012 min_mask_mask &= ht_req; 4013 4014 if (max_mask_mask != 0) 4015 OR_REG(osh, &cc->max_res_mask, max_mask_mask); 4016 4017 if (min_mask_mask != 0) 4018 OR_REG(osh, &cc->min_res_mask, min_mask_mask); 4019 4020 if (clk_ctl_st_mask & CCS_HTAVAIL) { 4021 /* Wait for HT_AVAIL to come back */ 4022 SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL), 4023 PMU_MAX_TRANSITION_DLY); 4024 ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4025 } 4026} 4027 4028/** 4029 * Caller wants to know the default values to program into BB PLL/FLL hardware for a specific chip. 4030 * 4031 * The relation between x-tal frequency, HT clock and divisor values to write into the PLL hardware 4032 * is given by a set of tables, one table per PLL/FLL frequency (480/485 Mhz). 4033 * 4034 * This function returns the table entry corresponding with the (chip specific) default x-tal 4035 * frequency. 4036 */ 4037static const pmu2_xtaltab0_t * 4038BCMINITFN(si_pmu2_xtaldef0)(si_t *sih) 4039{ 4040 switch (CHIPID(sih->chip)) { 4041 case BCM4314_CHIP_ID: 4042 case BCM43142_CHIP_ID: 4043 case BCM43143_CHIP_ID: 4044#ifdef BCM_BOOTLOADER 4045 return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_20000K]; 4046#else 4047 if (ISSIM_ENAB(sih)) 4048 return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_20000K]; 4049 else 4050 return &pmu2_xtaltab0_adfll_485[PMU15_XTALTAB0_20000K]; 4051#endif 4052 case BCM4334_CHIP_ID: 4053#ifdef BCM_BOOTLOADER 4054 return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_37400K]; 4055#else 4056 if (ISSIM_ENAB(sih)) 4057 return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_37400K]; 4058 else 4059 return &pmu2_xtaltab0_adfll_485[PMU15_XTALTAB0_37400K]; 4060#endif 4061 default: 4062 break; 4063 } 4064 4065 ASSERT(0); 4066 return NULL; 4067} 4068 4069static const pmu2_xtaltab0_t * 4070BCMINITFN(si_pmu2_xtaltab0)(si_t *sih) 4071{ 4072 switch (CHIPID(sih->chip)) { 4073 case BCM4314_CHIP_ID: 4074 case BCM43142_CHIP_ID: 4075 case BCM43143_CHIP_ID: 4076 case BCM4334_CHIP_ID: 4077#ifdef BCM_BOOTLOADER 4078 return pmu2_xtaltab0_adfll_480; 4079#else 4080 if (ISSIM_ENAB(sih)) 4081 return pmu2_xtaltab0_adfll_480; 4082 else 4083 return pmu2_xtaltab0_adfll_485; 4084#endif 4085 default: 4086 break; 4087 } 4088 4089 ASSERT(0); 4090 return NULL; 4091} 4092 4093/** For hardware workarounds, OTP can contain an entry to update FLL control registers */ 4094static void 4095BCMATTACHFN(si_pmu2_pll_vars_init)(si_t *sih, osl_t *osh, chipcregs_t *cc) 4096{ 4097 char name[16]; 4098 const char *otp_val; 4099 uint8 i, otp_entry_found = FALSE; 4100 uint32 pll_ctrlcnt; 4101 uint32 min_mask = 0, max_mask = 0, clk_ctl_st = 0; 4102 4103 if (sih->pmurev >= 5) { 4104 pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT; 4105 } 4106 else { 4107 pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT; 4108 } 4109 4110 /* Check if there is any otp enter for PLLcontrol registers */ 4111 for (i = 0; i < pll_ctrlcnt; i++) { 4112 snprintf(name, sizeof(name), "pll%d", i); 4113 if ((otp_val = getvar(NULL, name)) == NULL) 4114 continue; 4115 4116 /* If OTP entry is found for PLL register, then turn off the PLL 4117 * and set the status of the OTP entry accordingly. 4118 */ 4119 otp_entry_found = TRUE; 4120 break; 4121 } 4122 4123 /* If no OTP parameter is found, return. */ 4124 if (otp_entry_found == FALSE) 4125 return; 4126 4127 /* Make sure PLL is off */ 4128 si_pmu_pll_off(sih, osh, cc, &min_mask, &max_mask, &clk_ctl_st); 4129 4130 /* Update the PLL register if there is a OTP entry for PLL registers */ 4131 si_pmu_otp_pllcontrol(sih, osh); 4132 4133 /* Flush deferred pll control registers writes */ 4134 if (sih->pmurev >= 2) 4135 OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 4136 4137 /* Restore back the register values. This ensures PLL remains on if it 4138 * was originally on and remains off if it was originally off. 4139 */ 4140 si_pmu_pll_on(sih, osh, cc, min_mask, max_mask, clk_ctl_st); 4141} /* si_pmu2_pll_vars_init */ 4142 4143/** 4144 * PLL needs to be initialized to the correct frequency. This function will skip that 4145 * initialization if the PLL is already at the correct frequency. 4146 */ 4147static void 4148BCMATTACHFN(si_pmu2_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal) 4149{ 4150 const pmu2_xtaltab0_t *xt; 4151 int xt_idx; 4152 uint32 freq_tgt, pll0; 4153 4154 if (xtal == 0) { 4155 PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n")); 4156 goto exit; 4157 } 4158 4159 for (xt = si_pmu2_xtaltab0(sih), xt_idx = 0; xt != NULL && xt->fref != 0; xt++, xt_idx++) { 4160 if (xt->fref == xtal) 4161 break; 4162 } 4163 4164 if (xt == NULL || xt->fref == 0) { 4165 PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", 4166 xtal / 1000, xtal % 1000)); 4167 goto exit; 4168 } 4169 4170 W_REG(osh, &cc->pllcontrol_addr, PMU15_PLL_PLLCTL0); 4171 pll0 = R_REG(osh, &cc->pllcontrol_data); 4172 4173 freq_tgt = (pll0 & PMU15_PLL_PC0_FREQTGT_MASK) >> PMU15_PLL_PC0_FREQTGT_SHIFT; 4174 if (freq_tgt == xt->freq_tgt) { 4175 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 4176 xt->fref / 1000, xt->fref % 1000)); 4177 goto exit; 4178 } 4179 4180 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); 4181 PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000)); 4182 4183 /* Make sure the PLL is off */ 4184 switch (CHIPID(sih->chip)) { 4185 case BCM4334_CHIP_ID: 4186 AND_REG(osh, &cc->min_res_mask, 4187 ~(PMURES_BIT(RES4334_HT_AVAIL) | PMURES_BIT(RES4334_MACPHY_CLK_AVAIL))); 4188 AND_REG(osh, &cc->max_res_mask, 4189 ~(PMURES_BIT(RES4334_HT_AVAIL) | PMURES_BIT(RES4334_MACPHY_CLK_AVAIL))); 4190 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4191 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4192 break; 4193 case BCM4314_CHIP_ID: 4194 case BCM43142_CHIP_ID: 4195 AND_REG(osh, &cc->min_res_mask, 4196 ~(PMURES_BIT(RES4314_HT_AVAIL) | PMURES_BIT(RES4314_MACPHY_CLK_AVAIL))); 4197 AND_REG(osh, &cc->max_res_mask, 4198 ~(PMURES_BIT(RES4314_HT_AVAIL) | PMURES_BIT(RES4314_MACPHY_CLK_AVAIL))); 4199 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4200 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4201 break; 4202 case BCM43143_CHIP_ID: 4203 AND_REG(osh, &cc->min_res_mask, 4204 ~(PMURES_BIT(RES43143_HT_AVAIL) | PMURES_BIT(RES43143_MACPHY_CLK_AVAIL))); 4205 AND_REG(osh, &cc->max_res_mask, 4206 ~(PMURES_BIT(RES43143_HT_AVAIL) | PMURES_BIT(RES43143_MACPHY_CLK_AVAIL))); 4207 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4208 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4209 break; 4210 default: 4211 PMU_ERROR(("%s: Turn HT off for 0x%x????\n", __FUNCTION__, CHIPID(sih->chip))); 4212 break; 4213 } 4214 4215 pll0 = (pll0 & ~PMU15_PLL_PC0_FREQTGT_MASK) | (xt->freq_tgt << PMU15_PLL_PC0_FREQTGT_SHIFT); 4216 W_REG(osh, &cc->pllcontrol_data, pll0); 4217 4218 if (CST4334_CHIPMODE_HSIC(sih->chipst)) { 4219 uint32 hsic_freq; 4220 4221 /* Only update target freq from 480Mhz table for HSIC */ 4222 ASSERT(xt_idx < PMU15_XTALTAB0_END); 4223 hsic_freq = pmu2_xtaltab0_adfll_480[xt_idx].freq_tgt; 4224 4225 /* 4226 * Update new tgt freq for PLL control 5 4227 * This is activated when USB/HSIC core is taken out of reset (ch_reset()) 4228 */ 4229 si_pmu_pllcontrol(sih, PMU15_PLL_PLLCTL5, PMU15_PLL_PC5_FREQTGT_MASK, hsic_freq); 4230 } 4231 4232 /* Flush deferred pll control registers writes */ 4233 if (sih->pmurev >= 2) 4234 OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 4235 4236exit: 4237 /* Vars over-rides */ 4238 si_pmu2_pll_vars_init(sih, osh, cc); 4239} /* si_pmu2_pllinit0 */ 4240 4241/** returns the clock frequency at which the ARM is running */ 4242static uint32 4243BCMINITFN(si_pmu2_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 4244{ 4245 const pmu2_xtaltab0_t *xt; 4246 uint32 freq_tgt = 0, pll0 = 0; 4247 4248 switch (CHIPID(sih->chip)) { 4249 case BCM4314_CHIP_ID: 4250 case BCM43142_CHIP_ID: 4251 case BCM43143_CHIP_ID: 4252 case BCM4334_CHIP_ID: 4253 W_REG(osh, &cc->pllcontrol_addr, PMU15_PLL_PLLCTL0); 4254 pll0 = R_REG(osh, &cc->pllcontrol_data); 4255 freq_tgt = (pll0 & PMU15_PLL_PC0_FREQTGT_MASK) >> PMU15_PLL_PC0_FREQTGT_SHIFT; 4256 break; 4257 default: 4258 ASSERT(0); 4259 break; 4260 } 4261 4262 for (xt = pmu2_xtaltab0_adfll_480; xt != NULL && xt->fref != 0; xt++) { 4263 if (xt->freq_tgt == freq_tgt) 4264 return PMU15_ARM_96MHZ; 4265 } 4266 4267#ifndef BCM_BOOTLOADER 4268 for (xt = pmu2_xtaltab0_adfll_485; xt != NULL && xt->fref != 0; xt++) { 4269 if (xt->freq_tgt == freq_tgt) 4270 return PMU15_ARM_97MHZ; 4271 } 4272#endif 4273 4274 /* default */ 4275 return PMU15_ARM_96MHZ; 4276} 4277 4278/** Query ALP/xtal clock frequency */ 4279static uint32 4280BCMINITFN(si_pmu2_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 4281{ 4282 const pmu2_xtaltab0_t *xt; 4283 uint32 freq_tgt, pll0; 4284 4285 W_REG(osh, &cc->pllcontrol_addr, PMU15_PLL_PLLCTL0); 4286 pll0 = R_REG(osh, &cc->pllcontrol_data); 4287 4288 freq_tgt = (pll0 & PMU15_PLL_PC0_FREQTGT_MASK) >> PMU15_PLL_PC0_FREQTGT_SHIFT; 4289 4290 4291 for (xt = pmu2_xtaltab0_adfll_480; xt != NULL && xt->fref != 0; xt++) { 4292 if (xt->freq_tgt == freq_tgt) 4293 break; 4294 } 4295 4296#ifndef BCM_BOOTLOADER 4297 if (xt == NULL || xt->fref == 0) { 4298 for (xt = pmu2_xtaltab0_adfll_485; xt != NULL && xt->fref != 0; xt++) { 4299 if (xt->freq_tgt == freq_tgt) 4300 break; 4301 } 4302 } 4303#endif 4304 4305 /* Could not find it so assign a default value */ 4306 if (xt == NULL || xt->fref == 0) 4307 xt = si_pmu2_xtaldef0(sih); 4308 ASSERT(xt != NULL && xt->fref != 0); 4309 4310 return xt->fref * 1000; 4311} 4312 4313/* Set up PLL registers in the PMU as per the OTP values. */ 4314static void 4315BCMATTACHFN(si_pmu1_pllinit1)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal) 4316{ 4317 char name[16]; 4318 const char *otp_val; 4319 uint8 i, otp_entry_found = FALSE, pll_reg_update_required; 4320 uint32 pll_ctrlcnt; 4321 uint32 min_mask = 0, max_mask = 0, clk_ctl_st = 0; 4322 4323 if (sih->pmurev >= 5) { 4324 pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT; 4325 } 4326 else { 4327 pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT; 4328 } 4329 4330 /* Check if there is any otp enter for PLLcontrol registers */ 4331 for (i = 0; i < pll_ctrlcnt; i++) { 4332 snprintf(name, sizeof(name), "pll%d", i); 4333 if ((otp_val = getvar(NULL, name)) == NULL) 4334 continue; 4335 4336 /* If OTP entry is found for PLL register, then turn off the PLL 4337 * and set the status of the OTP entry accordingly. 4338 */ 4339 otp_entry_found = TRUE; 4340 break; 4341 } 4342 4343 pll_reg_update_required = si_pmu_update_pllcontrol(sih, osh, xtal, FALSE); 4344 4345 /* If no OTP parameter is found and no chip-specific updates are needed, return. */ 4346 if ((otp_entry_found == FALSE) && (pll_reg_update_required == FALSE)) 4347 return; 4348 4349 /* Make sure PLL is off */ 4350 si_pmu_pll_off(sih, osh, cc, &min_mask, &max_mask, &clk_ctl_st); 4351 4352 if (pll_reg_update_required) { 4353 /* Update any chip-specific PLL registers . Do actual write */ 4354 si_pmu_update_pllcontrol(sih, osh, xtal, TRUE); 4355 } 4356 4357 /* Update the PLL register if there is a OTP entry for PLL registers */ 4358 si_pmu_otp_pllcontrol(sih, osh); 4359 4360 /* Flush deferred pll control registers writes */ 4361 if (sih->pmurev >= 2) 4362 OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 4363 4364 /* Restore back the register values. This ensures PLL remains on if it 4365 * was originally on and remains off if it was originally off. 4366 */ 4367 si_pmu_pll_on(sih, osh, cc, min_mask, max_mask, clk_ctl_st); 4368} /* si_pmu1_pllinit1 */ 4369 4370/** 4371 * Set up PLL registers in the PMU as per the crystal speed. 4372 * XtalFreq field in pmucontrol register being 0 indicates the PLL 4373 * is not programmed and the h/w default is assumed to work, in which 4374 * case the xtal frequency is unknown to the s/w so we need to call 4375 * si_pmu1_xtaldef0() wherever it is needed to return a default value. 4376 */ 4377static void 4378BCMATTACHFN(si_pmu1_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal) 4379{ 4380 const pmu1_xtaltab0_t *xt; 4381 uint32 tmp; 4382 uint32 buf_strength = 0; 4383 uint8 ndiv_mode = 1; 4384 uint8 dacrate; 4385 4386 /* Use h/w default PLL config */ 4387 if (xtal == 0) { 4388 PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n")); 4389 return; 4390 } 4391 4392 /* Find the frequency in the table */ 4393 for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++) 4394 if (xt->fref == xtal) 4395 break; 4396 4397 /* Check current PLL state, bail out if it has been programmed or 4398 * we don't know how to program it. 4399 */ 4400 if (xt == NULL || xt->fref == 0) { 4401 PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", 4402 xtal / 1000, xtal % 1000)); 4403 return; 4404 } 4405 /* for 4319 bootloader already programs the PLL but bootloader does not program the 4406 PLL4 and PLL5. So Skip this check for 4319 4407 */ 4408 if ((((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> 4409 PCTL_XTALFREQ_SHIFT) == xt->xf) && 4410 !((CHIPID(sih->chip) == BCM4319_CHIP_ID) || (CHIPID(sih->chip) == BCM4330_CHIP_ID))) 4411 { 4412 PMU_MSG(("PLL already programmed for %d.%d MHz\n", 4413 xt->fref / 1000, xt->fref % 1000)); 4414 return; 4415 } 4416 4417 PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); 4418 PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000)); 4419 4420 switch (CHIPID(sih->chip)) { 4421 case BCM4325_CHIP_ID: 4422 /* Change the BBPLL drive strength to 2 for all channels */ 4423 buf_strength = 0x222222; 4424 /* Make sure the PLL is off */ 4425 AND_REG(osh, &cc->min_res_mask, 4426 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL))); 4427 AND_REG(osh, &cc->max_res_mask, 4428 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL))); 4429 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4430 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4431 break; 4432 case BCM4329_CHIP_ID: 4433 /* Change the BBPLL drive strength to 8 for all channels */ 4434 buf_strength = 0x888888; 4435 AND_REG(osh, &cc->min_res_mask, 4436 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL))); 4437 AND_REG(osh, &cc->max_res_mask, 4438 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL))); 4439 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4440 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4441 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 4442 if (xt->fref == 38400) 4443 tmp = 0x200024C0; 4444 else if (xt->fref == 37400) 4445 tmp = 0x20004500; 4446 else if (xt->fref == 26000) 4447 tmp = 0x200024C0; 4448 else 4449 tmp = 0x200005C0; /* Chip Dflt Settings */ 4450 W_REG(osh, &cc->pllcontrol_data, tmp); 4451 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 4452 tmp = R_REG(osh, &cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK; 4453 if ((xt->fref == 38400) || (xt->fref == 37400) || (xt->fref == 26000)) 4454 tmp |= 0x15; 4455 else 4456 tmp |= 0x25; /* Chip Dflt Settings */ 4457 W_REG(osh, &cc->pllcontrol_data, tmp); 4458 break; 4459 case BCM4315_CHIP_ID: 4460 /* Change the BBPLL drive strength to 2 for all channels */ 4461 buf_strength = 0x222222; 4462 /* Make sure the PLL is off */ 4463 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4315_HT_AVAIL))); 4464 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4315_HT_AVAIL))); 4465 OSL_DELAY(100); 4466 4467 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU))); 4468 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU))); 4469 OSL_DELAY(100); 4470 4471 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4472 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4473 break; 4474 4475 case BCM4319_CHIP_ID: 4476 /* Change the BBPLL drive strength to 2 for all channels */ 4477 buf_strength = 0x222222; 4478 4479 /* Make sure the PLL is off */ 4480 /* WAR65104: Disable the HT_AVAIL resource first and then 4481 * after a delay (more than downtime for HT_AVAIL) remove the 4482 * BBPLL resource; backplane clock moves to ALP from HT. 4483 */ 4484 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4319_HT_AVAIL))); 4485 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4319_HT_AVAIL))); 4486 4487 OSL_DELAY(100); 4488 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 4489 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 4490 4491 OSL_DELAY(100); 4492 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4493 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4494 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 4495 tmp = 0x200005c0; 4496 W_REG(osh, &cc->pllcontrol_data, tmp); 4497 break; 4498 4499 case BCM4336_CHIP_ID: 4500 case BCM43362_CHIP_ID: 4501 AND_REG(osh, &cc->min_res_mask, 4502 ~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 4503 AND_REG(osh, &cc->max_res_mask, 4504 ~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 4505 OSL_DELAY(100); 4506 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4507 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4508 break; 4509 4510 case BCM4330_CHIP_ID: 4511 AND_REG(osh, &cc->min_res_mask, 4512 ~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 4513 AND_REG(osh, &cc->max_res_mask, 4514 ~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 4515 OSL_DELAY(100); 4516 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4517 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4518 break; 4519 4520 default: 4521 ASSERT(0); 4522 } 4523 4524 PMU_MSG(("Done masking\n")); 4525 4526 /* Write p1div and p2div to pllcontrol[0] */ 4527 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 4528 tmp = R_REG(osh, &cc->pllcontrol_data) & 4529 ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK); 4530 tmp |= ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | 4531 ((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK); 4532 W_REG(osh, &cc->pllcontrol_data, tmp); 4533 4534 if ((CHIPID(sih->chip) == BCM4330_CHIP_ID)) { 4535 if (CHIPREV(sih->chiprev) < 2) 4536 dacrate = 160; 4537 else { 4538 if (!(dacrate = (uint8)getintvar(NULL, "dacrate2g"))) 4539 dacrate = 80; 4540 } 4541 si_pmu_set_4330_plldivs(sih, dacrate); 4542 } 4543 4544 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (CHIPREV(sih->chiprev) == 0)) { 4545 4546 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 4547 tmp = R_REG(osh, &cc->pllcontrol_data); 4548 tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK); 4549 tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL; 4550 W_REG(osh, &cc->pllcontrol_data, tmp); 4551 } 4552 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) || 4553 (CHIPID(sih->chip) == BCM4336_CHIP_ID) || 4554 (CHIPID(sih->chip) == BCM43362_CHIP_ID) || 4555 (CHIPID(sih->chip) == BCM4330_CHIP_ID)) 4556 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB; 4557 else 4558 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH; 4559 4560 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ 4561 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 4562 tmp = R_REG(osh, &cc->pllcontrol_data) & 4563 ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK); 4564 tmp |= ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK) | 4565 ((ndiv_mode << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK); 4566 W_REG(osh, &cc->pllcontrol_data, tmp); 4567 4568 /* Write ndiv_frac to pllcontrol[3] */ 4569 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 4570 tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; 4571 tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) & 4572 PMU1_PLL0_PC3_NDIV_FRAC_MASK); 4573 W_REG(osh, &cc->pllcontrol_data, tmp); 4574 4575 /* Write clock driving strength to pllcontrol[5] */ 4576 if (buf_strength) { 4577 PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength)); 4578 4579 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 4580 tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; 4581 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT); 4582 W_REG(osh, &cc->pllcontrol_data, tmp); 4583 } 4584 4585 PMU_MSG(("Done pll\n")); 4586 4587 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs 4588 * to be updated. 4589 */ 4590 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && (xt->fref != XTAL_FREQ_30000MHZ)) { 4591 W_REG(osh, &cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2); 4592 tmp = R_REG(osh, &cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK; 4593 if (xt->fref == XTAL_FREQ_24000MHZ) { 4594 tmp |= (CCTL_4319USB_24MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT); 4595 } else if (xt->fref == XTAL_FREQ_48000MHZ) { 4596 tmp |= (CCTL_4319USB_48MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT); 4597 } 4598 W_REG(osh, &cc->chipcontrol_data, tmp); 4599 } 4600 4601 /* Flush deferred pll control registers writes */ 4602 if (sih->pmurev >= 2) 4603 OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); 4604 4605 /* Write XtalFreq. Set the divisor also. */ 4606 tmp = R_REG(osh, &cc->pmucontrol) & 4607 ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); 4608 tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & 4609 PCTL_ILP_DIV_MASK) | 4610 ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); 4611 4612 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && CHIPREV(sih->chiprev) == 0) { 4613 /* clear the htstretch before clearing HTReqEn */ 4614 AND_REG(osh, &cc->clkstretch, ~CSTRETCH_HT); 4615 tmp &= ~PCTL_HT_REQ_EN; 4616 } 4617 4618 W_REG(osh, &cc->pmucontrol, tmp); 4619} /* si_pmu1_pllinit0 */ 4620 4621/** 4622 * returns the CPU clock frequency. Does this by determining current Fvco and the setting of the 4623 * clock divider that leads up to the ARM. 4624 */ 4625static uint32 4626BCMINITFN(si_pmu1_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc) 4627{ 4628 uint32 tmp, mdiv = 1; 4629#ifndef BCMPCIDEV 4630#endif /* BCMPCIDEV */ 4631 uint32 FVCO = si_pmu1_pllfvco0(sih); 4632 4633 switch (CHIPID(sih->chip)) { 4634 case BCM4325_CHIP_ID: 4635 case BCM4329_CHIP_ID: 4636 case BCM4315_CHIP_ID: 4637 case BCM4319_CHIP_ID: 4638 case BCM4336_CHIP_ID: 4639 case BCM43362_CHIP_ID: 4640 case BCM4330_CHIP_ID: 4641 /* Read m1div from pllcontrol[1] */ 4642 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 4643 tmp = R_REG(osh, &cc->pllcontrol_data); 4644 mdiv = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; 4645 break; 4646 case BCM43239_CHIP_ID: 4647 /* Read m6div from pllcontrol[2] */ 4648 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 4649 tmp = R_REG(osh, &cc->pllcontrol_data); 4650 mdiv = (tmp & PMU1_PLL0_PC2_M6DIV_MASK) >> PMU1_PLL0_PC2_M6DIV_SHIFT; 4651 break; 4652 case BCM4324_CHIP_ID: 4653 case BCM43242_CHIP_ID: 4654 case BCM43243_CHIP_ID: 4655 /* Read m2div from pllcontrol[1] */ 4656 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 4657 tmp = R_REG(osh, &cc->pllcontrol_data); 4658 mdiv = (tmp & PMU1_PLL0_PC1_M2DIV_MASK) >> PMU1_PLL0_PC1_M2DIV_SHIFT; 4659 break; 4660 case BCM4335_CHIP_ID: 4661 case BCM4350_CHIP_ID: 4662 /* Read m3div from pllcontrol[1] */ 4663 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 4664 tmp = R_REG(osh, &cc->pllcontrol_data); 4665 mdiv = (tmp & PMU1_PLL0_PC1_M3DIV_MASK) >> PMU1_PLL0_PC1_M3DIV_SHIFT; 4666 break; 4667 case BCM4360_CHIP_ID: 4668 case BCM43460_CHIP_ID: 4669 case BCM43526_CHIP_ID: 4670 case BCM4352_CHIP_ID: 4671 /* Read m6div from pllcontrol[5] */ 4672 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 4673 tmp = R_REG(osh, &cc->pllcontrol_data); 4674 mdiv = (tmp & PMU1_PLL0_PC2_M6DIV_MASK) >> PMU1_PLL0_PC2_M6DIV_SHIFT; 4675 break; 4676 default: 4677 PMU_MSG(("si_pmu1_cpuclk0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 4678 ASSERT(0); 4679 break; 4680 } 4681#ifndef BCMPCIDEV 4682#endif /* BCMPCIDEV */ 4683 /* Return ARM/SB clock */ 4684 return FVCO / mdiv * 1000; 4685} /* si_pmu1_cpuclk0 */ 4686 4687/** 4335 specific code. Returns the MAC clock frequency. */ 4688extern uint32 4689si_mac_clk(si_t *sih, osl_t *osh) 4690{ 4691 uint8 mdiv2 = 0; 4692 uint32 pll_reg, mac_clk = 0; 4693 chipcregs_t *cc; 4694 uint origidx, intr_val; 4695 4696 uint32 FVCO = si_pmu1_pllfvco0(sih); 4697 4698 /* Remember original core before switch to chipc */ 4699 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 4700 ASSERT(cc != NULL); 4701 4702 switch (CHIPID(sih->chip)) { 4703 case BCM4335_CHIP_ID: 4704 pll_reg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0); 4705 4706 mdiv2 = (pll_reg & PMU4335_PLL0_PC1_MDIV2_MASK) >> 4707 PMU4335_PLL0_PC1_MDIV2_SHIFT; 4708 mac_clk = FVCO / mdiv2; 4709 break; 4710 default: 4711 PMU_MSG(("si_mac_clk: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8))); 4712 ASSERT(0); 4713 break; 4714 } 4715 4716 /* Return to original core */ 4717 si_restore_core(sih, origidx, intr_val); 4718 4719 4720 return mac_clk; 4721} /* si_mac_clk */ 4722 4723bool 4724si_pmu_is_autoresetphyclk_disabled(si_t *sih, osl_t *osh) 4725{ 4726 chipcregs_t *cc; 4727 uint origidx; 4728 bool disable = FALSE; 4729 4730 /* Remember original core before switch to chipc */ 4731 origidx = si_coreidx(sih); 4732 cc = si_setcoreidx(sih, SI_CC_IDX); 4733 ASSERT(cc != NULL); 4734 4735 switch (CHIPID(sih->chip)) { 4736 case BCM43239_CHIP_ID: 4737 W_REG(osh, &cc->chipcontrol_addr, 0); 4738 if (R_REG(osh, &cc->chipcontrol_data) & 0x00000002) 4739 disable = TRUE; 4740 break; 4741 default: 4742 break; 4743 } 4744 4745 /* Return to original core */ 4746 si_setcoreidx(sih, origidx); 4747 return disable; 4748} 4749 4750static void 4751BCMATTACHFN(si_set_bb_vcofreq_frac)(si_t *sih, osl_t *osh, int vcofreq, int frac, int xtalfreq) 4752{ 4753 uint32 vcofreq_withfrac, p1div, ndiv_int, fraca, ndiv_mode, reg; 4754 /* shifts / masks for PMU PLL control register #2 : */ 4755 uint32 ndiv_int_shift, ndiv_mode_shift, p1div_shift, pllctrl2_mask; 4756 /* shifts / masks for PMU PLL control register #3 : */ 4757 uint32 pllctrl3_mask; 4758 4759 if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) || 4760 (CHIPID(sih->chip) == BCM43460_CHIP_ID) || 4761 (CHIPID(sih->chip) == BCM43526_CHIP_ID) || 4762 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) { 4763 chipcregs_t *cc; 4764 cc = si_setcoreidx(sih, SI_CC_IDX); 4765 if (R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) { 4766 PMU_MSG(("HTAVAIL is set, so not updating BBPLL Frequency \n")); 4767 return; 4768 } 4769 4770 ndiv_int_shift = 7; 4771 ndiv_mode_shift = 4; 4772 p1div_shift = 0; 4773 pllctrl2_mask = 0xffffffff; 4774 pllctrl3_mask = 0xffffffff; 4775 } else if (CHIPID(sih->chip) == BCM4350_CHIP_ID) { 4776 ndiv_int_shift = 23; 4777 ndiv_mode_shift = 20; 4778 p1div_shift = 16; 4779 pllctrl2_mask = 0xffff0000; 4780 pllctrl3_mask = 0x00ffffff; 4781 } else { 4782 /* put more chips here */ 4783 PMU_ERROR(("%s: only work on 4360, 4350\n", __FUNCTION__)); 4784 return; 4785 } 4786 4787 vcofreq_withfrac = vcofreq * 10000 + frac; 4788 p1div = 0x1; 4789 ndiv_int = vcofreq / xtalfreq; 4790 ndiv_mode = (vcofreq_withfrac % (xtalfreq * 10000)) ? 3 : 0; 4791 PMU_ERROR(("ChangeVCO => vco:%d, xtalF:%d, frac: %d, ndivMode: %d, ndivint: %d\n", 4792 vcofreq, xtalfreq, frac, ndiv_mode, ndiv_int)); 4793 4794 reg = (ndiv_int << ndiv_int_shift) | 4795 (ndiv_mode << ndiv_mode_shift) | 4796 (p1div << p1div_shift); 4797 PMU_ERROR(("Data written into the PLL_CNTRL_ADDR2: %08x\n", reg)); 4798 si_pmu_pllcontrol(sih, 2, pllctrl2_mask, reg); 4799 4800 if (ndiv_mode) { 4801 /* frac = (vcofreq_withfrac % (xtalfreq * 10000)) * 2^24) / (xtalfreq * 10000) */ 4802 uint32 r1, r0; 4803 bcm_uint64_multiple_add( 4804 &r1, &r0, vcofreq_withfrac % (xtalfreq * 10000), 1 << 24, 0); 4805 bcm_uint64_divide(&fraca, r1, r0, xtalfreq * 10000); 4806 PMU_ERROR(("Data written into the PLL_CNTRL_ADDR3 (Fractional): %08x\n", fraca)); 4807 si_pmu_pllcontrol(sih, 3, pllctrl3_mask, fraca); 4808 } 4809 4810 si_pmu_pllupd(sih); 4811} /* si_set_bb_vcofreq_frac */ 4812 4813/** given x-tal frequency, returns vcofreq with fraction in 100Hz */ 4814uint32 4815si_pmu_get_bb_vcofreq(si_t *sih, osl_t *osh, int xtalfreq) 4816{ 4817 uint32 ndiv_int, ndiv_mode, frac = 0, p1div; 4818 uint32 xtal1, vcofrac = 0, vcofreq; 4819 uint32 r1, r0, reg; 4820 4821 if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) || 4822 (CHIPID(sih->chip) == BCM43460_CHIP_ID) || 4823 (CHIPID(sih->chip) == BCM43526_CHIP_ID) || 4824 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) { 4825 reg = si_pmu_pllcontrol(sih, 2, 0, 0); 4826 ndiv_int = reg >> 7; 4827 ndiv_mode = (reg >> 4) & 7; 4828 p1div = 1; 4829 4830 if (ndiv_mode) 4831 frac = si_pmu_pllcontrol(sih, 3, 0, 0); 4832 } else if (CHIPID(sih->chip) == BCM4350_CHIP_ID) { 4833 reg = si_pmu_pllcontrol(sih, 2, 0, 0); 4834 ndiv_int = reg >> 23; 4835 ndiv_mode = (reg >> 20) & 7; 4836 p1div = (reg >> 16) & 0xf; 4837 4838 if (ndiv_mode) 4839 frac = si_pmu_pllcontrol(sih, 3, 0, 0) & 0x00ffffff; 4840 } else { 4841 /* put more chips here */ 4842 PMU_ERROR(("%s: only work on 4360, 4350\n", __FUNCTION__)); 4843 return 0; 4844 } 4845 4846 xtal1 = 10000 * xtalfreq / p1div; 4847 4848 if (ndiv_mode) { 4849 /* vcofreq fraction = (xtal1 * frac + (1 << 23)) / (1 << 24); 4850 * handle overflow 4851 */ 4852 bcm_uint64_multiple_add(&r1, &r0, xtal1, frac, 1 << 23); 4853 vcofrac = (r1 << 8) | (r0 >> 24); 4854 } 4855 4856 if ((int)xtal1 > (int)((0xffffffff - vcofrac) / ndiv_int)) { 4857 PMU_ERROR(("%s: xtalfreq is too big, %d\n", __FUNCTION__, xtalfreq)); 4858 return 0; 4859 } 4860 4861 vcofreq = xtal1 * ndiv_int + vcofrac; 4862 return vcofreq; 4863} /* si_pmu_get_bb_vcofreq */ 4864 4865/** 4866 * Initializes PLL given an x-tal frequency. 4867 * Calls si_pmuX_pllinitY() type of functions, where the reasoning behind 'X' and 'Y' is historical 4868 * rather than logical. 4869 * 4870 * xtalfreq : x-tal frequency in [KHz] 4871 */ 4872void 4873BCMATTACHFN(si_pmu_pll_init)(si_t *sih, osl_t *osh, uint xtalfreq) 4874{ 4875 chipcregs_t *cc; 4876 uint origidx; 4877 4878 ASSERT(sih->cccaps & CC_CAP_PMU); 4879 4880 /* Remember original core before switch to chipc */ 4881 origidx = si_coreidx(sih); 4882 cc = si_setcoreidx(sih, SI_CC_IDX); 4883 ASSERT(cc != NULL); 4884 4885 switch (CHIPID(sih->chip)) { 4886 case BCM4328_CHIP_ID: 4887 si_pmu0_pllinit0(sih, osh, cc, xtalfreq); 4888 break; 4889 case BCM5354_CHIP_ID: 4890 if (xtalfreq == 0) 4891 xtalfreq = 25000; 4892 si_pmu0_pllinit0(sih, osh, cc, xtalfreq); 4893 break; 4894 case BCM4325_CHIP_ID: 4895 si_pmu1_pllinit0(sih, osh, cc, xtalfreq); 4896 break; 4897 case BCM4329_CHIP_ID: 4898 if (xtalfreq == 0) 4899 xtalfreq = 38400; 4900 si_pmu1_pllinit0(sih, osh, cc, xtalfreq); 4901 break; 4902 case BCM4312_CHIP_ID: 4903 /* assume default works */ 4904 break; 4905 case BCM4322_CHIP_ID: 4906 case BCM43221_CHIP_ID: 4907 case BCM43231_CHIP_ID: 4908 case BCM4342_CHIP_ID: { 4909 if (CHIPREV(sih->chiprev) == 0) { 4910 uint32 minmask, maxmask; 4911 4912 minmask = R_REG(osh, &cc->min_res_mask); 4913 maxmask = R_REG(osh, &cc->max_res_mask); 4914 4915 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */ 4916 /* Have to remove HT Avail request before powering off PLL */ 4917 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 4918 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 4919 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 4920 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 4921 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 4922 OSL_DELAY(1000); 4923 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 4924 4925 4926 W_REG(osh, &cc->pllcontrol_addr, PMU2_SI_PLL_PLLCTL); 4927 W_REG(osh, &cc->pllcontrol_data, 0x380005c0); 4928 4929 4930 OSL_DELAY(100); 4931 W_REG(osh, &cc->max_res_mask, maxmask); 4932 OSL_DELAY(100); 4933 W_REG(osh, &cc->min_res_mask, minmask); 4934 OSL_DELAY(100); 4935 } 4936 4937 break; 4938 } 4939 4940 case BCM4360_CHIP_ID: 4941 case BCM43460_CHIP_ID: 4942 case BCM4352_CHIP_ID: { 4943 if (CHIPREV(sih->chiprev) > 2) 4944 si_set_bb_vcofreq_frac(sih, osh, 960, 98, 40); 4945 break; 4946 } 4947 4948 4949 case BCM4313_CHIP_ID: 4950 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 4951 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43420_CHIP_ID: 4952 case BCM43421_CHIP_ID: 4953 case BCM43226_CHIP_ID: 4954 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 4955 case BCM43237_CHIP_ID: 4956 case BCM43234_CHIP_ID: 4957 case BCM4331_CHIP_ID: 4958 case BCM43431_CHIP_ID: 4959 case BCM43131_CHIP_ID: 4960 case BCM43217_CHIP_ID: 4961 case BCM43227_CHIP_ID: 4962 case BCM43228_CHIP_ID: 4963 case BCM43428_CHIP_ID: 4964 case BCM6362_CHIP_ID: 4965 break; 4966 case BCM4315_CHIP_ID: 4967 case BCM4319_CHIP_ID: 4968 case BCM4336_CHIP_ID: 4969 case BCM43362_CHIP_ID: 4970 case BCM4330_CHIP_ID: 4971 si_pmu1_pllinit0(sih, osh, cc, xtalfreq); 4972 break; 4973 case BCM43239_CHIP_ID: 4974 case BCM4324_CHIP_ID: 4975 case BCM43242_CHIP_ID: 4976 case BCM43243_CHIP_ID: 4977 case BCM4335_CHIP_ID: 4978 si_pmu1_pllinit1(sih, osh, cc, xtalfreq); 4979 break; 4980 case BCM4350_CHIP_ID: 4981 si_pmu1_pllinit1(sih, osh, cc, xtalfreq); 4982 if (xtalfreq == 40000) 4983 si_set_bb_vcofreq_frac(sih, osh, 968, 0, 40); 4984 break; 4985 case BCM4314_CHIP_ID: 4986 case BCM43142_CHIP_ID: 4987 case BCM43143_CHIP_ID: 4988 if (xtalfreq == 0) 4989 xtalfreq = 20000; 4990 si_pmu2_pllinit0(sih, osh, cc, xtalfreq); 4991 break; 4992 case BCM4334_CHIP_ID: 4993 si_pmu2_pllinit0(sih, osh, cc, xtalfreq); 4994 break; 4995 default: 4996 PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n", 4997 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); 4998 break; 4999 } 5000 5001#ifdef BCMDBG_FORCEHT 5002 OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT); 5003#endif 5004 5005 /* Return to original core */ 5006 si_setcoreidx(sih, origidx); 5007} /* si_pmu_pll_init */ 5008 5009/** query alp clock frequency */ 5010uint32 5011BCMINITFN(si_pmu_alp_clock)(si_t *sih, osl_t *osh) 5012{ 5013 chipcregs_t *cc; 5014 uint origidx; 5015 uint32 clock = ALP_CLOCK; 5016 5017 ASSERT(sih->cccaps & CC_CAP_PMU); 5018 5019 /* Remember original core before switch to chipc */ 5020 origidx = si_coreidx(sih); 5021 cc = si_setcoreidx(sih, SI_CC_IDX); 5022 ASSERT(cc != NULL); 5023 5024 switch (CHIPID(sih->chip)) { 5025 case BCM4328_CHIP_ID: 5026 clock = si_pmu0_alpclk0(sih, osh, cc); 5027 break; 5028 case BCM5354_CHIP_ID: 5029 clock = si_pmu0_alpclk0(sih, osh, cc); 5030 break; 5031 case BCM4325_CHIP_ID: 5032 clock = si_pmu1_alpclk0(sih, osh, cc); 5033 break; 5034 case BCM4360_CHIP_ID: 5035 case BCM43460_CHIP_ID: 5036 case BCM4352_CHIP_ID: 5037 case BCM43526_CHIP_ID: 5038 if (sih->chipst & CST4360_XTAL_40MZ) 5039 clock = 40000 * 1000; 5040 else 5041 clock = 20000 * 1000; 5042 break; 5043 5044 5045 case BCM4312_CHIP_ID: 5046 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 5047 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 5048 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43420_CHIP_ID: 5049 case BCM43421_CHIP_ID: 5050 case BCM43226_CHIP_ID: 5051 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 5052 case BCM43237_CHIP_ID: case BCM43239_CHIP_ID: 5053 case BCM43234_CHIP_ID: 5054 case BCM4331_CHIP_ID: 5055 case BCM43431_CHIP_ID: 5056 case BCM43131_CHIP_ID: 5057 case BCM43217_CHIP_ID: 5058 case BCM43227_CHIP_ID: 5059 case BCM43228_CHIP_ID: 5060 case BCM43428_CHIP_ID: 5061 case BCM6362_CHIP_ID: 5062 case BCM4342_CHIP_ID: 5063 case BCM4716_CHIP_ID: 5064 case BCM4748_CHIP_ID: 5065 case BCM47162_CHIP_ID: 5066 case BCM4313_CHIP_ID: 5067 case BCM5357_CHIP_ID: 5068 case BCM4749_CHIP_ID: 5069 case BCM53572_CHIP_ID: 5070 /* always 20Mhz */ 5071 clock = 20000 * 1000; 5072 break; 5073 case BCM4329_CHIP_ID: 5074 case BCM4315_CHIP_ID: 5075 case BCM4319_CHIP_ID: 5076 case BCM4336_CHIP_ID: 5077 case BCM43362_CHIP_ID: 5078 case BCM4330_CHIP_ID: 5079 case BCM4324_CHIP_ID: 5080 case BCM43242_CHIP_ID: 5081 case BCM43243_CHIP_ID: 5082 case BCM4335_CHIP_ID: 5083 case BCM4350_CHIP_ID: 5084 clock = si_pmu1_alpclk0(sih, osh, cc); 5085 break; 5086 case BCM4314_CHIP_ID: 5087 case BCM43142_CHIP_ID: 5088 case BCM43143_CHIP_ID: 5089 case BCM4334_CHIP_ID: 5090 clock = si_pmu2_alpclk0(sih, osh, cc); 5091 break; 5092 case BCM5356_CHIP_ID: 5093 case BCM4706_CHIP_ID: 5094 /* always 25Mhz */ 5095 clock = 25000 * 1000; 5096 break; 5097 default: 5098 PMU_MSG(("No ALP clock specified " 5099 "for chip %s rev %d pmurev %d, using default %d Hz\n", 5100 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev, clock)); 5101 break; 5102 } 5103 5104 /* Return to original core */ 5105 si_setcoreidx(sih, origidx); 5106 return clock; 5107} /* si_pmu_alp_clock */ 5108 5109/** 5110 * Find the output of the "m" pll divider given pll controls that start with 5111 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. 5112 */ 5113static uint32 5114BCMINITFN(si_pmu5_clock)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, uint m) 5115{ 5116 uint32 tmp, div, ndiv, p1, p2, fc; 5117 5118 if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) { 5119 PMU_ERROR(("%s: Bad pll0: %d\n", __FUNCTION__, pll0)); 5120 return 0; 5121 } 5122 5123 5124 /* Strictly there is an m5 divider, but I'm not sure we use it */ 5125 if ((m == 0) || (m > 4)) { 5126 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__, m)); 5127 return 0; 5128 } 5129 5130 if ((CHIPID(sih->chip) == BCM5357_CHIP_ID) || 5131 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) { 5132 /* Detect failure in clock setting */ 5133 if ((R_REG(osh, &cc->chipstatus) & 0x40000) != 0) { 5134 return (133 * 1000000); 5135 } 5136 } 5137 5138 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF); 5139 (void)R_REG(osh, &cc->pllcontrol_addr); 5140 tmp = R_REG(osh, &cc->pllcontrol_data); 5141 p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT; 5142 p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT; 5143 5144 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF); 5145 (void)R_REG(osh, &cc->pllcontrol_addr); 5146 tmp = R_REG(osh, &cc->pllcontrol_data); 5147 div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK; 5148 5149 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF); 5150 (void)R_REG(osh, &cc->pllcontrol_addr); 5151 tmp = R_REG(osh, &cc->pllcontrol_data); 5152 ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT; 5153 5154 /* Do calculation in Mhz */ 5155 fc = si_pmu_alp_clock(sih, osh) / 1000000; 5156 fc = (p1 * ndiv * fc) / p2; 5157 5158 PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n", 5159 __FUNCTION__, p1, p2, ndiv, ndiv, m, div, fc, fc / div)); 5160 5161 /* Return clock in Hertz */ 5162 return ((fc / div) * 1000000); 5163} /* si_pmu5_clock */ 5164 5165static uint32 5166BCMINITFN(si_4706_pmu_clock)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, uint m) 5167{ 5168 uint32 w, ndiv, p1div, p2div; 5169 uint32 clock; 5170 5171 /* Strictly there is an m5 divider, but I'm not sure we use it */ 5172 if ((m == 0) || (m > 4)) { 5173 PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__, m)); 5174 return 0; 5175 } 5176 5177 /* Get N, P1 and P2 dividers to determine CPU clock */ 5178 W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU6_4706_PROCPLL_OFF); 5179 w = R_REG(NULL, &cc->pllcontrol_data); 5180 ndiv = (w & PMU6_4706_PROC_NDIV_INT_MASK) >> PMU6_4706_PROC_NDIV_INT_SHIFT; 5181 p1div = (w & PMU6_4706_PROC_P1DIV_MASK) >> PMU6_4706_PROC_P1DIV_SHIFT; 5182 p2div = (w & PMU6_4706_PROC_P2DIV_MASK) >> PMU6_4706_PROC_P2DIV_SHIFT; 5183 5184 if (R_REG(osh, &cc->chipstatus) & CST4706_PKG_OPTION) 5185 /* Low cost bonding: Fixed reference clock 25MHz and m = 4 */ 5186 clock = (25000000 / 4) * ndiv * p2div / p1div; 5187 else 5188 /* Fixed reference clock 25MHz and m = 2 */ 5189 clock = (25000000 / 2) * ndiv * p2div / p1div; 5190 5191 if (m == PMU5_MAINPLL_MEM) 5192 clock = clock / 2; 5193 else if (m == PMU5_MAINPLL_SI) 5194 clock = clock / 4; 5195 5196 return clock; 5197} 5198 5199/** 5200 * query backplane clock frequency 5201 * For designs that feed the same clock to both backplane 5202 * and CPU just return the CPU clock speed. 5203 */ 5204uint32 5205BCMINITFN(si_pmu_si_clock)(si_t *sih, osl_t *osh) 5206{ 5207 chipcregs_t *cc; 5208 uint origidx; 5209 uint32 clock = HT_CLOCK; 5210 5211 ASSERT(sih->cccaps & CC_CAP_PMU); 5212 5213 /* Remember original core before switch to chipc */ 5214 origidx = si_coreidx(sih); 5215 cc = si_setcoreidx(sih, SI_CC_IDX); 5216 ASSERT(cc != NULL); 5217 5218 switch (CHIPID(sih->chip)) { 5219 case BCM4328_CHIP_ID: 5220 clock = si_pmu0_cpuclk0(sih, osh, cc); 5221 break; 5222 case BCM5354_CHIP_ID: 5223 clock = 120000000; 5224 break; 5225 case BCM4325_CHIP_ID: 5226 clock = si_pmu1_cpuclk0(sih, osh, cc); 5227 break; 5228 case BCM4322_CHIP_ID: 5229 case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 5230 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 5231 case BCM43224_CHIP_ID: case BCM43420_CHIP_ID: 5232 case BCM43225_CHIP_ID: 5233 case BCM43421_CHIP_ID: 5234 case BCM43226_CHIP_ID: 5235 case BCM4331_CHIP_ID: 5236 case BCM43431_CHIP_ID: 5237 case BCM6362_CHIP_ID: 5238 case BCM4342_CHIP_ID: 5239 /* 96MHz backplane clock */ 5240 clock = 96000 * 1000; 5241 break; 5242 case BCM4716_CHIP_ID: 5243 case BCM4748_CHIP_ID: 5244 case BCM47162_CHIP_ID: 5245 clock = si_pmu5_clock(sih, osh, cc, PMU4716_MAINPLL_PLL0, PMU5_MAINPLL_SI); 5246 break; 5247 case BCM4329_CHIP_ID: 5248 if (CHIPREV(sih->chiprev) == 0) 5249 clock = 38400 * 1000; 5250 else 5251 clock = si_pmu1_cpuclk0(sih, osh, cc); 5252 break; 5253 case BCM4315_CHIP_ID: 5254 case BCM4319_CHIP_ID: 5255 case BCM4336_CHIP_ID: 5256 case BCM43362_CHIP_ID: 5257 case BCM4330_CHIP_ID: 5258 case BCM43239_CHIP_ID: 5259 case BCM4324_CHIP_ID: 5260 case BCM43242_CHIP_ID: 5261 case BCM43243_CHIP_ID: 5262 case BCM4335_CHIP_ID: 5263 case BCM4360_CHIP_ID: 5264 case BCM4350_CHIP_ID: 5265 case BCM43460_CHIP_ID: 5266 case BCM43526_CHIP_ID: 5267 case BCM4352_CHIP_ID: 5268 clock = si_pmu1_cpuclk0(sih, osh, cc); 5269 break; 5270 5271 case BCM4313_CHIP_ID: 5272 /* 80MHz backplane clock */ 5273 clock = 80000 * 1000; 5274 break; 5275 case BCM4314_CHIP_ID: 5276 case BCM43142_CHIP_ID: 5277 case BCM43143_CHIP_ID: /* HT clock and ARM clock have the same frequency */ 5278 case BCM4334_CHIP_ID: 5279 clock = si_pmu2_cpuclk0(sih, osh, cc); 5280 break; 5281 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 5282 case BCM43237_CHIP_ID: 5283 case BCM43234_CHIP_ID: 5284 clock = (cc->chipstatus & CST43236_BP_CLK) ? (120000 * 1000) : (96000 * 1000); 5285 break; 5286 case BCM5356_CHIP_ID: 5287 clock = si_pmu5_clock(sih, osh, cc, PMU5356_MAINPLL_PLL0, PMU5_MAINPLL_SI); 5288 break; 5289 case BCM5357_CHIP_ID: 5290 case BCM4749_CHIP_ID: 5291 clock = si_pmu5_clock(sih, osh, cc, PMU5357_MAINPLL_PLL0, PMU5_MAINPLL_SI); 5292 break; 5293 case BCM53572_CHIP_ID: 5294 clock = 75000000; 5295 break; 5296 case BCM4706_CHIP_ID: 5297 clock = si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_SI); 5298 break; 5299 default: 5300 PMU_MSG(("No backplane clock specified " 5301 "for chip %s rev %d pmurev %d, using default %d Hz\n", 5302 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev, clock)); 5303 break; 5304 } 5305 5306 /* Return to original core */ 5307 si_setcoreidx(sih, origidx); 5308 return clock; 5309} 5310 5311/** query CPU clock frequency */ 5312uint32 5313BCMINITFN(si_pmu_cpu_clock)(si_t *sih, osl_t *osh) 5314{ 5315 chipcregs_t *cc; 5316 uint origidx; 5317 uint32 clock; 5318 5319 ASSERT(sih->cccaps & CC_CAP_PMU); 5320 5321 /* 5354 chip uses a non programmable PLL of frequency 240MHz */ 5322 if (CHIPID(sih->chip) == BCM5354_CHIP_ID) 5323 return 240000000; 5324 5325 if (CHIPID(sih->chip) == BCM53572_CHIP_ID) 5326 return 300000000; 5327 5328 if ((sih->pmurev >= 5) && 5329 !((CHIPID(sih->chip) == BCM4329_CHIP_ID) || 5330 (CHIPID(sih->chip) == BCM4319_CHIP_ID) || 5331 (CHIPID(sih->chip) == BCM43234_CHIP_ID) || 5332 (CHIPID(sih->chip) == BCM43235_CHIP_ID) || 5333 (CHIPID(sih->chip) == BCM43236_CHIP_ID) || 5334 (CHIPID(sih->chip) == BCM43238_CHIP_ID) || 5335 (CHIPID(sih->chip) == BCM43237_CHIP_ID) || 5336 (CHIPID(sih->chip) == BCM43239_CHIP_ID) || 5337 (CHIPID(sih->chip) == BCM4336_CHIP_ID) || 5338 (CHIPID(sih->chip) == BCM43362_CHIP_ID) || 5339 (CHIPID(sih->chip) == BCM4314_CHIP_ID) || 5340 (CHIPID(sih->chip) == BCM43142_CHIP_ID) || 5341 (CHIPID(sih->chip) == BCM43143_CHIP_ID) || 5342 (CHIPID(sih->chip) == BCM4334_CHIP_ID) || 5343 (CHIPID(sih->chip) == BCM4324_CHIP_ID) || 5344 (CHIPID(sih->chip) == BCM43242_CHIP_ID) || 5345 (CHIPID(sih->chip) == BCM43243_CHIP_ID) || 5346 (CHIPID(sih->chip) == BCM4330_CHIP_ID) || 5347 (CHIPID(sih->chip) == BCM4360_CHIP_ID) || 5348 (CHIPID(sih->chip) == BCM43526_CHIP_ID) || 5349 (CHIPID(sih->chip) == BCM43460_CHIP_ID) || 5350 (CHIPID(sih->chip) == BCM4352_CHIP_ID) || 5351 (CHIPID(sih->chip) == BCM4335_CHIP_ID) || 5352 (CHIPID(sih->chip) == BCM4350_CHIP_ID) || 5353 0)) { 5354 uint pll; 5355 5356 switch (CHIPID(sih->chip)) { 5357 case BCM5356_CHIP_ID: 5358 pll = PMU5356_MAINPLL_PLL0; 5359 break; 5360 case BCM5357_CHIP_ID: 5361 case BCM4749_CHIP_ID: 5362 pll = PMU5357_MAINPLL_PLL0; 5363 break; 5364 default: 5365 pll = PMU4716_MAINPLL_PLL0; 5366 break; 5367 } 5368 5369 /* Remember original core before switch to chipc */ 5370 origidx = si_coreidx(sih); 5371 cc = si_setcoreidx(sih, SI_CC_IDX); 5372 ASSERT(cc != NULL); 5373 5374 if (CHIPID(sih->chip) == BCM4706_CHIP_ID) 5375 clock = si_4706_pmu_clock(sih, osh, cc, 5376 PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); 5377 else 5378 clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_CPU); 5379 5380 /* Return to original core */ 5381 si_setcoreidx(sih, origidx); 5382 } else 5383 clock = si_pmu_si_clock(sih, osh); 5384 5385 return clock; 5386} 5387 5388/** query memory clock frequency, which is the same as the HT clock for newer chips */ 5389uint32 5390BCMINITFN(si_pmu_mem_clock)(si_t *sih, osl_t *osh) 5391{ 5392 chipcregs_t *cc; 5393 uint origidx; 5394 uint32 clock; 5395 5396 ASSERT(sih->cccaps & CC_CAP_PMU); 5397 5398 if (CHIPID(sih->chip) == BCM53572_CHIP_ID) 5399 return 150000000; 5400 5401 if ((sih->pmurev >= 5) && 5402 !((CHIPID(sih->chip) == BCM4329_CHIP_ID) || 5403 (CHIPID(sih->chip) == BCM4319_CHIP_ID) || 5404 (CHIPID(sih->chip) == BCM4330_CHIP_ID) || 5405 (CHIPID(sih->chip) == BCM4314_CHIP_ID) || 5406 (CHIPID(sih->chip) == BCM43142_CHIP_ID) || 5407 (CHIPID(sih->chip) == BCM43143_CHIP_ID) || 5408 (CHIPID(sih->chip) == BCM4334_CHIP_ID) || 5409 (CHIPID(sih->chip) == BCM4336_CHIP_ID) || 5410 (CHIPID(sih->chip) == BCM43362_CHIP_ID) || 5411 (CHIPID(sih->chip) == BCM43234_CHIP_ID) || 5412 (CHIPID(sih->chip) == BCM43235_CHIP_ID) || 5413 (CHIPID(sih->chip) == BCM43236_CHIP_ID) || 5414 (CHIPID(sih->chip) == BCM43238_CHIP_ID) || 5415 (CHIPID(sih->chip) == BCM43237_CHIP_ID) || 5416 (CHIPID(sih->chip) == BCM43239_CHIP_ID) || 5417 (CHIPID(sih->chip) == BCM4324_CHIP_ID) || 5418 (CHIPID(sih->chip) == BCM43242_CHIP_ID) || 5419 (CHIPID(sih->chip) == BCM43243_CHIP_ID) || 5420 (CHIPID(sih->chip) == BCM4335_CHIP_ID) || 5421 (CHIPID(sih->chip) == BCM4350_CHIP_ID) || 5422 0)) { 5423 uint pll; 5424 5425 switch (CHIPID(sih->chip)) { 5426 case BCM5356_CHIP_ID: 5427 pll = PMU5356_MAINPLL_PLL0; 5428 break; 5429 case BCM5357_CHIP_ID: 5430 case BCM4749_CHIP_ID: 5431 pll = PMU5357_MAINPLL_PLL0; 5432 break; 5433 default: 5434 pll = PMU4716_MAINPLL_PLL0; 5435 break; 5436 } 5437 5438 /* Remember original core before switch to chipc */ 5439 origidx = si_coreidx(sih); 5440 cc = si_setcoreidx(sih, SI_CC_IDX); 5441 ASSERT(cc != NULL); 5442 5443 if (CHIPID(sih->chip) == BCM4706_CHIP_ID) 5444 clock = si_4706_pmu_clock(sih, osh, cc, 5445 PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_MEM); 5446 else 5447 clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_MEM); 5448 5449 /* Return to original core */ 5450 si_setcoreidx(sih, origidx); 5451 } else { 5452 clock = si_pmu_si_clock(sih, osh); 5453 } 5454 5455 return clock; 5456} 5457 5458/* Measure ILP clock frequency */ 5459#define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */ 5460 5461static uint32 ilpcycles_per_sec = 0; 5462 5463uint32 5464BCMINITFN(si_pmu_ilp_clock)(si_t *sih, osl_t *osh) 5465{ 5466 if (ISSIM_ENAB(sih)) 5467 return ILP_CLOCK; 5468 5469 if (ilpcycles_per_sec == 0) { 5470 uint32 start, end, delta; 5471 uint32 origidx = si_coreidx(sih); 5472 chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX); 5473 ASSERT(cc != NULL); 5474 start = R_REG(osh, &cc->pmutimer); 5475 if (start != R_REG(osh, &cc->pmutimer)) 5476 start = R_REG(osh, &cc->pmutimer); 5477 OSL_DELAY(ILP_CALC_DUR * 1000); 5478 end = R_REG(osh, &cc->pmutimer); 5479 if (end != R_REG(osh, &cc->pmutimer)) 5480 end = R_REG(osh, &cc->pmutimer); 5481 delta = end - start; 5482 ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); 5483 si_setcoreidx(sih, origidx); 5484 } 5485 5486 return ilpcycles_per_sec; 5487} 5488 5489/* SDIO Pad drive strength to select value mappings. 5490 * The last strength value in each table must be 0 (the tri-state value). 5491 */ 5492typedef struct { 5493 uint8 strength; /* Pad Drive Strength in mA */ 5494 uint8 sel; /* Chip-specific select value */ 5495} sdiod_drive_str_t; 5496 5497/* SDIO Drive Strength to sel value table for PMU Rev 1 */ 5498static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab1)[] = { 5499 {4, 0x2}, 5500 {2, 0x3}, 5501 {1, 0x0}, 5502 {0, 0x0} }; 5503 5504/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ 5505static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab2)[] = { 5506 {12, 0x7}, 5507 {10, 0x6}, 5508 {8, 0x5}, 5509 {6, 0x4}, 5510 {4, 0x2}, 5511 {2, 0x1}, 5512 {0, 0x0} }; 5513 5514/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ 5515static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab3)[] = { 5516 {32, 0x7}, 5517 {26, 0x6}, 5518 {22, 0x5}, 5519 {16, 0x4}, 5520 {12, 0x3}, 5521 {8, 0x2}, 5522 {4, 0x1}, 5523 {0, 0x0} }; 5524 5525/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8v) */ 5526static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab4_1v8)[] = { 5527 {32, 0x6}, 5528 {26, 0x7}, 5529 {22, 0x4}, 5530 {16, 0x5}, 5531 {12, 0x2}, 5532 {8, 0x3}, 5533 {4, 0x0}, 5534 {0, 0x1} }; 5535 5536/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.2v) */ 5537 5538/* SDIO Drive Strength to sel value table for PMU Rev 11 (2.5v) */ 5539 5540/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */ 5541static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab5_1v8)[] = { 5542 {6, 0x7}, 5543 {5, 0x6}, 5544 {4, 0x5}, 5545 {3, 0x4}, 5546 {2, 0x2}, 5547 {1, 0x1}, 5548 {0, 0x0} }; 5549 5550/* SDIO Drive Strength to sel value table for PMU Rev 13 (3.3v) */ 5551 5552 5553#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 5554 5555/** 5556 * Balance between stable SDIO operation and power consumption is achieved using this function. 5557 * Note that each drive strength table is for a specific VDDIO of the SDIO pads, ideally this 5558 * function should read the VDDIO itself to select the correct table. For now it has been solved 5559 * with the 'BCM_SDIO_VDDIO' preprocessor constant. 5560 * 5561 * 'drivestrength': desired pad drive strength in mA. Drive strength of 0 requests tri-state (if 5562 * hardware supports this), if no hw support drive strength is not programmed. 5563 */ 5564void 5565BCMINITFN(si_sdiod_drive_strength_init)(si_t *sih, osl_t *osh, uint32 drivestrength) 5566{ 5567 chipcregs_t *cc; 5568 uint origidx, intr_val = 0; 5569 sdiod_drive_str_t *str_tab = NULL; 5570 uint32 str_mask = 0; 5571 uint32 str_shift = 0; 5572 5573 if (!(sih->cccaps & CC_CAP_PMU)) { 5574 return; 5575 } 5576 5577 /* Remember original core before switch to chipc */ 5578 cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 5579 5580 switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { 5581 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): 5582 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; 5583 str_mask = 0x30000000; 5584 str_shift = 28; 5585 break; 5586 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): 5587 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): 5588 case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4): 5589 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; 5590 str_mask = 0x00003800; 5591 str_shift = 11; 5592 break; 5593 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): 5594 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 11): 5595 if (sih->pmurev == 8) { 5596 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab3; 5597 } 5598 else if (sih->pmurev == 11) { 5599 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8; 5600 } 5601 str_mask = 0x00003800; 5602 str_shift = 11; 5603 break; 5604 case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): 5605 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8; 5606 str_mask = 0x00003800; 5607 str_shift = 11; 5608 break; 5609 case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): 5610 str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab5_1v8; 5611 str_mask = 0x00003800; 5612 str_shift = 11; 5613 break; 5614 default: 5615 PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", 5616 bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); 5617 5618 break; 5619 } 5620 5621 if (str_tab != NULL && cc != NULL) { 5622 uint32 cc_data_temp; 5623 int i; 5624 5625 /* Pick the lowest available drive strength equal or greater than the 5626 * requested strength. Drive strength of 0 requests tri-state. 5627 */ 5628 for (i = 0; drivestrength < str_tab[i].strength; i++) 5629 ; 5630 5631 if (i > 0 && drivestrength > str_tab[i].strength) 5632 i--; 5633 5634 W_REG(osh, &cc->chipcontrol_addr, 1); 5635 cc_data_temp = R_REG(osh, &cc->chipcontrol_data); 5636 cc_data_temp &= ~str_mask; 5637 cc_data_temp |= str_tab[i].sel << str_shift; 5638 W_REG(osh, &cc->chipcontrol_data, cc_data_temp); 5639 5640 PMU_MSG(("SDIO: %dmA drive strength requested; set to %dmA\n", 5641 drivestrength, str_tab[i].strength)); 5642 } 5643 5644 /* Return to original core */ 5645 si_restore_core(sih, origidx, intr_val); 5646} /* si_sdiod_drive_strength_init */ 5647 5648/* initialize PMU */ 5649void 5650BCMATTACHFN(si_pmu_init)(si_t *sih, osl_t *osh) 5651{ 5652 chipcregs_t *cc; 5653 uint origidx; 5654 5655 ASSERT(sih->cccaps & CC_CAP_PMU); 5656 5657 /* Remember original core before switch to chipc */ 5658 origidx = si_coreidx(sih); 5659 cc = si_setcoreidx(sih, SI_CC_IDX); 5660 ASSERT(cc != NULL); 5661 5662 if (sih->pmurev == 1) 5663 AND_REG(osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); 5664 else if (sih->pmurev >= 2) 5665 OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT); 5666 5667 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 2)) { 5668 /* Fix for 4329b0 bad LPOM state. */ 5669 W_REG(osh, &cc->regcontrol_addr, 2); 5670 OR_REG(osh, &cc->regcontrol_data, 0x100); 5671 5672 W_REG(osh, &cc->regcontrol_addr, 3); 5673 OR_REG(osh, &cc->regcontrol_data, 0x4); 5674 } 5675#if defined(PMU_OPT_REV6) 5676 else if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) && (CHIPREV(sih->chiprev) >= 2)) { 5677 /* Fine control CBUCK's LPOM/AUTO/PWM modes 5678 * http://hwnbu-twiki.sj.broadcom.com/bin/view/Mwgroup/ 5679 * ToplevelArchitecture4335C0#PMU_VREG_Control_Registers_0x180 5680 * mini-PMU => PWM 5681 * PHY PWRSW Pending => LPOM 5682 * Rest all are AUTO 5683 */ 5684 si_pmu_regcontrol(sih, REGCTRLREG6, REGCTRL6_PWM_AUTO_CTRL_MASK, 5685 (0xAA6 << REGCTRL6_PWM_AUTO_CTRL_SHIFT)); 5686 si_pmu_regcontrol(sih, REGCTRLREG5, REGCTRL5_PWM_AUTO_CTRL_MASK, 5687 (0x2A << REGCTRL5_PWM_AUTO_CTRL_SHIFT)); 5688 5689 /* Enable Fine PWM/AUTO/LPOM control (bit 30=0x1) */ 5690 si_pmu_regcontrol(sih, REGCTRLREG6, ENABLE_FINE_CBUCK_CTRL, ENABLE_FINE_CBUCK_CTRL); 5691 } 5692#endif /* defined(PMU_OPT_REV6) */ 5693 5694 /* Return to original core */ 5695 si_setcoreidx(sih, origidx); 5696} 5697 5698static uint 5699BCMINITFN(si_pmu_res_uptime)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 rsrc) 5700{ 5701 uint32 deps; 5702 uint uptime, i, dup, dmax; 5703 uint32 min_mask = 0, max_mask = 0; 5704 5705 /* uptime of resource 'rsrc' */ 5706 W_REG(osh, &cc->res_table_sel, rsrc); 5707 if (sih->pmurev >= 13) 5708 uptime = (R_REG(osh, &cc->res_updn_timer) >> 16) & 0x3ff; 5709 else 5710 uptime = (R_REG(osh, &cc->res_updn_timer) >> 8) & 0xff; 5711 5712 /* direct dependencies of resource 'rsrc' */ 5713 deps = si_pmu_res_deps(sih, osh, cc, PMURES_BIT(rsrc), FALSE); 5714 for (i = 0; i <= PMURES_MAX_RESNUM; i ++) { 5715 if (!(deps & PMURES_BIT(i))) 5716 continue; 5717 deps &= ~si_pmu_res_deps(sih, osh, cc, PMURES_BIT(i), TRUE); 5718 } 5719 si_pmu_res_masks(sih, &min_mask, &max_mask); 5720 deps &= ~min_mask; 5721 5722 /* max uptime of direct dependencies */ 5723 dmax = 0; 5724 for (i = 0; i <= PMURES_MAX_RESNUM; i ++) { 5725 if (!(deps & PMURES_BIT(i))) 5726 continue; 5727 dup = si_pmu_res_uptime(sih, osh, cc, (uint8)i); 5728 if (dmax < dup) 5729 dmax = dup; 5730 } 5731 5732 PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n", 5733 rsrc, uptime, deps, dmax)); 5734 5735 return uptime + dmax + PMURES_UP_TRANSITION; 5736} 5737 5738/* Return dependencies (direct or all/indirect) for the given resources */ 5739static uint32 5740si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs, bool all) 5741{ 5742 uint32 deps = 0; 5743 uint32 i; 5744 5745 for (i = 0; i <= PMURES_MAX_RESNUM; i ++) { 5746 if (!(rsrcs & PMURES_BIT(i))) 5747 continue; 5748 W_REG(osh, &cc->res_table_sel, i); 5749 deps |= R_REG(osh, &cc->res_dep_mask); 5750 } 5751 5752 return !all ? deps : (deps ? (deps | si_pmu_res_deps(sih, osh, cc, deps, TRUE)) : 0); 5753} 5754 5755/** 5756 * OTP is powered down/up as a means of resetting it, or for saving current when OTP is unused. 5757 * OTP is powered up/down through PMU resources. 5758 */ 5759void 5760si_pmu_otp_power(si_t *sih, osl_t *osh, bool on) 5761{ 5762 chipcregs_t *cc; 5763 uint origidx; 5764 uint32 rsrcs = 0; /* rsrcs to turn on/off OTP power */ 5765 5766 ASSERT(sih->cccaps & CC_CAP_PMU); 5767 5768 /* Don't do anything if OTP is disabled */ 5769 if (si_is_otp_disabled(sih)) { 5770 PMU_MSG(("si_pmu_otp_power: OTP is disabled\n")); 5771 return; 5772 } 5773 5774 /* Remember original core before switch to chipc */ 5775 origidx = si_coreidx(sih); 5776 cc = si_setcoreidx(sih, SI_CC_IDX); 5777 ASSERT(cc != NULL); 5778 5779 switch (CHIPID(sih->chip)) { 5780 case BCM4322_CHIP_ID: 5781 case BCM43221_CHIP_ID: 5782 case BCM43231_CHIP_ID: 5783 case BCM4342_CHIP_ID: 5784 rsrcs = PMURES_BIT(RES4322_OTP_PU); 5785 break; 5786 case BCM4325_CHIP_ID: 5787 rsrcs = PMURES_BIT(RES4325_OTP_PU); 5788 break; 5789 case BCM4315_CHIP_ID: 5790 rsrcs = PMURES_BIT(RES4315_OTP_PU); 5791 break; 5792 case BCM4329_CHIP_ID: 5793 rsrcs = PMURES_BIT(RES4329_OTP_PU); 5794 break; 5795 case BCM4319_CHIP_ID: 5796 rsrcs = PMURES_BIT(RES4319_OTP_PU); 5797 break; 5798 case BCM4336_CHIP_ID: 5799 case BCM43362_CHIP_ID: 5800 rsrcs = PMURES_BIT(RES4336_OTP_PU); 5801 break; 5802 case BCM4330_CHIP_ID: 5803 rsrcs = PMURES_BIT(RES4330_OTP_PU); 5804 break; 5805 case BCM4314_CHIP_ID: 5806 case BCM43142_CHIP_ID: 5807 rsrcs = PMURES_BIT(RES4314_OTP_PU); 5808 break; 5809 case BCM43143_CHIP_ID: 5810 rsrcs = PMURES_BIT(RES43143_OTP_PU); 5811 break; 5812 case BCM4334_CHIP_ID: 5813 rsrcs = PMURES_BIT(RES4334_OTP_PU); 5814 break; 5815 case BCM4324_CHIP_ID: 5816 case BCM43242_CHIP_ID: 5817 case BCM43243_CHIP_ID: 5818 rsrcs = PMURES_BIT(RES4324_OTP_PU); 5819 break; 5820 case BCM4335_CHIP_ID: 5821 rsrcs = PMURES_BIT(RES4335_OTP_PU); 5822 break; 5823 case BCM4350_CHIP_ID: 5824 rsrcs = PMURES_BIT(RES4350_OTP_PU); 5825 break; 5826 case BCM4360_CHIP_ID: 5827 case BCM43460_CHIP_ID: 5828 case BCM4352_CHIP_ID: 5829 case BCM43526_CHIP_ID: 5830 rsrcs = PMURES_BIT(RES4360_OTP_PU); 5831 break; 5832 default: 5833 break; 5834 } 5835 5836 if (rsrcs != 0) { 5837 uint32 otps; 5838 5839 /* Figure out the dependencies (exclude min_res_mask) */ 5840 uint32 deps = si_pmu_res_deps(sih, osh, cc, rsrcs, TRUE); 5841 uint32 min_mask = 0, max_mask = 0; 5842 si_pmu_res_masks(sih, &min_mask, &max_mask); 5843 deps &= ~min_mask; 5844 /* Turn on/off the power */ 5845 if (on) { 5846 PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", rsrcs | deps)); 5847 OR_REG(osh, &cc->min_res_mask, (rsrcs | deps)); 5848 OSL_DELAY(1000); 5849 SPINWAIT(!(R_REG(osh, &cc->res_state) & rsrcs), PMU_MAX_TRANSITION_DLY); 5850 ASSERT(R_REG(osh, &cc->res_state) & rsrcs); 5851 } 5852 else { 5853 PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", rsrcs | deps)); 5854 AND_REG(osh, &cc->min_res_mask, ~(rsrcs | deps)); 5855 } 5856 5857 SPINWAIT((((otps = R_REG(osh, &cc->otpstatus)) & OTPS_READY) != 5858 (on ? OTPS_READY : 0)), 3000); 5859 ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0)); 5860 if ((otps & OTPS_READY) != (on ? OTPS_READY : 0)) 5861 PMU_MSG(("OTP ready bit not %s after wait\n", (on ? "ON" : "OFF"))); 5862 } 5863 5864 /* Return to original core */ 5865 si_setcoreidx(sih, origidx); 5866} /* si_pmu_otp_power */ 5867 5868/** only called for SSN and LP phy's. */ 5869void 5870si_pmu_rcal(si_t *sih, osl_t *osh) 5871{ 5872 chipcregs_t *cc; 5873 uint origidx; 5874 uint rcal_done, BT_out_of_reset; 5875 5876 ASSERT(sih->cccaps & CC_CAP_PMU); 5877 5878 /* Remember original core before switch to chipc */ 5879 origidx = si_coreidx(sih); 5880 cc = si_setcoreidx(sih, SI_CC_IDX); 5881 ASSERT(cc != NULL); 5882 5883 switch (CHIPID(sih->chip)) { 5884 case BCM4325_CHIP_ID: { 5885 uint8 rcal_code; 5886 uint32 val; 5887 5888 /* Kick RCal */ 5889 W_REG(osh, &cc->chipcontrol_addr, 1); 5890 5891 /* Power Down RCAL Block */ 5892 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 5893 5894 /* Check if RCAL is already done by BT */ 5895 rcal_done = ((R_REG(osh, &cc->chipstatus)) & 0x8) >> 3; 5896 5897 /* If RCAL already done, note that BT is out of reset */ 5898 if (rcal_done == 1) { 5899 BT_out_of_reset = 1; 5900 } else { 5901 BT_out_of_reset = 0; 5902 } 5903 5904 /* Power Up RCAL block */ 5905 OR_REG(osh, &cc->chipcontrol_data, 0x04); 5906 5907 /* Wait for completion */ 5908 SPINWAIT(!(R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000); 5909 ASSERT(R_REG(osh, &cc->chipstatus) & 0x08); 5910 5911 if (BT_out_of_reset) { 5912 rcal_code = 0x6; 5913 } else { 5914 /* Drop the LSB to convert from 5 bit code to 4 bit code */ 5915 rcal_code = (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f; 5916 } 5917 5918 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", 5919 R_REG(osh, &cc->chipstatus), rcal_code)); 5920 5921 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 5922 W_REG(osh, &cc->regcontrol_addr, 0); 5923 val = R_REG(osh, &cc->regcontrol_data) & ~((uint32)0x07 << 29); 5924 val |= (uint32)(rcal_code & 0x07) << 29; 5925 W_REG(osh, &cc->regcontrol_data, val); 5926 W_REG(osh, &cc->regcontrol_addr, 1); 5927 val = R_REG(osh, &cc->regcontrol_data) & ~(uint32)0x01; 5928 val |= (uint32)((rcal_code >> 3) & 0x01); 5929 W_REG(osh, &cc->regcontrol_data, val); 5930 5931 /* Write RCal code into pmu_chip_ctrl[33:30] */ 5932 W_REG(osh, &cc->chipcontrol_addr, 0); 5933 val = R_REG(osh, &cc->chipcontrol_data) & ~((uint32)0x03 << 30); 5934 val |= (uint32)(rcal_code & 0x03) << 30; 5935 W_REG(osh, &cc->chipcontrol_data, val); 5936 W_REG(osh, &cc->chipcontrol_addr, 1); 5937 val = R_REG(osh, &cc->chipcontrol_data) & ~(uint32)0x03; 5938 val |= (uint32)((rcal_code >> 2) & 0x03); 5939 W_REG(osh, &cc->chipcontrol_data, val); 5940 5941 /* Set override in pmu_chip_ctrl[29] */ 5942 W_REG(osh, &cc->chipcontrol_addr, 0); 5943 OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29)); 5944 5945 /* Power off RCal block */ 5946 W_REG(osh, &cc->chipcontrol_addr, 1); 5947 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 5948 5949 break; 5950 } 5951 case BCM4329_CHIP_ID: { 5952 uint8 rcal_code; 5953 uint32 val; 5954 5955 /* Kick RCal */ 5956 W_REG(osh, &cc->chipcontrol_addr, 1); 5957 5958 /* Power Down RCAL Block */ 5959 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 5960 5961 /* Power Up RCAL block */ 5962 OR_REG(osh, &cc->chipcontrol_data, 0x04); 5963 5964 /* Wait for completion */ 5965 SPINWAIT(!(R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000); 5966 ASSERT(R_REG(osh, &cc->chipstatus) & 0x08); 5967 5968 /* Drop the LSB to convert from 5 bit code to 4 bit code */ 5969 rcal_code = (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f; 5970 5971 PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", 5972 R_REG(osh, &cc->chipstatus), rcal_code)); 5973 5974 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 5975 W_REG(osh, &cc->regcontrol_addr, 0); 5976 val = R_REG(osh, &cc->regcontrol_data) & ~((uint32)0x07 << 29); 5977 val |= (uint32)(rcal_code & 0x07) << 29; 5978 W_REG(osh, &cc->regcontrol_data, val); 5979 W_REG(osh, &cc->regcontrol_addr, 1); 5980 val = R_REG(osh, &cc->regcontrol_data) & ~(uint32)0x01; 5981 val |= (uint32)((rcal_code >> 3) & 0x01); 5982 W_REG(osh, &cc->regcontrol_data, val); 5983 5984 /* Write RCal code into pmu_chip_ctrl[33:30] */ 5985 W_REG(osh, &cc->chipcontrol_addr, 0); 5986 val = R_REG(osh, &cc->chipcontrol_data) & ~((uint32)0x03 << 30); 5987 val |= (uint32)(rcal_code & 0x03) << 30; 5988 W_REG(osh, &cc->chipcontrol_data, val); 5989 W_REG(osh, &cc->chipcontrol_addr, 1); 5990 val = R_REG(osh, &cc->chipcontrol_data) & ~(uint32)0x03; 5991 val |= (uint32)((rcal_code >> 2) & 0x03); 5992 W_REG(osh, &cc->chipcontrol_data, val); 5993 5994 /* Set override in pmu_chip_ctrl[29] */ 5995 W_REG(osh, &cc->chipcontrol_addr, 0); 5996 OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29)); 5997 5998 /* Power off RCal block */ 5999 W_REG(osh, &cc->chipcontrol_addr, 1); 6000 AND_REG(osh, &cc->chipcontrol_data, ~0x04); 6001 6002 break; 6003 } 6004 default: 6005 break; 6006 } 6007 6008 /* Return to original core */ 6009 si_setcoreidx(sih, origidx); 6010} /* si_pmu_rcal */ 6011 6012/** only called for HT, LCN and N phy's. */ 6013void 6014si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid) 6015{ 6016 chipcregs_t *cc; 6017 uint origidx, intr_val; 6018 uint32 min_res_mask = 0, max_res_mask = 0, clk_ctl_st = 0; 6019 bool pll_off_on = FALSE; 6020 6021 ASSERT(CHIPID(sih->chip) != BCM43143_CHIP_ID); /* LCN40 PHY */ 6022 6023#ifdef BCMUSBDEV_ENABLED 6024 if ((CHIPID(sih->chip) == BCM4324_CHIP_ID) && (CHIPREV(sih->chiprev) <= 2)) { 6025 return; 6026 } 6027 /* spuravoid is not ready for 43242 */ 6028 if ((CHIPID(sih->chip) == BCM43242_CHIP_ID) || (CHIPID(sih->chip) == BCM43243_CHIP_ID)) { 6029 return; 6030 } 6031#endif 6032 6033 if ((CHIPID(sih->chip) == BCM4336_CHIP_ID) || 6034 (CHIPID(sih->chip) == BCM43362_CHIP_ID) || 6035 (CHIPID(sih->chip) == BCM43239_CHIP_ID) || 6036 (CHIPID(sih->chip) == BCM4314_CHIP_ID) || 6037 (CHIPID(sih->chip) == BCM43142_CHIP_ID) || 6038 (CHIPID(sih->chip) == BCM4334_CHIP_ID) || 6039 (CHIPID(sih->chip) == BCM43242_CHIP_ID) || 6040 (CHIPID(sih->chip) == BCM43243_CHIP_ID) || 6041 (CHIPID(sih->chip) == BCM4335_CHIP_ID) || 6042 (CHIPID(sih->chip) == BCM4330_CHIP_ID)) 6043 { 6044 pll_off_on = TRUE; 6045 } 6046 6047 /* Remember original core before switch to chipc */ 6048 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 6049 ASSERT(cc != NULL); 6050 6051 /* force the HT off */ 6052 if (pll_off_on) 6053 si_pmu_pll_off(sih, osh, cc, &min_res_mask, &max_res_mask, &clk_ctl_st); 6054 6055 /* update the pll changes */ 6056 si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid); 6057 6058 /* enable HT back on */ 6059 if (pll_off_on) 6060 si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st); 6061 6062 /* Return to original core */ 6063 si_restore_core(sih, origidx, intr_val); 6064} /* si_pmu_spuravoid */ 6065 6066/* below function are only for BBPLL parallel purpose */ 6067/** only called for HT, LCN and N phy's. */ 6068void 6069si_pmu_spuravoid_isdone(si_t *sih, osl_t *osh, uint32 min_res_mask, 6070uint32 max_res_mask, uint32 clk_ctl_st, uint8 spuravoid) 6071{ 6072 6073 chipcregs_t *cc; 6074 uint origidx, intr_val; 6075 bool pll_off_on = FALSE; 6076 6077 ASSERT(CHIPID(sih->chip) != BCM43143_CHIP_ID); /* LCN40 PHY */ 6078 6079#ifdef BCMUSBDEV_ENABLED 6080 if ((CHIPID(sih->chip) == BCM4324_CHIP_ID) && (CHIPREV(sih->chiprev) <= 2)) { 6081 return; 6082 } 6083 /* spuravoid is not ready for 43242 */ 6084 if ((CHIPID(sih->chip) == BCM43242_CHIP_ID) || (CHIPID(sih->chip) == BCM43243_CHIP_ID)) { 6085 return; 6086 } 6087#endif 6088 6089 if ((CHIPID(sih->chip) == BCM4336_CHIP_ID) || 6090 (CHIPID(sih->chip) == BCM43362_CHIP_ID) || 6091 (CHIPID(sih->chip) == BCM43239_CHIP_ID) || 6092 (CHIPID(sih->chip) == BCM4314_CHIP_ID) || 6093 (CHIPID(sih->chip) == BCM43142_CHIP_ID) || 6094 (CHIPID(sih->chip) == BCM4334_CHIP_ID) || 6095 (CHIPID(sih->chip) == BCM43242_CHIP_ID) || 6096 (CHIPID(sih->chip) == BCM43243_CHIP_ID) || 6097 (CHIPID(sih->chip) == BCM4335_CHIP_ID) || 6098 (CHIPID(sih->chip) == BCM4330_CHIP_ID)) 6099 { 6100 pll_off_on = TRUE; 6101 } 6102 /* Remember original core before switch to chipc */ 6103 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 6104 ASSERT(cc != NULL); 6105 6106 if (pll_off_on) 6107 si_pmu_pll_off_isdone(sih, osh, cc); 6108 /* update the pll changes */ 6109 si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid); 6110 6111 /* enable HT back on */ 6112 if (pll_off_on) 6113 si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st); 6114 6115 /* Return to original core */ 6116 si_restore_core(sih, origidx, intr_val); 6117} /* si_pmu_spuravoid_isdone */ 6118 6119/* below function are only for BBPLL parallel purpose */ 6120 6121/* For having the pllcontrol data values for spuravoid */ 6122typedef struct { 6123 uint8 spuravoid_mode; 6124 uint8 pllctrl_reg; 6125 uint32 pllctrl_regval; 6126} pllctrl_spuravoid_t; 6127 6128/* LCNXN */ 6129/* PLL Settings for spur avoidance on/off mode */ 6130static const pllctrl_spuravoid_t spuravoid_4324[] = { 6131 {1, PMU1_PLL0_PLLCTL0, 0xA7400040}, 6132 {1, PMU1_PLL0_PLLCTL1, 0x10080706}, 6133 {1, PMU1_PLL0_PLLCTL2, 0x0D311408}, 6134 {1, PMU1_PLL0_PLLCTL3, 0x804F66AC}, 6135 {1, PMU1_PLL0_PLLCTL4, 0x02600004}, 6136 {1, PMU1_PLL0_PLLCTL5, 0x00019AB1}, 6137 6138 {2, PMU1_PLL0_PLLCTL0, 0xA7400040}, 6139 {2, PMU1_PLL0_PLLCTL1, 0x10080706}, 6140 {2, PMU1_PLL0_PLLCTL2, 0x0D311408}, 6141 {2, PMU1_PLL0_PLLCTL3, 0x80F3ADDC}, 6142 {2, PMU1_PLL0_PLLCTL4, 0x02600004}, 6143 {2, PMU1_PLL0_PLLCTL5, 0x00019AB1}, 6144 6145 {0, PMU1_PLL0_PLLCTL0, 0xA7400040}, 6146 {0, PMU1_PLL0_PLLCTL1, 0x10080706}, 6147 {0, PMU1_PLL0_PLLCTL2, 0x0CB11408}, 6148 {0, PMU1_PLL0_PLLCTL3, 0x80AB1F7C}, 6149 {0, PMU1_PLL0_PLLCTL4, 0x02600004}, 6150 {0, PMU1_PLL0_PLLCTL5, 0x00019AB1} 6151}; 6152 6153static void 6154si_pmu_pllctrl_spurupdate(osl_t *osh, chipcregs_t *cc, uint8 spuravoid, 6155 const pllctrl_spuravoid_t *pllctrl_spur, uint32 array_size) 6156{ 6157 uint8 indx; 6158 for (indx = 0; indx < array_size; indx++) { 6159 if (pllctrl_spur[indx].spuravoid_mode == spuravoid) { 6160 W_REG(osh, &cc->pllcontrol_addr, pllctrl_spur[indx].pllctrl_reg); 6161 W_REG(osh, &cc->pllcontrol_data, pllctrl_spur[indx].pllctrl_regval); 6162 } 6163 } 6164} 6165 6166static void 6167si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, uint8 spuravoid) 6168{ 6169 uint32 tmp = 0; 6170 uint32 xtal_freq, reg_val, mxdiv, ndiv_int, ndiv_frac_int, part_mul; 6171 uint8 p1_div, p2_div, FCLkx; 6172 const pmu1_xtaltab0_t *params_tbl; 6173 6174 ASSERT(CHIPID(sih->chip) != BCM43143_CHIP_ID); /* LCN40 PHY */ 6175 6176 switch (CHIPID(sih->chip)) { 6177 case BCM4324_CHIP_ID: 6178 /* If we get an invalid spurmode, then set the spur0 settings. */ 6179 if (spuravoid > 2) 6180 spuravoid = 0; 6181 6182 si_pmu_pllctrl_spurupdate(osh, cc, spuravoid, spuravoid_4324, 6183 ARRAYSIZE(spuravoid_4324)); 6184 6185 tmp = PCTL_PLL_PLLCTL_UPD; 6186 break; 6187 6188 case BCM5357_CHIP_ID: case BCM4749_CHIP_ID: 6189 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 6190 case BCM43237_CHIP_ID: 6191 case BCM43234_CHIP_ID: 6192 case BCM6362_CHIP_ID: 6193 case BCM53572_CHIP_ID: 6194 6195 if ((CHIPID(sih->chip) == BCM6362_CHIP_ID) && (sih->chiprev == 0)) { 6196 /* 6362a0 (same clks as 4322[4-6]) */ 6197 if (spuravoid == 1) { 6198 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6199 W_REG(osh, &cc->pllcontrol_data, 0x11500010); 6200 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6201 W_REG(osh, &cc->pllcontrol_data, 0x000C0C06); 6202 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6203 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 6204 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6205 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6206 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6207 W_REG(osh, &cc->pllcontrol_data, 0x2001E920); 6208 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6209 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6210 } else { 6211 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6212 W_REG(osh, &cc->pllcontrol_data, 0x11100010); 6213 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6214 W_REG(osh, &cc->pllcontrol_data, 0x000c0c06); 6215 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6216 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 6217 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6218 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6219 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6220 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 6221 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6222 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6223 } 6224 6225 } else { 6226 /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */ 6227 const uint8 phypll_offset = ((CHIPID(sih->chip) == BCM5357_CHIP_ID) || 6228 (CHIPID(sih->chip) == BCM4749_CHIP_ID) || 6229 (CHIPID(sih->chip) == BCM53572_CHIP_ID)) 6230 ? 6 : 0; 6231 const uint8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5}; 6232 const uint8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc}; 6233 6234 /* 5357[ab]0, 43236[ab]0, and 6362b0 */ 6235 if (spuravoid > 2) 6236 spuravoid = 0; 6237 6238 /* RMW only the P1 divider */ 6239 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0 + phypll_offset); 6240 tmp = R_REG(osh, &cc->pllcontrol_data); 6241 tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK)); 6242 tmp |= (bcm5357_bcm43236_p1div[spuravoid] << PMU1_PLL0_PC0_P1DIV_SHIFT); 6243 W_REG(osh, &cc->pllcontrol_data, tmp); 6244 6245 /* RMW only the int feedback divider */ 6246 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2 + phypll_offset); 6247 tmp = R_REG(osh, &cc->pllcontrol_data); 6248 tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK); 6249 tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << PMU1_PLL0_PC2_NDIV_INT_SHIFT; 6250 W_REG(osh, &cc->pllcontrol_data, tmp); 6251 } 6252 6253 tmp = 1 << 10; 6254 break; 6255 6256 case BCM4331_CHIP_ID: 6257 case BCM43431_CHIP_ID: 6258 if (ISSIM_ENAB(sih)) { 6259 if (spuravoid == 2) { 6260 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6261 W_REG(osh, &cc->pllcontrol_data, 0x00000002); 6262 } else if (spuravoid == 1) { 6263 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6264 W_REG(osh, &cc->pllcontrol_data, 0x00000001); 6265 } else { 6266 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6267 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6268 } 6269 } else { 6270 if (spuravoid == 2) { 6271 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6272 W_REG(osh, &cc->pllcontrol_data, 0x11500014); 6273 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6274 W_REG(osh, &cc->pllcontrol_data, 0x0FC00a08); 6275 } else if (spuravoid == 1) { 6276 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6277 W_REG(osh, &cc->pllcontrol_data, 0x11500014); 6278 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6279 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 6280 } else { 6281 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6282 W_REG(osh, &cc->pllcontrol_data, 0x11100014); 6283 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6284 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 6285 } 6286 } 6287 tmp = 1 << 10; 6288 break; 6289 6290 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 6291 case BCM43226_CHIP_ID: 6292 if (spuravoid == 1) { 6293 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6294 W_REG(osh, &cc->pllcontrol_data, 0x11500010); 6295 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6296 W_REG(osh, &cc->pllcontrol_data, 0x000C0C06); 6297 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6298 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 6299 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6300 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6301 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6302 W_REG(osh, &cc->pllcontrol_data, 0x2001E920); 6303 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6304 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6305 } else { 6306 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6307 W_REG(osh, &cc->pllcontrol_data, 0x11100010); 6308 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6309 W_REG(osh, &cc->pllcontrol_data, 0x000c0c06); 6310 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6311 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 6312 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6313 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6314 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6315 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 6316 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6317 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6318 } 6319 tmp = 1 << 10; 6320 break; 6321 6322 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 6323 case BCM43420_CHIP_ID: 6324 if (spuravoid == 1) { 6325 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6326 W_REG(osh, &cc->pllcontrol_data, 0x11500008); 6327 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6328 W_REG(osh, &cc->pllcontrol_data, 0x0C000C06); 6329 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6330 W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); 6331 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6332 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6333 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6334 W_REG(osh, &cc->pllcontrol_data, 0x2001E920); 6335 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6336 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6337 } else { 6338 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6339 W_REG(osh, &cc->pllcontrol_data, 0x11100008); 6340 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6341 W_REG(osh, &cc->pllcontrol_data, 0x0c000c06); 6342 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6343 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 6344 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6345 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6346 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6347 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 6348 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6349 W_REG(osh, &cc->pllcontrol_data, 0x88888855); 6350 } 6351 6352 tmp = 1 << 10; 6353 break; 6354 6355 case BCM4716_CHIP_ID: 6356 case BCM4748_CHIP_ID: 6357 case BCM47162_CHIP_ID: 6358 if (spuravoid == 1) { 6359 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6360 W_REG(osh, &cc->pllcontrol_data, 0x11500060); 6361 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6362 W_REG(osh, &cc->pllcontrol_data, 0x080C0C06); 6363 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6364 W_REG(osh, &cc->pllcontrol_data, 0x0F600000); 6365 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6366 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6367 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6368 W_REG(osh, &cc->pllcontrol_data, 0x2001E924); 6369 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6370 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6371 } else { 6372 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6373 W_REG(osh, &cc->pllcontrol_data, 0x11100060); 6374 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6375 W_REG(osh, &cc->pllcontrol_data, 0x080c0c06); 6376 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6377 W_REG(osh, &cc->pllcontrol_data, 0x03000000); 6378 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6379 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6380 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6381 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 6382 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6383 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6384 } 6385 6386 tmp = 3 << 9; 6387 break; 6388 6389 case BCM4322_CHIP_ID: 6390 case BCM43221_CHIP_ID: 6391 case BCM43231_CHIP_ID: 6392 case BCM4342_CHIP_ID: 6393 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6394 W_REG(osh, &cc->pllcontrol_data, 0x11100070); 6395 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6396 W_REG(osh, &cc->pllcontrol_data, 0x1014140a); 6397 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6398 W_REG(osh, &cc->pllcontrol_data, 0x88888854); 6399 6400 if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */ 6401 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6402 W_REG(osh, &cc->pllcontrol_data, 0x05201828); 6403 } else { /* enable 40/80/160Mhz clock mode */ 6404 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6405 W_REG(osh, &cc->pllcontrol_data, 0x05001828); 6406 } 6407 6408 tmp = 1 << 10; 6409 break; 6410 case BCM4319_CHIP_ID: 6411 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6412 W_REG(osh, &cc->pllcontrol_data, 0x11100070); 6413 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6414 W_REG(osh, &cc->pllcontrol_data, 0x1014140a); 6415 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6416 W_REG(osh, &cc->pllcontrol_data, 0x88888854); 6417 6418 if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */ 6419 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6420 W_REG(osh, &cc->pllcontrol_data, 0x05201828); 6421 } else { /* enable 40/80/160Mhz clock mode */ 6422 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6423 W_REG(osh, &cc->pllcontrol_data, 0x05001828); 6424 } 6425 break; 6426 case BCM4336_CHIP_ID: 6427 case BCM43362_CHIP_ID: 6428 case BCM4330_CHIP_ID: 6429 xtal_freq = si_alp_clock(sih)/1000; 6430 /* Find the frequency in the table */ 6431 for (params_tbl = si_pmu1_xtaltab0(sih); 6432 params_tbl != NULL && params_tbl->xf != 0; params_tbl++) 6433 if ((params_tbl->fref) == xtal_freq) 6434 break; 6435 /* Could not find it so assign a default value */ 6436 if (params_tbl == NULL || params_tbl->xf == 0) 6437 params_tbl = si_pmu1_xtaldef0(sih); 6438 ASSERT(params_tbl != NULL && params_tbl->xf != 0); 6439 6440 /* FClkx = (P2/P1) * ((NDIV_INT + NDIV_FRAC/2^24)/MXDIV) * Fref 6441 Fref = XtalFreq 6442 FCLkx = 82MHz for spur avoidance mode 6443 80MHz for non-spur avoidance mode. 6444 */ 6445 xtal_freq = (uint32) params_tbl->fref/100; 6446 p1_div = params_tbl->p1div; 6447 p2_div = params_tbl->p2div; 6448 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6449 reg_val = R_REG(osh, &cc->pllcontrol_data); 6450 mxdiv = (reg_val >> PMU1_PLL0_PC2_M6DIV_SHIFT) & PMU1_PLL0_PC2_M5DIV_MASK; 6451 6452 if (spuravoid == 1) 6453 FCLkx = 82; 6454 else 6455 FCLkx = 80; 6456 6457 part_mul = (p1_div / p2_div) * mxdiv; 6458 ndiv_int = (FCLkx * part_mul * 10)/ (xtal_freq); 6459 ndiv_frac_int = ((FCLkx * part_mul * 10) % (xtal_freq)); 6460 ndiv_frac_int = ((ndiv_frac_int * 16777216) + (xtal_freq/2)) / (xtal_freq); 6461 6462 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6463 reg_val = R_REG(osh, &cc->pllcontrol_data); 6464 W_REG(osh, &cc->pllcontrol_data, ((reg_val & ~PMU1_PLL0_PC2_NDIV_INT_MASK) 6465 | (ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT))); 6466 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6467 W_REG(osh, &cc->pllcontrol_data, ndiv_frac_int); 6468 6469 tmp = PCTL_PLL_PLLCTL_UPD; 6470 break; 6471 6472 case BCM43131_CHIP_ID: 6473 case BCM43217_CHIP_ID: 6474 case BCM43227_CHIP_ID: 6475 case BCM43228_CHIP_ID: 6476 case BCM43428_CHIP_ID: 6477 /* LCNXN */ 6478 /* PLL Settings for spur avoidance on/off mode, no on2 support for 43228A0 */ 6479 if (spuravoid == 1) { 6480 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6481 W_REG(osh, &cc->pllcontrol_data, 0x01100014); 6482 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6483 W_REG(osh, &cc->pllcontrol_data, 0x040C0C06); 6484 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6485 W_REG(osh, &cc->pllcontrol_data, 0x03140A08); 6486 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6487 W_REG(osh, &cc->pllcontrol_data, 0x00333333); 6488 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6489 W_REG(osh, &cc->pllcontrol_data, 0x202C2820); 6490 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6491 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6492 } else { 6493 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); 6494 W_REG(osh, &cc->pllcontrol_data, 0x11100014); 6495 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); 6496 W_REG(osh, &cc->pllcontrol_data, 0x040c0c06); 6497 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); 6498 W_REG(osh, &cc->pllcontrol_data, 0x03000a08); 6499 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6500 W_REG(osh, &cc->pllcontrol_data, 0x00000000); 6501 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); 6502 W_REG(osh, &cc->pllcontrol_data, 0x200005c0); 6503 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); 6504 W_REG(osh, &cc->pllcontrol_data, 0x88888815); 6505 } 6506 tmp = 1 << 10; 6507 break; 6508 case BCM4314_CHIP_ID: 6509 case BCM43142_CHIP_ID: 6510 case BCM4334_CHIP_ID: 6511 { 6512 const pmu2_xtaltab0_t *xt; 6513 uint32 pll0; 6514 6515 xtal_freq = si_pmu_alp_clock(sih, osh)/1000; 6516 xt = (spuravoid == 1) ? pmu2_xtaltab0_adfll_492 : pmu2_xtaltab0_adfll_485; 6517 6518 for (; xt != NULL && xt->fref != 0; xt++) { 6519 if (xt->fref == xtal_freq) { 6520 W_REG(osh, &cc->pllcontrol_addr, PMU15_PLL_PLLCTL0); 6521 pll0 = R_REG(osh, &cc->pllcontrol_data); 6522 pll0 &= ~PMU15_PLL_PC0_FREQTGT_MASK; 6523 pll0 |= (xt->freq_tgt << PMU15_PLL_PC0_FREQTGT_SHIFT); 6524 W_REG(osh, &cc->pllcontrol_data, pll0); 6525 6526 tmp = PCTL_PLL_PLLCTL_UPD; 6527 break; 6528 } 6529 } 6530 } 6531 break; 6532 case BCM4335_CHIP_ID: 6533 /* 4335 PLL ctrl Registers */ 6534 /* PLL Settings for spur avoidance on/off mode, support for 4335A0 */ 6535 /* # spur_mode 0 VCO=963MHz 6536 # spur_mode 1 VCO=960MHz 6537 # spur_mode 2 VCO=961MHz 6538 # spur_mode 3 VCO=964MHz 6539 # spur_mode 4 VCO=962MHz 6540 # spur_mode 5 VCO=965MHz 6541 # spur_mode 6 VCO=966MHz 6542 # spur_mode 7 VCO=967MHz 6543 # spur_mode 8 VCO=968MHz 6544 # spur_mode 9 VCO=969MHz 6545 */ 6546 W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); 6547 switch (spuravoid) { 6548 case 0: 6549 W_REG(osh, &cc->pllcontrol_data, 0x80BFA863); 6550 break; 6551 case 1: 6552 W_REG(osh, &cc->pllcontrol_data, 0x80AB1F7D); 6553 break; 6554 case 2: 6555 W_REG(osh, &cc->pllcontrol_data, 0x80b1f7c9); 6556 break; 6557 case 3: 6558 W_REG(osh, &cc->pllcontrol_data, 0x80c680af); 6559 break; 6560 case 4: 6561 W_REG(osh, &cc->pllcontrol_data, 0x80B8D016); 6562 break; 6563 case 5: 6564 W_REG(osh, &cc->pllcontrol_data, 0x80CD58FC); 6565 break; 6566 case 6: 6567 W_REG(osh, &cc->pllcontrol_data, 0x80D43149); 6568 break; 6569 case 7: 6570 W_REG(osh, &cc->pllcontrol_data, 0x80DB0995); 6571 break; 6572 case 8: 6573 W_REG(osh, &cc->pllcontrol_data, 0x80E1E1E2); 6574 break; 6575 case 9: 6576 W_REG(osh, &cc->pllcontrol_data, 0x80E8BA2F); 6577 break; 6578 default: 6579 PMU_ERROR(("%s: unsupported spur mode for chip %s, not changing PLL\n", 6580 __FUNCTION__, bcm_chipname(sih->chip, chn, 8))); 6581 break; 6582 } 6583 tmp = PCTL_PLL_PLLCTL_UPD; 6584 break; 6585 default: 6586 PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n", 6587 __FUNCTION__, bcm_chipname(sih->chip, chn, 8))); 6588 break; 6589 } 6590 6591 tmp |= R_REG(osh, &cc->pmucontrol); 6592 W_REG(osh, &cc->pmucontrol, tmp); 6593} /* si_pmu_spuravoid_pllupdate */ 6594 6595extern uint32 6596si_pmu_cal_fvco(si_t *sih, osl_t *osh) 6597{ 6598 uint32 xf, ndiv_int, ndiv_frac, fvco, pll_reg, p1_div_scale; 6599 uint32 r_high, r_low, int_part, frac_part, rounding_const; 6600 uint8 p1_div; 6601 chipcregs_t *cc; 6602 uint origidx, intr_val; 6603 6604 /* Remember original core before switch to chipc */ 6605 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 6606 ASSERT(cc != NULL); 6607 6608 xf = si_pmu_alp_clock(sih, osh)/1000; 6609 6610 pll_reg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, 0, 0); 6611 6612 p1_div = (pll_reg & PMU4335_PLL0_PC2_P1DIV_MASK) >> 6613 PMU4335_PLL0_PC2_P1DIV_SHIFT; 6614 6615 ndiv_int = (pll_reg & PMU4335_PLL0_PC2_NDIV_INT_MASK) >> 6616 PMU4335_PLL0_PC2_NDIV_INT_SHIFT; 6617 6618 pll_reg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL3, 0, 0); 6619 6620 ndiv_frac = (pll_reg & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> 6621 PMU1_PLL0_PC3_NDIV_FRAC_SHIFT; 6622 6623 /* Actual expression is as below */ 6624 /* fvco1 = (100 * (xf * 1/p1_div) * (ndiv_int + (ndiv_frac * 1/(1 << 24)))) */ 6625 /* * 1/(1000 * 100); */ 6626 6627 /* Representing 1/p1_div as a 12 bit number */ 6628 /* Reason for the choice of 12: */ 6629 /* ndiv_int is represented by 9 bits */ 6630 /* so (ndiv_int << 24) needs 33 bits */ 6631 /* xf needs 16 bits for the worst case of 52MHz clock */ 6632 /* So (xf * (ndiv << 24)) needs atleast 49 bits */ 6633 /* So remaining bits for uint64 : 64 - 49 = 15 bits */ 6634 /* So, choosing 12 bits, with 3 bits of headroom */ 6635 int_part = xf * ndiv_int; 6636 6637 rounding_const = 1 << (BBPLL_NDIV_FRAC_BITS - 1); 6638 bcm_uint64_multiple_add(&r_high, &r_low, ndiv_frac, xf, rounding_const); 6639 bcm_uint64_right_shift(&frac_part, r_high, r_low, BBPLL_NDIV_FRAC_BITS); 6640 6641 p1_div_scale = (1 << P1_DIV_SCALE_BITS) / p1_div; 6642 rounding_const = 1 << (P1_DIV_SCALE_BITS - 1); 6643 6644 bcm_uint64_multiple_add(&r_high, &r_low, (int_part + frac_part), 6645 p1_div_scale, rounding_const); 6646 bcm_uint64_right_shift(&fvco, r_high, r_low, P1_DIV_SCALE_BITS); 6647 6648 /* Return to original core */ 6649 si_restore_core(sih, origidx, intr_val); 6650 return fvco; 6651} /* si_pmu_cal_fvco */ 6652 6653/** Only called by N (MIMO) PHY */ 6654void 6655si_pmu_gband_spurwar(si_t *sih, osl_t *osh) 6656{ 6657 chipcregs_t *cc; 6658 uint origidx, intr_val; 6659 uint32 cc_clk_ctl_st; 6660 uint32 minmask, maxmask; 6661 6662 if ((CHIPID(sih->chip) == BCM43222_CHIP_ID) || 6663 (CHIPID(sih->chip) == BCM43420_CHIP_ID)) { 6664 /* Remember original core before switch to chipc */ 6665 cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); 6666 ASSERT(cc != NULL); 6667 6668 /* Remove force HT and HT Avail Request from chipc core */ 6669 cc_clk_ctl_st = R_REG(osh, &cc->clk_ctl_st); 6670 AND_REG(osh, &cc->clk_ctl_st, ~(CCS_FORCEHT | CCS_HTAREQ)); 6671 6672 minmask = R_REG(osh, &cc->min_res_mask); 6673 maxmask = R_REG(osh, &cc->max_res_mask); 6674 6675 /* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */ 6676 /* Have to remove HT Avail request before powering off PLL */ 6677 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 6678 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_HT_SI_AVAIL))); 6679 SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); 6680 AND_REG(osh, &cc->min_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 6681 AND_REG(osh, &cc->max_res_mask, ~(PMURES_BIT(RES4322_SI_PLL_ON))); 6682 OSL_DELAY(150); 6683 ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 6684 6685 /* Change backplane clock speed from 96 MHz to 80 MHz */ 6686 W_REG(osh, &cc->pllcontrol_addr, PMU2_PLL_PLLCTL2); 6687 W_REG(osh, &cc->pllcontrol_data, (R_REG(osh, &cc->pllcontrol_data) & 6688 ~(PMU2_PLL_PC2_M6DIV_MASK)) | 6689 (0xc << PMU2_PLL_PC2_M6DIV_SHIFT)); 6690 6691 /* Reduce the driver strengths of the phyclk160, adcclk80, and phyck80 6692 * clocks from 0x8 to 0x1 6693 */ 6694 W_REG(osh, &cc->pllcontrol_addr, PMU2_PLL_PLLCTL5); 6695 W_REG(osh, &cc->pllcontrol_data, (R_REG(osh, &cc->pllcontrol_data) & 6696 ~(PMU2_PLL_PC5_CLKDRIVE_CH1_MASK | 6697 PMU2_PLL_PC5_CLKDRIVE_CH2_MASK | 6698 PMU2_PLL_PC5_CLKDRIVE_CH3_MASK | 6699 PMU2_PLL_PC5_CLKDRIVE_CH4_MASK)) | 6700 ((1 << PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT) | 6701 (1 << PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT) | 6702 (1 << PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT) | 6703 (1 << PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT))); 6704 6705 W_REG(osh, &cc->pmucontrol, R_REG(osh, &cc->pmucontrol) | PCTL_PLL_PLLCTL_UPD); 6706 6707 /* Restore min_res_mask and max_res_mask */ 6708 OSL_DELAY(100); 6709 W_REG(osh, &cc->max_res_mask, maxmask); 6710 OSL_DELAY(100); 6711 W_REG(osh, &cc->min_res_mask, minmask); 6712 OSL_DELAY(100); 6713 /* Make sure the PLL is on. Spinwait until the HTAvail is True */ 6714 SPINWAIT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY); 6715 ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); 6716 6717 /* Restore force HT and HT Avail Request on the chipc core */ 6718 W_REG(osh, &cc->clk_ctl_st, cc_clk_ctl_st); 6719 6720 /* Return to original core */ 6721 si_restore_core(sih, origidx, intr_val); 6722 } 6723} 6724 6725bool 6726si_pmu_is_otp_powered(si_t *sih, osl_t *osh) 6727{ 6728 uint idx; 6729 chipcregs_t *cc; 6730 bool st; 6731 6732 /* Remember original core before switch to chipc */ 6733 idx = si_coreidx(sih); 6734 cc = si_setcoreidx(sih, SI_CC_IDX); 6735 ASSERT(cc != NULL); 6736 6737 switch (CHIPID(sih->chip)) { 6738 case BCM4322_CHIP_ID: 6739 case BCM43221_CHIP_ID: 6740 case BCM43231_CHIP_ID: 6741 case BCM4342_CHIP_ID: 6742 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4322_OTP_PU)) != 0; 6743 break; 6744 case BCM4325_CHIP_ID: 6745 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4325_OTP_PU)) != 0; 6746 break; 6747 case BCM4329_CHIP_ID: 6748 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4329_OTP_PU)) != 0; 6749 break; 6750 case BCM4315_CHIP_ID: 6751 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4315_OTP_PU)) != 0; 6752 break; 6753 case BCM4319_CHIP_ID: 6754 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4319_OTP_PU)) != 0; 6755 break; 6756 case BCM4336_CHIP_ID: 6757 case BCM43362_CHIP_ID: 6758 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4336_OTP_PU)) != 0; 6759 break; 6760 case BCM43239_CHIP_ID: 6761 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES43239_OTP_PU)) != 0; 6762 break; 6763 case BCM4330_CHIP_ID: 6764 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4330_OTP_PU)) != 0; 6765 break; 6766 case BCM4314_CHIP_ID: 6767 case BCM43142_CHIP_ID: 6768 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4314_OTP_PU)) != 0; 6769 break; 6770 case BCM43143_CHIP_ID: 6771 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES43143_OTP_PU)) != 0; 6772 break; 6773 case BCM4334_CHIP_ID: 6774 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4334_OTP_PU)) != 0; 6775 break; 6776 case BCM4324_CHIP_ID: 6777 case BCM43242_CHIP_ID: 6778 case BCM43243_CHIP_ID: 6779 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4324_OTP_PU)) != 0; 6780 break; 6781 6782 case BCM4335_CHIP_ID: 6783 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4335_OTP_PU)) != 0; 6784 break; 6785 case BCM4350_CHIP_ID: 6786 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4350_OTP_PU)) != 0; 6787 break; 6788 case BCM4360_CHIP_ID: 6789 case BCM43460_CHIP_ID: 6790 case BCM43526_CHIP_ID: 6791 case BCM4352_CHIP_ID: 6792 st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4360_OTP_PU)) != 0; 6793 break; 6794 6795 6796 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on. 6797 * Use OTP_INIT command to reset/refresh state. 6798 */ 6799 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 6800 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 6801 case BCM43236_CHIP_ID: case BCM43235_CHIP_ID: case BCM43238_CHIP_ID: 6802 case BCM43237_CHIP_ID: case BCM43420_CHIP_ID: 6803 case BCM43234_CHIP_ID: 6804 case BCM4331_CHIP_ID: case BCM43431_CHIP_ID: 6805 st = TRUE; 6806 break; 6807 default: 6808 st = TRUE; 6809 break; 6810 } 6811 6812 /* Return to original core */ 6813 si_setcoreidx(sih, idx); 6814 return st; 6815} /* si_pmu_is_otp_powered */ 6816 6817void 6818#if defined(WLTEST) 6819si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable) 6820#else 6821BCMATTACHFN(si_pmu_sprom_enable)(si_t *sih, osl_t *osh, bool enable) 6822#endif 6823{ 6824 chipcregs_t *cc; 6825 uint origidx; 6826 6827 /* Remember original core before switch to chipc */ 6828 origidx = si_coreidx(sih); 6829 cc = si_setcoreidx(sih, SI_CC_IDX); 6830 ASSERT(cc != NULL); 6831 6832 switch (CHIPID(sih->chip)) { 6833 case BCM4315_CHIP_ID: 6834 if (CHIPREV(sih->chiprev) < 1) 6835 break; 6836 if (sih->chipst & CST4315_SPROM_SEL) { 6837 uint32 val; 6838 W_REG(osh, &cc->chipcontrol_addr, 0); 6839 val = R_REG(osh, &cc->chipcontrol_data); 6840 if (enable) 6841 val &= ~0x80000000; 6842 else 6843 val |= 0x80000000; 6844 W_REG(osh, &cc->chipcontrol_data, val); 6845 } 6846 break; 6847 default: 6848 break; 6849 } 6850 6851 /* Return to original core */ 6852 si_setcoreidx(sih, origidx); 6853} 6854 6855bool 6856#if defined(WLTEST) 6857si_pmu_is_sprom_enabled(si_t *sih, osl_t *osh) 6858#else 6859BCMATTACHFN(si_pmu_is_sprom_enabled)(si_t *sih, osl_t *osh) 6860#endif 6861{ 6862 chipcregs_t *cc; 6863 uint origidx; 6864 bool enable = TRUE; 6865 6866 /* Remember original core before switch to chipc */ 6867 origidx = si_coreidx(sih); 6868 cc = si_setcoreidx(sih, SI_CC_IDX); 6869 ASSERT(cc != NULL); 6870 6871 switch (CHIPID(sih->chip)) { 6872 case BCM4315_CHIP_ID: 6873 if (CHIPREV(sih->chiprev) < 1) 6874 break; 6875 if (!(sih->chipst & CST4315_SPROM_SEL)) 6876 break; 6877 W_REG(osh, &cc->chipcontrol_addr, 0); 6878 if (R_REG(osh, &cc->chipcontrol_data) & 0x80000000) 6879 enable = FALSE; 6880 break; 6881 default: 6882 break; 6883 } 6884 6885 /* Return to original core */ 6886 si_setcoreidx(sih, origidx); 6887 return enable; 6888} 6889 6890static void 6891BCMATTACHFN(si_pmu_set_lpoclk)(si_t *sih, osl_t *osh) 6892{ 6893 chipcregs_t *cc; 6894 uint origidx; 6895 6896 uint32 ext_lpo_sel = 0, int_lpo_sel = 0, timeout = 0, 6897 ext_lpo_avail = 0, lpo_sel = 0; 6898 6899 if (!(getintvar(NULL, "boardflags3"))) 6900 return; 6901 6902 /* Remember original core before switch to chipc */ 6903 origidx = si_coreidx(sih); 6904 cc = si_setcoreidx(sih, SI_CC_IDX); 6905 6906 ext_lpo_sel = getintvar(NULL, "boardflags3") & BFL3_FORCE_EXT_LPO_SEL; 6907 int_lpo_sel = getintvar(NULL, "boardflags3") & BFL3_FORCE_INT_LPO_SEL; 6908 6909 if (ext_lpo_sel != 0) { 6910 /* Force External LPO Power Up */ 6911 si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_EXT_LPO_PU, CC_EXT_LPO_PU); 6912 si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_EXT_LPO_PU, GC_EXT_LPO_PU); 6913 6914 ext_lpo_avail = R_REG(osh, &cc->pmustatus) & EXT_LPO_AVAIL; 6915 while (ext_lpo_avail == 0 && timeout < LPO_SEL_TIMEOUT) { 6916 OSL_DELAY(1000); 6917 ext_lpo_avail = R_REG(osh, &cc->pmustatus) & EXT_LPO_AVAIL; 6918 timeout++; 6919 } 6920 if (timeout >= LPO_SEL_TIMEOUT) { 6921 PMU_ERROR(("External LPO is not available\n")); 6922 } else { 6923 OSL_DELAY(1000); 6924 6925 /* Force External LPO Sel up */ 6926 si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, EXT_LPO_SEL); 6927 /* Clear Force Internal LPO Sel */ 6928 si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, 0x0); 6929 6930 OSL_DELAY(1000); 6931 6932 lpo_sel = R_REG(osh, &cc->pmucontrol) & LPO_SEL; 6933 timeout = 0; 6934 while (lpo_sel != 0 && timeout < LPO_SEL_TIMEOUT) { 6935 OSL_DELAY(1000); 6936 lpo_sel = R_REG(osh, &cc->pmucontrol) & LPO_SEL; 6937 timeout++; 6938 } 6939 if (timeout >= LPO_SEL_TIMEOUT) { 6940 PMU_ERROR(("External LPO is not set\n")); 6941 /* Clear Force External LPO Sel */ 6942 si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, 0x0); 6943 } else { 6944 /* Clear Force Internal LPO Power Up */ 6945 si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_INT_LPO_PU, 0x0); 6946 si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_INT_LPO_PU, 0x0); 6947 } 6948 } 6949 } else if (int_lpo_sel != 0) { 6950 /* Force Internal LPO Power Up */ 6951 si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_INT_LPO_PU, CC_INT_LPO_PU); 6952 si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_INT_LPO_PU, GC_INT_LPO_PU); 6953 6954 OSL_DELAY(1000); 6955 6956 /* Force Internal LPO Sel up */ 6957 si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, INT_LPO_SEL); 6958 /* Clear Force External LPO Sel */ 6959 si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, 0x0); 6960 6961 OSL_DELAY(1000); 6962 6963 lpo_sel = R_REG(osh, &cc->pmucontrol) & LPO_SEL; 6964 timeout = 0; 6965 while (lpo_sel == 0 && timeout < LPO_SEL_TIMEOUT) { 6966 OSL_DELAY(1000); 6967 lpo_sel = R_REG(osh, &cc->pmucontrol) & LPO_SEL; 6968 timeout++; 6969 } 6970 if (timeout >= LPO_SEL_TIMEOUT) { 6971 PMU_ERROR(("Internal LPO is not set\n")); 6972 /* Clear Force Internal LPO Sel */ 6973 si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, 0x0); 6974 } else { 6975 /* Clear Force External LPO Power Up */ 6976 si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_EXT_LPO_PU, 0x0); 6977 si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_EXT_LPO_PU, 0x0); 6978 } 6979 } 6980 6981 /* Return to original core */ 6982 si_setcoreidx(sih, origidx); 6983} /* si_pmu_set_lpoclk */ 6984 6985/** initialize PMU chip controls and other chip level stuff */ 6986void 6987BCMATTACHFN(si_pmu_chip_init)(si_t *sih, osl_t *osh) 6988{ 6989 uint origidx; 6990 6991 ASSERT(sih->cccaps & CC_CAP_PMU); 6992 6993 si_pmu_otp_chipcontrol(sih, osh); 6994 6995#ifdef CHIPC_UART_ALWAYS_ON 6996 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), CCS_FORCEALP, CCS_FORCEALP); 6997#endif /* CHIPC_UART_ALWAYS_ON */ 6998 6999#ifndef CONFIG_XIP 7000 /* Gate off SPROM clock and chip select signals */ 7001 si_pmu_sprom_enable(sih, osh, FALSE); 7002#endif 7003 7004 /* Remember original core */ 7005 origidx = si_coreidx(sih); 7006 7007 /* Misc. chip control, has nothing to do with PMU */ 7008 switch (CHIPID(sih->chip)) { 7009 case BCM4315_CHIP_ID: 7010#ifdef BCMUSBDEV 7011 si_setcore(sih, PCMCIA_CORE_ID, 0); 7012 si_core_disable(sih, 0); 7013#endif 7014 break; 7015 7016 case BCM4324_CHIP_ID: 7017 case BCM43242_CHIP_ID: 7018 case BCM43243_CHIP_ID: 7019 { 7020#if defined(BCM4324A0) || defined(BCM4324A1) 7021 si_pmu_chipcontrol(sih, PMU_CHIPCTL1, 7022 (PMU4324_CC1_GPIO_CONF(-1) | PMU4324_CC1_ENABLE_UART), 7023 (PMU4324_CC1_GPIO_CONF(0) | PMU4324_CC1_ENABLE_UART)); 7024 si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMU4324_CC2_SDIO_AOS_EN, 7025 PMU4324_CC2_SDIO_AOS_EN); 7026#endif 7027 7028#ifdef BCM4324B0 7029 si_pmu_chipcontrol(sih, PMU_CHIPCTL1, 7030 PMU4324_CC1_ENABLE_UART, 7031 0); 7032 si_pmu_chipcontrol(sih, PMU_CHIPCTL2, 7033 PMU4324_CC2_SDIO_AOS_EN, 7034 PMU4324_CC2_SDIO_AOS_EN); 7035#endif 7036 7037#if defined(BCM4324A1) || defined(BCM4324B0) 7038 7039 /* 4324 iPA Board hence muxing out PALDO_PU signal to O/p pin & 7040 * muxing out actual RF_SW_CTRL7-6 signals to O/p pin 7041 */ 7042 7043 si_pmu_chipcontrol(sih, 4, 0x1f0000, 0x140000); 7044#endif 7045 /* 7046 * Setting the pin mux to enable the GPIOs required for HSIC-OOB signals. 7047 */ 7048#if defined(BCM4324B1) 7049 si_pmu_chipcontrol(sih, PMU_CHIPCTL1, PMU4324_CC1_GPIO_CONF_MASK, 0x2); 7050#endif 7051 break; 7052 } 7053 7054 case BCM4336_CHIP_ID: 7055 case BCM43362_CHIP_ID: 7056 { 7057 uint32 mask, val = 0; 7058 uint16 clkreq_conf; 7059 mask = (1 << PMU_CC1_CLKREQ_TYPE_SHIFT); 7060 7061 clkreq_conf = (uint16)getintvar(NULL, "clkreq_conf"); 7062 7063 if (clkreq_conf & CLKREQ_TYPE_CONFIG_PUSHPULL) 7064 val = (1 << PMU_CC1_CLKREQ_TYPE_SHIFT); 7065 7066 si_pmu_chipcontrol(sih, PMU_CHIPCTL0, mask, val); 7067 break; 7068 } 7069 7070#ifdef BCMQT 7071 case BCM4314_CHIP_ID: 7072 { 7073 chipcregs_t *cc; 7074 uint32 tmp; 7075 7076 cc = si_setcoreidx(sih, SI_CC_IDX); 7077 7078 W_REG(osh, &cc->chipcontrol_addr, PMU_CHIPCTL3); 7079 tmp = R_REG(osh, &cc->chipcontrol_data); 7080 tmp &= ~(1 << PMU_CC3_ENABLE_RF_SHIFT); 7081 tmp |= (1 << PMU_CC3_RF_DISABLE_IVALUE_SHIFT); 7082 W_REG(osh, &cc->chipcontrol_data, tmp); 7083 break; 7084 } 7085#endif /* BCMQT */ 7086 7087 case BCM4350_CHIP_ID: 7088 { 7089 uint32 val; 7090 7091 if (CST4350_IFC_MODE(sih->chipst) == CST4350_IFC_MODE_PCIE) { 7092 /* JIRA: SWWLAN-27305 initialize 4350 pmu control registers */ 7093 si_pmu_chipcontrol(sih, PMU_CHIPCTL1, 7094 PMU_CC1_ENABLE_BBPLL_PWR_DOWN, PMU_CC1_ENABLE_BBPLL_PWR_DOWN); 7095 si_pmu_regcontrol(sih, 0, ~0, 1); 7096 7097 /* JIRA: SWWLAN-27486 optimize power consumption */ 7098 if (sih->chiprev == 0) { /* 4350A0 */ 7099 val = PMU_CC2_FORCE_SUBCORE_PWR_SWITCH_ON | 7100 PMU_CC2_FORCE_PHY_PWR_SWITCH_ON | 7101 PMU_CC2_FORCE_VDDM_PWR_SWITCH_ON | 7102 PMU_CC2_FORCE_MEMLPLDO_PWR_SWITCH_ON; 7103 si_pmu_chipcontrol(sih, PMU_CHIPCTL2, val, val); 7104 7105 val = PMU_CC6_ENABLE_CLKREQ_WAKEUP | 7106 PMU_CC6_ENABLE_PMU_WAKEUP_ALP; 7107 si_pmu_chipcontrol(sih, PMU_CHIPCTL6, val, val); 7108 } 7109 } 7110 break; 7111 } 7112 case BCM4335_CHIP_ID: 7113 { 7114 /* Set internal/external LPO */ 7115 si_pmu_set_lpoclk(sih, osh); 7116 break; 7117 } 7118 default: 7119 break; 7120 } 7121 7122 /* Return to original core */ 7123 si_setcoreidx(sih, origidx); 7124} /* si_pmu_chip_init */ 7125 7126/** initialize PMU registers in case default values proved to be suboptimal */ 7127void 7128BCMATTACHFN(si_pmu_swreg_init)(si_t *sih, osl_t *osh) 7129{ 7130 uint16 cbuck_mv; 7131 int8 vreg_val; 7132 7133 ASSERT(sih->cccaps & CC_CAP_PMU); 7134 7135 switch (CHIPID(sih->chip)) { 7136 case BCM4325_CHIP_ID: 7137 if (CHIPREV(sih->chiprev) < 3) 7138 break; 7139 if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> CST4325_PMUTOP_2B_SHIFT) == 1) { 7140 /* Bump CLDO PWM output voltage to 1.25V */ 7141 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xf); 7142 /* Bump CLDO BURST output voltage to 1.25V */ 7143 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, 0xf); 7144 } 7145 /* Bump CBUCK PWM output voltage to 1.5V */ 7146 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb); 7147 /* Bump CBUCK BURST output voltage to 1.5V */ 7148 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb); 7149 /* Bump LNLDO1 output voltage to 1.25V */ 7150 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0x1); 7151 /* Select LNLDO2 output voltage to 2.5V */ 7152 if (sih->boardflags & BFL_LNLDO2_2P5) 7153 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO2_SEL, 0x1); 7154 break; 7155 case BCM4315_CHIP_ID: { 7156 uint32 val; 7157 chipcregs_t *cc; 7158 uint origidx; 7159 7160 if (CHIPREV(sih->chiprev) != 2) 7161 break; 7162 7163 /* Remember original core before switch to chipc */ 7164 origidx = si_coreidx(sih); 7165 cc = si_setcoreidx(sih, SI_CC_IDX); 7166 ASSERT(cc != NULL); 7167 7168 W_REG(osh, &cc->regcontrol_addr, 4); 7169 val = R_REG(osh, &cc->regcontrol_data); 7170 val |= (uint32)(1 << 16); 7171 W_REG(osh, &cc->regcontrol_data, val); 7172 7173 /* Return to original core */ 7174 si_setcoreidx(sih, origidx); 7175 break; 7176 } 7177 case BCM4336_CHIP_ID: 7178 if (CHIPREV(sih->chiprev) < 2) { 7179 /* Reduce CLDO PWM output voltage to 1.2V */ 7180 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); 7181 /* Reduce CLDO BURST output voltage to 1.2V */ 7182 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, 0xe); 7183 /* Reduce LNLDO1 output voltage to 1.2V */ 7184 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0xe); 7185 } 7186 if (CHIPREV(sih->chiprev) == 2) { 7187 /* Reduce CBUCK PWM output voltage */ 7188 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0x16); 7189 /* Reduce CBUCK BURST output voltage */ 7190 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0x16); 7191 si_pmu_set_ldo_voltage(sih, osh, SET_LNLDO_PWERUP_LATCH_CTRL, 0x3); 7192 } 7193 if (CHIPREV(sih->chiprev) == 0) 7194 si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); 7195 7196 case BCM43362_CHIP_ID: 7197 case BCM4330_CHIP_ID: 7198 cbuck_mv = (uint16)getintvar(NULL, "cbuckout"); 7199 7200 /* set default cbuck output to be 1.5V */ 7201 if (!cbuck_mv) 7202 cbuck_mv = 1500; 7203 vreg_val = si_pmu_cbuckout_to_vreg_ctrl(sih, cbuck_mv); 7204 /* set vreg ctrl only if there is a mapping defined for vout to bit map */ 7205 if (vreg_val >= 0) { 7206 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, vreg_val); 7207 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, vreg_val); 7208 } 7209 break; 7210 case BCM4314_CHIP_ID: 7211 if (CHIPREV(sih->chiprev) == 0) { 7212 /* Reduce LPLDO2 output voltage to 1.0V */ 7213 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LDO2, 0); 7214 } 7215 break; 7216 case BCM4334_CHIP_ID: 7217 if (!CST4334_CHIPMODE_HSIC(sih->chipst)) 7218 si_pmu_chipcontrol(sih, 2, CCTRL4334_HSIC_LDO_PU, CCTRL4334_HSIC_LDO_PU); 7219 break; 7220 case BCM43143_CHIP_ID: 7221#ifndef BCM_BOOTLOADER 7222 /* Force CBUCK to PWM mode */ 7223 si_pmu_regcontrol(sih, 0, 0x2, 0x2); 7224 /* Increase CBUCK output voltage to 1.4V */ 7225 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0x2); 7226 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0x2); 7227 /* Decrease LNLDO output voltage to just under 1.2V */ 7228 si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0x7); 7229 7230 si_pmu_chipcontrol(sih, PMU_CHIPCTL0, PMU43143_XTAL_CORE_SIZE_MASK, 0x10); 7231#endif 7232 break; 7233 default: 7234 break; 7235 } 7236 si_pmu_otp_regcontrol(sih, osh); 7237} /* si_pmu_swreg_init */ 7238 7239void 7240si_pmu_radio_enable(si_t *sih, bool enable) 7241{ 7242 ASSERT(sih->cccaps & CC_CAP_PMU); 7243 7244 switch (CHIPID(sih->chip)) { 7245 case BCM4325_CHIP_ID: 7246 if (sih->boardflags & BFL_FASTPWR) 7247 break; 7248 7249 if ((sih->boardflags & BFL_BUCKBOOST)) { 7250 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), 7251 PMURES_BIT(RES4325_BUCK_BOOST_BURST), 7252 enable ? PMURES_BIT(RES4325_BUCK_BOOST_BURST) : 0); 7253 } 7254 7255 if (enable) { 7256 OSL_DELAY(100 * 1000); 7257 } 7258 break; 7259 case BCM4319_CHIP_ID: 7260 case BCM4330_CHIP_ID: 7261 case BCM4336_CHIP_ID: 7262 case BCM43362_CHIP_ID: 7263 { 7264 uint32 wrap_reg, val; 7265 wrap_reg = si_wrapperreg(sih, AI_OOBSELOUTB74, 0, 0); 7266 7267 val = ((1 << OOB_SEL_OUTEN_B_5) | (1 << OOB_SEL_OUTEN_B_6)); 7268 if (enable) 7269 wrap_reg |= val; 7270 else 7271 wrap_reg &= ~val; 7272 si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, wrap_reg); 7273 7274 break; 7275 } 7276 default: 7277 break; 7278 } 7279} /* si_pmu_radio_enable */ 7280 7281/** Wait for a particular clock level to be on the backplane */ 7282uint32 7283si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, uint32 clk, uint32 delay_val) 7284{ 7285 chipcregs_t *cc; 7286 uint origidx; 7287 7288 ASSERT(sih->cccaps & CC_CAP_PMU); 7289 7290 /* Remember original core before switch to chipc */ 7291 origidx = si_coreidx(sih); 7292 cc = si_setcoreidx(sih, SI_CC_IDX); 7293 ASSERT(cc != NULL); 7294 7295 if (delay_val) 7296 SPINWAIT(((R_REG(osh, &cc->pmustatus) & clk) != clk), delay_val); 7297 7298 /* Return to original core */ 7299 si_setcoreidx(sih, origidx); 7300 7301 return (R_REG(osh, &cc->pmustatus) & clk); 7302} 7303 7304/** 7305 * Measures the ALP clock frequency in KHz. Returns 0 if not possible. 7306 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal. 7307 */ 7308 7309#define EXT_ILP_HZ 32768 7310 7311uint32 7312BCMATTACHFN(si_pmu_measure_alpclk)(si_t *sih, osl_t *osh) 7313{ 7314 chipcregs_t *cc; 7315 uint origidx; 7316 uint32 alp_khz; 7317 uint32 pmustat_lpo = 0; 7318 7319 if (sih->pmurev < 10) 7320 return 0; 7321 7322 ASSERT(sih->cccaps & CC_CAP_PMU); 7323 7324 /* Remember original core before switch to chipc */ 7325 origidx = si_coreidx(sih); 7326 cc = si_setcoreidx(sih, SI_CC_IDX); 7327 ASSERT(cc != NULL); 7328 7329 if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) || 7330 (CHIPID(sih->chip) == BCM4350_CHIP_ID) || 7331 0) 7332 pmustat_lpo = !(R_REG(osh, &cc->pmucontrol) & PCTL_LPO_SEL); 7333 else 7334 pmustat_lpo = R_REG(osh, &cc->pmustatus) & PST_EXTLPOAVAIL; 7335 7336 if (pmustat_lpo) { 7337 uint32 ilp_ctr, alp_hz; 7338 7339 /* Enable the reg to measure the freq, in case disabled before */ 7340 W_REG(osh, &cc->pmu_xtalfreq, 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); 7341 7342 /* Delay for well over 4 ILP clocks */ 7343 OSL_DELAY(1000); 7344 7345 /* Read the latched number of ALP ticks per 4 ILP ticks */ 7346 ilp_ctr = R_REG(osh, &cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; 7347 7348 /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */ 7349 W_REG(osh, &cc->pmu_xtalfreq, 0); 7350 7351 /* Calculate ALP frequency */ 7352 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; 7353 7354 /* Round to nearest 100KHz, and at the same time convert to KHz */ 7355 alp_khz = (alp_hz + 50000) / 100000 * 100; 7356 } else 7357 alp_khz = 0; 7358 7359 /* Return to original core */ 7360 si_setcoreidx(sih, origidx); 7361 7362 return alp_khz; 7363} /* si_pmu_measure_alpclk */ 7364 7365void 7366si_pmu_set_4330_plldivs(si_t *sih, uint8 dacrate) 7367{ 7368 uint32 FVCO = si_pmu1_pllfvco0(sih)/1000; 7369 uint32 m1div, m2div, m3div, m4div, m5div, m6div; 7370 uint32 pllc1, pllc2; 7371 7372 m2div = m3div = m4div = m6div = FVCO/80; 7373 7374 m5div = FVCO/dacrate; 7375 7376 if (CST4330_CHIPMODE_SDIOD(sih->chipst)) 7377 m1div = FVCO/80; 7378 else 7379 m1div = FVCO/90; 7380 pllc1 = (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div << PMU1_PLL0_PC1_M2DIV_SHIFT) | 7381 (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div << PMU1_PLL0_PC1_M4DIV_SHIFT); 7382 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1); 7383 7384 pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, 0, 0); 7385 pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK); 7386 pllc2 |= ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) | (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT)); 7387 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2); 7388} /* si_pmu_set_4330_plldivs */ 7389 7390typedef struct cubkout2vreg { 7391 uint16 cbuck_mv; 7392 int8 vreg_val; 7393} cubkout2vreg_t; 7394 7395cubkout2vreg_t BCMATTACHDATA(cbuck2vreg_tbl)[] = { 7396 {1500, 0}, 7397 {1800, 0x17} 7398}; 7399 7400static int8 7401BCMATTACHFN(si_pmu_cbuckout_to_vreg_ctrl)(si_t *sih, uint16 cbuck_mv) 7402{ 7403 uint32 i; 7404 7405 for (i = 0; i < ARRAYSIZE(cbuck2vreg_tbl); i++) { 7406 if (cbuck_mv == cbuck2vreg_tbl[i].cbuck_mv) 7407 return cbuck2vreg_tbl[i].vreg_val; 7408 } 7409 return -1; 7410} 7411 7412/** Update min/max resources after SR-ASM download to d11 txfifo */ 7413void 7414si_pmu_res_minmax_update(si_t *sih, osl_t *osh) 7415{ 7416 uint32 min_mask = 0, max_mask = 0; 7417 chipcregs_t *cc; 7418 uint origidx; 7419 7420 /* Remember original core before switch to chipc */ 7421 origidx = si_coreidx(sih); 7422 cc = si_setcoreidx(sih, SI_CC_IDX); 7423 ASSERT(cc != NULL); 7424 7425 switch (CHIPID(sih->chip)) { 7426 case BCM4350_CHIP_ID: 7427 si_pmu_res_masks(sih, &min_mask, &max_mask); 7428 max_mask = 0; /* Only care about min_mask for now */ 7429 break; 7430 case BCM4335_CHIP_ID: 7431 /* Uses this min_mask for both SR and non-SR */ 7432 min_mask = RES4335_PMU_BG_PU; 7433 break; 7434 default: 7435 break; 7436 } 7437 7438 if (min_mask) 7439 W_REG(osh, &cc->min_res_mask, min_mask); 7440 7441 if (max_mask) 7442 W_REG(osh, &cc->max_res_mask, max_mask); 7443 7444 /* Return to original core */ 7445 si_setcoreidx(sih, origidx); 7446} /* si_pmu_res_minmax_update */ 7447