From owner-svn-src-all@FreeBSD.ORG Tue Mar 27 07:57:41 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id ED0471065677; Tue, 27 Mar 2012 07:57:41 +0000 (UTC) (envelope-from jchandra@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D74108FC17; Tue, 27 Mar 2012 07:57:41 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q2R7vf4N075861; Tue, 27 Mar 2012 07:57:41 GMT (envelope-from jchandra@svn.freebsd.org) Received: (from jchandra@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q2R7vfEG075857; Tue, 27 Mar 2012 07:57:41 GMT (envelope-from jchandra@svn.freebsd.org) Message-Id: <201203270757.q2R7vfEG075857@svn.freebsd.org> From: "Jayachandran C." Date: Tue, 27 Mar 2012 07:57:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233536 - in head/sys/mips/nlm: . hal X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Mar 2012 07:57:42 -0000 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 #include #include +#include #include #include #include @@ -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 */