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/cavium/octopci.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) 2010-2011 Juli Mallett <jmallett@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 
   35 #include <sys/bus.h>
   36 #include <sys/endian.h>
   37 #include <sys/interrupt.h>
   38 #include <sys/malloc.h>
   39 #include <sys/kernel.h>
   40 #include <sys/module.h>
   41 #include <sys/rman.h>
   42 
   43 #include <vm/vm.h>
   44 #include <vm/pmap.h>
   45 #include <vm/vm_extern.h>
   46 
   47 #include <machine/bus.h>
   48 #include <machine/cpu.h>
   49 #include <machine/pmap.h>
   50 
   51 #include <contrib/octeon-sdk/cvmx.h>
   52 #include <contrib/octeon-sdk/cvmx-interrupt.h>
   53 #include <contrib/octeon-sdk/cvmx-pcie.h>
   54 
   55 #include <dev/pci/pcireg.h>
   56 #include <dev/pci/pcivar.h>
   57 
   58 #include <dev/pci/pcib_private.h>
   59 
   60 #include <mips/cavium/octopcireg.h>
   61 #include <mips/cavium/octopcivar.h>
   62 
   63 #include "pcib_if.h"
   64 
   65 #define NPI_WRITE(addr, value)  cvmx_write64_uint32((addr) ^ 4, (value))
   66 #define NPI_READ(addr)          cvmx_read64_uint32((addr) ^ 4)
   67 
   68 struct octopci_softc {
   69         device_t sc_dev;
   70 
   71         unsigned sc_domain;
   72         unsigned sc_bus;
   73 
   74         bus_addr_t sc_io_base;
   75         unsigned sc_io_next;
   76         struct rman sc_io;
   77 
   78         bus_addr_t sc_mem1_base;
   79         unsigned sc_mem1_next;
   80         struct rman sc_mem1;
   81 };
   82 
   83 static void             octopci_identify(driver_t *, device_t);
   84 static int              octopci_probe(device_t);
   85 static int              octopci_attach(device_t);
   86 static int              octopci_read_ivar(device_t, device_t, int,
   87                                           uintptr_t *);
   88 static struct resource  *octopci_alloc_resource(device_t, device_t, int, int *,
   89                                                 u_long, u_long, u_long, u_int);
   90 static int              octopci_activate_resource(device_t, device_t, int, int,
   91                                                   struct resource *);
   92 static int      octopci_maxslots(device_t);
   93 static uint32_t octopci_read_config(device_t, u_int, u_int, u_int, u_int, int);
   94 static void     octopci_write_config(device_t, u_int, u_int, u_int, u_int,
   95                                      uint32_t, int);
   96 static int      octopci_route_interrupt(device_t, device_t, int);
   97 
   98 static unsigned octopci_init_bar(device_t, unsigned, unsigned, unsigned, unsigned, uint8_t *);
   99 static unsigned octopci_init_device(device_t, unsigned, unsigned, unsigned, unsigned);
  100 static unsigned octopci_init_bus(device_t, unsigned);
  101 static void     octopci_init_pci(device_t);
  102 static uint64_t octopci_cs_addr(unsigned, unsigned, unsigned, unsigned);
  103 
  104 static void
  105 octopci_identify(driver_t *drv, device_t parent)
  106 {
  107         /* XXX Check sysinfo flag.  */
  108 
  109         BUS_ADD_CHILD(parent, 0, "pcib", 0);
  110         if (octeon_has_feature(OCTEON_FEATURE_PCIE))
  111                 BUS_ADD_CHILD(parent, 0, "pcib", 1);
  112 }
  113 
  114 static int
  115 octopci_probe(device_t dev)
  116 {
  117         if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
  118                 device_set_desc(dev, "Cavium Octeon PCIe bridge");
  119                 return (0);
  120         }
  121 
  122         if (device_get_unit(dev) != 0)
  123                 return (ENXIO);
  124 
  125         device_set_desc(dev, "Cavium Octeon PCI bridge");
  126         return (0);
  127 }
  128 
  129 static int
  130 octopci_attach(device_t dev)
  131 {
  132         struct octopci_softc *sc;
  133         unsigned subbus;
  134         int error;
  135 
  136         sc = device_get_softc(dev);
  137         sc->sc_dev = dev;
  138 
  139         if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
  140                 sc->sc_domain = device_get_unit(dev);
  141 
  142                 error = cvmx_pcie_rc_initialize(sc->sc_domain);
  143                 if (error != 0) {
  144                         device_printf(dev, "Failed to put PCIe bus in host mode.\n");
  145                         return (ENXIO);
  146                 }
  147 
  148                 /*
  149                  * In RC mode, the Simple Executive programs the first bus to
  150                  * be numbered as bus 1, because some IDT bridges used in
  151                  * Octeon systems object to being attached to bus 0.
  152                  */
  153                 sc->sc_bus = 1;
  154 
  155                 sc->sc_io_base = CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(sc->sc_domain));
  156                 sc->sc_io.rm_descr = "Cavium Octeon PCIe I/O Ports";
  157 
  158                 sc->sc_mem1_base = CVMX_ADD_IO_SEG(cvmx_pcie_get_mem_base_address(sc->sc_domain));
  159                 sc->sc_mem1.rm_descr = "Cavium Octeon PCIe Memory";
  160         } else {
  161                 octopci_init_pci(dev);
  162 
  163                 sc->sc_domain = 0;
  164                 sc->sc_bus = 0;
  165 
  166                 sc->sc_io_base = CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_PCI, CVMX_OCT_SUBDID_PCI_IO));
  167                 sc->sc_io.rm_descr = "Cavium Octeon PCI I/O Ports";
  168 
  169                 sc->sc_mem1_base = CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_PCI, CVMX_OCT_SUBDID_PCI_MEM1));
  170                 sc->sc_mem1.rm_descr = "Cavium Octeon PCI Memory";
  171         }
  172 
  173         sc->sc_io.rm_type = RMAN_ARRAY;
  174         error = rman_init(&sc->sc_io);
  175         if (error != 0)
  176                 return (error);
  177 
  178         error = rman_manage_region(&sc->sc_io, CVMX_OCT_PCI_IO_BASE,
  179             CVMX_OCT_PCI_IO_BASE + CVMX_OCT_PCI_IO_SIZE);
  180         if (error != 0)
  181                 return (error);
  182 
  183         sc->sc_mem1.rm_type = RMAN_ARRAY;
  184         error = rman_init(&sc->sc_mem1);
  185         if (error != 0)
  186                 return (error);
  187 
  188         error = rman_manage_region(&sc->sc_mem1, CVMX_OCT_PCI_MEM1_BASE,
  189             CVMX_OCT_PCI_MEM1_BASE + CVMX_OCT_PCI_MEM1_SIZE);
  190         if (error != 0)
  191                 return (error);
  192 
  193         /*
  194          * Next offsets for resource allocation in octopci_init_bar.
  195          */
  196         sc->sc_io_next = 0;
  197         sc->sc_mem1_next = 0;
  198 
  199         /*
  200          * Configure devices.
  201          */
  202         octopci_write_config(dev, sc->sc_bus, 0, 0, PCIR_SUBBUS_1, 0xff, 1);
  203         subbus = octopci_init_bus(dev, sc->sc_bus);
  204         octopci_write_config(dev, sc->sc_bus, 0, 0, PCIR_SUBBUS_1, subbus, 1);
  205 
  206         device_add_child(dev, "pci", device_get_unit(dev));
  207 
  208         return (bus_generic_attach(dev));
  209 }
  210 
  211 static int
  212 octopci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
  213 {
  214         struct octopci_softc *sc;
  215         
  216         sc = device_get_softc(dev);
  217 
  218         switch (which) {
  219         case PCIB_IVAR_DOMAIN:
  220                 *result = sc->sc_domain;
  221                 return (0);
  222         case PCIB_IVAR_BUS:
  223                 *result = sc->sc_bus;
  224                 return (0);
  225                 
  226         }
  227         return (ENOENT);
  228 }
  229 
  230 static struct resource *
  231 octopci_alloc_resource(device_t bus, device_t child, int type, int *rid,
  232     u_long start, u_long end, u_long count, u_int flags)
  233 {
  234         struct octopci_softc *sc;
  235         struct resource *res;
  236         struct rman *rm;
  237         int error;
  238 
  239         sc = device_get_softc(bus);
  240 
  241         switch (type) {
  242         case SYS_RES_IRQ:
  243                 res = bus_generic_alloc_resource(bus, child, type, rid, start,
  244                     end, count, flags);
  245                 if (res != NULL)
  246                         return (res);
  247                 return (NULL);
  248         case SYS_RES_MEMORY:
  249                 rm = &sc->sc_mem1;
  250                 break;
  251         case SYS_RES_IOPORT:
  252                 rm = &sc->sc_io;
  253                 break;
  254         default:
  255                 return (NULL);
  256         }
  257 
  258         res = rman_reserve_resource(rm, start, end, count, flags, child);
  259         if (res == NULL)
  260                 return (NULL);
  261 
  262         rman_set_rid(res, *rid);
  263         rman_set_bustag(res, octopci_bus_space);
  264 
  265         switch (type) {
  266         case SYS_RES_MEMORY:
  267                 rman_set_bushandle(res, sc->sc_mem1_base + rman_get_start(res));
  268                 break;
  269         case SYS_RES_IOPORT:
  270                 rman_set_bushandle(res, sc->sc_io_base + rman_get_start(res));
  271 #if __mips_n64
  272                 rman_set_virtual(res, (void *)rman_get_bushandle(res));
  273 #else
  274                 /*
  275                  * XXX
  276                  * We can't access ports via a 32-bit pointer.
  277                  */
  278                 rman_set_virtual(res, NULL);
  279 #endif
  280                 break;
  281         }
  282 
  283         if ((flags & RF_ACTIVE) != 0) {
  284                 error = bus_activate_resource(child, type, *rid, res);
  285                 if (error != 0) {
  286                         rman_release_resource(res);
  287                         return (NULL);
  288                 }
  289         }
  290 
  291         return (res);
  292 }
  293 
  294 static int
  295 octopci_activate_resource(device_t bus, device_t child, int type, int rid,
  296     struct resource *res)
  297 {
  298         bus_space_handle_t bh;
  299         int error;
  300 
  301         switch (type) {
  302         case SYS_RES_IRQ:
  303                 error = bus_generic_activate_resource(bus, child, type, rid,
  304                                                       res);
  305                 if (error != 0)
  306                         return (error);
  307                 return (0);
  308         case SYS_RES_MEMORY:
  309         case SYS_RES_IOPORT:
  310                 error = bus_space_map(rman_get_bustag(res),
  311                     rman_get_bushandle(res), rman_get_size(res), 0, &bh);
  312                 if (error != 0)
  313                         return (error);
  314                 rman_set_bushandle(res, bh);
  315                 break;
  316         default:
  317                 return (ENXIO);
  318         }
  319 
  320         error = rman_activate_resource(res);
  321         if (error != 0)
  322                 return (error);
  323         return (0);
  324 }
  325 
  326 static int
  327 octopci_maxslots(device_t dev)
  328 {
  329         return (PCI_SLOTMAX);
  330 }
  331 
  332 static uint32_t
  333 octopci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
  334     int bytes)
  335 {
  336         struct octopci_softc *sc;
  337         uint64_t addr;
  338         uint32_t data;
  339 
  340         sc = device_get_softc(dev);
  341 
  342         if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
  343                 if (bus == 0 && slot == 0 && func == 0)
  344                         return ((uint32_t)-1);
  345 
  346                 switch (bytes) {
  347                 case 4:
  348                         return (cvmx_pcie_config_read32(sc->sc_domain, bus, slot, func, reg));
  349                 case 2:
  350                         return (cvmx_pcie_config_read16(sc->sc_domain, bus, slot, func, reg));
  351                 case 1:
  352                         return (cvmx_pcie_config_read8(sc->sc_domain, bus, slot, func, reg));
  353                 default:
  354                         return ((uint32_t)-1);
  355                 }
  356         }
  357 
  358         addr = octopci_cs_addr(bus, slot, func, reg);
  359 
  360         switch (bytes) {
  361         case 4:
  362                 data = le32toh(cvmx_read64_uint32(addr));
  363                 return (data);
  364         case 2:
  365                 data = le16toh(cvmx_read64_uint16(addr));
  366                 return (data);
  367         case 1:
  368                 data = cvmx_read64_uint8(addr);
  369                 return (data);
  370         default:
  371                 return ((uint32_t)-1);
  372         }
  373 }
  374 
  375 static void
  376 octopci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
  377     u_int reg, uint32_t data, int bytes)
  378 {
  379         struct octopci_softc *sc;
  380         uint64_t addr;
  381 
  382         sc = device_get_softc(dev);
  383 
  384         if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
  385                 switch (bytes) {
  386                 case 4:
  387                         cvmx_pcie_config_write32(sc->sc_domain, bus, slot, func, reg, data);
  388                         return;
  389                 case 2:
  390                         cvmx_pcie_config_write16(sc->sc_domain, bus, slot, func, reg, data);
  391                         return;
  392                 case 1:
  393                         cvmx_pcie_config_write8(sc->sc_domain, bus, slot, func, reg, data);
  394                         return;
  395                 default:
  396                         return;
  397                 }
  398         }
  399 
  400         addr = octopci_cs_addr(bus, slot, func, reg);
  401 
  402         switch (bytes) {
  403         case 4:
  404                 cvmx_write64_uint32(addr, htole32(data));
  405                 return;
  406         case 2:
  407                 cvmx_write64_uint16(addr, htole16(data));
  408                 return;
  409         case 1:
  410                 cvmx_write64_uint8(addr, data);
  411                 return;
  412         default:
  413                 return;
  414         }
  415 }
  416 
  417 static int
  418 octopci_route_interrupt(device_t dev, device_t child, int pin)
  419 {
  420         struct octopci_softc *sc;
  421         unsigned bus, slot, func;
  422         unsigned irq;
  423 
  424         sc = device_get_softc(dev);
  425 
  426         if (octeon_has_feature(OCTEON_FEATURE_PCIE))
  427                 return (CVMX_IRQ_PCI_INT0 + pin - 1);
  428 
  429         bus = pci_get_bus(child);
  430         slot = pci_get_slot(child);
  431         func = pci_get_function(child);
  432 
  433         /*
  434          * Board types we have to know at compile-time.
  435          */
  436 #if defined(OCTEON_BOARD_CAPK_0100ND)
  437         if (bus == 0 && slot == 12 && func == 0)
  438                 return (CVMX_IRQ_PCI_INT2);
  439 #endif
  440 
  441         /*
  442          * For board types we can determine at runtime.
  443          */
  444         switch (cvmx_sysinfo_get()->board_type) {
  445 #if defined(OCTEON_VENDOR_LANNER)
  446         case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
  447                 return (CVMX_IRQ_PCI_INT0 + pin - 1);
  448         case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
  449                 if (slot < 32) {
  450                         if (slot == 3 || slot == 9)
  451                                 irq = pin;
  452                         else
  453                                 irq = pin - 1;
  454                         return (CVMX_IRQ_PCI_INT0 + (irq & 3));
  455                 }
  456                 break;
  457 #endif
  458         default:
  459                 break;
  460         }
  461 
  462         irq = slot + pin - 3;
  463 
  464         return (CVMX_IRQ_PCI_INT0 + (irq & 3));
  465 }
  466 
  467 static unsigned
  468 octopci_init_bar(device_t dev, unsigned b, unsigned s, unsigned f, unsigned barnum, uint8_t *commandp)
  469 {
  470         struct octopci_softc *sc;
  471         uint64_t bar;
  472         unsigned size;
  473         int barsize;
  474 
  475         sc = device_get_softc(dev);
  476 
  477         octopci_write_config(dev, b, s, f, PCIR_BAR(barnum), 0xffffffff, 4);
  478         bar = octopci_read_config(dev, b, s, f, PCIR_BAR(barnum), 4);
  479 
  480         if (bar == 0) {
  481                 /* Bar not implemented; got to next bar.  */
  482                 return (barnum + 1);
  483         }
  484 
  485         if (PCI_BAR_IO(bar)) {
  486                 size = ~(bar & PCIM_BAR_IO_BASE) + 1;
  487 
  488                 sc->sc_io_next = (sc->sc_io_next + size - 1) & ~(size - 1);
  489                 if (sc->sc_io_next + size > CVMX_OCT_PCI_IO_SIZE) {
  490                         device_printf(dev, "%02x.%02x:%02x: no ports for BAR%u.\n",
  491                             b, s, f, barnum);
  492                         return (barnum + 1);
  493                 }
  494                 octopci_write_config(dev, b, s, f, PCIR_BAR(barnum),
  495                     CVMX_OCT_PCI_IO_BASE + sc->sc_io_next, 4);
  496                 sc->sc_io_next += size;
  497 
  498                 /*
  499                  * Enable I/O ports.
  500                  */
  501                 *commandp |= PCIM_CMD_PORTEN;
  502 
  503                 return (barnum + 1);
  504         } else {
  505                 if (PCIR_BAR(barnum) == PCIR_BIOS) {
  506                         /*
  507                          * ROM BAR is always 32-bit.
  508                          */
  509                         barsize = 1;
  510                 } else {
  511                         switch (bar & PCIM_BAR_MEM_TYPE) {
  512                         case PCIM_BAR_MEM_64:
  513                                 /*
  514                                  * XXX
  515                                  * High 32 bits are all zeroes for now.
  516                                  */
  517                                 octopci_write_config(dev, b, s, f, PCIR_BAR(barnum + 1), 0, 4);
  518                                 barsize = 2;
  519                                 break;
  520                         default:
  521                                 barsize = 1;
  522                                 break;
  523                         }
  524                 }
  525 
  526                 size = ~(bar & (uint32_t)PCIM_BAR_MEM_BASE) + 1;
  527 
  528                 sc->sc_mem1_next = (sc->sc_mem1_next + size - 1) & ~(size - 1);
  529                 if (sc->sc_mem1_next + size > CVMX_OCT_PCI_MEM1_SIZE) {
  530                         device_printf(dev, "%02x.%02x:%02x: no memory for BAR%u.\n",
  531                             b, s, f, barnum);
  532                         return (barnum + barsize);
  533                 }
  534                 octopci_write_config(dev, b, s, f, PCIR_BAR(barnum),
  535                     CVMX_OCT_PCI_MEM1_BASE + sc->sc_mem1_next, 4);
  536                 sc->sc_mem1_next += size;
  537 
  538                 /*
  539                  * Enable memory access.
  540                  */
  541                 *commandp |= PCIM_CMD_MEMEN;
  542 
  543                 return (barnum + barsize);
  544         }
  545 }
  546 
  547 static unsigned
  548 octopci_init_device(device_t dev, unsigned b, unsigned s, unsigned f, unsigned secbus)
  549 {
  550         unsigned barnum, bars;
  551         uint8_t brctl;
  552         uint8_t class, subclass;
  553         uint8_t command;
  554         uint8_t hdrtype;
  555 
  556         /* Read header type (again.)  */
  557         hdrtype = octopci_read_config(dev, b, s, f, PCIR_HDRTYPE, 1);
  558 
  559         /*
  560          * Disable memory and I/O while programming BARs.
  561          */
  562         command = octopci_read_config(dev, b, s, f, PCIR_COMMAND, 1);
  563         command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
  564         octopci_write_config(dev, b, s, f, PCIR_COMMAND, command, 1);
  565 
  566         DELAY(10000);
  567 
  568         /* Program BARs.  */
  569         switch (hdrtype & PCIM_HDRTYPE) {
  570         case PCIM_HDRTYPE_NORMAL:
  571                 bars = 6;
  572                 break;
  573         case PCIM_HDRTYPE_BRIDGE:
  574                 bars = 2;
  575                 break;
  576         case PCIM_HDRTYPE_CARDBUS:
  577                 bars = 0;
  578                 break;
  579         default:
  580                 device_printf(dev, "%02x.%02x:%02x: invalid header type %#x\n",
  581                     b, s, f, hdrtype);
  582                 return (secbus);
  583         }
  584 
  585         barnum = 0;
  586         while (barnum < bars)
  587                 barnum = octopci_init_bar(dev, b, s, f, barnum, &command);
  588 
  589         /* Enable bus mastering.  */
  590         command |= PCIM_CMD_BUSMASTEREN;
  591 
  592         /* Enable whatever facilities the BARs require.  */
  593         octopci_write_config(dev, b, s, f, PCIR_COMMAND, command, 1);
  594 
  595         DELAY(10000);
  596 
  597         /* 
  598          * Set cache line size.  On Octeon it should be 128 bytes,
  599          * but according to Linux some Intel bridges have trouble
  600          * with values over 64 bytes, so use 64 bytes.
  601          */
  602         octopci_write_config(dev, b, s, f, PCIR_CACHELNSZ, 16, 1);
  603 
  604         /* Set latency timer.  */
  605         octopci_write_config(dev, b, s, f, PCIR_LATTIMER, 48, 1);
  606 
  607         /* Board-specific or device-specific fixups and workarounds.  */
  608         switch (cvmx_sysinfo_get()->board_type) {
  609 #if defined(OCTEON_VENDOR_LANNER)
  610         case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
  611                 if (b == 1 && s == 7 && f == 0) {
  612                         bus_addr_t busaddr, unitbusaddr;
  613                         uint32_t bar;
  614                         uint32_t tmp;
  615                         unsigned unit;
  616 
  617                         /*
  618                          * Set Tx DMA power.
  619                          */
  620                         bar = octopci_read_config(dev, b, s, f,
  621                             PCIR_BAR(3), 4);
  622                         busaddr = CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_PCI,
  623                             CVMX_OCT_SUBDID_PCI_MEM1));
  624                         busaddr += (bar & (uint32_t)PCIM_BAR_MEM_BASE);
  625                         for (unit = 0; unit < 4; unit++) {
  626                                 unitbusaddr = busaddr + 0x430 + (unit << 8);
  627                                 tmp = le32toh(cvmx_read64_uint32(unitbusaddr));
  628                                 tmp &= ~0x700;
  629                                 tmp |= 0x300;
  630                                 cvmx_write64_uint32(unitbusaddr, htole32(tmp));
  631                         }
  632                 }
  633                 break;
  634 #endif
  635         default:
  636                 break;
  637         }
  638 
  639         /* Configure PCI-PCI bridges.  */
  640         class = octopci_read_config(dev, b, s, f, PCIR_CLASS, 1);
  641         if (class != PCIC_BRIDGE)
  642                 return (secbus);
  643 
  644         subclass = octopci_read_config(dev, b, s, f, PCIR_SUBCLASS, 1);
  645         if (subclass != PCIS_BRIDGE_PCI)
  646                 return (secbus);
  647 
  648         /* Enable memory and I/O access.  */
  649         command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
  650         octopci_write_config(dev, b, s, f, PCIR_COMMAND, command, 1);
  651 
  652         /* Enable errors and parity checking.  Do a bus reset.  */
  653         brctl = octopci_read_config(dev, b, s, f, PCIR_BRIDGECTL_1, 1);
  654         brctl |= PCIB_BCR_PERR_ENABLE | PCIB_BCR_SERR_ENABLE;
  655 
  656         /* Perform a secondary bus reset.  */
  657         brctl |= PCIB_BCR_SECBUS_RESET;
  658         octopci_write_config(dev, b, s, f, PCIR_BRIDGECTL_1, brctl, 1);
  659         DELAY(100000);
  660         brctl &= ~PCIB_BCR_SECBUS_RESET;
  661         octopci_write_config(dev, b, s, f, PCIR_BRIDGECTL_1, brctl, 1);
  662 
  663         secbus++;
  664 
  665         /* Program memory and I/O ranges.  */
  666         octopci_write_config(dev, b, s, f, PCIR_MEMBASE_1,
  667             CVMX_OCT_PCI_MEM1_BASE >> 16, 2);
  668         octopci_write_config(dev, b, s, f, PCIR_MEMLIMIT_1,
  669             (CVMX_OCT_PCI_MEM1_BASE + CVMX_OCT_PCI_MEM1_SIZE - 1) >> 16, 2);
  670 
  671         octopci_write_config(dev, b, s, f, PCIR_IOBASEL_1,
  672             CVMX_OCT_PCI_IO_BASE >> 8, 1);
  673         octopci_write_config(dev, b, s, f, PCIR_IOBASEH_1,
  674             CVMX_OCT_PCI_IO_BASE >> 16, 2);
  675 
  676         octopci_write_config(dev, b, s, f, PCIR_IOLIMITL_1,
  677             (CVMX_OCT_PCI_IO_BASE + CVMX_OCT_PCI_IO_SIZE - 1) >> 8, 1);
  678         octopci_write_config(dev, b, s, f, PCIR_IOLIMITH_1,
  679             (CVMX_OCT_PCI_IO_BASE + CVMX_OCT_PCI_IO_SIZE - 1) >> 16, 2);
  680 
  681         /* Program prefetchable memory decoder.  */
  682         /* XXX */
  683 
  684         /* Probe secondary/subordinate buses.  */
  685         octopci_write_config(dev, b, s, f, PCIR_PRIBUS_1, b, 1);
  686         octopci_write_config(dev, b, s, f, PCIR_SECBUS_1, secbus, 1);
  687         octopci_write_config(dev, b, s, f, PCIR_SUBBUS_1, 0xff, 1);
  688 
  689         /* Perform a secondary bus reset.  */
  690         brctl |= PCIB_BCR_SECBUS_RESET;
  691         octopci_write_config(dev, b, s, f, PCIR_BRIDGECTL_1, brctl, 1);
  692         DELAY(100000);
  693         brctl &= ~PCIB_BCR_SECBUS_RESET;
  694         octopci_write_config(dev, b, s, f, PCIR_BRIDGECTL_1, brctl, 1);
  695 
  696         /* Give the bus time to settle now before reading configspace.  */
  697         DELAY(100000);
  698 
  699         secbus = octopci_init_bus(dev, secbus);
  700 
  701         octopci_write_config(dev, b, s, f, PCIR_SUBBUS_1, secbus, 1);
  702 
  703         return (secbus);
  704 }
  705 
  706 static unsigned
  707 octopci_init_bus(device_t dev, unsigned b)
  708 {
  709         unsigned s, f;
  710         uint8_t hdrtype;
  711         unsigned secbus;
  712 
  713         secbus = b;
  714 
  715         for (s = 0; s <= PCI_SLOTMAX; s++) {
  716                 for (f = 0; f <= PCI_FUNCMAX; f++) {
  717                         hdrtype = octopci_read_config(dev, b, s, f, PCIR_HDRTYPE, 1);
  718 
  719                         if (hdrtype == 0xff) {
  720                                 if (f == 0)
  721                                         break; /* Next slot.  */
  722                                 continue; /* Next function.  */
  723                         }
  724 
  725                         secbus = octopci_init_device(dev, b, s, f, secbus);
  726 
  727                         if (f == 0 && (hdrtype & PCIM_MFDEV) == 0)
  728                                 break; /* Next slot.  */
  729                 }
  730         }
  731 
  732         return (secbus);
  733 }
  734 
  735 static uint64_t
  736 octopci_cs_addr(unsigned bus, unsigned slot, unsigned func, unsigned reg)
  737 {
  738         octeon_pci_config_space_address_t pci_addr;
  739 
  740         pci_addr.u64 = 0;
  741         pci_addr.s.upper = 2;
  742         pci_addr.s.io = 1;
  743         pci_addr.s.did = 3;
  744         pci_addr.s.subdid = CVMX_OCT_SUBDID_PCI_CFG;
  745         pci_addr.s.endian_swap = 1;
  746         pci_addr.s.bus = bus;
  747         pci_addr.s.dev = slot;
  748         pci_addr.s.func = func;
  749         pci_addr.s.reg = reg;
  750 
  751         return (pci_addr.u64);
  752 }
  753 
  754 static void
  755 octopci_init_pci(device_t dev)
  756 {
  757         cvmx_npi_mem_access_subid_t npi_mem_access_subid;
  758         cvmx_npi_pci_int_arb_cfg_t npi_pci_int_arb_cfg;
  759         cvmx_npi_ctl_status_t npi_ctl_status;
  760         cvmx_pci_ctl_status_2_t pci_ctl_status_2;
  761         cvmx_pci_cfg56_t pci_cfg56;
  762         cvmx_pci_cfg22_t pci_cfg22;
  763         cvmx_pci_cfg16_t pci_cfg16;
  764         cvmx_pci_cfg19_t pci_cfg19;
  765         cvmx_pci_cfg01_t pci_cfg01;
  766         unsigned i;
  767 
  768         /*
  769          * Reset the PCI bus.
  770          */
  771         cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1);
  772         cvmx_read_csr(CVMX_CIU_SOFT_PRST);
  773 
  774         DELAY(2000);
  775 
  776         npi_ctl_status.u64 = 0;
  777         npi_ctl_status.s.max_word = 1;
  778         npi_ctl_status.s.timer = 1;
  779         cvmx_write_csr(CVMX_NPI_CTL_STATUS, npi_ctl_status.u64);
  780 
  781         /*
  782          * Set host mode.
  783          */
  784         switch (cvmx_sysinfo_get()->board_type) {
  785 #if defined(OCTEON_VENDOR_LANNER)
  786         case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
  787         case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
  788                 /* 32-bit PCI-X */
  789                 cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x0);
  790                 break;
  791 #endif
  792         default:
  793                 /* 64-bit PCI-X */
  794                 cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x4);
  795                 break;
  796         }
  797         cvmx_read_csr(CVMX_CIU_SOFT_PRST);
  798 
  799         DELAY(2000);
  800 
  801         /*
  802          * Enable BARs and configure big BAR mode.
  803          */
  804         pci_ctl_status_2.u32 = 0;
  805         pci_ctl_status_2.s.bb1_hole = 5; /* 256MB hole in BAR1 */
  806         pci_ctl_status_2.s.bb1_siz = 1; /* BAR1 is 2GB */
  807         pci_ctl_status_2.s.bb_ca = 1; /* Bypass cache for big BAR */
  808         pci_ctl_status_2.s.bb_es = 1; /* Do big BAR byte-swapping */
  809         pci_ctl_status_2.s.bb1 = 1; /* BAR1 is big */
  810         pci_ctl_status_2.s.bb0 = 1; /* BAR0 is big */
  811         pci_ctl_status_2.s.bar2pres = 1; /* BAR2 present */
  812         pci_ctl_status_2.s.pmo_amod = 1; /* Round-robin priority */
  813         pci_ctl_status_2.s.tsr_hwm = 1;
  814         pci_ctl_status_2.s.bar2_enb = 1; /* Enable BAR2 */
  815         pci_ctl_status_2.s.bar2_esx = 1; /* Do BAR2 byte-swapping */
  816         pci_ctl_status_2.s.bar2_cax = 1; /* Bypass cache for BAR2 */
  817 
  818         NPI_WRITE(CVMX_NPI_PCI_CTL_STATUS_2, pci_ctl_status_2.u32);
  819 
  820         DELAY(2000);
  821 
  822         pci_ctl_status_2.u32 = NPI_READ(CVMX_NPI_PCI_CTL_STATUS_2);
  823 
  824         device_printf(dev, "%u-bit PCI%s bus.\n",
  825             pci_ctl_status_2.s.ap_64ad ? 64 : 32,
  826             pci_ctl_status_2.s.ap_pcix ? "-X" : "");
  827 
  828         /*
  829          * Set up transaction splitting, etc., parameters.
  830          */
  831         pci_cfg19.u32 = 0;
  832         pci_cfg19.s.mrbcm = 1;
  833         if (pci_ctl_status_2.s.ap_pcix) {
  834                 pci_cfg19.s.mdrrmc = 0;
  835                 pci_cfg19.s.tdomc = 4;
  836         } else {
  837                 pci_cfg19.s.mdrrmc = 2;
  838                 pci_cfg19.s.tdomc = 1;
  839         }
  840         NPI_WRITE(CVMX_NPI_PCI_CFG19, pci_cfg19.u32);
  841         NPI_READ(CVMX_NPI_PCI_CFG19);
  842 
  843         /*
  844          * Set up PCI error handling and memory access.
  845          */
  846         pci_cfg01.u32 = 0;
  847         pci_cfg01.s.fbbe = 1;
  848         pci_cfg01.s.see = 1;
  849         pci_cfg01.s.pee = 1;
  850         pci_cfg01.s.me = 1;
  851         pci_cfg01.s.msae = 1;
  852         if (pci_ctl_status_2.s.ap_pcix) {
  853                 pci_cfg01.s.fbb = 0;
  854         } else {
  855                 pci_cfg01.s.fbb = 1;
  856         }
  857         NPI_WRITE(CVMX_NPI_PCI_CFG01, pci_cfg01.u32);
  858         NPI_READ(CVMX_NPI_PCI_CFG01);
  859 
  860         /*
  861          * Enable the Octeon bus arbiter.
  862          */
  863         npi_pci_int_arb_cfg.u64 = 0;
  864         npi_pci_int_arb_cfg.s.en = 1;
  865         cvmx_write_csr(CVMX_NPI_PCI_INT_ARB_CFG, npi_pci_int_arb_cfg.u64);
  866 
  867         /*
  868          * Disable master latency timer.
  869          */
  870         pci_cfg16.u32 = 0;
  871         pci_cfg16.s.mltd = 1;
  872         NPI_WRITE(CVMX_NPI_PCI_CFG16, pci_cfg16.u32);
  873         NPI_READ(CVMX_NPI_PCI_CFG16);
  874 
  875         /*
  876          * Configure master arbiter.
  877          */
  878         pci_cfg22.u32 = 0;
  879         pci_cfg22.s.flush = 1;
  880         pci_cfg22.s.mrv = 255;
  881         NPI_WRITE(CVMX_NPI_PCI_CFG22, pci_cfg22.u32);
  882         NPI_READ(CVMX_NPI_PCI_CFG22);
  883 
  884         /*
  885          * Set up PCI-X capabilities.
  886          */
  887         if (pci_ctl_status_2.s.ap_pcix) {
  888                 pci_cfg56.u32 = 0;
  889                 pci_cfg56.s.most = 3;
  890                 pci_cfg56.s.roe = 1; /* Enable relaxed ordering */
  891                 pci_cfg56.s.dpere = 1;
  892                 pci_cfg56.s.ncp = 0xe8;
  893                 pci_cfg56.s.pxcid = 7;
  894                 NPI_WRITE(CVMX_NPI_PCI_CFG56, pci_cfg56.u32);
  895                 NPI_READ(CVMX_NPI_PCI_CFG56);
  896         }
  897 
  898         NPI_WRITE(CVMX_NPI_PCI_READ_CMD_6, 0x22);
  899         NPI_READ(CVMX_NPI_PCI_READ_CMD_6);
  900         NPI_WRITE(CVMX_NPI_PCI_READ_CMD_C, 0x33);
  901         NPI_READ(CVMX_NPI_PCI_READ_CMD_C);
  902         NPI_WRITE(CVMX_NPI_PCI_READ_CMD_E, 0x33);
  903         NPI_READ(CVMX_NPI_PCI_READ_CMD_E);
  904 
  905         /*
  906          * Configure MEM1 sub-DID access.
  907          */
  908         npi_mem_access_subid.u64 = 0;
  909         npi_mem_access_subid.s.esr = 1; /* Byte-swap on read */
  910         npi_mem_access_subid.s.esw = 1; /* Byte-swap on write */
  911         switch (cvmx_sysinfo_get()->board_type) {
  912 #if defined(OCTEON_VENDOR_LANNER)
  913         case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
  914                 npi_mem_access_subid.s.shortl = 1;
  915                 break;
  916 #endif
  917         default:
  918                 break;
  919         }
  920         cvmx_write_csr(CVMX_NPI_MEM_ACCESS_SUBID3, npi_mem_access_subid.u64);
  921 
  922         /*
  923          * Configure BAR2.  Linux says this has to come first.
  924          */
  925         NPI_WRITE(CVMX_NPI_PCI_CFG08, 0x00000000);
  926         NPI_READ(CVMX_NPI_PCI_CFG08);
  927         NPI_WRITE(CVMX_NPI_PCI_CFG09, 0x00000080);
  928         NPI_READ(CVMX_NPI_PCI_CFG09);
  929 
  930         /*
  931          * Disable BAR1 IndexX.
  932          */
  933         for (i = 0; i < 32; i++) {
  934                 NPI_WRITE(CVMX_NPI_PCI_BAR1_INDEXX(i), 0);
  935                 NPI_READ(CVMX_NPI_PCI_BAR1_INDEXX(i));
  936         }
  937 
  938         /*
  939          * Configure BAR0 and BAR1.
  940          */
  941         NPI_WRITE(CVMX_NPI_PCI_CFG04, 0x00000000);
  942         NPI_READ(CVMX_NPI_PCI_CFG04);
  943         NPI_WRITE(CVMX_NPI_PCI_CFG05, 0x00000000);
  944         NPI_READ(CVMX_NPI_PCI_CFG05);
  945 
  946         NPI_WRITE(CVMX_NPI_PCI_CFG06, 0x80000000);
  947         NPI_READ(CVMX_NPI_PCI_CFG06);
  948         NPI_WRITE(CVMX_NPI_PCI_CFG07, 0x00000000);
  949         NPI_READ(CVMX_NPI_PCI_CFG07);
  950 
  951         /*
  952          * Clear PCI interrupts.
  953          */
  954         cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, 0xffffffffffffffffull);
  955 }
  956 
  957 static device_method_t octopci_methods[] = {
  958         /* Device interface */
  959         DEVMETHOD(device_identify,      octopci_identify),
  960         DEVMETHOD(device_probe,         octopci_probe),
  961         DEVMETHOD(device_attach,        octopci_attach),
  962 
  963         /* Bus interface */
  964         DEVMETHOD(bus_read_ivar,        octopci_read_ivar),
  965         DEVMETHOD(bus_alloc_resource,   octopci_alloc_resource),
  966         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  967         DEVMETHOD(bus_activate_resource,octopci_activate_resource),
  968         DEVMETHOD(bus_deactivate_resource,bus_generic_deactivate_resource),
  969         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  970         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  971 
  972         DEVMETHOD(bus_add_child,        bus_generic_add_child),
  973 
  974         /* pcib interface */
  975         DEVMETHOD(pcib_maxslots,        octopci_maxslots),
  976         DEVMETHOD(pcib_read_config,     octopci_read_config),
  977         DEVMETHOD(pcib_write_config,    octopci_write_config),
  978         DEVMETHOD(pcib_route_interrupt, octopci_route_interrupt),
  979 
  980         DEVMETHOD_END
  981 };
  982 
  983 static driver_t octopci_driver = {
  984         "pcib",
  985         octopci_methods,
  986         sizeof(struct octopci_softc),
  987 };
  988 static devclass_t octopci_devclass;
  989 DRIVER_MODULE(octopci, ciu, octopci_driver, octopci_devclass, 0, 0);

Cache object: 212945d1af8f31d0b4bdf20155268877


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