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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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", ®_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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
+ * 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 <[email protected]>
+ * 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;
+}