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/chipc/chipc.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: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
    5  * Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com>
    6  * Copyright (c) 2017 The FreeBSD Foundation
    7  * All rights reserved.
    8  *
    9  * Portions of this software were developed by Landon Fuller
   10  * under sponsorship from the FreeBSD Foundation.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer,
   17  *    without modification.
   18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   19  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   20  *    redistribution must be conditioned upon including a substantially
   21  *    similar Disclaimer requirement for further binary redistribution.
   22  *
   23  * NO WARRANTY
   24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   26  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   28  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   29  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   32  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   34  * THE POSSIBILITY OF SUCH DAMAGES.
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD$");
   39 
   40 /*
   41  * Broadcom ChipCommon driver.
   42  * 
   43  * With the exception of some very early chipsets, the ChipCommon core
   44  * has been included in all HND SoCs and chipsets based on the siba(4) 
   45  * and bcma(4) interconnects, providing a common interface to chipset 
   46  * identification, bus enumeration, UARTs, clocks, watchdog interrupts,
   47  * GPIO, flash, etc.
   48  */
   49 
   50 #include <sys/param.h>
   51 #include <sys/kernel.h>
   52 #include <sys/lock.h>
   53 #include <sys/bus.h>
   54 #include <sys/rman.h>
   55 #include <sys/malloc.h>
   56 #include <sys/module.h>
   57 #include <sys/mutex.h>
   58 #include <sys/systm.h>
   59 
   60 #include <machine/bus.h>
   61 #include <machine/resource.h>
   62 
   63 #include <dev/bhnd/bhnd.h>
   64 #include <dev/bhnd/bhndvar.h>
   65 
   66 #include "chipcreg.h"
   67 #include "chipcvar.h"
   68 
   69 #include "chipc_private.h"
   70 
   71 static struct bhnd_device_quirk chipc_quirks[];
   72 
   73 /* Supported device identifiers */
   74 static const struct bhnd_device chipc_devices[] = {
   75         BHND_DEVICE(BCM, CC, NULL, chipc_quirks),
   76         BHND_DEVICE(BCM, 4706_CC, NULL, chipc_quirks),
   77         BHND_DEVICE_END
   78 };
   79 
   80 /* Device quirks table */
   81 static struct bhnd_device_quirk chipc_quirks[] = {
   82         /* HND OTP controller revisions */
   83         BHND_CORE_QUIRK (HWREV_EQ (12),         CHIPC_QUIRK_OTP_HND), /* (?) */
   84         BHND_CORE_QUIRK (HWREV_EQ (17),         CHIPC_QUIRK_OTP_HND), /* BCM4311 */
   85         BHND_CORE_QUIRK (HWREV_EQ (22),         CHIPC_QUIRK_OTP_HND), /* BCM4312 */
   86 
   87         /* IPX OTP controller revisions */
   88         BHND_CORE_QUIRK (HWREV_EQ (21),         CHIPC_QUIRK_OTP_IPX),
   89         BHND_CORE_QUIRK (HWREV_GTE(23),         CHIPC_QUIRK_OTP_IPX),
   90 
   91         BHND_CORE_QUIRK (HWREV_GTE(32),         CHIPC_QUIRK_SUPPORTS_SPROM),
   92         BHND_CORE_QUIRK (HWREV_GTE(35),         CHIPC_QUIRK_SUPPORTS_CAP_EXT),
   93         BHND_CORE_QUIRK (HWREV_GTE(49),         CHIPC_QUIRK_IPX_OTPL_SIZE),
   94 
   95         /* 4706 variant quirks */
   96         BHND_CORE_QUIRK (HWREV_EQ (38),         CHIPC_QUIRK_4706_NFLASH), /* BCM5357? */
   97         BHND_CHIP_QUIRK (4706,  HWREV_ANY,      CHIPC_QUIRK_4706_NFLASH),
   98 
   99         /* 4331 quirks*/
  100         BHND_CHIP_QUIRK (4331,  HWREV_ANY,      CHIPC_QUIRK_4331_EXTPA_MUX_SPROM),
  101         BHND_PKG_QUIRK  (4331,  TN,             CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM),
  102         BHND_PKG_QUIRK  (4331,  TNA0,           CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM),
  103         BHND_PKG_QUIRK  (4331,  TT,             CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM),
  104 
  105         /* 4360 quirks */
  106         BHND_CHIP_QUIRK (4352,  HWREV_LTE(2),   CHIPC_QUIRK_4360_FEM_MUX_SPROM),
  107         BHND_CHIP_QUIRK (43460, HWREV_LTE(2),   CHIPC_QUIRK_4360_FEM_MUX_SPROM),
  108         BHND_CHIP_QUIRK (43462, HWREV_LTE(2),   CHIPC_QUIRK_4360_FEM_MUX_SPROM),
  109         BHND_CHIP_QUIRK (43602, HWREV_LTE(2),   CHIPC_QUIRK_4360_FEM_MUX_SPROM),
  110 
  111         BHND_DEVICE_QUIRK_END
  112 };
  113 
  114 static int               chipc_add_children(struct chipc_softc *sc);
  115 
  116 static bhnd_nvram_src    chipc_find_nvram_src(struct chipc_softc *sc,
  117                              struct chipc_caps *caps);
  118 static int               chipc_read_caps(struct chipc_softc *sc,
  119                              struct chipc_caps *caps);
  120 
  121 static bool              chipc_should_enable_muxed_sprom(
  122                              struct chipc_softc *sc);
  123 static int               chipc_enable_otp_power(struct chipc_softc *sc);
  124 static void              chipc_disable_otp_power(struct chipc_softc *sc);
  125 static int               chipc_enable_sprom_pins(struct chipc_softc *sc);
  126 static void              chipc_disable_sprom_pins(struct chipc_softc *sc);
  127 
  128 static int               chipc_try_activate_resource(struct chipc_softc *sc,
  129                              device_t child, int type, int rid,
  130                              struct resource *r, bool req_direct);
  131 
  132 static int               chipc_init_rman(struct chipc_softc *sc);
  133 static void              chipc_free_rman(struct chipc_softc *sc);
  134 static struct rman      *chipc_get_rman(struct chipc_softc *sc, int type);
  135 
  136 /* quirk and capability flag convenience macros */
  137 #define CHIPC_QUIRK(_sc, _name) \
  138     ((_sc)->quirks & CHIPC_QUIRK_ ## _name)
  139     
  140 #define CHIPC_CAP(_sc, _name)   \
  141     ((_sc)->caps._name)
  142 
  143 #define CHIPC_ASSERT_QUIRK(_sc, name)   \
  144     KASSERT(CHIPC_QUIRK((_sc), name), ("quirk " __STRING(_name) " not set"))
  145 
  146 #define CHIPC_ASSERT_CAP(_sc, name)     \
  147     KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
  148 
  149 static int
  150 chipc_probe(device_t dev)
  151 {
  152         const struct bhnd_device *id;
  153 
  154         id = bhnd_device_lookup(dev, chipc_devices, sizeof(chipc_devices[0]));
  155         if (id == NULL)
  156                 return (ENXIO);
  157 
  158         bhnd_set_default_core_desc(dev);
  159         return (BUS_PROBE_DEFAULT);
  160 }
  161 
  162 static int
  163 chipc_attach(device_t dev)
  164 {
  165         struct chipc_softc              *sc;
  166         int                              error;
  167 
  168         sc = device_get_softc(dev);
  169         sc->dev = dev;
  170         sc->quirks = bhnd_device_quirks(dev, chipc_devices,
  171             sizeof(chipc_devices[0]));
  172         sc->sprom_refcnt = 0;
  173 
  174         CHIPC_LOCK_INIT(sc);
  175         STAILQ_INIT(&sc->mem_regions);
  176 
  177         /* Set up resource management */
  178         if ((error = chipc_init_rman(sc))) {
  179                 device_printf(sc->dev,
  180                     "failed to initialize chipc resource state: %d\n", error);
  181                 goto failed;
  182         }
  183 
  184         /* Allocate the region containing the chipc register block */
  185         if ((sc->core_region = chipc_find_region_by_rid(sc, 0)) == NULL) {
  186                 error = ENXIO;
  187                 goto failed;
  188         }
  189 
  190         error = chipc_retain_region(sc, sc->core_region,
  191             RF_ALLOCATED|RF_ACTIVE);
  192         if (error) {
  193                 sc->core_region = NULL;
  194                 goto failed;
  195         }
  196 
  197         /* Save a direct reference to our chipc registers */
  198         sc->core = sc->core_region->cr_res;
  199 
  200         /* Fetch and parse capability register(s) */
  201         if ((error = chipc_read_caps(sc, &sc->caps)))
  202                 goto failed;
  203 
  204         if (bootverbose)
  205                 chipc_print_caps(sc->dev, &sc->caps);
  206 
  207         /* Attach all supported child devices */
  208         if ((error = chipc_add_children(sc)))
  209                 goto failed;
  210 
  211         /*
  212          * Register ourselves with the bus; we're fully initialized and can
  213          * response to ChipCommin API requests.
  214          * 
  215          * Since our children may need access to ChipCommon, this must be done
  216          * before attaching our children below (via bus_generic_attach).
  217          */
  218         if ((error = bhnd_register_provider(dev, BHND_SERVICE_CHIPC)))
  219                 goto failed;
  220 
  221         if ((error = bus_generic_attach(dev)))
  222                 goto failed;
  223 
  224         return (0);
  225 
  226 failed:
  227         device_delete_children(sc->dev);
  228 
  229         if (sc->core_region != NULL) {
  230                 chipc_release_region(sc, sc->core_region,
  231                     RF_ALLOCATED|RF_ACTIVE);
  232         }
  233 
  234         chipc_free_rman(sc);
  235         CHIPC_LOCK_DESTROY(sc);
  236         return (error);
  237 }
  238 
  239 static int
  240 chipc_detach(device_t dev)
  241 {
  242         struct chipc_softc      *sc;
  243         int                      error;
  244 
  245         sc = device_get_softc(dev);
  246 
  247         if ((error = bus_generic_detach(dev)))
  248                 return (error);
  249 
  250         if ((error = device_delete_children(dev)))
  251                 return (error);
  252 
  253         if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY)))
  254                 return (error);
  255 
  256         chipc_release_region(sc, sc->core_region, RF_ALLOCATED|RF_ACTIVE);
  257         chipc_free_rman(sc);
  258 
  259         CHIPC_LOCK_DESTROY(sc);
  260 
  261         return (0);
  262 }
  263 
  264 static int
  265 chipc_add_children(struct chipc_softc *sc)
  266 {
  267         device_t         child;
  268         const char      *flash_bus;
  269         int              error;
  270 
  271         /* SPROM/OTP */
  272         if (sc->caps.nvram_src == BHND_NVRAM_SRC_SPROM ||
  273             sc->caps.nvram_src == BHND_NVRAM_SRC_OTP)
  274         {
  275                 child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_nvram", -1);
  276                 if (child == NULL) {
  277                         device_printf(sc->dev, "failed to add nvram device\n");
  278                         return (ENXIO);
  279                 }
  280 
  281                 /* Both OTP and external SPROM are mapped at CHIPC_SPROM_OTP */
  282                 error = chipc_set_mem_resource(sc, child, 0, CHIPC_SPROM_OTP,
  283                     CHIPC_SPROM_OTP_SIZE, 0, 0);
  284                 if (error) {
  285                         device_printf(sc->dev, "failed to set OTP memory "
  286                             "resource: %d\n", error);
  287                         return (error);
  288                 }
  289         }
  290 
  291         /*
  292          * PMU/PWR_CTRL
  293          * 
  294          * On AOB ("Always on Bus") devices, the PMU core (if it exists) is
  295          * attached directly to the bhnd(4) bus -- not chipc.
  296          */
  297         if (sc->caps.pmu && !sc->caps.aob) {
  298                 child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_pmu", -1);
  299                 if (child == NULL) {
  300                         device_printf(sc->dev, "failed to add pmu\n");
  301                         return (ENXIO);
  302                 }
  303         } else if (sc->caps.pwr_ctrl) {
  304                 child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_pwrctl", -1);
  305                 if (child == NULL) {
  306                         device_printf(sc->dev, "failed to add pwrctl\n");
  307                         return (ENXIO);
  308                 }
  309         }
  310 
  311         /* GPIO */
  312         child = BUS_ADD_CHILD(sc->dev, 0, "gpio", -1);
  313         if (child == NULL) {
  314                 device_printf(sc->dev, "failed to add gpio\n");
  315                 return (ENXIO);
  316         }
  317 
  318         error = chipc_set_mem_resource(sc, child, 0, 0, RM_MAX_END, 0, 0);
  319         if (error) {
  320                 device_printf(sc->dev, "failed to set gpio memory resource: "
  321                     "%d\n", error);
  322                 return (error);
  323         }
  324 
  325         /* All remaining devices are SoC-only */
  326         if (bhnd_get_attach_type(sc->dev) != BHND_ATTACH_NATIVE)
  327                 return (0);
  328 
  329         /* UARTs */
  330         for (u_int i = 0; i < min(sc->caps.num_uarts, CHIPC_UART_MAX); i++) {
  331                 int irq_rid, mem_rid;
  332 
  333                 irq_rid = 0;
  334                 mem_rid = 0;
  335 
  336                 child = BUS_ADD_CHILD(sc->dev, 0, "uart", -1);
  337                 if (child == NULL) {
  338                         device_printf(sc->dev, "failed to add uart%u\n", i);
  339                         return (ENXIO);
  340                 }
  341 
  342                 /* Shared IRQ */
  343                 error = chipc_set_irq_resource(sc, child, irq_rid, 0);
  344                 if (error) {
  345                         device_printf(sc->dev, "failed to set uart%u irq %u\n",
  346                             i, 0);
  347                         return (error);
  348                 }
  349 
  350                 /* UART registers are mapped sequentially */
  351                 error = chipc_set_mem_resource(sc, child, mem_rid,
  352                     CHIPC_UART(i), CHIPC_UART_SIZE, 0, 0);
  353                 if (error) {
  354                         device_printf(sc->dev, "failed to set uart%u memory "
  355                             "resource: %d\n", i, error);
  356                         return (error);
  357                 }
  358         }
  359 
  360         /* Flash */
  361         flash_bus = chipc_flash_bus_name(sc->caps.flash_type);
  362         if (flash_bus != NULL) {
  363                 int rid;
  364 
  365                 child = BUS_ADD_CHILD(sc->dev, 0, flash_bus, -1);
  366                 if (child == NULL) {
  367                         device_printf(sc->dev, "failed to add %s device\n",
  368                             flash_bus);
  369                         return (ENXIO);
  370                 }
  371 
  372                 /* flash memory mapping */
  373                 rid = 0;
  374                 error = chipc_set_mem_resource(sc, child, rid, 0, RM_MAX_END, 1,
  375                     1);
  376                 if (error) {
  377                         device_printf(sc->dev, "failed to set flash memory "
  378                             "resource %d: %d\n", rid, error);
  379                         return (error);
  380                 }
  381 
  382                 /* flashctrl registers */
  383                 rid++;
  384                 error = chipc_set_mem_resource(sc, child, rid,
  385                     CHIPC_SFLASH_BASE, CHIPC_SFLASH_SIZE, 0, 0);
  386                 if (error) {
  387                         device_printf(sc->dev, "failed to set flash memory "
  388                             "resource %d: %d\n", rid, error);
  389                         return (error);
  390                 }
  391         }
  392 
  393         return (0);
  394 }
  395 
  396 /**
  397  * Determine the NVRAM data source for this device.
  398  * 
  399  * The SPROM, OTP, and flash capability flags must be fully populated in
  400  * @p caps.
  401  *
  402  * @param sc chipc driver state.
  403  * @param caps capability flags to be used to derive NVRAM configuration.
  404  */
  405 static bhnd_nvram_src
  406 chipc_find_nvram_src(struct chipc_softc *sc, struct chipc_caps *caps)
  407 {
  408         uint32_t                 otp_st, srom_ctrl;
  409 
  410         /*
  411          * We check for hardware presence in order of precedence. For example,
  412          * SPROM is always used in preference to internal OTP if found.
  413          */
  414         if (CHIPC_QUIRK(sc, SUPPORTS_SPROM) && caps->sprom) {
  415                 srom_ctrl = bhnd_bus_read_4(sc->core, CHIPC_SPROM_CTRL);
  416                 if (srom_ctrl & CHIPC_SRC_PRESENT)
  417                         return (BHND_NVRAM_SRC_SPROM);
  418         }
  419 
  420         /* Check for programmed OTP H/W subregion (contains SROM data) */
  421         if (CHIPC_QUIRK(sc, SUPPORTS_OTP) && caps->otp_size > 0) {
  422                 /* TODO: need access to HND-OTP device */
  423                 if (!CHIPC_QUIRK(sc, OTP_HND)) {
  424                         device_printf(sc->dev,
  425                             "NVRAM unavailable: unsupported OTP controller.\n");
  426                         return (BHND_NVRAM_SRC_UNKNOWN);
  427                 }
  428 
  429                 otp_st = bhnd_bus_read_4(sc->core, CHIPC_OTPST);
  430                 if (otp_st & CHIPC_OTPS_GUP_HW)
  431                         return (BHND_NVRAM_SRC_OTP);
  432         }
  433 
  434         /* Check for flash */
  435         if (caps->flash_type != CHIPC_FLASH_NONE)
  436                 return (BHND_NVRAM_SRC_FLASH);
  437 
  438         /* No NVRAM hardware capability declared */
  439         return (BHND_NVRAM_SRC_UNKNOWN);
  440 }
  441 
  442 /* Read and parse chipc capabilities */
  443 static int
  444 chipc_read_caps(struct chipc_softc *sc, struct chipc_caps *caps)
  445 {
  446         uint32_t        cap_reg;
  447         uint32_t        cap_ext_reg;
  448         uint32_t        regval;
  449 
  450         /* Fetch cap registers */
  451         cap_reg = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES);
  452         cap_ext_reg = 0;
  453         if (CHIPC_QUIRK(sc, SUPPORTS_CAP_EXT))
  454                 cap_ext_reg = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES_EXT);
  455 
  456         /* Extract values */
  457         caps->num_uarts         = CHIPC_GET_BITS(cap_reg, CHIPC_CAP_NUM_UART);
  458         caps->mipseb            = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_MIPSEB);
  459         caps->uart_gpio         = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_UARTGPIO);
  460         caps->uart_clock        = CHIPC_GET_BITS(cap_reg, CHIPC_CAP_UCLKSEL);
  461 
  462         caps->extbus_type       = CHIPC_GET_BITS(cap_reg, CHIPC_CAP_EXTBUS);
  463         caps->pwr_ctrl          = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_PWR_CTL);
  464         caps->jtag_master       = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_JTAGP);
  465 
  466         caps->pll_type          = CHIPC_GET_BITS(cap_reg, CHIPC_CAP_PLL);
  467         caps->backplane_64      = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_BKPLN64);
  468         caps->boot_rom          = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_ROM);
  469         caps->pmu               = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_PMU);
  470         caps->eci               = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_ECI);
  471         caps->sprom             = CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_SPROM);
  472         caps->otp_size          = CHIPC_GET_BITS(cap_reg, CHIPC_CAP_OTP_SIZE);
  473 
  474         caps->seci              = CHIPC_GET_FLAG(cap_ext_reg, CHIPC_CAP2_SECI);
  475         caps->gsio              = CHIPC_GET_FLAG(cap_ext_reg, CHIPC_CAP2_GSIO);
  476         caps->aob               = CHIPC_GET_FLAG(cap_ext_reg, CHIPC_CAP2_AOB);
  477 
  478         /* Fetch OTP size for later IPX controller revisions */
  479         if (CHIPC_QUIRK(sc, IPX_OTPL_SIZE)) {
  480                 regval = bhnd_bus_read_4(sc->core, CHIPC_OTPLAYOUT);
  481                 caps->otp_size = CHIPC_GET_BITS(regval, CHIPC_OTPL_SIZE);
  482         }
  483 
  484         /* Determine flash type and parameters */
  485         caps->cfi_width = 0;
  486         switch (CHIPC_GET_BITS(cap_reg, CHIPC_CAP_FLASH)) {
  487         case CHIPC_CAP_SFLASH_ST:
  488                 caps->flash_type = CHIPC_SFLASH_ST;
  489                 break;
  490         case CHIPC_CAP_SFLASH_AT:
  491                 caps->flash_type = CHIPC_SFLASH_AT;
  492                 break;
  493         case CHIPC_CAP_NFLASH:
  494                 /* unimplemented */
  495                 caps->flash_type = CHIPC_NFLASH;
  496                 break;
  497         case CHIPC_CAP_PFLASH:
  498                 caps->flash_type = CHIPC_PFLASH_CFI;
  499 
  500                 /* determine cfi width */
  501                 regval = bhnd_bus_read_4(sc->core, CHIPC_FLASH_CFG);
  502                 if (CHIPC_GET_FLAG(regval, CHIPC_FLASH_CFG_DS))
  503                         caps->cfi_width = 2;
  504                 else
  505                         caps->cfi_width = 1;
  506 
  507                 break;
  508         case CHIPC_CAP_FLASH_NONE:
  509                 caps->flash_type = CHIPC_FLASH_NONE;
  510                 break;
  511                         
  512         }
  513 
  514         /* Handle 4706_NFLASH fallback */
  515         if (CHIPC_QUIRK(sc, 4706_NFLASH) &&
  516             CHIPC_GET_FLAG(cap_reg, CHIPC_CAP_4706_NFLASH))
  517         {
  518                 caps->flash_type = CHIPC_NFLASH_4706;
  519         }
  520 
  521         /* Determine NVRAM source. Must occur after the SPROM/OTP/flash
  522          * capability flags have been populated. */
  523         caps->nvram_src = chipc_find_nvram_src(sc, caps);
  524 
  525         /* Determine the SPROM offset within OTP (if any). SPROM-formatted
  526          * data is placed within the OTP general use region. */
  527         caps->sprom_offset = 0;
  528         if (caps->nvram_src == BHND_NVRAM_SRC_OTP) {
  529                 CHIPC_ASSERT_QUIRK(sc, OTP_IPX);
  530 
  531                 /* Bit offset to GUP HW subregion containing SPROM data */
  532                 regval = bhnd_bus_read_4(sc->core, CHIPC_OTPLAYOUT);
  533                 caps->sprom_offset = CHIPC_GET_BITS(regval, CHIPC_OTPL_GUP);
  534 
  535                 /* Convert to bytes */
  536                 caps->sprom_offset /= 8;
  537         }
  538 
  539         return (0);
  540 }
  541 
  542 static int
  543 chipc_suspend(device_t dev)
  544 {
  545         return (bus_generic_suspend(dev));
  546 }
  547 
  548 static int
  549 chipc_resume(device_t dev)
  550 {
  551         return (bus_generic_resume(dev));
  552 }
  553 
  554 static void
  555 chipc_probe_nomatch(device_t dev, device_t child)
  556 {
  557         struct resource_list    *rl;
  558         const char              *name;
  559 
  560         name = device_get_name(child);
  561         if (name == NULL)
  562                 name = "unknown device";
  563 
  564         device_printf(dev, "<%s> at", name);
  565 
  566         rl = BUS_GET_RESOURCE_LIST(dev, child);
  567         if (rl != NULL) {
  568                 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
  569                 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
  570         }
  571 
  572         printf(" (no driver attached)\n");
  573 }
  574 
  575 static int
  576 chipc_print_child(device_t dev, device_t child)
  577 {
  578         struct resource_list    *rl;
  579         int                      retval = 0;
  580 
  581         retval += bus_print_child_header(dev, child);
  582 
  583         rl = BUS_GET_RESOURCE_LIST(dev, child);
  584         if (rl != NULL) {
  585                 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
  586                     "%#jx");
  587                 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
  588                     "%jd");
  589         }
  590 
  591         retval += bus_print_child_domain(dev, child);
  592         retval += bus_print_child_footer(dev, child);
  593 
  594         return (retval);
  595 }
  596 
  597 static device_t
  598 chipc_add_child(device_t dev, u_int order, const char *name, int unit)
  599 {
  600         struct chipc_devinfo    *dinfo;
  601         device_t                 child;
  602 
  603         child = device_add_child_ordered(dev, order, name, unit);
  604         if (child == NULL)
  605                 return (NULL);
  606 
  607         dinfo = malloc(sizeof(struct chipc_devinfo), M_BHND, M_NOWAIT);
  608         if (dinfo == NULL) {
  609                 device_delete_child(dev, child);
  610                 return (NULL);
  611         }
  612 
  613         resource_list_init(&dinfo->resources);
  614         dinfo->irq_mapped = false;
  615         device_set_ivars(child, dinfo);
  616 
  617         return (child);
  618 }
  619 
  620 static void
  621 chipc_child_deleted(device_t dev, device_t child)
  622 {
  623         struct chipc_devinfo *dinfo = device_get_ivars(child);
  624 
  625         if (dinfo != NULL) {
  626                 /* Free the child's resource list */
  627                 resource_list_free(&dinfo->resources);
  628 
  629                 /* Unmap the child's IRQ */
  630                 if (dinfo->irq_mapped) {
  631                         bhnd_unmap_intr(dev, dinfo->irq);
  632                         dinfo->irq_mapped = false;
  633                 }
  634 
  635                 free(dinfo, M_BHND);
  636         }
  637 
  638         device_set_ivars(child, NULL);
  639 }
  640 
  641 static struct resource_list *
  642 chipc_get_resource_list(device_t dev, device_t child)
  643 {
  644         struct chipc_devinfo *dinfo = device_get_ivars(child);
  645         return (&dinfo->resources);
  646 }
  647 
  648 /* Allocate region records for the given port, and add the port's memory
  649  * range to the mem_rman */
  650 static int
  651 chipc_rman_init_regions (struct chipc_softc *sc, bhnd_port_type type,
  652     u_int port)
  653 {
  654         struct  chipc_region    *cr;
  655         rman_res_t               start, end;
  656         u_int                    num_regions;
  657         int                      error;
  658 
  659         num_regions = bhnd_get_region_count(sc->dev, type, port);
  660         for (u_int region = 0; region < num_regions; region++) {
  661                 /* Allocate new region record */
  662                 cr = chipc_alloc_region(sc, type, port, region);
  663                 if (cr == NULL)
  664                         return (ENODEV);
  665 
  666                 /* Can't manage regions that cannot be allocated */
  667                 if (cr->cr_rid < 0) {
  668                         BHND_DEBUG_DEV(sc->dev, "no rid for chipc region "
  669                             "%s%u.%u", bhnd_port_type_name(type), port, region);
  670                         chipc_free_region(sc, cr);
  671                         continue;
  672                 }
  673 
  674                 /* Add to rman's managed range */
  675                 start = cr->cr_addr;
  676                 end = cr->cr_end;
  677                 if ((error = rman_manage_region(&sc->mem_rman, start, end))) {
  678                         chipc_free_region(sc, cr);
  679                         return (error);
  680                 }
  681 
  682                 /* Add to region list */
  683                 STAILQ_INSERT_TAIL(&sc->mem_regions, cr, cr_link);
  684         }
  685 
  686         return (0);
  687 }
  688 
  689 /* Initialize memory state for all chipc port regions */
  690 static int
  691 chipc_init_rman(struct chipc_softc *sc)
  692 {
  693         u_int   num_ports;
  694         int     error;
  695 
  696         /* Port types for which we'll register chipc_region mappings */
  697         bhnd_port_type types[] = {
  698             BHND_PORT_DEVICE
  699         };
  700 
  701         /* Initialize resource manager */
  702         sc->mem_rman.rm_start = 0;
  703         sc->mem_rman.rm_end = BUS_SPACE_MAXADDR;
  704         sc->mem_rman.rm_type = RMAN_ARRAY;
  705         sc->mem_rman.rm_descr = "ChipCommon Device Memory";
  706         if ((error = rman_init(&sc->mem_rman))) {
  707                 device_printf(sc->dev, "could not initialize mem_rman: %d\n",
  708                     error);
  709                 return (error);
  710         }
  711 
  712         /* Populate per-port-region state */
  713         for (u_int i = 0; i < nitems(types); i++) {
  714                 num_ports = bhnd_get_port_count(sc->dev, types[i]);
  715                 for (u_int port = 0; port < num_ports; port++) {
  716                         error = chipc_rman_init_regions(sc, types[i], port);
  717                         if (error) {
  718                                 device_printf(sc->dev,
  719                                     "region init failed for %s%u: %d\n",
  720                                      bhnd_port_type_name(types[i]), port,
  721                                      error);
  722 
  723                                 goto failed;
  724                         }
  725                 }
  726         }
  727 
  728         return (0);
  729 
  730 failed:
  731         chipc_free_rman(sc);
  732         return (error);
  733 }
  734 
  735 /* Free memory management state */
  736 static void
  737 chipc_free_rman(struct chipc_softc *sc)
  738 {
  739         struct chipc_region *cr, *cr_next;
  740 
  741         STAILQ_FOREACH_SAFE(cr, &sc->mem_regions, cr_link, cr_next)
  742                 chipc_free_region(sc, cr);
  743 
  744         rman_fini(&sc->mem_rman);
  745 }
  746 
  747 /**
  748  * Return the rman instance for a given resource @p type, if any.
  749  * 
  750  * @param sc The chipc device state.
  751  * @param type The resource type (e.g. SYS_RES_MEMORY, SYS_RES_IRQ, ...)
  752  */
  753 static struct rman *
  754 chipc_get_rman(struct chipc_softc *sc, int type)
  755 {       
  756         switch (type) {
  757         case SYS_RES_MEMORY:
  758                 return (&sc->mem_rman);
  759 
  760         case SYS_RES_IRQ:
  761                 /* We delegate IRQ resource management to the parent bus */
  762                 return (NULL);
  763 
  764         default:
  765                 return (NULL);
  766         };
  767 }
  768 
  769 static struct resource *
  770 chipc_alloc_resource(device_t dev, device_t child, int type,
  771     int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
  772 {
  773         struct chipc_softc              *sc;
  774         struct chipc_region             *cr;
  775         struct resource_list_entry      *rle;
  776         struct resource                 *rv;
  777         struct rman                     *rm;
  778         int                              error;
  779         bool                             passthrough, isdefault;
  780 
  781         sc = device_get_softc(dev);
  782         passthrough = (device_get_parent(child) != dev);
  783         isdefault = RMAN_IS_DEFAULT_RANGE(start, end);
  784         rle = NULL;
  785 
  786         /* Fetch the resource manager, delegate request if necessary */
  787         rm = chipc_get_rman(sc, type);
  788         if (rm == NULL) {
  789                 /* Requested resource type is delegated to our parent */
  790                 rv = bus_generic_rl_alloc_resource(dev, child, type, rid,
  791                     start, end, count, flags);
  792                 return (rv);
  793         }
  794 
  795         /* Populate defaults */
  796         if (!passthrough && isdefault) {
  797                 /* Fetch the resource list entry. */
  798                 rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
  799                     type, *rid);
  800                 if (rle == NULL) {
  801                         device_printf(dev,
  802                             "default resource %#x type %d for child %s "
  803                             "not found\n", *rid, type,
  804                             device_get_nameunit(child));                        
  805                         return (NULL);
  806                 }
  807                 
  808                 if (rle->res != NULL) {
  809                         device_printf(dev,
  810                             "resource entry %#x type %d for child %s is busy "
  811                             "[%d]\n",
  812                             *rid, type, device_get_nameunit(child),
  813                             rman_get_flags(rle->res));
  814                         
  815                         return (NULL);
  816                 }
  817 
  818                 start = rle->start;
  819                 end = rle->end;
  820                 count = ulmax(count, rle->count);
  821         }
  822 
  823         /* Locate a mapping region */
  824         if ((cr = chipc_find_region(sc, start, end)) == NULL) {
  825                 /* Resource requests outside our shared port regions can be
  826                  * delegated to our parent. */
  827                 rv = bus_generic_rl_alloc_resource(dev, child, type, rid,
  828                     start, end, count, flags);
  829                 return (rv);
  830         }
  831 
  832         /*
  833          * As a special case, children that map the complete ChipCommon register
  834          * block are delegated to our parent.
  835          *
  836          * The rman API does not support sharing resources that are not
  837          * identical in size; since we allocate subregions to various children,
  838          * any children that need to map the entire register block (e.g. because
  839          * they require access to discontiguous register ranges) must make the
  840          * allocation through our parent, where we hold a compatible
  841          * RF_SHAREABLE allocation.
  842          */
  843         if (cr == sc->core_region && cr->cr_addr == start &&
  844             cr->cr_end == end && cr->cr_count == count)
  845         {
  846                 rv = bus_generic_rl_alloc_resource(dev, child, type, rid,
  847                     start, end, count, flags);
  848                 return (rv);
  849         }
  850 
  851         /* Try to retain a region reference */
  852         if ((error = chipc_retain_region(sc, cr, RF_ALLOCATED)))
  853                 return (NULL);
  854 
  855         /* Make our rman reservation */
  856         rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
  857             child);
  858         if (rv == NULL) {
  859                 chipc_release_region(sc, cr, RF_ALLOCATED);
  860                 return (NULL);
  861         }
  862 
  863         rman_set_rid(rv, *rid);
  864 
  865         /* Activate */
  866         if (flags & RF_ACTIVE) {
  867                 error = bus_activate_resource(child, type, *rid, rv);
  868                 if (error) {
  869                         device_printf(dev,
  870                             "failed to activate entry %#x type %d for "
  871                                 "child %s: %d\n",
  872                              *rid, type, device_get_nameunit(child), error);
  873 
  874                         chipc_release_region(sc, cr, RF_ALLOCATED);
  875                         rman_release_resource(rv);
  876 
  877                         return (NULL);
  878                 }
  879         }
  880 
  881         /* Update child's resource list entry */
  882         if (rle != NULL) {
  883                 rle->res = rv;
  884                 rle->start = rman_get_start(rv);
  885                 rle->end = rman_get_end(rv);
  886                 rle->count = rman_get_size(rv);
  887         }
  888 
  889         return (rv);
  890 }
  891 
  892 static int
  893 chipc_release_resource(device_t dev, device_t child, int type, int rid,
  894     struct resource *r)
  895 {
  896         struct chipc_softc              *sc;
  897         struct chipc_region             *cr;
  898         struct rman                     *rm;
  899         struct resource_list_entry      *rle;
  900         int                              error;
  901 
  902         sc = device_get_softc(dev);
  903 
  904         /* Handled by parent bus? */
  905         rm = chipc_get_rman(sc, type);
  906         if (rm == NULL || !rman_is_region_manager(r, rm)) {
  907                 return (bus_generic_rl_release_resource(dev, child, type, rid,
  908                     r));
  909         }
  910 
  911         /* Locate the mapping region */
  912         cr = chipc_find_region(sc, rman_get_start(r), rman_get_end(r));
  913         if (cr == NULL)
  914                 return (EINVAL);
  915 
  916         /* Deactivate resources */
  917         if (rman_get_flags(r) & RF_ACTIVE) {
  918                 error = BUS_DEACTIVATE_RESOURCE(dev, child, type, rid, r);
  919                 if (error)
  920                         return (error);
  921         }
  922 
  923         if ((error = rman_release_resource(r)))
  924                 return (error);
  925 
  926         /* Drop allocation reference */
  927         chipc_release_region(sc, cr, RF_ALLOCATED);
  928 
  929         /* Clear reference from the resource list entry if exists */
  930         rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child), type, rid);
  931         if (rle != NULL)
  932                 rle->res = NULL;
  933 
  934         return (0);
  935 }
  936 
  937 static int
  938 chipc_adjust_resource(device_t dev, device_t child, int type,
  939     struct resource *r, rman_res_t start, rman_res_t end)
  940 {
  941         struct chipc_softc              *sc;
  942         struct chipc_region             *cr;
  943         struct rman                     *rm;
  944 
  945         sc = device_get_softc(dev);
  946 
  947         /* Handled by parent bus? */
  948         rm = chipc_get_rman(sc, type);
  949         if (rm == NULL || !rman_is_region_manager(r, rm)) {
  950                 return (bus_generic_adjust_resource(dev, child, type, r, start,
  951                     end));
  952         }
  953 
  954         /* The range is limited to the existing region mapping */
  955         cr = chipc_find_region(sc, rman_get_start(r), rman_get_end(r));
  956         if (cr == NULL)
  957                 return (EINVAL);
  958 
  959         if (end <= start)
  960                 return (EINVAL);
  961 
  962         if (start < cr->cr_addr || end > cr->cr_end)
  963                 return (EINVAL);
  964 
  965         /* Range falls within the existing region */
  966         return (rman_adjust_resource(r, start, end));
  967 }
  968 
  969 /**
  970  * Retain an RF_ACTIVE reference to the region mapping @p r, and
  971  * configure @p r with its subregion values.
  972  *
  973  * @param sc Driver instance state.
  974  * @param child Requesting child device.
  975  * @param type resource type of @p r.
  976  * @param rid resource id of @p r
  977  * @param r resource to be activated.
  978  * @param req_direct If true, failure to allocate a direct bhnd resource
  979  * will be treated as an error. If false, the resource will not be marked
  980  * as RF_ACTIVE if bhnd direct resource allocation fails.
  981  */
  982 static int
  983 chipc_try_activate_resource(struct chipc_softc *sc, device_t child, int type,
  984     int rid, struct resource *r, bool req_direct)
  985 {
  986         struct rman             *rm;
  987         struct chipc_region     *cr;
  988         bhnd_size_t              cr_offset;
  989         rman_res_t               r_start, r_end, r_size;
  990         int                      error;
  991 
  992         rm = chipc_get_rman(sc, type);
  993         if (rm == NULL || !rman_is_region_manager(r, rm))
  994                 return (EINVAL);
  995 
  996         r_start = rman_get_start(r);
  997         r_end = rman_get_end(r);
  998         r_size = rman_get_size(r);
  999 
 1000         /* Find the corresponding chipc region */
 1001         cr = chipc_find_region(sc, r_start, r_end);
 1002         if (cr == NULL)
 1003                 return (EINVAL);
 1004 
 1005         /* Calculate subregion offset within the chipc region */
 1006         cr_offset = r_start - cr->cr_addr;
 1007 
 1008         /* Retain (and activate, if necessary) the chipc region */
 1009         if ((error = chipc_retain_region(sc, cr, RF_ACTIVE)))
 1010                 return (error);
 1011 
 1012         /* Configure child resource with its subregion values. */
 1013         if (cr->cr_res->direct) {
 1014                 error = chipc_init_child_resource(r, cr->cr_res->res,
 1015                     cr_offset, r_size);
 1016                 if (error)
 1017                         goto cleanup;
 1018 
 1019                 /* Mark active */
 1020                 if ((error = rman_activate_resource(r)))
 1021                         goto cleanup;
 1022         } else if (req_direct) {
 1023                 error = ENOMEM;
 1024                 goto cleanup;
 1025         }
 1026 
 1027         return (0);
 1028 
 1029 cleanup:
 1030         chipc_release_region(sc, cr, RF_ACTIVE);
 1031         return (error);
 1032 }
 1033 
 1034 static int
 1035 chipc_activate_bhnd_resource(device_t dev, device_t child, int type,
 1036     int rid, struct bhnd_resource *r)
 1037 {
 1038         struct chipc_softc      *sc;
 1039         struct rman             *rm;
 1040         int                      error;
 1041 
 1042         sc = device_get_softc(dev);
 1043 
 1044         /* Delegate non-locally managed resources to parent */
 1045         rm = chipc_get_rman(sc, type);
 1046         if (rm == NULL || !rman_is_region_manager(r->res, rm)) {
 1047                 return (bhnd_bus_generic_activate_resource(dev, child, type,
 1048                     rid, r));
 1049         }
 1050 
 1051         /* Try activating the chipc region resource */
 1052         error = chipc_try_activate_resource(sc, child, type, rid, r->res,
 1053             false);
 1054         if (error)
 1055                 return (error);
 1056 
 1057         /* Mark the child resource as direct according to the returned resource
 1058          * state */
 1059         if (rman_get_flags(r->res) & RF_ACTIVE)
 1060                 r->direct = true;
 1061 
 1062         return (0);
 1063 }
 1064 
 1065 static int
 1066 chipc_activate_resource(device_t dev, device_t child, int type, int rid,
 1067     struct resource *r)
 1068 {
 1069         struct chipc_softc      *sc;
 1070         struct rman             *rm;
 1071 
 1072         sc = device_get_softc(dev);
 1073 
 1074         /* Delegate non-locally managed resources to parent */
 1075         rm = chipc_get_rman(sc, type);
 1076         if (rm == NULL || !rman_is_region_manager(r, rm)) {
 1077                 return (bus_generic_activate_resource(dev, child, type, rid,
 1078                     r));
 1079         }
 1080 
 1081         /* Try activating the chipc region-based resource */
 1082         return (chipc_try_activate_resource(sc, child, type, rid, r, true));
 1083 }
 1084 
 1085 /**
 1086  * Default bhndb(4) implementation of BUS_DEACTIVATE_RESOURCE().
 1087  */
 1088 static int
 1089 chipc_deactivate_resource(device_t dev, device_t child, int type,
 1090     int rid, struct resource *r)
 1091 {
 1092         struct chipc_softc      *sc;
 1093         struct chipc_region     *cr;
 1094         struct rman             *rm;
 1095         int                      error;
 1096 
 1097         sc = device_get_softc(dev);
 1098 
 1099         /* Handled by parent bus? */
 1100         rm = chipc_get_rman(sc, type);
 1101         if (rm == NULL || !rman_is_region_manager(r, rm)) {
 1102                 return (bus_generic_deactivate_resource(dev, child, type, rid,
 1103                     r));
 1104         }
 1105 
 1106         /* Find the corresponding chipc region */
 1107         cr = chipc_find_region(sc, rman_get_start(r), rman_get_end(r));
 1108         if (cr == NULL)
 1109                 return (EINVAL);
 1110 
 1111         /* Mark inactive */
 1112         if ((error = rman_deactivate_resource(r)))
 1113                 return (error);
 1114 
 1115         /* Drop associated RF_ACTIVE reference */
 1116         chipc_release_region(sc, cr, RF_ACTIVE);
 1117 
 1118         return (0);
 1119 }
 1120 
 1121 /**
 1122  * Examine bus state and make a best effort determination of whether it's
 1123  * likely safe to enable the muxed SPROM pins.
 1124  * 
 1125  * On devices that do not use SPROM pin muxing, always returns true.
 1126  * 
 1127  * @param sc chipc driver state.
 1128  */
 1129 static bool
 1130 chipc_should_enable_muxed_sprom(struct chipc_softc *sc)
 1131 {
 1132         device_t        *devs;
 1133         device_t         hostb;
 1134         device_t         parent;
 1135         int              devcount;
 1136         int              error;
 1137         bool             result;
 1138 
 1139         /* Nothing to do? */
 1140         if (!CHIPC_QUIRK(sc, MUX_SPROM))
 1141                 return (true);
 1142 
 1143         bus_topo_lock();
 1144 
 1145         parent = device_get_parent(sc->dev);
 1146         hostb = bhnd_bus_find_hostb_device(parent);
 1147 
 1148         if ((error = device_get_children(parent, &devs, &devcount))) {
 1149                 bus_topo_unlock();
 1150                 return (false);
 1151         }
 1152 
 1153         /* Reject any active devices other than ChipCommon, or the
 1154          * host bridge (if any). */
 1155         result = true;
 1156         for (int i = 0; i < devcount; i++) {
 1157                 if (devs[i] == hostb || devs[i] == sc->dev)
 1158                         continue;
 1159 
 1160                 if (!device_is_attached(devs[i]))
 1161                         continue;
 1162 
 1163                 if (device_is_suspended(devs[i]))
 1164                         continue;
 1165 
 1166                 /* Active device; assume SPROM is busy */
 1167                 result = false;
 1168                 break;
 1169         }
 1170 
 1171         free(devs, M_TEMP);
 1172         bus_topo_unlock();
 1173         return (result);
 1174 }
 1175 
 1176 static int
 1177 chipc_enable_sprom(device_t dev)
 1178 {
 1179         struct chipc_softc      *sc;
 1180         int                      error;
 1181 
 1182         sc = device_get_softc(dev);
 1183         CHIPC_LOCK(sc);
 1184 
 1185         /* Already enabled? */
 1186         if (sc->sprom_refcnt >= 1) {
 1187                 sc->sprom_refcnt++;
 1188                 CHIPC_UNLOCK(sc);
 1189 
 1190                 return (0);
 1191         }
 1192 
 1193         switch (sc->caps.nvram_src) {
 1194         case BHND_NVRAM_SRC_SPROM:
 1195                 error = chipc_enable_sprom_pins(sc);
 1196                 break;
 1197         case BHND_NVRAM_SRC_OTP:
 1198                 error = chipc_enable_otp_power(sc);
 1199                 break;
 1200         default:
 1201                 error = 0;
 1202                 break;
 1203         }
 1204 
 1205         /* Bump the reference count */
 1206         if (error == 0)
 1207                 sc->sprom_refcnt++;
 1208 
 1209         CHIPC_UNLOCK(sc);
 1210         return (error);
 1211 }
 1212 
 1213 static void
 1214 chipc_disable_sprom(device_t dev)
 1215 {
 1216         struct chipc_softc      *sc;
 1217 
 1218         sc = device_get_softc(dev);
 1219         CHIPC_LOCK(sc);
 1220 
 1221         /* Check reference count, skip disable if in-use. */
 1222         KASSERT(sc->sprom_refcnt > 0, ("sprom refcnt overrelease"));
 1223         sc->sprom_refcnt--;
 1224         if (sc->sprom_refcnt > 0) {
 1225                 CHIPC_UNLOCK(sc);
 1226                 return;
 1227         }
 1228 
 1229         switch (sc->caps.nvram_src) {
 1230         case BHND_NVRAM_SRC_SPROM:
 1231                 chipc_disable_sprom_pins(sc);
 1232                 break;
 1233         case BHND_NVRAM_SRC_OTP:
 1234                 chipc_disable_otp_power(sc);
 1235                 break;
 1236         default:
 1237                 break;
 1238         }
 1239 
 1240         CHIPC_UNLOCK(sc);
 1241 }
 1242 
 1243 static int
 1244 chipc_enable_otp_power(struct chipc_softc *sc)
 1245 {
 1246         // TODO: Enable OTP resource via PMU, and wait up to 100 usec for
 1247         // OTPS_READY to be set in `optstatus`.
 1248         return (0);
 1249 }
 1250 
 1251 static void
 1252 chipc_disable_otp_power(struct chipc_softc *sc)
 1253 {
 1254         // TODO: Disable OTP resource via PMU
 1255 }
 1256 
 1257 /**
 1258  * If required by this device, enable access to the SPROM.
 1259  * 
 1260  * @param sc chipc driver state.
 1261  */
 1262 static int
 1263 chipc_enable_sprom_pins(struct chipc_softc *sc)
 1264 {
 1265         uint32_t                 cctrl;
 1266 
 1267         CHIPC_LOCK_ASSERT(sc, MA_OWNED);
 1268         KASSERT(sc->sprom_refcnt == 0, ("sprom pins already enabled"));
 1269 
 1270         /* Nothing to do? */
 1271         if (!CHIPC_QUIRK(sc, MUX_SPROM))
 1272                 return (0);
 1273 
 1274         /* Check whether bus is busy */
 1275         if (!chipc_should_enable_muxed_sprom(sc))
 1276                 return (EBUSY);
 1277 
 1278         cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
 1279 
 1280         /* 4331 devices */
 1281         if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
 1282                 cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN;
 1283 
 1284                 if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
 1285                         cctrl &= ~CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
 1286 
 1287                 if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
 1288                         cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN2;
 1289 
 1290                 bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
 1291                 return (0);
 1292         }
 1293 
 1294         /* 4360 devices */
 1295         if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
 1296                 /* Unimplemented */
 1297         }
 1298 
 1299         /* Refuse to proceed on unsupported devices with muxed SPROM pins */
 1300         device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
 1301         return (ENXIO);
 1302 }
 1303 
 1304 /**
 1305  * If required by this device, revert any GPIO/pin configuration applied
 1306  * to allow SPROM access.
 1307  * 
 1308  * @param sc chipc driver state.
 1309  */
 1310 static void
 1311 chipc_disable_sprom_pins(struct chipc_softc *sc)
 1312 {
 1313         uint32_t                 cctrl;
 1314 
 1315         /* Nothing to do? */
 1316         if (!CHIPC_QUIRK(sc, MUX_SPROM))
 1317                 return;
 1318 
 1319         CHIPC_LOCK_ASSERT(sc, MA_OWNED);
 1320         KASSERT(sc->sprom_refcnt == 0, ("sprom pins in use"));
 1321 
 1322         cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
 1323 
 1324         /* 4331 devices */
 1325         if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
 1326                 cctrl |= CHIPC_CCTRL4331_EXTPA_EN;
 1327 
 1328                 if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
 1329                         cctrl |= CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
 1330 
 1331                 if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
 1332                         cctrl |= CHIPC_CCTRL4331_EXTPA_EN2;
 1333 
 1334                 bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
 1335                 return;
 1336         }
 1337 
 1338         /* 4360 devices */
 1339         if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
 1340                 /* Unimplemented */
 1341         }
 1342 }
 1343 
 1344 static uint32_t
 1345 chipc_read_chipst(device_t dev)
 1346 {
 1347         struct chipc_softc *sc = device_get_softc(dev);
 1348         return (bhnd_bus_read_4(sc->core, CHIPC_CHIPST));
 1349 }
 1350 
 1351 static void
 1352 chipc_write_chipctrl(device_t dev, uint32_t value, uint32_t mask)
 1353 {
 1354         struct chipc_softc      *sc;
 1355         uint32_t                 cctrl;
 1356 
 1357         sc = device_get_softc(dev);
 1358 
 1359         CHIPC_LOCK(sc);
 1360 
 1361         cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
 1362         cctrl = (cctrl & ~mask) | (value | mask);
 1363         bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
 1364 
 1365         CHIPC_UNLOCK(sc);
 1366 }
 1367 
 1368 static struct chipc_caps *
 1369 chipc_get_caps(device_t dev)
 1370 {
 1371         struct chipc_softc      *sc;
 1372 
 1373         sc = device_get_softc(dev);
 1374         return (&sc->caps);
 1375 }
 1376 
 1377 static device_method_t chipc_methods[] = {
 1378         /* Device interface */
 1379         DEVMETHOD(device_probe,                 chipc_probe),
 1380         DEVMETHOD(device_attach,                chipc_attach),
 1381         DEVMETHOD(device_detach,                chipc_detach),
 1382         DEVMETHOD(device_suspend,               chipc_suspend),
 1383         DEVMETHOD(device_resume,                chipc_resume),
 1384 
 1385         /* Bus interface */
 1386         DEVMETHOD(bus_probe_nomatch,            chipc_probe_nomatch),
 1387         DEVMETHOD(bus_print_child,              chipc_print_child),
 1388 
 1389         DEVMETHOD(bus_add_child,                chipc_add_child),
 1390         DEVMETHOD(bus_child_deleted,            chipc_child_deleted),
 1391 
 1392         DEVMETHOD(bus_set_resource,             bus_generic_rl_set_resource),
 1393         DEVMETHOD(bus_get_resource,             bus_generic_rl_get_resource),
 1394         DEVMETHOD(bus_delete_resource,          bus_generic_rl_delete_resource),
 1395         DEVMETHOD(bus_alloc_resource,           chipc_alloc_resource),
 1396         DEVMETHOD(bus_release_resource,         chipc_release_resource),
 1397         DEVMETHOD(bus_adjust_resource,          chipc_adjust_resource),
 1398         DEVMETHOD(bus_activate_resource,        chipc_activate_resource),
 1399         DEVMETHOD(bus_deactivate_resource,      chipc_deactivate_resource),
 1400         DEVMETHOD(bus_get_resource_list,        chipc_get_resource_list),
 1401 
 1402         DEVMETHOD(bus_setup_intr,               bus_generic_setup_intr),
 1403         DEVMETHOD(bus_teardown_intr,            bus_generic_teardown_intr),
 1404         DEVMETHOD(bus_config_intr,              bus_generic_config_intr),
 1405         DEVMETHOD(bus_bind_intr,                bus_generic_bind_intr),
 1406         DEVMETHOD(bus_describe_intr,            bus_generic_describe_intr),
 1407 
 1408         /* BHND bus inteface */
 1409         DEVMETHOD(bhnd_bus_activate_resource,   chipc_activate_bhnd_resource),
 1410 
 1411         /* ChipCommon interface */
 1412         DEVMETHOD(bhnd_chipc_read_chipst,       chipc_read_chipst),
 1413         DEVMETHOD(bhnd_chipc_write_chipctrl,    chipc_write_chipctrl),
 1414         DEVMETHOD(bhnd_chipc_enable_sprom,      chipc_enable_sprom),
 1415         DEVMETHOD(bhnd_chipc_disable_sprom,     chipc_disable_sprom),
 1416         DEVMETHOD(bhnd_chipc_get_caps,          chipc_get_caps),
 1417 
 1418         DEVMETHOD_END
 1419 };
 1420 
 1421 DEFINE_CLASS_0(bhnd_chipc, bhnd_chipc_driver, chipc_methods, sizeof(struct chipc_softc));
 1422 EARLY_DRIVER_MODULE(bhnd_chipc, bhnd, bhnd_chipc_driver, 0, 0,
 1423     BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
 1424 MODULE_DEPEND(bhnd_chipc, bhnd, 1, 1, 1);
 1425 MODULE_VERSION(bhnd_chipc, 1);

Cache object: 7fb5c7dd21e394267f2219d8b3323a08


[ 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.