svn commit: r308391 - in head/sys: arm/conf arm/nvidia arm/nvidia/tegra124 boot/fdt/dts/arm contrib/dev/nvidia

Michal Meloun mmel at FreeBSD.org
Mon Nov 7 05:37:12 UTC 2016


Author: mmel
Date: Mon Nov  7 05:37:10 2016
New Revision: 308391
URL: https://svnweb.freebsd.org/changeset/base/308391

Log:
  Add NVIDIA Tegra XHCI driver and coresponding firmware blob.
  
  MFC after: 3 weeks
  Approved by: core@ (NVIDIA license)

Added:
  head/sys/arm/nvidia/tegra_xhci.c   (contents, props changed)
  head/sys/contrib/dev/nvidia/
  head/sys/contrib/dev/nvidia/LICENCE.nvidia
  head/sys/contrib/dev/nvidia/tegra124_xusb.bin.uu
Modified:
  head/sys/arm/conf/TEGRA124
  head/sys/arm/nvidia/tegra124/files.tegra124
  head/sys/boot/fdt/dts/arm/tegra124-jetson-tk1-fbsd.dts

Modified: head/sys/arm/conf/TEGRA124
==============================================================================
--- head/sys/arm/conf/TEGRA124	Mon Nov  7 05:34:44 2016	(r308390)
+++ head/sys/arm/conf/TEGRA124	Mon Nov  7 05:37:10 2016	(r308391)
@@ -50,7 +50,7 @@ device		vlan			# 802.1Q VLAN support
 #device		tun			# Packet tunnel.
 device		md			# Memory "disks"
 #device		gif			# IPv6 and IPv4 tunneling
-#device		firmware		# firmware assist module
+device		firmware		# firmware assist module
 device		ether			# Ethernet support
 device		miibus			# Required for ethernet
 device		bpf			# Berkeley packet filter (required for DHCP)
@@ -86,6 +86,8 @@ device		pass			# Passthrough device (dir
 # USB support
 options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
 device		ehci			# EHCI USB interface
+device		xhci			# XHCI USB interface
+device		tegra124_xusb_fw	# Tegra XUSB firmware
 device		usb			# USB Bus (required)
 device		umass			# Disks/Mass storage - Requires scbus and da
 device		uhid			# "Human Interface Devices"

Modified: head/sys/arm/nvidia/tegra124/files.tegra124
==============================================================================
--- head/sys/arm/nvidia/tegra124/files.tegra124	Mon Nov  7 05:34:44 2016	(r308390)
+++ head/sys/arm/nvidia/tegra124/files.tegra124	Mon Nov  7 05:37:10 2016	(r308391)
@@ -24,6 +24,7 @@ arm/nvidia/tegra_uart.c			optional	uart
 arm/nvidia/tegra_sdhci.c		optional	sdhci
 arm/nvidia/tegra_gpio.c			optional	gpio
 arm/nvidia/tegra_ehci.c			optional	ehci
+arm/nvidia/tegra_xhci.c			optional	xhci
 arm/nvidia/tegra_ahci.c			optional	ahci
 arm/nvidia/tegra_pcie.c			optional	pci
 arm/nvidia/tegra_i2c.c			optional	iic
@@ -45,11 +46,25 @@ arm/nvidia/tegra_mc.c			standard
 #arm/nvidia/drm2/tegra_fb.c		optional	drm2
 #arm/nvidia/drm2/tegra_bo.c		optional	drm2
 #
-# Optional devices.
+# Firmware
 #
-
+tegra124_xusb_fw.c			optional tegra124_xusb_fw	\
+	dependency	"$S/arm/nvidia/tegra124/files.tegra124"		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk tegra124_xusb.fw:tegra124_xusb_fw -mtegra124_xusb_fw -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"tegra124_xusb_fw.c"
+tegra124_xusb.fwo			optional tegra124_xusb_fw	\
+	dependency	"tegra124_xusb.fw"				\
+	compile-with	"${NORMAL_FWO}"					\
+	no-implicit-rule						\
+	clean		"tegra124_xusb.fwo"
+tegra124_xusb.fw			optional tegra124_xusb_fw	\
+	dependency	"$S/contrib/dev/nvidia/tegra124_xusb.bin.uu"	\
+	compile-with	"${NORMAL_FW}"					\
+	no-obj no-implicit-rule						\
+	clean		"tegra124_xusb.fw"
 #
-# Temporary/ to be moved stuff
+# Temporary/to be moved stuff
 #
 arm/nvidia/as3722.c			optional	iic
 arm/nvidia/as3722_regulators.c		optional	iic

