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