Author: jchandra
Date: Tue Mar 27 07:57:41 2012
New Revision: 233536
URL: http://svn.freebsd.org/changeset/base/233536

Log:
  XLP PCIe code update.
  
  - XLP supports hardware swap for PCIe IO/MEM accesses. Since we
    are in big-endian mode, enable hardware swap and use the normal
    bus space.
  - move some printfs to bootverbose, and remove others.
  - fix SoC device resource allocation code
  - Do not use '|' while updating PCIE_BRIDGE_MSI_ADDRL
  - some style fixes
  
  In collaboration with: Venkatesh J. V. (venkatesh at netlogicmicro com)

Modified:
  head/sys/mips/nlm/hal/iomap.h
  head/sys/mips/nlm/hal/pcibus.h
  head/sys/mips/nlm/xlp_pci.c

Modified: head/sys/mips/nlm/hal/iomap.h
==============================================================================
--- head/sys/mips/nlm/hal/iomap.h       Tue Mar 27 07:51:42 2012        
(r233535)
+++ head/sys/mips/nlm/hal/iomap.h       Tue Mar 27 07:57:41 2012        
(r233536)
@@ -190,6 +190,16 @@ nlm_uenginenum(uint64_t pcibase)
        return nlm_read_reg(pcibase, XLP_PCI_UCODEINFO_REG);
 }
 
+/*
+ * Find node on which a given Soc device is located.
+ * input is the pci device (slot) number.
+ */
+static __inline__ int
+nlm_get_device_node(int device)
+{
+       return (device / 8);
+}
+
 #endif /* !LOCORE or !__ASSEMBLY */
 
 #endif /* __NLM_HAL_IOMAP_H__ */

Modified: head/sys/mips/nlm/hal/pcibus.h
==============================================================================
--- head/sys/mips/nlm/hal/pcibus.h      Tue Mar 27 07:51:42 2012        
(r233535)
+++ head/sys/mips/nlm/hal/pcibus.h      Tue Mar 27 07:57:41 2012        
(r233536)
@@ -57,16 +57,26 @@
 
 #define        MSI_MIPS_DATA_INTVEC            0x000000ff
 
-#define        PCIE_BRIDGE_CMD         0x1
-#define        PCIE_BRIDGE_MSI_CAP     0x14
-#define        PCIE_BRIDGE_MSI_ADDRL   0x15
-#define        PCIE_BRIDGE_MSI_ADDRH   0x16
-#define        PCIE_BRIDGE_MSI_DATA    0x17
+/* PCIE Memory and IO regions */
+#define        PCIE_MEM_BASE                   0xd0000000ULL
+#define        PCIE_MEM_LIMIT                  0xdfffffffULL
+#define        PCIE_IO_BASE                    0x14000000ULL
+#define        PCIE_IO_LIMIT                   0x15ffffffULL
+
+#define        PCIE_BRIDGE_CMD                 0x1
+#define        PCIE_BRIDGE_MSI_CAP             0x14
+#define        PCIE_BRIDGE_MSI_ADDRL           0x15
+#define        PCIE_BRIDGE_MSI_ADDRH           0x16
+#define        PCIE_BRIDGE_MSI_DATA            0x17
 
 /* XLP Global PCIE configuration space registers */
-#define        PCIE_MSI_STATUS         0x25A
-#define        PCIE_MSI_EN             0x25B
-#define        PCIE_INT_EN0            0x261
+#define        PCIE_BYTE_SWAP_MEM_BASE         0x247
+#define        PCIE_BYTE_SWAP_MEM_LIM          0x248
+#define        PCIE_BYTE_SWAP_IO_BASE          0x249
+#define        PCIE_BYTE_SWAP_IO_LIM           0x24A
+#define        PCIE_MSI_STATUS                 0x25A
+#define        PCIE_MSI_EN                     0x25B
+#define        PCIE_INT_EN0                    0x261
 
 /* PCIE_MSI_EN */
 #define        PCIE_MSI_VECTOR_INT_EN          0xFFFFFFFF

Modified: head/sys/mips/nlm/xlp_pci.c
==============================================================================
--- head/sys/mips/nlm/xlp_pci.c Tue Mar 27 07:51:42 2012        (r233535)
+++ head/sys/mips/nlm/xlp_pci.c Tue Mar 27 07:57:41 2012        (r233536)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <mips/nlm/hal/iomap.h>
 #include <mips/nlm/hal/mips-extns.h>
 #include <mips/nlm/hal/pic.h>
+#include <mips/nlm/hal/bridge.h>
 #include <mips/nlm/hal/pcibus.h>
 #include <mips/nlm/hal/uart.h>
 #include <mips/nlm/xlp.h>
