Module Name:    src
Committed By:   jmcneill
Date:           Wed Oct 21 20:02:13 UTC 2015

Modified Files:
        src/sys/arch/arm/nvidia: files.tegra tegra_ehci.c tegra_io.c
        src/sys/arch/evbarm/conf: JETSONTK1
        src/sys/arch/evbarm/tegra: tegra_machdep.c
Added Files:
        src/sys/arch/arm/nvidia: tegra_usbphy.c tegra_usbreg.h
Removed Files:
        src/sys/arch/arm/nvidia: tegra_ehcireg.h

Log Message:
Split out USB PHY support out of the ehci glue and into a separate driver.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/nvidia/files.tegra
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_ehci.c
cvs rdiff -u -r1.2 -r0 src/sys/arch/arm/nvidia/tegra_ehcireg.h
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/nvidia/tegra_io.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/nvidia/tegra_usbphy.c \
    src/sys/arch/arm/nvidia/tegra_usbreg.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/evbarm/conf/JETSONTK1
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/evbarm/tegra/tegra_machdep.c

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.18 src/sys/arch/arm/nvidia/files.tegra:1.19
--- src/sys/arch/arm/nvidia/files.tegra:1.18	Mon Oct 19 21:18:36 2015
+++ src/sys/arch/arm/nvidia/files.tegra	Wed Oct 21 20:02:12 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.tegra,v 1.18 2015/10/19 21:18:36 jmcneill Exp $
+#	$NetBSD: files.tegra,v 1.19 2015/10/21 20:02:12 jmcneill Exp $
 #
 # Configuration info for NVIDIA Tegra ARM Peripherals
 #
@@ -71,6 +71,11 @@ device	tegrartc
 attach	tegrartc at tegraio with tegra_rtc
 file	arch/arm/nvidia/tegra_rtc.c		tegra_rtc
 
+# USB PHY
+device	tegrausbphy
+attach	tegrausbphy at tegraio with tegra_usbphy
+file	arch/arm/nvidia/tegra_usbphy.c		tegra_usbphy
+
 # USB 2.0
 attach	ehci at tegraio with tegra_ehci
 file	arch/arm/nvidia/tegra_ehci.c		tegra_ehci

