[U-Boot] [PATCH 0/3] Tegra: USB: EHCI: add Tegra30 compatible support

Tegra114 USB EHCI is compatible with Tegra30 USB EHCI except: 1. Port Reset - Tegra30 takes 55ms, Tegra114 takes 50 ms to finish. 2. PLL parameters.
Jim Lin (3): ARM: Tegra: FDT: Add USB support for T20/T30/T114 ARM: Tegra: USB: Add driver support for Tegra30/Tegra114 Tegra: Config: Enable Tegra30/Tegra114 USB function
arch/arm/dts/tegra114.dtsi | 105 ++++++++ arch/arm/dts/tegra20.dtsi | 81 ++++++ arch/arm/dts/tegra30.dtsi | 108 ++++++++ arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra20/usb.h | 279 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/usb.h | 294 ++++++++++++++++++++++ board/nvidia/common/board.c | 2 +- board/nvidia/dts/tegra114-dalmore.dts | 7 + board/nvidia/dts/tegra30-cardhu.dts | 6 + drivers/usb/host/ehci-hcd.c | 40 ++- drivers/usb/host/ehci-tegra.c | 376 ++++++++++++++++++++------- include/configs/cardhu.h | 14 + include/configs/dalmore.h | 14 + include/configs/tegra114-common.h | 3 + include/configs/tegra30-common.h | 3 + include/fdtdec.h | 2 + lib/fdtdec.c | 2 + 20 files changed, 1523 insertions(+), 360 deletions(-) delete mode 100644 arch/arm/include/asm/arch-tegra/usb.h create mode 100644 arch/arm/include/asm/arch-tegra114/usb.h create mode 100644 arch/arm/include/asm/arch-tegra20/usb.h create mode 100644 arch/arm/include/asm/arch-tegra30/usb.h

