Module Name:    src
Committed By:   jmcneill
Date:           Sat Sep 23 23:21:35 UTC 2017

Modified Files:
        src/sys/arch/arm/nvidia: tegra210_car.c tegra210_carreg.h
            tegra210_xusbpad.c

Log Message:
More XUSB init stuff.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/nvidia/tegra210_car.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra210_carreg.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra210_xusbpad.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/tegra210_car.c
diff -u src/sys/arch/arm/nvidia/tegra210_car.c:1.6 src/sys/arch/arm/nvidia/tegra210_car.c:1.7
--- src/sys/arch/arm/nvidia/tegra210_car.c:1.6	Fri Sep 22 10:54:44 2017
+++ src/sys/arch/arm/nvidia/tegra210_car.c	Sat Sep 23 23:21:35 2017
@@ -1,4 +1,5 @@
-/* $NetBSD: tegra210_car.c,v 1.6 2017/09/22 10:54:44 jmcneill Exp $ */
+/* $NetBSD: tegra210_car.c,v 1.7 2017/09/23 23:21:35 jmcneill Exp $ */
+#define TEGRA210_CAR_DEBUG
 
 /*-
  * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra210_car.c,v 1.6 2017/09/22 10:54:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra210_car.c,v 1.7 2017/09/23 23:21:35 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -738,31 +739,58 @@ tegra210_car_utmip_init(struct tegra210_
 	bus_space_tag_t bst = sc->sc_bst;
 	bus_space_handle_t bsh = sc->sc_bsh;
 
-	const u_int enable_dly_count = 5;
-	const u_int stable_count = 150;
-	const u_int active_dly_count = 24;
-	const u_int xtal_freq_count = 385;
+	/*
+	 * Set up the UTMI PLL.
+	 */
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG3_REG,
+	    0, CAR_UTMIP_PLL_CFG3_REF_SRC_SEL);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG3_REG,
+	    0, CAR_UTMIP_PLL_CFG3_REF_DIS);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG,
+	    0, CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE);
+	delay(10);
+	/* TODO UTMIP_PLL_CFG0 */
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG,
+	    CAR_UTMIP_PLL_CFG2_PHY_XTAL_CLOCKEN, 0);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG,
+	    0, CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT);	/* Don't care */
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG,
+	    0, CAR_UTMIP_PLL_CFG2_STABLE_COUNT);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG,
+	    0, CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG,
+	    0x3, CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT);
+
+	bus_space_write_4(bst, bsh, CAR_RST_DEV_W_CLR_REG, CAR_DEV_W_XUSB);
+	bus_space_write_4(bst, bsh, CAR_RST_DEV_Y_CLR_REG, CAR_DEV_Y_PEX_USB_UPHY);
+	bus_space_write_4(bst, bsh, CAR_RST_DEV_Y_CLR_REG, CAR_DEV_Y_SATA_USB_UPHY);
 
 	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_PD_SAMP_A_POWERUP |
+	    CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERUP |
+	    CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERUP,
 	    CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN |
 	    CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN |
-	    CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN |
-	    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);
+	    CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN);
 
+	/*
+	 * Set up UTMI PLL under hardware control
+	 */
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG, 0,
+	    CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERUP | CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG,
+	    0, CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG,
+	    CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE, 0);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG,
+	    0, CAR_UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG,
+	    CAR_UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET, 0);
+	tegra_reg_set_clear(bst, bsh, CLK_RST_CONTROLLER_XUSB_PLL_CFG0_REG,
+	    0, CLK_RST_CONTROLLER_XUSB_PLL_CFG0_UTMIPLL_LOCK_DLY);
+	delay(1);
+	tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG,
+	    CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE, 0);
 }
 
 static void
@@ -781,6 +809,11 @@ tegra210_car_xusb_init(struct tegra210_c
 	tegra_reg_set_clear(bst, bsh, CAR_PLLU_OUTA_REG, 0, CAR_PLLU_OUTA_OUT1_RSTN);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLU_OUTA_REG, 0, CAR_PLLU_OUTA_OUT2_RSTN);
 	delay(5);
