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