Add DT node for USB function.
Signed-off-by: Jim Lin jilin@nvidia.com --- arch/arm/dts/tegra114.dtsi | 105 ++++++++++++++++++++++++++++++++ arch/arm/dts/tegra20.dtsi | 81 ++++++++++++++++++++++++ arch/arm/dts/tegra30.dtsi | 108 +++++++++++++++++++++++++++++++++ board/nvidia/dts/tegra114-dalmore.dts | 7 ++ board/nvidia/dts/tegra30-cardhu.dts | 6 ++ include/fdtdec.h | 2 + lib/fdtdec.c | 2 + 7 files changed, 311 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi index f86d18d..0f8387b 100644 --- a/arch/arm/dts/tegra114.dtsi +++ b/arch/arm/dts/tegra114.dtsi @@ -216,4 +216,109 @@ clocks = <&tegra_car 15>; status = "disable"; }; + +/* This table has USB timing parameters for each Oscillator frequency we + * support. There are four sets of values: + * + * 1. PLLU configuration information (reference clock is osc/clk_m and + * PLLU-FOs are fixed at 12MHz/60MHz/480MHz). + * Reference frequency MHZ 12.0 13.0 19.2 26.0 + * ---------------------------------------------------- + * DIVN 960 960 200 960 + * DIVM 12 13 4 26 + * CPCON 12 12 3 12 + * LFCON 2 2 2 2 + * + * 2. PLL CONFIGURATION & PARAMETERS for different clock generators: + * Reference frequency MHZ 12.0 13.0 19.2 26.0 + * ---------------------------------------------------- + * PLLU_ENABLE_DLY_COUNT 02 2 3 4 + * PLLU_STABLE_COUNT 47 51 75 102 + * PLL_ACTIVE_DLY_COUNT 08 9 12 9 + * XTAL_FREQ_COUNT 118 127 188 254 + * + * 3. Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and + * SessEnd. Each of these signals have their own debouncer and for each of + * those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or + * BIAS_DEBOUNCE_B). + * + * The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows: + * 0xffff -> No debouncing at all + * <n> ms = <n> * 1000 / (1/19.2MHz) / 4 + * + * So to program a 10 ms debounce for BIAS_DEBOUNCE_A, we have: + * BIAS_DEBOUNCE_A[15:0] = 10 * 1000 * 19.2 / 4 = 48000 = 0xBB80 + * + * We need to use only DebounceA for BOOTROM. We don't need the DebounceB + * values, so we can keep those to default. + * + * 4. The 20 microsecond delay after bias cell operation. + * UTMIP_BIAS_PAD_TRK_COUNT + * + * enum { + * PARAM_DIVN, // PLL FEEDBACK DIVIDER + * PARAM_DIVM, // PLL INPUT DIVIDER + * PARAM_DIVP, // POST DIVIDER (2^N) + * PARAM_CPCON, // BASE PLLC CHARGE Pump setup ctrl + * PARAM_LFCON, // BASE PLLC LOOP FILter setup ctrl + * PARAM_ENABLE_DELAY_COUNT, // PLL-U Enable Delay Count + * PARAM_STABLE_COUNT, // PLL-U STABLE count + * PARAM_ACTIVE_DELAY_COUNT, // PLL-U Active delay count + * PARAM_XTAL_FREQ_COUNT, // PLL-U XTAL frequency count + * PARAM_DEBOUNCE_A_TIME, // 10MS DELAY for BIAS_DEBOUNCE_A + * PARAM_BIAS_TIME, // 20US DELAY AFter bias cell op + * // UTMIP_BIAS_PAD_TRK_COUNT + *}; + */ + usbparams@0 { + compatible = "nvidia,usbparams"; + osc-frequency = <13000000>; + /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ + params = <0x3c0 0x0d 0x00 0xc 2 0x02 0x33 0x09 0x7f 0x7ef4 6>; + }; + + usbparams@1 { + compatible = "nvidia,usbparams"; + osc-frequency = <19200000>; + params = <0x0c8 0x04 0x00 0x3 2 0x03 0x4b 0x0c 0xbc 0xbb80 8>; + }; + + usbparams@2 { + compatible = "nvidia,usbparams"; + osc-frequency = <12000000>; + params = <0x3c0 0x0c 0x00 0xc 2 0x02 0x2f 0x08 0x76 0x7530 5>; + }; + + usbparams@3 { + compatible = "nvidia,usbparams"; + osc-frequency = <26000000>; + params = <0x3c0 0x1a 0x00 0xc 2 0x04 0x66 0x09 0xfe 0xfde8 0xb>; + }; + + usb@7d000000 { + compatible = "nvidia,tegra30-ehci", "nvidia,tegra114-ehci"; + reg = <0x7d000000 0x4000>; + interrupts = < 52 >; + phy_type = "utmi"; + clocks = <&tegra_car 22>; /* PERIPH_ID_USBD */ + status = "disabled"; + }; + + usb@7d004000 { + compatible = "nvidia,tegra30-ehci", "nvidia,tegra114-ehci"; + reg = <0x7d004000 0x4000>; + interrupts = < 53 >; + phy_type = "utmi"; + clocks = <&tegra_car 58>; /* PERIPH_ID_USB2 */ + status = "disabled"; + }; + + usb@7d008000 { + compatible = "nvidia,tegra30-ehci", "nvidia,tegra114-ehci"; + reg = <0x7d008000 0x4000>; + interrupts = < 129 >; + phy_type = "utmi"; + clocks = <&tegra_car 59>; /* PERIPH_ID_USB3 */ + status = "disabled"; + }; }; diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi index 3805750..d0e39b4 100644 --- a/arch/arm/dts/tegra20.dtsi +++ b/arch/arm/dts/tegra20.dtsi @@ -290,6 +290,87 @@ reg = <0x7000f400 0x200>; };
+/* This table has USB timing parameters for each Oscillator frequency we + * support. There are four sets of values: + * + * 1. PLLU configuration information (reference clock is osc/clk_m and + * PLLU-FOs are fixed at 12MHz/60MHz/480MHz). + * + * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz + * ---------------------------------------------------------------------- + * DIVN 960 (0x3c0) 200 (0c8) 960 (3c0h) 960 (3c0) + * DIVM 13 (0d) 4 (04) 12 (0c) 26 (1a) + * Filter frequency (MHz) 1 4.8 6 2 + * CPCON 1100b 0011b 1100b 1100b + * LFCON0 0 0 0 0 + * + * 2. PLL CONFIGURATION & PARAMETERS for different clock generators: + * + * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz + * --------------------------------------------------------------------------- + * PLLU_ENABLE_DLY_COUNT 02 (0x02) 03 (03) 02 (02) 04 (04) + * PLLU_STABLE_COUNT 51 (33) 75 (4B) 47 (2F) 102 (66) + * PLL_ACTIVE_DLY_COUNT 05 (05) 06 (06) 04 (04) 09 (09) + * XTAL_FREQ_COUNT 127 (7F) 187 (BB) 118 (76) 254 (FE) + * + * 3. Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and + * SessEnd. Each of these signals have their own debouncer and for each of + * those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or + * BIAS_DEBOUNCE_B). + * + * The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows: + * 0xffff -> No debouncing at all + * <n> ms = <n> * 1000 / (1/19.2MHz) / 4 + * + * So to program a 10 ms debounce for BIAS_DEBOUNCE_A, we have: + * BIAS_DEBOUNCE_A[15:0] = 10 * 1000 * 19.2 / 4 = 48000 = 0xBB80 + * + * We need to use only DebounceA for BOOTROM. We don't need the DebounceB + * values, so we can keep those to default. + * + * 4. The 20 microsecond delay after bias cell operation. + * UTMIP_BIAS_PAD_TRK_COUNT + * + * enum { + * PARAM_DIVN, // PLL FEEDBACK DIVIDER + * PARAM_DIVM, // PLL INPUT DIVIDER + * PARAM_DIVP, // POST DIVIDER (2^N) + * PARAM_CPCON, // BASE PLLC CHARGE Pump setup ctrl + * PARAM_LFCON, // BASE PLLC LOOP FILter setup ctrl + * PARAM_ENABLE_DELAY_COUNT, // PLL-U Enable Delay Count + * PARAM_STABLE_COUNT, // PLL-U STABLE count + * PARAM_ACTIVE_DELAY_COUNT, // PLL-U Active delay count + * PARAM_XTAL_FREQ_COUNT, // PLL-U XTAL frequency count + * PARAM_DEBOUNCE_A_TIME, // 10MS DELAY for BIAS_DEBOUNCE_A + * PARAM_BIAS_TIME, // 20US DELAY AFter bias cell op + * // UTMIP_BIAS_PAD_TRK_COUNT + *}; + */ + usbparams@0 { + compatible = "nvidia,usbparams"; + osc-frequency = <13000000>; + /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ + params = <0x3c0 0x0d 0x00 0xc 0 0x02 0x33 0x05 0x7f 0x7ef4 5>; + }; + + usbparams@1 { + compatible = "nvidia,usbparams"; + osc-frequency = <19200000>; + params = <0x0c8 0x04 0x00 0x3 0 0x03 0x4b 0x06 0xbb 0xbb80 7>; + }; + + usbparams@2 { + compatible = "nvidia,usbparams"; + osc-frequency = <12000000>; + params = <0x3c0 0x0c 0x00 0xc 0 0x02 0x2f 0x04 0x76 0x7530 5>; + }; + + usbparams@3 { + compatible = "nvidia,usbparams"; + osc-frequency = <26000000>; + params = <0x3c0 0x1a 0x00 0xc 0 0x04 0x66 0x09 0xfe 0xfde8 9>; + }; + usb@c5000000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5000000 0x4000>; diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi index ccf154f..3e6fbc4 100644 --- a/arch/arm/dts/tegra30.dtsi +++ b/arch/arm/dts/tegra30.dtsi @@ -216,4 +216,112 @@ clocks = <&tegra_car 15>; status = "disabled"; }; + +/* This table has USB timing parameters for each Oscillator frequency we + * support. There are four sets of values: + * + * 1. PLLU configuration information (reference clock is osc/clk_m and + * PLLU-FOs are fixed at 12MHz/60MHz/480MHz). + * (T3x) + * Reference frequency MHZ 12.0 13.0 19.2 26.0 + * ---------------------------------------------------- + * DIVN 960 960 200 960 + * DIVM 12 13 4 26 + * CPCON 12 12 3 12 + * LFCON 1 1 0 1 + * + * 2. PLL CONFIGURATION & PARAMETERS for different clock generators: + * (T3x) + * Reference frequency MHZ 12.0 13.0 19.2 26.0 + * ---------------------------------------------------- + * Index 8 0 4 12 + * PLLU_ENABLE_DLY_COUNT 02 2 3 4 + * PLLU_STABLE_COUNT 47 51 75 102 + * PLL_ACTIVE_DLY_COUNT 08 9 12 9 + * XTAL_FREQ_COUNT 118 127 188 254 + * + * 3. Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and + * SessEnd. Each of these signals have their own debouncer and for each of + * those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or + * BIAS_DEBOUNCE_B). + * + * The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows: + * 0xffff -> No debouncing at all + * <n> ms = <n> * 1000 / (1/19.2MHz) / 4 + * + * So to program a 10 ms debounce for BIAS_DEBOUNCE_A, we have: + * BIAS_DEBOUNCE_A[15:0] = 10 * 1000 * 19.2 / 4 = 48000 = 0xBB80 + * + * We need to use only DebounceA for BOOTROM. We don't need the DebounceB + * values, so we can keep those to default. + * + * 4. The 20 microsecond delay after bias cell operation. + * UTMIP_BIAS_PAD_TRK_COUNT + * + * enum { + * PARAM_DIVN, // PLL FEEDBACK DIVIDER + * PARAM_DIVM, // PLL INPUT DIVIDER + * PARAM_DIVP, // POST DIVIDER (2^N) + * PARAM_CPCON, // BASE PLLC CHARGE Pump setup ctrl + * PARAM_LFCON, // BASE PLLC LOOP FILter setup ctrl + * PARAM_ENABLE_DELAY_COUNT, // PLL-U Enable Delay Count + * PARAM_STABLE_COUNT, // PLL-U STABLE count + * PARAM_ACTIVE_DELAY_COUNT, // PLL-U Active delay count + * PARAM_XTAL_FREQ_COUNT, // PLL-U XTAL frequency count + * PARAM_DEBOUNCE_A_TIME, // 10MS DELAY for BIAS_DEBOUNCE_A + * PARAM_BIAS_TIME, // 20US DELAY After bias cell op + * // UTMIP_BIAS_PAD_TRK_COUNT + *}; + */ + usbparams@0 { + compatible = "nvidia,usbparams"; + osc-frequency = <13000000>; + /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ + params = <0x3c0 0x0d 0x00 0xc 1 0x02 0x33 0x09 0x7f 0x7ef4 5>; + }; + + usbparams@1 { + compatible = "nvidia,usbparams"; + osc-frequency = <19200000>; + params = <0x0c8 0x04 0x00 0x3 0 0x03 0x4b 0x0c 0xbc 0xbb80 7>; + }; + + usbparams@2 { + compatible = "nvidia,usbparams"; + osc-frequency = <12000000>; + params = <0x3c0 0x0c 0x00 0xc 1 0x02 0x2f 0x08 0x76 0x7530 5>; + }; + + usbparams@3 { + compatible = "nvidia,usbparams"; + osc-frequency = <26000000>; + params = <0x3c0 0x1a 0x00 0xc 1 0x04 0x66 0x09 0xfe 0xfde8 9>; + }; + + usb@7d000000 { + compatible = "nvidia,tegra30-ehci"; + reg = <0x7d000000 0x4000>; + interrupts = < 52 >; + phy_type = "utmi"; + clocks = <&tegra_car 22>; /* PERIPH_ID_USBD */ + status = "disabled"; + }; + + usb@7d004000 { + compatible = "nvidia,tegra30-ehci"; + reg = <0x7d004000 0x4000>; + interrupts = < 53 >; + phy_type = "utmi"; + clocks = <&tegra_car 58>; /* PERIPH_ID_USB2 */ + status = "disabled"; + }; + + usb@7d008000 { + compatible = "nvidia,tegra30-ehci"; + reg = <0x7d008000 0x4000>; + interrupts = < 129 >; + phy_type = "utmi"; + clocks = <&tegra_car 59>; /* PERIPH_ID_USB3 */ + status = "disabled"; + }; }; diff --git a/board/nvidia/dts/tegra114-dalmore.dts b/board/nvidia/dts/tegra114-dalmore.dts index 86e9459..435c01e 100644 --- a/board/nvidia/dts/tegra114-dalmore.dts +++ b/board/nvidia/dts/tegra114-dalmore.dts @@ -14,6 +14,7 @@ i2c4 = "/i2c@7000c700"; sdhci0 = "/sdhci@78000600"; sdhci1 = "/sdhci@78000400"; + usb0 = "/usb@7d008000"; };
memory { @@ -61,4 +62,10 @@ bus-width = <8>; status = "okay"; }; + + usb@7d008000 { + /* SPDIF_IN: USB_VBUS_EN1 */ + nvidia,vbus-gpio = <&gpio 86 0>; + status = "okay"; + }; }; diff --git a/board/nvidia/dts/tegra30-cardhu.dts b/board/nvidia/dts/tegra30-cardhu.dts index 4d22b48..071a464 100644 --- a/board/nvidia/dts/tegra30-cardhu.dts +++ b/board/nvidia/dts/tegra30-cardhu.dts @@ -14,6 +14,7 @@ i2c4 = "/i2c@7000c700"; sdhci0 = "/sdhci@78000600"; sdhci1 = "/sdhci@78000000"; + usb0 = "/usb@7d008000"; };
memory { @@ -63,4 +64,9 @@ status = "okay"; bus-width = <8>; }; + + usb@7d008000 { + nvidia,vbus-gpio = <&gpio 233 3>; /* PDD1, EN_3V3_PU */ + status = "okay"; + }; }; diff --git a/include/fdtdec.h b/include/fdtdec.h index 844991e..454c971 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -64,6 +64,8 @@ struct fdt_memory { enum fdt_compat_id { COMPAT_UNKNOWN, COMPAT_NVIDIA_TEGRA20_USB, /* Tegra20 USB port */ + COMPAT_NVIDIA_TEGRA30_USB, /* Tegra30 USB port */ + COMPAT_NVIDIA_TEGRA114_USB, /* Tegra114 USB port */ COMPAT_NVIDIA_TEGRA114_I2C, /* Tegra114 I2C w/single clock source */ COMPAT_NVIDIA_TEGRA20_I2C, /* Tegra20 i2c */ COMPAT_NVIDIA_TEGRA20_DVC, /* Tegra20 dvc (really just i2c) */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 403babd..fc18c4f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -37,6 +37,8 @@ DECLARE_GLOBAL_DATA_PTR; static const char * const compat_names[COMPAT_COUNT] = { COMPAT(UNKNOWN, "<none>"), COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"), + COMPAT(NVIDIA_TEGRA30_USB, "nvidia,tegra30-ehci"), + COMPAT(NVIDIA_TEGRA114_USB, "nvidia,tegra114-ehci"), COMPAT(NVIDIA_TEGRA114_I2C, "nvidia,tegra114-i2c"), COMPAT(NVIDIA_TEGRA20_I2C, "nvidia,tegra20-i2c"), COMPAT(NVIDIA_TEGRA20_DVC, "nvidia,tegra20-i2c-dvc"),

On 04/29/2013 03:21 AM, Jim Lin wrote:
Add DT node for USB function.
diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi
+/* This table has USB timing parameters for each Oscillator frequency we
- support. There are four sets of values:
- PLLU configuration information (reference clock is osc/clk_m and
- PLLU-FOs are fixed at 12MHz/60MHz/480MHz).
- Reference frequency MHZ 12.0 13.0 19.2 26.0
DIVN 960 960 200 960
DIVM 12 13 4 26
CPCON 12 12 3 12
LFCON 2 2 2 2
- PLL CONFIGURATION & PARAMETERS for different clock generators:
- Reference frequency MHZ 12.0 13.0 19.2 26.0
- PLLU_ENABLE_DLY_COUNT 02 2 3 4
- PLLU_STABLE_COUNT 47 51 75 102
- PLL_ACTIVE_DLY_COUNT 08 9 12 9
- XTAL_FREQ_COUNT 118 127 188 254
- Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and
- SessEnd. Each of these signals have their own debouncer and for each of
- those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or
- BIAS_DEBOUNCE_B).
- The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows:
- 0xffff -> No debouncing at all
- <n> ms = <n> * 1000 / (1/19.2MHz) / 4
- So to program a 10 ms debounce for BIAS_DEBOUNCE_A, we have:
- BIAS_DEBOUNCE_A[15:0] = 10 * 1000 * 19.2 / 4 = 48000 = 0xBB80
- We need to use only DebounceA for BOOTROM. We don't need the DebounceB
- values, so we can keep those to default.
- The 20 microsecond delay after bias cell operation.
- UTMIP_BIAS_PAD_TRK_COUNT
- enum {
- PARAM_DIVN, // PLL FEEDBACK DIVIDER
- PARAM_DIVM, // PLL INPUT DIVIDER
- PARAM_DIVP, // POST DIVIDER (2^N)
- PARAM_CPCON, // BASE PLLC CHARGE Pump setup ctrl
- PARAM_LFCON, // BASE PLLC LOOP FILter setup ctrl
- PARAM_ENABLE_DELAY_COUNT, // PLL-U Enable Delay Count
- PARAM_STABLE_COUNT, // PLL-U STABLE count
- PARAM_ACTIVE_DELAY_COUNT, // PLL-U Active delay count
- PARAM_XTAL_FREQ_COUNT, // PLL-U XTAL frequency count
- PARAM_DEBOUNCE_A_TIME, // 10MS DELAY for BIAS_DEBOUNCE_A
- PARAM_BIAS_TIME, // 20US DELAY AFter bias cell op
// UTMIP_BIAS_PAD_TRK_COUNT
- *};
- */
- usbparams@0 {
compatible = "nvidia,usbparams";
osc-frequency = <13000000>;
/* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
params = <0x3c0 0x0d 0x00 0xc 2 0x02 0x33 0x09 0x7f 0x7ef4 6>;
- };
- usbparams@1 {
compatible = "nvidia,usbparams";
osc-frequency = <19200000>;
params = <0x0c8 0x04 0x00 0x3 2 0x03 0x4b 0x0c 0xbc 0xbb80 8>;
- };
- usbparams@2 {
compatible = "nvidia,usbparams";
osc-frequency = <12000000>;
params = <0x3c0 0x0c 0x00 0xc 2 0x02 0x2f 0x08 0x76 0x7530 5>;
- };
- usbparams@3 {
compatible = "nvidia,usbparams";
osc-frequency = <26000000>;
params = <0x3c0 0x1a 0x00 0xc 2 0x04 0x66 0x09 0xfe 0xfde8 0xb>;
- };
None of the above should be present; this is SoC-specific information and should be part of the USB driver itself. There's no benefit to putting the information into DT just to parse it back out into the same tables that the driver could have contained in the first place.
The same comment applies to all 3 tegra*.dtsi files. For the Tegra20 case, please make sure that what you add here is identical to what has been proposed for the final kernel USB bindings. Ask Venu (now CC'd) for a pointer to that.
- usb@7d000000 {
compatible = "nvidia,tegra30-ehci", "nvidia,tegra114-ehci";
reg = <0x7d000000 0x4000>;
interrupts = < 52 >;
There shouldn't be spaces after < or before >.
The bindings here don't match the kernel. Please make sure they do.
This patch only touches 2 board files: Cardhu and Dalmore. Will USB support on other boards continue to work without any DT changes? Existing functionality can't be broken. I'd expect to see a bunch more DT files edited here.

On Fri, 2013-05-03 at 03:10 +0800, Stephen Warren wrote:
On 04/29/2013 03:21 AM, Jim Lin wrote:
Add DT node for USB function.
diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi
+/* This table has USB timing parameters for each Oscillator frequency we
- support. There are four sets of values:
- PLLU configuration information (reference clock is osc/clk_m and
- PLLU-FOs are fixed at 12MHz/60MHz/480MHz).
- Reference frequency MHZ 12.0 13.0 19.2 26.0
DIVN 960 960 200 960
DIVM 12 13 4 26
CPCON 12 12 3 12
LFCON 2 2 2 2
- PLL CONFIGURATION & PARAMETERS for different clock generators:
- Reference frequency MHZ 12.0 13.0 19.2 26.0
- PLLU_ENABLE_DLY_COUNT 02 2 3 4
- PLLU_STABLE_COUNT 47 51 75 102
- PLL_ACTIVE_DLY_COUNT 08 9 12 9
- XTAL_FREQ_COUNT 118 127 188 254
- Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and
- SessEnd. Each of these signals have their own debouncer and for each of
- those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or
- BIAS_DEBOUNCE_B).
- The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows:
- 0xffff -> No debouncing at all
- <n> ms = <n> * 1000 / (1/19.2MHz) / 4
- So to program a 10 ms debounce for BIAS_DEBOUNCE_A, we have:
- BIAS_DEBOUNCE_A[15:0] = 10 * 1000 * 19.2 / 4 = 48000 = 0xBB80
- We need to use only DebounceA for BOOTROM. We don't need the DebounceB
- values, so we can keep those to default.
- The 20 microsecond delay after bias cell operation.
- UTMIP_BIAS_PAD_TRK_COUNT
- enum {
- PARAM_DIVN, // PLL FEEDBACK DIVIDER
- PARAM_DIVM, // PLL INPUT DIVIDER
- PARAM_DIVP, // POST DIVIDER (2^N)
- PARAM_CPCON, // BASE PLLC CHARGE Pump setup ctrl
- PARAM_LFCON, // BASE PLLC LOOP FILter setup ctrl
- PARAM_ENABLE_DELAY_COUNT, // PLL-U Enable Delay Count
- PARAM_STABLE_COUNT, // PLL-U STABLE count
- PARAM_ACTIVE_DELAY_COUNT, // PLL-U Active delay count
- PARAM_XTAL_FREQ_COUNT, // PLL-U XTAL frequency count
- PARAM_DEBOUNCE_A_TIME, // 10MS DELAY for BIAS_DEBOUNCE_A
- PARAM_BIAS_TIME, // 20US DELAY AFter bias cell op
// UTMIP_BIAS_PAD_TRK_COUNT
- *};
- */
- usbparams@0 {
compatible = "nvidia,usbparams";
osc-frequency = <13000000>;
/* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
params = <0x3c0 0x0d 0x00 0xc 2 0x02 0x33 0x09 0x7f 0x7ef4 6>;
- };
- usbparams@1 {
compatible = "nvidia,usbparams";
osc-frequency = <19200000>;
params = <0x0c8 0x04 0x00 0x3 2 0x03 0x4b 0x0c 0xbc 0xbb80 8>;
- };
- usbparams@2 {
compatible = "nvidia,usbparams";
osc-frequency = <12000000>;
params = <0x3c0 0x0c 0x00 0xc 2 0x02 0x2f 0x08 0x76 0x7530 5>;
- };
- usbparams@3 {
compatible = "nvidia,usbparams";
osc-frequency = <26000000>;
params = <0x3c0 0x1a 0x00 0xc 2 0x04 0x66 0x09 0xfe 0xfde8 0xb>;
- };
None of the above should be present; this is SoC-specific information and should be part of the USB driver itself. There's no benefit to putting the information into DT just to parse it back out into the same tables that the driver could have contained in the first place.
Parameters are not completely same for T20, T30, and T114. Putting over dt file is for expanding on future chips.
The same comment applies to all 3 tegra*.dtsi files. For the Tegra20 case, please make sure that what you add here is identical to what has been proposed for the final kernel USB bindings. Ask Venu (now CC'd) for a pointer to that.
- usb@7d000000 {
compatible = "nvidia,tegra30-ehci", "nvidia,tegra114-ehci";
reg = <0x7d000000 0x4000>;
interrupts = < 52 >;
There shouldn't be spaces after < or before >.
The bindings here don't match the kernel. Please make sure they do. This patch only touches 2 board files: Cardhu and Dalmore. Will USB support on other boards continue to work without any DT changes? Existing functionality can't be broken. I'd expect to see a bunch more DT files edited here.
For T20, I only have Seaboard and Harmony platforms. For other T20 platforms, I may blindly add USB support as you suggested, is that okay?
-- nvpublic

On 05/03/2013 05:07 AM, Jim Lin wrote:
On Fri, 2013-05-03 at 03:10 +0800, Stephen Warren wrote:
On 04/29/2013 03:21 AM, Jim Lin wrote:
Add DT node for USB function.
diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi
+/* This table has USB timing parameters for each Oscillator frequency we
- support. There are four sets of values:
...
- usbparams@3 {
compatible = "nvidia,usbparams";
osc-frequency = <26000000>;
params = <0x3c0 0x1a 0x00 0xc 2 0x04 0x66 0x09 0xfe 0xfde8 0xb>;
- };
None of the above should be present; this is SoC-specific information and should be part of the USB driver itself. There's no benefit to putting the information into DT just to parse it back out into the same tables that the driver could have contained in the first place.
Parameters are not completely same for T20, T30, and T114. Putting over dt file is for expanding on future chips.
The driver itself is going to need to change anything in all likelihood, so there's no point attempting to put the parameters somewhere else to avoid changing the driver.
Even ignoring all that, the USB DT binding for Tegra is already defined, and does not include this information, so it must be in the driver.
...
The bindings here don't match the kernel. Please make sure they do. This patch only touches 2 board files: Cardhu and Dalmore. Will USB support on other boards continue to work without any DT changes? Existing functionality can't be broken. I'd expect to see a bunch more DT files edited here.
For T20, I only have Seaboard and Harmony platforms. For other T20 platforms, I may blindly add USB support as you suggested, is that okay?
Yes, please update all Tegra boards so that nothing breaks. For boards you don't have, others can perform the testing once you've posted the patches.

-----Original Message----- From: Stephen Warren [mailto:swarren@wwwdotorg.org] Sent: Friday, May 03, 2013 12:40 AM To: Jim Lin Cc: u-boot@lists.denx.de; marex@denx.de; Stephen Warren; Tom Warren; Venu Byravarasu Subject: Re: [U-Boot] [PATCH 1/3] ARM: Tegra: FDT: Add USB support for T20/T30/T114
On 04/29/2013 03:21 AM, Jim Lin wrote:
Add DT node for USB function.
diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi
+/* This table has USB timing parameters for each Oscillator frequency we
- support. There are four sets of values:
The same comment applies to all 3 tegra*.dtsi files. For the Tegra20 case, please make sure that what you add here is identical to what has been proposed for the final kernel USB bindings. Ask Venu (now CC'd) for a pointer to that.
Plz see attached file for finalized Tegra20 DT bindings.
- usb@7d000000 {
compatible = "nvidia,tegra30-ehci", "nvidia,tegra114-ehci";
reg = <0x7d000000 0x4000>;
interrupts = < 52 >;
There shouldn't be spaces after < or before >.
The bindings here don't match the kernel. Please make sure they do.
This patch only touches 2 board files: Cardhu and Dalmore. Will USB support on other boards continue to work without any DT changes? Existing functionality can't be broken. I'd expect to see a bunch more DT files edited here.
----------------------------------------------------------------------------------- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. -----------------------------------------------------------------------------------

Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes 50 ms. 2. PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com --- arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra20/usb.h | 279 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/usb.h | 294 ++++++++++++++++++++++ board/nvidia/common/board.c | 2 +- drivers/usb/host/ehci-hcd.c | 40 ++- drivers/usb/host/ehci-tegra.c | 376 ++++++++++++++++++++------- 9 files changed, 1178 insertions(+), 360 deletions(-) delete mode 100644 arch/arm/include/asm/arch-tegra/usb.h create mode 100644 arch/arm/include/asm/arch-tegra114/usb.h create mode 100644 arch/arm/include/asm/arch-tegra20/usb.h create mode 100644 arch/arm/include/asm/arch-tegra30/usb.h
diff --git a/arch/arm/include/asm/arch-tegra/clk_rst.h b/arch/arm/include/asm/arch-tegra/clk_rst.h index c754ec7..9b8de9c 100644 --- a/arch/arm/include/asm/arch-tegra/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra/clk_rst.h @@ -225,6 +225,16 @@ enum { IN_408_OUT_9_6_DIVISOR = 83, };
+/* CLK_RST_CONTROLLER_UTMIP_PLL_CFG1_0 */ +#define PLLU_POWERDOWN (1 << 16) +#define PLL_ENABLE_POWERDOWN (1 << 14) +#define PLL_ACTIVE_POWERDOWN (1 << 12) + +/* CLK_RST_CONTROLLER_UTMIP_PLL_CFG2_0 */ +#define UTMIP_FORCE_PD_SAMP_C_POWERDOWN (1 << 4) +#define UTMIP_FORCE_PD_SAMP_B_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PD_SAMP_A_POWERDOWN (1 << 0) + /* CLK_RST_CONTROLLER_OSC_CTRL_0 */ #define OSC_XOBP_SHIFT 1 #define OSC_XOBP_MASK (1U << OSC_XOBP_SHIFT) diff --git a/arch/arm/include/asm/arch-tegra/usb.h b/arch/arm/include/asm/arch-tegra/usb.h deleted file mode 100644 index ef6c089..0000000 --- a/arch/arm/include/asm/arch-tegra/usb.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef _TEGRA_USB_H_ -#define _TEGRA_USB_H_ - - -/* USB Controller (USBx_CONTROLLER_) regs */ -struct usb_ctlr { - /* 0x000 */ - uint id; - uint reserved0; - uint host; - uint device; - - /* 0x010 */ - uint txbuf; - uint rxbuf; - uint reserved1[2]; - - /* 0x020 */ - uint reserved2[56]; - - /* 0x100 */ - u16 cap_length; - u16 hci_version; - uint hcs_params; - uint hcc_params; - uint reserved3[5]; - - /* 0x120 */ - uint dci_version; - uint dcc_params; - uint reserved4[6]; - - /* 0x140 */ - uint usb_cmd; - uint usb_sts; - uint usb_intr; - uint frindex; - - /* 0x150 */ - uint reserved5; - uint periodic_list_base; - uint async_list_addr; - uint async_tt_sts; - - /* 0x160 */ - uint burst_size; - uint tx_fill_tuning; - uint reserved6; /* is this port_sc1 on some controllers? */ - uint icusb_ctrl; - - /* 0x170 */ - uint ulpi_viewport; - uint reserved7; - uint endpt_nak; - uint endpt_nak_enable; - - /* 0x180 */ - uint reserved; - uint port_sc1; - uint reserved8[6]; - - /* 0x1a0 */ - uint reserved9; - uint otgsc; - uint usb_mode; - uint endpt_setup_stat; - - /* 0x1b0 */ - uint reserved10[20]; - - /* 0x200 */ - uint reserved11[0x80]; - - /* 0x400 */ - uint susp_ctrl; - uint phy_vbus_sensors; - uint phy_vbus_wakeup_id; - uint phy_alt_vbus_sys; - - /* 0x410 */ - uint usb1_legacy_ctrl; - uint reserved12[4]; - - /* 0x424 */ - uint ulpi_timing_ctrl_0; - uint ulpi_timing_ctrl_1; - uint reserved13[53]; - - /* 0x500 */ - uint reserved14[64 * 3]; - - /* 0x800 */ - uint utmip_pll_cfg0; - uint utmip_pll_cfg1; - uint utmip_xcvr_cfg0; - uint utmip_bias_cfg0; - - /* 0x810 */ - uint utmip_hsrx_cfg0; - uint utmip_hsrx_cfg1; - uint utmip_fslsrx_cfg0; - uint utmip_fslsrx_cfg1; - - /* 0x820 */ - uint utmip_tx_cfg0; - uint utmip_misc_cfg0; - uint utmip_misc_cfg1; - uint utmip_debounce_cfg0; - - /* 0x830 */ - uint utmip_bat_chrg_cfg0; - uint utmip_spare_cfg0; - uint utmip_xcvr_cfg1; - uint utmip_bias_cfg1; -}; - - -/* USB1_LEGACY_CTRL */ -#define USB1_NO_LEGACY_MODE 1 - -#define VBUS_SENSE_CTL_SHIFT 1 -#define VBUS_SENSE_CTL_MASK (3 << VBUS_SENSE_CTL_SHIFT) -#define VBUS_SENSE_CTL_VBUS_WAKEUP 0 -#define VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP 1 -#define VBUS_SENSE_CTL_AB_SESS_VLD 2 -#define VBUS_SENSE_CTL_A_SESS_VLD 3 - -/* USB2_IF_ULPI_TIMING_CTRL_0 */ -#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) -#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) - -/* USB2_IF_ULPI_TIMING_CTRL_1 */ -#define ULPI_DATA_TRIMMER_LOAD (1 << 0) -#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) -#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) -#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) -#define ULPI_DIR_TRIMMER_LOAD (1 << 24) -#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) - -/* USBx_IF_USB_SUSP_CTRL_0 */ -#define ULPI_PHY_ENB (1 << 13) -#define UTMIP_PHY_ENB (1 << 12) -#define UTMIP_RESET (1 << 11) -#define USB_PHY_CLK_VALID (1 << 7) -#define USB_SUSP_CLR (1 << 5) - -/* USBx_UTMIP_MISC_CFG1 */ -#define UTMIP_PLLU_STABLE_COUNT_SHIFT 6 -#define UTMIP_PLLU_STABLE_COUNT_MASK \ - (0xfff << UTMIP_PLLU_STABLE_COUNT_SHIFT) -#define UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT 18 -#define UTMIP_PLL_ACTIVE_DLY_COUNT_MASK \ - (0x1f << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT) -#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30) - -/* USBx_UTMIP_PLL_CFG1_0 */ -#define UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT 27 -#define UTMIP_PLLU_ENABLE_DLY_COUNT_MASK \ - (0xf << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT) -#define UTMIP_XTAL_FREQ_COUNT_SHIFT 0 -#define UTMIP_XTAL_FREQ_COUNT_MASK 0xfff - -/* USBx_UTMIP_BIAS_CFG1_0 */ -#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3 -#define UTMIP_BIAS_PDTRK_COUNT_MASK \ - (0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT) - -#define UTMIP_DEBOUNCE_CFG0_SHIFT 0 -#define UTMIP_DEBOUNCE_CFG0_MASK 0xffff - -/* USBx_UTMIP_TX_CFG0_0 */ -#define UTMIP_FS_PREAMBLE_J (1 << 19) - -/* USBx_UTMIP_BAT_CHRG_CFG0_0 */ -#define UTMIP_PD_CHRG 1 - -/* USBx_UTMIP_XCVR_CFG0_0 */ -#define UTMIP_XCVR_LSBIAS_SE (1 << 21) - -/* USBx_UTMIP_SPARE_CFG0_0 */ -#define FUSE_SETUP_SEL (1 << 3) - -/* USBx_UTMIP_HSRX_CFG0_0 */ -#define UTMIP_IDLE_WAIT_SHIFT 15 -#define UTMIP_IDLE_WAIT_MASK (0x1f << UTMIP_IDLE_WAIT_SHIFT) -#define UTMIP_ELASTIC_LIMIT_SHIFT 10 -#define UTMIP_ELASTIC_LIMIT_MASK \ - (0x1f << UTMIP_ELASTIC_LIMIT_SHIFT) - -/* USBx_UTMIP_HSRX_CFG0_1 */ -#define UTMIP_HS_SYNC_START_DLY_SHIFT 1 -#define UTMIP_HS_SYNC_START_DLY_MASK \ - (0xf << UTMIP_HS_SYNC_START_DLY_SHIFT) - -/* USBx_CONTROLLER_2_USB2D_ICUSB_CTRL_0 */ -#define IC_ENB1 (1 << 3) - -/* SB2_CONTROLLER_2_USB2D_PORTSC1_0 */ -#define PTS_SHIFT 30 -#define PTS_MASK (3U << PTS_SHIFT) -#define PTS_UTMI 0 -#define PTS_RESERVED 1 -#define PTS_ULPI 2 -#define PTS_ICUSB_SER 3 - -#define STS (1 << 29) -#define WKOC (1 << 22) -#define WKDS (1 << 21) -#define WKCN (1 << 20) - -/* USBx_UTMIP_XCVR_CFG0_0 */ -#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) -#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) -#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) - -/* USBx_UTMIP_XCVR_CFG1_0 */ -#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) -#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) -#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) - -/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */ -#define VBUS_VLD_STS (1 << 26) - - -/* Setup USB on the board */ -int board_usb_init(const void *blob); - -#endif /* _TEGRA_USB_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/tegra.h b/arch/arm/include/asm/arch-tegra114/tegra.h index 5d426b5..893d229 100644 --- a/arch/arm/include/asm/arch-tegra114/tegra.h +++ b/arch/arm/include/asm/arch-tegra114/tegra.h @@ -30,5 +30,6 @@ #define NVBOOTINFOTABLE_BCTPTR 0x4C /* BCT pointer in BIT in IRAM */
#define MAX_NUM_CPU 4 +#define TEGRA_USB1_BASE 0x7D000000
#endif /* TEGRA114_H */ diff --git a/arch/arm/include/asm/arch-tegra114/usb.h b/arch/arm/include/asm/arch-tegra114/usb.h new file mode 100644 index 0000000..c3ca5fa --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/usb.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (c) 2013 NVIDIA Corporation + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_USB_H_ +#define _TEGRA_USB_H_ + + +/* USB Controller (USBx_CONTROLLER_) regs */ +struct usb_ctlr { + /* 0x000 */ + uint id; + uint reserved0; + uint host; + uint device; + + /* 0x010 */ + uint txbuf; + uint rxbuf; + uint reserved1[2]; + + /* 0x020 */ + uint reserved2[56]; + + /* 0x100 */ + u16 cap_length; + u16 hci_version; + uint hcs_params; + uint hcc_params; + uint reserved3[5]; + + /* 0x120 */ + uint dci_version; + uint dcc_params; + uint reserved4[2]; + + /* 0x130 */ + uint usb_cmd; + uint usb_sts; + uint usb_intr; + uint frindex; + + /* 0x140 */ + uint reserved5; + uint periodic_list_base; + uint async_list_addr; + uint reserved5_1; + + /* 0x150 */ + uint burst_size; + uint tx_fill_tuning; + uint reserved6; + uint icusb_ctrl; + + /* 0x160 */ + uint ulpi_viewport; + uint reserved7; + uint reserved7_0; + uint reserved7_1; + + /* 0x170 */ + uint reserved; + uint port_sc1; + uint reserved8[6]; + + /* 0x190 */ + uint reserved9[8]; + + /* 0x1b0 */ + uint reserved10; + uint hostpc1_devlc; + uint reserved10_1[2]; + + /* 0x1c0 */ + uint reserved10_2[4]; + + /* 0x1d0 */ + uint reserved10_3[4]; + + /* 0x1e0 */ + uint reserved10_4[4]; + + /* 0x1f0 */ + uint reserved10_5; + uint otgsc; + uint usb_mode; + uint reserved10_6; + + /* 0x200 */ + uint endpt_nak; + uint endpt_nak_enable; + uint endpt_setup_stat; + uint reserved11_1[0x7D]; + + /* 0x400 */ + uint susp_ctrl; + uint phy_vbus_sensors; + uint phy_vbus_wakeup_id; + uint phy_alt_vbus_sys; + + /* 0x410 */ + uint usb1_legacy_ctrl; + uint reserved12[3]; + + /* 0x420 */ + uint reserved13[56]; + + /* 0x500 */ + uint reserved14[64 * 3]; + + /* 0x800 */ + uint utmip_pll_cfg0; + uint utmip_pll_cfg1; + uint utmip_xcvr_cfg0; + uint utmip_bias_cfg0; + + /* 0x810 */ + uint utmip_hsrx_cfg0; + uint utmip_hsrx_cfg1; + uint utmip_fslsrx_cfg0; + uint utmip_fslsrx_cfg1; + + /* 0x820 */ + uint utmip_tx_cfg0; + uint utmip_misc_cfg0; + uint utmip_misc_cfg1; + uint utmip_debounce_cfg0; + + /* 0x830 */ + uint utmip_bat_chrg_cfg0; + uint utmip_spare_cfg0; + uint utmip_xcvr_cfg1; + uint utmip_bias_cfg1; +}; + +/* USB1_LEGACY_CTRL */ +#define USB1_NO_LEGACY_MODE 1 + +#define VBUS_SENSE_CTL_SHIFT 1 +#define VBUS_SENSE_CTL_MASK (3 << VBUS_SENSE_CTL_SHIFT) +#define VBUS_SENSE_CTL_VBUS_WAKEUP 0 +#define VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP 1 +#define VBUS_SENSE_CTL_AB_SESS_VLD 2 +#define VBUS_SENSE_CTL_A_SESS_VLD 3 + +/* USBx_IF_USB_SUSP_CTRL_0 */ +#define UTMIP_PHY_ENB (1 << 12) +#define UTMIP_RESET (1 << 11) +#define USB_PHY_CLK_VALID (1 << 7) +#define USB_SUSP_CLR (1 << 5) + +/* USBx_UTMIP_MISC_CFG0 */ +#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) + +/* USBx_UTMIP_MISC_CFG1 */ +#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30) + +/* Moved to Clock and Reset register space */ +#define UTMIP_PLLU_STABLE_COUNT_SHIFT 6 +#define UTMIP_PLLU_STABLE_COUNT_MASK \ + (0xfff << UTMIP_PLLU_STABLE_COUNT_SHIFT) +/* Moved to Clock and Reset register space */ +#define UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT 18 +#define UTMIP_PLL_ACTIVE_DLY_COUNT_MASK \ + (0x1f << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT) + +/* USBx_UTMIP_PLL_CFG1_0 */ +/* Moved to Clock and Reset register space */ +#define UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT 27 +#define UTMIP_PLLU_ENABLE_DLY_COUNT_MASK \ + (0x1f << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT) +#define UTMIP_XTAL_FREQ_COUNT_SHIFT 0 +#define UTMIP_XTAL_FREQ_COUNT_MASK 0xfff + +/* USBx_UTMIP_BIAS_CFG0_0 */ +#define UTMIP_HSDISCON_LEVEL_MSB (1 << 24) +#define UTMIP_OTGPD (1 << 11) +#define UTMIP_BIASPD (1 << 10) +#define UTMIP_HSDISCON_LEVEL_SHIFT 2 +#define UTMIP_HSDISCON_LEVEL_MASK \ + (0x3 << UTMIP_HSDISCON_LEVEL_SHIFT) +#define UTMIP_HSSQUELCH_LEVEL_SHIFT 0 +#define UTMIP_HSSQUELCH_LEVEL_MASK \ + (0x3 << UTMIP_HSSQUELCH_LEVEL_SHIFT) + +/* USBx_UTMIP_BIAS_CFG1_0 */ +#define UTMIP_FORCE_PDTRK_POWERDOWN 1 +#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3 +#define UTMIP_BIAS_PDTRK_COUNT_MASK \ + (0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT) + +/* USBx_UTMIP_DEBOUNCE_CFG0_0 */ +#define UTMIP_DEBOUNCE_CFG0_SHIFT 0 +#define UTMIP_DEBOUNCE_CFG0_MASK 0xffff + +/* USBx_UTMIP_TX_CFG0_0 */ +#define UTMIP_FS_PREAMBLE_J (1 << 19) + +/* USBx_UTMIP_BAT_CHRG_CFG0_0 */ +#define UTMIP_PD_CHRG 1 + +/* USBx_UTMIP_SPARE_CFG0_0 */ +#define FUSE_SETUP_SEL (1 << 3) + +/* USBx_UTMIP_HSRX_CFG0_0 */ +#define UTMIP_IDLE_WAIT_SHIFT 15 +#define UTMIP_IDLE_WAIT_MASK (0x1f << UTMIP_IDLE_WAIT_SHIFT) +#define UTMIP_ELASTIC_LIMIT_SHIFT 10 +#define UTMIP_ELASTIC_LIMIT_MASK \ + (0x1f << UTMIP_ELASTIC_LIMIT_SHIFT) + +/* USBx_UTMIP_HSRX_CFG0_1 */ +#define UTMIP_HS_SYNC_START_DLY_SHIFT 1 +#define UTMIP_HS_SYNC_START_DLY_MASK \ + (0x1f << UTMIP_HS_SYNC_START_DLY_SHIFT) + +/* USBx_CONTROLLER_2_USB2D_ICUSB_CTRL_0 */ +#define IC_ENB1 (1 << 3) + +/* PORTSC1, USB1, defined for Tegra20 to avoid compiling error */ +#define PTS1_SHIFT 31 +#define PTS1_MASK (1 << PTS1_SHIFT) +#define STS1 (1 << 30) + +/* USB2D_HOSTPC1_DEVLC_0 */ +#define PTS_SHIFT 29 +#define PTS_MASK (0x7U << PTS_SHIFT) +#define PTS_UTMI 0 +#define PTS_RESERVED 1 +#define PTS_ULPI 2 +#define PTS_ICUSB_SER 3 +#define PTS_HSIC 4 + +#define STS (1 << 28) + +/* SB2_CONTROLLER_2_USB2D_PORTSC1_0 */ +#define WKOC (1 << 22) +#define WKDS (1 << 21) +#define WKCN (1 << 20) + +/* USBx_UTMIP_XCVR_CFG0_0 */ +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) +#define UTMIP_XCVR_LSBIAS_SE (1 << 21) +#define UTMIP_XCVR_HSSLEW_MSB_SHIFT 25 +#define UTMIP_XCVR_HSSLEW_MSB_MASK \ + (0x7f << UTMIP_XCVR_HSSLEW_MSB_SHIFT) +#define UTMIP_XCVR_SETUP_MSB_SHIFT 22 +#define UTMIP_XCVR_SETUP_MSB_MASK (0x7 << UTMIP_XCVR_SETUP_MSB_SHIFT) +#define UTMIP_XCVR_SETUP_SHIFT 0 +#define UTMIP_XCVR_SETUP_MASK (0xf << UTMIP_XCVR_SETUP_SHIFT) + +/* USBx_UTMIP_XCVR_CFG1_0 */ +#define UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT 18 +#define UTMIP_XCVR_TERM_RANGE_ADJ_MASK \ + (0xf << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT) +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) + +/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */ +#define VBUS_VLD_STS (1 << 26) + + +/* Setup USB on the board */ +int board_usb_init(const void *blob); + +#endif /* _TEGRA_USB_H_ */ diff --git a/arch/arm/include/asm/arch-tegra20/usb.h b/arch/arm/include/asm/arch-tegra20/usb.h new file mode 100644 index 0000000..415c0f6 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra20/usb.h @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (c) 2013 NVIDIA Corporation + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_USB_H_ +#define _TEGRA_USB_H_ + + +/* USB Controller (USBx_CONTROLLER_) regs */ +struct usb_ctlr { + /* 0x000 */ + uint id; + uint reserved0; + uint host; + uint device; + + /* 0x010 */ + uint txbuf; + uint rxbuf; + uint reserved1[2]; + + /* 0x020 */ + uint reserved2[56]; + + /* 0x100 */ + u16 cap_length; + u16 hci_version; + uint hcs_params; + uint hcc_params; + uint reserved3[5]; + + /* 0x120 */ + uint dci_version; + uint dcc_params; + uint reserved4[6]; + + /* 0x140 */ + uint usb_cmd; + uint usb_sts; + uint usb_intr; + uint frindex; + + /* 0x150 */ + uint reserved5; + uint periodic_list_base; + uint async_list_addr; + uint async_tt_sts; + + /* 0x160 */ + uint burst_size; + uint tx_fill_tuning; + uint reserved6; /* is this port_sc1 on some controllers? */ + uint icusb_ctrl; + + /* 0x170 */ + uint ulpi_viewport; + uint reserved7; + uint endpt_nak; + uint endpt_nak_enable; + + /* 0x180 */ + uint reserved; + uint port_sc1; + uint reserved8[6]; + + /* 0x1a0 */ + uint reserved9; + uint otgsc; + uint usb_mode; + uint endpt_setup_stat; + + /* 0x1b0 */ + uint reserved10[20]; + + /* 0x200 */ + uint reserved11[0x80]; + + /* 0x400 */ + uint susp_ctrl; + uint phy_vbus_sensors; + uint phy_vbus_wakeup_id; + uint phy_alt_vbus_sys; + + /* 0x410 */ + uint usb1_legacy_ctrl; + uint reserved12[4]; + + /* 0x424 */ + uint ulpi_timing_ctrl_0; + uint ulpi_timing_ctrl_1; + uint reserved13[53]; + + /* 0x500 */ + uint reserved14[64 * 3]; + + /* 0x800 */ + uint utmip_pll_cfg0; + uint utmip_pll_cfg1; + uint utmip_xcvr_cfg0; + uint utmip_bias_cfg0; + + /* 0x810 */ + uint utmip_hsrx_cfg0; + uint utmip_hsrx_cfg1; + uint utmip_fslsrx_cfg0; + uint utmip_fslsrx_cfg1; + + /* 0x820 */ + uint utmip_tx_cfg0; + uint utmip_misc_cfg0; + uint utmip_misc_cfg1; + uint utmip_debounce_cfg0; + + /* 0x830 */ + uint utmip_bat_chrg_cfg0; + uint utmip_spare_cfg0; + uint utmip_xcvr_cfg1; + uint utmip_bias_cfg1; +}; + + +/* USB1_LEGACY_CTRL */ +#define USB1_NO_LEGACY_MODE 1 + +#define VBUS_SENSE_CTL_SHIFT 1 +#define VBUS_SENSE_CTL_MASK (3 << VBUS_SENSE_CTL_SHIFT) +#define VBUS_SENSE_CTL_VBUS_WAKEUP 0 +#define VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP 1 +#define VBUS_SENSE_CTL_AB_SESS_VLD 2 +#define VBUS_SENSE_CTL_A_SESS_VLD 3 + +/* USB2_IF_ULPI_TIMING_CTRL_0 */ +#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) +#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) + +/* USB2_IF_ULPI_TIMING_CTRL_1 */ +#define ULPI_DATA_TRIMMER_LOAD (1 << 0) +#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) +#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) +#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) +#define ULPI_DIR_TRIMMER_LOAD (1 << 24) +#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) + +/* USBx_IF_USB_SUSP_CTRL_0 */ +#define ULPI_PHY_ENB (1 << 13) +#define UTMIP_PHY_ENB (1 << 12) +#define UTMIP_RESET (1 << 11) +#define USB_PHY_CLK_VALID (1 << 7) +#define USB_SUSP_CLR (1 << 5) + +/* USBx_UTMIP_MISC_CFG0 */ +#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) + +/* USBx_UTMIP_MISC_CFG1 */ +#define UTMIP_PLLU_STABLE_COUNT_SHIFT 6 +#define UTMIP_PLLU_STABLE_COUNT_MASK \ + (0xfff << UTMIP_PLLU_STABLE_COUNT_SHIFT) +#define UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT 18 +#define UTMIP_PLL_ACTIVE_DLY_COUNT_MASK \ + (0x1f << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT) +#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30) + +/* USBx_UTMIP_PLL_CFG1_0 */ +#define UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT 27 +#define UTMIP_PLLU_ENABLE_DLY_COUNT_MASK \ + (0xf << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT) +#define UTMIP_XTAL_FREQ_COUNT_SHIFT 0 +#define UTMIP_XTAL_FREQ_COUNT_MASK 0xfff + +/* USBx_UTMIP_BIAS_CFG0_0 */ +#define UTMIP_HSDISCON_LEVEL_MSB (1 << 24) +#define UTMIP_OTGPD (1 << 11) +#define UTMIP_BIASPD (1 << 10) +#define UTMIP_HSDISCON_LEVEL_SHIFT 2 +#define UTMIP_HSDISCON_LEVEL_MASK \ + (0x3 << UTMIP_HSDISCON_LEVEL_SHIFT) +#define UTMIP_HSSQUELCH_LEVEL_SHIFT 0 +#define UTMIP_HSSQUELCH_LEVEL_MASK \ + (0x3 << UTMIP_HSSQUELCH_LEVEL_SHIFT) + +/* USBx_UTMIP_BIAS_CFG1_0 */ +#define UTMIP_FORCE_PDTRK_POWERDOWN 1 +#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3 +#define UTMIP_BIAS_PDTRK_COUNT_MASK \ + (0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT) + +#define UTMIP_DEBOUNCE_CFG0_SHIFT 0 +#define UTMIP_DEBOUNCE_CFG0_MASK 0xffff + +/* USBx_UTMIP_TX_CFG0_0 */ +#define UTMIP_FS_PREAMBLE_J (1 << 19) + +/* USBx_UTMIP_BAT_CHRG_CFG0_0 */ +#define UTMIP_PD_CHRG 1 + +/* USBx_UTMIP_SPARE_CFG0_0 */ +#define FUSE_SETUP_SEL (1 << 3) + +/* USBx_UTMIP_HSRX_CFG0_0 */ +#define UTMIP_IDLE_WAIT_SHIFT 15 +#define UTMIP_IDLE_WAIT_MASK (0x1f << UTMIP_IDLE_WAIT_SHIFT) +#define UTMIP_ELASTIC_LIMIT_SHIFT 10 +#define UTMIP_ELASTIC_LIMIT_MASK \ + (0x1f << UTMIP_ELASTIC_LIMIT_SHIFT) + +/* USBx_UTMIP_HSRX_CFG0_1 */ +#define UTMIP_HS_SYNC_START_DLY_SHIFT 1 +#define UTMIP_HS_SYNC_START_DLY_MASK \ + (0xf << UTMIP_HS_SYNC_START_DLY_SHIFT) + +/* USBx_CONTROLLER_2_USB2D_ICUSB_CTRL_0 */ +#define IC_ENB1 (1 << 3) + +/* PORTSC1, USB1 */ +#define PTS1_SHIFT 31 +#define PTS1_MASK (1 << PTS1_SHIFT) +#define STS1 (1 << 30) + +/* PORTSC, USB2, USB3 */ +#define PTS_SHIFT 30 +#define PTS_MASK (3U << PTS_SHIFT) +#define PTS_UTMI 0 +#define PTS_RESERVED 1 +#define PTS_ULPI 2 +#define PTS_ICUSB_SER 3 + +#define STS (1 << 29) +#define WKOC (1 << 22) +#define WKDS (1 << 21) +#define WKCN (1 << 20) + +/* USBx_UTMIP_XCVR_CFG0_0 */ +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) +#define UTMIP_XCVR_LSBIAS_SE (1 << 21) +#define UTMIP_XCVR_HSSLEW_MSB_SHIFT 25 +#define UTMIP_XCVR_HSSLEW_MSB_MASK \ + (0x7f << UTMIP_XCVR_HSSLEW_MSB_SHIFT) +#define UTMIP_XCVR_SETUP_MSB_SHIFT 22 +#define UTMIP_XCVR_SETUP_MSB_MASK (0x7 << UTMIP_XCVR_SETUP_MSB_SHIFT) +#define UTMIP_XCVR_SETUP_SHIFT 0 +#define UTMIP_XCVR_SETUP_MASK (0xf << UTMIP_XCVR_SETUP_SHIFT) + + +/* USBx_UTMIP_XCVR_CFG1_0 */ +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) +#define UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT 18 +#define UTMIP_XCVR_TERM_RANGE_ADJ_MASK \ + (0xf << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT) + +/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */ +#define VBUS_VLD_STS (1 << 26) + + +/* Setup USB on the board */ +int board_usb_init(const void *blob); + +#endif /* _TEGRA_USB_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/usb.h b/arch/arm/include/asm/arch-tegra30/usb.h new file mode 100644 index 0000000..84049b7 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/usb.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (c) 2013 NVIDIA Corporation + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_USB_H_ +#define _TEGRA_USB_H_ + + +/* USB Controller (USBx_CONTROLLER_) regs */ +struct usb_ctlr { + /* 0x000 */ + uint id; + uint reserved0; + uint host; + uint device; + + /* 0x010 */ + uint txbuf; + uint rxbuf; + uint reserved1[2]; + + /* 0x020 */ + uint reserved2[56]; + + /* 0x100 */ + u16 cap_length; + u16 hci_version; + uint hcs_params; + uint hcc_params; + uint reserved3[5]; + + /* 0x120 */ + uint dci_version; + uint dcc_params; + uint reserved4[2]; + + /* 0x130 */ + uint usb_cmd; + uint usb_sts; + uint usb_intr; + uint frindex; + + /* 0x140 */ + uint reserved5; + uint periodic_list_base; + uint async_list_addr; + uint reserved5_1; + + /* 0x150 */ + uint burst_size; + uint tx_fill_tuning; + uint reserved6; /* is this port_sc1 on some controllers? */ + uint icusb_ctrl; + + /* 0x160 */ + uint ulpi_viewport; + uint reserved7; + uint endpt_nak; + uint endpt_nak_enable; + + /* 0x170 */ + uint reserved; + uint port_sc1; + uint reserved8[6]; + + /* 0x190 */ + uint reserved9[8]; + + /* 0x1b0 */ + uint reserved10; + uint hostpc1_devlc; + uint reserved10_1[2]; + + /* 0x1c0 */ + uint reserved10_2[4]; + + /* 0x1d0 */ + uint reserved10_3[4]; + + /* 0x1e0 */ + uint reserved10_4[4]; + + /* 0x1f0 */ + uint reserved10_5; + uint otgsc; + uint usb_mode; + uint reserved10_6; + + /* 0x200 */ + uint reserved11[2]; + uint endpt_setup_stat; + uint reserved11_1[0x7D]; + + /* 0x400 */ + uint susp_ctrl; + uint phy_vbus_sensors; + uint phy_vbus_wakeup_id; + uint phy_alt_vbus_sys; + + /* 0x410 */ + uint usb1_legacy_ctrl; + uint reserved12[3]; + + /* 0x420 */ + uint reserved13[56]; + + /* 0x500 */ + uint reserved14[64 * 3]; + + /* 0x800 */ + uint utmip_pll_cfg0; + uint utmip_pll_cfg1; + uint utmip_xcvr_cfg0; + uint utmip_bias_cfg0; + + /* 0x810 */ + uint utmip_hsrx_cfg0; + uint utmip_hsrx_cfg1; + uint utmip_fslsrx_cfg0; + uint utmip_fslsrx_cfg1; + + /* 0x820 */ + uint utmip_tx_cfg0; + uint utmip_misc_cfg0; + uint utmip_misc_cfg1; + uint utmip_debounce_cfg0; + + /* 0x830 */ + uint utmip_bat_chrg_cfg0; + uint utmip_spare_cfg0; + uint utmip_xcvr_cfg1; + uint utmip_bias_cfg1; +}; + +/* USB1_LEGACY_CTRL */ +#define USB1_NO_LEGACY_MODE 1 + +#define VBUS_SENSE_CTL_SHIFT 1 +#define VBUS_SENSE_CTL_MASK (3 << VBUS_SENSE_CTL_SHIFT) +#define VBUS_SENSE_CTL_VBUS_WAKEUP 0 +#define VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP 1 +#define VBUS_SENSE_CTL_AB_SESS_VLD 2 +#define VBUS_SENSE_CTL_A_SESS_VLD 3 + +/* USB2_IF_ULPI_TIMING_CTRL_0 */ +#define ULPI_OUTPUT_PINMUX_BYP (1 << 10) +#define ULPI_CLKOUT_PINMUX_BYP (1 << 11) + +/* USB2_IF_ULPI_TIMING_CTRL_1 */ +#define ULPI_DATA_TRIMMER_LOAD (1 << 0) +#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1) +#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16) +#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17) +#define ULPI_DIR_TRIMMER_LOAD (1 << 24) +#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25) + +/* USBx_IF_USB_SUSP_CTRL_0 */ +#define ULPI_PHY_ENB (1 << 13) +#define UTMIP_PHY_ENB (1 << 12) +#define UTMIP_RESET (1 << 11) +#define USB_PHY_CLK_VALID (1 << 7) +#define USB_SUSP_CLR (1 << 5) + +/* USBx_UTMIP_MISC_CFG0 */ +#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22) + +/* USBx_UTMIP_MISC_CFG1 */ +#define UTMIP_PLLU_STABLE_COUNT_SHIFT 6 +#define UTMIP_PLLU_STABLE_COUNT_MASK \ + (0xfff << UTMIP_PLLU_STABLE_COUNT_SHIFT) +#define UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT 18 +#define UTMIP_PLL_ACTIVE_DLY_COUNT_MASK \ + (0x1f << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT) +#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30) + +/* USBx_UTMIP_PLL_CFG1_0 */ +#define UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT 27 +#define UTMIP_PLLU_ENABLE_DLY_COUNT_MASK \ + (0xf << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT) +#define UTMIP_XTAL_FREQ_COUNT_SHIFT 0 +#define UTMIP_XTAL_FREQ_COUNT_MASK 0xfff + +/* USBx_UTMIP_BIAS_CFG0_0 */ +#define UTMIP_HSDISCON_LEVEL_MSB (1 << 24) +#define UTMIP_OTGPD (1 << 11) +#define UTMIP_BIASPD (1 << 10) +#define UTMIP_HSDISCON_LEVEL_SHIFT 2 +#define UTMIP_HSDISCON_LEVEL_MASK \ + (0x3 << UTMIP_HSDISCON_LEVEL_SHIFT) +#define UTMIP_HSSQUELCH_LEVEL_SHIFT 0 +#define UTMIP_HSSQUELCH_LEVEL_MASK \ + (0x3 << UTMIP_HSSQUELCH_LEVEL_SHIFT) + +/* USBx_UTMIP_BIAS_CFG1_0 */ +#define UTMIP_FORCE_PDTRK_POWERDOWN 1 +#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3 +#define UTMIP_BIAS_PDTRK_COUNT_MASK \ + (0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT) + +#define UTMIP_DEBOUNCE_CFG0_SHIFT 0 +#define UTMIP_DEBOUNCE_CFG0_MASK 0xffff + +/* USBx_UTMIP_TX_CFG0_0 */ +#define UTMIP_FS_PREAMBLE_J (1 << 19) + +/* USBx_UTMIP_BAT_CHRG_CFG0_0 */ +#define UTMIP_PD_CHRG 1 + +/* USBx_UTMIP_SPARE_CFG0_0 */ +#define FUSE_SETUP_SEL (1 << 3) + +/* USBx_UTMIP_HSRX_CFG0_0 */ +#define UTMIP_IDLE_WAIT_SHIFT 15 +#define UTMIP_IDLE_WAIT_MASK (0x1f << UTMIP_IDLE_WAIT_SHIFT) +#define UTMIP_ELASTIC_LIMIT_SHIFT 10 +#define UTMIP_ELASTIC_LIMIT_MASK \ + (0x1f << UTMIP_ELASTIC_LIMIT_SHIFT) + +/* USBx_UTMIP_HSRX_CFG0_1 */ +#define UTMIP_HS_SYNC_START_DLY_SHIFT 1 +#define UTMIP_HS_SYNC_START_DLY_MASK \ + (0xf << UTMIP_HS_SYNC_START_DLY_SHIFT) + +/* USBx_CONTROLLER_2_USB2D_ICUSB_CTRL_0 */ +#define IC_ENB1 (1 << 3) + +/* PORTSC1, USB1, defined for Tegra20 to avoid compiling error */ +#define PTS1_SHIFT 31 +#define PTS1_MASK (1 << PTS1_SHIFT) +#define STS1 (1 << 30) + +/* USB2D_HOSTPC1_DEVLC_0 */ +#define PTS_SHIFT 29 +#define PTS_MASK (0x7U << PTS_SHIFT) +#define PTS_UTMI 0 +#define PTS_RESERVED 1 +#define PTS_ULPI 2 +#define PTS_ICUSB_SER 3 +#define PTS_HSIC 4 + +#define STS (1 << 28) + +/* SB2_CONTROLLER_2_USB2D_PORTSC1_0 */ +#define WKOC (1 << 22) +#define WKDS (1 << 21) +#define WKCN (1 << 20) + +/* USBx_UTMIP_XCVR_CFG0_0 */ +#define UTMIP_FORCE_PD_POWERDOWN (1 << 14) +#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) +#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) +#define UTMIP_XCVR_LSBIAS_SE (1 << 21) +#define UTMIP_XCVR_HSSLEW_MSB_SHIFT 25 +#define UTMIP_XCVR_HSSLEW_MSB_MASK \ + (0x7f << UTMIP_XCVR_HSSLEW_MSB_SHIFT) +#define UTMIP_XCVR_SETUP_MSB_SHIFT 22 +#define UTMIP_XCVR_SETUP_MSB_MASK (0x7 << UTMIP_XCVR_SETUP_MSB_SHIFT) +#define UTMIP_XCVR_SETUP_SHIFT 0 +#define UTMIP_XCVR_SETUP_MASK (0xf << UTMIP_XCVR_SETUP_SHIFT) + +/* USBx_UTMIP_XCVR_CFG1_0 */ +#define UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT 18 +#define UTMIP_XCVR_TERM_RANGE_ADJ_MASK \ + (0xf << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT) +#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0) +#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2) +#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4) + +/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */ +#define VBUS_VLD_STS (1 << 26) + + +/* Setup USB on the board */ +int board_usb_init(const void *blob); + +#endif /* _TEGRA_USB_H_ */ diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 8d7a227..f0f81c9 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -46,7 +46,7 @@ #include <asm/arch/emc.h> #endif #ifdef CONFIG_USB_EHCI_TEGRA -#include <asm/arch-tegra/usb.h> +#include <asm/arch/usb.h> #endif #ifdef CONFIG_TEGRA_MMC #include <asm/arch-tegra/tegra_mmc.h> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c816878..6a55cd2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -122,6 +122,31 @@ static struct descriptor { #define ehci_is_TDI() (0) #endif
+int __ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) +{ + return PORTSC_PSPD(reg); +} + +int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) + __attribute__((weak, alias("__ehci_get_port_speed"))); + +void __ehci_set_usbmode(int index) +{ + uint32_t tmp; + uint32_t *reg_ptr; + + reg_ptr = (uint32_t *)((u8 *)&ehcic[index].hcor->or_usbcmd + USBMODE); + tmp = ehci_readl(reg_ptr); + tmp |= USBMODE_CM_HC; +#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN) + tmp |= USBMODE_BE; +#endif + ehci_writel(reg_ptr, tmp); +} + +void ehci_set_usbmode(int index) + __attribute__((weak, alias("__ehci_set_usbmode"))); + void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) { mdelay(50); @@ -149,8 +174,6 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) static int ehci_reset(int index) { uint32_t cmd; - uint32_t tmp; - uint32_t *reg_ptr; int ret = 0;
cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd); @@ -163,15 +186,8 @@ static int ehci_reset(int index) goto out; }
- if (ehci_is_TDI()) { - reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE); - tmp = ehci_readl(reg_ptr); - tmp |= USBMODE_CM_HC; -#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN) - tmp |= USBMODE_BE; -#endif - ehci_writel(reg_ptr, tmp); - } + if (ehci_is_TDI()) + ehci_set_usbmode(index);
#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning); @@ -711,7 +727,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
if (ehci_is_TDI()) { - switch (PORTSC_PSPD(reg)) { + switch (ehci_get_port_speed(ctrl->hcor, reg)) { case PORTSC_PSPD_FS: break; case PORTSC_PSPD_LS: diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 554145a..6b53659 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2011 The Chromium OS Authors. - * Copyright (c) 2009-2012 NVIDIA Corporation + * Copyright (c) 2009-2013 NVIDIA Corporation * Copyright (c) 2013 Lucas Stach * * See file CREDITS for list of people who contributed to this @@ -27,7 +27,8 @@ #include <asm/io.h> #include <asm-generic/gpio.h> #include <asm/arch/clock.h> -#include <asm/arch-tegra/usb.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch/usb.h> #include <usb.h> #include <usb/ulpi.h> #include <libfdt.h> @@ -35,6 +36,9 @@
#include "ehci.h"
+#define HOSTPC1_DEVLC 0x84 +#define HOSTPC1_PSPD(x) (((x) >> 25) & 0x3) + #ifdef CONFIG_USB_ULPI #ifndef CONFIG_USB_ULPI_VIEWPORT #error "To use CONFIG_USB_ULPI on Tegra Boards you have to also \ @@ -74,6 +78,7 @@ enum dr_mode { /* Information about a USB port */ struct fdt_usb { struct usb_ctlr *reg; /* address of registers in physical memory */ + int params[PARAM_COUNT]; /* timing parameters */ unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */ unsigned ulpi:1; /* 1 if port has external ULPI transceiver */ unsigned enabled:1; /* 1 to enable, 0 to disable */ @@ -87,55 +92,8 @@ struct fdt_usb {
static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */ static unsigned port_count; /* Number of available ports */ - -/* - * This table has USB timing parameters for each Oscillator frequency we - * support. There are four sets of values: - * - * 1. PLLU configuration information (reference clock is osc/clk_m and - * PLLU-FOs are fixed at 12MHz/60MHz/480MHz). - * - * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz - * ---------------------------------------------------------------------- - * DIVN 960 (0x3c0) 200 (0c8) 960 (3c0h) 960 (3c0) - * DIVM 13 (0d) 4 (04) 12 (0c) 26 (1a) - * Filter frequency (MHz) 1 4.8 6 2 - * CPCON 1100b 0011b 1100b 1100b - * LFCON0 0 0 0 0 - * - * 2. PLL CONFIGURATION & PARAMETERS for different clock generators: - * - * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz - * --------------------------------------------------------------------------- - * PLLU_ENABLE_DLY_COUNT 02 (0x02) 03 (03) 02 (02) 04 (04) - * PLLU_STABLE_COUNT 51 (33) 75 (4B) 47 (2F) 102 (66) - * PLL_ACTIVE_DLY_COUNT 05 (05) 06 (06) 04 (04) 09 (09) - * XTAL_FREQ_COUNT 127 (7F) 187 (BB) 118 (76) 254 (FE) - * - * 3. Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and - * SessEnd. Each of these signals have their own debouncer and for each of - * those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or - * BIAS_DEBOUNCE_B). - * - * The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows: - * 0xffff -> No debouncing at all - * <n> ms = <n> *1000 / (1/19.2MHz) / 4 - * - * So to program a 1 ms debounce for BIAS_DEBOUNCE_A, we have: - * BIAS_DEBOUNCE_A[15:0] = 1000 * 19.2 / 4 = 4800 = 0x12c0 - * - * We need to use only DebounceA for BOOTROM. We don't need the DebounceB - * values, so we can keep those to default. - * - * 4. The 20 microsecond delay after bias cell operation. - */ -static const unsigned usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = { - /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ - { 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 }, - { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 }, - { 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 }, - { 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 } -}; +static unsigned is_T30_compatible; +static unsigned is_T114_compatible;
/* UTMIP Idle Wait Delay */ static const u8 utmip_idle_wait_delay = 17; @@ -155,14 +113,62 @@ static const u8 utmip_hs_sync_start_delay = 9; */ void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) { - mdelay(50); - if (((u32) status_reg & TEGRA_USB_ADDR_MASK) != TEGRA_USB1_BASE) + udelay(49990); + if (is_T30_compatible) { + /* + * Tegra 114 takes 50 ms to assert Port Enable bit. + * We have to exit earlier. Otherwise ehci-hcd.c will clear + * our Port Enable bit. + */ + if (is_T114_compatible) + return; + /* Tegra 3 takes about 55 ms to assert Port Enable bit. */ + udelay(5010); + return; + } + udelay(10); + if (((u32)status_reg & TEGRA_USB_ADDR_MASK) != TEGRA_USB1_BASE) return; /* For EHCI_PS_CSC to be cleared in ehci_hcd.c */ if (ehci_readl(status_reg) & EHCI_PS_CSC) *reg |= EHCI_PS_CSC; }
+/* + * This ehci_set_usbmode overrides the weak function ehci_set_usbmode + * in "ehci-hcd.c". + */ +void ehci_set_usbmode(int index) +{ + struct fdt_usb *config; + struct usb_ctlr *usbctlr; + uint32_t tmp; + + config = &port[index]; + usbctlr = config->reg; + + tmp = ehci_readl(&usbctlr->usb_mode); + tmp |= USBMODE_CM_HC; + ehci_writel(&usbctlr->usb_mode, tmp); +} + +/* + * This ehci_get_port_speed overrides the weak function ehci_get_port_speed + * in "ehci-hcd.c". + */ +int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) +{ + uint32_t tmp; + uint32_t *reg_ptr; + + if (is_T30_compatible) { + reg_ptr = (uint32_t *)((u8 *)&hcor->or_usbcmd + HOSTPC1_DEVLC); + tmp = ehci_readl(reg_ptr); + return HOSTPC1_PSPD(tmp); + } else + return PORTSC_PSPD(reg); +} + /* Put the port into host mode */ static void set_host_mode(struct fdt_usb *config) { @@ -171,7 +177,7 @@ static void set_host_mode(struct fdt_usb *config) * bail out in this case. */ if (config->dr_mode == DR_MODE_OTG && - (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) + (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) return;
/* @@ -214,8 +220,10 @@ static int init_utmi_usb_controller(struct fdt_usb *config) { u32 val; int loop_count; - const unsigned *timing; + const u32 *timing; struct usb_ctlr *usbctlr = config->reg; + struct clk_rst_ctlr *clkrst; + struct usb_ctlr *usb1ctlr;
clock_enable(config->periph_id);
@@ -232,45 +240,112 @@ static int init_utmi_usb_controller(struct fdt_usb *config) * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP * mux must be switched to actually use a_sess_vld threshold. */ - if (fdt_gpio_isvalid(&config->vbus_gpio)) { + if (config->dr_mode == DR_MODE_OTG && + fdt_gpio_isvalid(&config->vbus_gpio)) clrsetbits_le32(&usbctlr->usb1_legacy_ctrl, - VBUS_SENSE_CTL_MASK, - VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT); - } + VBUS_SENSE_CTL_MASK, + VBUS_SENSE_CTL_A_SESS_VLD << + VBUS_SENSE_CTL_SHIFT);
/* * PLL Delay CONFIGURATION settings. The following parameters control * the bring up of the plls. */ - timing = usb_pll[clock_get_osc_freq()]; + timing = (u32 *)config->params; + if (is_T30_compatible) + goto pll_T30_init;
val = readl(&usbctlr->utmip_misc_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK, - timing[PARAM_STABLE_COUNT] << UTMIP_PLLU_STABLE_COUNT_SHIFT); + timing[PARAM_STABLE_COUNT] << + UTMIP_PLLU_STABLE_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK, - timing[PARAM_ACTIVE_DELAY_COUNT] << + timing[PARAM_ACTIVE_DELAY_COUNT] << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT); writel(val, &usbctlr->utmip_misc_cfg1);
/* Set PLL enable delay count and crystal frequency count */ val = readl(&usbctlr->utmip_pll_cfg1); clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK, - timing[PARAM_ENABLE_DELAY_COUNT] << + timing[PARAM_ENABLE_DELAY_COUNT] << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT); clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK, - timing[PARAM_XTAL_FREQ_COUNT] << + timing[PARAM_XTAL_FREQ_COUNT] << UTMIP_XTAL_FREQ_COUNT_SHIFT); writel(val, &usbctlr->utmip_pll_cfg1); + goto pll_init_done; + +pll_T30_init: + clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + val = readl(&clkrst->crc_utmip_pll_cfg2); + clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK, + timing[PARAM_STABLE_COUNT] << + UTMIP_PLLU_STABLE_COUNT_SHIFT); + clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK, + timing[PARAM_ACTIVE_DELAY_COUNT] << + UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT); + writel(val, &clkrst->crc_utmip_pll_cfg2); + + /* Set PLL enable delay count and crystal frequency count */ + val = readl(&clkrst->crc_utmip_pll_cfg1); + clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK, + timing[PARAM_ENABLE_DELAY_COUNT] << + UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT); + clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK, + timing[PARAM_XTAL_FREQ_COUNT] << + UTMIP_XTAL_FREQ_COUNT_SHIFT); + writel(val, &clkrst->crc_utmip_pll_cfg1); + + /* Disable Power Down state for PLL */ + clrbits_le32(&clkrst->crc_utmip_pll_cfg1, + PLLU_POWERDOWN | PLL_ENABLE_POWERDOWN | + PLL_ACTIVE_POWERDOWN); + + /* Recommended PHY settings for EYE diagram */ + val = readl(&usbctlr->utmip_xcvr_cfg0); + clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MASK, + 0x4 << UTMIP_XCVR_SETUP_SHIFT); + clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MSB_MASK, + 0x3 << UTMIP_XCVR_SETUP_MSB_SHIFT); + clrsetbits_le32(&val, UTMIP_XCVR_HSSLEW_MSB_MASK, + 0x8 << UTMIP_XCVR_HSSLEW_MSB_SHIFT); + writel(val, &usbctlr->utmip_xcvr_cfg0); + + clrsetbits_le32(&usbctlr->utmip_xcvr_cfg1, + UTMIP_XCVR_TERM_RANGE_ADJ_MASK, + 0x7 << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT); + + /* Some registers can be controlled from USB1 only. */ + if (config->periph_id != PERIPH_ID_USBD) { + clock_enable(PERIPH_ID_USBD); + /* Disable Reset if in Reset state */ + reset_set_enable(PERIPH_ID_USBD, 0); + } + usb1ctlr = (struct usb_ctlr *)TEGRA_USB1_BASE; + val = readl(&usb1ctlr->utmip_bias_cfg0); + setbits_le32(&val, UTMIP_HSDISCON_LEVEL_MSB); + clrsetbits_le32(&val, UTMIP_HSDISCON_LEVEL_MASK, + 0x1 << UTMIP_HSDISCON_LEVEL_SHIFT); + clrsetbits_le32(&val, UTMIP_HSSQUELCH_LEVEL_MASK, + 0x2 << UTMIP_HSSQUELCH_LEVEL_SHIFT); + writel(val, &usb1ctlr->utmip_bias_cfg0); + + /* Miscellaneous setting mentioned in Programming Guide */ + clrbits_le32(&usbctlr->utmip_misc_cfg0, UTMIP_SUSPEND_EXIT_ON_EDGE); +pll_init_done:
/* Setting the tracking length time */ clrsetbits_le32(&usbctlr->utmip_bias_cfg1, - UTMIP_BIAS_PDTRK_COUNT_MASK, - timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT); + UTMIP_BIAS_PDTRK_COUNT_MASK, + timing[PARAM_BIAS_TIME] << + UTMIP_BIAS_PDTRK_COUNT_SHIFT);
/* Program debounce time for VBUS to become valid */ clrsetbits_le32(&usbctlr->utmip_debounce_cfg0, - UTMIP_DEBOUNCE_CFG0_MASK, - timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT); + UTMIP_DEBOUNCE_CFG0_MASK, + timing[PARAM_DEBOUNCE_A_TIME] << + UTMIP_DEBOUNCE_CFG0_SHIFT);
setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);
@@ -292,15 +367,16 @@ static int init_utmi_usb_controller(struct fdt_usb *config) /* Set PLL enable delay count and Crystal frequency count */ val = readl(&usbctlr->utmip_hsrx_cfg0); clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK, - utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT); + utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT); clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK, - utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT); + utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT); writel(val, &usbctlr->utmip_hsrx_cfg0);
/* Configure the UTMIP_HS_SYNC_START_DLY */ clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1, - UTMIP_HS_SYNC_START_DLY_MASK, - utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT); + UTMIP_HS_SYNC_START_DLY_MASK, + utmip_hs_sync_start_delay << + UTMIP_HS_SYNC_START_DLY_SHIFT);
/* Preceed the crystal clock disable by >100ns delay. */ udelay(1); @@ -308,6 +384,14 @@ static int init_utmi_usb_controller(struct fdt_usb *config) /* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */ setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);
+ if (is_T30_compatible) { + if (config->periph_id == PERIPH_ID_USBD) + clrbits_le32(&clkrst->crc_utmip_pll_cfg2, + UTMIP_FORCE_PD_SAMP_A_POWERDOWN); + if (config->periph_id == PERIPH_ID_USB3) + clrbits_le32(&clkrst->crc_utmip_pll_cfg2, + UTMIP_FORCE_PD_SAMP_C_POWERDOWN); + } /* Finished the per-controller init. */
/* De-assert UTMIP_RESET to bring out of reset. */ @@ -325,17 +409,37 @@ static int init_utmi_usb_controller(struct fdt_usb *config) /* Disable ICUSB FS/LS transceiver */ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
- /* Select UTMI parallel interface */ - clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, - PTS_UTMI << PTS_SHIFT); - clrbits_le32(&usbctlr->port_sc1, STS); + if (!is_T30_compatible) { + /* Select UTMI parallel interface */ + if (config->periph_id == PERIPH_ID_USBD) { + clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK, + PTS_UTMI << PTS1_SHIFT); + clrbits_le32(&usbctlr->port_sc1, STS1); + } else { + clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, + PTS_UTMI << PTS_SHIFT); + clrbits_le32(&usbctlr->port_sc1, STS); + } + }
/* Deassert power down state */ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN | - UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN); + UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN); clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN | - UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN); + UTMIP_FORCE_PDCHRP_POWERDOWN | + UTMIP_FORCE_PDDR_POWERDOWN);
+ if (is_T30_compatible) { + /* + * BIAS Pad Power Down is common among all 3 USB + * controllers and can be controlled from USB1 only. + */ + usb1ctlr = (struct usb_ctlr *)TEGRA_USB1_BASE; + clrbits_le32(&usb1ctlr->utmip_bias_cfg0, UTMIP_BIASPD); + udelay(25); + clrbits_le32(&usb1ctlr->utmip_bias_cfg1, + UTMIP_FORCE_PDTRK_POWERDOWN); + } return 0; }
@@ -371,7 +475,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config)
/* enable pinmux bypass */ setbits_le32(&usbctlr->ulpi_timing_ctrl_0, - ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP); + ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);
/* Select ULPI parallel interface */ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_ULPI << PTS_SHIFT); @@ -431,16 +535,28 @@ static int init_ulpi_usb_controller(struct fdt_usb *config) } #endif
-static void config_clock(const u32 timing[]) +static void config_clock(const u32 *timing) { clock_start_pll(CLOCK_ID_USB, - timing[PARAM_DIVM], timing[PARAM_DIVN], timing[PARAM_DIVP], - timing[PARAM_CPCON], timing[PARAM_LFCON]); + timing[PARAM_DIVM], timing[PARAM_DIVN], + timing[PARAM_DIVP], timing[PARAM_CPCON], + timing[PARAM_LFCON]); }
-int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) +int fdt_decode_usb(const void *blob, int node, unsigned osc_frequency_hz, + struct fdt_usb *config) { const char *phy, *mode; + int clk_node = 0, rate; + + /* Find the parameters for our oscillator frequency */ + do { + clk_node = fdt_node_offset_by_compatible(blob, + clk_node, "nvidia,usbparams"); + if (clk_node < 0) + return -FDT_ERR_NOTFOUND; + rate = fdtdec_get_int(blob, clk_node, "osc-frequency", 0); + } while (rate != osc_frequency_hz);
config->reg = (struct usb_ctlr *)fdtdec_get_addr(blob, node, "reg"); mode = fdt_getprop(blob, node, "dr_mode", NULL); @@ -480,27 +596,30 @@ int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) config->ulpi, config->periph_id, config->vbus_gpio.gpio, config->phy_reset_gpio.gpio, config->dr_mode);
- return 0; + return fdtdec_get_int_array(blob, clk_node, "params", + (u32 *)&config->params, PARAM_COUNT); }
-int board_usb_init(const void *blob) +/* + * Process a list of nodes, adding them to our list of SDMMC ports. + * + * @param blob fdt blob + * @param node_list list of nodes to process (any <=0 are ignored) + * @param count number of nodes to process + * @return 0 if ok, -1 on error + */ +static int process_nodes(const void *blob, int node_list[], int count) { struct fdt_usb config; - enum clock_osc_freq freq; - int node_list[USB_PORTS_MAX]; - int node, count, i; + int node, i; + int clk_done = 0; + unsigned osc_freq = clock_get_rate(CLOCK_ID_OSC);
- /* Set up the USB clocks correctly based on our oscillator frequency */ - freq = clock_get_osc_freq(); - config_clock(usb_pll[freq]); - - /* count may return <0 on error */ - count = fdtdec_find_aliases_for_id(blob, "usb", - COMPAT_NVIDIA_TEGRA20_USB, node_list, USB_PORTS_MAX); + port_count = 0; for (i = 0; i < count; i++) { if (port_count == USB_PORTS_MAX) { - printf("tegrausb: Cannot register more than %d ports\n", - USB_PORTS_MAX); + printf("tegrausb: Cannot register more than %d ports\n" + , USB_PORTS_MAX); return -1; }
@@ -508,11 +627,15 @@ int board_usb_init(const void *blob) node = node_list[i]; if (!node) continue; - if (fdt_decode_usb(blob, node, &config)) { + if (fdt_decode_usb(blob, node, osc_freq, &config)) { debug("Cannot decode USB node %s\n", fdt_get_name(blob, node, NULL)); return -1; } + if (!clk_done) { + config_clock((u32 *)&config.params); + clk_done = 1; + } config.initialized = 0;
/* add new USB port to the list of available ports */ @@ -522,6 +645,49 @@ int board_usb_init(const void *blob) return 0; }
+int board_usb_init(const void *blob) +{ + int node_list[USB_PORTS_MAX]; + int count, err; + + is_T30_compatible = 0; + is_T114_compatible = 0; + + /* count may return <0 on error */ + count = fdtdec_find_aliases_for_id(blob, "usb", + COMPAT_NVIDIA_TEGRA20_USB, node_list, USB_PORTS_MAX); + if (!count) + goto skip_T20_process; + err = process_nodes(blob, node_list, count); + if (err) { + printf("%s: Error processing T20 compatible USB node(s)!\n", + __func__); + return err; + } +skip_T20_process: + + count = fdtdec_find_aliases_for_id(blob, "usb", + COMPAT_NVIDIA_TEGRA114_USB, node_list, USB_PORTS_MAX); + if (count) + is_T114_compatible = 1; + + count = fdtdec_find_aliases_for_id(blob, "usb", + COMPAT_NVIDIA_TEGRA30_USB, node_list, USB_PORTS_MAX); + if (count) + is_T30_compatible = 1; + else + goto skip_T30_process; + err = process_nodes(blob, node_list, count); + if (count && err) { + printf("%s: Error processing T30 compatible USB node(s)!\n", + __func__); + return err; + } +skip_T30_process: + + return 0; +} + /** * Start up the given port number (ports are numbered from 0 on each board). * This returns values for the appropriate hccr and hcor addresses to use for @@ -564,6 +730,20 @@ success: usbctlr = config->reg; *hccr = (struct ehci_hccr *)&usbctlr->cap_length; *hcor = (struct ehci_hcor *)&usbctlr->usb_cmd; + + if (is_T30_compatible) { + /* Set to Host mode after Controller Reset was done */ + clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, + USBMODE_CM_HC); + /* Select UTMI parallel interface after setting host mode */ + if (config->utmi) { + clrsetbits_le32((char *)&usbctlr->usb_cmd + + HOSTPC1_DEVLC, PTS_MASK, + PTS_UTMI << PTS_SHIFT); + clrbits_le32((char *)&usbctlr->usb_cmd + + HOSTPC1_DEVLC, STS); + } + } return 0; }

