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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 = {