+	tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG,
+	    __SHIFTIN(0x19, CAR_PLLU_BASE_DIVN) |
+	    __SHIFTIN(0x2, CAR_PLLU_BASE_DIVM) |
+	    __SHIFTIN(0x1, CAR_PLLU_BASE_DIVP),
+	    CAR_PLLU_BASE_DIVN | CAR_PLLU_BASE_DIVM | CAR_PLLU_BASE_DIVP);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, CAR_PLLU_BASE_ENABLE, 0);
 	do {
 		delay(2);
@@ -794,20 +827,60 @@ tegra210_car_xusb_init(struct tegra210_c
 	delay(2);
 
 	/*
+	 * Set up PLLREFE
+	 */
+	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG,
+	    0, CAR_PLLREFE_MISC_IDDQ);
+	delay(5);
+	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_BASE_REG,
+	    __SHIFTIN(0x4, CAR_PLLREFE_BASE_DIVM) |
+	    __SHIFTIN(0x41, CAR_PLLREFE_BASE_DIVN) |
+	    __SHIFTIN(0x0, CAR_PLLREFE_BASE_DIVP) |
+	    __SHIFTIN(0x0, CAR_PLLREFE_BASE_KCP),
+	    CAR_PLLREFE_BASE_DIVM |
+	    CAR_PLLREFE_BASE_DIVN |
+	    CAR_PLLREFE_BASE_DIVP |
+	    CAR_PLLREFE_BASE_KCP);
+	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_BASE_REG,
+	    CAR_PLLREFE_BASE_ENABLE, 0);
+	do {
+		delay(2);
+		val = bus_space_read_4(bst, bsh, CAR_PLLREFE_MISC_REG);
+	} while ((val & CAR_PLLREFE_MISC_LOCK) == 0);
+
+	/*
 	 * Set up the PLLE.
 	 */
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, 0, CAR_PLLE_AUX_REF_SEL_PLLREFE);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, 0, CAR_PLLE_AUX_REF_SRC);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, 0, CAR_PLLE_MISC_IDDQ_OVERRIDE);
 	delay(5);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, CAR_PLLE_MISC_PTS, 0);
+	tegra_reg_set_clear(bst, bsh, CAR_PLLE_BASE_REG,
+	    __SHIFTIN(0xe, CAR_PLLE_BASE_DIVP_CML) |
+	    __SHIFTIN(0x7d, CAR_PLLE_BASE_DIVN) |
+	    __SHIFTIN(0x2, CAR_PLLE_BASE_DIVM),
+	    CAR_PLLE_BASE_DIVP_CML |
+	    CAR_PLLE_BASE_DIVN |
+	    CAR_PLLE_BASE_DIVM);
+	tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG,
+	    CAR_PLLE_MISC_PTS,
+	    CAR_PLLE_MISC_KCP | CAR_PLLE_MISC_VREG_CTRL | CAR_PLLE_MISC_KVCO);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_BASE_REG, CAR_PLLE_BASE_ENABLE, 0);
 	do {
 		delay(2);
 		val = bus_space_read_4(bst, bsh, CAR_PLLE_MISC_REG);
 	} while ((val & CAR_PLLE_MISC_LOCK) == 0);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLE_SS_CNTL_REG, 0, CAR_PLLE_SS_CNTL_BYPASS_SS);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLE_SS_CNTL_REG, 0, CAR_PLLE_SS_CNTL_SSCBYP);
+	tegra_reg_set_clear(bst, bsh, CAR_PLLE_SS_CNTL_REG,
+	    __SHIFTIN(1, CAR_PLLE_SS_CNTL_SSCINC) |
+	    __SHIFTIN(0x23, CAR_PLLE_SS_CNTL_SSCINCINTRV) |
+	    __SHIFTIN(0x21, CAR_PLLE_SS_CNTL_SSCMAX),
+	    CAR_PLLE_SS_CNTL_SSCINC |
+	    CAR_PLLE_SS_CNTL_SSCINCINTRV |
+	    CAR_PLLE_SS_CNTL_SSCMAX |
+	    CAR_PLLE_SS_CNTL_SSCINVERT |
+	    CAR_PLLE_SS_CNTL_SSCCENTER |
+	    CAR_PLLE_SS_CNTL_BYPASS_SS |
+	    CAR_PLLE_SS_CNTL_SSCBYP);
 	delay(1);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_SS_CNTL_REG, 0, CAR_PLLE_SS_CNTL_INTERP_RESET);
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, 0, CAR_PLLE_MISC_IDDQ_SWCTL);
@@ -819,39 +892,7 @@ tegra210_car_xusb_init(struct tegra210_c
 	tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, CAR_PLLE_AUX_SEQ_ENABLE, 0);
 
 	bus_space_write_4(bst, bsh, CAR_CLK_ENB_W_SET_REG, CAR_DEV_W_XUSB);