Dear Jim Lin,
Tegra30 and Tegra114 are compatible except
- T30 takes 55 ms to finish Port Reset. T114 takes 50 ms.
- PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra20/usb.h | 279 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/usb.h | 294 ++++++++++++++++++++++
Do we now have three copies of the same stuff ?
[...] Best regards, Marek Vasut

Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes 50 ms. 2. PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Tom
[...] Best regards, Marek Vasut
-- nvpublic

Dear Tom Warren,
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes
50 ms.
- PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Thanks for clearing that up.
Best regards, Marek Vasut

On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes 50 ms. 2. PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and masks different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we can or cannot use a particular part of the struct?

Tom,
On Tue, Apr 30, 2013 at 10:20 AM, Tom Rini trini@ti.com wrote:
On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes 50 ms. 2. PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and masks different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we can or cannot use a particular part of the struct?
This is really Jim's patchset (and his specialty), but here's what I know about Tegra USB regs:
T20 had a gap in the registers @ offset 0x130. T30 (and T114) moved the offset of the command/status/interrupt regs down to fill in this gap, which dragged all the subsequent registers back 16 bytes. The two SoCs 'families' sync up again at offset 0x400 and are pretty much equal from there on out to 0x840.
The defines are probably 90% the same, with some weirdness for the first USB controller (USB1) and its PTS/STS bits that differs in offset from the other 2 controllers (again, no clue why the HW guys would do this).
So we could have the 3 different USB headers in the arch-tegraXX area contain the register structs, and have a common arch-tegra/usb.h that has the #defines that are the same, and is included in the arch-tegraxx/usb.h files. That would reduce this down somewhat, without the ugliness of #ifdefs in the structs.
What do you think?
Tom
-- Tom

