The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 69a3c67780011973e7a395dc138f0e3b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.