-
-	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG,
-	    0, CAR_PLLREFE_MISC_IDDQ);
-	val = __SHIFTIN(25, CAR_PLLREFE_BASE_DIVN) |
-	    __SHIFTIN(1, CAR_PLLREFE_BASE_DIVM);
-	bus_space_write_4(bst, bsh, CAR_PLLREFE_BASE_REG, val);
-
-	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG,
-	    0, CAR_PLLREFE_MISC_LOCK_OVERRIDE);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_BASE_REG,
-	    CAR_PLLREFE_BASE_ENABLE, 0);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG,
-	    CAR_PLLREFE_MISC_LOCK_ENABLE, 0);
-
-	do {
-		delay(2);
-		val = bus_space_read_4(bst, bsh, CAR_PLLREFE_MISC_REG);
-	} while ((val & CAR_PLLREFE_MISC_LOCK) == 0);
-
-	tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG,
-	    CAR_PLLE_MISC_IDDQ_SWCTL, CAR_PLLE_MISC_IDDQ_OVERRIDE);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLE_BASE_REG,
-	    CAR_PLLE_BASE_ENABLE, 0);
-	tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG,
-	    CAR_PLLE_MISC_LOCK_ENABLE, 0);
-
-	do {
-		delay(2);
-		val = bus_space_read_4(bst, bsh, CAR_PLLE_MISC_REG);
-	} while ((val & CAR_PLLE_MISC_LOCK) == 0);
-
-	tegra_reg_set_clear(bst, bsh, CAR_CLKSRC_XUSB_SS_REG,
-	    CAR_CLKSRC_XUSB_SS_HS_CLK_BYPASS, 0);
+	bus_space_write_4(bst, bsh, CAR_CLK_ENB_W_SET_REG, CAR_DEV_W_XUSB_PADCTL);
 }
 
 static void
@@ -964,6 +1005,9 @@ tegra210_car_clock_get_rate_pll(struct t
 	} else if (tpll->base_reg == CAR_PLLP_BASE_REG) {
 		/* XXX divp is not applied to PLLP's primary output */
 		divp = 0;
+	} else if (tpll->base_reg == CAR_PLLE_BASE_REG) {
+		divp = 0;
+		divm *= __SHIFTOUT(base, tpll->divp_mask);
 	} else {
 		divp = __SHIFTOUT(base, tpll->divp_mask);
 	}