On Wed, May 01, 2013 at 09:16:45AM -0700, Tom Warren wrote:
Tom,
On Tue, Apr 30, 2013 at 10:20 AM, Tom Rini trini@ti.com wrote:
On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes 50 ms. 2. PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and masks different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we can or cannot use a particular part of the struct?
This is really Jim's patchset (and his specialty), but here's what I know about Tegra USB regs:
T20 had a gap in the registers @ offset 0x130. T30 (and T114) moved the offset of the command/status/interrupt regs down to fill in this gap, which dragged all the subsequent registers back 16 bytes. The two SoCs 'families' sync up again at offset 0x400 and are pretty much equal from there on out to 0x840.
The defines are probably 90% the same, with some weirdness for the first USB controller (USB1) and its PTS/STS bits that differs in offset from the other 2 controllers (again, no clue why the HW guys would do this).
So we could have the 3 different USB headers in the arch-tegraXX area contain the register structs, and have a common arch-tegra/usb.h that has the #defines that are the same, and is included in the arch-tegraxx/usb.h files. That would reduce this down somewhat, without the ugliness of #ifdefs in the structs.
What do you think?
Sounds like the best we can do then. It's probable that trying to define USB_REGMAP_GAPSIZE1/2 or whatever to do it on the fly would just be uglier still. Thanks!

