Module Name:    src
Committed By:   jmcneill
Date:           Sun Dec 13 17:39:20 UTC 2015

Modified Files:
        src/sys/arch/arm/nvidia: files.tegra tegra_ahcisata.c tegra_car.c
            tegra_cec.c tegra_com.c tegra_drm.c tegra_drm.h tegra_drm_mode.c
            tegra_ehci.c tegra_fuse.c tegra_gpio.c tegra_hdaudio.c tegra_i2c.c
            tegra_mc.c tegra_mpio.c tegra_pcie.c tegra_pmc.c tegra_rtc.c
            tegra_sdhc.c tegra_soctherm.c tegra_timer.c tegra_usbphy.c
            tegra_xusbpad.c
        src/sys/arch/evbarm/conf: JETSONTK1 files.tegra mk.tegra
        src/sys/arch/evbarm/tegra: tegra_machdep.c tegra_start.S
Added Files:
        src/sys/arch/arm/nvidia: tegra_fdt.c tegra_lic.c
Removed Files:
        src/sys/arch/arm/nvidia: tegra_host1x.c tegra_io.c

Log Message:
Use fdt for device enumeration.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/arm/nvidia/files.tegra
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/nvidia/tegra_ahcisata.c \
    src/sys/arch/arm/nvidia/tegra_pmc.c
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/arm/nvidia/tegra_car.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/nvidia/tegra_cec.c \
    src/sys/arch/arm/nvidia/tegra_rtc.c \
    src/sys/arch/arm/nvidia/tegra_soctherm.c \
    src/sys/arch/arm/nvidia/tegra_timer.c \
    src/sys/arch/arm/nvidia/tegra_xusbpad.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_com.c \
    src/sys/arch/arm/nvidia/tegra_fuse.c src/sys/arch/arm/nvidia/tegra_mpio.c \
    src/sys/arch/arm/nvidia/tegra_usbphy.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_drm.c \
    src/sys/arch/arm/nvidia/tegra_gpio.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_drm.h \
    src/sys/arch/arm/nvidia/tegra_hdaudio.c \
    src/sys/arch/arm/nvidia/tegra_mc.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/nvidia/tegra_drm_mode.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_ehci.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/nvidia/tegra_fdt.c \
    src/sys/arch/arm/nvidia/tegra_lic.c
cvs rdiff -u -r1.1 -r0 src/sys/arch/arm/nvidia/tegra_host1x.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_i2c.c
cvs rdiff -u -r1.21 -r0 src/sys/arch/arm/nvidia/tegra_io.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/nvidia/tegra_pcie.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/nvidia/tegra_sdhc.c
cvs rdiff -u -r1.41 -r1.42 src/sys/arch/evbarm/conf/JETSONTK1
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/conf/files.tegra
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/conf/mk.tegra
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/evbarm/tegra/tegra_machdep.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/tegra/tegra_start.S

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/files.tegra
diff -u src/sys/arch/arm/nvidia/files.tegra:1.24 src/sys/arch/arm/nvidia/files.tegra:1.25
--- src/sys/arch/arm/nvidia/files.tegra:1.24	Sat Nov 21 22:55:32 2015
+++ src/sys/arch/arm/nvidia/files.tegra	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.tegra,v 1.24 2015/11/21 22:55:32 jmcneill Exp $
+#	$NetBSD: files.tegra,v 1.25 2015/12/13 17:39:19 jmcneill Exp $
 #
 # Configuration info for NVIDIA Tegra ARM Peripherals
 #
@@ -22,107 +22,109 @@ device	tegraio { [port=-1] } : bus_space
 attach	tegraio at mainbus with tegra_io 
 file	arch/arm/nvidia/tegra_io.c		tegra_io
 
+device	tegrafdt : bus_space_generic, fdtbus
+attach	tegrafdt at mainbus with tegra_fdt
+file	arch/arm/nvidia/tegra_fdt.c		tegra_fdt
+
+# Interrupt controller
+device	tegralic
+attach	tegralic at fdt with tegra_lic
+file	arch/arm/nvidia/tegra_lic.c		tegra_lic
+
 # Memory controller
 device	tegramc
-attach	tegramc at tegraio with tegra_mc
+attach	tegramc at fdt with tegra_mc
 file	arch/arm/nvidia/tegra_mc.c		tegra_mc
 
 # Power management controller
 device	tegrapmc
-attach	tegrapmc at tegraio with tegra_pmc
+attach	tegrapmc at fdt with tegra_pmc
 file	arch/arm/nvidia/tegra_pmc.c		tegra_pmc
 
 # eFUSE
 device	tegrafuse
-attach	tegrafuse at tegraio with tegra_fuse
+attach	tegrafuse at fdt with tegra_fuse
 file	arch/arm/nvidia/tegra_fuse.c		tegra_fuse
 
 # Clock and Reset controller
 device	tegracar
-attach	tegracar at tegraio with tegra_car
+attach	tegracar at fdt with tegra_car
 file	arch/arm/nvidia/tegra_car.c		tegra_car
 
 # GPIO controller
 device	tegragpio: gpiobus
-attach	tegragpio at tegraio with tegra_gpio
+attach	tegragpio at fdt with tegra_gpio
 file	arch/arm/nvidia/tegra_gpio.c		tegra_gpio
 
 # Timers
 device	tegratimer: sysmon_wdog
-attach	tegratimer at tegraio with tegra_timer
+attach	tegratimer at fdt with tegra_timer
 file	arch/arm/nvidia/tegra_timer.c		tegra_timer
 
 # MPIO / Pinmux
 device	tegrampio
-attach	tegrampio at tegraio with tegra_mpio
+attach	tegrampio at fdt with tegra_mpio
 file	arch/arm/nvidia/tegra_mpio.c		tegra_mpio
 
 # XUSB PADCTL
 device	tegraxusbpad
-attach	tegraxusbpad at tegraio with tegra_xusbpad
+attach	tegraxusbpad at fdt with tegra_xusbpad
 file	arch/arm/nvidia/tegra_xusbpad.c		tegra_xusbpad
 
 # UART
-attach	com at tegraio with tegra_com
+attach	com at fdt with tegra_com
 file	arch/arm/nvidia/tegra_com.c		tegra_com needs-flag
 
 # I2C
 device	tegrai2c: i2cbus, i2cexec
-attach	tegrai2c at tegraio with tegra_i2c
+attach	tegrai2c at fdt with tegra_i2c
 file	arch/arm/nvidia/tegra_i2c.c		tegra_i2c
 
 # RTC
 device	tegrartc
-attach	tegrartc at tegraio with tegra_rtc
+attach	tegrartc at fdt with tegra_rtc
 file	arch/arm/nvidia/tegra_rtc.c		tegra_rtc
 
 # USB PHY
-define	tegrausbphybus { }
 device	tegrausbphy
-attach	tegrausbphy at tegrausbphybus with tegra_usbphy
+attach	tegrausbphy at fdt with tegra_usbphy
 file	arch/arm/nvidia/tegra_usbphy.c		tegra_usbphy
 
 # USB 2.0
-device	tegraehci: usbus, usbroothub, usb_dma, ehci, tegrausbphybus
-attach	tegraehci at tegraio with tegra_ehci
+attach	ehci at fdt with tegra_ehci
 file	arch/arm/nvidia/tegra_ehci.c		tegra_ehci
 
 # SDMMC
-attach	sdhc at tegraio with tegra_sdhc
+attach	sdhc at fdt with tegra_sdhc
 file	arch/arm/nvidia/tegra_sdhc.c		tegra_sdhc
 
 # Thermal throttling controller
 device	tegrasoctherm: sysmon_envsys
-attach	tegrasoctherm at tegraio with tegra_soctherm
+attach	tegrasoctherm at fdt with tegra_soctherm
 file	arch/arm/nvidia/tegra_soctherm.c	tegra_soctherm
 
 # PCIE
 device	tegrapcie: pcibus
-attach	tegrapcie at tegraio with tegra_pcie
+attach	tegrapcie at fdt with tegra_pcie
 file	arch/arm/nvidia/tegra_pcie.c		tegra_pcie
 
 # SATA
-attach	ahcisata at tegraio with tegra_ahcisata
+attach	ahcisata at fdt with tegra_ahcisata
 file	arch/arm/nvidia/tegra_ahcisata.c	tegra_ahcisata
 
 # HDA
-attach	hdaudio at tegraio with tegra_hdaudio
+attach	hdaudio at fdt with tegra_hdaudio
 file	arch/arm/nvidia/tegra_hdaudio.c		tegra_hdaudio
 
-# Host1x subsystem
-device	tegrahost1x
-attach	tegrahost1x at tegraio with tegra_host1x
-file	arch/arm/nvidia/tegra_host1x.c		tegra_host1x
-
 # HDMI CEC
 device	tegracec: hdmicecbus
-attach	tegracec at tegraio with tegra_cec
+attach	tegracec at fdt with tegra_cec
 file	arch/arm/nvidia/tegra_cec.c		tegra_cec
 
 # Display
 define	tegrafbbus { }
-device	tegradrm: drmkms, tegrafbbus
-attach	tegradrm at tegraio with tegra_drm
+device	tegradrm: drmkms, ddc_read_edid, tegrafbbus
+attach	tegradrm at fdt with tegra_drm
 file	arch/arm/nvidia/tegra_drm.c		tegra_drm
 file	arch/arm/nvidia/tegra_drm_mode.c	tegra_drm
 file	arch/arm/nvidia/tegra_drm_fb.c		tegra_drm

