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

Cache object: e32c045a38205d64660e9615fedc71da


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