Module Name: src
Committed By: jmcneill
Date: Sat May 9 18:56:51 UTC 2015
Modified Files:
src/sys/arch/arm/nvidia: tegra_car.c tegra_carreg.h tegra_ehci.c
tegra_var.h
Added Files:
src/sys/arch/arm/nvidia: tegra_ehcireg.h
Log Message:
Tegra USB PHY support
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra_car.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/nvidia/tegra_carreg.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_ehci.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/nvidia/tegra_ehcireg.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_var.h
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/tegra_car.c
diff -u src/sys/arch/arm/nvidia/tegra_car.c:1.5 src/sys/arch/arm/nvidia/tegra_car.c:1.6
--- src/sys/arch/arm/nvidia/tegra_car.c:1.5 Sat May 9 11:17:59 2015
+++ src/sys/arch/arm/nvidia/tegra_car.c Sat May 9 18:56:51 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_car.c,v 1.5 2015/05/09 11:17:59 jmcneill Exp $ */
+/* $NetBSD: tegra_car.c,v 1.6 2015/05/09 18:56:51 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <[email protected]>
@@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.5 2015/05/09 11:17:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.6 2015/05/09 18:56:51 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -283,3 +283,91 @@ tegra_car_periph_sdmmc_set_div(u_int por
return 0;
}
+
+int
+tegra_car_periph_usb_enable(u_int port)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ bus_size_t rst_reg, enb_reg;
+ uint32_t dev_bit;
+
+ tegra_car_get_bs(&bst, &bsh);
+ switch (port) {
+ case 0:
+ rst_reg = CAR_RST_DEV_L_SET_REG;
+ enb_reg = CAR_CLK_ENB_L_SET_REG;
+ dev_bit = CAR_DEV_L_USBD;
+ break;
+ case 1:
+ rst_reg = CAR_RST_DEV_H_SET_REG;
+ enb_reg = CAR_CLK_ENB_H_SET_REG;
+ dev_bit = CAR_DEV_H_USB2;
+ break;
+ case 2:
+ rst_reg = CAR_RST_DEV_H_SET_REG;
+ enb_reg = CAR_CLK_ENB_H_SET_REG;
+ dev_bit = CAR_DEV_H_USB3;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ /* enter reset */
+ bus_space_write_4(bst, bsh, rst_reg, dev_bit);
+ /* enable clk */
+ bus_space_write_4(bst, bsh, enb_reg, dev_bit);
+
+ /* leave reset */
+ bus_space_write_4(bst, bsh, rst_reg+4, dev_bit);
+
+ return 0;
+}
+
+void
+tegra_car_utmip_init(void)
+{
+ const u_int enable_dly_count = 0x02;
+ const u_int stable_count = 0x33;
+ const u_int active_dly_count = 0x09;
+ const u_int xtal_freq_count = 0x7f;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ tegra_car_get_bs(&bst, &bsh);
+
+ tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG,
+ __SHIFTIN(stable_count, CAR_UTMIP_PLL_CFG2_STABLE_COUNT) |
+ __SHIFTIN(active_dly_count, CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT),
+ CAR_UTMIP_PLL_CFG2_STABLE_COUNT |
+ CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT);
+
+ tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG,
+ __SHIFTIN(enable_dly_count, CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT) |
+ __SHIFTIN(xtal_freq_count, CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT),
+ CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT |
+ CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT);
+
+ tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG,
+ 0,
+ CAR_UTMIP_PLL_CFG1_PLLU_POWERDOWN |
+ CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN);
+}
+
+void
+tegra_car_utmip_enable(u_int port)
+{
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ uint32_t bit = 0;
+
+ tegra_car_get_bs(&bst, &bsh);
+
+ switch (port) {
+ case 0: bit = CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN; break;
+ case 1: bit = CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN; break;
+ case 2: bit = CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN; break;
+ }
+
+ tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG, 0, bit);
+}
Index: src/sys/arch/arm/nvidia/tegra_carreg.h
diff -u src/sys/arch/arm/nvidia/tegra_carreg.h:1.6 src/sys/arch/arm/nvidia/tegra_carreg.h:1.7
--- src/sys/arch/arm/nvidia/tegra_carreg.h:1.6 Sat May 9 11:17:59 2015
+++ src/sys/arch/arm/nvidia/tegra_carreg.h Sat May 9 18:56:51 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_carreg.h,v 1.6 2015/05/09 11:17:59 jmcneill Exp $ */
+/* $NetBSD: tegra_carreg.h,v 1.7 2015/05/09 18:56:51 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <[email protected]>
@@ -213,4 +213,24 @@
#define CAR_DEV_H_AHBDMA __BIT(1)
#define CAR_DEV_H_MEM __BIT(0)
+#define CAR_UTMIP_PLL_CFG0_REG 0x480
+
+#define CAR_UTMIP_PLL_CFG1_REG 0x484
+#define CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT __BITS(31,27)
+#define CAR_UTMIP_PLL_CFG1_PLLU_POWERUP __BIT(17)
+#define CAR_UTMIP_PLL_CFG1_PLLU_POWERDOWN __BIT(16)
+#define CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERUP __BIT(15)
+#define CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN __BIT(14)
+#define CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT __BITS(11,0)
+
+#define CAR_UTMIP_PLL_CFG2_REG 0x488
+#define CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT __BITS(23,18)
+#define CAR_UTMIP_PLL_CFG2_STABLE_COUNT __BITS(17,6)
+#define CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERUP __BIT(5)
+#define CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN __BIT(4)
+#define CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERUP __BIT(3)
+#define CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN __BIT(2)
+#define CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERUP __BIT(1)
+#define CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN __BIT(0)
+
#endif /* _ARM_TEGRA_CARREG_H */
Index: src/sys/arch/arm/nvidia/tegra_ehci.c
diff -u src/sys/arch/arm/nvidia/tegra_ehci.c:1.3 src/sys/arch/arm/nvidia/tegra_ehci.c:1.4
--- src/sys/arch/arm/nvidia/tegra_ehci.c:1.3 Sat May 9 12:07:52 2015
+++ src/sys/arch/arm/nvidia/tegra_ehci.c Sat May 9 18:56:51 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_ehci.c,v 1.3 2015/05/09 12:07:52 jmcneill Exp $ */
+/* $NetBSD: tegra_ehci.c,v 1.4 2015/05/09 18:56:51 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <[email protected]>
@@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.3 2015/05/09 12:07:52 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.4 2015/05/09 18:56:51 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -46,19 +46,27 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c
#include <dev/usb/ehcivar.h>
#include <arm/nvidia/tegra_var.h>
+#include <arm/nvidia/tegra_ehcireg.h>
#define TEGRA_EHCI_REG_OFFSET 0x100
static int tegra_ehci_match(device_t, cfdata_t, void *);
static void tegra_ehci_attach(device_t, device_t, void *);
+static void tegra_ehci_init(struct ehci_softc *);
+
struct tegra_ehci_softc {
struct ehci_softc sc;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
void *sc_ih;
+ u_int sc_port;
struct tegra_gpio_pin *sc_pin_vbus;
};
+static void tegra_ehci_utmip_init(struct tegra_ehci_softc *);
+
CFATTACH_DECL2_NEW(tegra_ehci, sizeof(struct tegra_ehci_softc),
tegra_ehci_match, tegra_ehci_attach, NULL,
ehci_activate, NULL, ehci_childdet);
@@ -79,11 +87,16 @@ tegra_ehci_attach(device_t parent, devic
const char *pin;
int error;
+ sc->sc_bst = tio->tio_bst;
+ bus_space_subregion(tio->tio_bst, tio->tio_bsh,
+ loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+ sc->sc_port = loc->loc_port;
+
sc->sc.sc_dev = self;
sc->sc.sc_bus.hci_private = &sc->sc;
sc->sc.sc_bus.dmatag = tio->tio_dmat;
sc->sc.sc_bus.usbrev = USBREV_2_0;
- sc->sc.sc_flags = EHCIF_ETTF;
+ sc->sc.sc_flags = 0; /* XXX EHCIF_ETTF */
sc->sc.sc_id_vendor = 0x10de;
strlcpy(sc->sc.sc_vendor, "Tegra", sizeof(sc->sc.sc_vendor));
sc->sc.sc_size = loc->loc_size;
@@ -91,15 +104,27 @@ tegra_ehci_attach(device_t parent, devic
bus_space_subregion(tio->tio_bst, tio->tio_bsh,
loc->loc_offset + TEGRA_EHCI_REG_OFFSET,
loc->loc_size - TEGRA_EHCI_REG_OFFSET, &sc->sc.ioh);
+ sc->sc.sc_vendor_init = tegra_ehci_init;
aprint_naive("\n");
aprint_normal(": USB%d\n", loc->loc_port + 1);
+ 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)) {
- 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);
+ 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);
@@ -121,3 +146,168 @@ tegra_ehci_attach(device_t parent, devic
sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
}
+
+static void
+tegra_ehci_init(struct ehci_softc *esc)
+{
+ struct tegra_ehci_softc * const sc = device_private(esc->sc_dev);
+ uint32_t usbmode;
+
+ usbmode = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
+ TEGRA_EHCI_USBMODE_REG);
+
+ const u_int cm = __SHIFTOUT(usbmode, TEGRA_EHCI_USBMODE_CM);
+ if (cm != TEGRA_EHCI_USBMODE_CM_HOST) {
+ aprint_verbose_dev(esc->sc_dev, "switching to host mode\n");
+ usbmode &= ~TEGRA_EHCI_USBMODE_CM;
+ usbmode |= __SHIFTIN(TEGRA_EHCI_USBMODE_CM_HOST,
+ TEGRA_EHCI_USBMODE_CM);
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+ TEGRA_EHCI_USBMODE_REG, usbmode);
+ }
+
+ /* Parallel transceiver select */
+ tegra_reg_set_clear(sc->sc_bst, sc->sc_bsh,
+ TEGRA_EHCI_HOSTPC1_DEVLC_REG,
+ __SHIFTIN(TEGRA_EHCI_HOSTPC1_DEVLC_PTS_UTMI,
+ TEGRA_EHCI_HOSTPC1_DEVLC_PTS),
+ TEGRA_EHCI_HOSTPC1_DEVLC_PTS |
+ TEGRA_EHCI_HOSTPC1_DEVLC_STS);
+
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, TEGRA_EHCI_TXFILLTUNING_REG,
+ __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(8, 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(7, 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(2, 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(6, 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(0x73f4, 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(17, TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT) |
+ __SHIFTIN(16, 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(9, 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);
+ }
+}
Index: src/sys/arch/arm/nvidia/tegra_var.h
diff -u src/sys/arch/arm/nvidia/tegra_var.h:1.10 src/sys/arch/arm/nvidia/tegra_var.h:1.11
--- src/sys/arch/arm/nvidia/tegra_var.h:1.10 Sat May 9 11:17:59 2015
+++ src/sys/arch/arm/nvidia/tegra_var.h Sat May 9 18:56:51 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_var.h,v 1.10 2015/05/09 11:17:59 jmcneill Exp $ */
+/* $NetBSD: tegra_var.h,v 1.11 2015/05/09 18:56:51 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <[email protected]>
@@ -81,6 +81,9 @@ u_int tegra_car_pllp0_rate(void);
u_int tegra_car_uart_rate(u_int);
u_int tegra_car_periph_sdmmc_rate(u_int);
int tegra_car_periph_sdmmc_set_div(u_int, u_int);
+int tegra_car_periph_usb_enable(u_int);
+void tegra_car_utmip_init(void);
+void tegra_car_utmip_enable(u_int);
struct tegra_gpio_pin;
struct tegra_gpio_pin *tegra_gpio_acquire(const char *, u_int);
Added files:
Index: src/sys/arch/arm/nvidia/tegra_ehcireg.h
diff -u /dev/null src/sys/arch/arm/nvidia/tegra_ehcireg.h:1.1
--- /dev/null Sat May 9 18:56:51 2015
+++ src/sys/arch/arm/nvidia/tegra_ehcireg.h Sat May 9 18:56:51 2015
@@ -0,0 +1,113 @@
+/* $NetBSD: tegra_ehcireg.h,v 1.1 2015/05/09 18:56:51 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARM_TEGRA_EHCIREG_H
+#define _ARM_TEGRA_EHCIREG_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_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_EHCIREG_H */