Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Add Tegra K1 PCIE support.
details: https://anonhg.NetBSD.org/src/rev/7f40b41cfc81
branches: trunk
changeset: 337901:7f40b41cfc81
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun May 03 01:07:44 2015 +0000
description:
Add Tegra K1 PCIE support.
diffstat:
sys/arch/arm/nvidia/files.tegra | 7 +-
sys/arch/arm/nvidia/tegra_intr.h | 5 +-
sys/arch/arm/nvidia/tegra_io.c | 12 +-
sys/arch/arm/nvidia/tegra_pcie.c | 405 ++++++++++++++++++++++++++++++++++
sys/arch/arm/nvidia/tegra_pciereg.h | 45 +++
sys/arch/arm/nvidia/tegra_reg.h | 20 +-
sys/arch/arm/nvidia/tegra_soc.c | 26 ++-
sys/arch/arm/nvidia/tegra_var.h | 5 +-
sys/arch/evbarm/conf/JETSONTK1 | 15 +-
sys/arch/evbarm/conf/std.tegra | 4 +-
sys/arch/evbarm/tegra/tegra_machdep.c | 7 +-
11 files changed, 538 insertions(+), 13 deletions(-)
diffs (truncated from 748 to 300 lines):
diff -r 943d4ee1622e -r 7f40b41cfc81 sys/arch/arm/nvidia/files.tegra
--- a/sys/arch/arm/nvidia/files.tegra Sun May 03 00:04:06 2015 +0000
+++ b/sys/arch/arm/nvidia/files.tegra Sun May 03 01:07:44 2015 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.tegra,v 1.5 2015/05/02 17:15:20 jmcneill Exp $
+# $NetBSD: files.tegra,v 1.6 2015/05/03 01:07:44 jmcneill Exp $
#
# Configuration info for NVIDIA Tegra ARM Peripherals
#
@@ -53,6 +53,11 @@
attach sdhc at tegraio with tegra_sdhc
file arch/arm/nvidia/tegra_sdhc.c tegra_sdhc
+# PCIE
+device tegrapcie: pcibus
+attach tegrapcie at tegraio with tegra_pcie
+file arch/arm/nvidia/tegra_pcie.c tegra_pcie
+
# SATA
attach ahcisata at tegraio with tegra_ahcisata
file arch/arm/nvidia/tegra_ahcisata.c tegra_ahcisata
diff -r 943d4ee1622e -r 7f40b41cfc81 sys/arch/arm/nvidia/tegra_intr.h
--- a/sys/arch/arm/nvidia/tegra_intr.h Sun May 03 00:04:06 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_intr.h Sun May 03 01:07:44 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_intr.h,v 1.2 2015/03/29 10:44:54 jmcneill Exp $ */
+/* $NetBSD: tegra_intr.h,v 1.3 2015/05/03 01:07:44 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -50,5 +50,8 @@
#define TEGRA_INTR_HDA TEGRA_INTR(81)
#define TEGRA_INTR_UARTD TEGRA_INTR(90)
#define TEGRA_INTR_USB3 TEGRA_INTR(97)
+#define TEGRA_INTR_PCIE_INT TEGRA_INTR(98)
+#define TEGRA_INTR_PCIE_MSI TEGRA_INTR(99)
+#define TEGRA_INTR_PCIE_WAKE TEGRA_INTR(100)
#endif /* _ARM_TEGRA_INTR_H */
diff -r 943d4ee1622e -r 7f40b41cfc81 sys/arch/arm/nvidia/tegra_io.c
--- a/sys/arch/arm/nvidia/tegra_io.c Sun May 03 00:04:06 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_io.c Sun May 03 01:07:44 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_io.c,v 1.4 2015/05/02 12:08:32 jmcneill Exp $ */
+/* $NetBSD: tegra_io.c,v 1.5 2015/05/03 01:07:44 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_tegra.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.4 2015/05/02 12:08:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.5 2015/05/03 01:07:44 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -104,6 +104,11 @@
TEGRA_USB3_OFFSET, TEGRA_USB3_SIZE, 2, TEGRA_INTR_USB3 },
};
+static const struct tegra_locators tegra_pcie_locators[] = {
+ { "tegrapcie",
+ TEGRA_PCIE_OFFSET, TEGRA_PCIE_SIZE, NOPORT, TEGRA_INTR_PCIE_INT },
+};
+
int
tegraio_match(device_t parent, cfdata_t cf, void *aux)
{
@@ -126,6 +131,8 @@
tegra_apb_locators, __arraycount(tegra_apb_locators));
tegraio_scan(self, tegra_ahb_a2_bsh,
tegra_ahb_a2_locators, __arraycount(tegra_ahb_a2_locators));
+ tegraio_scan(self, (bus_space_handle_t)NULL,
+ tegra_pcie_locators, __arraycount(tegra_pcie_locators));
}
static void
@@ -140,6 +147,7 @@
.tio_a4x_bst = &armv7_generic_a4x_bs_tag,
.tio_bsh = bsh,
.tio_dmat = &tegra_dma_tag,
+ .tio_coherent_dmat = &tegra_coherent_dma_tag,
};
cfdata_t cf = config_search_ia(tegraio_find, self,
"tegraio", &tio);
diff -r 943d4ee1622e -r 7f40b41cfc81 sys/arch/arm/nvidia/tegra_pcie.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_pcie.c Sun May 03 01:07:44 2015 +0000
@@ -0,0 +1,405 @@
+/* $NetBSD: tegra_pcie.c,v 1.1 2015/05/03 01:07:44 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "locators.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.1 2015/05/03 01:07:44 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/extent.h>
+#include <sys/queue.h>
+#include <sys/mutex.h>
+#include <sys/kmem.h>
+
+#include <arm/cpufunc.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pciconf.h>
+
+#include <arm/nvidia/tegra_reg.h>
+#include <arm/nvidia/tegra_pciereg.h>
+#include <arm/nvidia/tegra_var.h>
+
+static int tegra_pcie_match(device_t, cfdata_t, void *);
+static void tegra_pcie_attach(device_t, device_t, void *);
+
+struct tegra_pcie_ih {
+ int (*ih_callback)(void *);
+ void *ih_arg;
+ int ih_ipl;
+ TAILQ_ENTRY(tegra_pcie_ih) ih_entry;
+};
+
+struct tegra_pcie_softc {
+ device_t sc_dev;
+ bus_dma_tag_t sc_dmat;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh_afi;
+ bus_space_handle_t sc_bsh_a1;
+ bus_space_handle_t sc_bsh_a2;
+ int sc_intr;
+
+ struct arm32_pci_chipset sc_pc;
+
+ void *sc_ih;
+
+ kmutex_t sc_lock;
+
+ TAILQ_HEAD(, tegra_pcie_ih) sc_intrs;
+ u_int sc_intrgen;
+};
+
+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_attach_hook(device_t, device_t,
+ struct pcibus_attach_args *);
+static int tegra_pcie_bus_maxdevs(void *, int);
+static pcitag_t tegra_pcie_make_tag(void *, int, int, int);
+static void tegra_pcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
+static pcireg_t tegra_pcie_conf_read(void *, pcitag_t, int);
+static void tegra_pcie_conf_write(void *, pcitag_t, int, pcireg_t);
+static int tegra_pcie_conf_hook(void *, int, int, int, pcireg_t);
+static void tegra_pcie_conf_interrupt(void *, int, int, int, int, int *);
+
+static int tegra_pcie_intr_map(const struct pci_attach_args *,
+ pci_intr_handle_t *);
+static const char *tegra_pcie_intr_string(void *, pci_intr_handle_t,
+ char *, size_t);
+const struct evcnt *tegra_pcie_intr_evcnt(void *, pci_intr_handle_t);
+static void * tegra_pcie_intr_establish(void *, pci_intr_handle_t,
+ int, int (*)(void *), void *);
+static void tegra_pcie_intr_disestablish(void *, void *);
+
+CFATTACH_DECL_NEW(tegra_pcie, sizeof(struct tegra_pcie_softc),
+ tegra_pcie_match, tegra_pcie_attach, NULL, NULL);
+
+static int
+tegra_pcie_match(device_t parent, cfdata_t cf, void *aux)
+{
+ return 1;
+}
+
+static void
+tegra_pcie_attach(device_t parent, device_t self, void *aux)
+{
+ 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 pcibus_attach_args pba;
+ int error;
+
+ sc->sc_dev = self;
+ sc->sc_dmat = tio->tio_coherent_dmat;
+ sc->sc_bst = tio->tio_bst;
+ sc->sc_intr = loc->loc_intr;
+ if (bus_space_map(sc->sc_bst, TEGRA_PCIE_AFI_BASE, TEGRA_PCIE_AFI_SIZE,
+ 0, &sc->sc_bsh_afi) != 0)
+ panic("couldn't map PCIE AFI");
+ if (bus_space_map(sc->sc_bst, TEGRA_PCIE_A1_BASE, TEGRA_PCIE_A1_SIZE,
+ 0, &sc->sc_bsh_a1) != 0)
+ panic("couldn't map PCIE A1");
+ if (bus_space_map(sc->sc_bst, TEGRA_PCIE_A2_BASE, TEGRA_PCIE_A2_SIZE,
+ 0, &sc->sc_bsh_a2) != 0)
+ panic("couldn't map PCIE A2");
+
+ TAILQ_INIT(&sc->sc_intrs);
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
+
+ aprint_naive("\n");
+ aprint_normal(": PCIE\n");
+
+ sc->sc_ih = intr_establish(loc->loc_intr, IPL_VM, IST_LEVEL,
+ tegra_pcie_intr, sc);
+ if (sc->sc_ih == NULL) {
+ aprint_error_dev(self, "failed to establish interrupt %d\n",
+ loc->loc_intr);
+ return;
+ }
+ aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+
+ tegra_pcie_init(&sc->sc_pc, sc);
+
+ memext = extent_create("pcimem", TEGRA_PCIE_MEM_BASE,
+ TEGRA_PCIE_MEM_BASE + TEGRA_PCIE_MEM_SIZE - 1,
+ NULL, 0, EX_NOWAIT);
+ pmemext = extent_create("pcipmem", TEGRA_PCIE_PMEM_BASE,
+ TEGRA_PCIE_PMEM_BASE + TEGRA_PCIE_PMEM_SIZE - 1,
+ NULL, 0, EX_NOWAIT);
+
+ error = pci_configure_bus(&sc->sc_pc, NULL, memext, pmemext, 0,
+ arm_dcache_align);
+
+ extent_destroy(memext);
+ extent_destroy(pmemext);
+
+ if (error) {
+ aprint_error_dev(self, "configuration failed (%d)\n",
+ error);
+ return;
+ }
+
+ tegra_pcie_enable(sc);
+
+ memset(&pba, 0, sizeof(pba));
+ pba.pba_flags = PCI_FLAGS_MRL_OKAY |
+ PCI_FLAGS_MRM_OKAY |
+ PCI_FLAGS_MWI_OKAY |
+ PCI_FLAGS_MEM_OKAY;
+ pba.pba_memt = sc->sc_bst;
+ pba.pba_dmat = sc->sc_dmat;
+ pba.pba_pc = &sc->sc_pc;
+ pba.pba_bus = 0;
+
+ config_found_ia(self, "pcibus", &pba, pcibusprint);
+}
+
+static int
+tegra_pcie_intr(void *priv)
+{
+ struct tegra_pcie_softc *sc = priv;
+ struct tegra_pcie_ih *pcie_ih;
+
+ const uint32_t code = bus_space_read_4(sc->sc_bst, sc->sc_bsh_afi,
+ AFI_INTR_CODE_REG);
+ const uint32_t sig = bus_space_read_4(sc->sc_bst, sc->sc_bsh_afi,
+ AFI_INTR_SIGNATURE_REG);
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh_afi, AFI_INTR_CODE_REG, 0);
+
+ switch (__SHIFTOUT(code, AFI_INTR_CODE_INT_CODE)) {
+ case AFI_INTR_CODE_SM_MSG:
+ mutex_enter(&sc->sc_lock);
+ const u_int lastgen = sc->sc_intrgen;
+ TAILQ_FOREACH(pcie_ih, &sc->sc_intrs, ih_entry) {
+ int (*callback)(void *) = pcie_ih->ih_callback;
+ void *arg = pcie_ih->ih_arg;
+ mutex_exit(&sc->sc_lock);
Home |
Main Index |
Thread Index |
Old Index