Dear Tom Rini,
On Wed, May 01, 2013 at 09:16:45AM -0700, Tom Warren wrote:
Tom,
On Tue, Apr 30, 2013 at 10:20 AM, Tom Rini trini@ti.com wrote:
On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to finish Port Reset. T114 takes
50 ms.
- PLL parameters
Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com
arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + arch/arm/include/asm/arch-tegra/usb.h | 249 ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and masks different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we can or cannot use a particular part of the struct?
This is really Jim's patchset (and his specialty), but here's what I know about Tegra USB regs:
T20 had a gap in the registers @ offset 0x130. T30 (and T114) moved the offset of the command/status/interrupt regs down to fill in this gap, which dragged all the subsequent registers back 16 bytes. The two SoCs 'families' sync up again at offset 0x400 and are pretty much equal from there on out to 0x840.
The defines are probably 90% the same, with some weirdness for the first USB controller (USB1) and its PTS/STS bits that differs in offset from the other 2 controllers (again, no clue why the HW guys would do this).
So we could have the 3 different USB headers in the arch-tegraXX area contain the register structs, and have a common arch-tegra/usb.h that has the #defines that are the same, and is included in the arch-tegraxx/usb.h files. That would reduce this down somewhat, without the ugliness of #ifdefs in the structs.
What do you think?
Sounds like the best we can do then. It's probable that trying to define USB_REGMAP_GAPSIZE1/2 or whatever to do it on the fly would just be uglier still. Thanks!
This is a problem with the struct-based access indeed. I agree with Tom it'd be worth to at least try distilling the common part into header shared between those three CPUs.
btw you're also adding some kernel-doc-alike annotations to functions, why don't you follow kerneldoc style altogether?
Best regards, Marek Vasut