Added: head/sys/arm/nvidia/tegra_xhci.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/nvidia/tegra_xhci.c	Mon Nov  7 05:37:10 2016	(r308391)
@@ -0,0 +1,1160 @@
+/*-
+ * Copyright (c) 2016 Michal Meloun <mmel at FreeBSD.org>
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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>
+__FBSDID("$FreeBSD$");
+
+/*
+ * XHCI driver for Tegra SoCs.
+ */
+#include "opt_bus.h"
+#include "opt_platform.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/condvar.h>
+#include <sys/firmware.h>
+#include <sys/rman.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+#include <dev/extres/phy/phy.h>
+#include <dev/extres/regulator/regulator.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/xhci.h>
+#include <dev/usb/controller/xhcireg.h>
+
+#include <arm/nvidia/tegra_pmc.h>
+
+#include "usbdevs.h"
+
+/* FPCI address space */
+#define	T_XUSB_CFG_0				0x000
+#define	T_XUSB_CFG_1				0x004
+#define	 CFG_1_BUS_MASTER				(1 << 2)
+#define	 CFG_1_MEMORY_SPACE				(1 << 1)
+#define	 CFG_1_IO_SPACE					(1 << 0)
+
+#define	T_XUSB_CFG_2				0x008
+#define	T_XUSB_CFG_3				0x00C
+#define	T_XUSB_CFG_4				0x010
+#define	 CFG_4_BASE_ADDRESS(x)				(((x) & 0x1FFFF) << 15)
+
+#define	T_XUSB_CFG_5				0x014
+#define	T_XUSB_CFG_ARU_MAILBOX_CMD		0x0E4
+#define  ARU_MAILBOX_CMD_INT_EN				(1U << 31)
+#define  ARU_MAILBOX_CMD_DEST_XHCI			(1  << 30)
+#define  ARU_MAILBOX_CMD_DEST_SMI			(1  << 29)
+#define  ARU_MAILBOX_CMD_DEST_PME			(1  << 28)
+#define  ARU_MAILBOX_CMD_DEST_FALC			(1  << 27)
+
+#define	T_XUSB_CFG_ARU_MAILBOX_DATA_IN		0x0E8
+#define	 ARU_MAILBOX_DATA_IN_DATA(x)			(((x) & 0xFFFFFF) <<  0)
+#define	 ARU_MAILBOX_DATA_IN_TYPE(x)			(((x) & 0x0000FF) << 24)
+
+#define	T_XUSB_CFG_ARU_MAILBOX_DATA_OUT		0x0EC
+#define	 ARU_MAILBOX_DATA_OUT_DATA(x)			(((x) >>  0) & 0xFFFFFF)
+#define	 ARU_MAILBOX_DATA_OUT_TYPE(x)			(((x) >> 24) & 0x0000FF)
+
+#define	T_XUSB_CFG_ARU_MAILBOX_OWNER		0x0F0
+#define	 ARU_MAILBOX_OWNER_SW				2
+#define	 ARU_MAILBOX_OWNER_FW				1
+#define	 ARU_MAILBOX_OWNER_NONE				0
+
+#define	XUSB_CFG_ARU_C11_CSBRANGE		0x41C	/* ! UNDOCUMENTED ! */
+#define	 ARU_C11_CSBRANGE_PAGE(x)			((x) >> 9)
+#define	 ARU_C11_CSBRANGE_ADDR(x)			(0x800 + ((x) & 0x1FF))
+#define	XUSB_CFG_ARU_SMI_INTR			0x428	/* ! UNDOCUMENTED ! */
+#define  ARU_SMI_INTR_EN				(1 << 3)
+#define  ARU_SMI_INTR_FW_HANG				(1 << 1)
+#define	XUSB_CFG_ARU_RST			0x42C	/* ! UNDOCUMENTED ! */
+#define	 ARU_RST_RESET					(1 << 0)
+
+#define	XUSB_HOST_CONFIGURATION			0x180
+#define	 CONFIGURATION_CLKEN_OVERRIDE			(1U<< 31)
+#define	 CONFIGURATION_PW_NO_DEVSEL_ERR_CYA		(1 << 19)
+#define	 CONFIGURATION_INITIATOR_READ_IDLE		(1 << 18)
+#define	 CONFIGURATION_INITIATOR_WRITE_IDLE		(1 << 17)
+#define	 CONFIGURATION_WDATA_LEAD_CYA			(1 << 15)
+#define	 CONFIGURATION_WR_INTRLV_CYA			(1 << 14)
+#define	 CONFIGURATION_TARGET_READ_IDLE			(1 << 11)
+#define	 CONFIGURATION_TARGET_WRITE_IDLE		(1 << 10)
+#define	 CONFIGURATION_MSI_VEC_EMPTY			(1 <<  9)
+#define	 CONFIGURATION_UFPCI_MSIAW			(1 <<  7)
+#define	 CONFIGURATION_UFPCI_PWPASSPW			(1 <<  6)
+#define	 CONFIGURATION_UFPCI_PASSPW			(1 <<  5)
+#define	 CONFIGURATION_UFPCI_PWPASSNPW			(1 <<  4)
+#define	 CONFIGURATION_DFPCI_PWPASSNPW			(1 <<  3)
+#define	 CONFIGURATION_DFPCI_RSPPASSPW			(1 <<  2)
+#define	 CONFIGURATION_DFPCI_PASSPW			(1 <<  1)
+#define	 CONFIGURATION_EN_FPCI				(1 <<  0)
+
+/* IPFS address space */
+#define	XUSB_HOST_FPCI_ERROR_MASKS		0x184
+#define	 FPCI_ERROR_MASTER_ABORT			(1 <<  2)
+#define	 FPCI_ERRORI_DATA_ERROR				(1 <<  1)
+#define	 FPCI_ERROR_TARGET_ABORT			(1 <<  0)
+
+#define	XUSB_HOST_INTR_MASK			0x188
+#define	 INTR_IP_INT_MASK				(1 << 16)
+#define	 INTR_MSI_MASK					(1 <<  8)
+#define	 INTR_INT_MASK					(1 <<  0)
+
+#define	XUSB_HOST_CLKGATE_HYSTERESIS		0x1BC
+
+ /* CSB Falcon CPU */
+#define	XUSB_FALCON_CPUCTL			0x100
+#define	 CPUCTL_STOPPED					(1 << 5)
+#define	 CPUCTL_HALTED					(1 << 4)
+#define	 CPUCTL_HRESET					(1 << 3)
+#define	 CPUCTL_SRESET					(1 << 2)
+#define	 CPUCTL_STARTCPU				(1 << 1)
+#define	 CPUCTL_IINVAL					(1 << 0)
+
+#define	XUSB_FALCON_BOOTVEC			0x104
+#define	XUSB_FALCON_DMACTL			0x10C
+#define	XUSB_FALCON_IMFILLRNG1			0x154
+#define	 IMFILLRNG1_TAG_HI(x)				(((x) & 0xFFF) << 16)
+#define	 IMFILLRNG1_TAG_LO(x)				(((x) & 0xFFF) <<  0)
+#define	XUSB_FALCON_IMFILLCTL			0x158
+
+/* CSB mempool */
+#define	XUSB_CSB_MEMPOOL_APMAP			0x10181C
+#define	 APMAP_BOOTPATH					(1U << 31)
+
+#define	XUSB_CSB_MEMPOOL_ILOAD_ATTR		0x101A00
+#define	XUSB_CSB_MEMPOOL_ILOAD_BASE_LO		0x101A04
+#define	XUSB_CSB_MEMPOOL_ILOAD_BASE_HI		0x101A08
+#define	XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE		0x101A10
+#define	 L2IMEMOP_SIZE_OFFSET(x)			(((x) & 0x3FF) <<  8)
+#define	 L2IMEMOP_SIZE_SIZE(x)				(((x) & 0x0FF) << 24)
+
+#define	XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG		0x101A14
+#define	 L2IMEMOP_INVALIDATE_ALL			(0x40 << 24)
+#define	 L2IMEMOP_LOAD_LOCKED_RESULT			(0x11 << 24)
+
+#define	XUSB_CSB_MEMPOOL_L2IMEMOP_RESULT        0x101A18
+#define	 L2IMEMOP_RESULT_VLD       (1U << 31)
+
+#define XUSB_CSB_IMEM_BLOCK_SIZE	256
+
+#define	TEGRA_XHCI_SS_HIGH_SPEED	120000000
+#define	TEGRA_XHCI_SS_LOW_SPEED		 12000000
+
+/* MBOX commands. */
+#define	MBOX_CMD_MSG_ENABLED			 1
+#define	MBOX_CMD_INC_FALC_CLOCK			 2
+#define	MBOX_CMD_DEC_FALC_CLOCK			 3
+#define	MBOX_CMD_INC_SSPI_CLOCK			 4
+#define	MBOX_CMD_DEC_SSPI_CLOCK			 5
+#define	MBOX_CMD_SET_BW				 6
+#define	MBOX_CMD_SET_SS_PWR_GATING		 7
+#define	MBOX_CMD_SET_SS_PWR_UNGATING		 8
+#define	MBOX_CMD_SAVE_DFE_CTLE_CTX		 9
+#define	MBOX_CMD_AIRPLANE_MODE_ENABLED		10
+#define	MBOX_CMD_AIRPLANE_MODE_DISABLED		11
+#define	MBOX_CMD_START_HSIC_IDLE		12
+#define	MBOX_CMD_STOP_HSIC_IDLE			13
+#define	MBOX_CMD_DBC_WAKE_STACK			14
+#define	MBOX_CMD_HSIC_PRETEND_CONNECT		15
+#define	MBOX_CMD_RESET_SSPI			16
+#define	MBOX_CMD_DISABLE_SS_LFPS_DETECTION	17
+#define	MBOX_CMD_ENABLE_SS_LFPS_DETECTION	18
+
+/* MBOX responses. */
+#define	MBOX_CMD_ACK				(0x80 + 0)
+#define	MBOX_CMD_NAK				(0x80 + 1)
+
+
+#define	IPFS_WR4(_sc, _r, _v)	bus_write_4((_sc)->mem_res_ipfs, (_r), (_v))
+#define	IPFS_RD4(_sc, _r)	bus_read_4((_sc)->mem_res_ipfs, (_r))
+#define	FPCI_WR4(_sc, _r, _v)	bus_write_4((_sc)->mem_res_fpci, (_r), (_v))
+#define	FPCI_RD4(_sc, _r)	bus_read_4((_sc)->mem_res_fpci, (_r))
+
+#define	LOCK(_sc)		mtx_lock(&(_sc)->mtx)
+#define	UNLOCK(_sc)		mtx_unlock(&(_sc)->mtx)
+#define	SLEEP(_sc, timeout)						\
+    mtx_sleep(sc, &sc->mtx, 0, "tegra_xhci", timeout);
+#define	LOCK_INIT(_sc)							\
+    mtx_init(&_sc->mtx, device_get_nameunit(_sc->dev), "tegra_xhci", MTX_DEF)
+#define	LOCK_DESTROY(_sc)	mtx_destroy(&_sc->mtx)
+#define	ASSERT_LOCKED(_sc)	mtx_assert(&_sc->mtx, MA_OWNED)
+#define	ASSERT_UNLOCKED(_sc)	mtx_assert(&_sc->mtx, MA_NOTOWNED)
+
+struct tegra_xusb_fw_hdr {
+	uint32_t	boot_loadaddr_in_imem;
+	uint32_t	boot_codedfi_offset;
+	uint32_t	boot_codetag;
+	uint32_t	boot_codesize;
+
+	uint32_t	phys_memaddr;
+	uint16_t	reqphys_memsize;
+	uint16_t	alloc_phys_memsize;
+
+	uint32_t	rodata_img_offset;
+	uint32_t	rodata_section_start;
+	uint32_t	rodata_section_end;
+	uint32_t	main_fnaddr;
+
+	uint32_t	fwimg_cksum;
+	uint32_t	fwimg_created_time;
+
+	uint32_t	imem_resident_start;
+	uint32_t	imem_resident_end;
+	uint32_t	idirect_start;
+	uint32_t	idirect_end;
+	uint32_t	l2_imem_start;
+	uint32_t	l2_imem_end;
+	uint32_t	version_id;
+	uint8_t		init_ddirect;
+	uint8_t		reserved[3];
+	uint32_t	phys_addr_log_buffer;
+	uint32_t	total_log_entries;
+	uint32_t	dequeue_ptr;
+	uint32_t	dummy[2];
+	uint32_t	fwimg_len;
+	uint8_t		magic[8];
+	uint32_t	ss_low_power_entry_timeout;
+	uint8_t		num_hsic_port;
+	uint8_t		ss_portmap;
+	uint8_t		build;
+	uint8_t		padding[137]; /* Pad to 256 bytes */
+};
+
+/* Compatible devices. */
+static struct ofw_compat_data compat_data[] = {
+	{"nvidia,tegra124-xusb",	1},
+	{NULL,		 		0}
+};
+
+struct tegra_xhci_softc {
+	struct xhci_softc 	xhci_softc;
+	device_t		dev;
+	struct mtx		mtx;
+	struct resource		*mem_res_fpci;
+	struct resource		*mem_res_ipfs;
+	struct resource		*irq_res_mbox;
+	void			*irq_hdl_mbox;
+
+	clk_t			clk_xusb_host;
+	clk_t			clk_xusb_gate;
+	clk_t			clk_xusb_falcon_src;
+	clk_t			clk_xusb_ss;
+	clk_t			clk_xusb_hs_src;
+	clk_t			clk_xusb_fs_src;
+	hwreset_t		hwreset_xusb_host;
+	hwreset_t		hwreset_xusb_ss;
+	regulator_t		supply_avddio_pex;
+	regulator_t		supply_dvddio_pex;
+	regulator_t		supply_avdd_usb;
+	regulator_t		supply_avdd_pll_utmip;
+	regulator_t		supply_avdd_pll_erefe;
+	regulator_t		supply_avdd_usb_ss_pll;
+	regulator_t		supply_hvdd_usb_ss;
+	regulator_t		supply_hvdd_usb_ss_pll_e;
+	phy_t 			phy_usb2_0;
+	phy_t 			phy_usb2_1;
+	phy_t 			phy_usb2_2;
+	phy_t 			phy_usb3_0;
+
+	struct intr_config_hook	irq_hook;
+	bool			xhci_inited;
+	char			*fw_name;
+	vm_offset_t		fw_vaddr;
+	vm_size_t		fw_size;
+};
+
+static uint32_t
+CSB_RD4(struct tegra_xhci_softc *sc, uint32_t addr)
+{
+
+	FPCI_WR4(sc, XUSB_CFG_ARU_C11_CSBRANGE, ARU_C11_CSBRANGE_PAGE(addr));
+	return (FPCI_RD4(sc, ARU_C11_CSBRANGE_ADDR(addr)));
+}
+
+static void
+CSB_WR4(struct tegra_xhci_softc *sc, uint32_t addr, uint32_t val)
+{
+
+	FPCI_WR4(sc, XUSB_CFG_ARU_C11_CSBRANGE, ARU_C11_CSBRANGE_PAGE(addr));
+	FPCI_WR4(sc, ARU_C11_CSBRANGE_ADDR(addr), val);
+}
+
+static int
+get_fdt_resources(struct tegra_xhci_softc *sc, phandle_t node)
+{
+	int rv;
+
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "avddio-pex-supply",
+	    &sc->supply_avddio_pex);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'avddio-pex' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "dvddio-pex-supply",
+	    &sc->supply_dvddio_pex);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'dvddio-pex' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-usb-supply",
+	    &sc->supply_avdd_usb);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'avdd-usb' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pll-utmip-supply",
+	    &sc->supply_avdd_pll_utmip);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'avdd-pll-utmip' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-pll-erefe-supply",
+	    &sc->supply_avdd_pll_erefe);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'avdd-pll-erefe' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "avdd-usb-ss-pll-supply",
+	    &sc->supply_avdd_usb_ss_pll);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'avdd-usb-ss-pll' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0, "hvdd-usb-ss-supply",
+	    &sc->supply_hvdd_usb_ss);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'hvdd-usb-ss' regulator\n");
+		return (ENXIO);
+	}
+	rv = regulator_get_by_ofw_property(sc->dev, 0,
+	    "hvdd-usb-ss-pll-e-supply", &sc->supply_hvdd_usb_ss_pll_e);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot get 'hvdd-usb-ss-pll-e' regulator\n");
+		return (ENXIO);
+	}
+
+	rv = hwreset_get_by_ofw_name(sc->dev, 0, "xusb_host",
+	    &sc->hwreset_xusb_host);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_host' reset\n");
+		return (ENXIO);
+	}
+	rv = hwreset_get_by_ofw_name(sc->dev, 0, "xusb_ss",
+	    &sc->hwreset_xusb_ss);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_ss' reset\n");
+		return (ENXIO);
+	}
+
+	rv = phy_get_by_ofw_name(sc->dev, 0, "usb2-0", &sc->phy_usb2_0);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'usb2-0' phy\n");
+		return (ENXIO);
+	}
+	rv = phy_get_by_ofw_name(sc->dev, 0, "usb2-1", &sc->phy_usb2_1);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'usb2-1' phy\n");
+		return (ENXIO);
+	}
+	rv = phy_get_by_ofw_name(sc->dev, 0, "usb2-2", &sc->phy_usb2_2);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'usb2-2' phy\n");
+		return (ENXIO);
+	}
+	rv = phy_get_by_ofw_name(sc->dev, 0, "usb3-0", &sc->phy_usb3_0);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'usb3-0' phy\n");
+		return (ENXIO);
+	}
+
+	rv = clk_get_by_ofw_name(sc->dev, 0, "xusb_host",
+	    &sc->clk_xusb_host);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_host' clock\n");
+		return (ENXIO);
+	}
+	rv = clk_get_by_ofw_name(sc->dev, 0, "xusb_falcon_src",
+	    &sc->clk_xusb_falcon_src);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_falcon_src' clock\n");
+		return (ENXIO);
+	}
+	rv = clk_get_by_ofw_name(sc->dev, 0, "xusb_ss",
+	    &sc->clk_xusb_ss);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_ss' clock\n");
+		return (ENXIO);
+	}
+	rv = clk_get_by_ofw_name(sc->dev, 0, "xusb_hs_src",
+	    &sc->clk_xusb_hs_src);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_hs_src' clock\n");
+		return (ENXIO);
+	}
+	rv = clk_get_by_ofw_name(sc->dev, 0, "xusb_fs_src",
+	    &sc->clk_xusb_fs_src);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_fs_src' clock\n");
+		return (ENXIO);
+	}
+	rv = clk_get_by_ofw_index_prop(sc->dev, 0, "freebsd,clock-xusb-gate", 0,
+	    &sc->clk_xusb_gate);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get 'xusb_gate' clock\n");
+		return (ENXIO);
+	}
+	return (0);
+}
+
+static int
+enable_fdt_resources(struct tegra_xhci_softc *sc)
+{
+	int rv;
+
+	rv = hwreset_assert(sc->hwreset_xusb_host);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot reset 'xusb_host' reset\n");
+		return (rv);
+	}
+	rv = hwreset_assert(sc->hwreset_xusb_ss);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot reset 'xusb_ss' reset\n");
+		return (rv);
+	}
+
+	rv = regulator_enable(sc->supply_avddio_pex);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'avddio_pex' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_dvddio_pex);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'dvddio_pex' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_avdd_usb);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'avdd_usb' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_avdd_pll_utmip);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'avdd_pll_utmip-5v' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_avdd_pll_erefe);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'avdd_pll_erefe' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_avdd_usb_ss_pll);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'avdd_usb_ss_pll' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_hvdd_usb_ss);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'hvdd_usb_ss' regulator\n");
+		return (rv);
+	}
+	rv = regulator_enable(sc->supply_hvdd_usb_ss_pll_e);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'hvdd_usb_ss_pll_e' regulator\n");
+		return (rv);
+	}
+
+	/* Power off XUSB host and XUSB SS domains. */
+	rv = tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot powerdown  'xusba' domain\n");
+		return (rv);
+	}
+	rv = tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot powerdown  'xusbc' domain\n");
+		return (rv);
+	}
+
+	/* Setup XUSB ss_src clock first */
+	clk_set_freq(sc->clk_xusb_ss, TEGRA_XHCI_SS_HIGH_SPEED, 0);
+	if (rv != 0)
+		return (rv);
+
+	/* The XUSB gate clock must be enabled before XUSBA can be powered. */
+	rv = clk_enable(sc->clk_xusb_gate);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'xusb_gate' clock\n");
+		return (rv);
+	}
+
+	/* Power on XUSB host and XUSB SS domains. */
+	rv = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBC,
+	    sc->clk_xusb_host, sc->hwreset_xusb_host);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot powerup 'xusbc' domain\n");
+		return (rv);
+	}
+	rv = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBA,
+	    sc->clk_xusb_ss, sc->hwreset_xusb_ss);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot powerup 'xusba' domain\n");
+		return (rv);
+	}
+
+	/* Enable rest of clocks */
+	rv = clk_enable(sc->clk_xusb_falcon_src);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'xusb_falcon_src' clock\n");
+		return (rv);
+	}
+	rv = clk_enable(sc->clk_xusb_fs_src);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'xusb_fs_src' clock\n");
+		return (rv);
+	}
+	rv = clk_enable(sc->clk_xusb_hs_src);
+	if (rv != 0) {
+		device_printf(sc->dev,
+		    "Cannot enable 'xusb_hs_src' clock\n");
+		return (rv);
+	}
+
+	rv = phy_enable(sc->dev, sc->phy_usb2_0);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot enable USB2_0 phy\n");
+		return (rv);
+	}
+	rv = phy_enable(sc->dev, sc->phy_usb2_1);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot enable USB2_1 phy\n");
+		return (rv);
+	}
+	rv = phy_enable(sc->dev, sc->phy_usb2_2);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot enable USB2_2 phy\n");
+		return (rv);
+	}
+	rv = phy_enable(sc->dev, sc->phy_usb3_0);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot enable USB3_0 phy\n");
+		return (rv);
+	}
+
+	return (0);
+}
+
+/* Respond by ACK/NAK back to FW */
+static void
+mbox_send_ack(struct tegra_xhci_softc *sc, uint32_t cmd, uint32_t data)
+{
+	uint32_t reg;
+
+	reg = ARU_MAILBOX_DATA_IN_TYPE(cmd) | ARU_MAILBOX_DATA_IN_DATA(data);
+	FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_DATA_IN, reg);
+
+	reg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_CMD);
+	reg |= ARU_MAILBOX_CMD_DEST_FALC | ARU_MAILBOX_CMD_INT_EN;
+	FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_CMD, reg);
+}
+
+/* Sent command to FW */
+static int
+mbox_send_cmd(struct tegra_xhci_softc *sc, uint32_t cmd, uint32_t data)
+{
+	uint32_t reg;
+	int i;
+
+	reg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_OWNER);
+	if (reg != ARU_MAILBOX_OWNER_NONE) {
+		device_printf(sc->dev,
+		    "CPU mailbox is busy: 0x%08X\n", reg);
+		return (EBUSY);
+	}
+	/* XXX Is this right? Retry loop? Wait before send? */
+	FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_OWNER, ARU_MAILBOX_OWNER_SW);
+	reg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_OWNER);
+	if (reg != ARU_MAILBOX_OWNER_SW) {
+		device_printf(sc->dev,
+		    "Cannot acquire CPU mailbox: 0x%08X\n", reg);
+		return (EBUSY);
+	}
+	reg = ARU_MAILBOX_DATA_IN_TYPE(cmd) | ARU_MAILBOX_DATA_IN_DATA(data);
+	FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_DATA_IN, reg);
+
+	reg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_CMD);
+	reg |= ARU_MAILBOX_CMD_DEST_FALC | ARU_MAILBOX_CMD_INT_EN;
+	FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_CMD, reg);
+
+	for (i = 250; i > 0; i--) {
+		reg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_OWNER);
+		if (reg == ARU_MAILBOX_OWNER_NONE)
+			break;
+		DELAY(100);
+	}
+	if (i <= 0) {
+		device_printf(sc->dev,
+		    "Command response timeout: 0x%08X\n", reg);
+		return (ETIMEDOUT);
+	}
+
+	return(0);
+}
+
+static void
+process_msg(struct tegra_xhci_softc *sc, uint32_t req_cmd, uint32_t req_data,
+    uint32_t *resp_cmd, uint32_t *resp_data)
+{
+	uint64_t freq;
+	int rv;
+
+	/* In most cases, data are echoed back. */
+	*resp_data = req_data;
+	switch (req_cmd) {
+	case MBOX_CMD_INC_FALC_CLOCK:
+	case MBOX_CMD_DEC_FALC_CLOCK:
+		rv = clk_set_freq(sc->clk_xusb_falcon_src, req_data * 1000ULL,
+		    0);
+		if (rv == 0) {
+			rv = clk_get_freq(sc->clk_xusb_falcon_src, &freq);
+			*resp_data = (uint32_t)(freq / 1000);
+		}
+		*resp_cmd = rv == 0 ? MBOX_CMD_ACK: MBOX_CMD_NAK;
+		break;
+
+	case MBOX_CMD_INC_SSPI_CLOCK:
+	case MBOX_CMD_DEC_SSPI_CLOCK:
+		rv = clk_set_freq(sc->clk_xusb_ss, req_data * 1000ULL,
+		    0);
+		if (rv == 0) {
+			rv = clk_get_freq(sc->clk_xusb_ss, &freq);
+			*resp_data = (uint32_t)(freq / 1000);
+		}
+		*resp_cmd = rv == 0 ? MBOX_CMD_ACK: MBOX_CMD_NAK;
+		break;
+
+	case MBOX_CMD_SET_BW:
+		/* No respense is expected. */
+		*resp_cmd = 0;
+		break;
+
+	case MBOX_CMD_SET_SS_PWR_GATING:
+	case MBOX_CMD_SET_SS_PWR_UNGATING:
+		*resp_cmd = MBOX_CMD_NAK;
+		break;
+
+	case MBOX_CMD_SAVE_DFE_CTLE_CTX:
+		/* Not implemented yet. */
+		*resp_cmd = MBOX_CMD_ACK;
+		break;
+
+
+	case MBOX_CMD_START_HSIC_IDLE:
+	case MBOX_CMD_STOP_HSIC_IDLE:
+		/* Not implemented yet. */
+		*resp_cmd = MBOX_CMD_NAK;
+		break;
+
+	case MBOX_CMD_DISABLE_SS_LFPS_DETECTION:
+	case MBOX_CMD_ENABLE_SS_LFPS_DETECTION:
+		/* Not implemented yet. */
+		*resp_cmd = MBOX_CMD_NAK;
+		break;
+
+	case MBOX_CMD_AIRPLANE_MODE_ENABLED:
+	case MBOX_CMD_AIRPLANE_MODE_DISABLED:
+	case MBOX_CMD_DBC_WAKE_STACK:
+	case MBOX_CMD_HSIC_PRETEND_CONNECT:
+	case MBOX_CMD_RESET_SSPI:
+		device_printf(sc->dev,
+		    "Received unused/unexpected command: %u\n", req_cmd);
+		*resp_cmd = 0;
+		break;
+
+	default:
+		device_printf(sc->dev,
+		    "Received unknown command: %u\n", req_cmd);
+	}
+}
+
+static void
+intr_mbox(void *arg)
+{
+	struct tegra_xhci_softc *sc;
+	uint32_t reg, msg, resp_cmd, resp_data;
+
+	sc = (struct tegra_xhci_softc *)arg;
+
+	/* Clear interrupt first */
+	reg = FPCI_RD4(sc, XUSB_CFG_ARU_SMI_INTR);
+	FPCI_WR4(sc, XUSB_CFG_ARU_SMI_INTR, reg);
+	if (reg & ARU_SMI_INTR_FW_HANG) {
+		device_printf(sc->dev,
+		    "XUSB CPU firmware hang!!! CPUCTL: 0x%08X\n",
+		    CSB_RD4(sc, XUSB_FALCON_CPUCTL));
+	}
+
+	msg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_DATA_OUT);
+	resp_cmd = 0;
+	process_msg(sc, ARU_MAILBOX_DATA_OUT_TYPE(msg),
+	   ARU_MAILBOX_DATA_OUT_DATA(msg), &resp_cmd, &resp_data);
+	if (resp_cmd != 0)
+		mbox_send_ack(sc, resp_cmd, resp_data);
+	else
+		FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_OWNER,
+		    ARU_MAILBOX_OWNER_NONE);
+
+	reg = FPCI_RD4(sc, T_XUSB_CFG_ARU_MAILBOX_CMD);
+	reg &= ~ARU_MAILBOX_CMD_DEST_SMI;
+	FPCI_WR4(sc, T_XUSB_CFG_ARU_MAILBOX_CMD, reg);
+
+}
+
+static int
+load_fw(struct tegra_xhci_softc *sc)
+{
+	const struct firmware *fw;
+	const struct tegra_xusb_fw_hdr *fw_hdr;
+	vm_paddr_t fw_paddr, fw_base;
+	vm_offset_t fw_vaddr;
+	vm_size_t fw_size;
+	uint32_t code_tags, code_size;
+	struct clocktime fw_clock;
+	struct timespec	fw_timespec;
+	int i;
+
+	/* Reset ARU */
+	FPCI_WR4(sc, XUSB_CFG_ARU_RST, ARU_RST_RESET);
+	DELAY(3000);
+
+	/* Check if FALCON already runs */
+	if (CSB_RD4(sc, XUSB_CSB_MEMPOOL_ILOAD_BASE_LO) != 0) {
+		device_printf(sc->dev,
+		    "XUSB CPU is already loaded, CPUCTL: 0x%08X\n",
+			 CSB_RD4(sc, XUSB_FALCON_CPUCTL));
+		return (0);
+	}
+
+	fw = firmware_get(sc->fw_name);
+	if (fw == NULL) {
+		device_printf(sc->dev, "Cannot read xusb firmware\n");
+		return (ENOENT);
+	}
+
+	/* Allocate uncached memory and copy firmware into. */
+	fw_hdr = (const struct tegra_xusb_fw_hdr *)fw->data;
+	fw_size = fw_hdr->fwimg_len;
+
+	fw_vaddr = kmem_alloc_contig(kernel_arena, fw_size,
+	    M_WAITOK, 0, -1UL, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE);
+	fw_paddr = vtophys(fw_vaddr);
+	fw_hdr = (const struct tegra_xusb_fw_hdr *)fw_vaddr;
+	memcpy((void *)fw_vaddr, fw->data, fw_size);
+
+	firmware_put(fw, FIRMWARE_UNLOAD);
+	sc->fw_vaddr = fw_vaddr;
+	sc->fw_size = fw_size;
+
+	/* Setup firmware physical address and size. */
+	fw_base = fw_paddr + sizeof(*fw_hdr);
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_ILOAD_ATTR, fw_size);
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_ILOAD_BASE_LO, fw_base & 0xFFFFFFFF);
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_ILOAD_BASE_HI, (uint64_t)fw_base >> 32);
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_APMAP, APMAP_BOOTPATH);
+
+	/* Invalidate full L2IMEM context. */
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG,
+	    L2IMEMOP_INVALIDATE_ALL);
+
+	/* Program load of L2IMEM by boot code. */
+	code_tags = howmany(fw_hdr->boot_codetag, XUSB_CSB_IMEM_BLOCK_SIZE);
+	code_size = howmany(fw_hdr->boot_codesize, XUSB_CSB_IMEM_BLOCK_SIZE);
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_L2IMEMOP_SIZE,
+	    L2IMEMOP_SIZE_OFFSET(code_tags) |
+	    L2IMEMOP_SIZE_SIZE(code_size));
+
+	/* Execute L2IMEM boot code fetch. */
+	CSB_WR4(sc, XUSB_CSB_MEMPOOL_L2IMEMOP_TRIG,
+	    L2IMEMOP_LOAD_LOCKED_RESULT);
+
+	/* Program FALCON auto-fill range and block count */
+	CSB_WR4(sc, XUSB_FALCON_IMFILLCTL, code_size);
+	CSB_WR4(sc, XUSB_FALCON_IMFILLRNG1,
+	    IMFILLRNG1_TAG_LO(code_tags) |
+	    IMFILLRNG1_TAG_HI(code_tags + code_size));
+
+	CSB_WR4(sc, XUSB_FALCON_DMACTL, 0);
+	/* Wait for CPU */
+	for (i = 500; i > 0; i--) {
+		if (CSB_RD4(sc, XUSB_CSB_MEMPOOL_L2IMEMOP_RESULT) &
+		     L2IMEMOP_RESULT_VLD)
+			break;
+		DELAY(100);
+	}
+	if (i <= 0) {
+		device_printf(sc->dev, "Timedout while wating for DMA, "
+		    "state: 0x%08X\n",
+		    CSB_RD4(sc, XUSB_CSB_MEMPOOL_L2IMEMOP_RESULT));
+		return (ETIMEDOUT);
+	}
+
+	/* Boot FALCON cpu */
+	CSB_WR4(sc, XUSB_FALCON_BOOTVEC, fw_hdr->boot_codetag);
+	CSB_WR4(sc, XUSB_FALCON_CPUCTL, CPUCTL_STARTCPU);
+
+	/* Wait for CPU */
+	for (i = 50; i > 0; i--) {
+		if (CSB_RD4(sc, XUSB_FALCON_CPUCTL) == CPUCTL_STOPPED)
+			break;
+		DELAY(100);
+	}
+	if (i <= 0) {
+		device_printf(sc->dev, "Timedout while wating for FALCON cpu, "
+		    "state: 0x%08X\n", CSB_RD4(sc, XUSB_FALCON_CPUCTL));
+		return (ETIMEDOUT);
+	}
+
+	fw_timespec.tv_sec = fw_hdr->fwimg_created_time;
+	fw_timespec.tv_nsec = 0;
+	clock_ts_to_ct(&fw_timespec, &fw_clock);
+	device_printf(sc->dev,
+	    " Falcon firmware version: %02X.%02X.%04X,"
+	    " (%d/%d/%d %d:%02d:%02d UTC)\n",
+	    (fw_hdr->version_id >> 24) & 0xFF,(fw_hdr->version_id >> 15) & 0xFF,
+	    fw_hdr->version_id & 0xFFFF,
+	    fw_clock.day, fw_clock.mon, fw_clock.year,
+	    fw_clock.hour, fw_clock.min, fw_clock.sec);
+
+	return (0);
+}
+
+static int
+init_hw(struct tegra_xhci_softc *sc)
+{
+	int rv;
+	uint32_t reg;
+	rman_res_t base_addr;
+
+	base_addr = rman_get_start(sc->xhci_softc.sc_io_res);
+
+	/* Enable FPCI access */
+	reg = IPFS_RD4(sc, XUSB_HOST_CONFIGURATION);
+	reg |= CONFIGURATION_EN_FPCI;
+	IPFS_WR4(sc, XUSB_HOST_CONFIGURATION, reg);
+	IPFS_RD4(sc, XUSB_HOST_CONFIGURATION);
+
+
+	/* Program bar for XHCI base address */
+	reg = FPCI_RD4(sc, T_XUSB_CFG_4);
+	reg &= ~CFG_4_BASE_ADDRESS(~0);
+	reg |= CFG_4_BASE_ADDRESS((uint32_t)base_addr >> 15);
+	FPCI_WR4(sc, T_XUSB_CFG_4, reg);
+	FPCI_WR4(sc, T_XUSB_CFG_5, (uint32_t)((uint64_t)(base_addr) >> 32));
+
+	/* Enable bus master */
+	reg = FPCI_RD4(sc, T_XUSB_CFG_1);
+	reg |= CFG_1_IO_SPACE;
+	reg |= CFG_1_MEMORY_SPACE;
+	reg |= CFG_1_BUS_MASTER;
+	FPCI_WR4(sc, T_XUSB_CFG_1, reg);
+
+	/* Enable Interrupts */
+	reg = IPFS_RD4(sc, XUSB_HOST_INTR_MASK);
+	reg |= INTR_IP_INT_MASK;
+	IPFS_WR4(sc, XUSB_HOST_INTR_MASK, reg);
+
+	/* Set hysteresis */
+	IPFS_WR4(sc, XUSB_HOST_CLKGATE_HYSTERESIS, 128);
+
+	rv = load_fw(sc);
+	if (rv != 0)
+		return rv;
+	return (0);
+}
+
+static int

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list