Index: src/sys/arch/arm/nvidia/tegra_ahcisata.c
diff -u src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.7 src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.8
--- src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.7	Thu Oct 15 09:04:35 2015
+++ src/sys/arch/arm/nvidia/tegra_ahcisata.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_ahcisata.c,v 1.7 2015/10/15 09:04:35 jmcneill Exp $ */
+/* $NetBSD: tegra_ahcisata.c,v 1.8 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.7 2015/10/15 09:04:35 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.8 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -44,6 +42,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_ahcisa
 #include <arm/nvidia/tegra_var.h>
 #include <arm/nvidia/tegra_ahcisatareg.h>
 
+#include <dev/fdt/fdtvar.h>
+
 #define TEGRA_AHCISATA_OFFSET	0x7000
 
 static int	tegra_ahcisata_match(device_t, cfdata_t, void *);
@@ -58,6 +58,14 @@ struct tegra_ahcisata_softc {
 	struct tegra_gpio_pin	*sc_pin_power;
 };
 
+static const char * const tegra_ahcisata_supplies[] = {
+    "hvdd-supply",
+    "vddio-supply",
+    "avdd-supply",
+    "target-5v-supply",
+    "target-12v-supply"
+};
+
 static void	tegra_ahcisata_init(struct tegra_ahcisata_softc *);
 
 CFATTACH_DECL_NEW(tegra_ahcisata, sizeof(struct tegra_ahcisata_softc),
@@ -66,38 +74,66 @@ CFATTACH_DECL_NEW(tegra_ahcisata, sizeof
 static int
 tegra_ahcisata_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-ahci", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_ahcisata_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_ahcisata_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
-	prop_dictionary_t prop = device_properties(self);
-	const char *pin;
-
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	bus_addr_t ahci_addr, sata_addr;
+	bus_size_t ahci_size, sata_size;
+	struct fdtbus_regulator *reg;
+	char intrstr[128];
+	int error, n;
+
+	if (fdtbus_get_reg(phandle, 0, &ahci_addr, &ahci_size) != 0) {
+		aprint_error(": couldn't get ahci registers\n");
+		return;
+	}
+	if (fdtbus_get_reg(phandle, 1, &sata_addr, &sata_size) != 0) {
+		aprint_error(": couldn't get sata registers\n");
+		return;
+	}
+
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, sata_addr, sata_size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map sata registers: %d\n", error);
+		return;
+	}
 
 	sc->sc.sc_atac.atac_dev = self;
-	sc->sc.sc_dmat = tio->tio_dmat;
-	sc->sc.sc_ahcit = tio->tio_bst;
-	sc->sc.sc_ahcis = loc->loc_size - TEGRA_AHCISATA_OFFSET;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset + TEGRA_AHCISATA_OFFSET,
-	    loc->loc_size - TEGRA_AHCISATA_OFFSET, &sc->sc.sc_ahcih);
+	sc->sc.sc_dmat = faa->faa_dmat;
+	sc->sc.sc_ahcit = faa->faa_bst;
+	sc->sc.sc_ahcis = ahci_size;
+	error = bus_space_map(sc->sc.sc_ahcit, ahci_addr, ahci_size, 0,
+	    &sc->sc.sc_ahcih);
+	if (error) {
+		aprint_error(": couldn't map ahci registers: %d\n", error);
+		return;
+	}
 	sc->sc.sc_ahci_quirks = AHCI_QUIRK_SKIP_RESET;
 
 	aprint_naive("\n");
 	aprint_normal(": SATA\n");
 
-	if (prop_dictionary_get_cstring_nocopy(prop, "power-gpio", &pin)) {
-		sc->sc_pin_power = tegra_gpio_acquire(pin, GPIO_PIN_OUTPUT);
-		if (sc->sc_pin_power)
-			tegra_gpio_write(sc->sc_pin_power, 1);
+	for (n = 0; n < __arraycount(tegra_ahcisata_supplies); n++) {
+		const char *supply = tegra_ahcisata_supplies[n];
+		reg = fdtbus_regulator_acquire(phandle, supply);
+		if (reg == NULL) {
+			aprint_error_dev(self, "couldn't acquire %s\n", supply);
+			continue;
+		}
+		if (fdtbus_regulator_enable(reg) != 0) {
+			aprint_error_dev(self, "couldn't enable %s\n", supply);
+		}
+		fdtbus_regulator_release(reg);
 	}
 
 	tegra_car_periph_sata_enable();
@@ -106,14 +142,19 @@ tegra_ahcisata_attach(device_t parent, d
 
 	tegra_ahcisata_init(sc);
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_BIO, IST_LEVEL,
+	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, 0,
 	    ahci_intr, &sc->sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "couldn't establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "failed to establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	ahci_attach(&sc->sc);
 }
Index: src/sys/arch/arm/nvidia/tegra_pmc.c
diff -u src/sys/arch/arm/nvidia/tegra_pmc.c:1.7 src/sys/arch/arm/nvidia/tegra_pmc.c:1.8
--- src/sys/arch/arm/nvidia/tegra_pmc.c:1.7	Sat Oct 17 21:14:49 2015
+++ src/sys/arch/arm/nvidia/tegra_pmc.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_pmc.c,v 1.7 2015/10/17 21:14:49 jmcneill Exp $ */
+/* $NetBSD: tegra_pmc.c,v 1.8 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_pmc.c,v 1.7 2015/10/17 21:14:49 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_pmc.c,v 1.8 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -42,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_pmc.c,
 #include <arm/nvidia/tegra_pmcreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_pmc_match(device_t, cfdata_t, void *);
 static void	tegra_pmc_attach(device_t, device_t, void *);
 
@@ -59,20 +59,33 @@ CFATTACH_DECL_NEW(tegra_pmc, sizeof(stru
 static int
 tegra_pmc_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-pmc", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_pmc_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_pmc_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	KASSERT(pmc_softc == NULL);
 	pmc_softc = sc;

Index: src/sys/arch/arm/nvidia/tegra_car.c
diff -u src/sys/arch/arm/nvidia/tegra_car.c:1.30 src/sys/arch/arm/nvidia/tegra_car.c:1.31
--- src/sys/arch/arm/nvidia/tegra_car.c:1.30	Sat Nov 21 22:55:32 2015
+++ src/sys/arch/arm/nvidia/tegra_car.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_car.c,v 1.30 2015/11/21 22:55:32 jmcneill Exp $ */
+/* $NetBSD: tegra_car.c,v 1.31 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.30 2015/11/21 22:55:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.31 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -45,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_car.c,
 #include <arm/nvidia/tegra_pmcreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_car_match(device_t, cfdata_t, void *);
 static void	tegra_car_attach(device_t, device_t, void *);
 
@@ -65,7 +65,7 @@ static void	tegra_car_rnd_attach(device_
 static void	tegra_car_rnd_intr(void *);
 static void	tegra_car_rnd_callback(size_t, void *);
 
-static struct tegra_car_softc *pmc_softc = NULL;
+static struct tegra_car_softc *car_softc = NULL;
 
 CFATTACH_DECL_NEW(tegra_car, sizeof(struct tegra_car_softc),
 	tegra_car_match, tegra_car_attach, NULL, NULL);
@@ -73,23 +73,36 @@ CFATTACH_DECL_NEW(tegra_car, sizeof(stru
 static int
 tegra_car_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-car", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_car_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_car_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
-	KASSERT(pmc_softc == NULL);
-	pmc_softc = sc;
+	KASSERT(car_softc == NULL);
+	car_softc = sc;
 
 	aprint_naive("\n");
 	aprint_normal(": CAR\n");
@@ -185,9 +198,9 @@ tegra_car_rnd_callback(size_t bytes_want
 static void
 tegra_car_get_bs(bus_space_tag_t *pbst, bus_space_handle_t *pbsh)
 {
-	if (pmc_softc) {
-		*pbst = pmc_softc->sc_bst;
-		*pbsh = pmc_softc->sc_bsh;
+	if (car_softc) {
+		*pbst = car_softc->sc_bst;
+		*pbsh = car_softc->sc_bsh;
 	} else {
 		*pbst = &armv7_generic_bs_tag;
 		bus_space_subregion(*pbst, tegra_ppsb_bsh,

Index: src/sys/arch/arm/nvidia/tegra_cec.c
diff -u src/sys/arch/arm/nvidia/tegra_cec.c:1.1 src/sys/arch/arm/nvidia/tegra_cec.c:1.2
--- src/sys/arch/arm/nvidia/tegra_cec.c:1.1	Sat Aug  1 21:20:11 2015
+++ src/sys/arch/arm/nvidia/tegra_cec.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_cec.c,v 1.1 2015/08/01 21:20:11 jmcneill Exp $ */
+/* $NetBSD: tegra_cec.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_cec.c,v 1.1 2015/08/01 21:20:11 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_cec.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -49,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_cec.c,
 #include <arm/nvidia/tegra_pmcreg.h>
 #include <arm/nvidia/tegra_cecreg.h>
 
+#include <dev/fdt/fdtvar.h>
+
 #define CEC_VENDORID_NVIDIA	0x00044b
 
 static int	tegra_cec_match(device_t, cfdata_t, void *);
@@ -112,22 +112,36 @@ CFATTACH_DECL_NEW(tegra_cec, sizeof(stru
 static int
 tegra_cec_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-cec", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_cec_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_cec_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
 	prop_dictionary_t prop = device_properties(self);
 	struct hdmicec_attach_args caa;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
 	cv_init(&sc->sc_cv, "tegracec");
 	selinit(&sc->sc_selinfo);
@@ -135,14 +149,19 @@ tegra_cec_attach(device_t parent, device
 	aprint_naive("\n");
 	aprint_normal(": HDMI CEC\n");
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_VM, IST_LEVEL|IST_MPSAFE,
-	    tegra_cec_intr, sc);
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM,
+	    FDT_INTR_MPSAFE, tegra_cec_intr, sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "couldn't establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	prop_dictionary_get_cstring_nocopy(prop, "hdmi-device",
 	    &sc->sc_hdmidevname);
Index: src/sys/arch/arm/nvidia/tegra_rtc.c
diff -u src/sys/arch/arm/nvidia/tegra_rtc.c:1.1 src/sys/arch/arm/nvidia/tegra_rtc.c:1.2
--- src/sys/arch/arm/nvidia/tegra_rtc.c:1.1	Tue May  5 00:25:44 2015
+++ src/sys/arch/arm/nvidia/tegra_rtc.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_rtc.c,v 1.1 2015/05/05 00:25:44 jmcneill Exp $ */
+/* $NetBSD: tegra_rtc.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_rtc.c,v 1.1 2015/05/05 00:25:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_rtc.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -45,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_rtc.c,
 #include <arm/nvidia/tegra_rtcreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_rtc_match(device_t, cfdata_t, void *);
 static void	tegra_rtc_attach(device_t, device_t, void *);
 
@@ -70,20 +70,33 @@ CFATTACH_DECL_NEW(tegra_rtc, sizeof(stru
 static int
 tegra_rtc_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-rtc", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_rtc_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_rtc_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	aprint_naive("\n");
 	aprint_normal(": RTC\n");
Index: src/sys/arch/arm/nvidia/tegra_soctherm.c
diff -u src/sys/arch/arm/nvidia/tegra_soctherm.c:1.1 src/sys/arch/arm/nvidia/tegra_soctherm.c:1.2
--- src/sys/arch/arm/nvidia/tegra_soctherm.c:1.1	Sat Nov 21 22:55:32 2015
+++ src/sys/arch/arm/nvidia/tegra_soctherm.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_soctherm.c,v 1.1 2015/11/21 22:55:32 jmcneill Exp $ */
+/* $NetBSD: tegra_soctherm.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.1 2015/11/21 22:55:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -45,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_socthe
 #include <arm/nvidia/tegra_socthermreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 #define FUSE_TSENSOR_CALIB_CP_TS_BASE	__BITS(12,0)
 #define FUSE_TSENSOR_CALIB_FT_TS_BASE	__BITS(25,13)
 
@@ -158,20 +158,33 @@ CFATTACH_DECL_NEW(tegra_soctherm, sizeof
 static int
 tegra_soctherm_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-soctherm", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_soctherm_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_soctherm_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	aprint_naive("\n");
 	aprint_normal(": SOC_THERM\n");
Index: src/sys/arch/arm/nvidia/tegra_timer.c
diff -u src/sys/arch/arm/nvidia/tegra_timer.c:1.1 src/sys/arch/arm/nvidia/tegra_timer.c:1.2
--- src/sys/arch/arm/nvidia/tegra_timer.c:1.1	Sat May 30 13:25:55 2015
+++ src/sys/arch/arm/nvidia/tegra_timer.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_timer.c,v 1.1 2015/05/30 13:25:55 jmcneill Exp $ */
+/* $NetBSD: tegra_timer.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.1 2015/05/30 13:25:55 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -43,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_timer.
 #include <arm/nvidia/tegra_timerreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 #define TEGRA_TIMER_WDOG_PERIOD_DEFAULT	10
 
 static int	tegra_timer_match(device_t, cfdata_t, void *);
@@ -72,20 +74,33 @@ CFATTACH_DECL_NEW(tegra_timer, sizeof(st
 static int
 tegra_timer_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-timer", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_timer_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_timer_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	aprint_naive("\n");
 	aprint_normal(": Timers\n");
Index: src/sys/arch/arm/nvidia/tegra_xusbpad.c
diff -u src/sys/arch/arm/nvidia/tegra_xusbpad.c:1.1 src/sys/arch/arm/nvidia/tegra_xusbpad.c:1.2
--- src/sys/arch/arm/nvidia/tegra_xusbpad.c:1.1	Fri May 15 11:49:10 2015
+++ src/sys/arch/arm/nvidia/tegra_xusbpad.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_xusbpad.c,v 1.1 2015/05/15 11:49:10 jmcneill Exp $ */
+/* $NetBSD: tegra_xusbpad.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_xusbpad.c,v 1.1 2015/05/15 11:49:10 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_xusbpad.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -42,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_xusbpa
 #include <arm/nvidia/tegra_xusbpadreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_xusbpad_match(device_t, cfdata_t, void *);
 static void	tegra_xusbpad_attach(device_t, device_t, void *);
 
@@ -59,27 +59,40 @@ CFATTACH_DECL_NEW(tegra_xusbpad, sizeof(
 static int
 tegra_xusbpad_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] =
+	    { "nvidia,tegra124-xusb-padctl", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_xusbpad_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_xusbpad_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	KASSERT(xusbpad_softc == NULL);
 	xusbpad_softc = sc;
 
 	aprint_naive("\n");
 	aprint_normal(": XUSB PADCTL\n");
-
 }
 
 static void

Index: src/sys/arch/arm/nvidia/tegra_com.c
diff -u src/sys/arch/arm/nvidia/tegra_com.c:1.2 src/sys/arch/arm/nvidia/tegra_com.c:1.3
--- src/sys/arch/arm/nvidia/tegra_com.c:1.2	Sun May  3 17:24:45 2015
+++ src/sys/arch/arm/nvidia/tegra_com.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_com.c,v 1.2 2015/05/03 17:24:45 jmcneill Exp $ */
+/* $NetBSD: tegra_com.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -29,11 +29,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: tegra_com.c,v 1.2 2015/05/03 17:24:45 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: tegra_com.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -48,6 +46,26 @@ __KERNEL_RCSID(1, "$NetBSD: tegra_com.c,
 
 #include <dev/ic/comvar.h>
 
+#include <dev/fdt/fdtvar.h>
+
+/* XXX */
+static int
+tegra_com_addr2port(bus_addr_t addr)
+{
+	switch (addr) {
+	case TEGRA_APB_BASE + TEGRA_UARTA_OFFSET:
+		return 0;
+	case TEGRA_APB_BASE + TEGRA_UARTB_OFFSET:
+		return 1;
+	case TEGRA_APB_BASE + TEGRA_UARTC_OFFSET:
+		return 2;
+	case TEGRA_APB_BASE + TEGRA_UARTD_OFFSET:
+		return 3;
+	default:
+		return -1;
+	}
+}
+
 static int tegra_com_match(device_t, cfdata_t, void *);
 static void tegra_com_attach(device_t, device_t, void *);
 
