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 <m...@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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to