On Wed, May 1, 2013 at 12:33 PM, Marek Vasut marex@denx.de wrote:
Dear Tom Rini,
On Wed, May 01, 2013 at 09:16:45AM -0700, Tom Warren wrote:
Tom,
On Tue, Apr 30, 2013 at 10:20 AM, Tom Rini trini@ti.com wrote:
On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
> Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms
to
> finish Port Reset. T114 takes > > 50 ms. > > 2. PLL parameters > > Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and
Tegra114
> Dalmore platforms. All works well. > > Signed-off-by: Jim Lin jilin@nvidia.com > --- > > arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + > arch/arm/include/asm/arch-tegra/usb.h | 249 > ------------------ arch/arm/include/asm/arch-tegra114/tegra.h
|
> 1 + > arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
> arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
> arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and
masks
different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we can or cannot use a particular part of the struct?
This is really Jim's patchset (and his specialty), but here's what I
know
about Tegra USB regs:
T20 had a gap in the registers @ offset 0x130. T30 (and T114) moved the offset of the command/status/interrupt regs down to fill in this gap, which dragged all the subsequent registers back 16 bytes. The two SoCs 'families' sync up again at offset 0x400 and are pretty much equal from there on out to 0x840.
The defines are probably 90% the same, with some weirdness for the
first
USB controller (USB1) and its PTS/STS bits that differs in offset from the other 2 controllers (again, no clue why the HW guys would do this).
So we could have the 3 different USB headers in the arch-tegraXX area contain the register structs, and have a common arch-tegra/usb.h that
has
the #defines that are the same, and is included in the
arch-tegraxx/usb.h
files. That would reduce this down somewhat, without the ugliness of #ifdefs in the structs.
What do you think?
Sounds like the best we can do then. It's probable that trying to define USB_REGMAP_GAPSIZE1/2 or whatever to do it on the fly would just be uglier still. Thanks!
This is a problem with the struct-based access indeed. I agree with Tom it'd be worth to at least try distilling the common part into header shared between those three CPUs.
btw you're also adding some kernel-doc-alike annotations to functions, why don't you follow kerneldoc style altogether?
I'll let Jim answer that.
Best regards, Marek Vasut