@@ -77,7 +78,6 @@ static struct rman irq_rman, port_rman, 
 static void
 xlp_pci_init_resources(void)
 {
-
        irq_rman.rm_start = 0;
        irq_rman.rm_end = 255;
        irq_rman.rm_type = RMAN_ARRAY;
@@ -91,7 +91,7 @@ xlp_pci_init_resources(void)
        port_rman.rm_type = RMAN_ARRAY;
        port_rman.rm_descr = "I/O ports";
        if (rman_init(&port_rman)
-           || rman_manage_region(&port_rman, 0x14000000UL, 0x15ffffffUL))
+           || rman_manage_region(&port_rman, PCIE_IO_BASE, PCIE_IO_LIMIT))
                panic("pci_init_resources port_rman");
 
        mem_rman.rm_start = 0;
@@ -99,15 +99,19 @@ xlp_pci_init_resources(void)
        mem_rman.rm_type = RMAN_ARRAY;
        mem_rman.rm_descr = "I/O memory";
        if (rman_init(&mem_rman)
-           || rman_manage_region(&mem_rman, 0xd0000000ULL, 0xdfffffffULL))
+           || rman_manage_region(&mem_rman, PCIE_MEM_BASE, PCIE_MEM_LIMIT))
                panic("pci_init_resources mem_rman");
 
+       /*
+        * This includes the GBU (nor flash) memory range and the PCIe
+        * memory area. 
+        */
        emul_rman.rm_start = 0;
        emul_rman.rm_end = ~0ul;
        emul_rman.rm_type = RMAN_ARRAY;
        emul_rman.rm_descr = "Emulated MEMIO";
        if (rman_init(&emul_rman)
-           || rman_manage_region(&emul_rman, 0x18000000ULL, 0x18ffffffULL))
+           || rman_manage_region(&emul_rman, 0x16000000UL, 0x18ffffffUL))
                panic("pci_init_resources emul_rman");
 }
 
@@ -220,15 +224,48 @@ xlp_pcib_write_config(device_t dev, u_in
        return;
 }
 
+/*
+ * Enable byte swap in hardware. Program a link's PCIe SWAP regions
+ * from the link's IO and MEM address ranges.
+ */
+static void
+xlp_pci_hardware_swap_enable(int node, int link)
+{
+       uint64_t bbase, linkpcibase;
+       uint32_t bar;
+       int pcieoffset;
+
+       pcieoffset = XLP_IO_PCIE_OFFSET(node, link);
+       if (!nlm_dev_exists(pcieoffset))
+               return;
+
+       bbase = nlm_get_bridge_regbase(node);
+       linkpcibase = nlm_pcicfg_base(pcieoffset);
+       bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_BASE0 + link);
+       nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_BASE, bar);
+
+       bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_LIMIT0 + link);
+       nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_LIM, bar);
+
+       bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_BASE0 + link);
+       nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_BASE, bar);
+
+       bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_LIMIT0 + link);
+       nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_LIM, bar);
+}
+
 static int 
 xlp_pcib_attach(device_t dev)
 {
-       struct xlp_pcib_softc *sc;
-       sc = device_get_softc(dev);
+       int node, link;
+
+       /* enable hardware swap on all nodes/links */
+       for (node = 0; node < XLP_MAX_NODES; node++)
+               for (link = 0; link < 4; link++)
+                       xlp_pci_hardware_swap_enable(node, link);
 
        device_add_child(dev, "pci", 0);
        bus_generic_attach(dev);
-
        return (0);
 }
 
@@ -249,10 +286,6 @@ xlp_pcie_link(device_t pcib, device_t de
        device_t parent, tmp;
 
        /* find the lane on which the slot is connected to */
-#if 0 /* Debug */
-       printf("xlp_pcie_link : bus %s dev %s\n", device_get_nameunit(pcib),
-               device_get_nameunit(dev));
-#endif
        tmp = dev;
        while (1) {
                parent = device_get_parent(tmp);
@@ -295,8 +328,6 @@ xlp_alloc_msi(device_t pcib, device_t de
 static int
 xlp_release_msi(device_t pcib, device_t dev, int count, int *irqs)
 {
-       device_printf(dev, "%s: msi release %d\n", device_get_nameunit(pcib),
-           count);
        return (0);
 }
 
@@ -369,7 +400,6 @@ mips_platform_pci_setup_intr(device_t de
                return (EINVAL);
        }
        xlpirq = rman_get_start(irq);
-       device_printf(dev, "setup intr %d\n", xlpirq);
 
        if (strcmp(device_get_name(dev), "pcib") != 0) {
                device_printf(dev, "ret 0 on dev\n");
@@ -389,7 +419,7 @@ mips_platform_pci_setup_intr(device_t de
                        return (0);
 
                node = nlm_nodeid();
-               link = (xlpirq / 32);
+               link = xlpirq / 32;
                base = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node,link));
 
                /* MSI Interrupt Vector enable at bridge's configuration */
@@ -398,24 +428,23 @@ mips_platform_pci_setup_intr(device_t de
                val = nlm_read_pci_reg(base, PCIE_INT_EN0);
                /* MSI Interrupt enable at bridge's configuration */
                nlm_write_pci_reg(base, PCIE_INT_EN0,
-                               (val | PCIE_MSI_INT_EN));
+                   (val | PCIE_MSI_INT_EN));
 
                /* legacy interrupt disable at bridge */
                val = nlm_read_pci_reg(base, PCIE_BRIDGE_CMD);
                nlm_write_pci_reg(base, PCIE_BRIDGE_CMD,
-                               (val | PCIM_CMD_INTxDIS));
+                   (val | PCIM_CMD_INTxDIS));
 
                /* MSI address update at bridge */
-               val = nlm_read_pci_reg(base, PCIE_BRIDGE_MSI_ADDRL);
                nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_ADDRL,
-                               (val | MSI_MIPS_ADDR_BASE));
+                   MSI_MIPS_ADDR_BASE);
+               nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_ADDRH, 0);
 
                val = nlm_read_pci_reg(base, PCIE_BRIDGE_MSI_CAP);
                /* MSI capability enable at bridge */
                nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_CAP, 