Index: src/sys/arch/arm/nvidia/tegra_ehci.c
diff -u src/sys/arch/arm/nvidia/tegra_ehci.c:1.8 src/sys/arch/arm/nvidia/tegra_ehci.c:1.9
--- src/sys/arch/arm/nvidia/tegra_ehci.c:1.8	Wed Oct 21 10:43:09 2015
+++ src/sys/arch/arm/nvidia/tegra_ehci.c	Wed Oct 21 20:02:12 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_ehci.c,v 1.8 2015/10/21 10:43:09 jmcneill Exp $ */
+/* $NetBSD: tegra_ehci.c,v 1.9 2015/10/21 20:02:12 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.8 2015/10/21 10:43:09 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.9 2015/10/21 20:02:12 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -46,7 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c
 #include <dev/usb/ehcivar.h>
 
 #include <arm/nvidia/tegra_var.h>
-#include <arm/nvidia/tegra_ehcireg.h>
+#include <arm/nvidia/tegra_usbreg.h>
 
 #define TEGRA_EHCI_REG_OFFSET	0x100
 
@@ -61,22 +61,8 @@ struct tegra_ehci_softc {
 	bus_space_handle_t	sc_bsh;
 	void			*sc_ih;
 	u_int			sc_port;
-
-	struct tegra_gpio_pin	*sc_pin_vbus;
-	uint8_t			sc_hssync_start_delay;
-	uint8_t			sc_idle_wait_delay;
-	uint8_t			sc_elastic_limit;
-	uint8_t			sc_term_range_adj;
-	uint8_t			sc_xcvr_setup;
-	uint8_t			sc_xcvr_lsfslew;
-	uint8_t			sc_xcvr_lsrslew;
-	uint8_t			sc_hssquelch_level;
-	uint8_t			sc_hsdiscon_level;
-	uint8_t			sc_xcvr_hsslew;
 };
 
-static int	tegra_ehci_parse_properties(struct tegra_ehci_softc *);
-static void	tegra_ehci_utmip_init(struct tegra_ehci_softc *);
 static int	tegra_ehci_port_status(struct ehci_softc *sc, uint32_t v,
 		    int i);
 
@@ -96,8 +82,6 @@ tegra_ehci_attach(device_t parent, devic
 	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;
-	prop_dictionary_t prop = device_properties(self);
-	const char *pin;
 	int error;
 
 	sc->sc_bst = tio->tio_bst;
@@ -124,27 +108,6 @@ tegra_ehci_attach(device_t parent, devic
 	aprint_naive("\n");
 	aprint_normal(": USB%d\n", loc->loc_port + 1);
 
-	if (tegra_ehci_parse_properties(sc) != 0)
-		return;
-
-	tegra_car_periph_usb_enable(sc->sc_port);
-	delay(2);
-
-	tegra_ehci_utmip_init(sc);
-
-	if (prop_dictionary_get_cstring_nocopy(prop, "vbus-gpio", &pin)) {
-		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);
-		} else {
-			aprint_normal_dev(self, "VBUS input active\n");
-		}
-        }
-
 	sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH);
 
 	sc->sc_ih = intr_establish(loc->loc_intr, IPL_USB, IST_LEVEL,
@@ -165,33 +128,6 @@ tegra_ehci_attach(device_t parent, devic
 	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
 }
 
-static int
-tegra_ehci_parse_properties(struct tegra_ehci_softc *sc)
-{
-#define PROPGET(k, v)	\
-	if (prop_dictionary_get_uint8(prop, (k), (v)) == false) {	\
-		aprint_error_dev(sc->sc.sc_dev,				\
-		    "missing property '%s'\n", (k));			\
-		return EIO;						\
-	}
-
-	prop_dictionary_t prop = device_properties(sc->sc.sc_dev);
-
-	PROPGET("nvidia,hssync-start-delay", &sc->sc_hssync_start_delay);
-	PROPGET("nvidia,idle-wait-delay", &sc->sc_idle_wait_delay);
-	PROPGET("nvidia,elastic-limit", &sc->sc_elastic_limit);
-	PROPGET("nvidia,term-range-adj", &sc->sc_term_range_adj);
-	PROPGET("nvidia,xcvr-setup", &sc->sc_xcvr_setup);
-	PROPGET("nvidia,xcvr-lsfslew", &sc->sc_xcvr_lsfslew);
-	PROPGET("nvidia,xcvr-lsrslew", &sc->sc_xcvr_lsrslew);
-	PROPGET("nvidia,hssquelch-level", &sc->sc_hssquelch_level);
-	PROPGET("nvidia,hsdiscon-level", &sc->sc_hsdiscon_level);
-	PROPGET("nvidia,xcvr-hsslew", &sc->sc_xcvr_hsslew);
-
-	return 0;
-#undef PROPGET
-}
-
 static void
 tegra_ehci_init(struct ehci_softc *esc)
 {
@@ -223,146 +159,6 @@ tegra_ehci_init(struct ehci_softc *esc)
 	    __SHIFTIN(0x10, TEGRA_EHCI_TXFILLTUNING_TXFIFOTHRES));
 }
 
-static void
-tegra_ehci_utmip_init(struct tegra_ehci_softc *sc)
-{
-	bus_space_tag_t bst = sc->sc_bst;
-	bus_space_handle_t bsh = sc->sc_bsh;
-	int retry;
-
-	/* Put UTMIP PHY into reset before programming UTMIP config registers */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG,
-	    TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET, 0);
-
-	/* Enable UTMIP PHY mode */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG,
-	    TEGRA_EHCI_SUSP_CTRL_UTMIP_PHY_ENB, 0);
-
-	/* Stop crystal clock */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG,
-	    0, TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN);
-	delay(1);
-
-	/* Clear session status */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_PHY_VBUS_SENSORS_REG,
-	    0,
-	    TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_VALUE |
-	    TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_EN);
-
-	/* PLL configuration */
-	tegra_car_utmip_init();
-
-	/* Transceiver configuration */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG,
-	    __SHIFTIN(4, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP) |
-	    __SHIFTIN(3, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB) |
-	    __SHIFTIN(sc->sc_xcvr_hsslew,
-		      TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB),
-	    TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP |
-	    TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB |
-	    TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB);
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG,
-	    __SHIFTIN(sc->sc_term_range_adj,
-		      TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ),
-	    TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ);
-
-	if (sc->sc_port == 0) {
-		tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG,
-		    TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL_MSB |
-		    __SHIFTIN(sc->sc_hsdiscon_level,
-			      TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL),
-		    TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL); 
-	}
-
-	/* Misc config */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG0_REG,
-	    0,
-	    TEGRA_EHCI_UTMIP_MISC_CFG0_SUSPEND_EXIT_ON_EDGE);
-
-	/* BIAS cell power down lag */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG,
-	    __SHIFTIN(5, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT),
-	    TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT);
-
-	/* Debounce config */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_REG,
-	    __SHIFTIN(0x7530, TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_A),
-	    TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_A);
-
-	/* Transmit signal preamble config */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_TX_CFG0_REG,
-	    TEGRA_EHCI_UTMIP_TX_CFG0_FS_PREAMBLE_J, 0);
-
-	/* Power-down battery charger circuit */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BAT_CHRG_CFG0_REG,
-	    TEGRA_EHCI_UTMIP_BAT_CHRG_CFG0_PD_CHRG, 0);
-
-	/* Select low speed bias method */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG,
-	    0, TEGRA_EHCI_UTMIP_XCVR_CFG0_LSBIAS_SEL);
-
-	/* High speed receive config */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_HSRX_CFG0_REG,
-	    __SHIFTIN(sc->sc_idle_wait_delay,
-		      TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT) |
-	    __SHIFTIN(sc->sc_elastic_limit,
-		      TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT),
-	    TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT |
-	    TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT);
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_HSRX_CFG1_REG,
-	    __SHIFTIN(sc->sc_hssync_start_delay,
-		      TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY),
-	    TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY);
-
-	/* Start crystal clock */
-	delay(1);
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG,
-	    TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN, 0);
-
-	/* Clear port PLL powerdown status */
-	tegra_car_utmip_enable(sc->sc_port);
-
-	/* Bring UTMIP PHY out of reset */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG,
-	    0, TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET);
-	for (retry = 100000; retry > 0; retry--) {
-		const uint32_t susp = bus_space_read_4(bst, bsh,
-		    TEGRA_EHCI_SUSP_CTRL_REG);
-		if (susp & TEGRA_EHCI_SUSP_CTRL_PHY_CLK_VALID)
-			break;
-		delay(1);
-	}
-	if (retry == 0) {
-		aprint_error_dev(sc->sc.sc_dev, "PHY clock is not valid\n");
-		return;
-	}
-
-	/* Disable ICUSB transceiver */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_ICUSB_CTRL_REG,
-	    0,
-	    TEGRA_EHCI_ICUSB_CTRL_ENB1);
-
-	/* Power up UTMPI transceiver */
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG,
-	    0,
-	    TEGRA_EHCI_UTMIP_XCVR_CFG0_PD_POWERDOWN |
-	    TEGRA_EHCI_UTMIP_XCVR_CFG0_PD2_POWERDOWN |
-	    TEGRA_EHCI_UTMIP_XCVR_CFG0_PDZI_POWERDOWN);
-	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG,
-	    0,
-	    TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDISC_POWERDOWN |
-	    TEGRA_EHCI_UTMIP_XCVR_CFG1_PDCHRP_POWERDOWN |
-	    TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDR_POWERDOWN);
-
-	if (sc->sc_port == 0) {
-		tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG,
-		    0, TEGRA_EHCI_UTMIP_BIAS_CFG0_BIASPD);
-		delay(25);
-		tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG,
-		    0, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_POWERDOWN);
-	}
-}
-
 static int
 tegra_ehci_port_status(struct ehci_softc *ehci_sc, uint32_t v, int i)
 {

Index: src/sys/arch/arm/nvidia/tegra_io.c
diff -u src/sys/arch/arm/nvidia/tegra_io.c:1.14 src/sys/arch/arm/nvidia/tegra_io.c:1.15
--- src/sys/arch/arm/nvidia/tegra_io.c:1.14	Sat Oct 17 21:18:16 2015
+++ src/sys/arch/arm/nvidia/tegra_io.c	Wed Oct 21 20:02:12 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_io.c,v 1.14 2015/10/17 21:18:16 jmcneill Exp $ */
+/* $NetBSD: tegra_io.c,v 1.15 2015/10/21 20:02:12 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -29,7 +29,7 @@
 #include "opt_tegra.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.14 2015/10/17 21:18:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.15 2015/10/21 20:02:12 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -118,8 +118,12 @@ static const struct tegra_locators tegra
 };
 
 static const struct tegra_locators tegra_ahb_a2_locators[] = {
+  { "tegrausbphy",
+    TEGRA_USB1_OFFSET, TEGRA_USB1_SIZE, 0, NOINTR },
   { "ehci",
     TEGRA_USB1_OFFSET, TEGRA_USB1_SIZE, 0, TEGRA_INTR_USB1 },
+  { "tegrausbphy",
+    TEGRA_USB2_OFFSET, TEGRA_USB2_SIZE, 1, NOINTR },
   { "ehci",
     TEGRA_USB2_OFFSET, TEGRA_USB2_SIZE, 1, TEGRA_INTR_USB2 },
   { "ehci",

Index: src/sys/arch/evbarm/conf/JETSONTK1
diff -u src/sys/arch/evbarm/conf/JETSONTK1:1.32 src/sys/arch/evbarm/conf/JETSONTK1:1.33
--- src/sys/arch/evbarm/conf/JETSONTK1:1.32	Sat Oct 17 21:18:47 2015
+++ src/sys/arch/evbarm/conf/JETSONTK1	Wed Oct 21 20:02:12 2015
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: JETSONTK1,v 1.32 2015/10/17 21:18:47 jmcneill Exp $
+#	$NetBSD: JETSONTK1,v 1.33 2015/10/21 20:02:12 jmcneill Exp $
 #
 #	NVIDIA Jetson TK1 - Tegra K1 development kit
 #	https://developer.nvidia.com/jetson-tk1
@@ -153,6 +153,8 @@ hdmicec*	at hdmicecbus?
 #nouveau0	at tegraio?		# GPU
 
 # USB 2.0
+tegrausbphy0	at tegraio? port 0	# USB PHY1
+tegrausbphy1	at tegraio? port 1	# USB PHY2
 ehci0		at tegraio? port 0	# USB1
 ehci1		at tegraio? port 1	# USB2
 ehci2		at tegraio? port 2	# USB3

Index: src/sys/arch/evbarm/tegra/tegra_machdep.c
diff -u src/sys/arch/evbarm/tegra/tegra_machdep.c:1.22 src/sys/arch/evbarm/tegra/tegra_machdep.c:1.23
--- src/sys/arch/evbarm/tegra/tegra_machdep.c:1.22	Wed Oct 21 10:43:09 2015
+++ src/sys/arch/evbarm/tegra/tegra_machdep.c	Wed Oct 21 20:02:13 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_machdep.c,v 1.22 2015/10/21 10:43:09 jmcneill Exp $ */
+/* $NetBSD: tegra_machdep.c,v 1.23 2015/10/21 20:02:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.22 2015/10/21 10:43:09 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.23 2015/10/21 20:02:13 jmcneill Exp $");
 
 #include "opt_tegra.h"
 #include "opt_machdep.h"
@@ -437,7 +437,7 @@ tegra_device_register(device_t self, voi
 	}
 
 #ifdef SOC_TEGRA124
-	if (device_is_a(self, "ehci")) {
+	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);

Added files:

Index: src/sys/arch/arm/nvidia/tegra_usbphy.c
diff -u /dev/null src/sys/arch/arm/nvidia/tegra_usbphy.c:1.1
--- /dev/null	Wed Oct 21 20:02:13 2015
+++ src/sys/arch/arm/nvidia/tegra_usbphy.c	Wed Oct 21 20:02:12 2015
@@ -0,0 +1,283 @@
+/* $NetBSD: tegra_usbphy.c,v 1.1 2015/10/21 20:02:12 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "locators.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_usbphy.c,v 1.1 2015/10/21 20:02:12 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 <arm/nvidia/tegra_var.h>
+#include <arm/nvidia/tegra_usbreg.h>
+
+static int	tegra_usbphy_match(device_t, cfdata_t, void *);
+static void	tegra_usbphy_attach(device_t, device_t, void *);
+
+struct tegra_usbphy_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	u_int			sc_port;
+
+	struct tegra_gpio_pin	*sc_pin_vbus;
+	uint8_t			sc_hssync_start_delay;
+	uint8_t			sc_idle_wait_delay;
+	uint8_t			sc_elastic_limit;
+	uint8_t			sc_term_range_adj;
+	uint8_t			sc_xcvr_setup;
+	uint8_t			sc_xcvr_lsfslew;
+	uint8_t			sc_xcvr_lsrslew;
+	uint8_t			sc_hssquelch_level;
+	uint8_t			sc_hsdiscon_level;
+	uint8_t			sc_xcvr_hsslew;
+};
+
+static int	tegra_usbphy_parse_properties(struct tegra_usbphy_softc *);
+static void	tegra_usbphy_utmip_init(struct tegra_usbphy_softc *);
+
+CFATTACH_DECL_NEW(tegra_usbphy, sizeof(struct tegra_usbphy_softc),
+	tegra_usbphy_match, tegra_usbphy_attach, NULL, NULL);
+
+static int
+tegra_usbphy_match(device_t parent, cfdata_t cf, void *aux)
+{
+	return 1;
+}
+
+static void
+tegra_usbphy_attach(device_t parent, device_t self, void *aux)
+{
+	struct tegra_usbphy_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_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;
+
+	aprint_naive("\n");
+	aprint_normal(": USB PHY%d\n", loc->loc_port + 1);
+
+	if (tegra_usbphy_parse_properties(sc) != 0)
+		return;
+
+	tegra_car_periph_usb_enable(sc->sc_port);
+	delay(2);
+
+	tegra_usbphy_utmip_init(sc);
+
+	if (prop_dictionary_get_cstring_nocopy(prop, "vbus-gpio", &pin)) {
+		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);
+		} else {
+			aprint_normal_dev(self, "VBUS input active\n");
+		}
+        }
+}
+
+static int
+tegra_usbphy_parse_properties(struct tegra_usbphy_softc *sc)
+{
+#define PROPGET(k, v)	\
+	if (prop_dictionary_get_uint8(prop, (k), (v)) == false) {	\
+		aprint_error_dev(sc->sc_dev,				\
+		    "missing property '%s'\n", (k));			\
+		return EIO;						\
+	}
+
+	prop_dictionary_t prop = device_properties(sc->sc_dev);
+
+	PROPGET("nvidia,hssync-start-delay", &sc->sc_hssync_start_delay);
+	PROPGET("nvidia,idle-wait-delay", &sc->sc_idle_wait_delay);
+	PROPGET("nvidia,elastic-limit", &sc->sc_elastic_limit);
+	PROPGET("nvidia,term-range-adj", &sc->sc_term_range_adj);
+	PROPGET("nvidia,xcvr-setup", &sc->sc_xcvr_setup);
+	PROPGET("nvidia,xcvr-lsfslew", &sc->sc_xcvr_lsfslew);
+	PROPGET("nvidia,xcvr-lsrslew", &sc->sc_xcvr_lsrslew);
+	PROPGET("nvidia,hssquelch-level", &sc->sc_hssquelch_level);
+	PROPGET("nvidia,hsdiscon-level", &sc->sc_hsdiscon_level);
+	PROPGET("nvidia,xcvr-hsslew", &sc->sc_xcvr_hsslew);
+
+	return 0;
+#undef PROPGET
+}
+
+static void
+tegra_usbphy_utmip_init(struct tegra_usbphy_softc *sc)
+{
+	bus_space_tag_t bst = sc->sc_bst;
+	bus_space_handle_t bsh = sc->sc_bsh;
+	int retry;
+
+	/* Put UTMIP PHY into reset before programming UTMIP config registers */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG,
+	    TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET, 0);
+
+	/* Enable UTMIP PHY mode */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG,
+	    TEGRA_EHCI_SUSP_CTRL_UTMIP_PHY_ENB, 0);
+
+	/* Stop crystal clock */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG,
+	    0, TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN);
+	delay(1);
+
+	/* Clear session status */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_PHY_VBUS_SENSORS_REG,
+	    0,
+	    TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_VALUE |
+	    TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_EN);
+
+	/* PLL configuration */
+	tegra_car_utmip_init();
+
+	/* Transceiver configuration */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG,
+	    __SHIFTIN(4, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP) |
+	    __SHIFTIN(3, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB) |
+	    __SHIFTIN(sc->sc_xcvr_hsslew,
+		      TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB),
+	    TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP |
+	    TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB |
+	    TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB);
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG,
+	    __SHIFTIN(sc->sc_term_range_adj,
+		      TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ),
+	    TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ);
+
+	if (sc->sc_port == 0) {
+		tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG,
+		    TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL_MSB |
+		    __SHIFTIN(sc->sc_hsdiscon_level,
+			      TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL),
+		    TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL); 
+	}
+
+	/* Misc config */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG0_REG,
+	    0,
+	    TEGRA_EHCI_UTMIP_MISC_CFG0_SUSPEND_EXIT_ON_EDGE);
+
+	/* BIAS cell power down lag */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG,
+	    __SHIFTIN(5, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT),
+	    TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT);
+
+	/* Debounce config */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_REG,
+	    __SHIFTIN(0x7530, TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_A),
+	    TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_A);
+
+	/* Transmit signal preamble config */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_TX_CFG0_REG,
+	    TEGRA_EHCI_UTMIP_TX_CFG0_FS_PREAMBLE_J, 0);
+
+	/* Power-down battery charger circuit */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BAT_CHRG_CFG0_REG,
+	    TEGRA_EHCI_UTMIP_BAT_CHRG_CFG0_PD_CHRG, 0);
+
+	/* Select low speed bias method */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG,
+	    0, TEGRA_EHCI_UTMIP_XCVR_CFG0_LSBIAS_SEL);
+
+	/* High speed receive config */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_HSRX_CFG0_REG,
+	    __SHIFTIN(sc->sc_idle_wait_delay,
+		      TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT) |
+	    __SHIFTIN(sc->sc_elastic_limit,
+		      TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT),
+	    TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT |
+	    TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT);
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_HSRX_CFG1_REG,
+	    __SHIFTIN(sc->sc_hssync_start_delay,
+		      TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY),
+	    TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY);
+
+	/* Start crystal clock */
+	delay(1);
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG,
+	    TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN, 0);
+
+	/* Clear port PLL powerdown status */
+	tegra_car_utmip_enable(sc->sc_port);
+
+	/* Bring UTMIP PHY out of reset */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG,
+	    0, TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET);
+	for (retry = 100000; retry > 0; retry--) {
+		const uint32_t susp = bus_space_read_4(bst, bsh,
+		    TEGRA_EHCI_SUSP_CTRL_REG);
+		if (susp & TEGRA_EHCI_SUSP_CTRL_PHY_CLK_VALID)
+			break;
+		delay(1);
+	}
+	if (retry == 0) {
+		aprint_error_dev(sc->sc_dev, "PHY clock is not valid\n");
+		return;
+	}
+
+	/* Disable ICUSB transceiver */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_ICUSB_CTRL_REG,
+	    0,
+	    TEGRA_EHCI_ICUSB_CTRL_ENB1);
+
+	/* Power up UTMPI transceiver */
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG,
+	    0,
+	    TEGRA_EHCI_UTMIP_XCVR_CFG0_PD_POWERDOWN |
+	    TEGRA_EHCI_UTMIP_XCVR_CFG0_PD2_POWERDOWN |
+	    TEGRA_EHCI_UTMIP_XCVR_CFG0_PDZI_POWERDOWN);
+	tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG,
+	    0,
+	    TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDISC_POWERDOWN |
+	    TEGRA_EHCI_UTMIP_XCVR_CFG1_PDCHRP_POWERDOWN |
+	    TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDR_POWERDOWN);
+
+	if (sc->sc_port == 0) {
+		tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG,
+		    0, TEGRA_EHCI_UTMIP_BIAS_CFG0_BIASPD);
+		delay(25);
+		tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG,
+		    0, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_POWERDOWN);
+	}
+}
Index: src/sys/arch/arm/nvidia/tegra_usbreg.h
diff -u /dev/null src/sys/arch/arm/nvidia/tegra_usbreg.h:1.1
--- /dev/null	Wed Oct 21 20:02:13 2015
+++ src/sys/arch/arm/nvidia/tegra_usbreg.h	Wed Oct 21 20:02:12 2015
@@ -0,0 +1,127 @@
+/* $NetBSD: tegra_usbreg.h,v 1.1 2015/10/21 20:02:12 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARM_TEGRA_USBREG_H
+#define _ARM_TEGRA_USBREG_H
+
+#define TEGRA_EHCI_TXFILLTUNING_REG		0x154
+#define TEGRA_EHCI_TXFILLTUNING_TXFIFOTHRES	__BITS(21,16)
+
+#define TEGRA_EHCI_ICUSB_CTRL_REG		0x15c
+#define TEGRA_EHCI_ICUSB_CTRL_ENB1		__BIT(3)
+#define TEGRA_EHCI_ICUSB_CTRL_VDD1		__BITS(2,0)
+
+#define TEGRA_EHCI_HOSTPC1_DEVLC_REG		0x1b4
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PTS		__BITS(31,29)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PTS_UTMI	0
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PTS_ULPI	2
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PTS_ICUSB_SER	3
+#define TEGRA_EHCI_HOSTPC1_DEVLC_STS		__BIT(28)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PTW		__BIT(27)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PSPD		__BITS(26,25)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PSPD_FS	0
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PSPD_LS	1
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PSPD_HS	2
+#define TEGRA_EHCI_HOSTPC1_DEVLC_ALPD		__BIT(24)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PFSC		__BIT(23)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_PHCD		__BIT(22)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_H_LPMX		__BITS(21,20)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_H_EPLPM	__BITS(19,16)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_H_LPMFRM	__BITS(15,12)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_D_ASUS		__BIT(17)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_D_STL		__BIT(16)
+#define TEGRA_EHCI_HOSTPC1_DEVLC_BA		__BITS(11,1)
+
+#define TEGRA_EHCI_USBMODE_REG			0x1f8
+#define TEGRA_EHCI_USBMODE_CM			__BITS(1,0)
+#define TEGRA_EHCI_USBMODE_CM_IDLE		0
+#define TEGRA_EHCI_USBMODE_CM_DEVICE		2
+#define TEGRA_EHCI_USBMODE_CM_HOST		3
+
+#define TEGRA_EHCI_SUSP_CTRL_REG		0x400
+#define TEGRA_EHCI_SUSP_CTRL_UHSIC_RESET	__BIT(14)
+#define TEGRA_EHCI_SUSP_CTRL_ULPI_PHY_ENB	__BIT(13)
+#define TEGRA_EHCI_SUSP_CTRL_UTMIP_PHY_ENB	__BIT(12)
+#define TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET	__BIT(11)
+#define TEGRA_EHCI_SUSP_CTRL_PHY_CLK_VALID	__BIT(7)
+
+#define TEGRA_EHCI_PHY_VBUS_SENSORS_REG		0x404
+#define TEGRA_EHCI_PHY_VBUS_SENSORS_A_VBUS_VLD_STS __BIT(26)
+#define TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_VALUE __BIT(12)
+#define TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_EN	__BIT(11)
+
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_REG		0x808
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB	__BITS(31,25)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB	__BITS(24,22)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_LSBIAS_SEL	__BIT(21)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP	__BITS(3,0)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_PDZI_POWERDOWN __BIT(18)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_PD2_POWERDOWN __BIT(16)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG0_PD_POWERDOWN	__BIT(14)
+
+#define TEGRA_EHCI_UTMIP_BIAS_CFG0_REG		0x80c
+#define TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL_MSB __BIT(24)
+#define TEGRA_EHCI_UTMIP_BIAS_CFG0_BIASPD	__BIT(10)
+#define TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL __BITS(3,2)
+
+#define TEGRA_EHCI_UTMIP_TX_CFG0_REG		0x820
+#define TEGRA_EHCI_UTMIP_TX_CFG0_FS_PREAMBLE_J	__BIT(19)
+
+#define TEGRA_EHCI_UTMIP_MISC_CFG0_REG		0x824
+#define TEGRA_EHCI_UTMIP_MISC_CFG0_SUSPEND_EXIT_ON_EDGE __BIT(22)
+
+#define TEGRA_EHCI_UTMIP_MISC_CFG1_REG		0x828
+#define TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN __BIT(30)
+
+#define TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_REG	0x82c
+#define TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_B	__BITS(31,16)
+#define TEGRA_EHCI_UTMIP_DEBOUNCE_CFG0_A	__BITS(15,0)
+
+#define TEGRA_EHCI_UTMIP_BAT_CHRG_CFG0_REG	0x830
+#define TEGRA_EHCI_UTMIP_BAT_CHRG_CFG0_PD_CHRG	__BIT(0)
+
+#define TEGRA_EHCI_UTMIP_SPARE_CFG0_REG		0x834
+
+#define TEGRA_EHCI_UTMIP_XCVR_CFG1_REG		0x838
+#define TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ __BITS(21,18)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDR_POWERDOWN __BIT(4)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG1_PDCHRP_POWERDOWN __BIT(2)
+#define TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDISC_POWERDOWN __BIT(0)
+
+#define TEGRA_EHCI_UTMIP_BIAS_CFG1_REG		0x83c
+#define TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT	__BITS(7,3)
+#define TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_POWERDOWN __BIT(0)
+
+#define TEGRA_EHCI_UTMIP_HSRX_CFG0_REG		0xc08
+#define TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT	__BITS(19,15)
+#define TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT __BITS(14,10)
+
+#define TEGRA_EHCI_UTMIP_HSRX_CFG1_REG		0xc0c
+#define TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY __BITS(5,1)
+
+#endif /* _ARM_TEGRA_USBREG_H */

Reply via email to