Index: src/sys/arch/arm/nvidia/tegra210_carreg.h
diff -u src/sys/arch/arm/nvidia/tegra210_carreg.h:1.5 src/sys/arch/arm/nvidia/tegra210_carreg.h:1.6
--- src/sys/arch/arm/nvidia/tegra210_carreg.h:1.5	Fri Sep 22 10:55:43 2017
+++ src/sys/arch/arm/nvidia/tegra210_carreg.h	Sat Sep 23 23:21:35 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra210_carreg.h,v 1.5 2017/09/22 10:55:43 jmcneill Exp $ */
+/* $NetBSD: tegra210_carreg.h,v 1.6 2017/09/23 23:21:35 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -172,6 +172,10 @@
 #define	CAR_PLLE_MISC_LOCK		__BIT(11)
 #define	CAR_PLLE_MISC_LOCK_ENABLE	__BIT(9)
 #define	CAR_PLLE_MISC_PTS		__BIT(8)
+#define	CAR_PLLE_MISC_KCP		__BITS(7,6)
+#define	CAR_PLLE_MISC_VREG_BG_CTRL	__BITS(5,4)
+#define	CAR_PLLE_MISC_VREG_CTRL		__BITS(3,2)
+#define	CAR_PLLE_MISC_KVCO		__BIT(0)
 
 #define	CAR_PLLD2_BASE_REG	0x4b8
 #define	CAR_PLLD2_BASE_BYPASS		__BIT(31)
@@ -511,6 +515,9 @@
 #define	CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT	__BITS(11,0)
 
 #define	CAR_UTMIP_PLL_CFG2_REG		0x488
+#define	CAR_UTMIP_PLL_CFG2_PHY_XTAL_CLOCKEN	__BIT(30)
+#define	CAR_UTMIP_PLL_CFG2_PD_SAMP_D_POWERUP	__BIT(25)
+#define	CAR_UTMIP_PLL_CFG2_PD_SAMP_D_POWERDOWN	__BIT(24)
 #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)
@@ -555,6 +562,12 @@
 #define	CAR_SATA_PLL_CFG1_PADPLL_PU_POST_DLY	__BITS(15,8)
 #define	CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_IDDQ_DLY __BITS(7,0)
 
+#define	CAR_UTMIP_PLL_CFG3_REG		0x4c0
+#define	CAR_UTMIP_PLL_CFG3_REF_SRC_SEL		__BIT(26)
+#define	CAR_UTMIP_PLL_CFG3_REF_DIS		__BIT(25)
+#define	CAR_UTMIP_PLL_CFG3_PTS			__BIT(24)
+#define	CAR_UTMIP_PLL_CFG3_SETUP		__BITS(23,0)
+
 #define	CAR_PLLREFE_BASE_REG		0x4c4
 #define	CAR_PLLREFE_BASE_BYPASS			__BIT(31)
 #define	CAR_PLLREFE_BASE_ENABLE			__BIT(30)
@@ -578,6 +591,7 @@
 #define	CAR_XUSBIO_PLL_CFG0_SEQ_STATE		__BITS(27,26)
 #define	CAR_XUSBIO_PLL_CFG0_SEQ_START_STATE	__BIT(25)
 #define	CAR_XUSBIO_PLL_CFG0_SEQ_ENABLE		__BIT(24)
+#define	CAR_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ	__BIT(13)
 #define	CAR_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET	__BIT(6)
 #define	CAR_XUSBIO_PLL_CFG0_SEQ_RESET_INPUT_VALUE	__BIT(5)
 #define	CAR_XUSBIO_PLL_CFG0_SEQ_IN_SWCTL	__BIT(4)
@@ -586,6 +600,26 @@
 #define	CAR_XUSBIO_PLL_CFG0_PADPLL_RESET_OVERRIDE_VALUE __BIT(1)
 #define	CAR_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL	__BIT(0)
 
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_REG	0x52c
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_LOCK		__BIT(31)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_STATE	__BITS(27,26)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE __BIT(25)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE	__BIT(24)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE __BIT(7)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET	__BIT(6)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE __BIT(5)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL	__BIT(4)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_OVERRIDE __BIT(3)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL __BIT(2)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE	__BIT(1)
+#define	CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL	__BIT(0)
+
+#define	CLK_RST_CONTROLLER_XUSB_PLL_CFG0_REG	0x534
+#define	CLK_RST_CONTROLLER_XUSB_PLL_CFG0_PLLU_CLK_SWITCH_DLY	__BITS(31,24)
+#define	CLK_RST_CONTROLLER_XUSB_PLL_CFG0_PLLU_LOCK_DLY		__BITS(23,14)
+#define	CLK_RST_CONTROLLER_XUSB_PLL_CFG0_UTMIPLL_IDDQ2_ENABLE_DLY __BITS(13,10)
+#define	CLK_RST_CONTROLLER_XUSB_PLL_CFG0_UTMIPLL_LOCK_DLY	__BITS(9,0)
+
 #define	CAR_CLKSRC_XUSB_HOST_REG	0x600
 #define	CAR_CLKSRC_XUSB_HOST_SRC		__BITS(31,29)
 #define	CAR_CLKSRC_XUSB_HOST_DIV		__BITS(7,0)

Index: src/sys/arch/arm/nvidia/tegra210_xusbpad.c
diff -u src/sys/arch/arm/nvidia/tegra210_xusbpad.c:1.4 src/sys/arch/arm/nvidia/tegra210_xusbpad.c:1.5
--- src/sys/arch/arm/nvidia/tegra210_xusbpad.c:1.4	Fri Sep 22 11:01:24 2017
+++ src/sys/arch/arm/nvidia/tegra210_xusbpad.c	Sat Sep 23 23:21:35 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra210_xusbpad.c,v 1.4 2017/09/22 11:01:24 jmcneill Exp $ */
+/* $NetBSD: tegra210_xusbpad.c,v 1.5 2017/09/23 23:21:35 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra210_xusbpad.c,v 1.4 2017/09/22 11:01:24 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra210_xusbpad.c,v 1.5 2017/09/23 23:21:35 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -46,6 +46,14 @@ __KERNEL_RCSID(0, "$NetBSD: tegra210_xus
 #define	 XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD			__BITS(19,18)
 #define	  XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB		1
 
+#define	XUSB_PADCTL_VBUS_OC_MAP_REG		0x18
+#define	 XUSB_PADCTL_VBUS_OC_MAP_VBUS_ENABLE(n)			__BIT((n) * 5)
+
+#define	XUSB_PADCTL_OC_DET_REG			0x1c
+#define	 XUSB_PADCTL_OC_DET_OC_DETECTED_VBUS_PAD(n)		__BIT(12 + (n))
+#define	 XUSB_PADCTL_OC_DET_OC_DETECTED(n)			__BIT(8 + (n))
+#define	 XUSB_PADCTL_OC_DET_SET_OC_DETECTED(n)			__BIT(0 + (n))
+
 #define	XUSB_PADCTL_ELPG_PROGRAM_1_REG		0x24
 #define	 XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_VCORE_DOWN	__BIT(31)
 #define	 XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN_EARLY	__BIT(30)
@@ -54,6 +62,39 @@ __KERNEL_RCSID(0, "$NetBSD: tegra210_xus
 #define	 XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN_EARLY(n)	__BIT((n) * 3 + 1)
 #define	 XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN(n)	__BIT((n) * 3 + 0)
 
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG		0x360
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV	__BITS(29,28)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV	__BITS(27,20)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV	__BITS(17,16)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS	__BIT(15)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD		__BIT(4)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE		__BIT(3)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP		__BITS(2,1)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ		__BIT(0)
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG		0x364
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL		__BITS(27,4)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD		__BIT(2)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE		__BIT(1)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN		__BIT(0)
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_3_REG		0x368
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG		0x36c
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN	__BIT(15)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL	__BITS(13,12)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN	__BIT(8)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL	__BITS(7,4)
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG		0x370
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL		__BITS(23,16)
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_6_REG		0x374
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_7_REG		0x378
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG		0x37c
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE	__BIT(31)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD	__BIT(15)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN	__BIT(13)
+#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN		__BIT(12)
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_9_REG		0x380
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_10_REG		0x384
+#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_11_REG		0x388
+
 #define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(n)	(0xa60 + (n) * 0x40)
 #define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL		__BITS(19,18)
 
@@ -380,6 +421,9 @@ tegra210_xusbpad_configure_usb3_port(str
 	delay(200);
 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
 	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_VCORE_DOWN(port->index));
+
+	SETCLR4(sc, XUSB_PADCTL_VBUS_OC_MAP_REG,
+	    XUSB_PADCTL_VBUS_OC_MAP_VBUS_ENABLE(port->index), 0);
 }
 
 static void
@@ -450,6 +494,8 @@ static void
 tegra210_xusbpad_xhci_enable(device_t dev)
 {
 	struct tegra210_xusbpad_softc * const sc = device_private(dev);
+	uint32_t val;
+	int retry;
 
 	SETCLR4(sc, XUSB_PADCTL_USB2_PAD_MUX_REG,
 	    __SHIFTIN(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB,
@@ -457,6 +503,121 @@ tegra210_xusbpad_xhci_enable(device_t de
 	    XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD);
 
 	tegra210_xusbpad_enable(sc);
+
+	/* UPHY PLLs */
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
+	    __SHIFTIN(0x136, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG,
+	    __SHIFTIN(0x2a, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD, 0);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD, 0);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD, 0);
+
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
+	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
+	    __SHIFTIN(2, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN, 0);
+
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    __SHIFTIN(0x19, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV),
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP);
+
+	delay(20);
+
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN, 0);
+
+	/* Calibration */
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN, 0);
+	for (retry = 10000; retry > 0; retry--) {
+		delay(2);
+		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG);
+		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) != 0)
+			break;
+	}
+	if (retry == 0) {
+		aprint_error_dev(dev, "timeout calibrating UPHY PLL (1)\n");
+		return;
+	}
+
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
+	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN);
+	for (retry = 10000; retry > 0; retry--) {
+		delay(2);
+		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG);
+		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) == 0)
+			break;
+	}
+	if (retry == 0) {
+		aprint_error_dev(dev, "timeout calibrating UPHY PLL (2)\n");
+		return;
+	}
+
+	/* Enable the PLL */
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE, 0);
+	for (retry = 10000; retry > 0; retry--) {
+		delay(2);
+		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG);
+		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS) != 0)
+			break;
+	}
+	if (retry == 0) {
+		aprint_error_dev(dev, "timeout enabling UPHY PLL\n");
+		return;
+	}
+
+	/* RCAL */
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN, 0);
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
+	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN, 0);
+	for (retry = 10000; retry > 0; retry--) {
+		delay(2);
+		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG);
+		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) != 0)
+			break;
+	}
+	if (retry == 0) {
+		aprint_error_dev(dev, "timeout calibrating UPHY PLL (3)\n");
+		return;
+	}
+
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
+	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN);
+	for (retry = 10000; retry > 0; retry--) {
+		delay(2);
+		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG);
+		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) == 0)
+			break;
+	}
+	if (retry == 0) {
+		aprint_error_dev(dev, "timeout calibrating UPHY PLL (4)\n");
+		return;
+	}
+
+	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
+	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN);
 }
 
 static const struct tegra_xusbpad_ops tegra210_xusbpad_ops = {

Reply via email to