Adding Jim back into the conversation since he got dropped a couple of emails back.
On Wed, May 1, 2013 at 4:20 PM, Tom Warren twarren.nvidia@gmail.com wrote:
On Wed, May 1, 2013 at 12:33 PM, Marek Vasut marex@denx.de wrote:
Dear Tom Rini,
On Wed, May 01, 2013 at 09:16:45AM -0700, Tom Warren wrote:
Tom,
On Tue, Apr 30, 2013 at 10:20 AM, Tom Rini trini@ti.com wrote:
On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
> -----Original Message----- > From: Marek Vasut [mailto:marex@denx.de] > Sent: Monday, April 29, 2013 4:47 PM > To: Jim Lin > Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren > Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for > Tegra30/Tegra114 > > Dear Jim Lin, > > > Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms
to
> > finish Port Reset. T114 takes > > > > 50 ms. > > > > 2. PLL parameters > > > > Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and
Tegra114
> > Dalmore platforms. All works well. > > > > Signed-off-by: Jim Lin jilin@nvidia.com > > --- > > > > arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + > > arch/arm/include/asm/arch-tegra/usb.h | 249 > > ------------------
arch/arm/include/asm/arch-tegra114/tegra.h |
> > 1 + > > arch/arm/include/asm/arch-tegra114/usb.h | 287 > > +++++++++++++++++++++ > > > arch/arm/include/asm/arch-tegra20/usb.h | 279 > > +++++++++++++++++++++ > > > arch/arm/include/asm/arch-tegra30/usb.h | 294 > > ++++++++++++++++++++++ > > Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to
arch-tegra20/usb.h,
and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't
see
any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and
masks
different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we
can
or cannot use a particular part of the struct?
This is really Jim's patchset (and his specialty), but here's what I
know
about Tegra USB regs:
T20 had a gap in the registers @ offset 0x130. T30 (and T114) moved
the
offset of the command/status/interrupt regs down to fill in this gap, which dragged all the subsequent registers back 16 bytes. The two SoCs 'families' sync up again at offset 0x400 and are pretty much equal
from
there on out to 0x840.
The defines are probably 90% the same, with some weirdness for the
first
USB controller (USB1) and its PTS/STS bits that differs in offset from the other 2 controllers (again, no clue why the HW guys would do
this).
So we could have the 3 different USB headers in the arch-tegraXX area contain the register structs, and have a common arch-tegra/usb.h that
has
the #defines that are the same, and is included in the
arch-tegraxx/usb.h
files. That would reduce this down somewhat, without the ugliness of #ifdefs in the structs.
What do you think?
Sounds like the best we can do then. It's probable that trying to define USB_REGMAP_GAPSIZE1/2 or whatever to do it on the fly would just be uglier still. Thanks!
This is a problem with the struct-based access indeed. I agree with Tom it'd be worth to at least try distilling the common part into header shared between those three CPUs.
btw you're also adding some kernel-doc-alike annotations to functions, why don't you follow kerneldoc style altogether?
I'll let Jim answer that.
Best regards, Marek Vasut

