1 /*- 2 * SPDX-License-Identifier: ISC 3 * 4 * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org> 5 * Copyright (C) 2010, Broadcom Corporation. 6 * All rights reserved. 7 * 8 * This file is derived from the hndpmu.c source contributed by Broadcom 9 * to to the Linux staging repository, as well as later revisions of hndpmu.c 10 * distributed with the Asus RT-N16 firmware source code release. 11 * 12 * Permission to use, copy, modify, and/or distribute this software for any 13 * purpose with or without fee is hereby granted, provided that the above 14 * copyright notice and this permission notice appear in all copies. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 17 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 23 */ 24 25 #include <sys/cdefs.h> 26 __FBSDID("$FreeBSD$"); 27 28 #include <sys/types.h> 29 30 #include <dev/bhnd/bhndvar.h> 31 #include <dev/bhnd/cores/chipc/chipc.h> 32 #include <dev/bhnd/cores/chipc/chipcreg.h> 33 34 #include <dev/bhnd/bcma/bcma_dmp.h> 35 36 #include "bhnd_nvram_map.h" 37 38 #include "bhnd_pmureg.h" 39 #include "bhnd_pmuvar.h" 40 41 #include "bhnd_pmu_private.h" 42 43 #define PMU_LOG(_sc, _fmt, ...) do { \ 44 if (_sc->dev != NULL) \ 45 device_printf(_sc->dev, _fmt, ##__VA_ARGS__); \ 46 else \ 47 printf(_fmt, ##__VA_ARGS__); \ 48 } while (0) 49 50 #ifdef BCMDBG 51 #define PMU_DEBUG(_sc, _fmt, ...) PMU_LOG(_sc, _fmt, ##__VA_ARGS__) 52 #else 53 #define PMU_DEBUG(_sc, _fmt, ...) 54 #endif 55 56 typedef struct pmu0_xtaltab0 pmu0_xtaltab0_t; 57 typedef struct pmu1_xtaltab0 pmu1_xtaltab0_t; 58 59 /* PLL controls/clocks */ 60 static const pmu1_xtaltab0_t *bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc); 61 static const pmu1_xtaltab0_t *bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc); 62 63 static void bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal); 64 static uint32_t bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc); 65 static uint32_t bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc); 66 67 static void bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal); 68 static uint32_t bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc); 69 static uint32_t bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc); 70 static uint32_t bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc); 71 72 static uint32_t bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m); 73 74 static uint32_t bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, 75 u_int m); 76 77 /* PMU resources */ 78 static bool bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc); 79 static bool bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc); 80 static bool bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc); 81 static bool bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc); 82 static uint32_t bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs, 83 bool all); 84 static int bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc, 85 uint32_t *uptime); 86 static int bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin, 87 uint32_t *pmax); 88 89 static int bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc, 90 bhnd_pmu_spuravoid spuravoid); 91 static void bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc); 92 93 #define BHND_PMU_REV(_sc) \ 94 ((uint8_t)BHND_PMU_GET_BITS((_sc)->caps, BHND_PMU_CAP_REV)) 95 96 #define PMU_WAIT_CLKST(_sc, _val, _mask) \ 97 bhnd_core_clkctl_wait((_sc)->clkctl, (_val), (_mask)) 98 99 #define PMURES_BIT(_bit) \ 100 (1 << (BHND_PMU_ ## _bit)) 101 102 #define PMU_CST4330_SDIOD_CHIPMODE(_sc) \ 103 CHIPC_CST4330_CHIPMODE_SDIOD((_sc)->io->rd_chipst((_sc)->io_ctx)) 104 105 /** 106 * Initialize @p query state. 107 * 108 * @param[out] query On success, will be populated with a valid query instance 109 * state. 110 * @param dev The device owning @p query, or NULL. 111 * @param id The bhnd chip identification. 112 * @param io I/O callback functions. 113 * @param ctx I/O callback context. 114 * 115 * @retval 0 success 116 * @retval non-zero if the query state could not be initialized. 117 */ 118 int 119 bhnd_pmu_query_init(struct bhnd_pmu_query *query, device_t dev, 120 struct bhnd_chipid id, const struct bhnd_pmu_io *io, void *ctx) 121 { 122 query->dev = dev; 123 query->io = io; 124 query->io_ctx = ctx; 125 query->cid = id; 126 query->caps = BHND_PMU_READ_4(query, BHND_PMU_CAP); 127 128 return (0); 129 } 130 131 /** 132 * Release any resources held by @p query. 133 * 134 * @param query A query instance previously initialized via 135 * bhnd_pmu_query_init(). 136 */ 137 void 138 bhnd_pmu_query_fini(struct bhnd_pmu_query *query) 139 { 140 /* nothing to do */ 141 } 142 143 /** 144 * Perform an indirect register read. 145 * 146 * @param addr Offset of the address register. 147 * @param data Offset of the data register. 148 * @param reg Indirect register to be read. 149 */ 150 uint32_t 151 bhnd_pmu_ind_read(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr, 152 bus_size_t data, uint32_t reg) 153 { 154 io->wr4(addr, reg, io_ctx); 155 return (io->rd4(data, io_ctx)); 156 } 157 158 /** 159 * Perform an indirect register write. 160 * 161 * @param addr Offset of the address register. 162 * @param data Offset of the data register. 163 * @param reg Indirect register to be written. 164 * @param val Value to be written to @p reg. 165 * @param mask Only the bits defined by @p mask will be updated from @p val. 166 */ 167 void 168 bhnd_pmu_ind_write(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr, 169 bus_size_t data, uint32_t reg, uint32_t val, uint32_t mask) 170 { 171 uint32_t rval; 172 173 io->wr4(addr, reg, io_ctx); 174 175 if (mask != UINT32_MAX) { 176 rval = io->rd4(data, io_ctx); 177 rval &= ~mask | (val & mask); 178 } else { 179 rval = val; 180 } 181 182 io->wr4(data, rval, io_ctx); 183 } 184 185 /* Setup switcher voltage */ 186 void 187 bhnd_pmu_set_switcher_voltage(struct bhnd_pmu_softc *sc, uint8_t bb_voltage, 188 uint8_t rf_voltage) 189 { 190 BHND_PMU_REGCTRL_WRITE(sc, 0x01, (bb_voltage & 0x1f) << 22, ~0); 191 BHND_PMU_REGCTRL_WRITE(sc, 0x00, (rf_voltage & 0x1f) << 14, ~0); 192 } 193 194 int 195 bhnd_pmu_set_ldo_voltage(struct bhnd_pmu_softc *sc, uint8_t ldo, 196 uint8_t voltage) 197 { 198 uint32_t chipst; 199 uint32_t regctrl; 200 uint8_t shift; 201 uint8_t mask; 202 uint8_t addr; 203 204 switch (sc->cid.chip_id) { 205 case BHND_CHIPID_BCM4328: 206 case BHND_CHIPID_BCM5354: 207 switch (ldo) { 208 case SET_LDO_VOLTAGE_LDO1: 209 addr = 2; 210 shift = 17 + 8; 211 mask = 0xf; 212 break; 213 case SET_LDO_VOLTAGE_LDO2: 214 addr = 3; 215 shift = 1; 216 mask = 0xf; 217 break; 218 case SET_LDO_VOLTAGE_LDO3: 219 addr = 3; 220 shift = 9; 221 mask = 0xf; 222 break; 223 case SET_LDO_VOLTAGE_PAREF: 224 addr = 3; 225 shift = 17; 226 mask = 0x3f; 227 break; 228 default: 229 PMU_LOG(sc, "unknown BCM4328/BCM5354 LDO %hhu\n", ldo); 230 return (ENODEV); 231 } 232 break; 233 case BHND_CHIPID_BCM4312: 234 switch (ldo) { 235 case SET_LDO_VOLTAGE_PAREF: 236 addr = 0; 237 shift = 21; 238 mask = 0x3f; 239 break; 240 default: 241 PMU_LOG(sc, "unknown BCM4312 LDO %hhu\n", ldo); 242 return (ENODEV); 243 } 244 break; 245 case BHND_CHIPID_BCM4325: 246 switch (ldo) { 247 case SET_LDO_VOLTAGE_CLDO_PWM: 248 addr = 5; 249 shift = 9; 250 mask = 0xf; 251 break; 252 case SET_LDO_VOLTAGE_CLDO_BURST: 253 addr = 5; 254 shift = 13; 255 mask = 0xf; 256 break; 257 case SET_LDO_VOLTAGE_CBUCK_PWM: 258 addr = 3; 259 shift = 20; 260 mask = 0x1f; 261 /* Bit 116 & 119 are inverted in CLB for opt 2b */ 262 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 263 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) 264 voltage ^= 0x9; 265 break; 266 case SET_LDO_VOLTAGE_CBUCK_BURST: 267 addr = 3; 268 shift = 25; 269 mask = 0x1f; 270 /* Bit 121 & 124 are inverted in CLB for opt 2b */ 271 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 272 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) 273 voltage ^= 0x9; 274 break; 275 case SET_LDO_VOLTAGE_LNLDO1: 276 addr = 5; 277 shift = 17; 278 mask = 0x1f; 279 break; 280 case SET_LDO_VOLTAGE_LNLDO2_SEL: 281 addr = 6; 282 shift = 0; 283 mask = 0x1; 284 break; 285 default: 286 PMU_LOG(sc, "unknown BCM4325 LDO %hhu\n", ldo); 287 return (ENODEV); 288 } 289 break; 290 case BHND_CHIPID_BCM4336: 291 switch (ldo) { 292 case SET_LDO_VOLTAGE_CLDO_PWM: 293 addr = 4; 294 shift = 1; 295 mask = 0xf; 296 break; 297 case SET_LDO_VOLTAGE_CLDO_BURST: 298 addr = 4; 299 shift = 5; 300 mask = 0xf; 301 break; 302 case SET_LDO_VOLTAGE_LNLDO1: 303 addr = 4; 304 shift = 17; 305 mask = 0xf; 306 break; 307 default: 308 PMU_LOG(sc, "unknown BCM4336 LDO %hhu\n", ldo); 309 return (ENODEV); 310 } 311 break; 312 case BHND_CHIPID_BCM4330: 313 switch (ldo) { 314 case SET_LDO_VOLTAGE_CBUCK_PWM: 315 addr = 3; 316 shift = 0; 317 mask = 0x1f; 318 break; 319 default: 320 PMU_LOG(sc, "unknown BCM4330 LDO %hhu\n", ldo); 321 return (ENODEV); 322 } 323 break; 324 case BHND_CHIPID_BCM4331: 325 switch (ldo) { 326 case SET_LDO_VOLTAGE_PAREF: 327 addr = 1; 328 shift = 0; 329 mask = 0xf; 330 break; 331 default: 332 PMU_LOG(sc, "unknown BCM4331 LDO %hhu\n", ldo); 333 return (ENODEV); 334 } 335 break; 336 default: 337 PMU_LOG(sc, "cannot set LDO voltage on unsupported chip %hu\n", 338 sc->cid.chip_id); 339 return (ENODEV); 340 } 341 342 regctrl = (voltage & mask) << shift; 343 BHND_PMU_REGCTRL_WRITE(sc, addr, regctrl, mask << shift); 344 345 return (0); 346 } 347 348 /* d11 slow to fast clock transition time in slow clock cycles */ 349 #define D11SCC_SLOW2FAST_TRANSITION 2 350 351 int 352 bhnd_pmu_fast_pwrup_delay(struct bhnd_pmu_softc *sc, u_int *pwrup_delay) 353 { 354 uint32_t ilp; 355 uint32_t uptime; 356 u_int delay; 357 int error; 358 359 switch (sc->cid.chip_id) { 360 case BHND_CHIPID_BCM43224: 361 case BHND_CHIPID_BCM43225: 362 case BHND_CHIPID_BCM43421: 363 case BHND_CHIPID_BCM43235: 364 case BHND_CHIPID_BCM43236: 365 case BHND_CHIPID_BCM43238: 366 case BHND_CHIPID_BCM4331: 367 case BHND_CHIPID_BCM6362: 368 case BHND_CHIPID_BCM4313: 369 delay = 3700; 370 break; 371 372 case BHND_CHIPID_BCM4325: 373 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4325_HT_AVAIL, 374 &uptime); 375 if (error) 376 return (error); 377 378 ilp = bhnd_pmu_ilp_clock(&sc->query); 379 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * 380 ((1000000 + ilp - 1) / ilp); 381 delay = (11 * delay) / 10; 382 break; 383 384 case BHND_CHIPID_BCM4329: 385 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4329_HT_AVAIL, 386 &uptime); 387 if (error) 388 return (error); 389 390 ilp = bhnd_pmu_ilp_clock(&sc->query); 391 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * 392 ((1000000 + ilp - 1) / ilp); 393 delay = (11 * delay) / 10; 394 break; 395 396 case BHND_CHIPID_BCM4319: 397 delay = 3700; 398 break; 399 400 case BHND_CHIPID_BCM4336: 401 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4336_HT_AVAIL, 402 &uptime); 403 if (error) 404 return (error); 405 406 ilp = bhnd_pmu_ilp_clock(&sc->query); 407 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * 408 ((1000000 + ilp - 1) / ilp); 409 delay = (11 * delay) / 10; 410 break; 411 412 case BHND_CHIPID_BCM4330: 413 error = bhnd_pmu_res_uptime(sc, BHND_PMU_RES4330_HT_AVAIL, 414 &uptime); 415 if (error) 416 return (error); 417 418 ilp = bhnd_pmu_ilp_clock(&sc->query); 419 delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * 420 ((1000000 + ilp - 1) / ilp); 421 delay = (11 * delay) / 10; 422 break; 423 424 default: 425 delay = BHND_PMU_MAX_TRANSITION_DLY; 426 break; 427 } 428 429 *pwrup_delay = delay; 430 return (0); 431 } 432 433 uint32_t 434 bhnd_pmu_force_ilp(struct bhnd_pmu_softc *sc, bool force) 435 { 436 uint32_t orig; 437 uint32_t pctrl; 438 439 pctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 440 orig = pctrl; 441 442 if (force) 443 pctrl &= ~(BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN); 444 else 445 pctrl |= (BHND_PMU_CTRL_HT_REQ_EN | BHND_PMU_CTRL_ALP_REQ_EN); 446 447 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pctrl); 448 449 return (orig); 450 } 451 452 /* Setup resource up/down timers */ 453 typedef struct { 454 uint8_t resnum; 455 uint16_t updown; 456 } pmu_res_updown_t; 457 458 typedef bool (*pmu_res_filter) (struct bhnd_pmu_softc *sc); 459 460 /* Change resource dependencies masks */ 461 typedef struct { 462 uint32_t res_mask; /* resources (chip specific) */ 463 int8_t action; /* action */ 464 uint32_t depend_mask; /* changes to the dependencies mask */ 465 pmu_res_filter filter; /* action is taken when filter is NULL or returns true */ 466 } pmu_res_depend_t; 467 468 /* Resource dependencies mask change action */ 469 #define RES_DEPEND_SET 0 /* Override the dependencies mask */ 470 #define RES_DEPEND_ADD 1 /* Add to the dependencies mask */ 471 #define RES_DEPEND_REMOVE -1 /* Remove from the dependencies mask */ 472 473 static const pmu_res_updown_t bcm4328a0_res_updown[] = { 474 { 475 BHND_PMU_RES4328_EXT_SWITCHER_PWM, 0x0101}, { 476 BHND_PMU_RES4328_BB_SWITCHER_PWM, 0x1f01}, { 477 BHND_PMU_RES4328_BB_SWITCHER_BURST, 0x010f}, { 478 BHND_PMU_RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, { 479 BHND_PMU_RES4328_ILP_REQUEST, 0x0202}, { 480 BHND_PMU_RES4328_RADIO_SWITCHER_PWM, 0x0f01}, { 481 BHND_PMU_RES4328_RADIO_SWITCHER_BURST, 0x0f01}, { 482 BHND_PMU_RES4328_ROM_SWITCH, 0x0101}, { 483 BHND_PMU_RES4328_PA_REF_LDO, 0x0f01}, { 484 BHND_PMU_RES4328_RADIO_LDO, 0x0f01}, { 485 BHND_PMU_RES4328_AFE_LDO, 0x0f01}, { 486 BHND_PMU_RES4328_PLL_LDO, 0x0f01}, { 487 BHND_PMU_RES4328_BG_FILTBYP, 0x0101}, { 488 BHND_PMU_RES4328_TX_FILTBYP, 0x0101}, { 489 BHND_PMU_RES4328_RX_FILTBYP, 0x0101}, { 490 BHND_PMU_RES4328_XTAL_PU, 0x0101}, { 491 BHND_PMU_RES4328_XTAL_EN, 0xa001}, { 492 BHND_PMU_RES4328_BB_PLL_FILTBYP, 0x0101}, { 493 BHND_PMU_RES4328_RF_PLL_FILTBYP, 0x0101}, { 494 BHND_PMU_RES4328_BB_PLL_PU, 0x0701} 495 }; 496 497 static const pmu_res_depend_t bcm4328a0_res_depend[] = { 498 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */ 499 { 500 PMURES_BIT(RES4328_ILP_REQUEST), 501 RES_DEPEND_SET, 502 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | 503 PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL} 504 }; 505 506 static const pmu_res_updown_t bcm4325a0_res_updown[] = { 507 { 508 BHND_PMU_RES4325_XTAL_PU, 0x1501} 509 }; 510 511 static const pmu_res_depend_t bcm4325a0_res_depend[] = { 512 /* Adjust OTP PU resource dependencies - remove BB BURST */ 513 { 514 PMURES_BIT(RES4325_OTP_PU), 515 RES_DEPEND_REMOVE, 516 PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL}, 517 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */ 518 { 519 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL), 520 RES_DEPEND_ADD, 521 PMURES_BIT(RES4325_BUCK_BOOST_BURST) | 522 PMURES_BIT(RES4325_BUCK_BOOST_PWM), bhnd_pmu_res_depfltr_bb}, 523 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 524 { 525 PMURES_BIT(RES4325_HT_AVAIL), 526 RES_DEPEND_ADD, 527 PMURES_BIT(RES4325_RX_PWRSW_PU) | 528 PMURES_BIT(RES4325_TX_PWRSW_PU) | 529 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | 530 PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL}, 531 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */ 532 { 533 PMURES_BIT(RES4325_ILP_REQUEST) | 534 PMURES_BIT(RES4325_ABUCK_BURST) | 535 PMURES_BIT(RES4325_ABUCK_PWM) | 536 PMURES_BIT(RES4325_LNLDO1_PU) | 537 PMURES_BIT(RES4325C1_LNLDO2_PU) | 538 PMURES_BIT(RES4325_XTAL_PU) | 539 PMURES_BIT(RES4325_ALP_AVAIL) | 540 PMURES_BIT(RES4325_RX_PWRSW_PU) | 541 PMURES_BIT(RES4325_TX_PWRSW_PU) | 542 PMURES_BIT(RES4325_RFPLL_PWRSW_PU) | 543 PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | 544 PMURES_BIT(RES4325_AFE_PWRSW_PU) | 545 PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | 546 PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE, 547 PMURES_BIT(RES4325B0_CBUCK_LPOM) | 548 PMURES_BIT(RES4325B0_CBUCK_BURST) | 549 PMURES_BIT(RES4325B0_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb} 550 }; 551 552 static const pmu_res_updown_t bcm4315a0_res_updown[] = { 553 { 554 BHND_PMU_RES4315_XTAL_PU, 0x2501} 555 }; 556 557 static const pmu_res_depend_t bcm4315a0_res_depend[] = { 558 /* Adjust OTP PU resource dependencies - not need PALDO unless write */ 559 { 560 PMURES_BIT(RES4315_OTP_PU), 561 RES_DEPEND_REMOVE, 562 PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_npaldo}, 563 /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */ 564 { 565 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL), 566 RES_DEPEND_ADD, 567 PMURES_BIT(RES4315_PALDO_PU), bhnd_pmu_res_depfltr_paldo}, 568 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 569 { 570 PMURES_BIT(RES4315_HT_AVAIL), 571 RES_DEPEND_ADD, 572 PMURES_BIT(RES4315_RX_PWRSW_PU) | 573 PMURES_BIT(RES4315_TX_PWRSW_PU) | 574 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | 575 PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL}, 576 /* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */ 577 { 578 PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) | 579 PMURES_BIT(RES4315_LNLDO1_PU) | 580 PMURES_BIT(RES4315_OTP_PU) | 581 PMURES_BIT(RES4315_LNLDO2_PU) | 582 PMURES_BIT(RES4315_XTAL_PU) | 583 PMURES_BIT(RES4315_ALP_AVAIL) | 584 PMURES_BIT(RES4315_RX_PWRSW_PU) | 585 PMURES_BIT(RES4315_TX_PWRSW_PU) | 586 PMURES_BIT(RES4315_RFPLL_PWRSW_PU) | 587 PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | 588 PMURES_BIT(RES4315_AFE_PWRSW_PU) | 589 PMURES_BIT(RES4315_BBPLL_PWRSW_PU) | 590 PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE, 591 PMURES_BIT(RES4315_CBUCK_LPOM) | 592 PMURES_BIT(RES4315_CBUCK_BURST) | 593 PMURES_BIT(RES4315_CBUCK_PWM), bhnd_pmu_res_depfltr_ncb} 594 }; 595 596 /* 4329 specific. needs to come back this issue later */ 597 static const pmu_res_updown_t bcm4329_res_updown[] = { 598 { 599 BHND_PMU_RES4329_XTAL_PU, 0x1501} 600 }; 601 602 static const pmu_res_depend_t bcm4329_res_depend[] = { 603 /* Adjust HT Avail resource dependencies */ 604 { 605 PMURES_BIT(RES4329_HT_AVAIL), 606 RES_DEPEND_ADD, 607 PMURES_BIT(RES4329_CBUCK_LPOM) | 608 PMURES_BIT(RES4329_CBUCK_BURST) | 609 PMURES_BIT(RES4329_CBUCK_PWM) | 610 PMURES_BIT(RES4329_CLDO_PU) | 611 PMURES_BIT(RES4329_PALDO_PU) | 612 PMURES_BIT(RES4329_LNLDO1_PU) | 613 PMURES_BIT(RES4329_XTAL_PU) | 614 PMURES_BIT(RES4329_ALP_AVAIL) | 615 PMURES_BIT(RES4329_RX_PWRSW_PU) | 616 PMURES_BIT(RES4329_TX_PWRSW_PU) | 617 PMURES_BIT(RES4329_RFPLL_PWRSW_PU) | 618 PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | 619 PMURES_BIT(RES4329_AFE_PWRSW_PU) | 620 PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL} 621 }; 622 623 static const pmu_res_updown_t bcm4319a0_res_updown[] = { 624 { 625 BHND_PMU_RES4319_XTAL_PU, 0x3f01} 626 }; 627 628 static const pmu_res_depend_t bcm4319a0_res_depend[] = { 629 /* Adjust OTP PU resource dependencies - not need PALDO unless write */ 630 { 631 PMURES_BIT(RES4319_OTP_PU), 632 RES_DEPEND_REMOVE, 633 PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_npaldo}, 634 /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */ 635 { 636 PMURES_BIT(RES4319_HT_AVAIL), 637 RES_DEPEND_ADD, 638 PMURES_BIT(RES4319_PALDO_PU), bhnd_pmu_res_depfltr_paldo}, 639 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ 640 { 641 PMURES_BIT(RES4319_HT_AVAIL), 642 RES_DEPEND_ADD, 643 PMURES_BIT(RES4319_RX_PWRSW_PU) | 644 PMURES_BIT(RES4319_TX_PWRSW_PU) | 645 PMURES_BIT(RES4319_RFPLL_PWRSW_PU) | 646 PMURES_BIT(RES4319_LOGEN_PWRSW_PU) | 647 PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL} 648 }; 649 650 static const pmu_res_updown_t bcm4336a0_res_updown[] = { 651 { 652 BHND_PMU_RES4336_HT_AVAIL, 0x0D01} 653 }; 654 655 static const pmu_res_depend_t bcm4336a0_res_depend[] = { 656 /* Just a dummy entry for now */ 657 { 658 PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL} 659 }; 660 661 static const pmu_res_updown_t bcm4330a0_res_updown[] = { 662 { 663 BHND_PMU_RES4330_HT_AVAIL, 0x0e02} 664 }; 665 666 static const pmu_res_depend_t bcm4330a0_res_depend[] = { 667 /* Just a dummy entry for now */ 668 { 669 PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL} 670 }; 671 672 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF 673 * and WLAN PA */ 674 static bool 675 bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc) 676 { 677 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_BUCKBOOST)); 678 } 679 680 /* true if the power topology doesn't use the cbuck. Key on chiprev also if 681 * the chip is BCM4325. */ 682 static bool 683 bhnd_pmu_res_depfltr_ncb(struct bhnd_pmu_softc *sc) 684 { 685 if (sc->cid.chip_id == BHND_CHIPID_BCM4325 && sc->cid.chip_rev <= 1) 686 return (false); 687 688 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_NOCBUCK)); 689 } 690 691 /* true if the power topology uses the PALDO */ 692 static bool 693 bhnd_pmu_res_depfltr_paldo(struct bhnd_pmu_softc *sc) 694 { 695 return (BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO)); 696 } 697 698 /* true if the power topology doesn't use the PALDO */ 699 static bool 700 bhnd_pmu_res_depfltr_npaldo(struct bhnd_pmu_softc *sc) 701 { 702 return (!BHND_PMU_GET_FLAG(sc->board.board_flags, BHND_BFL_PALDO)); 703 } 704 705 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */ 706 static int 707 bhnd_pmu_res_masks(struct bhnd_pmu_softc *sc, uint32_t *pmin, uint32_t *pmax) 708 { 709 uint32_t max_mask, min_mask; 710 uint32_t chipst, otpsel; 711 uint32_t nval; 712 uint8_t rsrcs; 713 int error; 714 715 max_mask = 0; 716 min_mask = 0; 717 718 /* # resources */ 719 rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC); 720 721 /* determine min/max rsrc masks */ 722 switch (sc->cid.chip_id) { 723 case BHND_CHIPID_BCM4325: 724 /* If used by this device, enable the CBUCK */ 725 if (!bhnd_pmu_res_depfltr_ncb(sc)) 726 min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM); 727 728 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 729 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) 730 min_mask |= PMURES_BIT(RES4325B0_CLDO_PU); 731 732 /* Is OTP required? */ 733 otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_SPROM_OTP_SEL); 734 if (otpsel != CHIPC_CST_OTP_PWRDN) 735 min_mask |= PMURES_BIT(RES4325_OTP_PU); 736 737 /* Leave buck boost on in burst mode for certain boards */ 738 if (sc->board.board_flags & BHND_BFL_BUCKBOOST) { 739 switch (sc->board.board_type) { 740 case BHND_BOARD_BCM94325DEVBU: 741 case BHND_BOARD_BCM94325BGABU: 742 min_mask |= PMURES_BIT( 743 RES4325_BUCK_BOOST_BURST); 744 break; 745 } 746 } 747 748 /* Allow all resources to be turned on upon requests */ 749 max_mask = ~(~0 << rsrcs); 750 break; 751 752 case BHND_CHIPID_BCM4312: 753 /* default min_mask = 0x80000cbb is wrong */ 754 min_mask = 0xcbb; 755 /* 756 * max_mask = 0x7fff; 757 * pmu_res_updown_table_sz = 0; 758 * pmu_res_depend_table_sz = 0; 759 */ 760 break; 761 762 case BHND_CHIPID_BCM4322: 763 case BHND_CHIPID_BCM43221: 764 case BHND_CHIPID_BCM43231: 765 case BHND_CHIPID_BCM4342: 766 if (sc->cid.chip_rev >= 2) 767 break; 768 769 /* request ALP(can skip for A1) */ 770 min_mask = PMURES_BIT(RES4322_RF_LDO) | 771 PMURES_BIT(RES4322_XTAL_PU) | 772 PMURES_BIT(RES4322_ALP_AVAIL); 773 774 if (bhnd_get_attach_type(sc->chipc_dev) == BHND_ATTACH_NATIVE) { 775 min_mask |= 776 PMURES_BIT(RES4322_SI_PLL_ON) | 777 PMURES_BIT(RES4322_HT_SI_AVAIL) | 778 PMURES_BIT(RES4322_PHY_PLL_ON) | 779 PMURES_BIT(RES4322_OTP_PU) | 780 PMURES_BIT(RES4322_HT_PHY_AVAIL); 781 max_mask = 0x1ff; 782 } 783 break; 784 785 case BHND_CHIPID_BCM43222: 786 case BHND_CHIPID_BCM43111: 787 case BHND_CHIPID_BCM43112: 788 case BHND_CHIPID_BCM43224: 789 case BHND_CHIPID_BCM43225: 790 case BHND_CHIPID_BCM43421: 791 case BHND_CHIPID_BCM43226: 792 case BHND_CHIPID_BCM43420: 793 case BHND_CHIPID_BCM43235: 794 case BHND_CHIPID_BCM43236: 795 case BHND_CHIPID_BCM43238: 796 case BHND_CHIPID_BCM43234: 797 case BHND_CHIPID_BCM43237: 798 case BHND_CHIPID_BCM4331: 799 case BHND_CHIPID_BCM43431: 800 case BHND_CHIPID_BCM6362: 801 /* use chip default */ 802 break; 803 804 case BHND_CHIPID_BCM4328: 805 min_mask = 806 PMURES_BIT(RES4328_BB_SWITCHER_PWM) | 807 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | 808 PMURES_BIT(RES4328_XTAL_EN); 809 max_mask = 0xfffffff; 810 break; 811 812 case BHND_CHIPID_BCM5354: 813 /* Allow (but don't require) PLL to turn on */ 814 max_mask = 0xfffffff; 815 break; 816 817 case BHND_CHIPID_BCM4329: 818 /* Down to save the power. */ 819 if (sc->cid.chip_rev >= 0x2) { 820 min_mask = 821 PMURES_BIT(RES4329_CBUCK_LPOM) | 822 PMURES_BIT(RES4329_LNLDO1_PU) | 823 PMURES_BIT(RES4329_CLDO_PU); 824 } else { 825 min_mask = 826 PMURES_BIT(RES4329_CBUCK_LPOM) | 827 PMURES_BIT(RES4329_CLDO_PU); 828 } 829 830 /* Is OTP required? */ 831 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 832 otpsel = BHND_PMU_GET_BITS(chipst, CHIPC_CST4329_SPROM_OTP_SEL); 833 if (otpsel != CHIPC_CST_OTP_PWRDN) 834 min_mask |= PMURES_BIT(RES4329_OTP_PU); 835 836 /* Allow (but don't require) PLL to turn on */ 837 max_mask = 0x3ff63e; 838 break; 839 840 case BHND_CHIPID_BCM4319: 841 /* We only need a few resources to be kept on all the time */ 842 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | 843 PMURES_BIT(RES4319_CLDO_PU); 844 845 /* Allow everything else to be turned on upon requests */ 846 max_mask = ~(~0 << rsrcs); 847 break; 848 849 case BHND_CHIPID_BCM4336: 850 /* Down to save the power. */ 851 min_mask = 852 PMURES_BIT(RES4336_CBUCK_LPOM) | 853 PMURES_BIT(RES4336_CLDO_PU) | 854 PMURES_BIT(RES4336_LDO3P3_PU) | 855 PMURES_BIT(RES4336_OTP_PU) | 856 PMURES_BIT(RES4336_DIS_INT_RESET_PD); 857 /* Allow (but don't require) PLL to turn on */ 858 max_mask = 0x1ffffff; 859 break; 860 861 case BHND_CHIPID_BCM4330: 862 /* Down to save the power. */ 863 min_mask = 864 PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU) 865 | PMURES_BIT(RES4330_DIS_INT_RESET_PD) | 866 PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU); 867 /* Allow (but don't require) PLL to turn on */ 868 max_mask = 0xfffffff; 869 break; 870 871 case BHND_CHIPID_BCM4313: 872 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) | 873 PMURES_BIT(RES4313_XTAL_PU_RSRC) | 874 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) | 875 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC); 876 max_mask = 0xffff; 877 break; 878 default: 879 break; 880 } 881 882 /* Apply nvram override to min mask */ 883 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMIN, &nval); 884 if (error && error != ENOENT) { 885 PMU_LOG(sc, "NVRAM error reading %s: %d\n", 886 BHND_NVAR_RMIN, error); 887 return (error); 888 } else if (!error) { 889 PMU_DEBUG(sc, "Applying rmin=%#x to min_mask\n", nval); 890 min_mask = nval; 891 } 892 893 /* Apply nvram override to max mask */ 894 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMAX, &nval); 895 if (error && error != ENOENT) { 896 PMU_LOG(sc, "NVRAM error reading %s: %d\n", 897 BHND_NVAR_RMAX, error); 898 return (error); 899 } else if (!error) { 900 PMU_DEBUG(sc, "Applying rmax=%#x to max_mask\n", nval); 901 min_mask = nval; 902 } 903 904 if (pmin != NULL) 905 *pmin = min_mask; 906 907 if (pmax != NULL) 908 *pmax = max_mask; 909 910 return (0); 911 } 912 913 /* initialize PMU resources */ 914 int 915 bhnd_pmu_res_init(struct bhnd_pmu_softc *sc) 916 { 917 const pmu_res_updown_t *pmu_res_updown_table; 918 const pmu_res_depend_t *pmu_res_depend_table; 919 size_t pmu_res_updown_table_sz; 920 size_t pmu_res_depend_table_sz; 921 uint32_t max_mask, min_mask; 922 uint8_t rsrcs; 923 int error; 924 925 pmu_res_depend_table = NULL; 926 pmu_res_depend_table_sz = 0; 927 928 pmu_res_updown_table = NULL; 929 pmu_res_updown_table_sz = 0; 930 931 switch (sc->cid.chip_id) { 932 case BHND_CHIPID_BCM4315: 933 /* Optimize resources up/down timers */ 934 pmu_res_updown_table = bcm4315a0_res_updown; 935 pmu_res_updown_table_sz = nitems(bcm4315a0_res_updown); 936 937 /* Optimize resources dependencies */ 938 pmu_res_depend_table = bcm4315a0_res_depend; 939 pmu_res_depend_table_sz = nitems(bcm4315a0_res_depend); 940 break; 941 942 case BHND_CHIPID_BCM4325: 943 /* Optimize resources up/down timers */ 944 pmu_res_updown_table = bcm4325a0_res_updown; 945 pmu_res_updown_table_sz = nitems(bcm4325a0_res_updown); 946 947 /* Optimize resources dependencies */ 948 pmu_res_depend_table = bcm4325a0_res_depend; 949 pmu_res_depend_table_sz = nitems(bcm4325a0_res_depend); 950 break; 951 952 case BHND_CHIPID_BCM4328: 953 /* Optimize resources up/down timers */ 954 pmu_res_updown_table = bcm4328a0_res_updown; 955 pmu_res_updown_table_sz = nitems(bcm4328a0_res_updown); 956 957 /* Optimize resources dependencies */ 958 pmu_res_depend_table = bcm4328a0_res_depend; 959 pmu_res_depend_table_sz = nitems(bcm4328a0_res_depend); 960 break; 961 962 case BHND_CHIPID_BCM4329: 963 /* Optimize resources up/down timers */ 964 pmu_res_updown_table = bcm4329_res_updown; 965 pmu_res_updown_table_sz = nitems(bcm4329_res_updown); 966 967 /* Optimize resources dependencies */ 968 pmu_res_depend_table = bcm4329_res_depend; 969 pmu_res_depend_table_sz = nitems(bcm4329_res_depend); 970 break; 971 972 case BHND_CHIPID_BCM4319: 973 /* Optimize resources up/down timers */ 974 pmu_res_updown_table = bcm4319a0_res_updown; 975 pmu_res_updown_table_sz = nitems(bcm4319a0_res_updown); 976 977 /* Optimize resources dependencies masks */ 978 pmu_res_depend_table = bcm4319a0_res_depend; 979 pmu_res_depend_table_sz = nitems(bcm4319a0_res_depend); 980 break; 981 982 case BHND_CHIPID_BCM4336: 983 /* Optimize resources up/down timers */ 984 pmu_res_updown_table = bcm4336a0_res_updown; 985 pmu_res_updown_table_sz = nitems(bcm4336a0_res_updown); 986 987 /* Optimize resources dependencies masks */ 988 pmu_res_depend_table = bcm4336a0_res_depend; 989 pmu_res_depend_table_sz = nitems(bcm4336a0_res_depend); 990 break; 991 992 case BHND_CHIPID_BCM4330: 993 /* Optimize resources up/down timers */ 994 pmu_res_updown_table = bcm4330a0_res_updown; 995 pmu_res_updown_table_sz = nitems(bcm4330a0_res_updown); 996 997 /* Optimize resources dependencies masks */ 998 pmu_res_depend_table = bcm4330a0_res_depend; 999 pmu_res_depend_table_sz = nitems(bcm4330a0_res_depend); 1000 break; 1001 default: 1002 break; 1003 } 1004 1005 /* # resources */ 1006 rsrcs = BHND_PMU_GET_BITS(sc->caps, BHND_PMU_CAP_RC); 1007 1008 /* Program up/down timers */ 1009 for (size_t i = 0; i < pmu_res_updown_table_sz; i++) { 1010 const pmu_res_updown_t *updt; 1011 1012 KASSERT(pmu_res_updown_table != NULL, ("no updown tables")); 1013 1014 updt = &pmu_res_updown_table[pmu_res_updown_table_sz - i - 1]; 1015 1016 PMU_DEBUG(sc, "Changing rsrc %d res_updn_timer to %#x\n", 1017 updt->resnum, updt->updown); 1018 1019 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, updt->resnum); 1020 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, updt->updown); 1021 } 1022 1023 /* Apply nvram overrides to up/down timers */ 1024 for (uint8_t i = 0; i < rsrcs; i++) { 1025 char name[6]; 1026 uint32_t val; 1027 1028 snprintf(name, sizeof(name), "r%dt", i); 1029 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val); 1030 1031 if (error == ENOENT) { 1032 continue; 1033 } else if (error) { 1034 PMU_LOG(sc, "NVRAM error reading %s: %d\n", 1035 name, error); 1036 return (error); 1037 } 1038 1039 PMU_DEBUG(sc, "Applying %s=%d to rsrc %d res_updn_timer\n", 1040 name, val, i); 1041 1042 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); 1043 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, val); 1044 } 1045 1046 /* Program resource dependencies table */ 1047 for (size_t i = 0; i < pmu_res_depend_table_sz; i++) { 1048 const pmu_res_depend_t *rdep; 1049 pmu_res_filter filter; 1050 uint32_t depend_mask; 1051 1052 KASSERT(pmu_res_depend_table != NULL, ("no depend tables")); 1053 1054 rdep = &pmu_res_depend_table[pmu_res_depend_table_sz - i - 1]; 1055 filter = rdep->filter; 1056 1057 if (filter != NULL && !filter(sc)) 1058 continue; 1059 1060 for (uint8_t i = 0; i < rsrcs; i++) { 1061 if ((rdep->res_mask & BHND_PMURES_BIT(i)) == 0) 1062 continue; 1063 1064 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); 1065 depend_mask = BHND_PMU_READ_4(sc, 1066 BHND_PMU_RES_DEP_MASK); 1067 switch (rdep->action) { 1068 case RES_DEPEND_SET: 1069 PMU_DEBUG(sc, "Changing rsrc %hhu res_dep_mask to " 1070 "%#x\n", i, table->depend_mask); 1071 depend_mask = rdep->depend_mask; 1072 break; 1073 1074 case RES_DEPEND_ADD: 1075 PMU_DEBUG(sc, "Adding %#x to rsrc %hhu " 1076 "res_dep_mask\n", table->depend_mask, i); 1077 1078 depend_mask |= rdep->depend_mask; 1079 break; 1080 1081 case RES_DEPEND_REMOVE: 1082 PMU_DEBUG(sc, "Removing %#x from rsrc %hhu " 1083 "res_dep_mask\n", table->depend_mask, i); 1084 1085 depend_mask &= ~(rdep->depend_mask); 1086 break; 1087 1088 default: 1089 panic("unknown RES_DEPEND action: %d\n", 1090 rdep->action); 1091 break; 1092 } 1093 1094 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_DEP_MASK, 1095 depend_mask); 1096 } 1097 } 1098 1099 /* Apply nvram overrides to dependencies masks */ 1100 for (uint8_t i = 0; i < rsrcs; i++) { 1101 char name[6]; 1102 uint32_t val; 1103 1104 snprintf(name, sizeof(name), "r%dd", i); 1105 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, name, &val); 1106 1107 if (error == ENOENT) { 1108 continue; 1109 } else if (error) { 1110 PMU_LOG(sc, "NVRAM error reading %s: %d\n", name, 1111 error); 1112 return (error); 1113 } 1114 1115 PMU_DEBUG(sc, "Applying %s=%d to rsrc %d res_dep_mask\n", name, 1116 val, i); 1117 1118 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); 1119 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_DEP_MASK, val); 1120 } 1121 1122 /* Determine min/max rsrc masks */ 1123 if ((error = bhnd_pmu_res_masks(sc, &min_mask, &max_mask))) 1124 return (error); 1125 1126 /* It is required to program max_mask first and then min_mask */ 1127 1128 /* Program max resource mask */ 1129 if (max_mask != 0) { 1130 PMU_DEBUG(sc, "Changing max_res_mask to 0x%x\n", max_mask); 1131 BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask); 1132 } 1133 1134 /* Program min resource mask */ 1135 1136 if (min_mask != 0) { 1137 PMU_DEBUG(sc, "Changing min_res_mask to 0x%x\n", min_mask); 1138 BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask); 1139 } 1140 1141 /* Add some delay; allow resources to come up and settle. */ 1142 DELAY(2000); 1143 1144 return (0); 1145 } 1146 1147 /* setup pll and query clock speed */ 1148 struct pmu0_xtaltab0 { 1149 uint16_t freq; 1150 uint8_t xf; 1151 uint8_t wbint; 1152 uint32_t wbfrac; 1153 }; 1154 1155 /* the following table is based on 880Mhz fvco */ 1156 static const pmu0_xtaltab0_t pmu0_xtaltab0[] = { 1157 { 1158 12000, 1, 73, 349525}, { 1159 13000, 2, 67, 725937}, { 1160 14400, 3, 61, 116508}, { 1161 15360, 4, 57, 305834}, { 1162 16200, 5, 54, 336579}, { 1163 16800, 6, 52, 399457}, { 1164 19200, 7, 45, 873813}, { 1165 19800, 8, 44, 466033}, { 1166 20000, 9, 44, 0}, { 1167 25000, 10, 70, 419430}, { 1168 26000, 11, 67, 725937}, { 1169 30000, 12, 58, 699050}, { 1170 38400, 13, 45, 873813}, { 1171 40000, 14, 45, 0}, { 1172 0, 0, 0, 0} 1173 }; 1174 1175 #define PMU0_XTAL0_DEFAULT 8 1176 1177 /* setup pll and query clock speed */ 1178 struct pmu1_xtaltab0 { 1179 uint16_t fref; 1180 uint8_t xf; 1181 uint8_t p1div; 1182 uint8_t p2div; 1183 uint8_t ndiv_int; 1184 uint32_t ndiv_frac; 1185 }; 1186 1187 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = { 1188 { 1189 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { 1190 13000, 2, 1, 6, 0xb, 0x483483}, { 1191 14400, 3, 1, 10, 0xa, 0x1C71C7}, { 1192 15360, 4, 1, 5, 0xb, 0x755555}, { 1193 16200, 5, 1, 10, 0x5, 0x6E9E06}, { 1194 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { 1195 19200, 7, 1, 4, 0xb, 0x755555}, { 1196 19800, 8, 1, 11, 0x4, 0xA57EB}, { 1197 20000, 9, 1, 11, 0x4, 0x0}, { 1198 24000, 10, 3, 11, 0xa, 0x0}, { 1199 25000, 11, 5, 16, 0xb, 0x0}, { 1200 26000, 12, 1, 1, 0x21, 0xD89D89}, { 1201 30000, 13, 3, 8, 0xb, 0x0}, { 1202 37400, 14, 3, 1, 0x46, 0x969696}, { 1203 38400, 15, 1, 1, 0x16, 0xEAAAAA}, { 1204 40000, 16, 1, 2, 0xb, 0}, { 1205 0, 0, 0, 0, 0, 0} 1206 }; 1207 1208 /* the following table is based on 880Mhz fvco */ 1209 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = { 1210 { 1211 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { 1212 13000, 2, 1, 6, 0xb, 0x483483}, { 1213 14400, 3, 1, 10, 0xa, 0x1C71C7}, { 1214 15360, 4, 1, 5, 0xb, 0x755555}, { 1215 16200, 5, 1, 10, 0x5, 0x6E9E06}, { 1216 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { 1217 19200, 7, 1, 4, 0xb, 0x755555}, { 1218 19800, 8, 1, 11, 0x4, 0xA57EB}, { 1219 20000, 9, 1, 11, 0x4, 0x0}, { 1220 24000, 10, 3, 11, 0xa, 0x0}, { 1221 25000, 11, 5, 16, 0xb, 0x0}, { 1222 26000, 12, 1, 2, 0x10, 0xEC4EC4}, { 1223 30000, 13, 3, 8, 0xb, 0x0}, { 1224 33600, 14, 1, 2, 0xd, 0x186186}, { 1225 38400, 15, 1, 2, 0xb, 0x755555}, { 1226 40000, 16, 1, 2, 0xb, 0}, { 1227 0, 0, 0, 0, 0, 0} 1228 }; 1229 1230 #define PMU1_XTALTAB0_880_12000K 0 1231 #define PMU1_XTALTAB0_880_13000K 1 1232 #define PMU1_XTALTAB0_880_14400K 2 1233 #define PMU1_XTALTAB0_880_15360K 3 1234 #define PMU1_XTALTAB0_880_16200K 4 1235 #define PMU1_XTALTAB0_880_16800K 5 1236 #define PMU1_XTALTAB0_880_19200K 6 1237 #define PMU1_XTALTAB0_880_19800K 7 1238 #define PMU1_XTALTAB0_880_20000K 8 1239 #define PMU1_XTALTAB0_880_24000K 9 1240 #define PMU1_XTALTAB0_880_25000K 10 1241 #define PMU1_XTALTAB0_880_26000K 11 1242 #define PMU1_XTALTAB0_880_30000K 12 1243 #define PMU1_XTALTAB0_880_37400K 13 1244 #define PMU1_XTALTAB0_880_38400K 14 1245 #define PMU1_XTALTAB0_880_40000K 15 1246 1247 /* the following table is based on 1760Mhz fvco */ 1248 static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = { 1249 { 1250 12000, 1, 3, 44, 0x9, 0xFFFFEF}, { 1251 13000, 2, 1, 12, 0xb, 0x483483}, { 1252 14400, 3, 1, 20, 0xa, 0x1C71C7}, { 1253 15360, 4, 1, 10, 0xb, 0x755555}, { 1254 16200, 5, 1, 20, 0x5, 0x6E9E06}, { 1255 16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, { 1256 19200, 7, 1, 18, 0x5, 0x17B425}, { 1257 19800, 8, 1, 22, 0x4, 0xA57EB}, { 1258 20000, 9, 1, 22, 0x4, 0x0}, { 1259 24000, 10, 3, 22, 0xa, 0x0}, { 1260 25000, 11, 5, 32, 0xb, 0x0}, { 1261 26000, 12, 1, 4, 0x10, 0xEC4EC4}, { 1262 30000, 13, 3, 16, 0xb, 0x0}, { 1263 38400, 14, 1, 10, 0x4, 0x955555}, { 1264 40000, 15, 1, 4, 0xb, 0}, { 1265 0, 0, 0, 0, 0, 0} 1266 }; 1267 1268 /* table index */ 1269 #define PMU1_XTALTAB0_1760_12000K 0 1270 #define PMU1_XTALTAB0_1760_13000K 1 1271 #define PMU1_XTALTAB0_1760_14400K 2 1272 #define PMU1_XTALTAB0_1760_15360K 3 1273 #define PMU1_XTALTAB0_1760_16200K 4 1274 #define PMU1_XTALTAB0_1760_16800K 5 1275 #define PMU1_XTALTAB0_1760_19200K 6 1276 #define PMU1_XTALTAB0_1760_19800K 7 1277 #define PMU1_XTALTAB0_1760_20000K 8 1278 #define PMU1_XTALTAB0_1760_24000K 9 1279 #define PMU1_XTALTAB0_1760_25000K 10 1280 #define PMU1_XTALTAB0_1760_26000K 11 1281 #define PMU1_XTALTAB0_1760_30000K 12 1282 #define PMU1_XTALTAB0_1760_38400K 13 1283 #define PMU1_XTALTAB0_1760_40000K 14 1284 1285 /* the following table is based on 1440Mhz fvco */ 1286 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = { 1287 { 1288 12000, 1, 1, 1, 0x78, 0x0}, { 1289 13000, 2, 1, 1, 0x6E, 0xC4EC4E}, { 1290 14400, 3, 1, 1, 0x64, 0x0}, { 1291 15360, 4, 1, 1, 0x5D, 0xC00000}, { 1292 16200, 5, 1, 1, 0x58, 0xE38E38}, { 1293 16800, 6, 1, 1, 0x55, 0xB6DB6D}, { 1294 19200, 7, 1, 1, 0x4B, 0}, { 1295 19800, 8, 1, 1, 0x48, 0xBA2E8B}, { 1296 20000, 9, 1, 1, 0x48, 0x0}, { 1297 25000, 10, 1, 1, 0x39, 0x999999}, { 1298 26000, 11, 1, 1, 0x37, 0x627627}, { 1299 30000, 12, 1, 1, 0x30, 0x0}, { 1300 37400, 13, 2, 1, 0x4D, 0x15E76}, { 1301 38400, 13, 2, 1, 0x4B, 0x0}, { 1302 40000, 14, 2, 1, 0x48, 0x0}, { 1303 48000, 15, 2, 1, 0x3c, 0x0}, { 1304 0, 0, 0, 0, 0, 0} 1305 }; 1306 1307 /* table index */ 1308 #define PMU1_XTALTAB0_1440_12000K 0 1309 #define PMU1_XTALTAB0_1440_13000K 1 1310 #define PMU1_XTALTAB0_1440_14400K 2 1311 #define PMU1_XTALTAB0_1440_15360K 3 1312 #define PMU1_XTALTAB0_1440_16200K 4 1313 #define PMU1_XTALTAB0_1440_16800K 5 1314 #define PMU1_XTALTAB0_1440_19200K 6 1315 #define PMU1_XTALTAB0_1440_19800K 7 1316 #define PMU1_XTALTAB0_1440_20000K 8 1317 #define PMU1_XTALTAB0_1440_25000K 9 1318 #define PMU1_XTALTAB0_1440_26000K 10 1319 #define PMU1_XTALTAB0_1440_30000K 11 1320 #define PMU1_XTALTAB0_1440_37400K 12 1321 #define PMU1_XTALTAB0_1440_38400K 13 1322 #define PMU1_XTALTAB0_1440_40000K 14 1323 #define PMU1_XTALTAB0_1440_48000K 15 1324 1325 #define XTAL_FREQ_24000MHZ 24000 1326 #define XTAL_FREQ_30000MHZ 30000 1327 #define XTAL_FREQ_37400MHZ 37400 1328 #define XTAL_FREQ_48000MHZ 48000 1329 1330 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = { 1331 { 1332 12000, 1, 1, 1, 0x50, 0x0}, { 1333 13000, 2, 1, 1, 0x49, 0xD89D89}, { 1334 14400, 3, 1, 1, 0x42, 0xAAAAAA}, { 1335 15360, 4, 1, 1, 0x3E, 0x800000}, { 1336 16200, 5, 1, 1, 0x39, 0x425ED0}, { 1337 16800, 6, 1, 1, 0x39, 0x249249}, { 1338 19200, 7, 1, 1, 0x32, 0x0}, { 1339 19800, 8, 1, 1, 0x30, 0x7C1F07}, { 1340 20000, 9, 1, 1, 0x30, 0x0}, { 1341 25000, 10, 1, 1, 0x26, 0x666666}, { 1342 26000, 11, 1, 1, 0x24, 0xEC4EC4}, { 1343 30000, 12, 1, 1, 0x20, 0x0}, { 1344 37400, 13, 2, 1, 0x33, 0x563EF9}, { 1345 38400, 14, 2, 1, 0x32, 0x0}, { 1346 40000, 15, 2, 1, 0x30, 0x0}, { 1347 48000, 16, 2, 1, 0x28, 0x0}, { 1348 0, 0, 0, 0, 0, 0} 1349 }; 1350 1351 /* table index */ 1352 #define PMU1_XTALTAB0_960_12000K 0 1353 #define PMU1_XTALTAB0_960_13000K 1 1354 #define PMU1_XTALTAB0_960_14400K 2 1355 #define PMU1_XTALTAB0_960_15360K 3 1356 #define PMU1_XTALTAB0_960_16200K 4 1357 #define PMU1_XTALTAB0_960_16800K 5 1358 #define PMU1_XTALTAB0_960_19200K 6 1359 #define PMU1_XTALTAB0_960_19800K 7 1360 #define PMU1_XTALTAB0_960_20000K 8 1361 #define PMU1_XTALTAB0_960_25000K 9 1362 #define PMU1_XTALTAB0_960_26000K 10 1363 #define PMU1_XTALTAB0_960_30000K 11 1364 #define PMU1_XTALTAB0_960_37400K 12 1365 #define PMU1_XTALTAB0_960_38400K 13 1366 #define PMU1_XTALTAB0_960_40000K 14 1367 #define PMU1_XTALTAB0_960_48000K 15 1368 1369 /* select xtal table for each chip */ 1370 static const pmu1_xtaltab0_t * 1371 bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc) 1372 { 1373 switch (sc->cid.chip_id) { 1374 case BHND_CHIPID_BCM4315: 1375 return (pmu1_xtaltab0_1760); 1376 case BHND_CHIPID_BCM4319: 1377 return (pmu1_xtaltab0_1440); 1378 case BHND_CHIPID_BCM4325: 1379 return (pmu1_xtaltab0_880); 1380 case BHND_CHIPID_BCM4329: 1381 return (pmu1_xtaltab0_880_4329); 1382 case BHND_CHIPID_BCM4336: 1383 return (pmu1_xtaltab0_960); 1384 case BHND_CHIPID_BCM4330: 1385 if (PMU_CST4330_SDIOD_CHIPMODE(sc)) 1386 return (pmu1_xtaltab0_960); 1387 else 1388 return (pmu1_xtaltab0_1440); 1389 default: 1390 PMU_DEBUG(sc, "bhnd_pmu1_xtaltab0: Unknown chipid %#hx\n", 1391 sc->cid.chip_id); 1392 return (NULL); 1393 } 1394 } 1395 1396 /* select default xtal frequency for each chip */ 1397 static const pmu1_xtaltab0_t * 1398 bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc) 1399 { 1400 switch (sc->cid.chip_id) { 1401 case BHND_CHIPID_BCM4315: 1402 /* Default to 26000Khz */ 1403 return (&pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_26000K]); 1404 case BHND_CHIPID_BCM4319: 1405 /* Default to 30000Khz */ 1406 return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K]); 1407 case BHND_CHIPID_BCM4325: 1408 /* Default to 26000Khz */ 1409 return (&pmu1_xtaltab0_880[PMU1_XTALTAB0_880_26000K]); 1410 case BHND_CHIPID_BCM4329: 1411 /* Default to 38400Khz */ 1412 return (&pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]); 1413 case BHND_CHIPID_BCM4336: 1414 /* Default to 26000Khz */ 1415 return (&pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K]); 1416 case BHND_CHIPID_BCM4330: 1417 /* Default to 37400Khz */ 1418 if (PMU_CST4330_SDIOD_CHIPMODE(sc)) 1419 return (&pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]); 1420 else 1421 return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]); 1422 default: 1423 PMU_DEBUG(sc, "bhnd_pmu1_xtaldef0: Unknown chipid %#hx\n", 1424 sc->cid.chip_id); 1425 return (NULL); 1426 } 1427 } 1428 1429 /* select default pll fvco for each chip */ 1430 static uint32_t 1431 bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc) 1432 { 1433 switch (sc->cid.chip_id) { 1434 case BHND_CHIPID_BCM4329: 1435 return (FVCO_880); 1436 case BHND_CHIPID_BCM4319: 1437 return (FVCO_1440); 1438 case BHND_CHIPID_BCM4336: 1439 return (FVCO_960); 1440 case BHND_CHIPID_BCM4330: 1441 if (PMU_CST4330_SDIOD_CHIPMODE(sc)) 1442 return (FVCO_960); 1443 else 1444 return (FVCO_1440); 1445 default: 1446 PMU_DEBUG(sc, "bhnd_pmu1_pllfvco0: Unknown chipid %#hx\n", 1447 sc->cid.chip_id); 1448 return (0); 1449 } 1450 } 1451 1452 /* query alp/xtal clock frequency */ 1453 static uint32_t 1454 bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc) 1455 { 1456 const pmu1_xtaltab0_t *xt; 1457 uint32_t xf; 1458 1459 /* Find the frequency in the table */ 1460 xf = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1461 xf = BHND_PMU_GET_BITS(xf, BHND_PMU_CTRL_XTALFREQ); 1462 1463 for (xt = bhnd_pmu1_xtaltab0(sc); xt != NULL && xt->fref != 0; xt++) { 1464 if (xt->xf == xf) 1465 break; 1466 } 1467 1468 /* Could not find it so assign a default value */ 1469 if (xt == NULL || xt->fref == 0) 1470 xt = bhnd_pmu1_xtaldef0(sc); 1471 1472 if (xt == NULL || xt->fref == 0) { 1473 PMU_LOG(sc, "no matching ALP/XTAL frequency found\n"); 1474 return (0); 1475 } 1476 1477 return (xt->fref * 1000); 1478 } 1479 1480 /* Set up PLL registers in the PMU as per the crystal speed. */ 1481 static void 1482 bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal) 1483 { 1484 const pmu0_xtaltab0_t *xt; 1485 uint32_t pll_data, pll_mask; 1486 uint32_t pll_res; 1487 uint32_t pmu_ctrl; 1488 uint32_t xf; 1489 1490 /* Use h/w default PLL config */ 1491 if (xtal == 0) { 1492 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL " 1493 "configuration\n"); 1494 return; 1495 } 1496 1497 /* Find the frequency in the table */ 1498 for (xt = pmu0_xtaltab0; xt->freq; xt ++) { 1499 if (xt->freq == xtal) 1500 break; 1501 } 1502 1503 if (xt->freq == 0) 1504 xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; 1505 1506 PMU_DEBUG(sc, "XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, 1507 xt->xf); 1508 1509 /* Check current PLL state */ 1510 pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1511 xf = BHND_PMU_GET_BITS(pmu_ctrl, BHND_PMU_CTRL_XTALFREQ); 1512 if (xf == xt->xf) { 1513 #ifdef BCMUSBDEV 1514 if (sc->cid.chip_id == BHND_CHIPID_BCM4328) { 1515 bhnd_pmu0_sbclk4328(sc, 1516 BHND_PMU0_PLL0_PC0_DIV_ARM_88MHZ); 1517 return; 1518 } 1519 #endif /* BCMUSBDEV */ 1520 1521 PMU_DEBUG(sc, "PLL already programmed for %d.%d MHz\n", 1522 xt->freq / 1000, xt->freq % 1000); 1523 return; 1524 } 1525 1526 if (xf != 0) { 1527 PMU_DEBUG(sc, 1528 "Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", 1529 xt->freq / 1000, xt->freq % 1000, 1530 pmu0_xtaltab0[tmp-1].freq / 1000, 1531 pmu0_xtaltab0[tmp-1].freq % 1000); 1532 } else { 1533 PMU_DEBUG(sc, "Programming PLL for %d.%d MHz\n", 1534 xt->freq / 1000, xt->freq % 1000); 1535 } 1536 1537 /* Make sure the PLL is off */ 1538 switch (sc->cid.chip_id) { 1539 case BHND_CHIPID_BCM4328: 1540 pll_res = PMURES_BIT(RES4328_BB_PLL_PU); 1541 break; 1542 case BHND_CHIPID_BCM5354: 1543 pll_res = PMURES_BIT(RES5354_BB_PLL_PU); 1544 break; 1545 default: 1546 panic("unsupported chipid %#hx\n", sc->cid.chip_id); 1547 } 1548 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~pll_res); 1549 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~pll_res); 1550 1551 /* Wait for HT clock to shutdown. */ 1552 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1553 1554 PMU_DEBUG(sc, "Done masking\n"); 1555 1556 /* Write PDIV in pllcontrol[0] */ 1557 if (xt->freq >= BHND_PMU0_PLL0_PC0_PDIV_FREQ) { 1558 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0, 1559 BHND_PMU0_PLL0_PC0_PDIV_MASK, BHND_PMU0_PLL0_PC0_PDIV_MASK); 1560 } else { 1561 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL0, 0, 1562 BHND_PMU0_PLL0_PC0_PDIV_MASK); 1563 } 1564 1565 /* Write WILD in pllcontrol[1] */ 1566 pll_data = 1567 BHND_PMU_SET_BITS(xt->wbint, BHND_PMU0_PLL0_PC1_WILD_INT) | 1568 BHND_PMU_SET_BITS(xt->wbfrac, BHND_PMU0_PLL0_PC1_WILD_FRAC); 1569 1570 if (xt->wbfrac == 0) { 1571 pll_data |= BHND_PMU0_PLL0_PC1_STOP_MOD; 1572 } else { 1573 pll_data &= ~BHND_PMU0_PLL0_PC1_STOP_MOD; 1574 } 1575 1576 pll_mask = 1577 BHND_PMU0_PLL0_PC1_WILD_INT_MASK | 1578 BHND_PMU0_PLL0_PC1_WILD_FRAC_MASK; 1579 1580 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL1, pll_data, pll_mask); 1581 1582 /* Write WILD in pllcontrol[2] */ 1583 pll_data = BHND_PMU_SET_BITS(xt->wbint, BHND_PMU0_PLL0_PC2_WILD_INT); 1584 pll_mask = BHND_PMU0_PLL0_PC2_WILD_INT_MASK; 1585 BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL2, pll_data, pll_mask); 1586 1587 PMU_DEBUG(sc, "Done pll\n"); 1588 1589 /* Write XtalFreq. Set the divisor also. */ 1590 pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1591 pmu_ctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK|BHND_PMU_CTRL_XTALFREQ_MASK); 1592 1593 pmu_ctrl |= BHND_PMU_SET_BITS(((xt->freq + 127) / 128) - 1, 1594 BHND_PMU_CTRL_ILP_DIV); 1595 pmu_ctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ); 1596 1597 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmu_ctrl); 1598 } 1599 1600 /* query alp/xtal clock frequency */ 1601 static uint32_t 1602 bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc) 1603 { 1604 const pmu0_xtaltab0_t *xt; 1605 uint32_t xf; 1606 1607 /* Find the frequency in the table */ 1608 xf = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1609 xf = BHND_PMU_GET_BITS(xf, BHND_PMU_CTRL_XTALFREQ); 1610 for (xt = pmu0_xtaltab0; xt->freq; xt++) 1611 if (xt->xf == xf) 1612 break; 1613 1614 /* PLL must be configured before */ 1615 if (xt == NULL || xt->freq == 0) 1616 panic("unsupported frequency: %u", xf); 1617 1618 return (xt->freq * 1000); 1619 } 1620 1621 /* query CPU clock frequency */ 1622 static uint32_t 1623 bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc) 1624 { 1625 uint32_t tmp, divarm; 1626 uint32_t FVCO; 1627 #ifdef BCMDBG 1628 uint32_t pdiv, wbint, wbfrac, fvco; 1629 uint32_t freq; 1630 #endif 1631 1632 FVCO = FVCO_880; 1633 1634 /* Read divarm from pllcontrol[0] */ 1635 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL0); 1636 divarm = BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC0_DIV_ARM); 1637 1638 #ifdef BCMDBG 1639 /* Calculate fvco based on xtal freq, pdiv, and wild */ 1640 pdiv = tmp & BHND_PMU0_PLL0_PC0_PDIV_MASK; 1641 1642 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL1); 1643 wbfrac = BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC1_WILD_FRAC); 1644 wbint = BHND_PMU_GET_BITS(tmp, PMU0_PLL0_PC1_WILD_INT); 1645 1646 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU0_PLL0_PLLCTL2); 1647 wbint += BHND_PMU_GET_BITS(tmp, BHND_PMU0_PLL0_PC2_WILD_INT); 1648 1649 freq = bhnd_pmu0_alpclk0(sih, osh, cc) / 1000; 1650 1651 fvco = (freq * wbint) << 8; 1652 fvco += (freq * (wbfrac >> 10)) >> 2; 1653 fvco += (freq * (wbfrac & 0x3ff)) >> 10; 1654 fvco >>= 8; 1655 fvco >>= pdiv; 1656 fvco /= 1000; 1657 fvco *= 1000; 1658 1659 PMU_DEBUG(sc, "bhnd_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n", 1660 wbint, wbfrac, fvco); 1661 1662 FVCO = fvco; 1663 #endif /* BCMDBG */ 1664 1665 /* Return ARM/SB clock */ 1666 return FVCO / (divarm + BHND_PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000; 1667 } 1668 1669 /* Set up PLL registers in the PMU as per the crystal speed. */ 1670 static void 1671 bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal) 1672 { 1673 const pmu1_xtaltab0_t *xt; 1674 uint32_t buf_strength; 1675 uint32_t plladdr, plldata, pllmask; 1676 uint32_t pmuctrl; 1677 uint32_t FVCO; 1678 uint8_t ndiv_mode; 1679 1680 FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000; 1681 buf_strength = 0; 1682 ndiv_mode = 1; 1683 1684 /* Use h/w default PLL config */ 1685 if (xtal == 0) { 1686 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL " 1687 "configuration\n"); 1688 return; 1689 } 1690 1691 /* Find the frequency in the table */ 1692 for (xt = bhnd_pmu1_xtaltab0(&sc->query); xt != NULL && xt->fref != 0; 1693 xt++) 1694 { 1695 if (xt->fref == xtal) 1696 break; 1697 } 1698 1699 /* Check current PLL state, bail out if it has been programmed or 1700 * we don't know how to program it. 1701 */ 1702 if (xt == NULL || xt->fref == 0) { 1703 PMU_LOG(sc, "Unsupported XTAL frequency %d.%dMHz, skipping PLL " 1704 "configuration\n", xtal / 1000, xtal % 1000); 1705 return; 1706 } 1707 1708 /* For 4319 bootloader already programs the PLL but bootloader does not 1709 * program the PLL4 and PLL5. So Skip this check for 4319. */ 1710 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1711 if (BHND_PMU_GET_BITS(pmuctrl, BHND_PMU_CTRL_XTALFREQ) == xt->xf && 1712 sc->cid.chip_id != BHND_CHIPID_BCM4319 && 1713 sc->cid.chip_id != BHND_CHIPID_BCM4330) 1714 { 1715 PMU_DEBUG(sc, "PLL already programmed for %d.%dMHz\n", 1716 xt->fref / 1000, xt->fref % 1000); 1717 return; 1718 } 1719 1720 PMU_DEBUG(sc, "XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf); 1721 PMU_DEBUG(sc, "Programming PLL for %d.%dMHz\n", xt->fref / 1000, 1722 xt->fref % 1000); 1723 1724 switch (sc->cid.chip_id) { 1725 case BHND_CHIPID_BCM4325: 1726 /* Change the BBPLL drive strength to 2 for all channels */ 1727 buf_strength = 0x222222; 1728 1729 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1730 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | 1731 PMURES_BIT(RES4325_HT_AVAIL))); 1732 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1733 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | 1734 PMURES_BIT(RES4325_HT_AVAIL))); 1735 1736 /* Wait for HT clock to shutdown. */ 1737 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1738 break; 1739 1740 case BHND_CHIPID_BCM4329: 1741 /* Change the BBPLL drive strength to 8 for all channels */ 1742 buf_strength = 0x888888; 1743 1744 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1745 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | 1746 PMURES_BIT(RES4329_HT_AVAIL))); 1747 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1748 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | 1749 PMURES_BIT(RES4329_HT_AVAIL))); 1750 1751 /* Wait for HT clock to shutdown. */ 1752 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1753 1754 /* Initialize PLL4 */ 1755 plladdr = BHND_PMU1_PLL0_PLLCTL4; 1756 if (xt->fref == 38400) 1757 plldata = 0x200024C0; 1758 else if (xt->fref == 37400) 1759 plldata = 0x20004500; 1760 else if (xt->fref == 26000) 1761 plldata = 0x200024C0; 1762 else 1763 plldata = 0x200005C0; /* Chip Dflt Settings */ 1764 1765 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0); 1766 1767 /* Initialize PLL5 */ 1768 plladdr = BHND_PMU1_PLL0_PLLCTL5; 1769 1770 plldata = BHND_PMU_PLL_READ(sc, plladdr); 1771 plldata &= BHND_PMU1_PLL0_PC5_CLK_DRV_MASK; 1772 1773 if (xt->fref == 38400 || 1774 xt->fref == 37400 || 1775 xt->fref == 26000) { 1776 plldata |= 0x15; 1777 } else { 1778 plldata |= 0x25; /* Chip Dflt Settings */ 1779 } 1780 1781 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0); 1782 break; 1783 1784 case BHND_CHIPID_BCM4319: 1785 /* Change the BBPLL drive strength to 2 for all channels */ 1786 buf_strength = 0x222222; 1787 1788 /* Make sure the PLL is off */ 1789 /* WAR65104: Disable the HT_AVAIL resource first and then 1790 * after a delay (more than downtime for HT_AVAIL) remove the 1791 * BBPLL resource; backplane clock moves to ALP from HT. 1792 */ 1793 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1794 ~(PMURES_BIT(RES4319_HT_AVAIL))); 1795 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1796 ~(PMURES_BIT(RES4319_HT_AVAIL))); 1797 1798 DELAY(100); 1799 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1800 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 1801 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1802 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 1803 1804 DELAY(100); 1805 1806 /* Wait for HT clock to shutdown. */ 1807 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1808 1809 plldata = 0x200005c0; 1810 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, plldata, ~0); 1811 break; 1812 1813 case BHND_CHIPID_BCM4336: 1814 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1815 ~(PMURES_BIT(RES4336_HT_AVAIL) | 1816 PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 1817 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1818 ~(PMURES_BIT(RES4336_HT_AVAIL) | 1819 PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 1820 DELAY(100); 1821 1822 /* Wait for HT clock to shutdown. */ 1823 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1824 1825 break; 1826 1827 case BHND_CHIPID_BCM4330: 1828 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1829 ~(PMURES_BIT(RES4330_HT_AVAIL) | 1830 PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 1831 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1832 ~(PMURES_BIT(RES4330_HT_AVAIL) | 1833 PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 1834 DELAY(100); 1835 1836 /* Wait for HT clock to shutdown. */ 1837 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1838 1839 break; 1840 1841 default: 1842 panic("unsupported chipid %#hx\n", sc->cid.chip_id); 1843 } 1844 1845 PMU_DEBUG(sc, "Done masking\n"); 1846 1847 /* Write p1div and p2div to pllcontrol[0] */ 1848 plldata = 1849 BHND_PMU_SET_BITS(xt->p1div, BHND_PMU1_PLL0_PC0_P1DIV) | 1850 BHND_PMU_SET_BITS(xt->p2div, BHND_PMU1_PLL0_PC0_P2DIV); 1851 pllmask = BHND_PMU1_PLL0_PC0_P1DIV_MASK|BHND_PMU1_PLL0_PC0_P2DIV_MASK; 1852 1853 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1854 plldata &= ~(BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK); 1855 pllmask |= BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK; 1856 if (!xt->ndiv_frac) { 1857 plldata |= BHND_PMU_SET_BITS(1, 1858 BHND_PMU1_PLL0_PC0_BYPASS_SDMOD); 1859 } 1860 } 1861 1862 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, plldata, pllmask); 1863 1864 if (sc->cid.chip_id == BHND_CHIPID_BCM4330) 1865 bhnd_pmu_set_4330_plldivs(sc); 1866 1867 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) { 1868 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 1869 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_VAL, 1870 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_MASK); 1871 } 1872 1873 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ 1874 if (sc->cid.chip_id == BHND_CHIPID_BCM4336 || 1875 sc->cid.chip_id == BHND_CHIPID_BCM4330) 1876 { 1877 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB; 1878 } else if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1879 if (!(xt->ndiv_frac)) 1880 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_INT; 1881 else 1882 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB; 1883 } else { 1884 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MASH; 1885 } 1886 1887 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 1888 BHND_PMU_SET_BITS(xt->ndiv_int, BHND_PMU1_PLL0_PC2_NDIV_INT) | 1889 BHND_PMU_SET_BITS(ndiv_mode, BHND_PMU1_PLL0_PC2_NDIV_MODE), 1890 BHND_PMU1_PLL0_PC2_NDIV_INT_MASK | 1891 BHND_PMU1_PLL0_PC2_NDIV_MODE_MASK); 1892 1893 /* Write ndiv_frac to pllcontrol[3] */ 1894 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 1895 BHND_PMU_SET_BITS(xt->ndiv_frac, BHND_PMU1_PLL0_PC3_NDIV_FRAC), 1896 BHND_PMU1_PLL0_PC3_NDIV_FRAC_MASK); 1897 1898 /* Writing to pllcontrol[4] */ 1899 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1900 uint8_t xs; 1901 1902 if (!xt->ndiv_frac) 1903 plldata = 0x200005c0; 1904 else 1905 plldata = 0x202C2820; 1906 1907 if (FVCO < 1600) 1908 xs = 4; 1909 else 1910 xs = 7; 1911 1912 plldata &= ~(BHND_PMU1_PLL0_PC4_KVCO_XS_MASK); 1913 plldata |= BHND_PMU_SET_BITS(xs, BHND_PMU1_PLL0_PC4_KVCO_XS); 1914 BHND_PMU_WRITE_4(sc, BHND_PMU1_PLL0_PLLCTL4, plldata); 1915 } 1916 1917 /* Write clock driving strength to pllcontrol[5] */ 1918 if (buf_strength) { 1919 PMU_DEBUG(sc, "Adjusting PLL buffer drive strength: %x\n", 1920 buf_strength); 1921 1922 plldata = BHND_PMU_SET_BITS(buf_strength, 1923 BHND_PMU1_PLL0_PC5_CLK_DRV); 1924 pllmask = BHND_PMU1_PLL0_PC5_CLK_DRV_MASK; 1925 1926 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1927 pllmask |= 1928 BHND_PMU1_PLL0_PC5_VCO_RNG_MASK | 1929 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK; 1930 1931 if (!xt->ndiv_frac) { 1932 plldata |= BHND_PMU_SET_BITS(0x25, 1933 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32); 1934 } else { 1935 plldata |= BHND_PMU_SET_BITS(0x15, 1936 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32); 1937 } 1938 1939 if (FVCO >= 1600) { 1940 plldata |= BHND_PMU_SET_BITS(0x1, 1941 BHND_PMU1_PLL0_PC5_VCO_RNG); 1942 } 1943 } 1944 1945 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, plldata, 1946 pllmask); 1947 } 1948 1949 PMU_DEBUG(sc, "Done pll\n"); 1950 1951 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs 1952 * to be updated. 1953 */ 1954 if (sc->cid.chip_id == BHND_CHIPID_BCM4319 && 1955 xt->fref != XTAL_FREQ_30000MHZ) 1956 { 1957 uint32_t pll_sel; 1958 1959 switch (xt->fref) { 1960 case XTAL_FREQ_24000MHZ: 1961 pll_sel = BHND_PMU_CCTRL4319USB_24MHZ_PLL_SEL; 1962 break; 1963 case XTAL_FREQ_48000MHZ: 1964 pll_sel = BHND_PMU_CCTRL4319USB_48MHZ_PLL_SEL; 1965 break; 1966 default: 1967 panic("unsupported 4319USB XTAL frequency: %hu\n", 1968 xt->fref); 1969 } 1970 1971 BHND_PMU_CCTRL_WRITE(sc, BHND_PMU1_PLL0_CHIPCTL2, 1972 BHND_PMU_SET_BITS(pll_sel, BHND_PMU_CCTRL4319USB_XTAL_SEL), 1973 BHND_PMU_CCTRL4319USB_XTAL_SEL_MASK); 1974 } 1975 1976 /* Flush deferred pll control registers writes */ 1977 if (BHND_PMU_REV(sc) >= 2) 1978 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_PLL_PLLCTL_UPD); 1979 1980 /* Write XtalFreq. Set the divisor also. */ 1981 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1982 pmuctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK | BHND_PMU_CTRL_XTALFREQ_MASK); 1983 pmuctrl |= BHND_PMU_SET_BITS(((xt->fref + 127) / 128) - 1, 1984 BHND_PMU_CTRL_ILP_DIV); 1985 pmuctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ); 1986 1987 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) { 1988 /* clear the htstretch before clearing HTReqEn */ 1989 BHND_PMU_AND_4(sc, BHND_PMU_CLKSTRETCH, ~BHND_PMU_CLKSTRETCH); 1990 pmuctrl &= ~BHND_PMU_CTRL_HT_REQ_EN; 1991 } 1992 1993 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmuctrl); 1994 } 1995 1996 /* query the CPU clock frequency */ 1997 static uint32_t 1998 bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc) 1999 { 2000 uint32_t tmp, m1div; 2001 #ifdef BCMDBG 2002 uint32_t ndiv_int, ndiv_frac, p2div, p1div, fvco; 2003 uint32_t fref; 2004 #endif 2005 uint32_t FVCO = bhnd_pmu1_pllfvco0(sc); 2006 2007 /* Read m1div from pllcontrol[1] */ 2008 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL1); 2009 m1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC1_M1DIV); 2010 2011 #ifdef BCMDBG 2012 /* Read p2div/p1div from pllcontrol[0] */ 2013 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL0); 2014 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P2DIV); 2015 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P1DIV); 2016 2017 /* Calculate fvco based on xtal freq and ndiv and pdiv */ 2018 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL2); 2019 ndiv_int = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC2_NDIV_INT); 2020 2021 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL3); 2022 ndiv_frac = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC3_NDIV_FRAC); 2023 2024 fref = bhnd_pmu1_alpclk0(sc) / 1000; 2025 2026 fvco = (fref * ndiv_int) << 8; 2027 fvco += (fref * (ndiv_frac >> 12)) >> 4; 2028 fvco += (fref * (ndiv_frac & 0xfff)) >> 12; 2029 fvco >>= 8; 2030 fvco *= p2div; 2031 fvco /= p1div; 2032 fvco /= 1000; 2033 fvco *= 1000; 2034 2035 PMU_DEBUG(sc, "bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u " 2036 "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco); 2037 2038 FVCO = fvco; 2039 #endif /* BCMDBG */ 2040 2041 /* Return ARM/SB clock */ 2042 return (FVCO / m1div * 1000); 2043 } 2044 2045 /* initialize PLL */ 2046 void 2047 bhnd_pmu_pll_init(struct bhnd_pmu_softc *sc, u_int xtalfreq) 2048 { 2049 uint32_t max_mask, min_mask; 2050 uint32_t res_ht, res_pll; 2051 2052 switch (sc->cid.chip_id) { 2053 case BHND_CHIPID_BCM4312: 2054 /* assume default works */ 2055 break; 2056 case BHND_CHIPID_BCM4322: 2057 case BHND_CHIPID_BCM43221: 2058 case BHND_CHIPID_BCM43231: 2059 case BHND_CHIPID_BCM4342: 2060 if (sc->cid.chip_rev != 0) 2061 break; 2062 2063 min_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK); 2064 max_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK); 2065 res_ht = PMURES_BIT(RES4322_HT_SI_AVAIL); 2066 res_pll = PMURES_BIT(RES4322_SI_PLL_ON); 2067 2068 /* Have to remove HT Avail request before powering off PLL */ 2069 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_ht); 2070 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_ht); 2071 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 2072 2073 /* Make sure the PLL is off */ 2074 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_pll); 2075 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_pll); 2076 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 2077 2078 DELAY(1000); 2079 2080 BHND_PMU_PLL_WRITE(sc, BHND_PMU2_SI_PLL_PLLCTL, 0x380005c0, ~0); 2081 DELAY(100); 2082 2083 BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask); 2084 DELAY(100); 2085 BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask); 2086 DELAY(100); 2087 2088 break; 2089 case BHND_CHIPID_BCM4325: 2090 bhnd_pmu1_pllinit0(sc, xtalfreq); 2091 break; 2092 case BHND_CHIPID_BCM4328: 2093 bhnd_pmu0_pllinit0(sc, xtalfreq); 2094 break; 2095 case BHND_CHIPID_BCM5354: 2096 if (xtalfreq == 0) 2097 xtalfreq = 25000; 2098 bhnd_pmu0_pllinit0(sc, xtalfreq); 2099 break; 2100 case BHND_CHIPID_BCM4329: 2101 if (xtalfreq == 0) 2102 xtalfreq = 38400; 2103 bhnd_pmu1_pllinit0(sc, xtalfreq); 2104 break; 2105 2106 case BHND_CHIPID_BCM4313: 2107 case BHND_CHIPID_BCM43222: 2108 case BHND_CHIPID_BCM43111: 2109 case BHND_CHIPID_BCM43112: 2110 case BHND_CHIPID_BCM43224: 2111 case BHND_CHIPID_BCM43225: 2112 case BHND_CHIPID_BCM43420: 2113 case BHND_CHIPID_BCM43421: 2114 case BHND_CHIPID_BCM43226: 2115 case BHND_CHIPID_BCM43235: 2116 case BHND_CHIPID_BCM43236: 2117 case BHND_CHIPID_BCM43238: 2118 case BHND_CHIPID_BCM43234: 2119 case BHND_CHIPID_BCM43237: 2120 case BHND_CHIPID_BCM4331: 2121 case BHND_CHIPID_BCM43431: 2122 case BHND_CHIPID_BCM43131: 2123 case BHND_CHIPID_BCM43227: 2124 case BHND_CHIPID_BCM43228: 2125 case BHND_CHIPID_BCM43428: 2126 case BHND_CHIPID_BCM6362: 2127 /* assume default works */ 2128 break; 2129 2130 case BHND_CHIPID_BCM4315: 2131 case BHND_CHIPID_BCM4319: 2132 case BHND_CHIPID_BCM4336: 2133 case BHND_CHIPID_BCM4330: 2134 bhnd_pmu1_pllinit0(sc, xtalfreq); 2135 break; 2136 default: 2137 PMU_DEBUG("No PLL init done for chip %#hx rev %d pmurev %d\n", 2138 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc)); 2139 break; 2140 } 2141 } 2142 2143 /** 2144 * Return the ALP/XTAL clock frequency, in Hz. 2145 * 2146 * @param sc PMU query instance. 2147 */ 2148 uint32_t 2149 bhnd_pmu_alp_clock(struct bhnd_pmu_query *sc) 2150 { 2151 uint32_t clock; 2152 2153 clock = BHND_PMU_ALP_CLOCK; 2154 switch (sc->cid.chip_id) { 2155 case BHND_CHIPID_BCM4328: 2156 case BHND_CHIPID_BCM5354: 2157 clock = bhnd_pmu0_alpclk0(sc); 2158 break; 2159 case BHND_CHIPID_BCM4315: 2160 case BHND_CHIPID_BCM4319: 2161 case BHND_CHIPID_BCM4325: 2162 case BHND_CHIPID_BCM4329: 2163 case BHND_CHIPID_BCM4330: 2164 case BHND_CHIPID_BCM4336: 2165 clock = bhnd_pmu1_alpclk0(sc); 2166 break; 2167 case BHND_CHIPID_BCM4312: 2168 case BHND_CHIPID_BCM4322: 2169 case BHND_CHIPID_BCM43221: 2170 case BHND_CHIPID_BCM43231: 2171 case BHND_CHIPID_BCM43222: 2172 case BHND_CHIPID_BCM43111: 2173 case BHND_CHIPID_BCM43112: 2174 case BHND_CHIPID_BCM43224: 2175 case BHND_CHIPID_BCM43225: 2176 case BHND_CHIPID_BCM43420: 2177 case BHND_CHIPID_BCM43421: 2178 case BHND_CHIPID_BCM43226: 2179 case BHND_CHIPID_BCM43235: 2180 case BHND_CHIPID_BCM43236: 2181 case BHND_CHIPID_BCM43238: 2182 case BHND_CHIPID_BCM43234: 2183 case BHND_CHIPID_BCM43237: 2184 case BHND_CHIPID_BCM4331: 2185 case BHND_CHIPID_BCM43431: 2186 case BHND_CHIPID_BCM43131: 2187 case BHND_CHIPID_BCM43227: 2188 case BHND_CHIPID_BCM43228: 2189 case BHND_CHIPID_BCM43428: 2190 case BHND_CHIPID_BCM6362: 2191 case BHND_CHIPID_BCM4342: 2192 case BHND_CHIPID_BCM4716: 2193 case BHND_CHIPID_BCM4748: 2194 case BHND_CHIPID_BCM47162: 2195 case BHND_CHIPID_BCM4313: 2196 case BHND_CHIPID_BCM5357: 2197 case BHND_CHIPID_BCM4749: 2198 case BHND_CHIPID_BCM53572: 2199 /* always 20Mhz */ 2200 clock = 20000 * 1000; 2201 break; 2202 case BHND_CHIPID_BCM5356: 2203 case BHND_CHIPID_BCM4706: 2204 /* always 25Mhz */ 2205 clock = 25000 * 1000; 2206 break; 2207 default: 2208 PMU_DEBUG("No ALP clock specified " 2209 "for chip %s rev %d pmurev %d, using default %d Hz\n", 2210 bcm_chipname(sih->chip, chn, 8), sih->chiprev, 2211 sih->pmurev, clock); 2212 break; 2213 } 2214 2215 return (clock); 2216 } 2217 2218 /* Find the output of the "m" pll divider given pll controls that start with 2219 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. 2220 */ 2221 static uint32_t 2222 bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m) 2223 { 2224 uint32_t div; 2225 uint32_t fc; 2226 uint32_t ndiv; 2227 uint32_t p1, p2; 2228 uint32_t tmp; 2229 2230 if ((pll0 & 3) || (pll0 > BHND_PMU4716_MAINPLL_PLL0)) { 2231 PMU_LOG(sc, "%s: Bad pll0: %d", __func__, pll0); 2232 return (0); 2233 } 2234 2235 /* Strictly there is an m5 divider, but I'm not sure we use it */ 2236 if ((m == 0) || (m > 4)) { 2237 PMU_LOG(sc, "%s: Bad m divider: %d", __func__, m); 2238 return (0); 2239 } 2240 2241 if (sc->cid.chip_id == BHND_CHIPID_BCM5357 || 2242 sc->cid.chip_id == BHND_CHIPID_BCM4749) 2243 { 2244 /* Detect failure in clock setting */ 2245 tmp = sc->io->rd_chipst(sc->io_ctx); 2246 if ((tmp & 0x40000) != 0) 2247 return (133 * 1000000); 2248 } 2249 2250 /* Fetch p1 and p2 */ 2251 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2252 pll0 + BHND_PMU5_PLL_P1P2_OFF); 2253 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2254 2255 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2256 p1 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P1); 2257 p2 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P2); 2258 2259 /* Fetch div */ 2260 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2261 pll0 + BHND_PMU5_PLL_M14_OFF); 2262 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2263 2264 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2265 div = (tmp >> ((m - 1) * BHND_PMU5_PLL_MDIV_WIDTH)); 2266 div &= BHND_PMU5_PLL_MDIV_MASK; 2267 2268 /* Fetch ndiv */ 2269 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2270 pll0 + BHND_PMU5_PLL_NM5_OFF); 2271 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2272 2273 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2274 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_NDIV); 2275 2276 /* Do calculation in Mhz */ 2277 fc = bhnd_pmu_alp_clock(sc) / 1000000; 2278 fc = (p1 * ndiv * fc) / p2; 2279 2280 PMU_DEBUG(sc, "%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, " 2281 "clock=%d\n", __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div); 2282 2283 /* Return clock in Hertz */ 2284 return ((fc / div) * 1000000); 2285 } 2286 2287 static uint32_t 2288 bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m) 2289 { 2290 uint32_t chipst, clock; 2291 uint32_t ndiv, p1div, p2div, tmp; 2292 2293 /* Get N, P1 and P2 dividers to determine CPU clock */ 2294 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2295 pll0 + BHND_PMU6_4706_PROCPLL_OFF); 2296 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2297 2298 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2299 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_NDIV_INT); 2300 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P1DIV); 2301 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P2DIV); 2302 2303 /* Fixed 25MHz reference clock */ 2304 clock = 25 * 1000 * 1000; 2305 2306 /* The low-cost bonding uses an input divider of 4; otherwise, 2 */ 2307 chipst = sc->io->rd_chipst(sc->io_ctx); 2308 if (chipst & CHIPC_CST4706_LOWCOST_PKG) 2309 clock /= 4; 2310 else 2311 clock /= 2; 2312 2313 clock *= ndiv * p2div / p1div; 2314 2315 switch (m) { 2316 case BHND_PMU6_MAINPLL_CPU: 2317 return (clock); 2318 case BHND_PMU6_MAINPLL_MEM: 2319 return (clock / 2); 2320 case BHND_PMU6_MAINPLL_SI: 2321 return (clock / 4); 2322 default: 2323 PMU_LOG(sc, "bad m divider: %d", m); 2324 return (0); 2325 } 2326 } 2327 2328 /** 2329 * Return the backplane clock frequency, in Hz. 2330 * 2331 * On designs that feed the same clock to both backplane 2332 * and CPU, this returns the CPU clock speed. 2333 * 2334 * @param sc PMU query instance. 2335 */ 2336 uint32_t 2337 bhnd_pmu_si_clock(struct bhnd_pmu_query *sc) 2338 { 2339 uint32_t chipst; 2340 uint32_t clock; 2341 2342 clock = BHND_PMU_HT_CLOCK; 2343 2344 switch (sc->cid.chip_id) { 2345 case BHND_CHIPID_BCM4322: 2346 case BHND_CHIPID_BCM43221: 2347 case BHND_CHIPID_BCM43231: 2348 case BHND_CHIPID_BCM43222: 2349 case BHND_CHIPID_BCM43111: 2350 case BHND_CHIPID_BCM43112: 2351 case BHND_CHIPID_BCM43224: 2352 case BHND_CHIPID_BCM43420: 2353 case BHND_CHIPID_BCM43225: 2354 case BHND_CHIPID_BCM43421: 2355 case BHND_CHIPID_BCM43226: 2356 case BHND_CHIPID_BCM4331: 2357 case BHND_CHIPID_BCM43431: 2358 case BHND_CHIPID_BCM6362: 2359 case BHND_CHIPID_BCM4342: 2360 /* 96MHz backplane clock */ 2361 clock = 96000 * 1000; 2362 break; 2363 2364 case BHND_CHIPID_BCM4716: 2365 case BHND_CHIPID_BCM4748: 2366 case BHND_CHIPID_BCM47162: 2367 clock = bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0, 2368 BHND_PMU5_MAINPLL_SI); 2369 break; 2370 2371 case BHND_CHIPID_BCM4325: 2372 clock = bhnd_pmu1_cpuclk0(sc); 2373 break; 2374 2375 case BHND_CHIPID_BCM4328: 2376 clock = bhnd_pmu0_cpuclk0(sc); 2377 break; 2378 2379 case BHND_CHIPID_BCM4329: 2380 if (sc->cid.chip_rev == 0) 2381 clock = 38400 * 1000; 2382 else 2383 clock = bhnd_pmu1_cpuclk0(sc); 2384 break; 2385 2386 case BHND_CHIPID_BCM4315: 2387 case BHND_CHIPID_BCM4319: 2388 case BHND_CHIPID_BCM4336: 2389 case BHND_CHIPID_BCM4330: 2390 clock = bhnd_pmu1_cpuclk0(sc); 2391 break; 2392 2393 case BHND_CHIPID_BCM4312: 2394 case BHND_CHIPID_BCM4313: 2395 /* 80MHz backplane clock */ 2396 clock = 80000 * 1000; 2397 break; 2398 2399 case BHND_CHIPID_BCM43234: 2400 case BHND_CHIPID_BCM43235: 2401 case BHND_CHIPID_BCM43236: 2402 case BHND_CHIPID_BCM43238: 2403 chipst = sc->io->rd_chipst(sc->io_ctx); 2404 if (chipst & CHIPC_CST43236_BP_CLK) 2405 clock = 120000 * 1000; 2406 else 2407 clock = 96000 * 1000; 2408 break; 2409 case BHND_CHIPID_BCM43237: 2410 chipst = sc->io->rd_chipst(sc->io_ctx); 2411 if (chipst & CHIPC_CST43237_BP_CLK) 2412 clock = 96000 * 1000; 2413 else 2414 clock = 80000 * 1000; 2415 break; 2416 case BHND_CHIPID_BCM5356: 2417 clock = bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0, 2418 BHND_PMU5_MAINPLL_SI); 2419 break; 2420 case BHND_CHIPID_BCM5357: 2421 case BHND_CHIPID_BCM4749: 2422 clock = bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0, 2423 BHND_PMU5_MAINPLL_SI); 2424 break; 2425 case BHND_CHIPID_BCM4706: 2426 clock = bhnd_pmu6_4706_clock(sc, BHND_PMU4706_MAINPLL_PLL0, 2427 BHND_PMU6_MAINPLL_SI); 2428 break; 2429 case BHND_CHIPID_BCM53572: 2430 clock = 75000000; 2431 break; 2432 default: 2433 PMU_LOG(sc, "No backplane clock specified for chip %#hx rev " 2434 "%hhd pmurev %hhd, using default %dHz\n", 2435 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc), clock); 2436 break; 2437 } 2438 2439 return (clock); 2440 } 2441 2442 /** 2443 * Return the CPU clock frequency, in Hz. 2444 * 2445 * @param sc PMU query instance. 2446 */ 2447 uint32_t 2448 bhnd_pmu_cpu_clock(struct bhnd_pmu_query *sc) 2449 { 2450 /* 5354 chip uses a non programmable PLL of frequency 240MHz */ 2451 if (sc->cid.chip_id == BHND_CHIPID_BCM5354) 2452 return (240 * 1000 * 1000); /* 240MHz */ 2453 2454 if (sc->cid.chip_id == BHND_CHIPID_BCM53572) 2455 return (300000000); 2456 2457 if (BHND_PMU_REV(sc) >= 5 && 2458 sc->cid.chip_id != BHND_CHIPID_BCM4329 && 2459 sc->cid.chip_id != BHND_CHIPID_BCM4319 && 2460 sc->cid.chip_id != BHND_CHIPID_BCM43234 && 2461 sc->cid.chip_id != BHND_CHIPID_BCM43235 && 2462 sc->cid.chip_id != BHND_CHIPID_BCM43236 && 2463 sc->cid.chip_id != BHND_CHIPID_BCM43237 && 2464 sc->cid.chip_id != BHND_CHIPID_BCM43238 && 2465 sc->cid.chip_id != BHND_CHIPID_BCM4336 && 2466 sc->cid.chip_id != BHND_CHIPID_BCM4330) 2467 { 2468 switch (sc->cid.chip_id) { 2469 case BHND_CHIPID_BCM5356: 2470 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0, 2471 BHND_PMU5_MAINPLL_CPU)); 2472 2473 case BHND_CHIPID_BCM5357: 2474 case BHND_CHIPID_BCM4749: 2475 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0, 2476 BHND_PMU5_MAINPLL_CPU)); 2477 2478 case BHND_CHIPID_BCM4706: 2479 return (bhnd_pmu6_4706_clock(sc, 2480 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_CPU)); 2481 2482 default: 2483 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0, 2484 BHND_PMU5_MAINPLL_CPU)); 2485 } 2486 } else { 2487 return (bhnd_pmu_si_clock(sc)); 2488 } 2489 } 2490 2491 /** 2492 * Return the memory clock frequency, in Hz. 2493 * 2494 * @param sc PMU query instance. 2495 */ 2496 uint32_t 2497 bhnd_pmu_mem_clock(struct bhnd_pmu_query *sc) 2498 { 2499 if (BHND_PMU_REV(sc) >= 5 && 2500 sc->cid.chip_id != BHND_CHIPID_BCM4329 && 2501 sc->cid.chip_id != BHND_CHIPID_BCM4319 && 2502 sc->cid.chip_id != BHND_CHIPID_BCM43234 && 2503 sc->cid.chip_id != BHND_CHIPID_BCM43235 && 2504 sc->cid.chip_id != BHND_CHIPID_BCM43236 && 2505 sc->cid.chip_id != BHND_CHIPID_BCM43237 && 2506 sc->cid.chip_id != BHND_CHIPID_BCM43238 && 2507 sc->cid.chip_id != BHND_CHIPID_BCM4336 && 2508 sc->cid.chip_id != BHND_CHIPID_BCM4330) 2509 { 2510 switch (sc->cid.chip_id) { 2511 case BHND_CHIPID_BCM5356: 2512 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0, 2513 BHND_PMU5_MAINPLL_MEM)); 2514 2515 case BHND_CHIPID_BCM5357: 2516 case BHND_CHIPID_BCM4749: 2517 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0, 2518 BHND_PMU5_MAINPLL_MEM)); 2519 2520 case BHND_CHIPID_BCM4706: 2521 return (bhnd_pmu6_4706_clock(sc, 2522 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_MEM)); 2523 2524 default: 2525 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0, 2526 BHND_PMU5_MAINPLL_MEM)); 2527 } 2528 2529 } else { 2530 return (bhnd_pmu_si_clock(sc)); 2531 } 2532 } 2533 2534 /* Measure ILP clock frequency */ 2535 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */ 2536 2537 /** 2538 * Measure and return the ILP clock frequency, in Hz. 2539 * 2540 * @param sc PMU query instance. 2541 */ 2542 uint32_t 2543 bhnd_pmu_ilp_clock(struct bhnd_pmu_query *sc) 2544 { 2545 uint32_t start, end, delta; 2546 2547 if (sc->ilp_cps == 0) { 2548 start = BHND_PMU_READ_4(sc, BHND_PMU_TIMER); 2549 DELAY(ILP_CALC_DUR); 2550 end = BHND_PMU_READ_4(sc, BHND_PMU_TIMER); 2551 delta = end - start; 2552 sc->ilp_cps = delta * (1000 / ILP_CALC_DUR); 2553 } 2554 2555 return (sc->ilp_cps); 2556 } 2557 2558 /* SDIO Pad drive strength to select value mappings */ 2559 typedef struct { 2560 uint8_t strength; /* Pad Drive Strength in mA */ 2561 uint8_t sel; /* Chip-specific select value */ 2562 } sdiod_drive_str_t; 2563 2564 /* SDIO Drive Strength to sel value table for PMU Rev 1 */ 2565 static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { 2566 { 2567 4, 0x2}, { 2568 2, 0x3}, { 2569 1, 0x0}, { 2570 0, 0x0} 2571 }; 2572 2573 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ 2574 static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { 2575 { 2576 12, 0x7}, { 2577 10, 0x6}, { 2578 8, 0x5}, { 2579 6, 0x4}, { 2580 4, 0x2}, { 2581 2, 0x1}, { 2582 0, 0x0} 2583 }; 2584 2585 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ 2586 static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { 2587 { 2588 32, 0x7}, { 2589 26, 0x6}, { 2590 22, 0x5}, { 2591 16, 0x4}, { 2592 12, 0x3}, { 2593 8, 0x2}, { 2594 4, 0x1}, { 2595 0, 0x0} 2596 }; 2597 2598 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 2599 2600 void 2601 bhnd_pmu_sdiod_drive_strength_init(struct bhnd_pmu_softc *sc, 2602 uint32_t drivestrength) 2603 { 2604 const sdiod_drive_str_t *str_tab; 2605 uint32_t str_mask; 2606 uint32_t str_shift; 2607 2608 str_tab = NULL; 2609 str_mask = 0; 2610 str_shift = 0; 2611 2612 switch (SDIOD_DRVSTR_KEY(sc->cid.chip_id, BHND_PMU_REV(sc))) { 2613 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 1): 2614 str_tab = sdiod_drive_strength_tab1; 2615 str_mask = 0x30000000; 2616 str_shift = 28; 2617 break; 2618 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 2): 2619 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 3): 2620 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4315, 4): 2621 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4319, 7): 2622 str_tab = sdiod_drive_strength_tab2; 2623 str_mask = 0x00003800; 2624 str_shift = 11; 2625 break; 2626 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4336, 8): 2627 str_tab = sdiod_drive_strength_tab3; 2628 str_mask = 0x00003800; 2629 str_shift = 11; 2630 break; 2631 2632 default: 2633 PMU_LOG(sc, "No SDIO Drive strength init done for chip %#x " 2634 "rev %hhd pmurev %hhd\n", sc->cid.chip_id, sc->cid.chip_rev, 2635 BHND_PMU_REV(sc)); 2636 break; 2637 } 2638 2639 if (str_tab != NULL) { 2640 uint32_t drivestrength_sel = 0; 2641 uint32_t cc_data_temp; 2642 2643 for (u_int i = 0; str_tab[i].strength != 0; i++) { 2644 if (drivestrength >= str_tab[i].strength) { 2645 drivestrength_sel = str_tab[i].sel; 2646 break; 2647 } 2648 } 2649 2650 cc_data_temp = BHND_PMU_CCTRL_READ(sc, 1); 2651 cc_data_temp &= ~str_mask; 2652 drivestrength_sel <<= str_shift; 2653 cc_data_temp |= drivestrength_sel; 2654 BHND_PMU_CCTRL_WRITE(sc, 1, cc_data_temp, ~0); 2655 2656 PMU_DEBUG(sc, "SDIO: %dmA drive strength selected, set to " 2657 "0x%08x\n", drivestrength, cc_data_temp); 2658 } 2659 } 2660 2661 /** 2662 * Initialize the PMU. 2663 */ 2664 int 2665 bhnd_pmu_init(struct bhnd_pmu_softc *sc) 2666 { 2667 uint32_t xtalfreq; 2668 int error; 2669 2670 if (BHND_PMU_REV(sc) == 1) { 2671 BHND_PMU_AND_4(sc, BHND_PMU_CTRL, ~BHND_PMU_CTRL_NOILP_ON_WAIT); 2672 } else if (BHND_PMU_REV(sc) >= 2) { 2673 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_NOILP_ON_WAIT); 2674 } 2675 2676 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 2) { 2677 /* Fix for 4329b0 bad LPOM state. */ 2678 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x100, ~0); 2679 BHND_PMU_REGCTRL_WRITE(sc, 3, 0x4, ~0); 2680 } 2681 2682 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 2683 /* Limiting the PALDO spike during init time */ 2684 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x00000005, 0x00000007); 2685 } 2686 2687 /* Fetch target xtalfreq, in KHz */ 2688 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_XTALFREQ, 2689 &xtalfreq); 2690 2691 /* If not available, log any real errors, and then try to measure it */ 2692 if (error) { 2693 if (error != ENOENT) 2694 PMU_LOG(sc, "error fetching xtalfreq: %d\n", error); 2695 2696 xtalfreq = bhnd_pmu_measure_alpclk(sc); 2697 } 2698 2699 /* Perform PLL initialization */ 2700 bhnd_pmu_pll_init(sc, xtalfreq); 2701 2702 if ((error = bhnd_pmu_res_init(sc))) 2703 return (error); 2704 2705 bhnd_pmu_swreg_init(sc); 2706 2707 return (0); 2708 } 2709 2710 /* Return up time in ILP cycles for the given resource. */ 2711 static int 2712 bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc, uint32_t *uptime) 2713 { 2714 uint32_t deps; 2715 uint32_t up, dup, dmax; 2716 uint32_t min_mask; 2717 int error; 2718 2719 /* uptime of resource 'rsrc' */ 2720 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, rsrc); 2721 up = BHND_PMU_READ_4(sc, BHND_PMU_RES_UPDN_TIMER); 2722 up = BHND_PMU_GET_BITS(up, BHND_PMU_RES_UPDN_UPTME); 2723 2724 /* Find direct dependencies of resource 'rsrc' */ 2725 deps = bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(rsrc), false); 2726 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) { 2727 if (!(deps & BHND_PMURES_BIT(i))) 2728 continue; 2729 deps &= ~bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(i), true); 2730 } 2731 2732 /* Exclude the minimum resource set */ 2733 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL))) 2734 return (error); 2735 2736 deps &= ~min_mask; 2737 2738 /* max uptime of direct dependencies */ 2739 dmax = 0; 2740 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) { 2741 if (!(deps & BHND_PMURES_BIT(i))) 2742 continue; 2743 2744 if ((error = bhnd_pmu_res_uptime(sc, i, &dup))) 2745 return (error); 2746 2747 if (dmax < dup) 2748 dmax = dup; 2749 } 2750 2751 PMU_DEBUG(sc, "bhnd_pmu_res_uptime: rsrc %hhu uptime %u(deps 0x%08x " 2752 "uptime %u)\n", rsrc, up, deps, dmax); 2753 2754 *uptime = (up + dmax + BHND_PMURES_UP_TRANSITION); 2755 return (0); 2756 } 2757 2758 /* Return dependencies (direct or all/indirect) for the given resources */ 2759 static uint32_t 2760 bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs, bool all) 2761 { 2762 uint32_t deps; 2763 2764 deps = 0; 2765 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) { 2766 if (!(rsrcs & BHND_PMURES_BIT(i))) 2767 continue; 2768 2769 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); 2770 deps |= BHND_PMU_READ_4(sc, BHND_PMU_RES_DEP_MASK); 2771 } 2772 2773 /* None found? */ 2774 if (deps == 0) 2775 return (0); 2776 2777 /* Recurse dependencies */ 2778 if (all) 2779 deps |= bhnd_pmu_res_deps(sc, deps, true); 2780 2781 return (deps); 2782 } 2783 2784 /* power up/down OTP through PMU resources */ 2785 int 2786 bhnd_pmu_otp_power(struct bhnd_pmu_softc *sc, bool on) 2787 { 2788 uint32_t deps; 2789 uint32_t min_mask; 2790 uint32_t rsrcs; 2791 int error; 2792 2793 /* Determine rsrcs to turn on/off OTP power */ 2794 switch (sc->cid.chip_id) { 2795 case BHND_CHIPID_BCM4322: 2796 case BHND_CHIPID_BCM43221: 2797 case BHND_CHIPID_BCM43231: 2798 case BHND_CHIPID_BCM4342: 2799 rsrcs = PMURES_BIT(RES4322_OTP_PU); 2800 break; 2801 case BHND_CHIPID_BCM4315: 2802 rsrcs = PMURES_BIT(RES4315_OTP_PU); 2803 break; 2804 case BHND_CHIPID_BCM4325: 2805 rsrcs = PMURES_BIT(RES4325_OTP_PU); 2806 break; 2807 case BHND_CHIPID_BCM4329: 2808 rsrcs = PMURES_BIT(RES4329_OTP_PU); 2809 break; 2810 case BHND_CHIPID_BCM4319: 2811 rsrcs = PMURES_BIT(RES4319_OTP_PU); 2812 break; 2813 case BHND_CHIPID_BCM4336: 2814 rsrcs = PMURES_BIT(RES4336_OTP_PU); 2815 break; 2816 case BHND_CHIPID_BCM4330: 2817 rsrcs = PMURES_BIT(RES4330_OTP_PU); 2818 break; 2819 default: 2820 /* Not required? */ 2821 return (0); 2822 } 2823 2824 /* Fetch all dependencies */ 2825 deps = bhnd_pmu_res_deps(sc, rsrcs, true); 2826 2827 /* Exclude the minimum resource set */ 2828 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL))) 2829 return (error); 2830 2831 deps &= ~min_mask; 2832 2833 /* Turn on/off the power */ 2834 if (on) { 2835 uint32_t state; 2836 2837 PMU_DEBUG(sc, "Adding rsrc 0x%x to min_res_mask\n", 2838 rsrcs | deps); 2839 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, (rsrcs|deps)); 2840 2841 /* Wait for all resources to become available */ 2842 for (int i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) { 2843 state = BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE); 2844 if ((state & rsrcs) == rsrcs) 2845 break; 2846 2847 DELAY(10); 2848 } 2849 2850 if ((state & rsrcs) != rsrcs) { 2851 PMU_LOG(sc, "timeout waiting for OTP resource " 2852 "enable\n"); 2853 return (ENXIO); 2854 } 2855 } else { 2856 PMU_DEBUG(sc, "Removing rsrc 0x%x from min_res_mask\n", 2857 rsrcs | deps); 2858 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~(rsrcs|deps)); 2859 } 2860 2861 return (0); 2862 } 2863 2864 void 2865 bhnd_pmu_rcal(struct bhnd_pmu_softc *sc) 2866 { 2867 uint32_t chipst; 2868 uint32_t val; 2869 uint8_t rcal_code; 2870 bool bluetooth_rcal; 2871 2872 bluetooth_rcal = false; 2873 2874 switch (sc->cid.chip_id) { 2875 case BHND_CHIPID_BCM4325: 2876 case BHND_CHIPID_BCM4329: 2877 /* Kick RCal */ 2878 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1); 2879 2880 /* Power Down RCAL Block */ 2881 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, ~0x04); 2882 2883 if (sc->cid.chip_id == BHND_CHIPID_BCM4325) { 2884 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 2885 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_RCAL_VALID)) 2886 bluetooth_rcal = true; 2887 } 2888 2889 /* Power Up RCAL block */ 2890 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, 0x04); 2891 2892 /* Wait for completion */ 2893 for (int i = 0; i < (10 * 1000 * 1000); i++) { 2894 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 2895 2896 if (chipst & 0x08) 2897 break; 2898 2899 DELAY(10); 2900 } 2901 KASSERT((chipst & 0x08) != 0, ("rcal completion timeout")); 2902 2903 if (bluetooth_rcal) { 2904 rcal_code = 0x6; 2905 } else { 2906 /* Drop LSB to convert from 5 bit code to 4 bit code */ 2907 rcal_code = (uint8_t) (chipst >> 5) & 0x0f; 2908 } 2909 2910 PMU_DEBUG("RCal completed, status 0x%x, code 0x%x\n", 2911 R_REG(&cc->chipstatus), rcal_code); 2912 2913 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 2914 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 0); 2915 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA); 2916 val &= ~((uint32_t) 0x07 << 29); 2917 val |= (uint32_t) (rcal_code & 0x07) << 29; 2918 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val); 2919 2920 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 1); 2921 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA); 2922 val &= ~(uint32_t) 0x01; 2923 val |= (uint32_t) ((rcal_code >> 3) & 0x01); 2924 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val); 2925 2926 /* Write RCal code into pmu_chip_ctrl[33:30] */ 2927 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 0); 2928 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIP_CONTROL_DATA); 2929 val &= ~((uint32_t) 0x03 << 30); 2930 val |= (uint32_t) (rcal_code & 0x03) << 30; 2931 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_DATA, val); 2932 2933 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1); 2934 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIP_CONTROL_DATA); 2935 val &= ~(uint32_t) 0x03; 2936 val |= (uint32_t) ((rcal_code >> 2) & 0x03); 2937 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_DATA, val); 2938 2939 /* Set override in pmu_chip_ctrl[29] */ 2940 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 0); 2941 BHND_PMU_OR_4(sc, BHND_PMU_CHIP_CONTROL_DATA, (0x01 << 29)); 2942 2943 /* Power off RCal block */ 2944 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1); 2945 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, ~0x04); 2946 break; 2947 default: 2948 break; 2949 } 2950 } 2951 2952 int 2953 bhnd_pmu_set_spuravoid(struct bhnd_pmu_softc *sc, bhnd_pmu_spuravoid spuravoid) 2954 { 2955 int error; 2956 2957 /* force the HT off */ 2958 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) { 2959 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 2960 ~BHND_PMU_RES4336_HT_AVAIL); 2961 2962 /* wait for the ht to really go away */ 2963 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 2964 } 2965 2966 /* update the pll changes */ 2967 error = bhnd_pmu_spuravoid_pllupdate(sc, spuravoid); 2968 2969 /* enable HT back on */ 2970 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) { 2971 BHND_PMU_OR_4(sc, BHND_PMU_MAX_RES_MASK, 2972 BHND_PMU_RES4336_HT_AVAIL); 2973 } 2974 2975 return (error); 2976 } 2977 2978 static int 2979 bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc, 2980 bhnd_pmu_spuravoid spuravoid) 2981 { 2982 uint16_t chip_id; 2983 uint32_t pmuctrl; 2984 uint32_t tmp; 2985 2986 /* 6362a0 has same clks as 4322[4-6] */ 2987 chip_id = sc->cid.chip_id; 2988 if (chip_id == BHND_CHIPID_BCM6362 && sc->cid.chip_rev == 0) { 2989 chip_id = BHND_CHIPID_BCM43224; 2990 } 2991 2992 switch (chip_id) { 2993 case BHND_CHIPID_BCM6362: 2994 KASSERT(sc->cid.chip_rev != 0, ("invalid clock config")); 2995 /* fallthrough */ 2996 case BHND_CHIPID_BCM5357: 2997 case BHND_CHIPID_BCM4749: 2998 case BHND_CHIPID_BCM43235: 2999 case BHND_CHIPID_BCM43236: 3000 case BHND_CHIPID_BCM43238: 3001 case BHND_CHIPID_BCM43234: 3002 case BHND_CHIPID_BCM43237: 3003 case BHND_CHIPID_BCM53572: { 3004 uint8_t p1div, ndiv; 3005 uint8_t phypll_offset; 3006 3007 switch (spuravoid) { 3008 case BHND_PMU_SPURAVOID_NONE: 3009 p1div = 0x1; 3010 ndiv = 0x30; 3011 break; 3012 case BHND_PMU_SPURAVOID_M1: 3013 p1div = 0x5; 3014 ndiv = 0xf6; 3015 break; 3016 case BHND_PMU_SPURAVOID_M2: 3017 p1div = 0x5; 3018 ndiv = 0xfc; 3019 break; 3020 default: 3021 return (ENODEV); 3022 } 3023 3024 /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset 3025 * PLL0_PLLCTL[02] by 6 */ 3026 phypll_offset = 0; 3027 if (sc->cid.chip_id == BHND_CHIPID_BCM5357) 3028 phypll_offset = 6; 3029 3030 /* RMW only the P1 divider */ 3031 tmp = BHND_PMU_SET_BITS(p1div, BHND_PMU1_PLL0_PC0_P1DIV); 3032 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0 + phypll_offset, 3033 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK); 3034 3035 /* RMW only the int feedback divider */ 3036 tmp = BHND_PMU_SET_BITS(ndiv, BHND_PMU1_PLL0_PC2_NDIV_INT); 3037 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2 + phypll_offset, 3038 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK); 3039 3040 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3041 break; 3042 } 3043 3044 case BHND_CHIPID_BCM4331: 3045 switch (spuravoid) { 3046 case BHND_PMU_SPURAVOID_NONE: 3047 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3048 0x11100014, ~0); 3049 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3050 0x03000a08, ~0); 3051 break; 3052 3053 case BHND_PMU_SPURAVOID_M1: 3054 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3055 0x11500014, ~0); 3056 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3057 0x0F600a08, ~0); 3058 break; 3059 3060 case BHND_PMU_SPURAVOID_M2: 3061 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3062 0x11500014, ~0); 3063 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3064 0x0FC00a08, ~0); 3065 break; 3066 3067 default: 3068 return (ENODEV); 3069 } 3070 3071 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3072 break; 3073 3074 case BHND_CHIPID_BCM43224: 3075 case BHND_CHIPID_BCM43225: 3076 case BHND_CHIPID_BCM43226: 3077 case BHND_CHIPID_BCM43421: 3078 switch (spuravoid) { 3079 case BHND_PMU_SPURAVOID_NONE: 3080 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3081 0x11100010, ~0); 3082 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3083 0x000c0c06, ~0); 3084 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3085 0x03000a08, ~0); 3086 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3087 0x00000000, ~0); 3088 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3089 0x200005c0, ~0); 3090 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3091 0x88888815, ~0); 3092 break; 3093 3094 case BHND_PMU_SPURAVOID_M1: 3095 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3096 0x11500010, ~0); 3097 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3098 0x000C0C06, ~0); 3099 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3100 0x0F600a08, ~0); 3101 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3102 0x00000000, ~0); 3103 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3104 0x2001E920, ~0); 3105 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3106 0x88888815, ~0); 3107 break; 3108 3109 case BHND_PMU_SPURAVOID_M2: 3110 default: 3111 return (ENODEV); 3112 } 3113 3114 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3115 break; 3116 3117 case BHND_CHIPID_BCM43111: 3118 case BHND_CHIPID_BCM43112: 3119 case BHND_CHIPID_BCM43222: 3120 case BHND_CHIPID_BCM43420: 3121 switch (spuravoid) { 3122 case BHND_PMU_SPURAVOID_NONE: 3123 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3124 0x11100008, ~0); 3125 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3126 0x0c000c06, ~0); 3127 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3128 0x03000a08, ~0); 3129 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3130 0x00000000, ~0); 3131 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3132 0x200005c0, ~0); 3133 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3134 0x88888855, ~0); 3135 break; 3136 3137 case BHND_PMU_SPURAVOID_M1: 3138 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3139 0x11500008, ~0); 3140 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3141 0x0c000c06, ~0); 3142 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3143 0x0f600a08, ~0); 3144 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3145 0x00000000, ~0); 3146 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3147 0x2001e920, ~0); 3148 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3149 0x88888815, ~0); 3150 break; 3151 3152 case BHND_PMU_SPURAVOID_M2: 3153 default: 3154 return (ENODEV); 3155 } 3156 3157 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3158 break; 3159 3160 case BHND_CHIPID_BCM4716: 3161 case BHND_CHIPID_BCM4748: 3162 case BHND_CHIPID_BCM47162: 3163 switch (spuravoid) { 3164 case BHND_PMU_SPURAVOID_NONE: 3165 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3166 0x11100060, ~0); 3167 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3168 0x080c0c06, ~0); 3169 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3170 0x03000000, ~0); 3171 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3172 0x00000000, ~0); 3173 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3174 0x200005c0, ~0); 3175 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3176 0x88888815, ~0); 3177 break; 3178 3179 case BHND_PMU_SPURAVOID_M1: 3180 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3181 0x11500060, ~0); 3182 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3183 0x080C0C06, ~0); 3184 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3185 0x0F600000, ~0); 3186 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3187 0x00000000, ~0); 3188 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3189 0x2001E924, ~0); 3190 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3191 0x88888815, ~0); 3192 break; 3193 3194 case BHND_PMU_SPURAVOID_M2: 3195 default: 3196 return (ENODEV); 3197 } 3198 3199 pmuctrl = BHND_PMU_CTRL_NOILP_ON_WAIT | 3200 BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3201 break; 3202 3203 case BHND_CHIPID_BCM4319: 3204 pmuctrl = 0; 3205 break; 3206 3207 case BHND_CHIPID_BCM4322: 3208 case BHND_CHIPID_BCM43221: 3209 case BHND_CHIPID_BCM43231: 3210 case BHND_CHIPID_BCM4342: 3211 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x11100070, ~0); 3212 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x1014140a, ~0); 3213 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888854, ~0); 3214 3215 switch (spuravoid) { 3216 case BHND_PMU_SPURAVOID_NONE: 3217 /* enable 40/80/160Mhz clock mode */ 3218 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3219 0x05001828, ~0); 3220 break; 3221 3222 case BHND_PMU_SPURAVOID_M1: 3223 /* spur_avoid ON, enable 41/82/164Mhz clock mode */ 3224 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3225 0x05201828, ~0); 3226 break; 3227 3228 case BHND_PMU_SPURAVOID_M2: 3229 default: 3230 return (ENODEV); 3231 } 3232 3233 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3234 break; 3235 3236 case BHND_CHIPID_BCM4336: 3237 /* Looks like these are only for default xtal freq 26MHz */ 3238 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x02100020, ~0); 3239 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x0C0C0C0C, ~0); 3240 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 0x01240C0C, ~0); 3241 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 0x202C2820, ~0); 3242 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888825, ~0); 3243 3244 switch (spuravoid) { 3245 case BHND_PMU_SPURAVOID_NONE: 3246 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3247 0x00762762, ~0); 3248 break; 3249 3250 case BHND_PMU_SPURAVOID_M1: 3251 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3252 0x00EC4EC4, ~0); 3253 break; 3254 3255 case BHND_PMU_SPURAVOID_M2: 3256 default: 3257 return (ENODEV); 3258 } 3259 3260 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3261 break; 3262 3263 case BHND_CHIPID_BCM43131: 3264 case BHND_CHIPID_BCM43227: 3265 case BHND_CHIPID_BCM43228: 3266 case BHND_CHIPID_BCM43428: 3267 /* LCNXN */ 3268 /* PLL Settings for spur avoidance on/off mode, no on2 support 3269 * for 43228A0 */ 3270 switch (spuravoid) { 3271 case BHND_PMU_SPURAVOID_NONE: 3272 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3273 0x11100014, ~0); 3274 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3275 0x040c0c06, ~0); 3276 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3277 0x03000a08, ~0); 3278 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3279 0x00000000, ~0); 3280 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3281 0x200005c0, ~0); 3282 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3283 0x88888815, ~0); 3284 break; 3285 3286 case BHND_PMU_SPURAVOID_M1: 3287 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3288 0x01100014, ~0); 3289 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3290 0x040C0C06, ~0); 3291 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3292 0x03140A08, ~0); 3293 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3294 0x00333333, ~0); 3295 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3296 0x202C2820, ~0); 3297 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3298 0x88888815, ~0); 3299 break; 3300 3301 case BHND_PMU_SPURAVOID_M2: 3302 default: 3303 return (ENODEV); 3304 } 3305 3306 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3307 break; 3308 default: 3309 PMU_LOG(sc, "%s: unknown spuravoidance settings for chip %#hx, " 3310 "not changing PLL", __func__, sc->cid.chip_id); 3311 3312 return (ENODEV); 3313 } 3314 3315 if (pmuctrl != 0) 3316 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, pmuctrl); 3317 3318 return (0); 3319 } 3320 3321 bool 3322 bhnd_pmu_is_otp_powered(struct bhnd_pmu_softc *sc) 3323 { 3324 uint32_t otp_res; 3325 3326 /* Determine per-chip OTP resource */ 3327 switch (sc->cid.chip_id) { 3328 case BHND_CHIPID_BCM4329: 3329 otp_res = PMURES_BIT(RES4329_OTP_PU); 3330 break; 3331 case BHND_CHIPID_BCM4319: 3332 otp_res = PMURES_BIT(RES4319_OTP_PU); 3333 break; 3334 case BHND_CHIPID_BCM4336: 3335 otp_res = PMURES_BIT(RES4336_OTP_PU); 3336 break; 3337 case BHND_CHIPID_BCM4330: 3338 otp_res = PMURES_BIT(RES4330_OTP_PU); 3339 break; 3340 3341 /* These chips don't use PMU bit to power up/down OTP. OTP always on. 3342 * Use OTP_INIT command to reset/refresh state. 3343 */ 3344 case BHND_CHIPID_BCM43224: 3345 case BHND_CHIPID_BCM43225: 3346 case BHND_CHIPID_BCM43421: 3347 case BHND_CHIPID_BCM43236: 3348 case BHND_CHIPID_BCM43235: 3349 case BHND_CHIPID_BCM43238: 3350 return (true); 3351 3352 default: 3353 return (true); 3354 } 3355 3356 /* Check resource state */ 3357 if ((BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE) & otp_res) == 0) 3358 return (false); 3359 3360 return (true); 3361 } 3362 3363 int 3364 bhnd_pmu_paref_ldo_enable(struct bhnd_pmu_softc *sc, bool enable) 3365 { 3366 uint32_t ldo; 3367 3368 switch (sc->cid.chip_id) { 3369 case BHND_CHIPID_BCM4328: 3370 ldo = PMURES_BIT(RES4328_PA_REF_LDO); 3371 break; 3372 case BHND_CHIPID_BCM5354: 3373 ldo = PMURES_BIT(RES5354_PA_REF_LDO); 3374 break; 3375 case BHND_CHIPID_BCM4312: 3376 ldo = PMURES_BIT(RES4312_PA_REF_LDO); 3377 break; 3378 default: 3379 return (ENODEV); 3380 } 3381 3382 if (enable) { 3383 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, ldo); 3384 } else { 3385 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~ldo); 3386 } 3387 3388 return (0); 3389 } 3390 3391 /* initialize PMU switch/regulators */ 3392 void 3393 bhnd_pmu_swreg_init(struct bhnd_pmu_softc *sc) 3394 { 3395 uint32_t chipst; 3396 3397 switch (sc->cid.chip_id) { 3398 case BHND_CHIPID_BCM4325: 3399 if (sc->cid.chip_rev <= 2) 3400 break; 3401 3402 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 3403 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) { 3404 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 3405 0xf); 3406 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 3407 0xf); 3408 } 3409 3410 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb); 3411 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb); 3412 3413 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0x1); 3414 if (sc->board.board_flags & BHND_BFL_LNLDO2_2P5) { 3415 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO2_SEL, 3416 0x1); 3417 } 3418 3419 break; 3420 case BHND_CHIPID_BCM4336: 3421 /* Reduce CLDO PWM output voltage to 1.2V */ 3422 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); 3423 /* Reduce CLDO BURST output voltage to 1.2V */ 3424 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 0xe); 3425 /* Reduce LNLDO1 output voltage to 1.2V */ 3426 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0xe); 3427 if (sc->cid.chip_rev == 0) 3428 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x400000, 0x400000); 3429 break; 3430 3431 case BHND_CHIPID_BCM4330: 3432 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ 3433 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0); 3434 break; 3435 default: 3436 break; 3437 } 3438 } 3439 3440 int 3441 bhnd_pmu_radio_enable(struct bhnd_pmu_softc *sc, device_t d11core, bool enable) 3442 { 3443 uint32_t oobsel; 3444 uint32_t rsrcs; 3445 int error; 3446 3447 if (bhnd_get_device(d11core) != BHND_COREID_D11) { 3448 device_printf(sc->dev, 3449 "bhnd_pmu_radio_enable() called on non-D11 core"); 3450 return (EINVAL); 3451 } 3452 3453 switch (sc->cid.chip_id) { 3454 case BHND_CHIPID_BCM4325: 3455 if (sc->board.board_flags & BHND_BFL_FASTPWR) 3456 break; 3457 3458 if ((sc->board.board_flags & BHND_BFL_BUCKBOOST) == 0) 3459 break; 3460 3461 rsrcs = PMURES_BIT(RES4325_BUCK_BOOST_BURST); 3462 3463 if (enable) { 3464 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, rsrcs); 3465 DELAY(100 * 1000); /* 100ms */ 3466 } else { 3467 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~rsrcs); 3468 } 3469 3470 return (0); 3471 3472 case BHND_CHIPID_BCM4319: 3473 error = bhnd_read_config(d11core, BCMA_DMP_OOBSELOUTB74, 3474 &oobsel, 4); 3475 if (error) 3476 return (error); 3477 3478 if (enable) { 3479 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3480 BCMA_DMP_OOBSEL_5); 3481 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3482 BCMA_DMP_OOBSEL_6); 3483 } else { 3484 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3485 BCMA_DMP_OOBSEL_5); 3486 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3487 BCMA_DMP_OOBSEL_6); 3488 } 3489 3490 return (bhnd_write_config(d11core, BCMA_DMP_OOBSELOUTB74, 3491 &oobsel, 4)); 3492 } 3493 3494 return (0); 3495 } 3496 3497 /* Wait for a particular clock level to be on the backplane */ 3498 uint32_t 3499 bhnd_pmu_waitforclk_on_backplane(struct bhnd_pmu_softc *sc, uint32_t clk, 3500 uint32_t delay) 3501 { 3502 uint32_t pmu_st; 3503 3504 for (uint32_t i = 0; i < delay; i += 10) { 3505 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST); 3506 if ((pmu_st & clk) == clk) 3507 return (clk); 3508 3509 DELAY(10); 3510 } 3511 3512 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST); 3513 return (pmu_st & clk); 3514 } 3515 3516 /* 3517 * Measures the ALP clock frequency in KHz. Returns 0 if not possible. 3518 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal. 3519 */ 3520 3521 #define EXT_ILP_HZ 32768 3522 3523 uint32_t 3524 bhnd_pmu_measure_alpclk(struct bhnd_pmu_softc *sc) 3525 { 3526 uint32_t alp_khz; 3527 uint32_t pmu_st; 3528 3529 if (BHND_PMU_REV(sc) < 10) 3530 return (0); 3531 3532 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST); 3533 if (pmu_st & BHND_PMU_ST_EXTLPOAVAIL) { 3534 uint32_t alp_hz, ilp_ctr; 3535 3536 /* Enable frequency measurement */ 3537 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 1U << 3538 BHND_PMU_XTALFREQ_REG_MEASURE_SHIFT); 3539 3540 /* Delay for well over 4 ILP clocks */ 3541 DELAY(1000); 3542 3543 /* Read the latched number of ALP ticks per 4 ILP ticks */ 3544 ilp_ctr = BHND_PMU_READ_4(sc, BHND_PMU_XTALFREQ); 3545 ilp_ctr = BHND_PMU_GET_BITS(ilp_ctr, 3546 BHND_PMU_XTALFREQ_REG_ILPCTR); 3547 3548 /* Turn off PMU_XTALFREQ_REG_MEASURE to save power */ 3549 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 0); 3550 3551 /* Calculate ALP frequency */ 3552 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; 3553 3554 /* Round to nearest 100KHz and convert to KHz */ 3555 alp_khz = (alp_hz + 50000) / 100000 * 100; 3556 } else { 3557 alp_khz = 0; 3558 } 3559 3560 return (alp_khz); 3561 } 3562 3563 static void 3564 bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc) 3565 { 3566 uint32_t FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000; 3567 uint32_t m1div, m2div, m3div, m4div, m5div, m6div; 3568 uint32_t pllc1, pllc2; 3569 3570 m2div = m3div = m4div = m6div = FVCO / 80; 3571 m5div = FVCO / 160; 3572 3573 if (PMU_CST4330_SDIOD_CHIPMODE(sc)) 3574 m1div = FVCO / 80; 3575 else 3576 m1div = FVCO / 90; 3577 3578 pllc1 = 0; 3579 pllc1 |= BHND_PMU_SET_BITS(m1div, BHND_PMU1_PLL0_PC1_M1DIV); 3580 pllc1 |= BHND_PMU_SET_BITS(m2div, BHND_PMU1_PLL0_PC1_M2DIV); 3581 pllc1 |= BHND_PMU_SET_BITS(m3div, BHND_PMU1_PLL0_PC1_M3DIV); 3582 pllc1 |= BHND_PMU_SET_BITS(m4div, BHND_PMU1_PLL0_PC1_M4DIV); 3583 3584 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, pllc1, ~0); 3585 3586 pllc2 = 0; 3587 pllc2 |= BHND_PMU_SET_BITS(m5div, BHND_PMU1_PLL0_PC2_M5DIV); 3588 pllc2 |= BHND_PMU_SET_BITS(m6div, BHND_PMU1_PLL0_PC2_M6DIV); 3589 3590 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, pllc2, 3591 BHND_PMU1_PLL0_PC2_M5DIV_MASK | BHND_PMU1_PLL0_PC2_M6DIV_MASK); 3592 } 3593