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 /* Set up PLL registers in the PMU as per the crystal speed. */ 1669 static void 1670 bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal) 1671 { 1672 const pmu1_xtaltab0_t *xt; 1673 uint32_t buf_strength; 1674 uint32_t plladdr, plldata, pllmask; 1675 uint32_t pmuctrl; 1676 uint32_t FVCO; 1677 uint8_t ndiv_mode; 1678 1679 FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000; 1680 buf_strength = 0; 1681 ndiv_mode = 1; 1682 1683 /* Use h/w default PLL config */ 1684 if (xtal == 0) { 1685 PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL " 1686 "configuration\n"); 1687 return; 1688 } 1689 1690 /* Find the frequency in the table */ 1691 for (xt = bhnd_pmu1_xtaltab0(&sc->query); xt != NULL && xt->fref != 0; 1692 xt++) 1693 { 1694 if (xt->fref == xtal) 1695 break; 1696 } 1697 1698 /* Check current PLL state, bail out if it has been programmed or 1699 * we don't know how to program it. 1700 */ 1701 if (xt == NULL || xt->fref == 0) { 1702 PMU_LOG(sc, "Unsupported XTAL frequency %d.%dMHz, skipping PLL " 1703 "configuration\n", xtal / 1000, xtal % 1000); 1704 return; 1705 } 1706 1707 /* For 4319 bootloader already programs the PLL but bootloader does not 1708 * program the PLL4 and PLL5. So Skip this check for 4319. */ 1709 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1710 if (BHND_PMU_GET_BITS(pmuctrl, BHND_PMU_CTRL_XTALFREQ) == xt->xf && 1711 sc->cid.chip_id != BHND_CHIPID_BCM4319 && 1712 sc->cid.chip_id != BHND_CHIPID_BCM4330) 1713 { 1714 PMU_DEBUG(sc, "PLL already programmed for %d.%dMHz\n", 1715 xt->fref / 1000, xt->fref % 1000); 1716 return; 1717 } 1718 1719 PMU_DEBUG(sc, "XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf); 1720 PMU_DEBUG(sc, "Programming PLL for %d.%dMHz\n", xt->fref / 1000, 1721 xt->fref % 1000); 1722 1723 switch (sc->cid.chip_id) { 1724 case BHND_CHIPID_BCM4325: 1725 /* Change the BBPLL drive strength to 2 for all channels */ 1726 buf_strength = 0x222222; 1727 1728 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1729 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | 1730 PMURES_BIT(RES4325_HT_AVAIL))); 1731 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1732 ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | 1733 PMURES_BIT(RES4325_HT_AVAIL))); 1734 1735 /* Wait for HT clock to shutdown. */ 1736 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1737 break; 1738 1739 case BHND_CHIPID_BCM4329: 1740 /* Change the BBPLL drive strength to 8 for all channels */ 1741 buf_strength = 0x888888; 1742 1743 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1744 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | 1745 PMURES_BIT(RES4329_HT_AVAIL))); 1746 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1747 ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | 1748 PMURES_BIT(RES4329_HT_AVAIL))); 1749 1750 /* Wait for HT clock to shutdown. */ 1751 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1752 1753 /* Initialize PLL4 */ 1754 plladdr = BHND_PMU1_PLL0_PLLCTL4; 1755 if (xt->fref == 38400) 1756 plldata = 0x200024C0; 1757 else if (xt->fref == 37400) 1758 plldata = 0x20004500; 1759 else if (xt->fref == 26000) 1760 plldata = 0x200024C0; 1761 else 1762 plldata = 0x200005C0; /* Chip Dflt Settings */ 1763 1764 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0); 1765 1766 /* Initialize PLL5 */ 1767 plladdr = BHND_PMU1_PLL0_PLLCTL5; 1768 1769 plldata = BHND_PMU_PLL_READ(sc, plladdr); 1770 plldata &= BHND_PMU1_PLL0_PC5_CLK_DRV_MASK; 1771 1772 if (xt->fref == 38400 || 1773 xt->fref == 37400 || 1774 xt->fref == 26000) { 1775 plldata |= 0x15; 1776 } else { 1777 plldata |= 0x25; /* Chip Dflt Settings */ 1778 } 1779 1780 BHND_PMU_PLL_WRITE(sc, plladdr, plldata, ~0); 1781 break; 1782 1783 case BHND_CHIPID_BCM4319: 1784 /* Change the BBPLL drive strength to 2 for all channels */ 1785 buf_strength = 0x222222; 1786 1787 /* Make sure the PLL is off */ 1788 /* WAR65104: Disable the HT_AVAIL resource first and then 1789 * after a delay (more than downtime for HT_AVAIL) remove the 1790 * BBPLL resource; backplane clock moves to ALP from HT. 1791 */ 1792 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1793 ~(PMURES_BIT(RES4319_HT_AVAIL))); 1794 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1795 ~(PMURES_BIT(RES4319_HT_AVAIL))); 1796 1797 DELAY(100); 1798 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1799 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 1800 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1801 ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); 1802 1803 DELAY(100); 1804 1805 /* Wait for HT clock to shutdown. */ 1806 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1807 1808 plldata = 0x200005c0; 1809 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, plldata, ~0); 1810 break; 1811 1812 case BHND_CHIPID_BCM4336: 1813 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1814 ~(PMURES_BIT(RES4336_HT_AVAIL) | 1815 PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 1816 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1817 ~(PMURES_BIT(RES4336_HT_AVAIL) | 1818 PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); 1819 DELAY(100); 1820 1821 /* Wait for HT clock to shutdown. */ 1822 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1823 1824 break; 1825 1826 case BHND_CHIPID_BCM4330: 1827 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, 1828 ~(PMURES_BIT(RES4330_HT_AVAIL) | 1829 PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 1830 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 1831 ~(PMURES_BIT(RES4330_HT_AVAIL) | 1832 PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); 1833 DELAY(100); 1834 1835 /* Wait for HT clock to shutdown. */ 1836 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 1837 1838 break; 1839 1840 default: 1841 panic("unsupported chipid %#hx\n", sc->cid.chip_id); 1842 } 1843 1844 PMU_DEBUG(sc, "Done masking\n"); 1845 1846 /* Write p1div and p2div to pllcontrol[0] */ 1847 plldata = 1848 BHND_PMU_SET_BITS(xt->p1div, BHND_PMU1_PLL0_PC0_P1DIV) | 1849 BHND_PMU_SET_BITS(xt->p2div, BHND_PMU1_PLL0_PC0_P2DIV); 1850 pllmask = BHND_PMU1_PLL0_PC0_P1DIV_MASK|BHND_PMU1_PLL0_PC0_P2DIV_MASK; 1851 1852 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1853 plldata &= ~(BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK); 1854 pllmask |= BHND_PMU1_PLL0_PC0_BYPASS_SDMOD_MASK; 1855 if (!xt->ndiv_frac) { 1856 plldata |= BHND_PMU_SET_BITS(1, 1857 BHND_PMU1_PLL0_PC0_BYPASS_SDMOD); 1858 } 1859 } 1860 1861 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, plldata, pllmask); 1862 1863 if (sc->cid.chip_id == BHND_CHIPID_BCM4330) 1864 bhnd_pmu_set_4330_plldivs(sc); 1865 1866 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) { 1867 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 1868 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_VAL, 1869 BHND_PMU_DOT11MAC_880MHZ_CLK_DIVISOR_MASK); 1870 } 1871 1872 /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ 1873 if (sc->cid.chip_id == BHND_CHIPID_BCM4336 || 1874 sc->cid.chip_id == BHND_CHIPID_BCM4330) 1875 { 1876 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB; 1877 } else if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1878 if (!(xt->ndiv_frac)) 1879 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_INT; 1880 else 1881 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MFB; 1882 } else { 1883 ndiv_mode = BHND_PMU1_PLL0_PC2_NDIV_MODE_MASH; 1884 } 1885 1886 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 1887 BHND_PMU_SET_BITS(xt->ndiv_int, BHND_PMU1_PLL0_PC2_NDIV_INT) | 1888 BHND_PMU_SET_BITS(ndiv_mode, BHND_PMU1_PLL0_PC2_NDIV_MODE), 1889 BHND_PMU1_PLL0_PC2_NDIV_INT_MASK | 1890 BHND_PMU1_PLL0_PC2_NDIV_MODE_MASK); 1891 1892 /* Write ndiv_frac to pllcontrol[3] */ 1893 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 1894 BHND_PMU_SET_BITS(xt->ndiv_frac, BHND_PMU1_PLL0_PC3_NDIV_FRAC), 1895 BHND_PMU1_PLL0_PC3_NDIV_FRAC_MASK); 1896 1897 /* Writing to pllcontrol[4] */ 1898 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1899 uint8_t xs; 1900 1901 if (!xt->ndiv_frac) 1902 plldata = 0x200005c0; 1903 else 1904 plldata = 0x202C2820; 1905 1906 if (FVCO < 1600) 1907 xs = 4; 1908 else 1909 xs = 7; 1910 1911 plldata &= ~(BHND_PMU1_PLL0_PC4_KVCO_XS_MASK); 1912 plldata |= BHND_PMU_SET_BITS(xs, BHND_PMU1_PLL0_PC4_KVCO_XS); 1913 BHND_PMU_WRITE_4(sc, BHND_PMU1_PLL0_PLLCTL4, plldata); 1914 } 1915 1916 /* Write clock driving strength to pllcontrol[5] */ 1917 if (buf_strength) { 1918 PMU_DEBUG(sc, "Adjusting PLL buffer drive strength: %x\n", 1919 buf_strength); 1920 1921 plldata = BHND_PMU_SET_BITS(buf_strength, 1922 BHND_PMU1_PLL0_PC5_CLK_DRV); 1923 pllmask = BHND_PMU1_PLL0_PC5_CLK_DRV_MASK; 1924 1925 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 1926 pllmask |= 1927 BHND_PMU1_PLL0_PC5_VCO_RNG_MASK | 1928 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32_MASK; 1929 1930 if (!xt->ndiv_frac) { 1931 plldata |= BHND_PMU_SET_BITS(0x25, 1932 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32); 1933 } else { 1934 plldata |= BHND_PMU_SET_BITS(0x15, 1935 BHND_PMU1_PLL0_PC5_PLL_CTRL_37_32); 1936 } 1937 1938 if (FVCO >= 1600) { 1939 plldata |= BHND_PMU_SET_BITS(0x1, 1940 BHND_PMU1_PLL0_PC5_VCO_RNG); 1941 } 1942 } 1943 1944 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, plldata, 1945 pllmask); 1946 } 1947 1948 PMU_DEBUG(sc, "Done pll\n"); 1949 1950 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs 1951 * to be updated. 1952 */ 1953 if (sc->cid.chip_id == BHND_CHIPID_BCM4319 && 1954 xt->fref != XTAL_FREQ_30000MHZ) 1955 { 1956 uint32_t pll_sel; 1957 1958 switch (xt->fref) { 1959 case XTAL_FREQ_24000MHZ: 1960 pll_sel = BHND_PMU_CCTRL4319USB_24MHZ_PLL_SEL; 1961 break; 1962 case XTAL_FREQ_48000MHZ: 1963 pll_sel = BHND_PMU_CCTRL4319USB_48MHZ_PLL_SEL; 1964 break; 1965 default: 1966 panic("unsupported 4319USB XTAL frequency: %hu\n", 1967 xt->fref); 1968 } 1969 1970 BHND_PMU_CCTRL_WRITE(sc, BHND_PMU1_PLL0_CHIPCTL2, 1971 BHND_PMU_SET_BITS(pll_sel, BHND_PMU_CCTRL4319USB_XTAL_SEL), 1972 BHND_PMU_CCTRL4319USB_XTAL_SEL_MASK); 1973 } 1974 1975 /* Flush deferred pll control registers writes */ 1976 if (BHND_PMU_REV(sc) >= 2) 1977 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_PLL_PLLCTL_UPD); 1978 1979 /* Write XtalFreq. Set the divisor also. */ 1980 pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); 1981 pmuctrl &= ~(BHND_PMU_CTRL_ILP_DIV_MASK | BHND_PMU_CTRL_XTALFREQ_MASK); 1982 pmuctrl |= BHND_PMU_SET_BITS(((xt->fref + 127) / 128) - 1, 1983 BHND_PMU_CTRL_ILP_DIV); 1984 pmuctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ); 1985 1986 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 0) { 1987 /* clear the htstretch before clearing HTReqEn */ 1988 BHND_PMU_AND_4(sc, BHND_PMU_CLKSTRETCH, ~BHND_PMU_CLKSTRETCH); 1989 pmuctrl &= ~BHND_PMU_CTRL_HT_REQ_EN; 1990 } 1991 1992 BHND_PMU_WRITE_4(sc, BHND_PMU_CTRL, pmuctrl); 1993 } 1994 1995 /* query the CPU clock frequency */ 1996 static uint32_t 1997 bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc) 1998 { 1999 uint32_t tmp, m1div; 2000 #ifdef BCMDBG 2001 uint32_t ndiv_int, ndiv_frac, p2div, p1div, fvco; 2002 uint32_t fref; 2003 #endif 2004 uint32_t FVCO = bhnd_pmu1_pllfvco0(sc); 2005 2006 /* Read m1div from pllcontrol[1] */ 2007 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL1); 2008 m1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC1_M1DIV); 2009 2010 #ifdef BCMDBG 2011 /* Read p2div/p1div from pllcontrol[0] */ 2012 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL0); 2013 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P2DIV); 2014 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC0_P1DIV); 2015 2016 /* Calculate fvco based on xtal freq and ndiv and pdiv */ 2017 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL2); 2018 ndiv_int = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC2_NDIV_INT); 2019 2020 tmp = BHND_PMU_PLL_READ(sc, BHND_PMU1_PLL0_PLLCTL3); 2021 ndiv_frac = BHND_PMU_GET_BITS(tmp, BHND_PMU1_PLL0_PC3_NDIV_FRAC); 2022 2023 fref = bhnd_pmu1_alpclk0(sc) / 1000; 2024 2025 fvco = (fref * ndiv_int) << 8; 2026 fvco += (fref * (ndiv_frac >> 12)) >> 4; 2027 fvco += (fref * (ndiv_frac & 0xfff)) >> 12; 2028 fvco >>= 8; 2029 fvco *= p2div; 2030 fvco /= p1div; 2031 fvco /= 1000; 2032 fvco *= 1000; 2033 2034 PMU_DEBUG(sc, "bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u " 2035 "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco); 2036 2037 FVCO = fvco; 2038 #endif /* BCMDBG */ 2039 2040 /* Return ARM/SB clock */ 2041 return (FVCO / m1div * 1000); 2042 } 2043 2044 /* initialize PLL */ 2045 void 2046 bhnd_pmu_pll_init(struct bhnd_pmu_softc *sc, u_int xtalfreq) 2047 { 2048 uint32_t max_mask, min_mask; 2049 uint32_t res_ht, res_pll; 2050 2051 switch (sc->cid.chip_id) { 2052 case BHND_CHIPID_BCM4312: 2053 /* assume default works */ 2054 break; 2055 case BHND_CHIPID_BCM4322: 2056 case BHND_CHIPID_BCM43221: 2057 case BHND_CHIPID_BCM43231: 2058 case BHND_CHIPID_BCM4342: 2059 if (sc->cid.chip_rev != 0) 2060 break; 2061 2062 min_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK); 2063 max_mask = BHND_PMU_READ_4(sc, BHND_PMU_MIN_RES_MASK); 2064 res_ht = PMURES_BIT(RES4322_HT_SI_AVAIL); 2065 res_pll = PMURES_BIT(RES4322_SI_PLL_ON); 2066 2067 /* Have to remove HT Avail request before powering off PLL */ 2068 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_ht); 2069 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_ht); 2070 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 2071 2072 /* Make sure the PLL is off */ 2073 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~res_pll); 2074 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, ~res_pll); 2075 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 2076 2077 DELAY(1000); 2078 2079 BHND_PMU_PLL_WRITE(sc, BHND_PMU2_SI_PLL_PLLCTL, 0x380005c0, ~0); 2080 DELAY(100); 2081 2082 BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask); 2083 DELAY(100); 2084 BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask); 2085 DELAY(100); 2086 2087 break; 2088 case BHND_CHIPID_BCM4325: 2089 bhnd_pmu1_pllinit0(sc, xtalfreq); 2090 break; 2091 case BHND_CHIPID_BCM4328: 2092 bhnd_pmu0_pllinit0(sc, xtalfreq); 2093 break; 2094 case BHND_CHIPID_BCM5354: 2095 if (xtalfreq == 0) 2096 xtalfreq = 25000; 2097 bhnd_pmu0_pllinit0(sc, xtalfreq); 2098 break; 2099 case BHND_CHIPID_BCM4329: 2100 if (xtalfreq == 0) 2101 xtalfreq = 38400; 2102 bhnd_pmu1_pllinit0(sc, xtalfreq); 2103 break; 2104 2105 case BHND_CHIPID_BCM4313: 2106 case BHND_CHIPID_BCM43222: 2107 case BHND_CHIPID_BCM43111: 2108 case BHND_CHIPID_BCM43112: 2109 case BHND_CHIPID_BCM43224: 2110 case BHND_CHIPID_BCM43225: 2111 case BHND_CHIPID_BCM43420: 2112 case BHND_CHIPID_BCM43421: 2113 case BHND_CHIPID_BCM43226: 2114 case BHND_CHIPID_BCM43235: 2115 case BHND_CHIPID_BCM43236: 2116 case BHND_CHIPID_BCM43238: 2117 case BHND_CHIPID_BCM43234: 2118 case BHND_CHIPID_BCM43237: 2119 case BHND_CHIPID_BCM4331: 2120 case BHND_CHIPID_BCM43431: 2121 case BHND_CHIPID_BCM43131: 2122 case BHND_CHIPID_BCM43227: 2123 case BHND_CHIPID_BCM43228: 2124 case BHND_CHIPID_BCM43428: 2125 case BHND_CHIPID_BCM6362: 2126 /* assume default works */ 2127 break; 2128 2129 case BHND_CHIPID_BCM4315: 2130 case BHND_CHIPID_BCM4319: 2131 case BHND_CHIPID_BCM4336: 2132 case BHND_CHIPID_BCM4330: 2133 bhnd_pmu1_pllinit0(sc, xtalfreq); 2134 break; 2135 default: 2136 PMU_DEBUG("No PLL init done for chip %#hx rev %d pmurev %d\n", 2137 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc)); 2138 break; 2139 } 2140 } 2141 2142 /** 2143 * Return the ALP/XTAL clock frequency, in Hz. 2144 * 2145 * @param sc PMU query instance. 2146 */ 2147 uint32_t 2148 bhnd_pmu_alp_clock(struct bhnd_pmu_query *sc) 2149 { 2150 uint32_t clock; 2151 2152 clock = BHND_PMU_ALP_CLOCK; 2153 switch (sc->cid.chip_id) { 2154 case BHND_CHIPID_BCM4328: 2155 case BHND_CHIPID_BCM5354: 2156 clock = bhnd_pmu0_alpclk0(sc); 2157 break; 2158 case BHND_CHIPID_BCM4315: 2159 case BHND_CHIPID_BCM4319: 2160 case BHND_CHIPID_BCM4325: 2161 case BHND_CHIPID_BCM4329: 2162 case BHND_CHIPID_BCM4330: 2163 case BHND_CHIPID_BCM4336: 2164 clock = bhnd_pmu1_alpclk0(sc); 2165 break; 2166 case BHND_CHIPID_BCM4312: 2167 case BHND_CHIPID_BCM4322: 2168 case BHND_CHIPID_BCM43221: 2169 case BHND_CHIPID_BCM43231: 2170 case BHND_CHIPID_BCM43222: 2171 case BHND_CHIPID_BCM43111: 2172 case BHND_CHIPID_BCM43112: 2173 case BHND_CHIPID_BCM43224: 2174 case BHND_CHIPID_BCM43225: 2175 case BHND_CHIPID_BCM43420: 2176 case BHND_CHIPID_BCM43421: 2177 case BHND_CHIPID_BCM43226: 2178 case BHND_CHIPID_BCM43235: 2179 case BHND_CHIPID_BCM43236: 2180 case BHND_CHIPID_BCM43238: 2181 case BHND_CHIPID_BCM43234: 2182 case BHND_CHIPID_BCM43237: 2183 case BHND_CHIPID_BCM4331: 2184 case BHND_CHIPID_BCM43431: 2185 case BHND_CHIPID_BCM43131: 2186 case BHND_CHIPID_BCM43227: 2187 case BHND_CHIPID_BCM43228: 2188 case BHND_CHIPID_BCM43428: 2189 case BHND_CHIPID_BCM6362: 2190 case BHND_CHIPID_BCM4342: 2191 case BHND_CHIPID_BCM4716: 2192 case BHND_CHIPID_BCM4748: 2193 case BHND_CHIPID_BCM47162: 2194 case BHND_CHIPID_BCM4313: 2195 case BHND_CHIPID_BCM5357: 2196 case BHND_CHIPID_BCM4749: 2197 case BHND_CHIPID_BCM53572: 2198 /* always 20Mhz */ 2199 clock = 20000 * 1000; 2200 break; 2201 case BHND_CHIPID_BCM5356: 2202 case BHND_CHIPID_BCM4706: 2203 /* always 25Mhz */ 2204 clock = 25000 * 1000; 2205 break; 2206 default: 2207 PMU_DEBUG("No ALP clock specified " 2208 "for chip %s rev %d pmurev %d, using default %d Hz\n", 2209 bcm_chipname(sih->chip, chn, 8), sih->chiprev, 2210 sih->pmurev, clock); 2211 break; 2212 } 2213 2214 return (clock); 2215 } 2216 2217 /* Find the output of the "m" pll divider given pll controls that start with 2218 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. 2219 */ 2220 static uint32_t 2221 bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m) 2222 { 2223 uint32_t div; 2224 uint32_t fc; 2225 uint32_t ndiv; 2226 uint32_t p1, p2; 2227 uint32_t tmp; 2228 2229 if ((pll0 & 3) || (pll0 > BHND_PMU4716_MAINPLL_PLL0)) { 2230 PMU_LOG(sc, "%s: Bad pll0: %d", __func__, pll0); 2231 return (0); 2232 } 2233 2234 /* Strictly there is an m5 divider, but I'm not sure we use it */ 2235 if ((m == 0) || (m > 4)) { 2236 PMU_LOG(sc, "%s: Bad m divider: %d", __func__, m); 2237 return (0); 2238 } 2239 2240 if (sc->cid.chip_id == BHND_CHIPID_BCM5357 || 2241 sc->cid.chip_id == BHND_CHIPID_BCM4749) 2242 { 2243 /* Detect failure in clock setting */ 2244 tmp = sc->io->rd_chipst(sc->io_ctx); 2245 if ((tmp & 0x40000) != 0) 2246 return (133 * 1000000); 2247 } 2248 2249 /* Fetch p1 and p2 */ 2250 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2251 pll0 + BHND_PMU5_PLL_P1P2_OFF); 2252 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2253 2254 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2255 p1 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P1); 2256 p2 = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_P2); 2257 2258 /* Fetch div */ 2259 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2260 pll0 + BHND_PMU5_PLL_M14_OFF); 2261 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2262 2263 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2264 div = (tmp >> ((m - 1) * BHND_PMU5_PLL_MDIV_WIDTH)); 2265 div &= BHND_PMU5_PLL_MDIV_MASK; 2266 2267 /* Fetch ndiv */ 2268 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2269 pll0 + BHND_PMU5_PLL_NM5_OFF); 2270 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2271 2272 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2273 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU5_PLL_NDIV); 2274 2275 /* Do calculation in Mhz */ 2276 fc = bhnd_pmu_alp_clock(sc) / 1000000; 2277 fc = (p1 * ndiv * fc) / p2; 2278 2279 PMU_DEBUG(sc, "%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, " 2280 "clock=%d\n", __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div); 2281 2282 /* Return clock in Hertz */ 2283 return ((fc / div) * 1000000); 2284 } 2285 2286 static uint32_t 2287 bhnd_pmu6_4706_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m) 2288 { 2289 uint32_t chipst, clock; 2290 uint32_t ndiv, p1div, p2div, tmp; 2291 2292 /* Get N, P1 and P2 dividers to determine CPU clock */ 2293 BHND_PMU_WRITE_4(sc, BHND_PMU_PLL_CONTROL_ADDR, 2294 pll0 + BHND_PMU6_4706_PROCPLL_OFF); 2295 BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_ADDR); 2296 2297 tmp = BHND_PMU_READ_4(sc, BHND_PMU_PLL_CONTROL_DATA); 2298 ndiv = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_NDIV_INT); 2299 p1div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P1DIV); 2300 p2div = BHND_PMU_GET_BITS(tmp, BHND_PMU6_4706_PROC_P2DIV); 2301 2302 /* Fixed 25MHz reference clock */ 2303 clock = 25 * 1000 * 1000; 2304 2305 /* The low-cost bonding uses an input divider of 4; otherwise, 2 */ 2306 chipst = sc->io->rd_chipst(sc->io_ctx); 2307 if (chipst & CHIPC_CST4706_LOWCOST_PKG) 2308 clock /= 4; 2309 else 2310 clock /= 2; 2311 2312 clock *= ndiv * p2div / p1div; 2313 2314 switch (m) { 2315 case BHND_PMU6_MAINPLL_CPU: 2316 return (clock); 2317 case BHND_PMU6_MAINPLL_MEM: 2318 return (clock / 2); 2319 case BHND_PMU6_MAINPLL_SI: 2320 return (clock / 4); 2321 default: 2322 PMU_LOG(sc, "bad m divider: %d", m); 2323 return (0); 2324 } 2325 } 2326 2327 /** 2328 * Return the backplane clock frequency, in Hz. 2329 * 2330 * On designs that feed the same clock to both backplane 2331 * and CPU, this returns the CPU clock speed. 2332 * 2333 * @param sc PMU query instance. 2334 */ 2335 uint32_t 2336 bhnd_pmu_si_clock(struct bhnd_pmu_query *sc) 2337 { 2338 uint32_t chipst; 2339 uint32_t clock; 2340 2341 clock = BHND_PMU_HT_CLOCK; 2342 2343 switch (sc->cid.chip_id) { 2344 case BHND_CHIPID_BCM4322: 2345 case BHND_CHIPID_BCM43221: 2346 case BHND_CHIPID_BCM43231: 2347 case BHND_CHIPID_BCM43222: 2348 case BHND_CHIPID_BCM43111: 2349 case BHND_CHIPID_BCM43112: 2350 case BHND_CHIPID_BCM43224: 2351 case BHND_CHIPID_BCM43420: 2352 case BHND_CHIPID_BCM43225: 2353 case BHND_CHIPID_BCM43421: 2354 case BHND_CHIPID_BCM43226: 2355 case BHND_CHIPID_BCM4331: 2356 case BHND_CHIPID_BCM43431: 2357 case BHND_CHIPID_BCM6362: 2358 case BHND_CHIPID_BCM4342: 2359 /* 96MHz backplane clock */ 2360 clock = 96000 * 1000; 2361 break; 2362 2363 case BHND_CHIPID_BCM4716: 2364 case BHND_CHIPID_BCM4748: 2365 case BHND_CHIPID_BCM47162: 2366 clock = bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0, 2367 BHND_PMU5_MAINPLL_SI); 2368 break; 2369 2370 case BHND_CHIPID_BCM4325: 2371 clock = bhnd_pmu1_cpuclk0(sc); 2372 break; 2373 2374 case BHND_CHIPID_BCM4328: 2375 clock = bhnd_pmu0_cpuclk0(sc); 2376 break; 2377 2378 case BHND_CHIPID_BCM4329: 2379 if (sc->cid.chip_rev == 0) 2380 clock = 38400 * 1000; 2381 else 2382 clock = bhnd_pmu1_cpuclk0(sc); 2383 break; 2384 2385 case BHND_CHIPID_BCM4315: 2386 case BHND_CHIPID_BCM4319: 2387 case BHND_CHIPID_BCM4336: 2388 case BHND_CHIPID_BCM4330: 2389 clock = bhnd_pmu1_cpuclk0(sc); 2390 break; 2391 2392 case BHND_CHIPID_BCM4312: 2393 case BHND_CHIPID_BCM4313: 2394 /* 80MHz backplane clock */ 2395 clock = 80000 * 1000; 2396 break; 2397 2398 case BHND_CHIPID_BCM43234: 2399 case BHND_CHIPID_BCM43235: 2400 case BHND_CHIPID_BCM43236: 2401 case BHND_CHIPID_BCM43238: 2402 chipst = sc->io->rd_chipst(sc->io_ctx); 2403 if (chipst & CHIPC_CST43236_BP_CLK) 2404 clock = 120000 * 1000; 2405 else 2406 clock = 96000 * 1000; 2407 break; 2408 case BHND_CHIPID_BCM43237: 2409 chipst = sc->io->rd_chipst(sc->io_ctx); 2410 if (chipst & CHIPC_CST43237_BP_CLK) 2411 clock = 96000 * 1000; 2412 else 2413 clock = 80000 * 1000; 2414 break; 2415 case BHND_CHIPID_BCM5356: 2416 clock = bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0, 2417 BHND_PMU5_MAINPLL_SI); 2418 break; 2419 case BHND_CHIPID_BCM5357: 2420 case BHND_CHIPID_BCM4749: 2421 clock = bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0, 2422 BHND_PMU5_MAINPLL_SI); 2423 break; 2424 case BHND_CHIPID_BCM4706: 2425 clock = bhnd_pmu6_4706_clock(sc, BHND_PMU4706_MAINPLL_PLL0, 2426 BHND_PMU6_MAINPLL_SI); 2427 break; 2428 case BHND_CHIPID_BCM53572: 2429 clock = 75000000; 2430 break; 2431 default: 2432 PMU_LOG(sc, "No backplane clock specified for chip %#hx rev " 2433 "%hhd pmurev %hhd, using default %dHz\n", 2434 sc->cid.chip_id, sc->cid.chip_rev, BHND_PMU_REV(sc), clock); 2435 break; 2436 } 2437 2438 return (clock); 2439 } 2440 2441 /** 2442 * Return the CPU clock frequency, in Hz. 2443 * 2444 * @param sc PMU query instance. 2445 */ 2446 uint32_t 2447 bhnd_pmu_cpu_clock(struct bhnd_pmu_query *sc) 2448 { 2449 /* 5354 chip uses a non programmable PLL of frequency 240MHz */ 2450 if (sc->cid.chip_id == BHND_CHIPID_BCM5354) 2451 return (240 * 1000 * 1000); /* 240MHz */ 2452 2453 if (sc->cid.chip_id == BHND_CHIPID_BCM53572) 2454 return (300000000); 2455 2456 if (BHND_PMU_REV(sc) >= 5 && 2457 sc->cid.chip_id != BHND_CHIPID_BCM4329 && 2458 sc->cid.chip_id != BHND_CHIPID_BCM4319 && 2459 sc->cid.chip_id != BHND_CHIPID_BCM43234 && 2460 sc->cid.chip_id != BHND_CHIPID_BCM43235 && 2461 sc->cid.chip_id != BHND_CHIPID_BCM43236 && 2462 sc->cid.chip_id != BHND_CHIPID_BCM43237 && 2463 sc->cid.chip_id != BHND_CHIPID_BCM43238 && 2464 sc->cid.chip_id != BHND_CHIPID_BCM4336 && 2465 sc->cid.chip_id != BHND_CHIPID_BCM4330) 2466 { 2467 switch (sc->cid.chip_id) { 2468 case BHND_CHIPID_BCM5356: 2469 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0, 2470 BHND_PMU5_MAINPLL_CPU)); 2471 2472 case BHND_CHIPID_BCM5357: 2473 case BHND_CHIPID_BCM4749: 2474 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0, 2475 BHND_PMU5_MAINPLL_CPU)); 2476 2477 case BHND_CHIPID_BCM4706: 2478 return (bhnd_pmu6_4706_clock(sc, 2479 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_CPU)); 2480 2481 default: 2482 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0, 2483 BHND_PMU5_MAINPLL_CPU)); 2484 } 2485 } else { 2486 return (bhnd_pmu_si_clock(sc)); 2487 } 2488 } 2489 2490 /** 2491 * Return the memory clock frequency, in Hz. 2492 * 2493 * @param sc PMU query instance. 2494 */ 2495 uint32_t 2496 bhnd_pmu_mem_clock(struct bhnd_pmu_query *sc) 2497 { 2498 if (BHND_PMU_REV(sc) >= 5 && 2499 sc->cid.chip_id != BHND_CHIPID_BCM4329 && 2500 sc->cid.chip_id != BHND_CHIPID_BCM4319 && 2501 sc->cid.chip_id != BHND_CHIPID_BCM43234 && 2502 sc->cid.chip_id != BHND_CHIPID_BCM43235 && 2503 sc->cid.chip_id != BHND_CHIPID_BCM43236 && 2504 sc->cid.chip_id != BHND_CHIPID_BCM43237 && 2505 sc->cid.chip_id != BHND_CHIPID_BCM43238 && 2506 sc->cid.chip_id != BHND_CHIPID_BCM4336 && 2507 sc->cid.chip_id != BHND_CHIPID_BCM4330) 2508 { 2509 switch (sc->cid.chip_id) { 2510 case BHND_CHIPID_BCM5356: 2511 return (bhnd_pmu5_clock(sc, BHND_PMU5356_MAINPLL_PLL0, 2512 BHND_PMU5_MAINPLL_MEM)); 2513 2514 case BHND_CHIPID_BCM5357: 2515 case BHND_CHIPID_BCM4749: 2516 return (bhnd_pmu5_clock(sc, BHND_PMU5357_MAINPLL_PLL0, 2517 BHND_PMU5_MAINPLL_MEM)); 2518 2519 case BHND_CHIPID_BCM4706: 2520 return (bhnd_pmu6_4706_clock(sc, 2521 BHND_PMU4706_MAINPLL_PLL0, BHND_PMU6_MAINPLL_MEM)); 2522 2523 default: 2524 return (bhnd_pmu5_clock(sc, BHND_PMU4716_MAINPLL_PLL0, 2525 BHND_PMU5_MAINPLL_MEM)); 2526 } 2527 2528 } else { 2529 return (bhnd_pmu_si_clock(sc)); 2530 } 2531 } 2532 2533 /* Measure ILP clock frequency */ 2534 #define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */ 2535 2536 /** 2537 * Measure and return the ILP clock frequency, in Hz. 2538 * 2539 * @param sc PMU query instance. 2540 */ 2541 uint32_t 2542 bhnd_pmu_ilp_clock(struct bhnd_pmu_query *sc) 2543 { 2544 uint32_t start, end, delta; 2545 2546 if (sc->ilp_cps == 0) { 2547 start = BHND_PMU_READ_4(sc, BHND_PMU_TIMER); 2548 DELAY(ILP_CALC_DUR); 2549 end = BHND_PMU_READ_4(sc, BHND_PMU_TIMER); 2550 delta = end - start; 2551 sc->ilp_cps = delta * (1000 / ILP_CALC_DUR); 2552 } 2553 2554 return (sc->ilp_cps); 2555 } 2556 2557 /* SDIO Pad drive strength to select value mappings */ 2558 typedef struct { 2559 uint8_t strength; /* Pad Drive Strength in mA */ 2560 uint8_t sel; /* Chip-specific select value */ 2561 } sdiod_drive_str_t; 2562 2563 /* SDIO Drive Strength to sel value table for PMU Rev 1 */ 2564 static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { 2565 { 2566 4, 0x2}, { 2567 2, 0x3}, { 2568 1, 0x0}, { 2569 0, 0x0} 2570 }; 2571 2572 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ 2573 static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { 2574 { 2575 12, 0x7}, { 2576 10, 0x6}, { 2577 8, 0x5}, { 2578 6, 0x4}, { 2579 4, 0x2}, { 2580 2, 0x1}, { 2581 0, 0x0} 2582 }; 2583 2584 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ 2585 static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { 2586 { 2587 32, 0x7}, { 2588 26, 0x6}, { 2589 22, 0x5}, { 2590 16, 0x4}, { 2591 12, 0x3}, { 2592 8, 0x2}, { 2593 4, 0x1}, { 2594 0, 0x0} 2595 }; 2596 2597 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 2598 2599 void 2600 bhnd_pmu_sdiod_drive_strength_init(struct bhnd_pmu_softc *sc, 2601 uint32_t drivestrength) 2602 { 2603 const sdiod_drive_str_t *str_tab; 2604 uint32_t str_mask; 2605 uint32_t str_shift; 2606 u_int intr_val; 2607 2608 str_tab = NULL; 2609 str_mask = 0; 2610 str_shift = 0; 2611 intr_val = 0; 2612 2613 switch (SDIOD_DRVSTR_KEY(sc->cid.chip_id, BHND_PMU_REV(sc))) { 2614 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 1): 2615 str_tab = sdiod_drive_strength_tab1; 2616 str_mask = 0x30000000; 2617 str_shift = 28; 2618 break; 2619 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 2): 2620 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4325, 3): 2621 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4315, 4): 2622 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4319, 7): 2623 str_tab = sdiod_drive_strength_tab2; 2624 str_mask = 0x00003800; 2625 str_shift = 11; 2626 break; 2627 case SDIOD_DRVSTR_KEY(BHND_CHIPID_BCM4336, 8): 2628 str_tab = sdiod_drive_strength_tab3; 2629 str_mask = 0x00003800; 2630 str_shift = 11; 2631 break; 2632 2633 default: 2634 PMU_LOG(sc, "No SDIO Drive strength init done for chip %#x " 2635 "rev %hhd pmurev %hhd\n", sc->cid.chip_id, sc->cid.chip_rev, 2636 BHND_PMU_REV(sc)); 2637 break; 2638 } 2639 2640 if (str_tab != NULL) { 2641 uint32_t drivestrength_sel = 0; 2642 uint32_t cc_data_temp; 2643 2644 for (u_int i = 0; str_tab[i].strength != 0; i++) { 2645 if (drivestrength >= str_tab[i].strength) { 2646 drivestrength_sel = str_tab[i].sel; 2647 break; 2648 } 2649 } 2650 2651 cc_data_temp = BHND_PMU_CCTRL_READ(sc, 1); 2652 cc_data_temp &= ~str_mask; 2653 drivestrength_sel <<= str_shift; 2654 cc_data_temp |= drivestrength_sel; 2655 BHND_PMU_CCTRL_WRITE(sc, 1, cc_data_temp, ~0); 2656 2657 PMU_DEBUG(sc, "SDIO: %dmA drive strength selected, set to " 2658 "0x%08x\n", drivestrength, cc_data_temp); 2659 } 2660 } 2661 2662 /** 2663 * Initialize the PMU. 2664 */ 2665 int 2666 bhnd_pmu_init(struct bhnd_pmu_softc *sc) 2667 { 2668 uint32_t xtalfreq; 2669 int error; 2670 2671 if (BHND_PMU_REV(sc) == 1) { 2672 BHND_PMU_AND_4(sc, BHND_PMU_CTRL, ~BHND_PMU_CTRL_NOILP_ON_WAIT); 2673 } else if (BHND_PMU_REV(sc) >= 2) { 2674 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, BHND_PMU_CTRL_NOILP_ON_WAIT); 2675 } 2676 2677 if (sc->cid.chip_id == BHND_CHIPID_BCM4329 && sc->cid.chip_rev == 2) { 2678 /* Fix for 4329b0 bad LPOM state. */ 2679 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x100, ~0); 2680 BHND_PMU_REGCTRL_WRITE(sc, 3, 0x4, ~0); 2681 } 2682 2683 if (sc->cid.chip_id == BHND_CHIPID_BCM4319) { 2684 /* Limiting the PALDO spike during init time */ 2685 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x00000005, 0x00000007); 2686 } 2687 2688 /* Fetch target xtalfreq, in KHz */ 2689 error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_XTALFREQ, 2690 &xtalfreq); 2691 2692 /* If not available, log any real errors, and then try to measure it */ 2693 if (error) { 2694 if (error != ENOENT) 2695 PMU_LOG(sc, "error fetching xtalfreq: %d\n", error); 2696 2697 xtalfreq = bhnd_pmu_measure_alpclk(sc); 2698 } 2699 2700 /* Perform PLL initialization */ 2701 bhnd_pmu_pll_init(sc, xtalfreq); 2702 2703 if ((error = bhnd_pmu_res_init(sc))) 2704 return (error); 2705 2706 bhnd_pmu_swreg_init(sc); 2707 2708 return (0); 2709 } 2710 2711 /* Return up time in ILP cycles for the given resource. */ 2712 static int 2713 bhnd_pmu_res_uptime(struct bhnd_pmu_softc *sc, uint8_t rsrc, uint32_t *uptime) 2714 { 2715 uint32_t deps; 2716 uint32_t up, dup, dmax; 2717 uint32_t min_mask; 2718 int error; 2719 2720 /* uptime of resource 'rsrc' */ 2721 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, rsrc); 2722 up = BHND_PMU_READ_4(sc, BHND_PMU_RES_UPDN_TIMER); 2723 up = BHND_PMU_GET_BITS(up, BHND_PMU_RES_UPDN_UPTME); 2724 2725 /* Find direct dependencies of resource 'rsrc' */ 2726 deps = bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(rsrc), false); 2727 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) { 2728 if (!(deps & BHND_PMURES_BIT(i))) 2729 continue; 2730 deps &= ~bhnd_pmu_res_deps(sc, BHND_PMURES_BIT(i), true); 2731 } 2732 2733 /* Exclude the minimum resource set */ 2734 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL))) 2735 return (error); 2736 2737 deps &= ~min_mask; 2738 2739 /* max uptime of direct dependencies */ 2740 dmax = 0; 2741 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) { 2742 if (!(deps & BHND_PMURES_BIT(i))) 2743 continue; 2744 2745 if ((error = bhnd_pmu_res_uptime(sc, i, &dup))) 2746 return (error); 2747 2748 if (dmax < dup) 2749 dmax = dup; 2750 } 2751 2752 PMU_DEBUG(sc, "bhnd_pmu_res_uptime: rsrc %hhu uptime %u(deps 0x%08x " 2753 "uptime %u)\n", rsrc, up, deps, dmax); 2754 2755 *uptime = (up + dmax + BHND_PMURES_UP_TRANSITION); 2756 return (0); 2757 } 2758 2759 /* Return dependencies (direct or all/indirect) for the given resources */ 2760 static uint32_t 2761 bhnd_pmu_res_deps(struct bhnd_pmu_softc *sc, uint32_t rsrcs, bool all) 2762 { 2763 uint32_t deps; 2764 2765 deps = 0; 2766 for (uint8_t i = 0; i <= BHND_PMU_RESNUM_MAX; i++) { 2767 if (!(rsrcs & BHND_PMURES_BIT(i))) 2768 continue; 2769 2770 BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); 2771 deps |= BHND_PMU_READ_4(sc, BHND_PMU_RES_DEP_MASK); 2772 } 2773 2774 /* None found? */ 2775 if (deps == 0) 2776 return (0); 2777 2778 /* Recurse dependencies */ 2779 if (all) 2780 deps |= bhnd_pmu_res_deps(sc, deps, true); 2781 2782 return (deps); 2783 } 2784 2785 /* power up/down OTP through PMU resources */ 2786 int 2787 bhnd_pmu_otp_power(struct bhnd_pmu_softc *sc, bool on) 2788 { 2789 uint32_t deps; 2790 uint32_t min_mask; 2791 uint32_t rsrcs; 2792 int error; 2793 2794 /* Determine rsrcs to turn on/off OTP power */ 2795 switch (sc->cid.chip_id) { 2796 case BHND_CHIPID_BCM4322: 2797 case BHND_CHIPID_BCM43221: 2798 case BHND_CHIPID_BCM43231: 2799 case BHND_CHIPID_BCM4342: 2800 rsrcs = PMURES_BIT(RES4322_OTP_PU); 2801 break; 2802 case BHND_CHIPID_BCM4315: 2803 rsrcs = PMURES_BIT(RES4315_OTP_PU); 2804 break; 2805 case BHND_CHIPID_BCM4325: 2806 rsrcs = PMURES_BIT(RES4325_OTP_PU); 2807 break; 2808 case BHND_CHIPID_BCM4329: 2809 rsrcs = PMURES_BIT(RES4329_OTP_PU); 2810 break; 2811 case BHND_CHIPID_BCM4319: 2812 rsrcs = PMURES_BIT(RES4319_OTP_PU); 2813 break; 2814 case BHND_CHIPID_BCM4336: 2815 rsrcs = PMURES_BIT(RES4336_OTP_PU); 2816 break; 2817 case BHND_CHIPID_BCM4330: 2818 rsrcs = PMURES_BIT(RES4330_OTP_PU); 2819 break; 2820 default: 2821 /* Not required? */ 2822 return (0); 2823 } 2824 2825 /* Fetch all dependencies */ 2826 deps = bhnd_pmu_res_deps(sc, rsrcs, true); 2827 2828 /* Exclude the minimum resource set */ 2829 if ((error = bhnd_pmu_res_masks(sc, &min_mask, NULL))) 2830 return (error); 2831 2832 deps &= ~min_mask; 2833 2834 /* Turn on/off the power */ 2835 if (on) { 2836 uint32_t state; 2837 2838 PMU_DEBUG(sc, "Adding rsrc 0x%x to min_res_mask\n", 2839 rsrcs | deps); 2840 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, (rsrcs|deps)); 2841 2842 /* Wait for all resources to become available */ 2843 for (int i = 0; i < BHND_PMU_MAX_TRANSITION_DLY; i += 10) { 2844 state = BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE); 2845 if ((state & rsrcs) == rsrcs) 2846 break; 2847 2848 DELAY(10); 2849 } 2850 2851 if ((state & rsrcs) != rsrcs) { 2852 PMU_LOG(sc, "timeout waiting for OTP resource " 2853 "enable\n"); 2854 return (ENXIO); 2855 } 2856 } else { 2857 PMU_DEBUG(sc, "Removing rsrc 0x%x from min_res_mask\n", 2858 rsrcs | deps); 2859 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~(rsrcs|deps)); 2860 } 2861 2862 return (0); 2863 } 2864 2865 void 2866 bhnd_pmu_rcal(struct bhnd_pmu_softc *sc) 2867 { 2868 uint32_t chipst; 2869 uint32_t val; 2870 uint8_t rcal_code; 2871 bool bluetooth_rcal; 2872 2873 bluetooth_rcal = false; 2874 2875 switch (sc->cid.chip_id) { 2876 case BHND_CHIPID_BCM4325: 2877 case BHND_CHIPID_BCM4329: 2878 /* Kick RCal */ 2879 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1); 2880 2881 /* Power Down RCAL Block */ 2882 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, ~0x04); 2883 2884 if (sc->cid.chip_id == BHND_CHIPID_BCM4325) { 2885 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 2886 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_RCAL_VALID)) 2887 bluetooth_rcal = true; 2888 } 2889 2890 /* Power Up RCAL block */ 2891 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, 0x04); 2892 2893 /* Wait for completion */ 2894 for (int i = 0; i < (10 * 1000 * 1000); i++) { 2895 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 2896 2897 if (chipst & 0x08) 2898 break; 2899 2900 DELAY(10); 2901 } 2902 KASSERT((chipst & 0x08) != 0, ("rcal completion timeout")); 2903 2904 if (bluetooth_rcal) { 2905 rcal_code = 0x6; 2906 } else { 2907 /* Drop LSB to convert from 5 bit code to 4 bit code */ 2908 rcal_code = (uint8_t) (chipst >> 5) & 0x0f; 2909 } 2910 2911 PMU_DEBUG("RCal completed, status 0x%x, code 0x%x\n", 2912 R_REG(&cc->chipstatus), rcal_code); 2913 2914 /* Write RCal code into pmu_vreg_ctrl[32:29] */ 2915 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 0); 2916 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA); 2917 val &= ~((uint32_t) 0x07 << 29); 2918 val |= (uint32_t) (rcal_code & 0x07) << 29; 2919 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val); 2920 2921 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_ADDR, 1); 2922 val = BHND_PMU_READ_4(sc, BHND_PMU_REG_CONTROL_DATA); 2923 val &= ~(uint32_t) 0x01; 2924 val |= (uint32_t) ((rcal_code >> 3) & 0x01); 2925 BHND_PMU_WRITE_4(sc, BHND_PMU_REG_CONTROL_DATA, val); 2926 2927 /* Write RCal code into pmu_chip_ctrl[33:30] */ 2928 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 0); 2929 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIP_CONTROL_DATA); 2930 val &= ~((uint32_t) 0x03 << 30); 2931 val |= (uint32_t) (rcal_code & 0x03) << 30; 2932 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_DATA, val); 2933 2934 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1); 2935 val = BHND_PMU_READ_4(sc, BHND_PMU_CHIP_CONTROL_DATA); 2936 val &= ~(uint32_t) 0x03; 2937 val |= (uint32_t) ((rcal_code >> 2) & 0x03); 2938 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_DATA, val); 2939 2940 /* Set override in pmu_chip_ctrl[29] */ 2941 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 0); 2942 BHND_PMU_OR_4(sc, BHND_PMU_CHIP_CONTROL_DATA, (0x01 << 29)); 2943 2944 /* Power off RCal block */ 2945 BHND_PMU_WRITE_4(sc, BHND_PMU_CHIP_CONTROL_ADDR, 1); 2946 BHND_PMU_AND_4(sc, BHND_PMU_CHIP_CONTROL_DATA, ~0x04); 2947 break; 2948 default: 2949 break; 2950 } 2951 } 2952 2953 int 2954 bhnd_pmu_set_spuravoid(struct bhnd_pmu_softc *sc, bhnd_pmu_spuravoid spuravoid) 2955 { 2956 int error; 2957 2958 /* force the HT off */ 2959 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) { 2960 BHND_PMU_AND_4(sc, BHND_PMU_MAX_RES_MASK, 2961 ~BHND_PMU_RES4336_HT_AVAIL); 2962 2963 /* wait for the ht to really go away */ 2964 PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); 2965 } 2966 2967 /* update the pll changes */ 2968 error = bhnd_pmu_spuravoid_pllupdate(sc, spuravoid); 2969 2970 /* enable HT back on */ 2971 if (sc->cid.chip_id == BHND_CHIPID_BCM4336) { 2972 BHND_PMU_OR_4(sc, BHND_PMU_MAX_RES_MASK, 2973 BHND_PMU_RES4336_HT_AVAIL); 2974 } 2975 2976 return (error); 2977 } 2978 2979 static int 2980 bhnd_pmu_spuravoid_pllupdate(struct bhnd_pmu_softc *sc, 2981 bhnd_pmu_spuravoid spuravoid) 2982 { 2983 uint16_t chip_id; 2984 uint32_t pmuctrl; 2985 uint32_t tmp; 2986 2987 /* 6362a0 has same clks as 4322[4-6] */ 2988 chip_id = sc->cid.chip_id; 2989 if (chip_id == BHND_CHIPID_BCM6362 && sc->cid.chip_rev == 0) { 2990 chip_id = BHND_CHIPID_BCM43224; 2991 } 2992 2993 switch (chip_id) { 2994 case BHND_CHIPID_BCM6362: 2995 KASSERT(sc->cid.chip_rev != 0, ("invalid clock config")); 2996 /* fallthrough */ 2997 case BHND_CHIPID_BCM5357: 2998 case BHND_CHIPID_BCM4749: 2999 case BHND_CHIPID_BCM43235: 3000 case BHND_CHIPID_BCM43236: 3001 case BHND_CHIPID_BCM43238: 3002 case BHND_CHIPID_BCM43234: 3003 case BHND_CHIPID_BCM43237: 3004 case BHND_CHIPID_BCM53572: { 3005 uint8_t p1div, ndiv; 3006 uint8_t phypll_offset; 3007 3008 switch (spuravoid) { 3009 case BHND_PMU_SPURAVOID_NONE: 3010 p1div = 0x1; 3011 ndiv = 0x30; 3012 break; 3013 case BHND_PMU_SPURAVOID_M1: 3014 p1div = 0x5; 3015 ndiv = 0xf6; 3016 break; 3017 case BHND_PMU_SPURAVOID_M2: 3018 p1div = 0x5; 3019 ndiv = 0xfc; 3020 break; 3021 default: 3022 return (ENODEV); 3023 } 3024 3025 /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset 3026 * PLL0_PLLCTL[02] by 6 */ 3027 phypll_offset = 0; 3028 if (sc->cid.chip_id == BHND_CHIPID_BCM5357) 3029 phypll_offset = 6; 3030 3031 /* RMW only the P1 divider */ 3032 tmp = BHND_PMU_SET_BITS(p1div, BHND_PMU1_PLL0_PC0_P1DIV); 3033 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0 + phypll_offset, 3034 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK); 3035 3036 /* RMW only the int feedback divider */ 3037 tmp = BHND_PMU_SET_BITS(ndiv, BHND_PMU1_PLL0_PC2_NDIV_INT); 3038 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2 + phypll_offset, 3039 tmp, BHND_PMU1_PLL0_PC0_P1DIV_MASK); 3040 3041 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3042 break; 3043 } 3044 3045 case BHND_CHIPID_BCM4331: 3046 switch (spuravoid) { 3047 case BHND_PMU_SPURAVOID_NONE: 3048 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3049 0x11100014, ~0); 3050 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3051 0x03000a08, ~0); 3052 break; 3053 3054 case BHND_PMU_SPURAVOID_M1: 3055 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3056 0x11500014, ~0); 3057 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3058 0x0F600a08, ~0); 3059 break; 3060 3061 case BHND_PMU_SPURAVOID_M2: 3062 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3063 0x11500014, ~0); 3064 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3065 0x0FC00a08, ~0); 3066 break; 3067 3068 default: 3069 return (ENODEV); 3070 } 3071 3072 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3073 break; 3074 3075 case BHND_CHIPID_BCM43224: 3076 case BHND_CHIPID_BCM43225: 3077 case BHND_CHIPID_BCM43226: 3078 case BHND_CHIPID_BCM43421: 3079 switch (spuravoid) { 3080 case BHND_PMU_SPURAVOID_NONE: 3081 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3082 0x11100010, ~0); 3083 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3084 0x000c0c06, ~0); 3085 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3086 0x03000a08, ~0); 3087 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3088 0x00000000, ~0); 3089 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3090 0x200005c0, ~0); 3091 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3092 0x88888815, ~0); 3093 break; 3094 3095 case BHND_PMU_SPURAVOID_M1: 3096 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3097 0x11500010, ~0); 3098 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3099 0x000C0C06, ~0); 3100 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3101 0x0F600a08, ~0); 3102 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3103 0x00000000, ~0); 3104 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3105 0x2001E920, ~0); 3106 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3107 0x88888815, ~0); 3108 break; 3109 3110 case BHND_PMU_SPURAVOID_M2: 3111 default: 3112 return (ENODEV); 3113 } 3114 3115 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3116 break; 3117 3118 case BHND_CHIPID_BCM43111: 3119 case BHND_CHIPID_BCM43112: 3120 case BHND_CHIPID_BCM43222: 3121 case BHND_CHIPID_BCM43420: 3122 switch (spuravoid) { 3123 case BHND_PMU_SPURAVOID_NONE: 3124 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3125 0x11100008, ~0); 3126 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3127 0x0c000c06, ~0); 3128 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3129 0x03000a08, ~0); 3130 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3131 0x00000000, ~0); 3132 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3133 0x200005c0, ~0); 3134 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3135 0x88888855, ~0); 3136 break; 3137 3138 case BHND_PMU_SPURAVOID_M1: 3139 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3140 0x11500008, ~0); 3141 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3142 0x0c000c06, ~0); 3143 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3144 0x0f600a08, ~0); 3145 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3146 0x00000000, ~0); 3147 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3148 0x2001e920, ~0); 3149 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3150 0x88888815, ~0); 3151 break; 3152 3153 case BHND_PMU_SPURAVOID_M2: 3154 default: 3155 return (ENODEV); 3156 } 3157 3158 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3159 break; 3160 3161 case BHND_CHIPID_BCM4716: 3162 case BHND_CHIPID_BCM4748: 3163 case BHND_CHIPID_BCM47162: 3164 switch (spuravoid) { 3165 case BHND_PMU_SPURAVOID_NONE: 3166 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3167 0x11100060, ~0); 3168 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3169 0x080c0c06, ~0); 3170 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3171 0x03000000, ~0); 3172 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3173 0x00000000, ~0); 3174 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3175 0x200005c0, ~0); 3176 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3177 0x88888815, ~0); 3178 break; 3179 3180 case BHND_PMU_SPURAVOID_M1: 3181 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3182 0x11500060, ~0); 3183 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3184 0x080C0C06, ~0); 3185 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3186 0x0F600000, ~0); 3187 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3188 0x00000000, ~0); 3189 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3190 0x2001E924, ~0); 3191 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3192 0x88888815, ~0); 3193 break; 3194 3195 case BHND_PMU_SPURAVOID_M2: 3196 default: 3197 return (ENODEV); 3198 } 3199 3200 pmuctrl = BHND_PMU_CTRL_NOILP_ON_WAIT | 3201 BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3202 break; 3203 3204 case BHND_CHIPID_BCM4319: 3205 pmuctrl = 0; 3206 break; 3207 3208 case BHND_CHIPID_BCM4322: 3209 case BHND_CHIPID_BCM43221: 3210 case BHND_CHIPID_BCM43231: 3211 case BHND_CHIPID_BCM4342: 3212 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x11100070, ~0); 3213 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x1014140a, ~0); 3214 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888854, ~0); 3215 3216 switch (spuravoid) { 3217 case BHND_PMU_SPURAVOID_NONE: 3218 /* enable 40/80/160Mhz clock mode */ 3219 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3220 0x05001828, ~0); 3221 break; 3222 3223 case BHND_PMU_SPURAVOID_M1: 3224 /* spur_avoid ON, enable 41/82/164Mhz clock mode */ 3225 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3226 0x05201828, ~0); 3227 break; 3228 3229 case BHND_PMU_SPURAVOID_M2: 3230 default: 3231 return (ENODEV); 3232 } 3233 3234 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3235 break; 3236 3237 case BHND_CHIPID_BCM4336: 3238 /* Looks like these are only for default xtal freq 26MHz */ 3239 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 0x02100020, ~0); 3240 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 0x0C0C0C0C, ~0); 3241 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 0x01240C0C, ~0); 3242 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 0x202C2820, ~0); 3243 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 0x88888825, ~0); 3244 3245 switch (spuravoid) { 3246 case BHND_PMU_SPURAVOID_NONE: 3247 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3248 0x00762762, ~0); 3249 break; 3250 3251 case BHND_PMU_SPURAVOID_M1: 3252 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3253 0x00EC4EC4, ~0); 3254 break; 3255 3256 case BHND_PMU_SPURAVOID_M2: 3257 default: 3258 return (ENODEV); 3259 } 3260 3261 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3262 break; 3263 3264 case BHND_CHIPID_BCM43131: 3265 case BHND_CHIPID_BCM43227: 3266 case BHND_CHIPID_BCM43228: 3267 case BHND_CHIPID_BCM43428: 3268 /* LCNXN */ 3269 /* PLL Settings for spur avoidance on/off mode, no on2 support 3270 * for 43228A0 */ 3271 switch (spuravoid) { 3272 case BHND_PMU_SPURAVOID_NONE: 3273 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3274 0x11100014, ~0); 3275 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3276 0x040c0c06, ~0); 3277 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3278 0x03000a08, ~0); 3279 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3280 0x00000000, ~0); 3281 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3282 0x200005c0, ~0); 3283 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3284 0x88888815, ~0); 3285 break; 3286 3287 case BHND_PMU_SPURAVOID_M1: 3288 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL0, 3289 0x01100014, ~0); 3290 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, 3291 0x040C0C06, ~0); 3292 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, 3293 0x03140A08, ~0); 3294 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL3, 3295 0x00333333, ~0); 3296 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL4, 3297 0x202C2820, ~0); 3298 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL5, 3299 0x88888815, ~0); 3300 break; 3301 3302 case BHND_PMU_SPURAVOID_M2: 3303 default: 3304 return (ENODEV); 3305 } 3306 3307 pmuctrl = BHND_PMU_CTRL_PLL_PLLCTL_UPD; 3308 break; 3309 default: 3310 PMU_LOG(sc, "%s: unknown spuravoidance settings for chip %#hx, " 3311 "not changing PLL", __func__, sc->cid.chip_id); 3312 3313 return (ENODEV); 3314 } 3315 3316 if (pmuctrl != 0) 3317 BHND_PMU_OR_4(sc, BHND_PMU_CTRL, pmuctrl); 3318 3319 return (0); 3320 } 3321 3322 bool 3323 bhnd_pmu_is_otp_powered(struct bhnd_pmu_softc *sc) 3324 { 3325 uint32_t otp_res; 3326 3327 /* Determine per-chip OTP resource */ 3328 switch (sc->cid.chip_id) { 3329 case BHND_CHIPID_BCM4329: 3330 otp_res = PMURES_BIT(RES4329_OTP_PU); 3331 break; 3332 case BHND_CHIPID_BCM4319: 3333 otp_res = PMURES_BIT(RES4319_OTP_PU); 3334 break; 3335 case BHND_CHIPID_BCM4336: 3336 otp_res = PMURES_BIT(RES4336_OTP_PU); 3337 break; 3338 case BHND_CHIPID_BCM4330: 3339 otp_res = PMURES_BIT(RES4330_OTP_PU); 3340 break; 3341 3342 /* These chips don't use PMU bit to power up/down OTP. OTP always on. 3343 * Use OTP_INIT command to reset/refresh state. 3344 */ 3345 case BHND_CHIPID_BCM43224: 3346 case BHND_CHIPID_BCM43225: 3347 case BHND_CHIPID_BCM43421: 3348 case BHND_CHIPID_BCM43236: 3349 case BHND_CHIPID_BCM43235: 3350 case BHND_CHIPID_BCM43238: 3351 return (true); 3352 3353 default: 3354 return (true); 3355 } 3356 3357 /* Check resource state */ 3358 if ((BHND_PMU_READ_4(sc, BHND_PMU_RES_STATE) & otp_res) == 0) 3359 return (false); 3360 3361 return (true); 3362 } 3363 3364 int 3365 bhnd_pmu_paref_ldo_enable(struct bhnd_pmu_softc *sc, bool enable) 3366 { 3367 uint32_t ldo; 3368 3369 switch (sc->cid.chip_id) { 3370 case BHND_CHIPID_BCM4328: 3371 ldo = PMURES_BIT(RES4328_PA_REF_LDO); 3372 break; 3373 case BHND_CHIPID_BCM5354: 3374 ldo = PMURES_BIT(RES5354_PA_REF_LDO); 3375 break; 3376 case BHND_CHIPID_BCM4312: 3377 ldo = PMURES_BIT(RES4312_PA_REF_LDO); 3378 break; 3379 default: 3380 return (ENODEV); 3381 } 3382 3383 if (enable) { 3384 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, ldo); 3385 } else { 3386 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~ldo); 3387 } 3388 3389 return (0); 3390 } 3391 3392 /* initialize PMU switch/regulators */ 3393 void 3394 bhnd_pmu_swreg_init(struct bhnd_pmu_softc *sc) 3395 { 3396 uint32_t chipst; 3397 3398 switch (sc->cid.chip_id) { 3399 case BHND_CHIPID_BCM4325: 3400 if (sc->cid.chip_rev <= 2) 3401 break; 3402 3403 chipst = BHND_CHIPC_READ_CHIPST(sc->chipc_dev); 3404 if (BHND_PMU_GET_BITS(chipst, CHIPC_CST4325_PMUTOP_2B)) { 3405 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 3406 0xf); 3407 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 3408 0xf); 3409 } 3410 3411 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb); 3412 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb); 3413 3414 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0x1); 3415 if (sc->board.board_flags & BHND_BFL_LNLDO2_2P5) { 3416 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO2_SEL, 3417 0x1); 3418 } 3419 3420 break; 3421 case BHND_CHIPID_BCM4336: 3422 /* Reduce CLDO PWM output voltage to 1.2V */ 3423 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); 3424 /* Reduce CLDO BURST output voltage to 1.2V */ 3425 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CLDO_BURST, 0xe); 3426 /* Reduce LNLDO1 output voltage to 1.2V */ 3427 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_LNLDO1, 0xe); 3428 if (sc->cid.chip_rev == 0) 3429 BHND_PMU_REGCTRL_WRITE(sc, 2, 0x400000, 0x400000); 3430 break; 3431 3432 case BHND_CHIPID_BCM4330: 3433 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ 3434 bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_CBUCK_PWM, 0); 3435 break; 3436 default: 3437 break; 3438 } 3439 } 3440 3441 int 3442 bhnd_pmu_radio_enable(struct bhnd_pmu_softc *sc, device_t d11core, bool enable) 3443 { 3444 uint32_t oobsel; 3445 uint32_t rsrcs; 3446 int error; 3447 3448 if (bhnd_get_device(d11core) != BHND_COREID_D11) { 3449 device_printf(sc->dev, 3450 "bhnd_pmu_radio_enable() called on non-D11 core"); 3451 return (EINVAL); 3452 } 3453 3454 switch (sc->cid.chip_id) { 3455 case BHND_CHIPID_BCM4325: 3456 if (sc->board.board_flags & BHND_BFL_FASTPWR) 3457 break; 3458 3459 if ((sc->board.board_flags & BHND_BFL_BUCKBOOST) == 0) 3460 break; 3461 3462 rsrcs = PMURES_BIT(RES4325_BUCK_BOOST_BURST); 3463 3464 if (enable) { 3465 BHND_PMU_OR_4(sc, BHND_PMU_MIN_RES_MASK, rsrcs); 3466 DELAY(100 * 1000); /* 100ms */ 3467 } else { 3468 BHND_PMU_AND_4(sc, BHND_PMU_MIN_RES_MASK, ~rsrcs); 3469 } 3470 3471 return (0); 3472 3473 case BHND_CHIPID_BCM4319: 3474 error = bhnd_read_config(d11core, BCMA_DMP_OOBSELOUTB74, 3475 &oobsel, 4); 3476 if (error) 3477 return (error); 3478 3479 if (enable) { 3480 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3481 BCMA_DMP_OOBSEL_5); 3482 oobsel |= BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3483 BCMA_DMP_OOBSEL_6); 3484 } else { 3485 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3486 BCMA_DMP_OOBSEL_5); 3487 oobsel &= ~BHND_PMU_SET_BITS(BCMA_DMP_OOBSEL_EN, 3488 BCMA_DMP_OOBSEL_6); 3489 } 3490 3491 return (bhnd_write_config(d11core, BCMA_DMP_OOBSELOUTB74, 3492 &oobsel, 4)); 3493 } 3494 3495 return (0); 3496 } 3497 3498 /* Wait for a particular clock level to be on the backplane */ 3499 uint32_t 3500 bhnd_pmu_waitforclk_on_backplane(struct bhnd_pmu_softc *sc, uint32_t clk, 3501 uint32_t delay) 3502 { 3503 uint32_t pmu_st; 3504 3505 for (uint32_t i = 0; i < delay; i += 10) { 3506 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST); 3507 if ((pmu_st & clk) == clk) 3508 return (clk); 3509 3510 DELAY(10); 3511 } 3512 3513 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST); 3514 return (pmu_st & clk); 3515 } 3516 3517 /* 3518 * Measures the ALP clock frequency in KHz. Returns 0 if not possible. 3519 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal. 3520 */ 3521 3522 #define EXT_ILP_HZ 32768 3523 3524 uint32_t 3525 bhnd_pmu_measure_alpclk(struct bhnd_pmu_softc *sc) 3526 { 3527 uint32_t alp_khz; 3528 uint32_t pmu_st; 3529 3530 if (BHND_PMU_REV(sc) < 10) 3531 return (0); 3532 3533 pmu_st = BHND_PMU_READ_4(sc, BHND_PMU_ST); 3534 if (pmu_st & BHND_PMU_ST_EXTLPOAVAIL) { 3535 uint32_t alp_hz, ilp_ctr; 3536 3537 /* Enable frequency measurement */ 3538 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 1U << 3539 BHND_PMU_XTALFREQ_REG_MEASURE_SHIFT); 3540 3541 /* Delay for well over 4 ILP clocks */ 3542 DELAY(1000); 3543 3544 /* Read the latched number of ALP ticks per 4 ILP ticks */ 3545 ilp_ctr = BHND_PMU_READ_4(sc, BHND_PMU_XTALFREQ); 3546 ilp_ctr = BHND_PMU_GET_BITS(ilp_ctr, 3547 BHND_PMU_XTALFREQ_REG_ILPCTR); 3548 3549 /* Turn off PMU_XTALFREQ_REG_MEASURE to save power */ 3550 BHND_PMU_WRITE_4(sc, BHND_PMU_XTALFREQ, 0); 3551 3552 /* Calculate ALP frequency */ 3553 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; 3554 3555 /* Round to nearest 100KHz and convert to KHz */ 3556 alp_khz = (alp_hz + 50000) / 100000 * 100; 3557 } else { 3558 alp_khz = 0; 3559 } 3560 3561 return (alp_khz); 3562 } 3563 3564 static void 3565 bhnd_pmu_set_4330_plldivs(struct bhnd_pmu_softc *sc) 3566 { 3567 uint32_t FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000; 3568 uint32_t m1div, m2div, m3div, m4div, m5div, m6div; 3569 uint32_t pllc1, pllc2; 3570 3571 m2div = m3div = m4div = m6div = FVCO / 80; 3572 m5div = FVCO / 160; 3573 3574 if (PMU_CST4330_SDIOD_CHIPMODE(sc)) 3575 m1div = FVCO / 80; 3576 else 3577 m1div = FVCO / 90; 3578 3579 pllc1 = 0; 3580 pllc1 |= BHND_PMU_SET_BITS(m1div, BHND_PMU1_PLL0_PC1_M1DIV); 3581 pllc1 |= BHND_PMU_SET_BITS(m2div, BHND_PMU1_PLL0_PC1_M2DIV); 3582 pllc1 |= BHND_PMU_SET_BITS(m3div, BHND_PMU1_PLL0_PC1_M3DIV); 3583 pllc1 |= BHND_PMU_SET_BITS(m4div, BHND_PMU1_PLL0_PC1_M4DIV); 3584 3585 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL1, pllc1, ~0); 3586 3587 pllc2 = 0; 3588 pllc2 |= BHND_PMU_SET_BITS(m5div, BHND_PMU1_PLL0_PC2_M5DIV); 3589 pllc2 |= BHND_PMU_SET_BITS(m6div, BHND_PMU1_PLL0_PC2_M6DIV); 3590 3591 BHND_PMU_PLL_WRITE(sc, BHND_PMU1_PLL0_PLLCTL2, pllc2, 3592 BHND_PMU1_PLL0_PC2_M5DIV_MASK | BHND_PMU1_PLL0_PC2_M6DIV_MASK); 3593 } 3594