On Thu, 2013-05-02 at 03:33 +0800, Marek Vasut wrote:
Dear Tom Rini,
On Wed, May 01, 2013 at 09:16:45AM -0700, Tom Warren wrote:
Tom,
On Tue, Apr 30, 2013 at 10:20 AM, Tom Rini trini@ti.com wrote:
On Tue, Apr 30, 2013 at 09:21:18AM -0700, Tom Warren wrote:
Marek,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Monday, April 29, 2013 4:47 PM To: Jim Lin Cc: u-boot@lists.denx.de; Tom Warren; Stephen Warren Subject: Re: [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
> Tegra30 and Tegra114 are compatible except 1. T30 takes 55 ms to > finish Port Reset. T114 takes > > 50 ms. > > 2. PLL parameters > > Tested on Tegra20 Harmony/Seaboard, Tegra30 Cardhu, and Tegra114 > Dalmore platforms. All works well. > > Signed-off-by: Jim Lin jilin@nvidia.com > --- > > arch/arm/include/asm/arch-tegra/clk_rst.h | 10 + > arch/arm/include/asm/arch-tegra/usb.h | 249 > ------------------ arch/arm/include/asm/arch-tegra114/tegra.h | > 1 + > arch/arm/include/asm/arch-tegra114/usb.h | 287
+++++++++++++++++++++
> arch/arm/include/asm/arch-tegra20/usb.h | 279
+++++++++++++++++++++
> arch/arm/include/asm/arch-tegra30/usb.h | 294
++++++++++++++++++++++
Do we now have three copies of the same stuff ?
When only T20 was supported (for USB), there was a common (arch-tegra/usb.h) header. That's been moved to arch-tegra20/usb.h, and (unfortunately) there are 2 new usb.h files due to the HW differences in the registers between T20 and T30/T114. I don't see any easy way to have a common usb.h file for Tegra w/o adding ugly #ifdefs to the USB register space struct(s).
Just how different are they? Are all of the related defines and masks different too? Do we have conflicts? Moved registers? Just conflicting values? A quick peek shows '30' and '114' are pretty similar, except for masks. Maybe splitting the struct up so you can discard some of the reserved gaps, run-time checking to see if we can or cannot use a particular part of the struct?
This is really Jim's patchset (and his specialty), but here's what I know about Tegra USB regs:
T20 had a gap in the registers @ offset 0x130. T30 (and T114) moved the offset of the command/status/interrupt regs down to fill in this gap, which dragged all the subsequent registers back 16 bytes. The two SoCs 'families' sync up again at offset 0x400 and are pretty much equal from there on out to 0x840.
The defines are probably 90% the same, with some weirdness for the first USB controller (USB1) and its PTS/STS bits that differs in offset from the other 2 controllers (again, no clue why the HW guys would do this).
So we could have the 3 different USB headers in the arch-tegraXX area contain the register structs, and have a common arch-tegra/usb.h that has the #defines that are the same, and is included in the arch-tegraxx/usb.h files. That would reduce this down somewhat, without the ugliness of #ifdefs in the structs.
What do you think?
Sounds like the best we can do then. It's probable that trying to define USB_REGMAP_GAPSIZE1/2 or whatever to do it on the fly would just be uglier still. Thanks!
This is a problem with the struct-based access indeed. I agree with Tom it'd be worth to at least try distilling the common part into header shared between those three CPUs.
OK. I will add this into next version of patch.
btw you're also adding some kernel-doc-alike annotations to functions, why don't you follow kerneldoc style altogether?
I don't understand what you meant here. Could you give me an example? Like what I did is wrong or not good. And what is correct or better one. Thanks.
-- nvpublic

Dear Jim Lin,
[...]
This is a problem with the struct-based access indeed. I agree with Tom it'd be worth to at least try distilling the common part into header shared between those three CPUs.
OK. I will add this into next version of patch.
btw you're also adding some kernel-doc-alike annotations to functions, why don't you follow kerneldoc style altogether?
I don't understand what you meant here. Could you give me an example? Like what I did is wrong or not good. And what is correct or better one.
These kinds of annotations:
+/* + * Process a list of nodes, adding them to our list of SDMMC ports. + * + * @param blob fdt blob + * @param node_list list of nodes to process (any <=0 are ignored) + * @param count number of nodes to process + * @return 0 if ok, -1 on error + */
See http://www.denx.de/wiki/U-Boot/CodingStyle at the bottom for the right style.
Best regards, Marek Vasut

Jim,
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, May 02, 2013 4:39 AM To: Jim Lin Cc: Tom Rini; u-boot@lists.denx.de; Tom Warren; Stephen Warren; Tom Warren Subject: Re: [U-Boot] [PATCH 2/3] ARM: Tegra: USB: Add driver support for Tegra30/Tegra114
Dear Jim Lin,
[...]
This is a problem with the struct-based access indeed. I agree with Tom it'd be worth to at least try distilling the common part into header shared between those three CPUs.
OK. I will add this into next version of patch.
I did a quick hack for arch-tegra/usb.h (common defines) and arch-tegra114/usb.h (register struct plus some unique defines) that I'll send you as an example.
btw you're also adding some kernel-doc-alike annotations to functions, why don't you follow kerneldoc style altogether?
I don't understand what you meant here. Could you give me an example? Like what I did is wrong or not good. And what is correct or better one.
These kinds of annotations:
+/*
- Process a list of nodes, adding them to our list of SDMMC ports.
- @param blob fdt blob
- @param node_list list of nodes to process (any <=0 are ignored)
- @param count number of nodes to process
- @return 0 if ok, -1 on error
- */
See http://www.denx.de/wiki/U-Boot/CodingStyle at the bottom for the right style.
Note that the 'SDMMC ports' part s/b 'USB ports', or 'USB controllers'. Please change it.
Marek is asking why we have inconsistent function commenting in ehci-tegra.c - read the kernel.doc howto pointed to in the URL above, and make sure any function/struct/enum comments adhere to that style (/** to start, Return: instead of @return, etc.), so that one can run the kernel-doc scripts and extract info about our EHCI driver's functions, etc. This is something I'll look at doing in all the Tegra-specific drivers and source in a future patchset.
Tom
Best regards, Marek Vasut
-- nvpublic

On 04/29/2013 03:21 AM, Jim Lin wrote:
Tegra30 and Tegra114 are compatible except
- T30 takes 55 ms to finish Port Reset. T114 takes 50 ms.
Is that 55-vs-50 some aspect of the HW specification itself, or the overall result of multiple separate delays? I ask because the statement that one piece of HW differs from another only in a delay, especially where that delay is enormous in HW terms, seem very unusual.
diff --git a/arch/arm/include/asm/arch-tegra114/tegra.h b/arch/arm/include/asm/arch-tegra114/tegra.h
+#define TEGRA_USB1_BASE 0x7D000000
That shouldn't be needed; if some of the module base addresses come from DT, then they all should, or there's no point using DT.
diff --git a/arch/arm/include/asm/arch-tegra114/usb.h b/arch/arm/include/asm/arch-tegra114/usb.h
+#ifndef _TEGRA_USB_H_ +#define _TEGRA_USB_H_
+/* USB Controller (USBx_CONTROLLER_) regs */
There's an extra blank line there. The same problem exists elsewhere, and in the other copies of this file.
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) {
- mdelay(50);
- if (((u32) status_reg & TEGRA_USB_ADDR_MASK) != TEGRA_USB1_BASE)
- udelay(49990);
- if (is_T30_compatible) {
The code shouldn't test against a specific chip version, but rather against some property of the HW (like the length of the delay). That way, it will be scalable when we support 10 different Tegra versions and the mapping from version number to feature isn't easy to represent.
/*
* Tegra 114 takes 50 ms to assert Port Enable bit.
* We have to exit earlier. Otherwise ehci-hcd.c will clear
* our Port Enable bit.
*/
if (is_T114_compatible)
return;
/* Tegra 3 takes about 55 ms to assert Port Enable bit. */
udelay(5010);
return;
- }
This looks like an enormous hack. What is it doing? Why? Can't all 3 chips simply loop polling until some enable status bit is set?
- udelay(10);
- if (((u32)status_reg & TEGRA_USB_ADDR_MASK) != TEGRA_USB1_BASE) return;
This also should test against a feature, not the identity of the port. The DT properties nvidia,has-legacy-mode or nvidia,needs-double-reset might be relevant here?
@@ -171,7 +177,7 @@ static void set_host_mode(struct fdt_usb *config) * bail out in this case. */ if (config->dr_mode == DR_MODE_OTG &&
(readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS))
(readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS))
That's an unrelated whitespace change. Whitespace cleanup should be in a separate patch first, so it doesn't clutter functional changes.
@@ -232,45 +240,112 @@ static int init_utmi_usb_controller(struct fdt_usb *config) * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP * mux must be switched to actually use a_sess_vld threshold. */
- if (fdt_gpio_isvalid(&config->vbus_gpio)) {
- if (config->dr_mode == DR_MODE_OTG &&
clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,fdt_gpio_isvalid(&config->vbus_gpio))
VBUS_SENSE_CTL_MASK,
VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
- }
VBUS_SENSE_CTL_MASK,
VBUS_SENSE_CTL_A_SESS_VLD <<
VBUS_SENSE_CTL_SHIFT);
Partially a white-space change. There are many other ws-changes later that I didn't bother pointing out.
- timing = (u32 *)config->params;
- if (is_T30_compatible)
goto pll_T30_init;
...
- goto pll_init_done;
+pll_T30_init:
...
+pll_init_done:
Uggh. Use functions.
@@ -325,17 +409,37 @@ static int init_utmi_usb_controller(struct fdt_usb *config) /* Disable ICUSB FS/LS transceiver */ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
- /* Select UTMI parallel interface */
- clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
PTS_UTMI << PTS_SHIFT);
- clrbits_le32(&usbctlr->port_sc1, STS);
- if (!is_T30_compatible) {
/* Select UTMI parallel interface */
if (config->periph_id == PERIPH_ID_USBD) {
clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
PTS_UTMI << PTS1_SHIFT);
clrbits_le32(&usbctlr->port_sc1, STS1);
} else {
clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
PTS_UTMI << PTS_SHIFT);
clrbits_le32(&usbctlr->port_sc1, STS);
}
- }
This changes behaviour on Tegra20. While it may be correct, it has nothing to do with adding Tegra30/114 support, and hence should be a separate patch earlier in the series.
+int board_usb_init(const void *blob)
- if (!count)
goto skip_T20_process;
- err = process_nodes(blob, node_list, count);
- if (err) {
printf("%s: Error processing T20 compatible USB node(s)!\n",
__func__);
return err;
- }
+skip_T20_process:
Uggh. Instead of:
if (!count) goto skip; code; skip:
do:
if (count) { code; }
- count = fdtdec_find_aliases_for_id(blob, "usb",
COMPAT_NVIDIA_TEGRA114_USB, node_list, USB_PORTS_MAX);
- if (count)
is_T114_compatible = 1;
Don't use globals for that. Or, if you do, just return as soon as you've found a match, so it's impossible to end up with some Tegra20 and some Tegra30 controllers both enabled.

On Fri, 2013-05-03 at 03:29 +0800, Stephen Warren wrote:
On 04/29/2013 03:21 AM, Jim Lin wrote:
Tegra30 and Tegra114 are compatible except
- T30 takes 55 ms to finish Port Reset. T114 takes 50 ms.
Is that 55-vs-50 some aspect of the HW specification itself, or the overall result of multiple separate delays? I ask because the statement that one piece of HW differs from another only in a delay, especially where that delay is enormous in HW terms, seem very unusual.
50 ms comes from USB 2.0 specification for root port. 55 ms comes from T30 Technical Reference Manual. Overall result of multiple separate delays.
-- nvpublic

On 05/03/2013 04:53 AM, Jim Lin wrote:
On Fri, 2013-05-03 at 03:29 +0800, Stephen Warren wrote:
On 04/29/2013 03:21 AM, Jim Lin wrote:
Tegra30 and Tegra114 are compatible except
- T30 takes 55 ms to finish Port Reset. T114 takes 50 ms.
Is that 55-vs-50 some aspect of the HW specification itself, or the overall result of multiple separate delays? I ask because the statement that one piece of HW differs from another only in a delay, especially where that delay is enormous in HW terms, seem very unusual.
50 ms comes from USB 2.0 specification for root port. 55 ms comes from T30 Technical Reference Manual.
OK, I see this value is indeed in the TRM, so I guess the code is OK.
Overall result of multiple separate delays.
That doesn't seem true though; the TRM simply documents a single 55ms delay, not a set of delays that add up to 55ms.

Add USB EHCI, storage and network support.
Tested on Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
Signed-off-by: Jim Lin jilin@nvidia.com --- include/configs/cardhu.h | 14 ++++++++++++++ include/configs/dalmore.h | 14 ++++++++++++++ include/configs/tegra114-common.h | 3 +++ include/configs/tegra30-common.h | 3 +++ 4 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h index 6a99175..fd46083 100644 --- a/include/configs/cardhu.h +++ b/include/configs/cardhu.h @@ -70,6 +70,20 @@ #define CONFIG_CMD_SF #define CONFIG_SPI_FLASH_SIZE (4 << 20)
+/* USB Host support */ +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_TEGRA +#define CONFIG_USB_STORAGE +#define CONFIG_CMD_USB + +/* USB networking support */ +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_ASIX + +/* General networking support */ +#define CONFIG_CMD_NET +#define CONFIG_CMD_DHCP + #include "tegra-common-post.h"
#endif /* __CONFIG_H */ diff --git a/include/configs/dalmore.h b/include/configs/dalmore.h index 7b68f7c..2723843 100644 --- a/include/configs/dalmore.h +++ b/include/configs/dalmore.h @@ -75,6 +75,20 @@ #define CONFIG_CMD_SF #define CONFIG_SPI_FLASH_SIZE (4 << 20)
+/* USB Host support */ +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_TEGRA +#define CONFIG_USB_STORAGE +#define CONFIG_CMD_USB + +/* USB networking support */ +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_ASIX + +/* General networking support */ +#define CONFIG_CMD_NET +#define CONFIG_CMD_DHCP + #include "tegra-common-post.h"
#endif /* __CONFIG_H */ diff --git a/include/configs/tegra114-common.h b/include/configs/tegra114-common.h index 721b29c..44e98e5 100644 --- a/include/configs/tegra114-common.h +++ b/include/configs/tegra114-common.h @@ -77,4 +77,7 @@ /* Total I2C ports on Tegra114 */ #define TEGRA_I2C_NUM_CONTROLLERS 5
+/* For USB EHCI controller */ +#define CONFIG_EHCI_IS_TDI + #endif /* _TEGRA114_COMMON_H_ */ diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h index ed36e11..7ea36be 100644 --- a/include/configs/tegra30-common.h +++ b/include/configs/tegra30-common.h @@ -90,4 +90,7 @@ /* Total I2C ports on Tegra30 */ #define TEGRA_I2C_NUM_CONTROLLERS 5
+/* For USB EHCI controller */ +#define CONFIG_EHCI_IS_TDI + #endif /* _TEGRA30_COMMON_H_ */

On 04/29/2013 03:21 AM, Jim Lin wrote:
Add USB EHCI, storage and network support.
Tested on Tegra30 Cardhu, and Tegra114 Dalmore platforms. All works well.
What about updating include/configs/beaver.h too?

On 04/29/2013 03:21 AM, Jim Lin wrote:
Tegra114 USB EHCI is compatible with Tegra30 USB EHCI except:
- Port Reset - Tegra30 takes 55ms, Tegra114 takes 50 ms to finish.
- PLL parameters.
Jim Lin (3): ARM: Tegra: FDT: Add USB support for T20/T30/T114 ARM: Tegra: USB: Add driver support for Tegra30/Tegra114 Tegra: Config: Enable Tegra30/Tegra114 USB function
The series,
Tested-by: Stephen Warren swarren@nvidia.com
On both Cardhu (Tegra30) and Dalmore (Tegra114). :-) :-) Now, I can netboot with upstream U-Boot on all my boards.

On 05/03/2013 09:02 AM, Stephen Warren wrote:
On 04/29/2013 03:21 AM, Jim Lin wrote:
Tegra114 USB EHCI is compatible with Tegra30 USB EHCI except:
- Port Reset - Tegra30 takes 55ms, Tegra114 takes 50 ms to finish.
- PLL parameters.
Jim Lin (3): ARM: Tegra: FDT: Add USB support for T20/T30/T114 ARM: Tegra: USB: Add driver support for Tegra30/Tegra114 Tegra: Config: Enable Tegra30/Tegra114 USB function
The series,
Tested-by: Stephen Warren swarren@nvidia.com
On both Cardhu (Tegra30) and Dalmore (Tegra114). :-) :-) Now, I can netboot with upstream U-Boot on all my boards.
I just noticed one problem with this patch series. If I run the following commands with Cardhu in its dock, and a USB Ethernet dongle attached to the dock:
usb start 0 dhcp ${scriptaddr} boot.scr.uimg
... then everything works as expected; the file is downloaded.
However, if I run those same commands with Cardhu either undocked, or docked but with no USB Ethernet dongle plugged into the dock, then the dhcp command hangs the system hard; CTRL-C won't interrupt it for example.
Can you please fix this?
participants (7)
-
Jim Lin
-
Marek Vasut
-
Stephen Warren
-
Tom Rini
-
Tom Warren
-
Tom Warren
-
Venu Byravarasu