Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/nvidia Jetson TK1 u-boot sets up PCI IO space i...



details:   https://anonhg.NetBSD.org/src/rev/e5710c294068
branches:  trunk
changeset: 811765:e5710c294068
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Sat Nov 14 03:44:52 2015 +0000

description:
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.

diffstat:

 sys/arch/arm/nvidia/tegra_pcie.c |  80 +++++++++++++++++++++++++++++++++++++---
 sys/arch/arm/nvidia/tegra_reg.h  |  10 +++--
 2 files changed, 80 insertions(+), 10 deletions(-)

diffs (172 lines):

diff -r f578f99a163f -r e5710c294068 sys/arch/arm/nvidia/tegra_pcie.c
--- a/sys/arch/arm/nvidia/tegra_pcie.c  Sat Nov 14 03:25:53 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_pcie.c  Sat Nov 14 03:44:52 2015 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 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 @@
        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 @@
        }
        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_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 @@
        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 @@
 }
 
 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 @@
 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
diff -r f578f99a163f -r e5710c294068 sys/arch/arm/nvidia/tegra_reg.h
--- a/sys/arch/arm/nvidia/tegra_reg.h   Sat Nov 14 03:25:53 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_reg.h   Sat Nov 14 03:44:52 2015 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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
 



Home | Main Index | Thread Index | Old Index