Module Name:    src
Committed By:   jakllsch
Date:           Sat Nov 14 03:44:52 UTC 2015

Modified Files:
        src/sys/arch/arm/nvidia: tegra_pcie.c tegra_reg.h

Log Message:
Jetson TK1 u-boot sets up PCI IO space in an impossible-to-use
configuration.  As we're already allocating resources on the PCI
bus, set up our own mapping of PCI address spaces into the ARM
address space.  We rely on a potential overlap of address space
windows to allow us to use the same bus_space_tag for PCI Memory
and IO spaces.

The PCI attachment of the onboard re(4) uses PCI IO space in
preference to PCI Memory space for register accessses.  As IO space
was impossible to use, we had to avoid IO space.  This is now no
longer the case, so set up and enable IO space for PCI devices.

Also, map ROM BARs.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/nvidia/tegra_pcie.c
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/nvidia/tegra_reg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/nvidia/tegra_pcie.c
diff -u src/sys/arch/arm/nvidia/tegra_pcie.c:1.9 src/sys/arch/arm/nvidia/tegra_pcie.c:1.10
--- src/sys/arch/arm/nvidia/tegra_pcie.c:1.9	Sat Nov 14 02:10:10 2015
+++ src/sys/arch/arm/nvidia/tegra_pcie.c	Sat Nov 14 03:44:52 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_pcie.c,v 1.9 2015/11/14 02:10:10 jakllsch Exp $ */
+/* $NetBSD: tegra_pcie.c,v 1.10 2015/11/14 03:44:52 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.9 2015/11/14 02:10:10 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.10 2015/11/14 03:44:52 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -84,6 +84,7 @@ struct tegra_pcie_softc {
 static int	tegra_pcie_intr(void *);
 static void	tegra_pcie_init(pci_chipset_tag_t, void *);
 static void	tegra_pcie_enable(struct tegra_pcie_softc *);
+static void	tegra_pcie_setup(struct tegra_pcie_softc * const);
 
 static void	tegra_pcie_attach_hook(device_t, device_t,
 				       struct pcibus_attach_args *);
@@ -119,7 +120,7 @@ tegra_pcie_attach(device_t parent, devic
 	struct tegra_pcie_softc * const sc = device_private(self);
 	struct tegraio_attach_args * const tio = aux;
 	const struct tegra_locators * const loc = &tio->tio_loc;
-	struct extent *memext, *pmemext;
+	struct extent *ioext, *memext, *pmemext;
 	struct pcibus_attach_args pba;
 	int error;
 
@@ -156,8 +157,13 @@ tegra_pcie_attach(device_t parent, devic
 	}
 	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
 
+	tegra_pcie_setup(sc);
+
 	tegra_pcie_init(&sc->sc_pc, sc);
 
+	ioext = extent_create("pciio", TEGRA_PCIE_IO_BASE,
+	    TEGRA_PCIE_IO_BASE + TEGRA_PCIE_IO_SIZE - 1,
+	    NULL, 0, EX_NOWAIT);
 	memext = extent_create("pcimem", TEGRA_PCIE_MEM_BASE,
 	    TEGRA_PCIE_MEM_BASE + TEGRA_PCIE_MEM_SIZE - 1,
 	    NULL, 0, EX_NOWAIT);
@@ -165,9 +171,10 @@ tegra_pcie_attach(device_t parent, devic
 	    TEGRA_PCIE_PMEM_BASE + TEGRA_PCIE_PMEM_SIZE - 1,
 	    NULL, 0, EX_NOWAIT);
 
-	error = pci_configure_bus(&sc->sc_pc, NULL, memext, pmemext, 0,
+	error = pci_configure_bus(&sc->sc_pc, ioext, memext, pmemext, 0,
 	    arm_dcache_align);
 
+	extent_destroy(ioext);
 	extent_destroy(memext);
 	extent_destroy(pmemext);
 
@@ -183,7 +190,9 @@ tegra_pcie_attach(device_t parent, devic
 	pba.pba_flags = PCI_FLAGS_MRL_OKAY |
 			PCI_FLAGS_MRM_OKAY |
 			PCI_FLAGS_MWI_OKAY |
-			PCI_FLAGS_MEM_OKAY;
+			PCI_FLAGS_MEM_OKAY |
+			PCI_FLAGS_IO_OKAY;
+	pba.pba_iot = sc->sc_bst;
 	pba.pba_memt = sc->sc_bst;
 	pba.pba_dmat = sc->sc_dmat;
 	pba.pba_pc = &sc->sc_pc;
@@ -246,6 +255,65 @@ tegra_pcie_intr(void *priv)
 }
 
 static void
+tegra_pcie_setup(struct tegra_pcie_softc * const sc)
+{
+	size_t i;
+
+	/*
+	 * Map PCI address spaces into ARM address space via
+	 * HyperTransport-like "FPCI".
+	 */
+	static const struct { uint32_t size, base, fpci; } pcie_init_table[] = {
+		/*
+		 * === BEWARE ===
+		 *
+		 * We depend on our TEGRA_PCIE_IO window overlaping the
+		 * TEGRA_PCIE_A1 window to allow us to use the same
+		 * bus_space_tag for both PCI IO and Memory spaces.
+		 *
+		 * 0xfdfc000000-0xfdfdffffff is the FPCI/HyperTransport
+		 * mapping for 0x0000000-0x1ffffff of PCI IO space.
+		 */
+		{ TEGRA_PCIE_IO_SIZE >> 12, TEGRA_PCIE_IO_BASE,
+		  (0xfdfc000000 + TEGRA_PCIE_IO_BASE) >> 8 | 0, },
+
+		/* HyperTransport Technology Type 1 Address Format */
+		{ TEGRA_PCIE_CONF_SIZE >> 12, TEGRA_PCIE_CONF_BASE,
+		  0xfdff000000 >> 8 | 0, },
+
+		/* 1:1 MMIO mapping */
+		{ TEGRA_PCIE_MEM_SIZE >> 12, TEGRA_PCIE_MEM_BASE,
+		  TEGRA_PCIE_MEM_BASE >> 8 | 1, },
+
+		/* Extended HyperTransport Technology Type 1 Address Format */
+		{ TEGRA_PCIE_EXTC_SIZE >> 12, TEGRA_PCIE_EXTC_BASE,
+		  0xfe10000000 >> 8 | 0, },
+
+		/* 1:1 prefetchable MMIO mapping */
+		{ TEGRA_PCIE_PMEM_SIZE >> 12, TEGRA_PCIE_PMEM_BASE,
+		  TEGRA_PCIE_PMEM_BASE >> 8 | 1, },
+	};
+
+	for (i = 0; i < AFI_AXI_NBAR; i++) {
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi,
+		    AFI_AXI_BARi_SZ(i), 0);
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi,
+		    AFI_AXI_BARi_START(i), 0);
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi,
+		    AFI_FPCI_BARi(i), 0);
+	}
+
+	for (i = 0; i < __arraycount(pcie_init_table); i++) {
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi,
+		    AFI_AXI_BARi_START(i), pcie_init_table[i].base);
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi,
+		    AFI_FPCI_BARi(i), pcie_init_table[i].fpci);
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi,
+		    AFI_AXI_BARi_SZ(i), pcie_init_table[i].size);
+	}
+}
+
+static void
 tegra_pcie_enable(struct tegra_pcie_softc *sc)
 {
 	/* disable MSI */
@@ -374,7 +442,7 @@ tegra_pcie_conf_write(void *v, pcitag_t 
 static int
 tegra_pcie_conf_hook(void *v, int b, int d, int f, pcireg_t id)
 {
-	return PCI_CONF_ENABLE_MEM | PCI_CONF_MAP_MEM | PCI_CONF_ENABLE_BM;
+	return PCI_CONF_ALL;
 }
 
 static void

Index: src/sys/arch/arm/nvidia/tegra_reg.h
diff -u src/sys/arch/arm/nvidia/tegra_reg.h:1.16 src/sys/arch/arm/nvidia/tegra_reg.h:1.17
--- src/sys/arch/arm/nvidia/tegra_reg.h:1.16	Sat Nov 14 02:10:10 2015
+++ src/sys/arch/arm/nvidia/tegra_reg.h	Sat Nov 14 03:44:52 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_reg.h,v 1.16 2015/11/14 02:10:10 jakllsch Exp $ */
+/* $NetBSD: tegra_reg.h,v 1.17 2015/11/14 03:44:52 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -50,10 +50,12 @@
 
 #define TEGRA_PCIE_CONF_BASE	0x02000000
 #define TEGRA_PCIE_CONF_SIZE	0x01000000
-#define TEGRA_PCIE_IO_BASE	0x12000000
-#define TEGRA_PCIE_IO_SIZE	0x00010000
-#define TEGRA_PCIE_MEM_BASE	0x13000000
+#define TEGRA_PCIE_IO_BASE	0x01800000	/* comment in tegra_pcie.c */
+#define TEGRA_PCIE_IO_SIZE	0x00800000
+#define TEGRA_PCIE_MEM_BASE	0x03000000
 #define TEGRA_PCIE_MEM_SIZE	0x0d000000
+#define TEGRA_PCIE_EXTC_BASE	0x10000000
+#define TEGRA_PCIE_EXTC_SIZE	0x10000000
 #define TEGRA_PCIE_PMEM_BASE	0x20000000
 #define TEGRA_PCIE_PMEM_SIZE	0x20000000
 

Reply via email to