Author: jmallett
Date: Mon Sep 27 20:12:57 2010
New Revision: 213228
URL: http://svn.freebsd.org/changeset/base/213228

Log:
  o) Program the Lanner MR-320 for 32-bit mode, too.
  o) Give a virtual address for I/O ports on n64.
  o) On the Portwell CAM-0100, return the right IRQ for the on-board SATA.
  o) Except on bridges, only set PORTEN and MEMEN on devices that have I/O or
     memory BARs respectively.
  o) Disable PORTEN and MEMEN while reprogramming BARs.
  o) On the Lanner MR-955, set the Tx DMA power register for the on-board 
Promise
     SATA controller.

Modified:
  head/sys/mips/cavium/octopci.c

Modified: head/sys/mips/cavium/octopci.c
==============================================================================
--- head/sys/mips/cavium/octopci.c      Mon Sep 27 19:45:34 2010        
(r213227)
+++ head/sys/mips/cavium/octopci.c      Mon Sep 27 20:12:57 2010        
(r213228)
@@ -92,7 +92,7 @@ static void   octopci_write_config(device_
                                     uint32_t, int);
 static int     octopci_route_interrupt(device_t, device_t, int);
 
-static void    octopci_init_bar(device_t, unsigned, unsigned, unsigned, 
unsigned);
+static void    octopci_init_bar(device_t, unsigned, unsigned, unsigned, 
unsigned, uint8_t *);
 static unsigned        octopci_init_device(device_t, unsigned, unsigned, 
unsigned, unsigned);
 static unsigned        octopci_init_bus(device_t, unsigned);
 static uint64_t        octopci_cs_addr(unsigned, unsigned, unsigned, unsigned);
@@ -148,6 +148,7 @@ octopci_attach(device_t dev)
         */
        switch (cvmx_sysinfo_get()->board_type) {
 #if defined(OCTEON_VENDOR_LANNER)
+       case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
        case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
                /* 32-bit PCI-X */
                cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x0);
@@ -422,14 +423,14 @@ octopci_alloc_resource(device_t bus, dev
                break;
        case SYS_RES_IOPORT:
                rman_set_bushandle(res, 
CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_PCI, CVMX_OCT_SUBDID_PCI_IO)) + 
rman_get_start(res));
+#if __mips_n64
+               rman_set_virtual(res, (void *)rman_get_bushandle(res));
+#else
                /*
                 * XXX
-                * We should just disallow use of io ports on !n64 since without
-                * 64-bit PTEs we can't even do a 32-bit virtual address
-                * mapped to them.
+                * We can't access ports via a 32-bit pointer.
                 */
-#if 0
-               rman_set_virtual(res, (void *)rman_get_bushandle(res));
+               rman_set_virtual(res, NULL);
 #endif
                break;
        }
