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

Cache object: 262e77f7a0fd52098540061cbc9fef2f


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