From owner-svn-src-head@freebsd.org Tue Apr 3 21:25:16 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1ACB8F81E8D; Tue, 3 Apr 2018 21:25:16 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E37F075CD6; Tue, 3 Apr 2018 21:25:15 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DE643212A; Tue, 3 Apr 2018 21:25:15 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w33LPF4p040445; Tue, 3 Apr 2018 21:25:15 GMT (envelope-from mw@FreeBSD.org) Received: (from mw@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w33LPFIK040441; Tue, 3 Apr 2018 21:25:15 GMT (envelope-from mw@FreeBSD.org) Message-Id: <201804032125.w33LPFIK040441@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mw set sender to mw@FreeBSD.org using -f From: Marcin Wojtas Date: Tue, 3 Apr 2018 21:25:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331953 - head/sys/arm/mv X-SVN-Group: head X-SVN-Commit-Author: mw X-SVN-Commit-Paths: head/sys/arm/mv X-SVN-Commit-Revision: 331953 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Apr 2018 21:25:16 -0000 Author: mw Date: Tue Apr 3 21:25:15 2018 New Revision: 331953 URL: https://svnweb.freebsd.org/changeset/base/331953 Log: Make Marvell mv_pci.c driver generic PCI ports differ between Marvell SoCs, but have the same compatible in FDT. Identification is made based on parent compatible during attach. For ArmadaXP skipping enable procedure is necessary. To achieve it sc_skip_enable_procedure flag is used. For Armada38x find root procedure is necessary. For other SoCs root link is always at slot 0. sc_enable_find_root_slot flag is used to select proper behaviour. Marvell armv5 platforms does not support msi. Submitted by: Rafal Kozik Reviewed by: andrew Obtained from: Semihalf Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D14735 Modified: head/sys/arm/mv/mv_pci.c head/sys/arm/mv/mvwin.h Modified: head/sys/arm/mv/mv_pci.c ============================================================================== --- head/sys/arm/mv/mv_pci.c Tue Apr 3 21:22:43 2018 (r331952) +++ head/sys/arm/mv/mv_pci.c Tue Apr 3 21:25:15 2018 (r331953) @@ -308,6 +308,9 @@ struct mv_pcib_softc { int sc_type; int sc_mode; /* Endpoint / Root Complex */ + int sc_msi_supported; + int sc_skip_enable_procedure; + int sc_enable_find_root_slot; struct ofw_bus_iinfo sc_pci_iinfo; }; @@ -341,11 +344,10 @@ static uint32_t mv_pcib_read_config(device_t, u_int, u static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int, uint32_t, int); static int mv_pcib_route_interrupt(device_t, device_t, int); -#if defined(SOC_MV_ARMADAXP) + static int mv_pcib_alloc_msi(device_t, device_t, int, int, int *); static int mv_pcib_map_msi(device_t, device_t, int, uint64_t *, uint32_t *); static int mv_pcib_release_msi(device_t, device_t, int, int *); -#endif /* * Bus interface definitions. @@ -371,11 +373,10 @@ static device_method_t mv_pcib_methods[] = { DEVMETHOD(pcib_write_config, mv_pcib_write_config), DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt), DEVMETHOD(pcib_request_feature, pcib_request_feature_allow), -#if defined(SOC_MV_ARMADAXP) + DEVMETHOD(pcib_alloc_msi, mv_pcib_alloc_msi), DEVMETHOD(pcib_release_msi, mv_pcib_release_msi), DEVMETHOD(pcib_map_msi, mv_pcib_map_msi), -#endif /* OFW bus interface */ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), @@ -442,9 +443,19 @@ mv_pcib_attach(device_t self) if (ofw_bus_node_is_compatible(node, "mrvl,pcie")) { sc->sc_type = MV_TYPE_PCIE; - sc->sc_win_target = MV_WIN_PCIE_TARGET(port_id); - sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(port_id); - sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(port_id); + if (ofw_bus_node_is_compatible(parnode, "marvell,armada-370-pcie")) { + sc->sc_win_target = MV_WIN_PCIE_TARGET_ARMADA38X(port_id); + sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR_ARMADA38X(port_id); + sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR_ARMADA38X(port_id); + sc->sc_enable_find_root_slot = 1; + } else { + sc->sc_win_target = MV_WIN_PCIE_TARGET(port_id); + sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(port_id); + sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(port_id); +#if __ARM_ARCH >= 6 + sc->sc_skip_enable_procedure = 1; +#endif + } } else if (ofw_bus_node_is_compatible(node, "mrvl,pci")) { sc->sc_type = MV_TYPE_PCI; sc->sc_win_target = MV_WIN_PCI_TARGET; @@ -541,9 +552,11 @@ static void mv_pcib_enable(struct mv_pcib_softc *sc, uint32_t unit) { uint32_t val; -#if !defined(SOC_MV_ARMADAXP) int timeout; + if (sc->sc_skip_enable_procedure) + goto pcib_enable_root_mode; + /* * Check if PCIE device is enabled. */ @@ -561,9 +574,8 @@ mv_pcib_enable(struct mv_pcib_softc *sc, uint32_t unit PCIE_REG_STATUS); } } -#endif - +pcib_enable_root_mode: if (sc->sc_mode == MV_MODE_ROOT) { /* * Enable PCI bridge. @@ -1042,20 +1054,19 @@ mv_pcib_maxslots(device_t dev) static int mv_pcib_root_slot(device_t dev, u_int bus, u_int slot, u_int func) { -#if defined(SOC_MV_ARMADA38X) struct mv_pcib_softc *sc = device_get_softc(dev); uint32_t vendor, device; +/* On platforms other than Armada38x, root link is always at slot 0 */ + if (!sc->sc_enable_find_root_slot) + return (slot == 0); + vendor = mv_pcib_hw_cfgread(sc, bus, slot, func, PCIR_VENDOR, PCIR_VENDOR_LENGTH); device = mv_pcib_hw_cfgread(sc, bus, slot, func, PCIR_DEVICE, PCIR_DEVICE_LENGTH) & MV_DEV_FAMILY_MASK; return (vendor == PCI_VENDORID_MRVL && device == MV_DEV_ARMADA38X); -#else - /* On platforms other than Armada38x, root link is always at slot 0 */ - return (slot == 0); -#endif } static uint32_t @@ -1159,7 +1170,6 @@ mv_pcib_decode_win(phandle_t node, struct mv_pcib_soft return (0); } -#if defined(SOC_MV_ARMADAXP) static int mv_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr, uint32_t *data) @@ -1167,6 +1177,9 @@ mv_pcib_map_msi(device_t dev, device_t child, int irq, struct mv_pcib_softc *sc; sc = device_get_softc(dev); + if (!sc->sc_msi_supported) + return (ENOTSUP); + irq = irq - MSI_IRQ; /* validate parameters */ @@ -1175,7 +1188,9 @@ mv_pcib_map_msi(device_t dev, device_t child, int irq, return (EINVAL); } +#if __ARM_ARCH >= 6 mv_msi_data(irq, addr, data); +#endif debugf("%s: irq: %d addr: %jx data: %x\n", __func__, irq, *addr, *data); @@ -1190,10 +1205,13 @@ mv_pcib_alloc_msi(device_t dev, device_t child, int co struct mv_pcib_softc *sc; u_int start = 0, i; + sc = device_get_softc(dev); + if (!sc->sc_msi_supported) + return (ENOTSUP); + if (powerof2(count) == 0 || count > MSI_IRQ_NUM) return (EINVAL); - sc = device_get_softc(dev); mtx_lock(&sc->sc_msi_mtx); for (start = 0; (start + count) < MSI_IRQ_NUM; start++) { @@ -1227,6 +1245,9 @@ mv_pcib_release_msi(device_t dev, device_t child, int u_int i; sc = device_get_softc(dev); + if(!sc->sc_msi_supported) + return (ENOTSUP); + mtx_lock(&sc->sc_msi_mtx); for (i = 0; i < count; i++) @@ -1235,5 +1256,3 @@ mv_pcib_release_msi(device_t dev, device_t child, int mtx_unlock(&sc->sc_msi_mtx); return (0); } -#endif - Modified: head/sys/arm/mv/mvwin.h ============================================================================== --- head/sys/arm/mv/mvwin.h Tue Apr 3 21:22:43 2018 (r331952) +++ head/sys/arm/mv/mvwin.h Tue Apr 3 21:25:15 2018 (r331953) @@ -64,12 +64,8 @@ #define MV_PCI_PORTS 1 /* 1x PCIE */ #elif defined(SOC_MV_DISCOVERY) #define MV_PCI_PORTS 8 /* 8x PCIE */ -#elif defined(SOC_MV_ARMADAXP) -#define MV_PCI_PORTS 3 /* 3x PCIE */ -#elif defined(SOC_MV_ARMADA38X) -#define MV_PCI_PORTS 4 /* 4x PCIE */ #else -#error "MV_PCI_PORTS not configured !" +#define MV_PCI_PORTS 1 /* 1x PCIE -> worst case */ #endif /* PCI/PCIE Memory */ @@ -77,15 +73,11 @@ #define MV_PCI_MEM_SIZE (512 * 1024 * 1024) /* 512 MB */ #define MV_PCI_MEM_BASE MV_PCI_MEM_PHYS_BASE #define MV_PCI_MEM_SLICE_SIZE (MV_PCI_MEM_SIZE / MV_PCI_PORTS) -#define MV_PCI_MEM_SLICE(n) (MV_PCI_MEM_BASE + ((n) * \ - MV_PCI_MEM_SLICE_SIZE)) /* PCI/PCIE I/O */ #define MV_PCI_IO_PHYS_BASE 0xBF000000 #define MV_PCI_IO_SIZE (16 * 1024 * 1024) /* 16 MB */ #define MV_PCI_IO_BASE MV_PCI_IO_PHYS_BASE #define MV_PCI_IO_SLICE_SIZE (MV_PCI_IO_SIZE / MV_PCI_PORTS) -#define MV_PCI_IO_SLICE(n) (MV_PCI_IO_BASE + ((n) * MV_PCI_IO_SLICE_SIZE)) - #define MV_PCI_VA_MEM_BASE 0 #define MV_PCI_VA_IO_BASE 0 @@ -131,22 +123,9 @@ #define MV_PCI_BASE (MV_BASE + 0x30000) #define MV_PCI_SIZE 0x2000 -#if defined(SOC_MV_ARMADA38X) -#define MV_PCIE_BASE (MV_BASE + 0x80000) -#else +#define MV_PCIE_BASE_ARMADA38X (MV_BASE + 0x80000) #define MV_PCIE_BASE (MV_BASE + 0x40000) -#endif #define MV_PCIE_SIZE 0x2000 - -#define MV_PCIE00_BASE (MV_PCIE_BASE + 0x00000) -#define MV_PCIE01_BASE (MV_PCIE_BASE + 0x04000) -#define MV_PCIE02_BASE (MV_PCIE_BASE + 0x08000) -#define MV_PCIE03_BASE (MV_PCIE_BASE + 0x0C000) -#define MV_PCIE10_BASE (MV_PCIE_BASE + 0x40000) -#define MV_PCIE11_BASE (MV_PCIE_BASE + 0x44000) -#define MV_PCIE12_BASE (MV_PCIE_BASE + 0x48000) -#define MV_PCIE13_BASE (MV_PCIE_BASE + 0x4C000) - #define MV_SDIO_BASE (MV_BASE + 0x90000) #define MV_SDIO_SIZE 0x10000 @@ -255,22 +234,24 @@ #define MV_XOR_CHAN_MAX 2 #define MV_XOR_NON_REMAP 4 +#define MV_WIN_PCIE_TARGET_ARMADAXP(n) (4 + (4 * ((n) % 2))) +#define MV_WIN_PCIE_MEM_ATTR_ARMADAXP(n) (0xE8 + (0x10 * ((n) / 2))) +#define MV_WIN_PCIE_IO_ATTR_ARMADAXP(n) (0xE0 + (0x10 * ((n) / 2))) +#define MV_WIN_PCIE_TARGET_ARMADA38X(n) ((n) == 0 ? 8 : 4) +#define MV_WIN_PCIE_MEM_ATTR_ARMADA38X(n) ((n) < 2 ? 0xE8 : (0xD8 - (((n) % 2) * 0x20))) +#define MV_WIN_PCIE_IO_ATTR_ARMADA38X(n) ((n) < 2 ? 0xE0 : (0xD0 - (((n) % 2) * 0x20))) #if defined(SOC_MV_DISCOVERY) || defined(SOC_MV_KIRKWOOD) #define MV_WIN_PCIE_TARGET(n) 4 #define MV_WIN_PCIE_MEM_ATTR(n) 0xE8 #define MV_WIN_PCIE_IO_ATTR(n) 0xE0 -#elif defined(SOC_MV_ARMADAXP) -#define MV_WIN_PCIE_TARGET(n) (4 + (4 * ((n) % 2))) -#define MV_WIN_PCIE_MEM_ATTR(n) (0xE8 + (0x10 * ((n) / 2))) -#define MV_WIN_PCIE_IO_ATTR(n) (0xE0 + (0x10 * ((n) / 2))) -#elif defined(SOC_MV_ARMADA38X) -#define MV_WIN_PCIE_TARGET(n) ((n) == 0 ? 8 : 4) -#define MV_WIN_PCIE_MEM_ATTR(n) ((n) < 2 ? 0xE8 : (0xD8 - (((n) % 2) * 0x20))) -#define MV_WIN_PCIE_IO_ATTR(n) ((n) < 2 ? 0xE0 : (0xD0 - (((n) % 2) * 0x20))) #elif defined(SOC_MV_ORION) #define MV_WIN_PCIE_TARGET(n) 4 #define MV_WIN_PCIE_MEM_ATTR(n) 0x59 #define MV_WIN_PCIE_IO_ATTR(n) 0x51 +#else +#define MV_WIN_PCIE_TARGET(n) (4 + (4 * ((n) % 2))) +#define MV_WIN_PCIE_MEM_ATTR(n) (0xE8 + (0x10 * ((n) / 2))) +#define MV_WIN_PCIE_IO_ATTR(n) (0xE0 + (0x10 * ((n) / 2))) #endif #define MV_WIN_PCI_TARGET 3