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/arm/broadcom/bcm2835/bcm2838_pci.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) 2020 Dr Robert Harvey Crowston <crowston@protonmail.com>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  *
   18  *
   19  * $FreeBSD$
   20  *
   21  */
   22 
   23 /*
   24  * BCM2838-compatible PCI-express controller.
   25  *
   26  * Broadcom likes to give the same chip lots of different names. The name of
   27  * this driver is taken from the Raspberry Pi 4 Broadcom 2838 chip.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/endian.h>
   36 #include <sys/kernel.h>
   37 #include <sys/module.h>
   38 #include <sys/bus.h>
   39 #include <sys/proc.h>
   40 #include <sys/rman.h>
   41 #include <sys/intr.h>
   42 #include <sys/mutex.h>
   43 
   44 #include <dev/ofw/openfirm.h>
   45 #include <dev/ofw/ofw_bus.h>
   46 #include <dev/ofw/ofw_bus_subr.h>
   47 
   48 #include <dev/pci/pci_host_generic.h>
   49 #include <dev/pci/pci_host_generic_fdt.h>
   50 #include <dev/pci/pcivar.h>
   51 #include <dev/pci/pcireg.h>
   52 #include <dev/pci/pcib_private.h>
   53 
   54 #include <machine/bus.h>
   55 #include <machine/intr.h>
   56 
   57 #include "pcib_if.h"
   58 #include "msi_if.h"
   59 
   60 #define PCI_ID_VAL3             0x43c
   61 #define CLASS_SHIFT             0x10
   62 #define SUBCLASS_SHIFT          0x8
   63 
   64 #define REG_CONTROLLER_HW_REV                   0x406c
   65 #define REG_BRIDGE_CTRL                         0x9210
   66 #define BRIDGE_DISABLE_FLAG     0x1
   67 #define BRIDGE_RESET_FLAG       0x2
   68 #define REG_BRIDGE_SERDES_MODE                  0x4204
   69 #define REG_DMA_CONFIG                          0x4008
   70 #define REG_DMA_WINDOW_LOW                      0x4034
   71 #define REG_DMA_WINDOW_HIGH                     0x4038
   72 #define REG_DMA_WINDOW_1                        0x403c
   73 #define REG_BRIDGE_GISB_WINDOW                  0x402c
   74 #define REG_BRIDGE_STATE                        0x4068
   75 #define REG_BRIDGE_LINK_STATE                   0x00bc
   76 #define REG_BUS_WINDOW_LOW                      0x400c
   77 #define REG_BUS_WINDOW_HIGH                     0x4010
   78 #define REG_CPU_WINDOW_LOW                      0x4070
   79 #define REG_CPU_WINDOW_START_HIGH               0x4080
   80 #define REG_CPU_WINDOW_END_HIGH                 0x4084
   81 
   82 #define REG_MSI_ADDR_LOW                        0x4044
   83 #define REG_MSI_ADDR_HIGH                       0x4048
   84 #define REG_MSI_CONFIG                          0x404c
   85 #define REG_MSI_CLR                             0x4508
   86 #define REG_MSI_MASK_CLR                        0x4514
   87 #define REG_MSI_RAISED                          0x4500
   88 #define REG_MSI_EOI                             0x4060
   89 #define NUM_MSI                 32
   90 
   91 #define REG_EP_CONFIG_CHOICE                    0x9000
   92 #define REG_EP_CONFIG_DATA                      0x8000
   93 
   94 /*
   95  * The system memory controller can address up to 16 GiB of physical memory
   96  * (although at time of writing the largest memory size available for purchase
   97  * is 8 GiB). However, the system DMA controller is capable of accessing only a
   98  * limited portion of the address space. Worse, the PCI-e controller has further
   99  * constraints for DMA, and those limitations are not wholly clear to the
  100  * author. NetBSD and Linux allow DMA on the lower 3 GiB of the physical memory,
  101  * but experimentation shows DMA performed above 960 MiB results in data
  102  * corruption with this driver. The limit of 960 MiB is taken from OpenBSD, but
  103  * apparently that value was chosen for satisfying a constraint of an unrelated
  104  * peripheral.
  105  *
  106  * Whatever the true maximum address, 960 MiB works.
  107  */
  108 #define DMA_HIGH_LIMIT                  0x3c000000
  109 #define MAX_MEMORY_LOG2                 0x21
  110 #define REG_VALUE_DMA_WINDOW_LOW        (MAX_MEMORY_LOG2 - 0xf)
  111 #define REG_VALUE_DMA_WINDOW_HIGH       0x0
  112 #define DMA_WINDOW_ENABLE               0x3000
  113 #define REG_VALUE_DMA_WINDOW_CONFIG     \
  114     (((MAX_MEMORY_LOG2 - 0xf) << 0x1b) | DMA_WINDOW_ENABLE)
  115 
  116 #define REG_VALUE_MSI_CONFIG    0xffe06540
  117 
  118 struct bcm_pcib_irqsrc {
  119         struct intr_irqsrc      isrc;
  120         u_int                   irq;
  121         bool                    allocated;
  122 };
  123 
  124 struct bcm_pcib_softc {
  125         struct generic_pcie_fdt_softc   base;
  126         device_t                        dev;
  127         bus_dma_tag_t                   dmat;
  128         struct mtx                      config_mtx;
  129         struct mtx                      msi_mtx;
  130         struct resource                 *msi_irq_res;
  131         void                            *msi_intr_cookie;
  132         struct bcm_pcib_irqsrc          *msi_isrcs;
  133         pci_addr_t                      msi_addr;
  134 };
  135 
  136 static struct ofw_compat_data compat_data[] = {
  137         {"brcm,bcm2711-pcie",                   1},
  138         {"brcm,bcm7211-pcie",                   1},
  139         {"brcm,bcm7445-pcie",                   1},
  140         {NULL,                                  0}
  141 };
  142 
  143 static int
  144 bcm_pcib_probe(device_t dev)
  145 {
  146 
  147         if (!ofw_bus_status_okay(dev))
  148                 return (ENXIO);
  149 
  150         if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
  151                 return (ENXIO);
  152 
  153         device_set_desc(dev,
  154             "BCM2838-compatible PCI-express controller");
  155         return (BUS_PROBE_DEFAULT);
  156 }
  157 
  158 static bus_dma_tag_t
  159 bcm_pcib_get_dma_tag(device_t dev, device_t child)
  160 {
  161         struct bcm_pcib_softc *sc;
  162 
  163         sc = device_get_softc(dev);
  164         return (sc->dmat);
  165 }
  166 
  167 static void
  168 bcm_pcib_set_reg(struct bcm_pcib_softc *sc, uint32_t reg, uint32_t val)
  169 {
  170 
  171         bus_space_write_4(sc->base.base.bst, sc->base.base.bsh, reg,
  172             htole32(val));
  173 }
  174 
  175 static uint32_t
  176 bcm_pcib_read_reg(struct bcm_pcib_softc *sc, uint32_t reg)
  177 {
  178 
  179         return (le32toh(bus_space_read_4(sc->base.base.bst, sc->base.base.bsh,
  180             reg)));
  181 }
  182 
  183 static void
  184 bcm_pcib_reset_controller(struct bcm_pcib_softc *sc)
  185 {
  186         uint32_t val;
  187 
  188         val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
  189         val = val | BRIDGE_RESET_FLAG | BRIDGE_DISABLE_FLAG;
  190         bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
  191 
  192         DELAY(100);
  193 
  194         val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
  195         val = val & ~BRIDGE_RESET_FLAG;
  196         bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
  197 
  198         DELAY(100);
  199 
  200         bcm_pcib_set_reg(sc, REG_BRIDGE_SERDES_MODE, 0);
  201 
  202         DELAY(100);
  203 }
  204 
  205 static void
  206 bcm_pcib_enable_controller(struct bcm_pcib_softc *sc)
  207 {
  208         uint32_t val;
  209 
  210         val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
  211         val = val & ~BRIDGE_DISABLE_FLAG;
  212         bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
  213 
  214         DELAY(100);
  215 }
  216 
  217 static int
  218 bcm_pcib_check_ranges(device_t dev)
  219 {
  220         struct bcm_pcib_softc *sc;
  221         struct pcie_range *ranges;
  222         int error = 0, i;
  223 
  224         sc = device_get_softc(dev);
  225         ranges = &sc->base.base.ranges[0];
  226 
  227         /* The first range needs to be non-zero. */
  228         if (ranges[0].size == 0) {
  229                 device_printf(dev, "error: first outbound memory range "
  230                     "(pci addr: 0x%jx, cpu addr: 0x%jx) has zero size.\n",
  231                     ranges[0].pci_base, ranges[0].phys_base);
  232                 error = ENXIO;
  233         }
  234 
  235         /*
  236          * The controller can actually handle three distinct ranges, but we
  237          * only implement support for one.
  238          */
  239         for (i = 1; (bootverbose || error) && i < MAX_RANGES_TUPLES; ++i) {
  240                 if (ranges[i].size > 0)
  241                         device_printf(dev,
  242                             "note: outbound memory range %d (pci addr: 0x%jx, "
  243                             "cpu addr: 0x%jx, size: 0x%jx) will be ignored.\n",
  244                             i, ranges[i].pci_base, ranges[i].phys_base,
  245                             ranges[i].size);
  246         }
  247 
  248         return (error);
  249 }
  250 
  251 static const char *
  252 bcm_pcib_link_state_string(uint32_t mode)
  253 {
  254 
  255         switch(mode & PCIEM_LINK_STA_SPEED) {
  256         case 0:
  257                 return ("not up");
  258         case 1:
  259                 return ("2.5 GT/s");
  260         case 2:
  261                 return ("5.0 GT/s");
  262         case 4:
  263                 return ("8.0 GT/s");
  264         default:
  265                 return ("unknown");
  266         }
  267 }
  268 
  269 static bus_addr_t
  270 bcm_get_offset_and_prepare_config(struct bcm_pcib_softc *sc, u_int bus,
  271     u_int slot, u_int func, u_int reg)
  272 {
  273         /*
  274          * Config for an end point is only available through a narrow window for
  275          * one end point at a time. We first tell the controller which end point
  276          * we want, then access it through the window.
  277          */
  278         uint32_t func_index;
  279 
  280         if (bus == 0 && slot == 0 && func == 0)
  281                 /*
  282                  * Special case for root device; its config is always available
  283                  * through the zero-offset.
  284                  */
  285                 return (reg);
  286 
  287         /* Tell the controller to show us the config in question. */
  288         func_index = PCIE_ADDR_OFFSET(bus, slot, func, 0);
  289         bcm_pcib_set_reg(sc, REG_EP_CONFIG_CHOICE, func_index);
  290 
  291         return (REG_EP_CONFIG_DATA + reg);
  292 }
  293 
  294 static bool
  295 bcm_pcib_is_valid_quad(struct bcm_pcib_softc *sc, u_int bus, u_int slot,
  296     u_int func, u_int reg)
  297 {
  298 
  299         if ((bus < sc->base.base.bus_start) || (bus > sc->base.base.bus_end))
  300                 return (false);
  301         if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
  302                 return (false);
  303 
  304         if (bus == 0 && slot == 0 && func == 0)
  305                 return (true);
  306         if (bus == 0)
  307                 /*
  308                  * Probing other slots and funcs on bus 0 will lock up the
  309                  * memory controller.
  310                  */
  311                 return (false);
  312 
  313         return (true);
  314 }
  315 
  316 static uint32_t
  317 bcm_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
  318     int bytes)
  319 {
  320         struct bcm_pcib_softc *sc;
  321         bus_space_handle_t h;
  322         bus_space_tag_t t;
  323         bus_addr_t offset;
  324         uint32_t data;
  325 
  326         sc = device_get_softc(dev);
  327         if (!bcm_pcib_is_valid_quad(sc, bus, slot, func, reg))
  328                 return (~0U);
  329 
  330         mtx_lock(&sc->config_mtx);
  331         offset = bcm_get_offset_and_prepare_config(sc, bus, slot, func, reg);
  332 
  333         t = sc->base.base.bst;
  334         h = sc->base.base.bsh;
  335 
  336         switch (bytes) {
  337         case 1:
  338                 data = bus_space_read_1(t, h, offset);
  339                 break;
  340         case 2:
  341                 data = le16toh(bus_space_read_2(t, h, offset));
  342                 break;
  343         case 4:
  344                 data = le32toh(bus_space_read_4(t, h, offset));
  345                 break;
  346         default:
  347                 data = ~0U;
  348                 break;
  349         }
  350 
  351         mtx_unlock(&sc->config_mtx);
  352         return (data);
  353 }
  354 
  355 static void
  356 bcm_pcib_write_config(device_t dev, u_int bus, u_int slot,
  357     u_int func, u_int reg, uint32_t val, int bytes)
  358 {
  359         struct bcm_pcib_softc *sc;
  360         bus_space_handle_t h;
  361         bus_space_tag_t t;
  362         uint32_t offset;
  363 
  364         sc = device_get_softc(dev);
  365         if (!bcm_pcib_is_valid_quad(sc, bus, slot, func, reg))
  366                 return;
  367 
  368         mtx_lock(&sc->config_mtx);
  369         offset = bcm_get_offset_and_prepare_config(sc, bus, slot, func, reg);
  370 
  371         t = sc->base.base.bst;
  372         h = sc->base.base.bsh;
  373 
  374         switch (bytes) {
  375         case 1:
  376                 bus_space_write_1(t, h, offset, val);
  377                 break;
  378         case 2:
  379                 bus_space_write_2(t, h, offset, htole16(val));
  380                 break;
  381         case 4:
  382                 bus_space_write_4(t, h, offset, htole32(val));
  383                 break;
  384         default:
  385                 break;
  386         }
  387 
  388         mtx_unlock(&sc->config_mtx);
  389 }
  390 
  391 static void
  392 bcm_pcib_msi_intr_process(struct bcm_pcib_softc *sc, uint32_t interrupt_bitmap,
  393     struct trapframe *tf)
  394 {
  395         struct bcm_pcib_irqsrc *irqsrc;
  396         uint32_t bit, irq;
  397 
  398         while ((bit = ffs(interrupt_bitmap))) {
  399                 irq = bit - 1;
  400 
  401                 /* Acknowledge interrupt. */
  402                 bcm_pcib_set_reg(sc, REG_MSI_CLR, 1 << irq);
  403 
  404                 /* Send EOI. */
  405                 bcm_pcib_set_reg(sc, REG_MSI_EOI, 1);
  406 
  407                 /* Despatch to handler. */
  408                 irqsrc = &sc->msi_isrcs[irq];
  409                 if (intr_isrc_dispatch(&irqsrc->isrc, tf))
  410                         device_printf(sc->dev,
  411                             "note: unexpected interrupt (%d) triggered.\n",
  412                             irq);
  413 
  414                 /* Done with this interrupt. */
  415                 interrupt_bitmap = interrupt_bitmap & ~(1 << irq);
  416         }
  417 }
  418 
  419 static int
  420 bcm_pcib_msi_intr(void *arg)
  421 {
  422         struct bcm_pcib_softc *sc;
  423         struct trapframe *tf;
  424         uint32_t interrupt_bitmap;
  425 
  426         sc = (struct bcm_pcib_softc *) arg;
  427         tf = curthread->td_intr_frame;
  428 
  429         while ((interrupt_bitmap = bcm_pcib_read_reg(sc, REG_MSI_RAISED)))
  430                 bcm_pcib_msi_intr_process(sc, interrupt_bitmap, tf);
  431 
  432         return (FILTER_HANDLED);
  433 }
  434 
  435 static int
  436 bcm_pcib_alloc_msi(device_t dev, device_t child, int count, int maxcount,
  437     device_t *pic, struct intr_irqsrc **srcs)
  438 {
  439         struct bcm_pcib_softc *sc;
  440         int first_int, i;
  441 
  442         sc = device_get_softc(dev);
  443         mtx_lock(&sc->msi_mtx);
  444 
  445         /* Find a continguous region of free message-signalled interrupts. */
  446         for (first_int = 0; first_int + count < NUM_MSI; ) {
  447                 for (i = first_int; i < first_int + count; ++i) {
  448                         if (sc->msi_isrcs[i].allocated)
  449                                 goto next;
  450                 }
  451                 goto found;
  452 next:
  453                 first_int = i + 1;
  454         }
  455 
  456         /* No appropriate region available. */
  457         mtx_unlock(&sc->msi_mtx);
  458         device_printf(dev, "warning: failed to allocate %d MSI messages.\n",
  459             count);
  460         return (ENXIO);
  461 
  462 found:
  463         /* Mark the messages as in use. */
  464         for (i = 0; i < count; ++i) {
  465                 sc->msi_isrcs[i + first_int].allocated = true;
  466                 srcs[i] = &(sc->msi_isrcs[i + first_int].isrc);
  467         }
  468 
  469         mtx_unlock(&sc->msi_mtx);
  470         *pic = device_get_parent(dev);
  471 
  472         return (0);
  473 }
  474 
  475 static int
  476 bcm_pcib_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc,
  477     uint64_t *addr, uint32_t *data)
  478 {
  479         struct bcm_pcib_softc *sc;
  480         struct bcm_pcib_irqsrc *msi_msg;
  481 
  482         sc = device_get_softc(dev);
  483         msi_msg = (struct bcm_pcib_irqsrc *) isrc;
  484 
  485         *addr = sc->msi_addr;
  486         *data = (REG_VALUE_MSI_CONFIG & 0xffff) | msi_msg->irq;
  487         return (0);
  488 }
  489 
  490 static int
  491 bcm_pcib_release_msi(device_t dev, device_t child, int count,
  492     struct intr_irqsrc **isrc)
  493 {
  494         struct bcm_pcib_softc *sc;
  495         struct bcm_pcib_irqsrc *msi_isrc;
  496         int i;
  497 
  498         sc = device_get_softc(dev);
  499         mtx_lock(&sc->msi_mtx);
  500 
  501         for (i = 0; i < count; i++) {
  502                 msi_isrc = (struct bcm_pcib_irqsrc *) isrc[i];
  503                 msi_isrc->allocated = false;
  504         }
  505 
  506         mtx_unlock(&sc->msi_mtx);
  507         return (0);
  508 }
  509 
  510 static int
  511 bcm_pcib_msi_attach(device_t dev)
  512 {
  513         struct bcm_pcib_softc *sc;
  514         phandle_t node, xref;
  515         char const *bcm_name;
  516         int error, i, rid;
  517 
  518         sc = device_get_softc(dev);
  519         sc->msi_addr = 0xffffffffc;
  520 
  521         /* Clear any pending interrupts. */
  522         bcm_pcib_set_reg(sc, REG_MSI_CLR, 0xffffffff);
  523 
  524         rid = 1;
  525         sc->msi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  526             RF_ACTIVE);
  527         if (sc->msi_irq_res == NULL) {
  528                 device_printf(dev, "could not allocate MSI irq resource.\n");
  529                 return (ENXIO);
  530         }
  531 
  532         sc->msi_isrcs = malloc(sizeof(*sc->msi_isrcs) * NUM_MSI, M_DEVBUF,
  533             M_WAITOK | M_ZERO);
  534 
  535         error = bus_setup_intr(dev, sc->msi_irq_res, INTR_TYPE_BIO |
  536             INTR_MPSAFE, bcm_pcib_msi_intr, NULL, sc, &sc->msi_intr_cookie);
  537         if (error != 0) {
  538                 device_printf(dev, "error: failed to setup MSI handler.\n");
  539                 return (error);
  540         }
  541 
  542         bcm_name = device_get_nameunit(dev);
  543         for (i = 0; i < NUM_MSI; i++) {
  544                 sc->msi_isrcs[i].irq = i;
  545                 error = intr_isrc_register(&sc->msi_isrcs[i].isrc, dev, 0,
  546                     "%s,%u", bcm_name, i);
  547                 if (error != 0) {
  548                         device_printf(dev,
  549                             "error: failed to register interrupt %d.\n", i);
  550                         return (error);
  551                 }
  552         }
  553 
  554         node = ofw_bus_get_node(dev);
  555         xref = OF_xref_from_node(node);
  556         OF_device_register_xref(xref, dev);
  557 
  558         error = intr_msi_register(dev, xref);
  559         if (error != 0)
  560                 return (error);
  561 
  562         mtx_init(&sc->msi_mtx, "bcm_pcib: msi_mtx", NULL, MTX_DEF);
  563 
  564         bcm_pcib_set_reg(sc, REG_MSI_MASK_CLR, 0xffffffff);
  565         bcm_pcib_set_reg(sc, REG_MSI_ADDR_LOW, (sc->msi_addr & 0xffffffff) | 1);
  566         bcm_pcib_set_reg(sc, REG_MSI_ADDR_HIGH, (sc->msi_addr >> 32));
  567         bcm_pcib_set_reg(sc, REG_MSI_CONFIG, REG_VALUE_MSI_CONFIG);
  568 
  569         return (0);
  570 }
  571 
  572 static void
  573 bcm_pcib_relocate_bridge_window(device_t dev)
  574 {
  575         /*
  576          * In principle an out-of-bounds bridge window could be automatically
  577          * adjusted at resource-activation time to lie within the bus address
  578          * space by pcib_grow_window(), but that is not possible because the
  579          * out-of-bounds resource allocation fails at allocation time. Instead,
  580          * we will just fix up the window on the controller here, before it is
  581          * re-discovered by pcib_probe_windows().
  582          */
  583 
  584         struct bcm_pcib_softc *sc;
  585         pci_addr_t base, size, new_base, new_limit;
  586         uint16_t val;
  587 
  588         sc = device_get_softc(dev);
  589 
  590         val = bcm_pcib_read_config(dev, 0, 0, 0, PCIR_MEMBASE_1, 2);
  591         base = PCI_PPBMEMBASE(0, val);
  592 
  593         val = bcm_pcib_read_config(dev, 0, 0, 0, PCIR_MEMLIMIT_1, 2);
  594         size = PCI_PPBMEMLIMIT(0, val) - base;
  595 
  596         new_base = sc->base.base.ranges[0].pci_base;
  597         val = (uint16_t) (new_base >> 16);
  598         bcm_pcib_write_config(dev, 0, 0, 0, PCIR_MEMBASE_1, val, 2);
  599 
  600         new_limit = new_base + size;
  601         val = (uint16_t) (new_limit >> 16);
  602         bcm_pcib_write_config(dev, 0, 0, 0, PCIR_MEMLIMIT_1, val, 2);
  603 }
  604 
  605 static uint32_t
  606 encode_cpu_window_low(pci_addr_t phys_base, bus_size_t size)
  607 {
  608 
  609         return (((phys_base >> 0x10) & 0xfff0) |
  610             ((phys_base + size - 1) & 0xfff00000));
  611 }
  612 
  613 static uint32_t
  614 encode_cpu_window_start_high(pci_addr_t phys_base)
  615 {
  616 
  617         return ((phys_base >> 0x20) & 0xff);
  618 }
  619 
  620 static uint32_t
  621 encode_cpu_window_end_high(pci_addr_t phys_base, bus_size_t size)
  622 {
  623 
  624         return (((phys_base + size - 1) >> 0x20) & 0xff);
  625 }
  626 
  627 static int
  628 bcm_pcib_attach(device_t dev)
  629 {
  630         struct bcm_pcib_softc *sc;
  631         pci_addr_t phys_base, pci_base;
  632         bus_size_t size;
  633         uint32_t hardware_rev, bridge_state, link_state;
  634         int error, tries;
  635 
  636         sc = device_get_softc(dev);
  637         sc->dev = dev;
  638 
  639         /*
  640          * This tag will be used in preference to the one created in
  641          * pci_host_generic.c.
  642          */
  643         error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
  644             1, 0,                               /* alignment, bounds */
  645             DMA_HIGH_LIMIT,                     /* lowaddr */
  646             BUS_SPACE_MAXADDR,                  /* highaddr */
  647             NULL, NULL,                         /* filter, filterarg */
  648             DMA_HIGH_LIMIT,                     /* maxsize */
  649             BUS_SPACE_UNRESTRICTED,             /* nsegments */
  650             DMA_HIGH_LIMIT,                     /* maxsegsize */
  651             0,                                  /* flags */
  652             NULL, NULL,                         /* lockfunc, lockarg */
  653             &sc->dmat);
  654         if (error != 0)
  655                 return (error);
  656 
  657         error = pci_host_generic_setup_fdt(dev);
  658         if (error != 0)
  659                 return (error);
  660 
  661         error = bcm_pcib_check_ranges(dev);
  662         if (error != 0)
  663                 return (error);
  664 
  665         mtx_init(&sc->config_mtx, "bcm_pcib: config_mtx", NULL, MTX_DEF);
  666 
  667         bcm_pcib_reset_controller(sc);
  668 
  669         hardware_rev = bcm_pcib_read_reg(sc, REG_CONTROLLER_HW_REV) & 0xffff;
  670         device_printf(dev, "hardware identifies as revision 0x%x.\n",
  671             hardware_rev);
  672 
  673         /*
  674          * Set PCI->CPU memory window. This encodes the inbound window showing
  675          * the system memory to the controller.
  676          */
  677         bcm_pcib_set_reg(sc, REG_DMA_WINDOW_LOW, REG_VALUE_DMA_WINDOW_LOW);
  678         bcm_pcib_set_reg(sc, REG_DMA_WINDOW_HIGH, REG_VALUE_DMA_WINDOW_HIGH);
  679         bcm_pcib_set_reg(sc, REG_DMA_CONFIG, REG_VALUE_DMA_WINDOW_CONFIG);
  680 
  681         bcm_pcib_set_reg(sc, REG_BRIDGE_GISB_WINDOW, 0);
  682         bcm_pcib_set_reg(sc, REG_DMA_WINDOW_1, 0);
  683 
  684         bcm_pcib_enable_controller(sc);
  685 
  686         /* Wait for controller to start. */
  687         for(tries = 0; ; ++tries) {
  688                 bridge_state = bcm_pcib_read_reg(sc, REG_BRIDGE_STATE);
  689 
  690                 if ((bridge_state & 0x30) == 0x30)
  691                         /* Controller ready. */
  692                         break;
  693 
  694                 if (tries > 100) {
  695                         device_printf(dev,
  696                             "error: controller failed to start.\n");
  697                         return (ENXIO);
  698                 }
  699 
  700                 DELAY(1000);
  701         }
  702 
  703         link_state = bcm_pcib_read_reg(sc, REG_BRIDGE_LINK_STATE) >> 0x10;
  704         if (!link_state) {
  705                 device_printf(dev, "error: controller started but link is not "
  706                     "up.\n");
  707                 return (ENXIO);
  708         }
  709         if (bootverbose)
  710                 device_printf(dev, "note: reported link speed is %s.\n",
  711                     bcm_pcib_link_state_string(link_state));
  712 
  713         /*
  714          * Set the CPU->PCI memory window. The map in this direction is not 1:1.
  715          * Addresses seen by the CPU need to be adjusted to make sense to the
  716          * controller as they pass through the window.
  717          */
  718         pci_base  = sc->base.base.ranges[0].pci_base;
  719         phys_base = sc->base.base.ranges[0].phys_base;
  720         size      = sc->base.base.ranges[0].size;
  721 
  722         bcm_pcib_set_reg(sc, REG_BUS_WINDOW_LOW, pci_base & 0xffffffff);
  723         bcm_pcib_set_reg(sc, REG_BUS_WINDOW_HIGH, pci_base >> 32);
  724 
  725         bcm_pcib_set_reg(sc, REG_CPU_WINDOW_LOW,
  726             encode_cpu_window_low(phys_base, size));
  727         bcm_pcib_set_reg(sc, REG_CPU_WINDOW_START_HIGH,
  728             encode_cpu_window_start_high(phys_base));
  729         bcm_pcib_set_reg(sc, REG_CPU_WINDOW_END_HIGH,
  730             encode_cpu_window_end_high(phys_base, size));
  731 
  732         /*
  733          * The controller starts up declaring itself an endpoint; readvertise it
  734          * as a bridge.
  735          */
  736         bcm_pcib_set_reg(sc, PCI_ID_VAL3,
  737             PCIC_BRIDGE << CLASS_SHIFT | PCIS_BRIDGE_PCI << SUBCLASS_SHIFT);
  738 
  739         bcm_pcib_set_reg(sc, REG_BRIDGE_SERDES_MODE, 0x2);
  740         DELAY(100);
  741 
  742         bcm_pcib_relocate_bridge_window(dev);
  743 
  744         /* Configure interrupts. */
  745         error = bcm_pcib_msi_attach(dev);
  746         if (error != 0)
  747                 return (error);
  748 
  749         /* Done. */
  750         device_add_child(dev, "pci", -1);
  751         return (bus_generic_attach(dev));
  752 }
  753 
  754 /*
  755  * Device method table.
  756  */
  757 static device_method_t bcm_pcib_methods[] = {
  758         /* Bus interface. */
  759         DEVMETHOD(bus_get_dma_tag,              bcm_pcib_get_dma_tag),
  760 
  761         /* Device interface. */
  762         DEVMETHOD(device_probe,                 bcm_pcib_probe),
  763         DEVMETHOD(device_attach,                bcm_pcib_attach),
  764 
  765         /* PCIB interface. */
  766         DEVMETHOD(pcib_read_config,             bcm_pcib_read_config),
  767         DEVMETHOD(pcib_write_config,            bcm_pcib_write_config),
  768 
  769         /* MSI interface. */
  770         DEVMETHOD(msi_alloc_msi,                bcm_pcib_alloc_msi),
  771         DEVMETHOD(msi_release_msi,              bcm_pcib_release_msi),
  772         DEVMETHOD(msi_map_msi,                  bcm_pcib_map_msi),
  773 
  774         DEVMETHOD_END
  775 };
  776 
  777 DEFINE_CLASS_1(pcib, bcm_pcib_driver, bcm_pcib_methods,
  778     sizeof(struct bcm_pcib_softc), generic_pcie_fdt_driver);
  779 
  780 DRIVER_MODULE(bcm_pcib, simplebus, bcm_pcib_driver, 0, 0);
  781 

Cache object: 34a4328f91d74358c92475b1e224f578


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