-                               (val |
-                               (PCIM_MSICTRL_MSI_ENABLE << 16) |
-                               (PCIM_MSICTRL_MMC_32 << 16)));
+                   (val | (PCIM_MSICTRL_MSI_ENABLE << 16) |
+                       (PCIM_MSICTRL_MMC_32 << 16)));
 
                xlpirq = xlp_pcie_link_irt(xlpirq / 32);
                if (xlpirq == -1)
@@ -423,12 +452,10 @@ mips_platform_pci_setup_intr(device_t de
                xlpirq = xlp_irt_to_irq(xlpirq);
        }
        /* Set all irqs to CPU 0 for now */
-       printf("set up intr %d->%d(%d)\n", xlp_irq_to_irt(xlpirq), xlpirq, 
(int)rman_get_start(irq));
        nlm_pic_write_irt_direct(xlp_pic_base, xlp_irq_to_irt(xlpirq), 1, 0,
-                                PIC_LOCAL_SCHEDULING, xlpirq, 0);
+           PIC_LOCAL_SCHEDULING, xlpirq, 0);
        extra_ack = NULL;
-       if (xlpirq >= PIC_PCIE_0_IRQ &&
-           xlpirq <= PIC_PCIE_3_IRQ)
+       if (xlpirq >= PIC_PCIE_0_IRQ && xlpirq <= PIC_PCIE_3_IRQ)
                extra_ack = bridge_pcie_ack;
        xlp_establish_intr(device_get_name(child), filt,
            intr, arg, xlpirq, flags, cookiep, extra_ack);
@@ -451,34 +478,37 @@ static void
 assign_soc_resource(device_t child, int type, u_long *startp, u_long *endp,
     u_long *countp, struct rman **rm, bus_space_tag_t *bst, vm_offset_t *va)
 {
-       int devid = pci_get_device(child);
-       int inst = pci_get_function(child);
-       int node = pci_get_slot(child) / 8;
-       int dev = pci_get_slot(child) % 8;
+       int devid, inst, node, unit;
+
+       devid = pci_get_device(child);
+       inst = pci_get_function(child);
+       node = pci_get_slot(child) / 8;
+       unit = device_get_unit(child);
 
        *rm = NULL;
        *va = 0;
        *bst = 0;
-       if (type == SYS_RES_IRQ) {
-               printf("%s: %d %d %d : start %d, end %d\n", __func__,
-                               node, dev, inst, (int)*startp, (int)*endp);
-       } else if (type == SYS_RES_MEMORY) {
+       if (type == SYS_RES_MEMORY) { 
                switch (devid) {
                case PCI_DEVICE_ID_NLM_UART:
                        *va = nlm_get_uart_regbase(node, inst);
-                       *startp = MIPS_KSEG1_TO_PHYS(va);
+                       *startp = MIPS_KSEG1_TO_PHYS(*va);
                        *countp = 0x100;
                        *rm = &emul_rman;
                        *bst = uart_bus_space_mem;
                        break;
                }
-
-       } else
+               /* calculate end if allocated */
+               if (*rm)
+                       *endp = *startp + *countp - 1;
+       } else if (type != SYS_RES_IRQ) {
+               /*
+                * IRQ allocation is done by route_interrupt,
+                * for any other request print warning.
+                */
                printf("Unknown type %d in req for [%x%x]\n",
                        type, devid, inst);
-       /* default to rmi_bus_space for SoC resources */
-       if (type == SYS_RES_MEMORY && *bst == 0)
-               *bst = rmi_bus_space;
+       }
 }
 
 static struct resource *
@@ -529,7 +559,7 @@ xlp_pci_alloc_resource(device_t bus, dev
                if (va == 0)
                        va = (vm_offset_t)pmap_mapdev(start, count);
                if (bst == 0)
-                       bst = rmi_pci_bus_space;
+                       bst = rmi_bus_space;
 
                rman_set_bushandle(rv, va);
                rman_set_virtual(rv, (void *)va);
@@ -590,7 +620,6 @@ mips_pci_route_interrupt(device_t bus, d
        if ((pin < 1) || (pin > 4))
                return (255);
 
-       device_printf(bus, "route  %s %d", device_get_nameunit(dev), pin);
        if (pci_get_bus(dev) == 0 &&
            pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC) {
                /* SoC devices */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to