@@ -62,18 +80,10 @@ CFATTACH_DECL_NEW(tegra_com, sizeof(stru
 static int
 tegra_com_match(device_t parent, cfdata_t cf, void *aux)
 {
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
-	bus_space_tag_t bst = tio->tio_a4x_bst;
-	bus_space_handle_t bsh;
-
-	if (com_is_console(bst, TEGRA_APB_BASE + loc->loc_offset, NULL))
-		return 1;
+	const char * const compatible[] = { "nvidia,tegra124-uart", NULL };
+	struct fdt_attach_args * const faa = aux;
 
-	bus_space_subregion(bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &bsh);
-
-	return comprobe1(bst, bsh);
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
@@ -81,29 +91,69 @@ tegra_com_attach(device_t parent, device
 {
 	struct tegra_com_softc * const tsc = device_private(self);
 	struct com_softc * const sc = &tsc->tsc_sc;
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
-	bus_space_tag_t bst = tio->tio_a4x_bst;
-	const bus_addr_t iobase = TEGRA_APB_BASE + loc->loc_offset;
+	struct fdt_attach_args * const faa = aux;
 	bus_space_handle_t bsh;
+	bus_space_tag_t bst;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	u_int reg_shift;
+	int error, len;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	len = OF_getprop(faa->faa_phandle, "reg-shift", &reg_shift,
+	    sizeof(reg_shift));
+	if (len == sizeof(reg_shift)) {
+		reg_shift = be32toh(reg_shift);
+		if (reg_shift == 2) {
+			bst = faa->faa_a4x_bst;
+		} else if (reg_shift == 0) {
+			bst = faa->faa_bst;
+		} else {
+			aprint_error(": unsupported reg-shift value %d\n",
+			    reg_shift);
+			return;
+		}
+	} else {
+		/* missing or bad reg-shift property, assume 2 */
+		bst = faa->faa_a4x_bst;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_frequency = tegra_car_uart_rate(loc->loc_port);
+
+	/* XXX */
+	const int port = tegra_com_addr2port(addr);
+	if (port == -1) {
+		panic("unsupported com address %#llx", (uint64_t)addr);
+	}
+	sc->sc_frequency = tegra_car_uart_rate(port);
 	sc->sc_type = COM_TYPE_TEGRA;
 
-	if (com_is_console(bst, iobase, &bsh) == 0
-	    && bus_space_subregion(bst, tio->tio_bsh,
-		loc->loc_offset / 4, loc->loc_size, &bsh)) {
-		panic(": can't map registers");
+	error = bus_space_map(bst, addr, size, 0, &bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
 	}
-	COM_INIT_REGS(sc->sc_regs, bst, bsh, iobase);
+
+	COM_INIT_REGS(sc->sc_regs, bst, bsh, addr);
 
 	com_attach_subr(sc);
 	aprint_naive("\n");
 
-	tsc->tsc_ih = intr_establish(loc->loc_intr, IPL_SERIAL,
-	    IST_LEVEL | IST_MPSAFE, comintr, sc);
-	if (tsc->tsc_ih == NULL)
-		panic("%s: failed to establish interrupt %d",
-		    device_xname(self), loc->loc_intr);
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	tsc->tsc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SERIAL,
+	    FDT_INTR_MPSAFE, comintr, sc);
+	if (tsc->tsc_ih == NULL) {
+		aprint_error_dev(self, "failed to establish interrupt on %s\n",
+		    intrstr);
+	}
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 }
Index: src/sys/arch/arm/nvidia/tegra_fuse.c
diff -u src/sys/arch/arm/nvidia/tegra_fuse.c:1.2 src/sys/arch/arm/nvidia/tegra_fuse.c:1.3
--- src/sys/arch/arm/nvidia/tegra_fuse.c:1.2	Sat Nov 21 22:52:31 2015
+++ src/sys/arch/arm/nvidia/tegra_fuse.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_fuse.c,v 1.2 2015/11/21 22:52:31 jmcneill Exp $ */
+/* $NetBSD: tegra_fuse.c,v 1.3 2015/12/13 17:39:19 jmcneill 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_fuse.c,v 1.2 2015/11/21 22:52:31 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_fuse.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -41,6 +41,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_fuse.c
 #include <arm/nvidia/tegra_reg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_fuse_match(device_t, cfdata_t, void *);
 static void	tegra_fuse_attach(device_t, device_t, void *);
 
@@ -58,20 +60,33 @@ CFATTACH_DECL_NEW(tegra_fuse, sizeof(str
 static int
 tegra_fuse_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-efuse", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_fuse_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_fuse_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	KASSERT(fuse_softc == NULL);
 	fuse_softc = sc;
Index: src/sys/arch/arm/nvidia/tegra_mpio.c
diff -u src/sys/arch/arm/nvidia/tegra_mpio.c:1.2 src/sys/arch/arm/nvidia/tegra_mpio.c:1.3
--- src/sys/arch/arm/nvidia/tegra_mpio.c:1.2	Fri May  8 17:00:51 2015
+++ src/sys/arch/arm/nvidia/tegra_mpio.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_mpio.c,v 1.2 2015/05/08 17:00:51 jmcneill Exp $ */
+/* $NetBSD: tegra_mpio.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_mpio.c,v 1.2 2015/05/08 17:00:51 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_mpio.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -46,6 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_mpio.c
 #include <arm/nvidia/tegra_mpioreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_mpio_match(device_t, cfdata_t, void *);
 static void	tegra_mpio_attach(device_t, device_t, void *);
 
@@ -337,20 +339,33 @@ CFATTACH_DECL_NEW(tegra_mpio, sizeof(str
 static int
 tegra_mpio_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-pinmux", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_mpio_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_mpio_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	aprint_naive("\n");
 	aprint_normal(": MPIO\n");
Index: src/sys/arch/arm/nvidia/tegra_usbphy.c
diff -u src/sys/arch/arm/nvidia/tegra_usbphy.c:1.2 src/sys/arch/arm/nvidia/tegra_usbphy.c:1.3
--- src/sys/arch/arm/nvidia/tegra_usbphy.c:1.2	Thu Nov 19 22:09:16 2015
+++ src/sys/arch/arm/nvidia/tegra_usbphy.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_usbphy.c,v 1.2 2015/11/19 22:09:16 jmcneill Exp $ */
+/* $NetBSD: tegra_usbphy.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_usbphy.c,v 1.2 2015/11/19 22:09:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_usbphy.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -38,9 +36,28 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_usbphy
 #include <sys/systm.h>
 #include <sys/kernel.h>
 
+#include <arm/nvidia/tegra_reg.h>
 #include <arm/nvidia/tegra_var.h>
 #include <arm/nvidia/tegra_usbreg.h>
 
+#include <dev/fdt/fdtvar.h>
+
+/* XXX */
+static int
+tegra_usbphy_addr2port(bus_addr_t addr)
+{
+	switch (addr) {
+	case TEGRA_AHB_A2_BASE + TEGRA_USB1_OFFSET:
+		return 0;
+	case TEGRA_AHB_A2_BASE + TEGRA_USB2_OFFSET:
+		return 1;
+	case TEGRA_AHB_A2_BASE + TEGRA_USB3_OFFSET:
+		return 2;
+	default:
+		return -1;
+	}
+}
+
 static int	tegra_usbphy_match(device_t, cfdata_t, void *);
 static void	tegra_usbphy_attach(device_t, device_t, void *);
 
@@ -48,6 +65,7 @@ struct tegra_usbphy_softc {
 	device_t		sc_dev;
 	bus_space_tag_t		sc_bst;
 	bus_space_handle_t	sc_bsh;
+	int			sc_phandle;
 	u_int			sc_port;
 
 	struct tegra_gpio_pin	*sc_pin_vbus;
@@ -72,21 +90,36 @@ CFATTACH_DECL_NEW(tegra_usbphy, sizeof(s
 static int
 tegra_usbphy_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-usb-phy", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_usbphy_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_usbphy_softc * const sc = device_private(self);
-	struct tegrausbphy_attach_args * const tup = aux;
-	prop_dictionary_t prop = device_properties(self);
-	const char *pin;
+	struct fdt_attach_args * const faa = aux;
+	struct fdtbus_regulator *reg;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tup->tup_bst;
-	sc->sc_bsh = tup->tup_bsh;
-	sc->sc_port = tup->tup_port;
+	sc->sc_phandle = faa->faa_phandle;
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
+	sc->sc_port = tegra_usbphy_addr2port(addr);
 
 	aprint_naive("\n");
 	aprint_normal(": USB PHY%d\n", sc->sc_port + 1);
@@ -99,14 +132,12 @@ tegra_usbphy_attach(device_t parent, dev
 
 	tegra_usbphy_utmip_init(sc);
 
-	if (prop_dictionary_get_cstring_nocopy(prop, "vbus-gpio", &pin)) {
+	reg = fdtbus_regulator_acquire(faa->faa_phandle, "vbus-supply");
+	if (reg) {
 		const uint32_t v = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
 		    TEGRA_EHCI_PHY_VBUS_SENSORS_REG);
 		if ((v & TEGRA_EHCI_PHY_VBUS_SENSORS_A_VBUS_VLD_STS) == 0) {
-			sc->sc_pin_vbus = tegra_gpio_acquire(pin,
-			    GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN);
-			if (sc->sc_pin_vbus)
-				tegra_gpio_write(sc->sc_pin_vbus, 1);
+			fdtbus_regulator_enable(reg);
 		} else {
 			aprint_normal_dev(self, "VBUS input active\n");
 		}
@@ -116,14 +147,19 @@ tegra_usbphy_attach(device_t parent, dev
 static int
 tegra_usbphy_parse_properties(struct tegra_usbphy_softc *sc)
 {
-#define PROPGET(k, v)	\
-	if (prop_dictionary_get_uint8(prop, (k), (v)) == false) {	\
+	const int phandle = sc->sc_phandle;
+	const int plen = sizeof(u_int);
+	u_int val;
+
+#define PROPGET(k, v)							\
+do {									\
+	if (OF_getprop(phandle, (k), &val, plen) != plen) {		\
 		aprint_error_dev(sc->sc_dev,				\
 		    "missing property '%s'\n", (k));			\
 		return EIO;						\
-	}
-
-	prop_dictionary_t prop = device_properties(sc->sc_dev);
+	}								\
+	*(v) = be32toh(val);						\
+} while (0)
 
 	PROPGET("nvidia,hssync-start-delay", &sc->sc_hssync_start_delay);
 	PROPGET("nvidia,idle-wait-delay", &sc->sc_idle_wait_delay);

Index: src/sys/arch/arm/nvidia/tegra_drm.c
diff -u src/sys/arch/arm/nvidia/tegra_drm.c:1.3 src/sys/arch/arm/nvidia/tegra_drm.c:1.4
--- src/sys/arch/arm/nvidia/tegra_drm.c:1.3	Thu Nov 12 00:43:52 2015
+++ src/sys/arch/arm/nvidia/tegra_drm.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_drm.c,v 1.3 2015/11/12 00:43:52 jmcneill Exp $ */
+/* $NetBSD: tegra_drm.c,v 1.4 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.3 2015/11/12 00:43:52 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.4 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -48,6 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,
 #include <arm/nvidia/tegra_var.h>
 #include <arm/nvidia/tegra_drm.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_drm_match(device_t, cfdata_t, void *);
 static void	tegra_drm_attach(device_t, device_t, void *);
 
@@ -106,47 +106,71 @@ CFATTACH_DECL_NEW(tegra_drm, sizeof(stru
 static int
 tegra_drm_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * compatible[] = { "nvidia,tegra124-host1x", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_drm_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_drm_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	prop_dictionary_t prop = device_properties(self);
+	struct fdt_attach_args * const faa = aux;
 	struct drm_driver * const driver = &tegra_drm_driver;
-	const char *pin, *dev;
-	int error;
+	prop_dictionary_t prop = device_properties(self);
+	int error, node, hdmi_phandle, ddc_phandle;
+	const char * const hdmi_compat[] = { "nvidia,tegra124-hdmi", NULL };
+	const char * const hdmi_supplies[] = {
+		"hdmi-supply", "pll-supply", "vdd-supply"
+	};
+	struct fdtbus_regulator *reg;
+	u_int n;
 
 	sc->sc_dev = self;
-	sc->sc_dmat = tio->tio_dmat;
-	sc->sc_bst = tio->tio_bst;
+	sc->sc_dmat = faa->faa_dmat;
+	sc->sc_bst = faa->faa_bst;
+	sc->sc_phandle = faa->faa_phandle;
 
-	if (prop_dictionary_get_cstring_nocopy(prop, "hpd-gpio", &pin)) {
-		sc->sc_pin_hpd = tegra_gpio_acquire(pin, GPIO_PIN_INPUT);
-	}
-	if (prop_dictionary_get_cstring_nocopy(prop, "pll-gpio", &pin)) {
-		sc->sc_pin_pll = tegra_gpio_acquire(pin, GPIO_PIN_OUTPUT);
-		if (sc->sc_pin_pll) {
-			tegra_gpio_write(sc->sc_pin_pll, 0);
-		} else {
-			panic("couldn't get pll-gpio pin");
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	tegra_car_host1x_enable();
+
+	hdmi_phandle = -1;
+	for (node = OF_child(faa->faa_phandle); node; node = OF_peer(node)) {
+		if (of_match_compatible(node, hdmi_compat)) {
+			hdmi_phandle = node;
+			break;
 		}
 	}
-	if (prop_dictionary_get_cstring_nocopy(prop, "power-gpio", &pin)) {
-		sc->sc_pin_power = tegra_gpio_acquire(pin, GPIO_PIN_OUTPUT);
-		if (sc->sc_pin_power) {
-			tegra_gpio_write(sc->sc_pin_power, 1);
+	if (hdmi_phandle >= 0) {
+		ddc_phandle = fdtbus_get_phandle(hdmi_phandle,
+		    "nvidia,ddc-i2c-bus");
+		if (ddc_phandle >= 0) {
+			sc->sc_ddc = fdtbus_get_i2c_tag(ddc_phandle);
+		}
+
+		sc->sc_pin_hpd = fdtbus_gpio_acquire(hdmi_phandle,
+		    "nvidia,hpd-gpio", GPIO_PIN_INPUT);
+
+		for (n = 0; n < __arraycount(hdmi_supplies); n++) {
+			const char *supply = hdmi_supplies[n];
+			reg = fdtbus_regulator_acquire(hdmi_phandle, supply);
+			if (reg == NULL) {
+				aprint_error_dev(self, "couldn't acquire %s\n",
+				    supply);
+				continue;
+			}
+			if (fdtbus_regulator_enable(reg) != 0) {
+				aprint_error_dev(self, "couldn't enable %s\n",
+				    supply);
+			}
+			fdtbus_regulator_release(reg);
 		}
 	}
-	if (prop_dictionary_get_cstring_nocopy(prop, "ddc-device", &dev)) {
-		sc->sc_ddcdev = device_find_by_xname(dev);
-	}
-	prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi);
 
-	aprint_naive("\n");
-	aprint_normal("\n");
+	prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi);
 
 	driver->bus = &tegra_drm_bus;
 
Index: src/sys/arch/arm/nvidia/tegra_gpio.c
diff -u src/sys/arch/arm/nvidia/tegra_gpio.c:1.3 src/sys/arch/arm/nvidia/tegra_gpio.c:1.4
--- src/sys/arch/arm/nvidia/tegra_gpio.c:1.3	Sat May  9 12:07:11 2015
+++ src/sys/arch/arm/nvidia/tegra_gpio.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_gpio.c,v 1.3 2015/05/09 12:07:11 jmcneill Exp $ */
+/* $NetBSD: tegra_gpio.c,v 1.4 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_gpio.c,v 1.3 2015/05/09 12:07:11 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_gpio.c,v 1.4 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -46,6 +44,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_gpio.c
 #include <arm/nvidia/tegra_gpioreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 const struct tegra_gpio_pinbank {
 	const char *name;
 	bus_size_t base;
@@ -86,6 +86,19 @@ const struct tegra_gpio_pinbank {
 static int	tegra_gpio_match(device_t, cfdata_t, void *);
 static void	tegra_gpio_attach(device_t, device_t, void *);
 
+static void *	tegra_gpio_fdt_acquire(device_t, const void *,
+		    size_t, int);
+static void	tegra_gpio_fdt_release(device_t, void *);
+static int	tegra_gpio_fdt_read(device_t, void *);
+static void	tegra_gpio_fdt_write(device_t, void *, int);
+
+struct fdtbus_gpio_controller_func tegra_gpio_funcs = {
+	.acquire = tegra_gpio_fdt_acquire,
+	.release = tegra_gpio_fdt_release,
+	.read = tegra_gpio_fdt_read,
+	.write = tegra_gpio_fdt_write
+};
+
 struct tegra_gpio_softc;
 
 struct tegra_gpio_bank {
@@ -109,6 +122,7 @@ struct tegra_gpio_pin {
 	struct tegra_gpio_bank	pin_bank;
 	int			pin_no;
 	u_int			pin_flags;
+	bool			pin_actlo;
 };
 
 static void	tegra_gpio_attach_bank(struct tegra_gpio_softc *, u_int);
@@ -134,21 +148,34 @@ CFATTACH_DECL_NEW(tegra_gpio, sizeof(str
 static int
 tegra_gpio_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-gpio", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_gpio_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_gpio_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
 	u_int n;
 
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	aprint_naive("\n");
 	aprint_normal(": GPIO\n");
@@ -158,6 +185,9 @@ tegra_gpio_attach(device_t parent, devic
 	for (n = 0; n < nbank; n++) {
 		tegra_gpio_attach_bank(sc, n);
 	}
+
+	fdtbus_register_gpio_controller(self, faa->faa_phandle,
+	    &tegra_gpio_funcs);
 }
 
 static void
@@ -249,6 +279,65 @@ tegra_gpio_pin_ctl(void *priv, int pin, 
 	}
 }
 
+static void *
+tegra_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags)
+{
+	struct tegra_gpio_bank gbank;
+	struct tegra_gpio_pin *gpin;
+	const u_int *gpio = data;
+
+	if (len != 12)
+		return NULL;
+
+	const u_int bank = be32toh(gpio[1]) >> 3;
+	const u_int pin = be32toh(gpio[1]) & 7;
+	const bool actlo = be32toh(gpio[2]) & 1;
+
+	if (bank >= __arraycount(tegra_gpio_pinbanks) || pin > 8)
+		return NULL;
+
+	gbank.bank_sc = device_private(dev);
+	gbank.bank_pb = &tegra_gpio_pinbanks[bank];
+
+	const uint32_t cnf = GPIO_READ(&gbank, GPIO_CNF_REG);
+	if ((cnf & __BIT(pin)) == 0)
+		GPIO_WRITE(&gbank, GPIO_CNF_REG, cnf | __BIT(pin));
+
+	gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP);
+	gpin->pin_bank = gbank;
+	gpin->pin_no = pin;
+	gpin->pin_flags = flags;
+	gpin->pin_actlo = actlo;
+
+	tegra_gpio_pin_ctl(&gpin->pin_bank, gpin->pin_no, gpin->pin_flags);
+
+	return gpin;
+}
+
+static void
+tegra_gpio_fdt_release(device_t dev, void *priv)
+{
+	struct tegra_gpio_pin *gpin = priv;
+
+	tegra_gpio_release(gpin);
+}
+
+static int
+tegra_gpio_fdt_read(device_t dev, void *priv)
+{
+	struct tegra_gpio_pin *gpin = priv;
+
+	return tegra_gpio_read(gpin);
+}
+
+static void
+tegra_gpio_fdt_write(device_t dev, void *priv, int val)
+{
+	struct tegra_gpio_pin *gpin = priv;
+
+	tegra_gpio_write(gpin, val);
+}
+
 static const struct tegra_gpio_pinbank *
 tegra_gpio_pin_lookup(const char *pinname, int *ppin)
 {
@@ -320,17 +409,32 @@ tegra_gpio_release(struct tegra_gpio_pin
 int
 tegra_gpio_read(struct tegra_gpio_pin *gpin)
 {
+	int ret;
+
 	if (gpin->pin_flags & GPIO_PIN_INPUT) {
-		return tegra_gpio_pin_read(&gpin->pin_bank, gpin->pin_no);
+		ret = tegra_gpio_pin_read(&gpin->pin_bank, gpin->pin_no);
 	} else {
 		const uint32_t v = GPIO_READ(&gpin->pin_bank, GPIO_OUT_REG);
-		return (v >> gpin->pin_no) & 1;
+		ret = (v >> gpin->pin_no) & 1;
 	}
+
+#if 0
+	if (gpin->pin_actlo)
+		ret = !ret;
+#endif
+
+	return ret;
 }
 
 void
 tegra_gpio_write(struct tegra_gpio_pin *gpin, int val)
 {
 	KASSERT((gpin->pin_flags & GPIO_PIN_OUTPUT) != 0);
+
+#if 0
+	if (gpin->pin_actlo)
+		val = !val;
+#endif
+
 	tegra_gpio_pin_write(&gpin->pin_bank, gpin->pin_no, val);
 }

Index: src/sys/arch/arm/nvidia/tegra_drm.h
diff -u src/sys/arch/arm/nvidia/tegra_drm.h:1.4 src/sys/arch/arm/nvidia/tegra_drm.h:1.5
--- src/sys/arch/arm/nvidia/tegra_drm.h:1.4	Sat Nov 14 11:55:36 2015
+++ src/sys/arch/arm/nvidia/tegra_drm.h	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_drm.h,v 1.4 2015/11/14 11:55:36 jmcneill Exp $ */
+/* $NetBSD: tegra_drm.h,v 1.5 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -52,8 +52,11 @@ struct tegra_drm_softc {
 	bus_space_tag_t		sc_bst;
 	bus_dma_tag_t		sc_dmat;
 
-	device_t		sc_ddcdev;
-	struct tegra_gpio_pin	*sc_pin_hpd;
+	int			sc_phandle;
+
+	i2c_tag_t		sc_ddc;
+	struct fdtbus_gpio_pin	*sc_pin_hpd;
+
 	struct tegra_gpio_pin	*sc_pin_pll;
 	struct tegra_gpio_pin	*sc_pin_power;
 
@@ -94,9 +97,9 @@ struct tegra_encoder {
 
 struct tegra_connector {
 	struct drm_connector	base;
-	device_t		ddcdev;
+	i2c_tag_t		ddc;
 	struct i2c_adapter	*adapter;
-	struct tegra_gpio_pin	*hpd;
+	struct fdtbus_gpio_pin	*hpd;
 
 	bool			has_hdmi_sink;
 	bool			has_audio;
Index: src/sys/arch/arm/nvidia/tegra_hdaudio.c
diff -u src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.4 src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.5
--- src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.4	Sun Jul 26 17:54:46 2015
+++ src/sys/arch/arm/nvidia/tegra_hdaudio.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_hdaudio.c,v 1.4 2015/07/26 17:54:46 jmcneill Exp $ */
+/* $NetBSD: tegra_hdaudio.c,v 1.5 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.4 2015/07/26 17:54:46 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.5 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -45,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_hdaudi
 #include <arm/nvidia/tegra_pmcreg.h>
 #include <arm/nvidia/tegra_hdaudioreg.h>
 
+#include <dev/fdt/fdtvar.h>
+
 #define TEGRA_HDAUDIO_OFFSET	0x8000
 
 #define TEGRA_HDA_IFPS_BAR0_REG		0x0080
@@ -66,6 +66,7 @@ struct tegra_hdaudio_softc {
 	bus_space_tag_t		sc_bst;
 	bus_space_handle_t	sc_bsh;
 	void			*sc_ih;
+	int			sc_phandle;
 };
 
 static void	tegra_hdaudio_init(struct tegra_hdaudio_softc *);
@@ -77,39 +78,58 @@ CFATTACH_DECL2_NEW(tegra_hdaudio, sizeof
 static int
 tegra_hdaudio_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-hda", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_hdaudio_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_hdaudio_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
-
-	sc->sc.sc_memt = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset + TEGRA_HDAUDIO_OFFSET,
-	    loc->loc_size - TEGRA_HDAUDIO_OFFSET, &sc->sc.sc_memh);
+	sc->sc_phandle = faa->faa_phandle;
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
+
+	sc->sc.sc_memt = faa->faa_bst;
+	bus_space_subregion(sc->sc.sc_memt, sc->sc_bsh, TEGRA_HDAUDIO_OFFSET,
+	    size - TEGRA_HDAUDIO_OFFSET, &sc->sc.sc_memh);
 	sc->sc.sc_memvalid = true;
-	sc->sc.sc_dmat = tio->tio_dmat;
+	sc->sc.sc_dmat = faa->faa_dmat;
 	sc->sc.sc_flags = HDAUDIO_FLAG_NO_STREAM_RESET;
 
 	aprint_naive("\n");
 	aprint_normal(": HDA\n");
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_AUDIO, IST_LEVEL,
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_AUDIO, 0,
 	    tegra_hdaudio_intr, sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "couldn't establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	tegra_pmc_power(PMC_PARTID_DISB, true);
 	tegra_car_periph_hda_enable();
@@ -147,7 +167,7 @@ tegra_hdaudio_detach(device_t self, int 
 	hdaudio_detach(&sc->sc, flags);
 
 	if (sc->sc_ih) {
-		intr_disestablish(sc->sc_ih);
+		fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
 		sc->sc_ih = NULL;
 	}
 
Index: src/sys/arch/arm/nvidia/tegra_mc.c
diff -u src/sys/arch/arm/nvidia/tegra_mc.c:1.4 src/sys/arch/arm/nvidia/tegra_mc.c:1.5
--- src/sys/arch/arm/nvidia/tegra_mc.c:1.4	Sun Nov 22 12:26:11 2015
+++ src/sys/arch/arm/nvidia/tegra_mc.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_mc.c,v 1.4 2015/11/22 12:26:11 jmcneill Exp $ */
+/* $NetBSD: tegra_mc.c,v 1.5 2015/12/13 17:39:19 jmcneill 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_mc.c,v 1.4 2015/11/22 12:26:11 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_mc.c,v 1.5 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -42,6 +42,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_mc.c,v
 #include <arm/nvidia/tegra_mcreg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_mc_match(device_t, cfdata_t, void *);
 static void	tegra_mc_attach(device_t, device_t, void *);
 
@@ -69,20 +71,34 @@ CFATTACH_DECL_NEW(tegra_mc, sizeof(struc
 static int
 tegra_mc_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-mc", NULL };
+	struct fdt_attach_args * const faa = aux;
+	
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_mc_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_mc_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
 
 	KASSERT(mc_softc == NULL);
 	mc_softc = sc;
@@ -90,14 +106,19 @@ tegra_mc_attach(device_t parent, device_
 	aprint_naive("\n");
 	aprint_normal(": MC\n");
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_VM, IST_LEVEL|IST_MPSAFE,
-	    tegra_mc_intr, sc);
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM,
+	    FDT_INTR_MPSAFE, tegra_mc_intr, sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "failed to establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "failed to establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	MC_WRITE(sc, MC_INTSTATUS_REG, MC_INT__ALL);
 	MC_WRITE(sc, MC_INTMASK_REG, MC_INT__ALL);

Index: src/sys/arch/arm/nvidia/tegra_drm_mode.c
diff -u src/sys/arch/arm/nvidia/tegra_drm_mode.c:1.9 src/sys/arch/arm/nvidia/tegra_drm_mode.c:1.10
--- src/sys/arch/arm/nvidia/tegra_drm_mode.c:1.9	Mon Nov 16 21:14:51 2015
+++ src/sys/arch/arm/nvidia/tegra_drm_mode.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_drm_mode.c,v 1.9 2015/11/16 21:14:51 jmcneill Exp $ */
+/* $NetBSD: tegra_drm_mode.c,v 1.10 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_drm_mode.c,v 1.9 2015/11/16 21:14:51 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_drm_mode.c,v 1.10 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
@@ -43,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_drm_mo
 #include <arm/nvidia/tegra_hdmireg.h>
 #include <arm/nvidia/tegra_drm.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static struct drm_framebuffer *tegra_fb_create(struct drm_device *,
 		    struct drm_file *, struct drm_mode_fb_cmd2 *);
 
@@ -1097,8 +1099,8 @@ tegra_connector_init(struct drm_device *
 	if (!connector->hpd)
 		DRM_ERROR("failed to find hpd pin for connector\n");
 
-	connector->ddcdev = sc->sc_ddcdev;
-	if (!connector->ddcdev)
+	connector->ddc = sc->sc_ddc;
+	if (!connector->ddc)
 		DRM_ERROR("failed to find ddc device for connector\n");
 
 	return 0;
@@ -1127,7 +1129,7 @@ tegra_connector_detect(struct drm_connec
 		return connector_status_connected;
 	}
 
-	con = tegra_gpio_read(tegra_connector->hpd);
+	con = fdtbus_gpio_read(tegra_connector->hpd);
 	if (con) {
 		return connector_status_connected;
 	} else {
@@ -1156,10 +1158,10 @@ tegra_connector_get_modes(struct drm_con
 	struct edid *pedid = NULL;
 	int error, block;
 
-	if (tegra_connector->ddcdev) {
+	if (tegra_connector->ddc) {
 		memset(edid, 0, sizeof(edid));
 		for (block = 0; block < 4; block++) {
-			error = ddc_dev_read_edid_block(tegra_connector->ddcdev,
+			error = ddc_read_edid_block(tegra_connector->ddc,
 			    &edid[block * EDID_LENGTH], EDID_LENGTH, block);
 			if (error)
 				break;

Index: src/sys/arch/arm/nvidia/tegra_ehci.c
diff -u src/sys/arch/arm/nvidia/tegra_ehci.c:1.10 src/sys/arch/arm/nvidia/tegra_ehci.c:1.11
--- src/sys/arch/arm/nvidia/tegra_ehci.c:1.10	Thu Nov 19 22:09:16 2015
+++ src/sys/arch/arm/nvidia/tegra_ehci.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_ehci.c,v 1.10 2015/11/19 22:09:16 jmcneill Exp $ */
+/* $NetBSD: tegra_ehci.c,v 1.11 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.10 2015/11/19 22:09:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.11 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -49,6 +47,24 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c
 #include <arm/nvidia/tegra_var.h>
 #include <arm/nvidia/tegra_usbreg.h>
 
+#include <dev/fdt/fdtvar.h>
+
+/* XXX */
+static int
+tegra_ehci_addr2port(bus_addr_t addr)
+{
+	switch (addr) {
+	case TEGRA_AHB_A2_BASE + TEGRA_USB1_OFFSET:
+		return 0;
+	case TEGRA_AHB_A2_BASE + TEGRA_USB2_OFFSET:
+		return 1;
+	case TEGRA_AHB_A2_BASE + TEGRA_USB3_OFFSET:
+		return 2;
+	default:
+		return -1;
+	}
+}
+
 #define TEGRA_EHCI_REG_OFFSET	0x100
 
 static int	tegra_ehci_match(device_t, cfdata_t, void *);
@@ -62,8 +78,6 @@ struct tegra_ehci_softc {
 	bus_space_handle_t	sc_bsh;
 	void			*sc_ih;
 	u_int			sc_port;
-
-	device_t		sc_usbphydev;
 };
 
 static int	tegra_ehci_port_status(struct ehci_softc *sc, uint32_t v,
@@ -76,36 +90,44 @@ CFATTACH_DECL2_NEW(tegra_ehci, sizeof(st
 static int
 tegra_ehci_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-ehci", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_ehci_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_ehci_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
-	struct tegrausbphy_attach_args tup;
+	struct fdt_attach_args * const faa = aux;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
 	int error;
 
-	sc->sc_bst = tio->tio_bst;
-	error = bus_space_map(sc->sc_bst, TEGRA_AHB_A2_BASE + loc->loc_offset,
-	    loc->loc_size, 0, &sc->sc_bsh);
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	sc->sc_bst = faa->faa_bst;
+	sc->sc_port = tegra_ehci_addr2port(addr);
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
 	if (error) {
-		aprint_error(": couldn't map USB%d\n", loc->loc_port + 1);
+		aprint_error(": couldn't map USB%d\n", sc->sc_port + 1);
 		return;
 	}
-	sc->sc_port = loc->loc_port;
 
 	sc->sc.sc_dev = self;
 	sc->sc.sc_bus.hci_private = &sc->sc;
-	sc->sc.sc_bus.dmatag = tio->tio_dmat;
+	sc->sc.sc_bus.dmatag = faa->faa_dmat;
 	sc->sc.sc_bus.usbrev = USBREV_2_0;
 	sc->sc.sc_ncomp = 0;
 	sc->sc.sc_flags = EHCIF_ETTF;
 	sc->sc.sc_id_vendor = 0x10de;
 	strlcpy(sc->sc.sc_vendor, "Tegra", sizeof(sc->sc.sc_vendor));
-	sc->sc.sc_size = loc->loc_size - TEGRA_EHCI_REG_OFFSET;
+	sc->sc.sc_size = size - TEGRA_EHCI_REG_OFFSET;
 	sc->sc.iot = sc->sc_bst;
 	bus_space_subregion(sc->sc_bst, sc->sc_bsh, TEGRA_EHCI_REG_OFFSET,
 	    sc->sc.sc_size, &sc->sc.ioh);
@@ -113,23 +135,23 @@ tegra_ehci_attach(device_t parent, devic
 	sc->sc.sc_vendor_port_status = tegra_ehci_port_status;
 
 	aprint_naive("\n");
-	aprint_normal(": USB%d\n", loc->loc_port + 1);
+	aprint_normal(": USB%d\n", sc->sc_port + 1);
 
 	sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH);
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_USB, IST_LEVEL,
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_USB, 0,
 	    ehci_intr, &sc->sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "couldn't establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
-
-	tup.tup_bst = sc->sc_bst;
-	tup.tup_bsh = sc->sc_bsh;
-	tup.tup_port = sc->sc_port;
-	sc->sc_usbphydev = config_found_ia(self, "tegrausbphybus", &tup, NULL);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	error = ehci_init(&sc->sc);
 	if (error != USBD_NORMAL_COMPLETION) {

Index: src/sys/arch/arm/nvidia/tegra_i2c.c
diff -u src/sys/arch/arm/nvidia/tegra_i2c.c:1.8 src/sys/arch/arm/nvidia/tegra_i2c.c:1.9
--- src/sys/arch/arm/nvidia/tegra_i2c.c:1.8	Thu Nov 12 10:31:29 2015
+++ src/sys/arch/arm/nvidia/tegra_i2c.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_i2c.c,v 1.8 2015/11/12 10:31:29 jmcneill Exp $ */
+/* $NetBSD: tegra_i2c.c,v 1.9 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_i2c.c,v 1.8 2015/11/12 10:31:29 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_i2c.c,v 1.9 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -44,9 +42,39 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_i2c.c,
 #include <arm/nvidia/tegra_i2creg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
+/* XXX */
+static int
+tegra_i2c_addr2port(bus_addr_t addr)
+{
+	switch (addr) {
+	case TEGRA_APB_BASE + TEGRA_I2C1_OFFSET:
+		return 0;
+	case TEGRA_APB_BASE + TEGRA_I2C2_OFFSET:
+		return 1;
+	case TEGRA_APB_BASE + TEGRA_I2C3_OFFSET:
+		return 2;
+	case TEGRA_APB_BASE + TEGRA_I2C4_OFFSET:
+		return 3;
+	case TEGRA_APB_BASE + TEGRA_I2C5_OFFSET:
+		return 4;
+	case TEGRA_APB_BASE + TEGRA_I2C6_OFFSET:
+		return 5;
+	default:
+		return -1;
+	}
+}
+
 static int	tegra_i2c_match(device_t, cfdata_t, void *);
 static void	tegra_i2c_attach(device_t, device_t, void *);
 
+static i2c_tag_t tegra_i2c_get_tag(device_t);
+
+struct fdtbus_i2c_controller_func tegra_i2c_funcs = {
+	.get_tag = tegra_i2c_get_tag
+};
+
 struct tegra_i2c_softc {
 	device_t		sc_dev;
 	bus_space_tag_t		sc_bst;
@@ -87,48 +115,63 @@ CFATTACH_DECL_NEW(tegra_i2c, sizeof(stru
 static int
 tegra_i2c_match(device_t parent, cfdata_t cf, void *aux)
 {
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
-
-	if (loc->loc_port == TEGRAIOCF_PORT_DEFAULT)
-		return 0;
+	const char * const compatible[] = { "nvidia,tegra124-i2c", NULL };
+	struct fdt_attach_args * const faa = aux;
 
-	return 1;
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_i2c_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_i2c_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
+	struct fdt_attach_args * const faa = aux;
 	struct i2cbus_attach_args iba;
+	prop_dictionary_t devs;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	u_int address_cells;
+	int len, error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
 
 	sc->sc_dev = self;
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
-	sc->sc_port = loc->loc_port;
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
+	sc->sc_port = tegra_i2c_addr2port(addr);
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
 	cv_init(&sc->sc_cv, device_xname(self));
 
 	aprint_naive("\n");
-	aprint_normal(": I2C%d\n", loc->loc_port + 1);
+	aprint_normal(": I2C%d\n", sc->sc_port + 1);
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_VM, IST_LEVEL|IST_MPSAFE,
-	    tegra_i2c_intr, sc);
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM,
+	    FDT_INTR_MPSAFE, tegra_i2c_intr, sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "couldn't establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	/*
 	 * Recommended setting for standard mode is to use an I2C source div
 	 * of 20 (Tegra K1 Technical Reference Manual, Table 137)
 	 */
-	tegra_car_periph_i2c_enable(loc->loc_port, 20400000);
+	tegra_car_periph_i2c_enable(sc->sc_port, 20400000);
 
 	tegra_i2c_init(sc);
 
@@ -137,10 +180,39 @@ tegra_i2c_attach(device_t parent, device
 	sc->sc_ic.ic_release_bus = tegra_i2c_release_bus;
 	sc->sc_ic.ic_exec = tegra_i2c_exec;
 
+	fdtbus_register_i2c_controller(self, faa->faa_phandle,
+	    &tegra_i2c_funcs);
+
+	devs = prop_dictionary_create();
+	len = OF_getprop(faa->faa_phandle, "#address-cells",
+	    &address_cells, sizeof(address_cells));
+	if (len == sizeof(address_cells)) {
+		address_cells = be32toh(address_cells);
+	} else {
+		address_cells = 1;
+	}
+	of_enter_i2c_devs(devs, faa->faa_phandle, address_cells * 4, 0);
+
 	iba.iba_tag = &sc->sc_ic;
+	iba.iba_child_devices = prop_dictionary_get(devs, "i2c-child-devices");
+	if (iba.iba_child_devices != NULL) {
+		prop_object_retain(iba.iba_child_devices);
+	} else {
+		iba.iba_child_devices = prop_array_create();
+	}
+	prop_object_release(devs);
+
 	sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print);
 }
 
+static i2c_tag_t
+tegra_i2c_get_tag(device_t dev)
+{
+	struct tegra_i2c_softc * const sc = device_private(dev);
+
+	return &sc->sc_ic;
+}
+
 static void
 tegra_i2c_init(struct tegra_i2c_softc *sc)
 {

Index: src/sys/arch/arm/nvidia/tegra_pcie.c
diff -u src/sys/arch/arm/nvidia/tegra_pcie.c:1.13 src/sys/arch/arm/nvidia/tegra_pcie.c:1.14
--- src/sys/arch/arm/nvidia/tegra_pcie.c:1.13	Thu Nov 19 22:09:16 2015
+++ src/sys/arch/arm/nvidia/tegra_pcie.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_pcie.c,v 1.13 2015/11/19 22:09:16 jmcneill Exp $ */
+/* $NetBSD: tegra_pcie.c,v 1.14 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,10 +26,8 @@
  * SUCH DAMAGE.
  */
 
-#include "locators.h"
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.13 2015/11/19 22:09:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.14 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -52,6 +50,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c
 #include <arm/nvidia/tegra_pciereg.h>
 #include <arm/nvidia/tegra_var.h>
 
+#include <dev/fdt/fdtvar.h>
+
 static int	tegra_pcie_match(device_t, cfdata_t, void *);
 static void	tegra_pcie_attach(device_t, device_t, void *);
 
@@ -71,7 +71,7 @@ struct tegra_pcie_softc {
 	bus_space_tag_t		sc_bst;
 	bus_space_handle_t	sc_bsh_afi;
 	bus_space_handle_t	sc_bsh_rpconf;
-	int			sc_intr;
+	int			sc_phandle;
 
 	struct arm32_pci_chipset sc_pc;
 
@@ -119,29 +119,55 @@ CFATTACH_DECL_NEW(tegra_pcie, sizeof(str
 static int
 tegra_pcie_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-pcie", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 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 fdt_attach_args * const faa = aux;
 	struct extent *ioext, *memext, *pmemext;
 	struct pcibus_attach_args pba;
+	bus_addr_t afi_addr, cs_addr;
+	bus_size_t afi_size, cs_size;
+	char intrstr[128];
 	int error;
 
+	if (fdtbus_get_reg(faa->faa_phandle, 1, &afi_addr, &afi_size) != 0) {
+		aprint_error(": couldn't get afi registers\n");
+		return;
+	}
+#if notyet
+	if (fdtbus_get_reg(faa->faa_phandle, 2, &cs_addr, &cs_size) != 0) {
+		aprint_error(": couldn't get cs registers\n");
+		return;
+	}
+#else
+	cs_addr = TEGRA_PCIE_RPCONF_BASE;
+	cs_size = TEGRA_PCIE_RPCONF_SIZE;
+#endif
+
 	sc->sc_dev = self;
-	sc->sc_dmat = tio->tio_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_RPCONF_BASE,
-	    TEGRA_PCIE_RPCONF_SIZE, 0, &sc->sc_bsh_rpconf) != 0)
-		panic("couldn't map PCIE root ports");
+	sc->sc_dmat = faa->faa_dmat;
+	sc->sc_bst = faa->faa_bst;
+	sc->sc_phandle = faa->faa_phandle;
+	error = bus_space_map(sc->sc_bst, afi_addr, afi_size, 0,
+	    &sc->sc_bsh_afi);
+	if (error) {
+		aprint_error(": couldn't map afi registers: %d\n", error);
+		return;
+	}
+	error = bus_space_map(sc->sc_bst, cs_addr, cs_size, 0,
+	    &sc->sc_bsh_rpconf);
+	if (error) {
+		aprint_error(": couldn't map cs registers: %d\n", error);
+		return;
+	}
+
 	tegra_pcie_conf_map_buses(sc);
 
 	TAILQ_INIT(&sc->sc_intrs);
@@ -150,14 +176,19 @@ tegra_pcie_attach(device_t parent, devic
 	aprint_naive("\n");
 	aprint_normal(": PCIE\n");
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_VM, IST_LEVEL,
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM, 0,
 	    tegra_pcie_intr, sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "failed to establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "failed to establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	tegra_pcie_setup(sc);
 
@@ -514,9 +545,7 @@ static void
 tegra_pcie_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz,
     int *ilinep)
 {
-	const struct tegra_pcie_softc * const sc = v;
-
-	*ilinep = sc->sc_intr & PCI_INTERRUPT_LINE_MASK;
+	*ilinep = 5;
 }
 
 static int
@@ -536,7 +565,9 @@ tegra_pcie_intr_string(void *v, pci_intr
 	if (ih == PCI_INTERRUPT_PIN_NONE)
 		return NULL;
 
-	snprintf(buf, len, "irq %d", sc->sc_intr);
+	if (!fdtbus_intr_str(sc->sc_phandle, 0, buf, len))
+		return NULL;
+
 	return buf;
 }
 

Index: src/sys/arch/arm/nvidia/tegra_sdhc.c
diff -u src/sys/arch/arm/nvidia/tegra_sdhc.c:1.11 src/sys/arch/arm/nvidia/tegra_sdhc.c:1.12
--- src/sys/arch/arm/nvidia/tegra_sdhc.c:1.11	Mon Aug  3 12:11:52 2015
+++ src/sys/arch/arm/nvidia/tegra_sdhc.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_sdhc.c,v 1.11 2015/08/03 12:11:52 jmcneill Exp $ */
+/* $NetBSD: tegra_sdhc.c,v 1.12 2015/12/13 17:39:19 jmcneill 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_sdhc.c,v 1.11 2015/08/03 12:11:52 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_sdhc.c,v 1.12 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -42,10 +42,28 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_sdhc.c
 #include <dev/sdmmc/sdhcvar.h>
 #include <dev/sdmmc/sdmmcvar.h>
 
+#include <arm/nvidia/tegra_reg.h>
 #include <arm/nvidia/tegra_var.h>
 
-/* 8-bit eMMC is supported on SDMMC2 and SDMMC4 */
-#define SDMMC_8BIT_P(port)	((port) == 1 || (port) == 3)
+#include <dev/fdt/fdtvar.h>
+
+/* XXX */
+static int
+tegra_sdhc_addr2port(bus_addr_t addr)
+{
+	switch (addr) {
+	case TEGRA_APB_BASE + TEGRA_SDMMC1_OFFSET:
+		return 0;
+	case TEGRA_APB_BASE + TEGRA_SDMMC2_OFFSET:
+		return 1;
+	case TEGRA_APB_BASE + TEGRA_SDMMC3_OFFSET:
+		return 2;
+	case TEGRA_APB_BASE + TEGRA_SDMMC4_OFFSET:
+		return 3;
+	default:
+		return -1;
+	}
+}
 
 static int	tegra_sdhc_match(device_t, cfdata_t, void *);
 static void	tegra_sdhc_attach(device_t, device_t, void *);
@@ -64,9 +82,9 @@ struct tegra_sdhc_softc {
 	struct sdhc_host	*sc_host;
 	void			*sc_ih;
 
-	struct tegra_gpio_pin	*sc_pin_cd;
-	struct tegra_gpio_pin	*sc_pin_power;
-	struct tegra_gpio_pin	*sc_pin_wp;
+	struct fdtbus_gpio_pin	*sc_pin_cd;
+	struct fdtbus_gpio_pin	*sc_pin_power;
+	struct fdtbus_gpio_pin	*sc_pin_wp;
 };
 
 CFATTACH_DECL_NEW(tegra_sdhc, sizeof(struct tegra_sdhc_softc),
@@ -75,21 +93,37 @@ CFATTACH_DECL_NEW(tegra_sdhc, sizeof(str
 static int
 tegra_sdhc_match(device_t parent, cfdata_t cf, void *aux)
 {
-	return 1;
+	const char * const compatible[] = { "nvidia,tegra124-sdhci", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
 static void
 tegra_sdhc_attach(device_t parent, device_t self, void *aux)
 {
 	struct tegra_sdhc_softc * const sc = device_private(self);
-	struct tegraio_attach_args * const tio = aux;
-	const struct tegra_locators * const loc = &tio->tio_loc;
-	prop_dictionary_t prop = device_properties(self);
-	const char *pin;
+	struct fdt_attach_args * const faa = aux;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	u_int bus_width;
 	int error;
 
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	if (OF_getprop(faa->faa_phandle, "bus-width", &bus_width,
+	    sizeof(bus_width)) == sizeof(bus_width)) {
+		bus_width = be32toh(bus_width);
+	} else {
+		bus_width = 4;
+	}
+
 	sc->sc.sc_dev = self;
-	sc->sc.sc_dmat = tio->tio_dmat;
+	sc->sc.sc_dmat = faa->faa_dmat;
 	sc->sc.sc_flags = SDHC_FLAG_32BIT_ACCESS |
 			  SDHC_FLAG_NO_PWR0 |
 			  SDHC_FLAG_NO_CLKBASE |
@@ -97,60 +131,68 @@ tegra_sdhc_attach(device_t parent, devic
 			  SDHC_FLAG_SINGLE_POWER_WRITE |
 			  SDHC_FLAG_USE_DMA |
 			  SDHC_FLAG_USE_ADMA2;
-	if (SDMMC_8BIT_P(loc->loc_port)) {
+	if (bus_width == 8) {
 		sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
 	}
 	sc->sc.sc_host = &sc->sc_host;
 
-	sc->sc_bst = tio->tio_bst;
-	bus_space_subregion(tio->tio_bst, tio->tio_bsh,
-	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
-	sc->sc_bsz = loc->loc_size;
-	sc->sc_port = loc->loc_port;
-
-	if (prop_dictionary_get_cstring_nocopy(prop, "power-gpio", &pin)) {
-		sc->sc_pin_power = tegra_gpio_acquire(pin, GPIO_PIN_OUTPUT);
-		if (sc->sc_pin_power)
-			tegra_gpio_write(sc->sc_pin_power, 1);
-	}
-
-	if (prop_dictionary_get_cstring_nocopy(prop, "cd-gpio", &pin))
-		sc->sc_pin_cd = tegra_gpio_acquire(pin, GPIO_PIN_INPUT);
-	if (prop_dictionary_get_cstring_nocopy(prop, "wp-gpio", &pin))
-		sc->sc_pin_wp = tegra_gpio_acquire(pin, GPIO_PIN_INPUT);
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
+	sc->sc_bsz = size;
+	sc->sc_port = tegra_sdhc_addr2port(addr);
+
+	sc->sc_pin_power = fdtbus_gpio_acquire(faa->faa_phandle,
+	    "power-gpios", GPIO_PIN_OUTPUT);
+	if (sc->sc_pin_power)
+		fdtbus_gpio_write(sc->sc_pin_power, 1);
+
+	sc->sc_pin_cd = fdtbus_gpio_acquire(faa->faa_phandle, 
+	    "cd-gpios", GPIO_PIN_INPUT);
+	sc->sc_pin_wp = fdtbus_gpio_acquire(faa->faa_phandle,
+	    "wp-gpios", GPIO_PIN_INPUT);
 
 	if (sc->sc_pin_cd) {
 		sc->sc.sc_vendor_card_detect = tegra_sdhc_card_detect;
 		sc->sc.sc_flags |= SDHC_FLAG_POLL_CARD_DET;
 	}
-	if (sc->sc_pin_wp)
+	if (sc->sc_pin_wp) {
 		sc->sc.sc_vendor_write_protect = tegra_sdhc_write_protect;
+	}
 
 	tegra_car_periph_sdmmc_set_rate(sc->sc_port, 204000000);
 	sc->sc.sc_clkbase = tegra_car_periph_sdmmc_rate(sc->sc_port) / 1000;
 
 	aprint_naive("\n");
-	aprint_normal(": SDMMC%d\n", loc->loc_port + 1);
+	aprint_normal(": SDMMC%d\n", sc->sc_port + 1);
 
 	if (sc->sc.sc_clkbase == 0) {
 		aprint_error_dev(self, "couldn't determine frequency\n");
 		return;
 	}
 
-	sc->sc_ih = intr_establish(loc->loc_intr, IPL_SDMMC, IST_LEVEL,
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SDMMC, 0,
 	    sdhc_intr, &sc->sc);
 	if (sc->sc_ih == NULL) {
-		aprint_error_dev(self, "couldn't establish interrupt %d\n",
-		    loc->loc_intr);
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
 		return;
 	}
-	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
 	error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_bsh, sc->sc_bsz);
 	if (error) {
 		aprint_error_dev(self, "couldn't initialize host, error = %d\n",
 		    error);
-		intr_disestablish(sc->sc_ih);
+		fdtbus_intr_disestablish(faa->faa_phandle, sc->sc_ih);
 		sc->sc_ih = NULL;
 		return;
 	}
@@ -163,7 +205,7 @@ tegra_sdhc_card_detect(struct sdhc_softc
 
 	KASSERT(sc->sc_pin_cd != NULL);
 
-	return !tegra_gpio_read(sc->sc_pin_cd);
+	return !fdtbus_gpio_read(sc->sc_pin_cd);
 }
 
 static int
@@ -173,5 +215,5 @@ tegra_sdhc_write_protect(struct sdhc_sof
 
 	KASSERT(sc->sc_pin_wp != NULL);
 
-	return tegra_gpio_read(sc->sc_pin_wp);
+	return fdtbus_gpio_read(sc->sc_pin_wp);
 }

Index: src/sys/arch/evbarm/conf/JETSONTK1
diff -u src/sys/arch/evbarm/conf/JETSONTK1:1.41 src/sys/arch/evbarm/conf/JETSONTK1:1.42
--- src/sys/arch/evbarm/conf/JETSONTK1:1.41	Sat Nov 21 22:55:46 2015
+++ src/sys/arch/evbarm/conf/JETSONTK1	Sun Dec 13 17:39:19 2015
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: JETSONTK1,v 1.41 2015/11/21 22:55:46 jmcneill Exp $
+#	$NetBSD: JETSONTK1,v 1.42 2015/12/13 17:39:19 jmcneill Exp $
 #
 #	NVIDIA Jetson TK1 - Tegra K1 development kit
 #	https://developer.nvidia.com/jetson-tk1
@@ -14,6 +14,9 @@ options 	BOARD_JETSONTK1
 options 	MULTIPROCESSOR
 #options 	MEMSIZE=2048
 
+options 	FDT		# Flattened Device Tree support
+pseudo-device 	openfirm	# /dev/openfirm
+
 options 	DIAGNOSTIC	# internal consistency checks
 #options 	DEBUG
 #options 	LOCKDEBUG
@@ -34,37 +37,44 @@ armgic0		at armperiph?				# Interrupt Co
 armgtmr0	at armperiph?				# ARM Generic Timer
 
 # On-board I/O
-tegraio0	at mainbus?
+tegrafdt0	at mainbus?
+fdt0		at tegrafdt0 
+simplebus*	at fdt?
+fdt*		at simplebus?
+
+fregulator*	at fdt?
+
+# Interrupt controller
+tegralic*	at fdt?			# LIC
+gic*		at fdt?			# GIC
 
 # Memory controller
-tegramc0	at tegraio?		# MC
+tegramc*	at fdt?			# MC
 
 # FUSE controller
-tegrafuse0	at tegraio?		# FUSE
+tegrafuse*	at fdt?			# FUSE
 
 # Power management controller
-tegrapmc0	at tegraio?		# PMC
+tegrapmc*	at fdt?			# PMC
 
 # Clock and Reset controller
-tegracar0	at tegraio?		# CAR
+tegracar0	at fdt?			# CAR
 
 # GPIO controller
-tegragpio0	at tegraio?		# GPIO
+tegragpio*	at fdt?			# GPIO
 gpio*		at gpiobus?
-gpiobutton0	at gpio16 offset 0 mask 1 flag 0x01	# Power button
-gpiorfkill0	at gpio23 offset 7 mask 1		# WiFi enable
 
 # Timers
-tegratimer0	at tegraio?		# Timers
+tegratimer*	at fdt?			# Timers
 
 # MPIO / Pinmux
-tegrampio0	at tegraio?		# MPIO
+tegrampio*	at fdt?			# MPIO
 
 # XUSB PADCTL
-tegraxusbpad0	at tegraio?		# XUSB PADCTL
+tegraxusbpad*	at fdt?			# XUSB PADCTL
 
 # PCIE
-tegrapcie0	at tegraio?		# PCIE
+tegrapcie0	at fdt?			# PCIE
 pci*		at tegrapcie0
 ppb*		at pci? dev ? function ?
 pci*		at ppb?
@@ -80,46 +90,38 @@ ath*		at pci? dev ? function ?	# Atheros
 athn*		at pci? dev ? function ?	# Atheros IEEE 802.11
 
 # UART
-com3		at tegraio? port 3	# UART-D
+com*		at fdt?			# UART
 options 	CONSADDR=0x70006300, CONSPEED=115200
 
 # I2C
-tegrai2c0	at tegraio? port 0	# I2C1
-iic0		at tegrai2c0
-titemp0		at iic0 addr 0x4c		# TI TMP451 
-seeprom0	at iic0 addr 0x56 size 256	# Atmel 24C02 serial EEPROM
-tegrai2c1	at tegraio? port 1	# I2C2
-iic1		at tegrai2c1
-tegrai2c2	at tegraio? port 2	# I2C3
-iic2		at tegrai2c2
-tegrai2c3	at tegraio? port 3	# I2C4
-iic3		at tegrai2c3
-ddc0		at iic3 addr 0x50		# HDMI DDC
-tegrai2c4	at tegraio? port 4	# I2C5
-iic4		at tegrai2c4
-as3722pmic0	at iic4 addr 0x40		# AMS AS3722 PMIC
+tegrai2c*	at fdt?			# I2C
+iic*		at tegrai2c?
+titemp*		at iic?
+seeprom*	at iic?
+as3722pmic*	at iic?
+
+#titemp0		at iic0 addr 0x4c		# TI TMP451 
+#seeprom0	at iic0 addr 0x56 size 256	# Atmel 24C02 serial EEPROM
+#ddc0		at iic3 addr 0x50		# HDMI DDC
+#as3722pmic0	at iic4 addr 0x40		# AMS AS3722 PMIC
 
 # RTC
-tegrartc0	at tegraio?		# RTC
+tegrartc*	at fdt?			# RTC
 
 # SDMMC
-sdhc2		at tegraio? port 2	# SDMMC3 (SD card)
-sdmmc2		at sdhc2
-sdhc3		at tegraio? port 3	# SDMMC4 (eMMC)
-sdmmc3		at sdhc3
-
-ld0		at sdmmc3		# eMMC
-ld1		at sdmmc2		# SD card
+sdhc*		at fdt?			# SDMMC
+sdmmc*		at sdhc?
+ld*		at sdmmc?
 
 # SATA
-ahcisata0	at tegraio?		# SATA
+ahcisata*	at fdt?			# SATA
 atabus*		at ata?
 atapibus*	at atapi?
 wd*		at atabus? drive ?
 cd*		at atapibus? drive ?
 
 # HDA
-hdaudio*	at tegraio?		# HDA
+hdaudio*	at fdt?			# HDA
 hdafg*		at hdaudiobus?
 audio*		at audiobus?
 options 	HDAUDIOVERBOSE
@@ -128,14 +130,11 @@ options 	HDAUDIO_ENABLE_HDMI
 options 	HDAUDIO_ENABLE_DISPLAYPORT
 
 # HDMI CEC
-tegracec0	at tegraio?		# HDMI CEC
+tegracec0	at fdt?			# HDMI CEC
 hdmicec*	at hdmicecbus?
 
-# Host1x subsystem
-tegrahost1x0	at tegraio?		# HOST1X
-
 # Display
-tegradrm0	at tegraio?		# Display
+tegradrm*	at fdt?			# Display
 tegrafb*	at tegrafbbus?
 wsdisplay*	at wsemuldisplaydev?
 options 	VCONS_DRAW_INTR
@@ -153,17 +152,15 @@ pseudo-device	wsmux
 pseudo-device	wsfont
 
 # GPU
-#nouveau0	at tegraio?		# GPU
+#nouveau0	at fdt?			# GPU
 
 # Thermal throttling controller
-tegrasoctherm0	at tegraio?		# SOC_THERM
+tegrasoctherm*	at fdt?			# SOC_THERM
 
 # USB 2.0
-tegraehci0	at tegraio? port 0	# USB1
-tegraehci1	at tegraio? port 1	# USB2
-tegraehci2	at tegraio? port 2	# USB3
-tegrausbphy*	at tegrausbphybus?	# USB PHY
-usb*		at tegraehci?
+tegrausbphy*	at fdt?			# USB PHY
+ehci*		at fdt?			# USB
+usb*		at ehci?
 
 include "dev/usb/usbdevices.config"
 midi*		at midibus?

Index: src/sys/arch/evbarm/conf/files.tegra
diff -u src/sys/arch/evbarm/conf/files.tegra:1.1 src/sys/arch/evbarm/conf/files.tegra:1.2
--- src/sys/arch/evbarm/conf/files.tegra:1.1	Sun Mar 29 10:41:59 2015
+++ src/sys/arch/evbarm/conf/files.tegra	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.tegra,v 1.1 2015/03/29 10:41:59 jmcneill Exp $
+#	$NetBSD: files.tegra,v 1.2 2015/12/13 17:39:19 jmcneill Exp $
 #
 # NVIDIA Tegra configuration info
 #
@@ -7,4 +7,8 @@ file	arch/evbarm/tegra/tegra_machdep.c
 
 defparam opt_machdep.h				BOOT_ARGS
 
+include "dev/ofw/files.ofw"
+include "dev/fdt/files.fdt"
+include "arch/arm/fdt/files.fdt"
+
 include "arch/arm/nvidia/files.tegra"

Index: src/sys/arch/evbarm/conf/mk.tegra
diff -u src/sys/arch/evbarm/conf/mk.tegra:1.2 src/sys/arch/evbarm/conf/mk.tegra:1.3
--- src/sys/arch/evbarm/conf/mk.tegra:1.2	Sun Apr 26 16:11:57 2015
+++ src/sys/arch/evbarm/conf/mk.tegra	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: mk.tegra,v 1.2 2015/04/26 16:11:57 jmcneill Exp $
+#	$NetBSD: mk.tegra,v 1.3 2015/12/13 17:39:19 jmcneill Exp $
 CPPFLAGS+=		-mcpu=cortex-a15 -mfpu=neon
 
 SYSTEM_FIRST_OBJ=	tegra_start.o
@@ -8,7 +8,7 @@ GENASSYM_EXTRAS+=	${THISARM}/tegra/genas
 
 _OSRELEASE!=		${HOST_SH} $S/conf/osrelease.sh
 
-MKUBOOTIMAGEARGS=	-A arm -T kernel
+MKUBOOTIMAGEARGS=	-A arm -T kernel -O linux
 MKUBOOTIMAGEARGS+=	-a $(KERNEL_BASE_PHYS) -e $(KERNEL_BASE_PHYS)
 MKUBOOTIMAGEARGS+=	-n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}"
 MKUBOOTIMAGEARGS_NONE=	${MKUBOOTIMAGEARGS} -C none

Index: src/sys/arch/evbarm/tegra/tegra_machdep.c
diff -u src/sys/arch/evbarm/tegra/tegra_machdep.c:1.33 src/sys/arch/evbarm/tegra/tegra_machdep.c:1.34
--- src/sys/arch/evbarm/tegra/tegra_machdep.c:1.33	Sat Nov 21 12:22:25 2015
+++ src/sys/arch/evbarm/tegra/tegra_machdep.c	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_machdep.c,v 1.33 2015/11/21 12:22:25 jmcneill Exp $ */
+/* $NetBSD: tegra_machdep.c,v 1.34 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.33 2015/11/21 12:22:25 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.34 2015/12/13 17:39:19 jmcneill Exp $");
 
 #include "opt_tegra.h"
 #include "opt_machdep.h"
@@ -105,6 +105,13 @@ char *boot_args = NULL;
 u_int uboot_args[4] = { 0 };	/* filled in by tegra_start.S (not in bss) */
 #endif
 
+#include <libfdt.h>
+#include <dev/fdt/fdt_openfirm.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/fdt/fdtvar.h>
+#define FDT_BUF_SIZE	(128*1024)
+static uint8_t fdt_data[FDT_BUF_SIZE];
+
 extern char KERNEL_BASE_phys[];
 #define KERNEL_BASE_PHYS ((paddr_t)KERNEL_BASE_phys)
 
@@ -256,6 +263,37 @@ initarm(void *arg)
 	parse_mi_bootargs(mi_bootargs);
 #endif
 
+	const uint8_t *fdt_addr_r = (const uint8_t *)uboot_args[2];
+	int error = fdt_check_header(fdt_addr_r);
+	if (error == 0) {
+		error = fdt_move(fdt_addr_r, fdt_data, sizeof(fdt_data));
+		if (error != 0) {
+			panic("fdt_move failed: %s", fdt_strerror(error));
+		}
+		fdt_openfirm_set_data(fdt_data);
+	} else {
+		panic("fdt_check_header failed: %s", fdt_strerror(error));
+	}
+
+	const u_int chip_id = tegra_chip_id();
+	switch (chip_id) {
+#ifdef SOC_TEGRA124
+        case CHIP_ID_TEGRA124: {
+		const char * const tegra124_compatible_strings[] = {
+			"nvidia,tegra124",
+			NULL
+		};
+		const int node = OF_peer(0);
+                if (of_compatible(node, tegra124_compatible_strings) < 0) {
+			panic("FDT is not compatible with Tegra124");
+		}
+                break;
+	}
+#endif
+	default:
+		panic("Kernel does not support Tegra SOC ID %#x", chip_id);
+	}
+
 	DPRINTF("KERNEL_BASE=0x%x, KERNEL_VM_BASE=0x%x, KERNEL_VM_BASE - KERNEL_BASE=0x%x, KERNEL_BASE_VOFFSET=0x%x\n",
 		KERNEL_BASE, KERNEL_VM_BASE, KERNEL_VM_BASE - KERNEL_BASE, KERNEL_BASE_VOFFSET);
 
@@ -302,6 +340,11 @@ initarm(void *arg)
 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, devmap,
 	    mapallmem_p);
 
+	const int chosen = OF_finddevice("/chosen");
+	if (chosen >= 0) {
+		OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs));
+	}
+
 	DPRINTF("bootargs: %s\n", bootargs);
 
 	boot_args = bootargs;
@@ -442,86 +485,20 @@ tegra_device_register(device_t self, voi
 			prop_dictionary_set_cstring(dict, "debug", debug);
 	}
 
-#ifdef SOC_TEGRA124
-	if (device_is_a(self, "tegrausbphy")) {
-		prop_dictionary_set_uint8(dict, "nvidia,hssync-start-delay", 0);
-		prop_dictionary_set_uint8(dict, "nvidia,idle-wait-delay", 17);
-		prop_dictionary_set_uint8(dict, "nvidia,elastic-limit", 16);
-		prop_dictionary_set_uint8(dict, "nvidia,term-range-adj", 6);
-		prop_dictionary_set_uint8(dict, "nvidia,xcvr-setup", 9);
-		prop_dictionary_set_uint8(dict, "nvidia,xcvr-lsfslew", 0);
-		prop_dictionary_set_uint8(dict, "nvidia,xcvr-lsrslew", 3);
-		prop_dictionary_set_uint8(dict, "nvidia,hssquelch-level", 2);
-		prop_dictionary_set_uint8(dict, "nvidia,hsdiscon-level", 5);
-		prop_dictionary_set_uint8(dict, "nvidia,xcvr-hsslew", 12);
-	}
-#endif
-
-#ifdef BOARD_JETSONTK1
-	if (device_is_a(self, "sdhc")
-	    && device_is_a(device_parent(self), "tegraio")) {
-		struct tegraio_attach_args * const tio = aux;
-		const struct tegra_locators * const loc = &tio->tio_loc;
-
-		if (loc->loc_port == 2) {
-			prop_dictionary_set_cstring(dict, "cd-gpio", "V2");
-			prop_dictionary_set_cstring(dict, "power-gpio", "R0");
-			prop_dictionary_set_cstring(dict, "wp-gpio", "Q4");
-		}
-	}
-
-	if (device_is_a(self, "ahcisata")
-	    && device_is_a(device_parent(self), "tegraio")) {
-		prop_dictionary_set_cstring(dict, "power-gpio", "EE2");
-	}
-
-	if (device_is_a(self, "tegrausbphy")) {
-		struct tegrausbphy_attach_args * const tup = aux;
-
-		if (tup->tup_port == 0) {
-			prop_dictionary_set_cstring(dict, "vbus-gpio", "N4");
-		} else if (tup->tup_port == 2) {
-			prop_dictionary_set_cstring(dict, "vbus-gpio", "N5");
-		}
-	}
-
-	if (device_is_a(self, "tegradrm")) {
-		prop_dictionary_set_cstring(dict, "hpd-gpio", "N7");
-		prop_dictionary_set_cstring(dict, "pll-gpio", "H7");
-		prop_dictionary_set_cstring(dict, "power-gpio", "K6");
-		prop_dictionary_set_cstring(dict, "ddc-device", "ddc0");
-	}
-#endif
-
-#ifdef BOARD_NYAN_BIG
-	if (device_is_a(self, "sdhc")
-	    && device_is_a(device_parent(self), "tegraio")) {
-		struct tegraio_attach_args * const tio = aux;
-		const struct tegra_locators * const loc = &tio->tio_loc;
-
-		if (loc->loc_port == 2) {
-			prop_dictionary_set_cstring(dict, "cd-gpio", "V2");
-			prop_dictionary_set_cstring(dict, "power-gpio", "R0");
-		}
-	}
-
-	if (device_is_a(self, "tegrausbphy")) {
-		struct tegrausbphy_attach_args * const tup = aux;
-
-		if (tup->tup_port == 0) {
-			prop_dictionary_set_cstring(dict, "vbus-gpio", "N4");
-		} else if (tup->tup_port == 2) {
-			prop_dictionary_set_cstring(dict, "vbus-gpio", "N5");
+	if (device_is_a(self, "tegrapcie")) {
+		const char * const jetsontk1_compat[] = {
+		    "nvidia,jetson-tk1", NULL
+		};
+		int phandle = OF_peer(0);
+		if (of_match_compatible(phandle, jetsontk1_compat)) {
+			/* rfkill GPIO at GPIO X7 */
+			struct tegra_gpio_pin *pin;
+			pin = tegra_gpio_acquire("X7", GPIO_PIN_OUTPUT);
+			if (pin) {
+				tegra_gpio_write(pin, 1);
+			}
 		}
 	}
-
-	if (device_is_a(self, "tegradrm")) {
-		prop_dictionary_set_cstring(dict, "hpd-gpio", "N7");
-		prop_dictionary_set_cstring(dict, "pll-gpio", "H7");
-		prop_dictionary_set_cstring(dict, "power-gpio", "K6");
-		prop_dictionary_set_cstring(dict, "ddc-device", "ddc0");
-	}
-#endif
 }
 
 static void

Index: src/sys/arch/evbarm/tegra/tegra_start.S
diff -u src/sys/arch/evbarm/tegra/tegra_start.S:1.7 src/sys/arch/evbarm/tegra/tegra_start.S:1.8
--- src/sys/arch/evbarm/tegra/tegra_start.S:1.7	Sat Aug 22 15:10:04 2015
+++ src/sys/arch/evbarm/tegra/tegra_start.S	Sun Dec 13 17:39:19 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_start.S,v 1.7 2015/08/22 15:10:04 jmcneill Exp $ */
+/* $NetBSD: tegra_start.S,v 1.8 2015/12/13 17:39:19 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014, 2015 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
 #include <arm/nvidia/tegra_reg.h>
 #include <evbarm/tegra/platform.h>
 
-RCSID("$NetBSD: tegra_start.S,v 1.7 2015/08/22 15:10:04 jmcneill Exp $")
+RCSID("$NetBSD: tegra_start.S,v 1.8 2015/12/13 17:39:19 jmcneill Exp $")
 
 #if defined(VERBOSE_INIT_ARM)
 #define	XPUTC(n)	mov r0, n; bl xputc
@@ -101,22 +101,6 @@ _C_LABEL(tegra_start):
 	sub	r4, r4, #KERNEL_BASE_VOFFSET
 
 	stmia	r4, {r0-r3}		// Save the arguments
-
-	/*
-	 * Copy the value of the "bootargs" environment variable from r3.
-	 */
-	movw	r4, #:lower16:bootargs
-	movt	r4, #:upper16:bootargs
-	sub	r4, r4, #KERNEL_BASE_VOFFSET
-
-	cmp	r3, #0
-	beq	1f
-2:
-	ldrb	r0, [r3], #1
-	strb	r0, [r4], #1
-	teq	r0, #0
-	bne	2b
-1:
 #endif
 
 	/*

Added files:

Index: src/sys/arch/arm/nvidia/tegra_fdt.c
diff -u /dev/null src/sys/arch/arm/nvidia/tegra_fdt.c:1.1
--- /dev/null	Sun Dec 13 17:39:20 2015
+++ src/sys/arch/arm/nvidia/tegra_fdt.c	Sun Dec 13 17:39:19 2015
@@ -0,0 +1,95 @@
+/* $NetBSD: tegra_fdt.c,v 1.1 2015/12/13 17:39:19 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
+ * 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 "opt_tegra.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_fdt.c,v 1.1 2015/12/13 17:39:19 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/cpu.h>
+#include <sys/bus.h>
+
+#include <arm/mainbus/mainbus.h>
+#include <arm/nvidia/tegra_reg.h>
+#include <arm/nvidia/tegra_var.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/ofw/openfirm.h>
+
+static int	tegrafdt_match(device_t, cfdata_t, void *);
+static void	tegrafdt_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(tegra_fdt, 0,
+    tegrafdt_match, tegrafdt_attach, NULL, NULL);
+
+static bool tegrafdt_found = false;
+
+int
+tegrafdt_match(device_t parent, cfdata_t cf, void *aux)
+{
+	if (tegrafdt_found)
+		return 0;
+	return 1;
+}
+
+void
+tegrafdt_attach(device_t parent, device_t self, void *aux)
+{
+	const char *tegrafdt_init[] = {
+		"interrupt-controller",
+		"clock",
+		"pinmux",
+		"gpio",
+		"regulators",
+		"dma",
+		"pmc",
+		"memory-controller",
+		"i2c",
+		"usb-phy"
+	};
+
+	tegrafdt_found = true;
+
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	struct fdt_attach_args faa = {
+		.faa_name = "",
+		.faa_bst = &armv7_generic_bs_tag,
+		.faa_a4x_bst = &armv7_generic_a4x_bs_tag,
+		.faa_dmat = &tegra_dma_tag,
+		.faa_phandle = OF_peer(0),
+		.faa_init = tegrafdt_init,
+		.faa_ninit = __arraycount(tegrafdt_init)
+	};
+	config_found(self, &faa, NULL);
+}
Index: src/sys/arch/arm/nvidia/tegra_lic.c
diff -u /dev/null src/sys/arch/arm/nvidia/tegra_lic.c:1.1
--- /dev/null	Sun Dec 13 17:39:20 2015
+++ src/sys/arch/arm/nvidia/tegra_lic.c	Sun Dec 13 17:39:19 2015
@@ -0,0 +1,199 @@
+/* $NetBSD: tegra_lic.c,v 1.1 2015/12/13 17:39:19 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_lic.c,v 1.1 2015/12/13 17:39:19 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/kmem.h>
+
+#include <arm/nvidia/tegra_reg.h>
+#include <arm/nvidia/tegra_var.h>
+
+#include <arm/cortex/gic_intr.h>
+
+#include <dev/fdt/fdtvar.h>
+
+static int	tegra_lic_match(device_t, cfdata_t, void *);
+static void	tegra_lic_attach(device_t, device_t, void *);
+
+static void *	tegra_lic_establish(device_t, int, u_int, int, int,
+		    int (*)(void *), void *);
+static void	tegra_lic_disestablish(device_t, void *);
+static bool	tegra_lic_intrstr(device_t, int, u_int, char *, size_t);
+
+struct fdtbus_interrupt_controller_func tegra_lic_funcs = {
+	.establish = tegra_lic_establish,
+	.disestablish = tegra_lic_disestablish,
+	.intrstr = tegra_lic_intrstr
+};
+
+struct tegra_lic_softc {
+	device_t		sc_dev;
+	int			sc_phandle;
+};
+
+CFATTACH_DECL_NEW(tegra_lic, sizeof(struct tegra_lic_softc),
+	tegra_lic_match, tegra_lic_attach, NULL, NULL);
+
+static int
+tegra_lic_match(device_t parent, cfdata_t cf, void *aux)
+{
+	const char * const compatible[] = { "nvidia,tegra124-ictlr", NULL };
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+tegra_lic_attach(device_t parent, device_t self, void *aux)
+{
+	struct tegra_lic_softc * const sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	int error;
+
+	sc->sc_dev = self;
+	sc->sc_phandle = faa->faa_phandle;
+
+	error = fdtbus_register_interrupt_controller(self, faa->faa_phandle,
+	    &tegra_lic_funcs);
+	if (error) {
+		aprint_error(": couldn't register with fdtbus: %d\n", error);
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": LIC\n");
+}
+
+static void *
+tegra_lic_establish(device_t dev, int phandle, u_int index, int ipl, int flags,
+    int (*func)(void *), void *arg)
+{
+	struct tegra_lic_softc * const sc = device_private(dev);
+	int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
+	u_int *interrupts;
+	int interrupt_cells, len;
+
+	len = OF_getprop(sc->sc_phandle, "#interrupt-cells", &interrupt_cells,
+	    sizeof(interrupt_cells));
+	if (len != sizeof(interrupt_cells) || interrupt_cells <= 0)
+		return NULL;
+	interrupt_cells = be32toh(interrupt_cells);
+
+	len = OF_getproplen(phandle, "interrupts");
+	if (len <= 0)
+		return NULL;
+
+	const u_int clen = interrupt_cells * 4;
+	const u_int nintr = len / interrupt_cells;
+
+	if (index >= nintr)
+		return NULL;
+
+	interrupts = kmem_alloc(len, KM_SLEEP);
+
+	if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
+		kmem_free(interrupts, len);
+		return NULL;
+	}
+
+	/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
+	/* 2nd cell is the interrupt number */
+	/* 3rd cell is flags */
+
+	const u_int type = be32toh(interrupts[index * clen + 0]);
+	const u_int intr = be32toh(interrupts[index * clen + 1]);
+	const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
+	const u_int trig = be32toh(interrupts[index * clen + 2]) & 0xf;
+	const u_int level = (trig & 0x3) ? IST_EDGE : IST_LEVEL;
+
+	kmem_free(interrupts, len);
+
+	return intr_establish(irq, ipl, level | iflags, func, arg);
+}
+
+static void
+tegra_lic_disestablish(device_t dev, void *ih)
+{
+	intr_disestablish(ih);
+}
+
+static bool
+tegra_lic_intrstr(device_t dev, int phandle, u_int index, char *buf,
+    size_t buflen)
+{
+	struct tegra_lic_softc * const sc = device_private(dev);
+	u_int *interrupts;
+	int interrupt_cells, len;
+
+	len = OF_getprop(sc->sc_phandle, "#interrupt-cells", &interrupt_cells,
+	    sizeof(interrupt_cells));
+	if (len != sizeof(interrupt_cells) || interrupt_cells <= 0) {
+		return false;
+	}
+	interrupt_cells = be32toh(interrupt_cells);
+
+	len = OF_getproplen(phandle, "interrupts");
+	if (len <= 0) {
+		return false;
+	}
+
+	const u_int clen = interrupt_cells * 4;
+	const u_int nintr = len / interrupt_cells;
+
+	if (index >= nintr) {
+		return false;
+	}
+
+	interrupts = kmem_alloc(len, KM_SLEEP);
+
+	if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
+		kmem_free(interrupts, len);
+		return false;
+	}
+
+	/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
+	/* 2nd cell is the interrupt number */
+	/* 3rd cell is flags */
+
+	const u_int type = be32toh(interrupts[index * clen + 0]);
+	const u_int intr = be32toh(interrupts[index * clen + 1]);
+	const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
+
+	kmem_free(interrupts, len);
+
+	snprintf(buf, buflen, "LIC irq %d", irq);
+
+	return true;
+}

Reply via email to