@@ -549,8 +550,19 @@ octopci_route_interrupt(device_t dev, de
         slot = pci_get_slot(child);
         func = pci_get_function(child);
 
-#if defined(OCTEON_VENDOR_LANNER)
+       /*
+        * Board types we have to know at compile-time.
+        */
+#if defined(OCTEON_BOARD_CAPK_0100ND)
+       if (bus == 0 && slot == 12 && func == 0)
+               return (CVMX_IRQ_PCI_INT2);
+#endif
+
+       /*
+        * For board types we can determine at runtime.
+        */
        switch (cvmx_sysinfo_get()->board_type) {
+#if defined(OCTEON_VENDOR_LANNER)
        case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
                return (CVMX_IRQ_PCI_INT0 + pin - 1);
        case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
@@ -562,10 +574,10 @@ octopci_route_interrupt(device_t dev, de
                        return (CVMX_IRQ_PCI_INT0 + (irq & 3));
                }
                break;
+#endif
        default:
                break;
        }
-#endif
 
        irq = slot + pin - 3;
 
@@ -573,7 +585,7 @@ octopci_route_interrupt(device_t dev, de
 }
 
 static void
-octopci_init_bar(device_t dev, unsigned b, unsigned s, unsigned f, unsigned 
barnum)
+octopci_init_bar(device_t dev, unsigned b, unsigned s, unsigned f, unsigned 
barnum, uint8_t *commandp)
 {
        struct octopci_softc *sc;
        uint32_t bar;
@@ -603,6 +615,11 @@ octopci_init_bar(device_t dev, unsigned 
                octopci_write_config(dev, b, s, f, PCIR_BAR(barnum),
                    CVMX_OCT_PCI_IO_BASE + sc->sc_io_next, 4);
                sc->sc_io_next += size;
+
+               /*
+                * Enable I/O ports.
+                */
+               *commandp |= PCIM_CMD_PORTEN;
        } else {
                size = ~(bar & (uint32_t)PCIM_BAR_MEM_BASE) + 1;
 
@@ -615,6 +632,11 @@ octopci_init_bar(device_t dev, unsigned 
                octopci_write_config(dev, b, s, f, PCIR_BAR(barnum),
                    CVMX_OCT_PCI_MEM1_BASE + sc->sc_mem1_next, 4);
                sc->sc_mem1_next += size;
+
+               /*
+                * Enable memory access.
+                */
+               *commandp |= PCIM_CMD_MEMEN;
        }
 }
 
@@ -630,6 +652,13 @@ octopci_init_device(device_t dev, unsign
        /* Read header type (again.)  */
        hdrtype = octopci_read_config(dev, b, s, f, PCIR_HDRTYPE, 1);
 
+       /*
+        * Disable memory and I/O while programming BARs.
+        */
+       command = octopci_read_config(dev, b, s, f, PCIR_COMMAND, 1);
+       command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
+       octopci_write_config(dev, b, s, f, PCIR_COMMAND, command, 1);
+
        /* Program BARs.  */
        switch (hdrtype & PCIM_HDRTYPE) {
        case PCIM_HDRTYPE_NORMAL:
@@ -648,14 +677,12 @@ octopci_init_device(device_t dev, unsign
        }
 
        for (barnum = 0; barnum < bars; barnum++)
-               octopci_init_bar(dev, b, s, f, barnum);
-
-       /* Enable memory and I/O.  */
-       command = octopci_read_config(dev, b, s, f, PCIR_COMMAND, 1);
-       command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
+               octopci_init_bar(dev, b, s, f, barnum, &command);
 
        /* Enable bus mastering.  */
        command |= PCIM_CMD_BUSMASTEREN;
+
+       /* Enable whatever facilities the BARs require.  */
        octopci_write_config(dev, b, s, f, PCIR_COMMAND, command, 1);
 
        /* 
@@ -668,6 +695,38 @@ octopci_init_device(device_t dev, unsign
        /* Set latency timer.  */
        octopci_write_config(dev, b, s, f, PCIR_LATTIMER, 48, 1);
 
+       /* Board-specific or device-specific fixups and workarounds.  */
+       switch (cvmx_sysinfo_get()->board_type) {
+#if defined(OCTEON_VENDOR_LANNER)
+       case CVMX_BOARD_TYPE_CUST_LANNER_MR955:
+               if (b == 1 && s == 7 && f == 0) {
+                       bus_addr_t busaddr, unitbusaddr;
+                       uint32_t bar;
+                       uint32_t tmp;
+                       unsigned unit;
+
+                       /*
+                        * Set Tx DMA power.
+                        */
+                       bar = octopci_read_config(dev, b, s, f,
+                           PCIR_BAR(3), 4);
+                       busaddr = CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_PCI,
+                           CVMX_OCT_SUBDID_PCI_MEM1));
+                       busaddr += (bar & (uint32_t)PCIM_BAR_MEM_BASE);
+                       for (unit = 0; unit < 4; unit++) {
+                               unitbusaddr = busaddr + 0x430 + (unit << 8);
+                               tmp = le32toh(cvmx_read64_uint32(unitbusaddr));
+                               tmp &= ~0x700;
+                               tmp |= 0x300;
+                               cvmx_write64_uint32(unitbusaddr, htole32(tmp));
+                       }
+               }
+               break;
+#endif
+       default:
+               break;
+       }
+
        /* Configure PCI-PCI bridges.  */
        class = octopci_read_config(dev, b, s, f, PCIR_CLASS, 1);
        if (class != PCIC_BRIDGE)
@@ -677,6 +736,10 @@ octopci_init_device(device_t dev, unsign
        if (subclass != PCIS_BRIDGE_PCI)
                return (secbus);
 
+       /* Enable memory and I/O access.  */
+       command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
+       octopci_write_config(dev, b, s, f, PCIR_COMMAND, command, 1);
+
        /* Enable errors and parity checking.  Do a bus reset.  */
        brctl = octopci_read_config(dev, b, s, f, PCIR_BRIDGECTL_1, 1);
        brctl |= PCIB_BCR_PERR_ENABLE | PCIB_BCR_SERR_ENABLE;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to