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/mips/broadcom/bhnd_nexus.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  * Copyright (c) 2015-2016 Landon Fuller <landon@freebsd.org>
    3  * Copyright (c) 2017 The FreeBSD Foundation
    4  * All rights reserved.
    5  *
    6  * Portions of this software were developed by Landon Fuller
    7  * under sponsorship from the FreeBSD Foundation.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer,
   14  *    without modification.
   15  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   16  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   17  *    redistribution must be conditioned upon including a substantially
   18  *    similar Disclaimer requirement for further binary redistribution.
   19  *
   20  * NO WARRANTY
   21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   24  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   25  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   26  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   31  * THE POSSIBILITY OF SUCH DAMAGES.
   32  * 
   33  * $FreeBSD$
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 /*
   40  * bhnd(4) driver mix-in providing shared common methods for
   41  * bhnd bus devices attached via a MIPS root nexus.
   42  */
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/bus.h>
   47 #include <sys/intr.h>
   48 #include <sys/limits.h>
   49 #include <sys/kernel.h>
   50 #include <sys/module.h>
   51 #include <sys/rman.h>
   52 #include <sys/malloc.h>
   53 
   54 #include <machine/bus.h>
   55 
   56 #include <dev/bhnd/bhndvar.h>
   57 #include <dev/bhnd/bhnd_ids.h>
   58 
   59 #include <dev/bhnd/cores/chipc/chipcreg.h>
   60 
   61 #include "bcm_machdep.h"
   62 #include "bcm_mipsvar.h"
   63 
   64 #include "bhnd_nexusvar.h"
   65 
   66 
   67 /**
   68  * Default bhnd_nexus implementation of BHND_BUS_GET_SERVICE_REGISTRY().
   69  */
   70 static struct bhnd_service_registry *
   71 bhnd_nexus_get_service_registry(device_t dev, device_t child)
   72 {
   73         struct bcm_platform *bp = bcm_get_platform();
   74         return (&bp->services);
   75 }
   76 
   77 /**
   78  * Default bhnd_nexus implementation of BHND_BUS_ACTIVATE_RESOURCE().
   79  */
   80 static int
   81 bhnd_nexus_activate_resource(device_t dev, device_t child, int type, int rid,
   82     struct bhnd_resource *r)
   83 {
   84         int error;
   85 
   86         /* Always direct */
   87         if ((error = bus_activate_resource(child, type, rid, r->res)))
   88                 return (error);
   89 
   90         r->direct = true;
   91         return (0);
   92 }
   93 
   94 /**
   95  * Default bhnd_nexus implementation of BHND_BUS_DEACTIVATE_RESOURCE().
   96  */
   97 static int
   98 bhnd_nexus_deactivate_resource(device_t dev, device_t child,
   99     int type, int rid, struct bhnd_resource *r)
  100 {
  101         int error;
  102 
  103         /* Always direct */
  104         KASSERT(r->direct, ("indirect resource delegated to bhnd_nexus\n"));
  105 
  106         if ((error = bus_deactivate_resource(child, type, rid, r->res)))
  107                 return (error);
  108 
  109         r->direct = false;
  110         return (0);
  111 }
  112 
  113 /**
  114  * Default bhnd_nexus implementation of BHND_BUS_IS_HW_DISABLED().
  115  */
  116 static bool
  117 bhnd_nexus_is_hw_disabled(device_t dev, device_t child)
  118 {
  119         struct bcm_platform     *bp;
  120         struct bhnd_chipid      *cid;
  121 
  122         bp = bcm_get_platform();
  123         cid = &bp->cid;
  124 
  125         /* The BCM4706 low-cost package leaves secondary GMAC cores
  126          * floating */
  127         if (cid->chip_id == BHND_CHIPID_BCM4706 &&
  128             cid->chip_pkg == BHND_PKGID_BCM4706L &&
  129             bhnd_get_device(child) == BHND_COREID_4706_GMAC &&
  130             bhnd_get_core_unit(child) != 0)
  131         {
  132                 return (true);
  133         }
  134 
  135         return (false);
  136 }
  137 
  138 /**
  139  * Default bhnd_nexus implementation of BHND_BUS_AGET_ATTACH_TYPE().
  140  */
  141 static bhnd_attach_type
  142 bhnd_nexus_get_attach_type(device_t dev, device_t child)
  143 {
  144         return (BHND_ATTACH_NATIVE);
  145 }
  146 
  147 /**
  148  * Default bhnd_nexus implementation of BHND_BUS_GET_CHIPID().
  149  */
  150 static const struct bhnd_chipid *
  151 bhnd_nexus_get_chipid(device_t dev, device_t child)
  152 {
  153         return (&bcm_get_platform()->cid);
  154 }
  155 
  156 /**
  157  * Default bhnd_nexus implementation of BHND_BUS_READ_BOARD_INFO().
  158  */
  159 static int
  160 bhnd_nexus_read_board_info(device_t dev, device_t child,
  161     struct bhnd_board_info *info)
  162 {
  163         int error;
  164 
  165         /* Initialize with NVRAM-derived values */
  166         if ((error = bhnd_bus_generic_read_board_info(dev, child, info)))
  167                 return (error);
  168 
  169         /* The board vendor should default to PCI_VENDOR_BROADCOM if not
  170          * otherwise specified */
  171         if (info->board_vendor == 0)
  172                 info->board_vendor = PCI_VENDOR_BROADCOM;
  173 
  174         return (0);
  175 }
  176 
  177 /**
  178  * Default bhnd_nexus implementation of BHND_BUS_MAP_INTR().
  179  */
  180 static int
  181 bhnd_nexus_map_intr(device_t dev, device_t child, u_int intr, rman_res_t *irq)
  182 {
  183         struct bcm_mips_intr_map_data   *imd;
  184         u_int                            ivec;
  185         uintptr_t                        xref;
  186         int                              error;
  187 
  188         /* Fetch the backplane interrupt vector */
  189         if ((error = bhnd_get_intr_ivec(child, intr, &ivec))) {
  190                 device_printf(dev, "error fetching ivec for intr %u: %d\n",
  191                     intr, error);
  192                 return (error);
  193         }
  194 
  195         /* Determine our interrupt domain */
  196         xref = BHND_BUS_GET_INTR_DOMAIN(dev, child, false);
  197         KASSERT(xref != 0, ("missing interrupt domain"));
  198 
  199         /* Allocate our map data */
  200         imd = (struct bcm_mips_intr_map_data *)intr_alloc_map_data(
  201             INTR_MAP_DATA_BCM_MIPS, sizeof(*imd), M_WAITOK | M_ZERO);
  202         imd->ivec = ivec;
  203 
  204         /* Map the IRQ */
  205         *irq = intr_map_irq(NULL, xref, &imd->mdata);
  206         return (0);
  207 }
  208 
  209 /**
  210  * Default bhnd_nexus implementation of BHND_BUS_UNMAP_INTR().
  211  */
  212 static void
  213 bhnd_nexus_unmap_intr(device_t dev, device_t child, rman_res_t irq)
  214 {
  215         if (irq > UINT_MAX)
  216                 panic("invalid irq: %ju", (uintmax_t)irq);
  217 
  218         intr_unmap_irq(irq);
  219 }
  220 
  221 /**
  222  * Default bhnd_nexus implementation of BHND_BUS_GET_DMA_TRANSLATION().
  223  */
  224 static int
  225 bhnd_nexus_get_dma_translation(device_t dev, device_t child,
  226     u_int width, uint32_t flags, bus_dma_tag_t *dmat,
  227     struct bhnd_dma_translation *translation)
  228 {
  229         struct bcm_platform *bp = bcm_get_platform();
  230 
  231         /* We don't (currently) support any flags */
  232         if (flags != 0x0)
  233                 return (ENOENT);
  234 
  235         KASSERT(width > 0 && width <= BHND_DMA_ADDR_64BIT,
  236             ("invalid width %u", width));
  237 
  238         /* Is the requested width supported? */
  239         if (width > BHND_DMA_ADDR_32BIT) {
  240                 /* Backplane must support 64-bit addressing */
  241                 if (!(bp->cid.chip_caps & BHND_CAP_BP64))
  242                         width = BHND_DMA_ADDR_32BIT;
  243         }
  244 
  245         /* No DMA address translation required */
  246         if (dmat != NULL)
  247                 *dmat = bus_get_dma_tag(dev);
  248 
  249         if (translation != NULL) {
  250                 *translation = (struct bhnd_dma_translation) {
  251                         .base_addr      = 0x0,
  252                         .addr_mask      = BHND_DMA_ADDR_BITMASK(width),
  253                         .addrext_mask   = 0
  254                 };
  255         }
  256 
  257         return (0);
  258 }
  259 
  260 static device_method_t bhnd_nexus_methods[] = {
  261         /* bhnd interface */
  262         DEVMETHOD(bhnd_bus_get_service_registry,bhnd_nexus_get_service_registry),
  263         DEVMETHOD(bhnd_bus_register_provider,   bhnd_bus_generic_sr_register_provider),
  264         DEVMETHOD(bhnd_bus_deregister_provider, bhnd_bus_generic_sr_deregister_provider),
  265         DEVMETHOD(bhnd_bus_retain_provider,     bhnd_bus_generic_sr_retain_provider),
  266         DEVMETHOD(bhnd_bus_release_provider,    bhnd_bus_generic_sr_release_provider),
  267         DEVMETHOD(bhnd_bus_activate_resource,   bhnd_nexus_activate_resource),
  268         DEVMETHOD(bhnd_bus_deactivate_resource, bhnd_nexus_deactivate_resource),
  269         DEVMETHOD(bhnd_bus_is_hw_disabled,      bhnd_nexus_is_hw_disabled),
  270         DEVMETHOD(bhnd_bus_get_attach_type,     bhnd_nexus_get_attach_type),
  271         DEVMETHOD(bhnd_bus_get_chipid,          bhnd_nexus_get_chipid),
  272         DEVMETHOD(bhnd_bus_get_dma_translation, bhnd_nexus_get_dma_translation),
  273         DEVMETHOD(bhnd_bus_get_intr_domain,     bhnd_bus_generic_get_intr_domain),
  274         DEVMETHOD(bhnd_bus_map_intr,            bhnd_nexus_map_intr),
  275         DEVMETHOD(bhnd_bus_read_board_info,     bhnd_nexus_read_board_info),
  276         DEVMETHOD(bhnd_bus_unmap_intr,          bhnd_nexus_unmap_intr),
  277 
  278         DEVMETHOD_END
  279 };
  280 
  281 DEFINE_CLASS_0(bhnd, bhnd_nexus_driver, bhnd_nexus_methods,
  282     sizeof(struct bhnd_softc));

Cache object: 563695433f6e8550d8a687020b354739


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