Date: Mon, 27 Sep 2010 20:12:57 +0000 (UTC) From: Juli Mallett <jmallett@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r213228 - head/sys/mips/cavium Message-ID: <201009272012.o8RKCvvF048632@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009272012.o8RKCvvF048632>