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