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