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/pcie2/bhnd_pcie2_hostb.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 Landon Fuller <landon@landonf.org>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer,
   12  *    without modification.
   13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   15  *    redistribution must be conditioned upon including a substantially
   16  *    similar Disclaimer requirement for further binary redistribution.
   17  *
   18  * NO WARRANTY
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   29  * THE POSSIBILITY OF SUCH DAMAGES.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 /*
   36  * Broadcom BHND PCIe-Gen2 PCI-Host Bridge.
   37  * 
   38  * This driver handles all interactions with PCIe-G2 bridge cores operating in
   39  * endpoint mode.
   40  * 
   41  * Host-level PCI operations are handled at the bhndb bridge level by the
   42  * bhndb_pci driver.
   43  */
   44 
   45 // TODO
   46 //
   47 // A full survey of known quirks/work-arounds has not been completed.
   48 //
   49 // Work-arounds for the following are not yet implemented:
   50 // - BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH
   51 //   4360 PCIe SerDes Tx amplitude/deemphasis (vendor Apple, boards
   52 //   BCM94360X51P2, BCM94360X51A)
   53 
   54 #include <sys/param.h>
   55 #include <sys/kernel.h>
   56 
   57 #include <sys/malloc.h>
   58 
   59 #include <sys/bus.h>
   60 #include <sys/module.h>
   61 
   62 #include <sys/systm.h>
   63 
   64 #include <machine/bus.h>
   65 #include <sys/rman.h>
   66 #include <machine/resource.h>
   67 
   68 #include <dev/bhnd/bhnd.h>
   69 
   70 #include <dev/pci/pcireg.h>
   71 #include <dev/pci/pcivar.h>
   72 
   73 #include "bhnd_pcie2_reg.h"
   74 #include "bhnd_pcie2_hostbvar.h"
   75 
   76 static const struct bhnd_device_quirk bhnd_pcie2_quirks[];
   77 
   78 static int      bhnd_pcie2_wars_early_once(struct bhnd_pcie2hb_softc *sc);
   79 static int      bhnd_pcie2_wars_hwup(struct bhnd_pcie2hb_softc *sc);
   80 static int      bhnd_pcie2_wars_hwdown(struct bhnd_pcie2hb_softc *sc);
   81 
   82 /*
   83  * device/quirk tables
   84  */
   85 
   86 #define BHND_PCI_DEV(_core, _quirks)            \
   87         BHND_DEVICE(BCM, _core, NULL, _quirks, BHND_DF_HOSTB)
   88 
   89 static const struct bhnd_device bhnd_pcie2_devs[] = {
   90         BHND_PCI_DEV(PCIE2,     bhnd_pcie2_quirks),
   91         BHND_DEVICE_END
   92 };
   93 
   94 static const struct bhnd_device_quirk bhnd_pcie2_quirks[] = {
   95         /* Apple BCM4360 boards that require adjusting TX amplitude and
   96          * differential output de-emphasis of the PCIe SerDes */
   97         {{ BHND_MATCH_BOARD(PCI_VENDOR_APPLE, BCM94360X51P2), },
   98                 BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH },
   99         {{ BHND_MATCH_BOARD(PCI_VENDOR_APPLE, BCM94360X51A), },
  100                 BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH },
  101 
  102         BHND_DEVICE_QUIRK_END
  103 };
  104 
  105 static int
  106 bhnd_pcie2_hostb_attach(device_t dev)
  107 {
  108         struct bhnd_pcie2hb_softc       *sc;
  109         int                              error;
  110 
  111         sc = device_get_softc(dev);
  112         sc->dev = dev;
  113         sc->quirks = bhnd_device_quirks(dev, bhnd_pcie2_devs,
  114             sizeof(bhnd_pcie2_devs[0]));
  115 
  116         /* Find the host PCI bridge device */
  117         sc->pci_dev = bhnd_find_bridge_root(dev, devclass_find("pci"));
  118         if (sc->pci_dev == NULL) {
  119                 device_printf(dev, "parent pci bridge device not found\n");
  120                 return (ENXIO);
  121         }
  122 
  123         /* Common setup */
  124         if ((error = bhnd_pcie2_generic_attach(dev)))
  125                 return (error);
  126 
  127         /* Apply early single-shot work-arounds */
  128         if ((error = bhnd_pcie2_wars_early_once(sc)))
  129                 goto failed;
  130 
  131         /* Apply attach/resume work-arounds */
  132         if ((error = bhnd_pcie2_wars_hwup(sc)))
  133                 goto failed;
  134 
  135         return (0);
  136 
  137 failed:
  138         bhnd_pcie2_generic_detach(dev);
  139         return (error);
  140 }
  141 
  142 static int
  143 bhnd_pcie2_hostb_detach(device_t dev)
  144 {
  145         struct bhnd_pcie2hb_softc       *sc;
  146         int                              error;
  147 
  148         sc = device_get_softc(dev);
  149 
  150         /* Apply suspend/detach work-arounds */
  151         if ((error = bhnd_pcie2_wars_hwdown(sc)))
  152                 return (error);
  153 
  154         return (bhnd_pcie2_generic_detach(dev));
  155 }
  156 
  157 static int
  158 bhnd_pcie2_hostb_suspend(device_t dev)
  159 {
  160         struct bhnd_pcie2hb_softc       *sc;
  161         int                              error;
  162 
  163         sc = device_get_softc(dev);
  164 
  165         /* Apply suspend/detach work-arounds */
  166         if ((error = bhnd_pcie2_wars_hwdown(sc)))
  167                 return (error);
  168 
  169         return (bhnd_pcie2_generic_suspend(dev));
  170 }
  171 
  172 static int
  173 bhnd_pcie2_hostb_resume(device_t dev)
  174 {
  175         struct bhnd_pcie2hb_softc       *sc;
  176         int                              error;
  177 
  178         sc = device_get_softc(dev);
  179 
  180         if ((error = bhnd_pcie2_generic_resume(dev)))
  181                 return (error);
  182 
  183         /* Apply attach/resume work-arounds */
  184         if ((error = bhnd_pcie2_wars_hwup(sc))) {
  185                 bhnd_pcie2_generic_detach(dev);
  186                 return (error);
  187         }
  188 
  189         return (0);
  190 }
  191 
  192 /**
  193  * Apply any hardware work-arounds that must be executed exactly once, early in
  194  * the attach process.
  195  * 
  196  * This must be called after core enumeration and discovery of all applicable
  197  * quirks, but prior to probe/attach of any cores, parsing of
  198  * SPROM, etc.
  199  */
  200 static int
  201 bhnd_pcie2_wars_early_once(struct bhnd_pcie2hb_softc *sc)
  202 {
  203         // TODO
  204         return (ENXIO);
  205 }
  206 
  207 /**
  208  * Apply any hardware workarounds that are required upon attach or resume
  209  * of the bridge device.
  210  */
  211 static int
  212 bhnd_pcie2_wars_hwup(struct bhnd_pcie2hb_softc *sc)
  213 {
  214         // TODO
  215         return (ENXIO);
  216 }
  217 
  218 /**
  219  * Apply any hardware workarounds that are required upon detach or suspend
  220  * of the bridge device.
  221  */
  222 static int
  223 bhnd_pcie2_wars_hwdown(struct bhnd_pcie2hb_softc *sc)
  224 {
  225         // TODO
  226         return (ENXIO);
  227 }
  228 
  229 static device_method_t bhnd_pcie2_hostb_methods[] = {
  230         /* Device interface */
  231         DEVMETHOD(device_attach,                bhnd_pcie2_hostb_attach),
  232         DEVMETHOD(device_detach,                bhnd_pcie2_hostb_detach),
  233         DEVMETHOD(device_suspend,               bhnd_pcie2_hostb_suspend),
  234         DEVMETHOD(device_resume,                bhnd_pcie2_hostb_resume),       
  235 
  236         DEVMETHOD_END
  237 };
  238 
  239 DEFINE_CLASS_1(bhnd_hostb, bhnd_pcie2_hostb_driver,
  240     bhnd_pcie2_hostb_methods, sizeof(struct bhnd_pcie2hb_softc),
  241     bhnd_pcie2_driver);
  242 
  243 DRIVER_MODULE(bhnd_pcie2_hostb, bhnd, bhnd_pcie2_hostb_driver, 0, 0);
  244 
  245 MODULE_VERSION(bhnd_pcie2_hostb, 1);
  246 MODULE_DEPEND(bhnd_pcie2_hostb, bhnd, 1, 1, 1);
  247 MODULE_DEPEND(bhnd_pcie2_hostb, bhnd_pcie2, 1, 1, 1);

Cache object: 4f1bef1b3d5b0c9e600b51072394a8aa


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