blob: 7c73eb66b6056bc4d879c64fcf004b990204a7e5 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass08d6ec22012-02-27 10:52:49 +00002/*
Lucas Stach26c32162013-02-07 07:16:29 +00003 * Copyright (c) 2011 The Chromium OS Authors.
Tom Warrenab0cc6b2015-03-04 16:36:00 -07004 * Copyright (c) 2009-2015 NVIDIA Corporation
Lucas Stach26c32162013-02-07 07:16:29 +00005 * Copyright (c) 2013 Lucas Stach
Simon Glass08d6ec22012-02-27 10:52:49 +00006 */
7
Simon Glass9c574772015-03-25 12:22:48 -06008#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Simon Glassdbd79542020-05-10 11:40:11 -060010#include <linux/delay.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090011#include <linux/errno.h>
Lucas Stach26c32162013-02-07 07:16:29 +000012#include <asm/io.h>
13#include <asm-generic/gpio.h>
14#include <asm/arch/clock.h>
15#include <asm/arch-tegra/usb.h>
Jim Lin2fefb8b2013-06-21 19:05:47 +080016#include <asm/arch-tegra/clk_rst.h>
Simon Glass08d6ec22012-02-27 10:52:49 +000017#include <usb.h>
Lucas Stach26c32162013-02-07 07:16:29 +000018#include <usb/ulpi.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090019#include <linux/libfdt.h>
Simon Glass08d6ec22012-02-27 10:52:49 +000020
21#include "ehci.h"
Simon Glass08d6ec22012-02-27 10:52:49 +000022
Jim Lin2fefb8b2013-06-21 19:05:47 +080023#define USB1_ADDR_MASK 0xFFFF0000
24
25#define HOSTPC1_DEVLC 0x84
26#define HOSTPC1_PSPD(x) (((x) >> 25) & 0x3)
27
Lucas Stach26c32162013-02-07 07:16:29 +000028#ifdef CONFIG_USB_ULPI
29 #ifndef CONFIG_USB_ULPI_VIEWPORT
30 #error "To use CONFIG_USB_ULPI on Tegra Boards you have to also \
31 define CONFIG_USB_ULPI_VIEWPORT"
32 #endif
33#endif
34
Lucas Stach26c32162013-02-07 07:16:29 +000035/* Parameters we need for USB */
36enum {
37 PARAM_DIVN, /* PLL FEEDBACK DIVIDer */
38 PARAM_DIVM, /* PLL INPUT DIVIDER */
39 PARAM_DIVP, /* POST DIVIDER (2^N) */
40 PARAM_CPCON, /* BASE PLLC CHARGE Pump setup ctrl */
41 PARAM_LFCON, /* BASE PLLC LOOP FILter setup ctrl */
42 PARAM_ENABLE_DELAY_COUNT, /* PLL-U Enable Delay Count */
43 PARAM_STABLE_COUNT, /* PLL-U STABLE count */
44 PARAM_ACTIVE_DELAY_COUNT, /* PLL-U Active delay count */
45 PARAM_XTAL_FREQ_COUNT, /* PLL-U XTAL frequency count */
46 PARAM_DEBOUNCE_A_TIME, /* 10MS DELAY for BIAS_DEBOUNCE_A */
47 PARAM_BIAS_TIME, /* 20US DELAY AFter bias cell op */
48
49 PARAM_COUNT
50};
51
52/* Possible port types (dual role mode) */
53enum dr_mode {
54 DR_MODE_NONE = 0,
55 DR_MODE_HOST, /* supports host operation */
56 DR_MODE_DEVICE, /* supports device operation */
57 DR_MODE_OTG, /* supports both */
58};
59
Simon Glass92a419e2015-03-25 12:22:20 -060060enum usb_ctlr_type {
61 USB_CTLR_T20,
62 USB_CTLR_T30,
63 USB_CTLR_T114,
Tom Warrenab0cc6b2015-03-04 16:36:00 -070064 USB_CTLR_T210,
Simon Glass92a419e2015-03-25 12:22:20 -060065
66 USB_CTRL_COUNT,
67};
68
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +030069struct tegra_utmip_config {
70 u32 hssync_start_delay;
71 u32 elastic_limit;
72 u32 idle_wait_delay;
73 u32 term_range_adj;
74 bool xcvr_setup_use_fuses;
75 u32 xcvr_setup;
76 u32 xcvr_lsfslew;
77 u32 xcvr_lsrslew;
78 u32 xcvr_hsslew;
79 u32 hssquelch_level;
80 u32 hsdiscon_level;
81};
82
Lucas Stach26c32162013-02-07 07:16:29 +000083/* Information about a USB port */
84struct fdt_usb {
Simon Glass9c574772015-03-25 12:22:48 -060085 struct ehci_ctrl ehci;
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +030086 struct tegra_utmip_config utmip_config;
Lucas Stach26c32162013-02-07 07:16:29 +000087 struct usb_ctlr *reg; /* address of registers in physical memory */
88 unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */
89 unsigned ulpi:1; /* 1 if port has external ULPI transceiver */
90 unsigned enabled:1; /* 1 to enable, 0 to disable */
91 unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
Simon Glass92a419e2015-03-25 12:22:20 -060092 enum usb_ctlr_type type;
Stephen Warren8b263f92014-04-30 15:09:57 -060093 enum usb_init_type init_type;
Lucas Stach26c32162013-02-07 07:16:29 +000094 enum dr_mode dr_mode; /* dual role mode */
95 enum periph_id periph_id;/* peripheral id */
Simon Glassfec09c52015-01-05 20:05:39 -070096 struct gpio_desc vbus_gpio; /* GPIO for vbus enable */
97 struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
Lucas Stach26c32162013-02-07 07:16:29 +000098};
99
Lucas Stach26c32162013-02-07 07:16:29 +0000100/*
101 * This table has USB timing parameters for each Oscillator frequency we
102 * support. There are four sets of values:
103 *
104 * 1. PLLU configuration information (reference clock is osc/clk_m and
105 * PLLU-FOs are fixed at 12MHz/60MHz/480MHz).
106 *
107 * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz
108 * ----------------------------------------------------------------------
109 * DIVN 960 (0x3c0) 200 (0c8) 960 (3c0h) 960 (3c0)
110 * DIVM 13 (0d) 4 (04) 12 (0c) 26 (1a)
111 * Filter frequency (MHz) 1 4.8 6 2
112 * CPCON 1100b 0011b 1100b 1100b
113 * LFCON0 0 0 0 0
114 *
115 * 2. PLL CONFIGURATION & PARAMETERS for different clock generators:
116 *
117 * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz
118 * ---------------------------------------------------------------------------
119 * PLLU_ENABLE_DLY_COUNT 02 (0x02) 03 (03) 02 (02) 04 (04)
120 * PLLU_STABLE_COUNT 51 (33) 75 (4B) 47 (2F) 102 (66)
121 * PLL_ACTIVE_DLY_COUNT 05 (05) 06 (06) 04 (04) 09 (09)
122 * XTAL_FREQ_COUNT 127 (7F) 187 (BB) 118 (76) 254 (FE)
123 *
124 * 3. Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and
125 * SessEnd. Each of these signals have their own debouncer and for each of
126 * those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or
127 * BIAS_DEBOUNCE_B).
128 *
129 * The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows:
130 * 0xffff -> No debouncing at all
131 * <n> ms = <n> *1000 / (1/19.2MHz) / 4
132 *
133 * So to program a 1 ms debounce for BIAS_DEBOUNCE_A, we have:
134 * BIAS_DEBOUNCE_A[15:0] = 1000 * 19.2 / 4 = 4800 = 0x12c0
135 *
136 * We need to use only DebounceA for BOOTROM. We don't need the DebounceB
137 * values, so we can keep those to default.
138 *
139 * 4. The 20 microsecond delay after bias cell operation.
140 */
Jim Lin2fefb8b2013-06-21 19:05:47 +0800141static const unsigned T20_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
Lucas Stach26c32162013-02-07 07:16:29 +0000142 /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
143 { 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200144 { 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 },
145 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
146 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Lucas Stach26c32162013-02-07 07:16:29 +0000147 { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200148 { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 },
149 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
150 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
151 { 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 },
Lucas Stach26c32162013-02-07 07:16:29 +0000152 { 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 },
Tom Warren27bce712015-06-22 13:03:44 -0700153 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200154 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
155 { 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }
Lucas Stach26c32162013-02-07 07:16:29 +0000156};
157
Jim Lin2fefb8b2013-06-21 19:05:47 +0800158static const unsigned T30_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
159 /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
160 { 0x3C0, 0x0D, 0x00, 0xC, 1, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 5 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200161 { 0x3C0, 0x0D, 0x00, 0xC, 1, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 5 },
162 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
163 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Jim Lin2fefb8b2013-06-21 19:05:47 +0800164 { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200165 { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 },
166 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
167 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Jim Lin2fefb8b2013-06-21 19:05:47 +0800168 { 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200169 { 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
170 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Tom Warren27bce712015-06-22 13:03:44 -0700171 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200172 { 0x3C0, 0x1A, 0x00, 0xC, 1, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }
Jim Lin2fefb8b2013-06-21 19:05:47 +0800173};
174
175static const unsigned T114_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
176 /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
177 { 0x3C0, 0x0D, 0x00, 0xC, 2, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 6 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200178 { 0x3C0, 0x0D, 0x00, 0xC, 2, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 6 },
179 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
180 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
181 { 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 },
Jim Lin2fefb8b2013-06-21 19:05:47 +0800182 { 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200183 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
184 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
185 { 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
Jim Lin2fefb8b2013-06-21 19:05:47 +0800186 { 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200187 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Tom Warren27bce712015-06-22 13:03:44 -0700188 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200189 { 0x3C0, 0x1A, 0x00, 0xC, 2, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 11 }
Jim Lin2fefb8b2013-06-21 19:05:47 +0800190};
191
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700192/* NOTE: 13/26MHz settings are N/A for T210, so dupe 12MHz settings for now */
193static const unsigned T210_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
194 /* DivN, DivM, DivP, KCP, KVCO, Delays Debounce, Bias */
Tom Warren27bce712015-06-22 13:03:44 -0700195 { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 32500, 5 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200196 { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 32500, 5 },
197 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
198 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700199 { 0x019, 0x01, 0x01, 0x0, 0, 0x03, 0x4B, 0x0C, 0xBB, 48000, 8 },
Tom Warren27bce712015-06-22 13:03:44 -0700200 { 0x019, 0x02, 0x01, 0x0, 0, 0x05, 0x96, 0x18, 0x177, 96000, 15 },
Svyatoslav Ryhel7f4ab332023-02-01 10:53:01 +0200201 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
202 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
203 { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 },
204 { 0x028, 0x04, 0x01, 0x0, 0, 0x04, 0x66, 0x09, 0xFE, 120000, 20 },
205 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
206 { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
207 { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 65000, 5 }
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700208};
209
Jim Lin2fefb8b2013-06-21 19:05:47 +0800210struct fdt_usb_controller {
Jim Lin2fefb8b2013-06-21 19:05:47 +0800211 /* flag to determine whether controller supports hostpc register */
212 u32 has_hostpc:1;
213 const unsigned *pll_parameter;
214};
215
Simon Glass92a419e2015-03-25 12:22:20 -0600216static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
Jim Lin2fefb8b2013-06-21 19:05:47 +0800217 {
Jim Lin2fefb8b2013-06-21 19:05:47 +0800218 .has_hostpc = 0,
219 .pll_parameter = (const unsigned *)T20_usb_pll,
220 },
221 {
Jim Lin2fefb8b2013-06-21 19:05:47 +0800222 .has_hostpc = 1,
223 .pll_parameter = (const unsigned *)T30_usb_pll,
224 },
225 {
Jim Lin2fefb8b2013-06-21 19:05:47 +0800226 .has_hostpc = 1,
227 .pll_parameter = (const unsigned *)T114_usb_pll,
228 },
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700229 {
230 .has_hostpc = 1,
231 .pll_parameter = (const unsigned *)T210_usb_pll,
232 },
Jim Lin2fefb8b2013-06-21 19:05:47 +0800233};
234
Jim Lin5a057e32012-06-24 20:40:57 +0000235/*
236 * A known hardware issue where Connect Status Change bit of PORTSC register
237 * of USB1 controller will be set after Port Reset.
238 * We have to clear it in order for later device enumeration to proceed.
Jim Lin5a057e32012-06-24 20:40:57 +0000239 */
Simon Glassdc9f3ed2015-03-25 12:22:27 -0600240static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
241 uint32_t *status_reg, uint32_t *reg)
Jim Lin5a057e32012-06-24 20:40:57 +0000242{
Simon Glass66a79f32015-03-25 12:22:22 -0600243 struct fdt_usb *config = ctrl->priv;
244 struct fdt_usb_controller *controller;
245
246 controller = &fdt_usb_controllers[config->type];
Jim Lin5a057e32012-06-24 20:40:57 +0000247 mdelay(50);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800248 /* This is to avoid PORT_ENABLE bit to be cleared in "ehci-hcd.c". */
249 if (controller->has_hostpc)
250 *reg |= EHCI_PS_PE;
251
Simon Glass57c76c32015-03-25 12:22:45 -0600252 if (!config->has_legacy_mode)
Jim Lin5a057e32012-06-24 20:40:57 +0000253 return;
254 /* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
255 if (ehci_readl(status_reg) & EHCI_PS_CSC)
256 *reg |= EHCI_PS_CSC;
257}
Simon Glass08d6ec22012-02-27 10:52:49 +0000258
Simon Glassdc9f3ed2015-03-25 12:22:27 -0600259static void tegra_ehci_set_usbmode(struct ehci_ctrl *ctrl)
Jim Lin2fefb8b2013-06-21 19:05:47 +0800260{
Simon Glass2d387ab2015-03-25 12:22:23 -0600261 struct fdt_usb *config = ctrl->priv;
Jim Lin2fefb8b2013-06-21 19:05:47 +0800262 struct usb_ctlr *usbctlr;
263 uint32_t tmp;
264
Jim Lin2fefb8b2013-06-21 19:05:47 +0800265 usbctlr = config->reg;
266
267 tmp = ehci_readl(&usbctlr->usb_mode);
268 tmp |= USBMODE_CM_HC;
269 ehci_writel(&usbctlr->usb_mode, tmp);
270}
271
Simon Glassdc9f3ed2015-03-25 12:22:27 -0600272static int tegra_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
Jim Lin2fefb8b2013-06-21 19:05:47 +0800273{
Simon Glass66a79f32015-03-25 12:22:22 -0600274 struct fdt_usb *config = ctrl->priv;
275 struct fdt_usb_controller *controller;
Jim Lin2fefb8b2013-06-21 19:05:47 +0800276 uint32_t tmp;
277 uint32_t *reg_ptr;
278
Simon Glass66a79f32015-03-25 12:22:22 -0600279 controller = &fdt_usb_controllers[config->type];
Jim Lin2fefb8b2013-06-21 19:05:47 +0800280 if (controller->has_hostpc) {
Simon Glassc78c7652015-03-25 12:22:18 -0600281 reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd +
282 HOSTPC1_DEVLC);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800283 tmp = ehci_readl(reg_ptr);
284 return HOSTPC1_PSPD(tmp);
285 } else
286 return PORTSC_PSPD(reg);
287}
288
Stephen Warren8b263f92014-04-30 15:09:57 -0600289/* Set up VBUS for host/device mode */
290static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init)
Lucas Stach26c32162013-02-07 07:16:29 +0000291{
292 /*
Stephen Warren8b263f92014-04-30 15:09:57 -0600293 * If we are an OTG port initializing in host mode,
294 * check if remote host is driving VBus and bail out in this case.
Lucas Stach26c32162013-02-07 07:16:29 +0000295 */
Stephen Warren8b263f92014-04-30 15:09:57 -0600296 if (init == USB_INIT_HOST &&
297 config->dr_mode == DR_MODE_OTG &&
298 (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) {
299 printf("tegrausb: VBUS input active; not enabling as host\n");
Lucas Stach26c32162013-02-07 07:16:29 +0000300 return;
Stephen Warren8b263f92014-04-30 15:09:57 -0600301 }
Lucas Stach26c32162013-02-07 07:16:29 +0000302
Simon Glassfec09c52015-01-05 20:05:39 -0700303 if (dm_gpio_is_valid(&config->vbus_gpio)) {
Stephen Warren8b263f92014-04-30 15:09:57 -0600304 int vbus_value;
305
Simon Glassfec09c52015-01-05 20:05:39 -0700306 vbus_value = (init == USB_INIT_HOST);
307 dm_gpio_set_value(&config->vbus_gpio, vbus_value);
Stephen Warren8b263f92014-04-30 15:09:57 -0600308
Simon Glassfec09c52015-01-05 20:05:39 -0700309 debug("set_up_vbus: GPIO %d %d\n",
310 gpio_get_number(&config->vbus_gpio), vbus_value);
Lucas Stach26c32162013-02-07 07:16:29 +0000311 }
312}
313
Simon Glass6f7d3422015-03-25 12:22:46 -0600314static void usbf_reset_controller(struct fdt_usb *config,
315 struct usb_ctlr *usbctlr)
Lucas Stach26c32162013-02-07 07:16:29 +0000316{
317 /* Reset the USB controller with 2us delay */
318 reset_periph(config->periph_id, 2);
319
320 /*
321 * Set USB1_NO_LEGACY_MODE to 1, Registers are accessible under
322 * base address
323 */
324 if (config->has_legacy_mode)
325 setbits_le32(&usbctlr->usb1_legacy_ctrl, USB1_NO_LEGACY_MODE);
326
327 /* Put UTMIP1/3 in reset */
328 setbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);
329
330 /* Enable the UTMIP PHY */
331 if (config->utmi)
332 setbits_le32(&usbctlr->susp_ctrl, UTMIP_PHY_ENB);
333}
334
Simon Glass92a419e2015-03-25 12:22:20 -0600335static const unsigned *get_pll_timing(struct fdt_usb_controller *controller)
Jim Lin2fefb8b2013-06-21 19:05:47 +0800336{
337 const unsigned *timing;
338
339 timing = controller->pll_parameter +
340 clock_get_osc_freq() * PARAM_COUNT;
341
342 return timing;
343}
344
Stephen Warren600246c2014-04-30 15:09:56 -0600345/* select the PHY to use with a USB controller */
Stephen Warren8b263f92014-04-30 15:09:57 -0600346static void init_phy_mux(struct fdt_usb *config, uint pts,
347 enum usb_init_type init)
Stephen Warren600246c2014-04-30 15:09:56 -0600348{
349 struct usb_ctlr *usbctlr = config->reg;
350
351#if defined(CONFIG_TEGRA20)
352 if (config->periph_id == PERIPH_ID_USBD) {
353 clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
Marcel Ziswilerafc106e2014-10-04 01:46:10 +0200354 pts << PTS1_SHIFT);
Stephen Warren600246c2014-04-30 15:09:56 -0600355 clrbits_le32(&usbctlr->port_sc1, STS1);
356 } else {
357 clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
Marcel Ziswilerafc106e2014-10-04 01:46:10 +0200358 pts << PTS_SHIFT);
Stephen Warren600246c2014-04-30 15:09:56 -0600359 clrbits_le32(&usbctlr->port_sc1, STS);
360 }
361#else
Stephen Warren8b263f92014-04-30 15:09:57 -0600362 /* Set to Host mode (if applicable) after Controller Reset was done */
Stephen Warren600246c2014-04-30 15:09:56 -0600363 clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC,
Stephen Warren8b263f92014-04-30 15:09:57 -0600364 (init == USB_INIT_HOST) ? USBMODE_CM_HC : 0);
365 /*
366 * Select PHY interface after setting host mode.
367 * For device mode, the ordering requirement is not an issue, since
368 * only the first USB controller supports device mode, and that USB
369 * controller can only talk to a UTMI PHY, so the PHY selection is
370 * already made at reset time, so this write is a no-op.
371 */
Stephen Warren600246c2014-04-30 15:09:56 -0600372 clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK,
373 pts << PTS_SHIFT);
374 clrbits_le32(&usbctlr->hostpc1_devlc, STS);
375#endif
376}
377
Lucas Stach26c32162013-02-07 07:16:29 +0000378/* set up the UTMI USB controller with the parameters provided */
Stephen Warren8b263f92014-04-30 15:09:57 -0600379static int init_utmi_usb_controller(struct fdt_usb *config,
380 enum usb_init_type init)
Lucas Stach26c32162013-02-07 07:16:29 +0000381{
Simon Glass92a419e2015-03-25 12:22:20 -0600382 struct fdt_usb_controller *controller;
Stephen Warren8b263f92014-04-30 15:09:57 -0600383 u32 b_sess_valid_mask, val;
Lucas Stach26c32162013-02-07 07:16:29 +0000384 int loop_count;
385 const unsigned *timing;
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300386 struct tegra_utmip_config *utmip_config = &config->utmip_config;
Lucas Stach26c32162013-02-07 07:16:29 +0000387 struct usb_ctlr *usbctlr = config->reg;
Jim Lin2fefb8b2013-06-21 19:05:47 +0800388 struct clk_rst_ctlr *clkrst;
389 struct usb_ctlr *usb1ctlr;
Lucas Stach26c32162013-02-07 07:16:29 +0000390
391 clock_enable(config->periph_id);
392
393 /* Reset the usb controller */
394 usbf_reset_controller(config, usbctlr);
395
396 /* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */
397 clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);
398
399 /* Follow the crystal clock disable by >100ns delay */
400 udelay(1);
401
Stephen Warren8b263f92014-04-30 15:09:57 -0600402 b_sess_valid_mask = (VBUS_B_SESS_VLD_SW_VALUE | VBUS_B_SESS_VLD_SW_EN);
403 clrsetbits_le32(&usbctlr->phy_vbus_sensors, b_sess_valid_mask,
404 (init == USB_INIT_DEVICE) ? b_sess_valid_mask : 0);
405
Lucas Stach26c32162013-02-07 07:16:29 +0000406 /*
407 * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP
408 * mux must be switched to actually use a_sess_vld threshold.
409 */
Jim Lin2fefb8b2013-06-21 19:05:47 +0800410 if (config->dr_mode == DR_MODE_OTG &&
Simon Glassfec09c52015-01-05 20:05:39 -0700411 dm_gpio_is_valid(&config->vbus_gpio))
Lucas Stach26c32162013-02-07 07:16:29 +0000412 clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
413 VBUS_SENSE_CTL_MASK,
414 VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
Lucas Stach26c32162013-02-07 07:16:29 +0000415
Simon Glass92a419e2015-03-25 12:22:20 -0600416 controller = &fdt_usb_controllers[config->type];
417 debug("controller=%p, type=%d\n", controller, config->type);
418
Lucas Stach26c32162013-02-07 07:16:29 +0000419 /*
420 * PLL Delay CONFIGURATION settings. The following parameters control
421 * the bring up of the plls.
422 */
Simon Glass92a419e2015-03-25 12:22:20 -0600423 timing = get_pll_timing(controller);
Lucas Stach26c32162013-02-07 07:16:29 +0000424
Jim Lin2fefb8b2013-06-21 19:05:47 +0800425 if (!controller->has_hostpc) {
426 val = readl(&usbctlr->utmip_misc_cfg1);
427 clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
428 timing[PARAM_STABLE_COUNT] <<
429 UTMIP_PLLU_STABLE_COUNT_SHIFT);
430 clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
431 timing[PARAM_ACTIVE_DELAY_COUNT] <<
432 UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
433 writel(val, &usbctlr->utmip_misc_cfg1);
Lucas Stach26c32162013-02-07 07:16:29 +0000434
Jim Lin2fefb8b2013-06-21 19:05:47 +0800435 /* Set PLL enable delay count and crystal frequency count */
436 val = readl(&usbctlr->utmip_pll_cfg1);
437 clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
438 timing[PARAM_ENABLE_DELAY_COUNT] <<
439 UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
440 clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
441 timing[PARAM_XTAL_FREQ_COUNT] <<
442 UTMIP_XTAL_FREQ_COUNT_SHIFT);
443 writel(val, &usbctlr->utmip_pll_cfg1);
444 } else {
445 clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
446
447 val = readl(&clkrst->crc_utmip_pll_cfg2);
448 clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
449 timing[PARAM_STABLE_COUNT] <<
450 UTMIP_PLLU_STABLE_COUNT_SHIFT);
451 clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
452 timing[PARAM_ACTIVE_DELAY_COUNT] <<
453 UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
454 writel(val, &clkrst->crc_utmip_pll_cfg2);
455
456 /* Set PLL enable delay count and crystal frequency count */
457 val = readl(&clkrst->crc_utmip_pll_cfg1);
458 clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
459 timing[PARAM_ENABLE_DELAY_COUNT] <<
460 UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
461 clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
462 timing[PARAM_XTAL_FREQ_COUNT] <<
463 UTMIP_XTAL_FREQ_COUNT_SHIFT);
464 writel(val, &clkrst->crc_utmip_pll_cfg1);
465
466 /* Disable Power Down state for PLL */
467 clrbits_le32(&clkrst->crc_utmip_pll_cfg1,
468 PLLU_POWERDOWN | PLL_ENABLE_POWERDOWN |
469 PLL_ACTIVE_POWERDOWN);
470
471 /* Recommended PHY settings for EYE diagram */
472 val = readl(&usbctlr->utmip_xcvr_cfg0);
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300473
474 if (!utmip_config->xcvr_setup_use_fuses) {
475 clrsetbits_le32(&val, UTMIP_XCVR_SETUP(~0),
476 UTMIP_XCVR_SETUP(utmip_config->xcvr_setup));
477 clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MSB(~0),
478 UTMIP_XCVR_SETUP_MSB(utmip_config->xcvr_setup));
479 }
480
481 clrsetbits_le32(&val, UTMIP_XCVR_LSFSLEW(~0),
482 UTMIP_XCVR_LSFSLEW(utmip_config->xcvr_lsfslew));
483 clrsetbits_le32(&val, UTMIP_XCVR_LSRSLEW(~0),
484 UTMIP_XCVR_LSRSLEW(utmip_config->xcvr_lsrslew));
485
486 clrsetbits_le32(&val, UTMIP_XCVR_HSSLEW(~0),
487 UTMIP_XCVR_HSSLEW(utmip_config->xcvr_hsslew));
488 clrsetbits_le32(&val, UTMIP_XCVR_HSSLEW_MSB(~0),
489 UTMIP_XCVR_HSSLEW_MSB(utmip_config->xcvr_hsslew));
Jim Lin2fefb8b2013-06-21 19:05:47 +0800490 writel(val, &usbctlr->utmip_xcvr_cfg0);
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300491
Jim Lin2fefb8b2013-06-21 19:05:47 +0800492 clrsetbits_le32(&usbctlr->utmip_xcvr_cfg1,
493 UTMIP_XCVR_TERM_RANGE_ADJ_MASK,
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300494 utmip_config->term_range_adj <<
495 UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800496
497 /* Some registers can be controlled from USB1 only. */
498 if (config->periph_id != PERIPH_ID_USBD) {
499 clock_enable(PERIPH_ID_USBD);
500 /* Disable Reset if in Reset state */
501 reset_set_enable(PERIPH_ID_USBD, 0);
502 }
503 usb1ctlr = (struct usb_ctlr *)
Thierry Reding4375b442015-03-20 12:41:27 +0100504 ((unsigned long)config->reg & USB1_ADDR_MASK);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800505 val = readl(&usb1ctlr->utmip_bias_cfg0);
506 setbits_le32(&val, UTMIP_HSDISCON_LEVEL_MSB);
507 clrsetbits_le32(&val, UTMIP_HSDISCON_LEVEL_MASK,
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300508 utmip_config->hsdiscon_level <<
509 UTMIP_HSDISCON_LEVEL_SHIFT);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800510 clrsetbits_le32(&val, UTMIP_HSSQUELCH_LEVEL_MASK,
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300511 utmip_config->hssquelch_level <<
512 UTMIP_HSSQUELCH_LEVEL_SHIFT);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800513 writel(val, &usb1ctlr->utmip_bias_cfg0);
514
515 /* Miscellaneous setting mentioned in Programming Guide */
516 clrbits_le32(&usbctlr->utmip_misc_cfg0,
517 UTMIP_SUSPEND_EXIT_ON_EDGE);
518 }
Lucas Stach26c32162013-02-07 07:16:29 +0000519
520 /* Setting the tracking length time */
521 clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
522 UTMIP_BIAS_PDTRK_COUNT_MASK,
523 timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT);
524
525 /* Program debounce time for VBUS to become valid */
526 clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
527 UTMIP_DEBOUNCE_CFG0_MASK,
528 timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT);
529
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700530 if (timing[PARAM_DEBOUNCE_A_TIME] > 0xFFFF) {
531 clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
532 UTMIP_DEBOUNCE_CFG0_MASK,
533 (timing[PARAM_DEBOUNCE_A_TIME] >> 1)
534 << UTMIP_DEBOUNCE_CFG0_SHIFT);
535 clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
536 UTMIP_BIAS_DEBOUNCE_TIMESCALE_MASK,
537 1 << UTMIP_BIAS_DEBOUNCE_TIMESCALE_SHIFT);
538 }
539
Lucas Stach26c32162013-02-07 07:16:29 +0000540 setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);
541
542 /* Disable battery charge enabling bit */
543 setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG);
544
545 clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE);
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300546
547 if (utmip_config->xcvr_setup_use_fuses)
548 setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL);
549 else
550 clrbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL);
Lucas Stach26c32162013-02-07 07:16:29 +0000551
552 /*
553 * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT
554 * Setting these fields, together with default values of the
555 * other fields, results in programming the registers below as
556 * follows:
557 * UTMIP_HSRX_CFG0 = 0x9168c000
558 * UTMIP_HSRX_CFG1 = 0x13
559 */
560
561 /* Set PLL enable delay count and Crystal frequency count */
562 val = readl(&usbctlr->utmip_hsrx_cfg0);
563 clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK,
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300564 utmip_config->idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT);
Lucas Stach26c32162013-02-07 07:16:29 +0000565 clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK,
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300566 utmip_config->elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT);
Lucas Stach26c32162013-02-07 07:16:29 +0000567 writel(val, &usbctlr->utmip_hsrx_cfg0);
568
569 /* Configure the UTMIP_HS_SYNC_START_DLY */
570 clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1,
571 UTMIP_HS_SYNC_START_DLY_MASK,
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300572 utmip_config->hssync_start_delay <<
573 UTMIP_HS_SYNC_START_DLY_SHIFT);
Lucas Stach26c32162013-02-07 07:16:29 +0000574
575 /* Preceed the crystal clock disable by >100ns delay. */
576 udelay(1);
577
578 /* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */
579 setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);
580
Jim Lin2fefb8b2013-06-21 19:05:47 +0800581 if (controller->has_hostpc) {
582 if (config->periph_id == PERIPH_ID_USBD)
583 clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
584 UTMIP_FORCE_PD_SAMP_A_POWERDOWN);
Stefan Agnerafc492b2014-03-02 19:46:48 +0100585 if (config->periph_id == PERIPH_ID_USB2)
586 clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
587 UTMIP_FORCE_PD_SAMP_B_POWERDOWN);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800588 if (config->periph_id == PERIPH_ID_USB3)
589 clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
590 UTMIP_FORCE_PD_SAMP_C_POWERDOWN);
591 }
Lucas Stach26c32162013-02-07 07:16:29 +0000592 /* Finished the per-controller init. */
593
594 /* De-assert UTMIP_RESET to bring out of reset. */
595 clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);
596
597 /* Wait for the phy clock to become valid in 100 ms */
598 for (loop_count = 100000; loop_count != 0; loop_count--) {
599 if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
600 break;
601 udelay(1);
602 }
603 if (!loop_count)
Simon Glass6f7d3422015-03-25 12:22:46 -0600604 return -ETIMEDOUT;
Lucas Stach26c32162013-02-07 07:16:29 +0000605
606 /* Disable ICUSB FS/LS transceiver */
607 clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
608
609 /* Select UTMI parallel interface */
Stephen Warren8b263f92014-04-30 15:09:57 -0600610 init_phy_mux(config, PTS_UTMI, init);
Lucas Stach26c32162013-02-07 07:16:29 +0000611
612 /* Deassert power down state */
613 clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN |
614 UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN);
615 clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN |
616 UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN);
617
Jim Lin2fefb8b2013-06-21 19:05:47 +0800618 if (controller->has_hostpc) {
619 /*
620 * BIAS Pad Power Down is common among all 3 USB
621 * controllers and can be controlled from USB1 only.
622 */
623 usb1ctlr = (struct usb_ctlr *)
Thierry Reding4375b442015-03-20 12:41:27 +0100624 ((unsigned long)config->reg & USB1_ADDR_MASK);
Jim Lin2fefb8b2013-06-21 19:05:47 +0800625 clrbits_le32(&usb1ctlr->utmip_bias_cfg0, UTMIP_BIASPD);
626 udelay(25);
627 clrbits_le32(&usb1ctlr->utmip_bias_cfg1,
628 UTMIP_FORCE_PDTRK_POWERDOWN);
629 }
Lucas Stach26c32162013-02-07 07:16:29 +0000630 return 0;
631}
632
633#ifdef CONFIG_USB_ULPI
634/* if board file does not set a ULPI reference frequency we default to 24MHz */
Tom Rini364d0022023-01-10 11:19:45 -0500635#ifndef CFG_ULPI_REF_CLK
636#define CFG_ULPI_REF_CLK 24000000
Lucas Stach26c32162013-02-07 07:16:29 +0000637#endif
638
639/* set up the ULPI USB controller with the parameters provided */
Stephen Warren8b263f92014-04-30 15:09:57 -0600640static int init_ulpi_usb_controller(struct fdt_usb *config,
641 enum usb_init_type init)
Lucas Stach26c32162013-02-07 07:16:29 +0000642{
643 u32 val;
644 int loop_count;
645 struct ulpi_viewport ulpi_vp;
646 struct usb_ctlr *usbctlr = config->reg;
Simon Glass6f7d3422015-03-25 12:22:46 -0600647 int ret;
Lucas Stach26c32162013-02-07 07:16:29 +0000648
649 /* set up ULPI reference clock on pllp_out4 */
650 clock_enable(PERIPH_ID_DEV2_OUT);
Tom Rini364d0022023-01-10 11:19:45 -0500651 clock_set_pllout(CLOCK_ID_PERIPH, PLL_OUT4, CFG_ULPI_REF_CLK);
Lucas Stach26c32162013-02-07 07:16:29 +0000652
653 /* reset ULPI phy */
Simon Glassfec09c52015-01-05 20:05:39 -0700654 if (dm_gpio_is_valid(&config->phy_reset_gpio)) {
Stephen Warren7c259752016-09-15 12:19:37 -0600655 /*
656 * This GPIO is typically active-low, and marked as such in
657 * device tree. dm_gpio_set_value() takes this into account
658 * and inverts the value we pass here if required. In other
659 * words, this first call logically asserts the reset signal,
660 * which typically results in driving the physical GPIO low,
661 * and the second call logically de-asserts the reset signal,
662 * which typically results in driver the GPIO high.
663 */
Simon Glassfec09c52015-01-05 20:05:39 -0700664 dm_gpio_set_value(&config->phy_reset_gpio, 1);
Stephen Warren7c259752016-09-15 12:19:37 -0600665 mdelay(5);
666 dm_gpio_set_value(&config->phy_reset_gpio, 0);
Lucas Stach26c32162013-02-07 07:16:29 +0000667 }
668
669 /* Reset the usb controller */
670 clock_enable(config->periph_id);
671 usbf_reset_controller(config, usbctlr);
672
673 /* enable pinmux bypass */
674 setbits_le32(&usbctlr->ulpi_timing_ctrl_0,
675 ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);
676
677 /* Select ULPI parallel interface */
Stephen Warren8b263f92014-04-30 15:09:57 -0600678 init_phy_mux(config, PTS_ULPI, init);
Lucas Stach26c32162013-02-07 07:16:29 +0000679
680 /* enable ULPI transceiver */
681 setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB);
682
683 /* configure ULPI transceiver timings */
684 val = 0;
685 writel(val, &usbctlr->ulpi_timing_ctrl_1);
686
687 val |= ULPI_DATA_TRIMMER_SEL(4);
688 val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
689 val |= ULPI_DIR_TRIMMER_SEL(4);
690 writel(val, &usbctlr->ulpi_timing_ctrl_1);
691 udelay(10);
692
693 val |= ULPI_DATA_TRIMMER_LOAD;
694 val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
695 val |= ULPI_DIR_TRIMMER_LOAD;
696 writel(val, &usbctlr->ulpi_timing_ctrl_1);
697
698 /* set up phy for host operation with external vbus supply */
699 ulpi_vp.port_num = 0;
700 ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport;
701
Simon Glass6f7d3422015-03-25 12:22:46 -0600702 ret = ulpi_init(&ulpi_vp);
703 if (ret) {
Lucas Stach26c32162013-02-07 07:16:29 +0000704 printf("Tegra ULPI viewport init failed\n");
Simon Glass6f7d3422015-03-25 12:22:46 -0600705 return ret;
Lucas Stach26c32162013-02-07 07:16:29 +0000706 }
707
708 ulpi_set_vbus(&ulpi_vp, 1, 1);
709 ulpi_set_vbus_indicator(&ulpi_vp, 1, 1, 0);
710
711 /* enable wakeup events */
712 setbits_le32(&usbctlr->port_sc1, WKCN | WKDS | WKOC);
713
714 /* Enable and wait for the phy clock to become valid in 100 ms */
715 setbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);
716 for (loop_count = 100000; loop_count != 0; loop_count--) {
717 if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
718 break;
719 udelay(1);
720 }
721 if (!loop_count)
Simon Glass6f7d3422015-03-25 12:22:46 -0600722 return -ETIMEDOUT;
Lucas Stach26c32162013-02-07 07:16:29 +0000723 clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);
724
725 return 0;
726}
727#else
Stephen Warren8b263f92014-04-30 15:09:57 -0600728static int init_ulpi_usb_controller(struct fdt_usb *config,
729 enum usb_init_type init)
Lucas Stach26c32162013-02-07 07:16:29 +0000730{
731 printf("No code to set up ULPI controller, please enable"
732 "CONFIG_USB_ULPI and CONFIG_USB_ULPI_VIEWPORT");
Simon Glass6f7d3422015-03-25 12:22:46 -0600733 return -ENOSYS;
Lucas Stach26c32162013-02-07 07:16:29 +0000734}
735#endif
736
737static void config_clock(const u32 timing[])
738{
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700739 debug("%s: DIVM = %d, DIVN = %d, DIVP = %d, cpcon/lfcon = %d/%d\n",
740 __func__, timing[PARAM_DIVM], timing[PARAM_DIVN],
741 timing[PARAM_DIVP], timing[PARAM_CPCON], timing[PARAM_LFCON]);
742
Lucas Stach26c32162013-02-07 07:16:29 +0000743 clock_start_pll(CLOCK_ID_USB,
744 timing[PARAM_DIVM], timing[PARAM_DIVN], timing[PARAM_DIVP],
745 timing[PARAM_CPCON], timing[PARAM_LFCON]);
746}
747
Simon Glass09717782015-08-11 08:33:29 -0600748static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config)
Lucas Stach26c32162013-02-07 07:16:29 +0000749{
750 const char *phy, *mode;
751
Johan Jonker8d5d8e02023-03-13 01:32:04 +0100752 config->reg = dev_read_addr_ptr(dev);
Simon Glass4c36be02017-07-25 08:30:04 -0600753 debug("reg=%p\n", config->reg);
754 mode = dev_read_string(dev, "dr_mode");
Lucas Stach26c32162013-02-07 07:16:29 +0000755 if (mode) {
756 if (0 == strcmp(mode, "host"))
757 config->dr_mode = DR_MODE_HOST;
758 else if (0 == strcmp(mode, "peripheral"))
759 config->dr_mode = DR_MODE_DEVICE;
760 else if (0 == strcmp(mode, "otg"))
761 config->dr_mode = DR_MODE_OTG;
762 else {
763 debug("%s: Cannot decode dr_mode '%s'\n", __func__,
764 mode);
Simon Glass6f7d3422015-03-25 12:22:46 -0600765 return -EINVAL;
Lucas Stach26c32162013-02-07 07:16:29 +0000766 }
767 } else {
768 config->dr_mode = DR_MODE_HOST;
769 }
770
Simon Glass4c36be02017-07-25 08:30:04 -0600771 phy = dev_read_string(dev, "phy_type");
Lucas Stach26c32162013-02-07 07:16:29 +0000772 config->utmi = phy && 0 == strcmp("utmi", phy);
773 config->ulpi = phy && 0 == strcmp("ulpi", phy);
Simon Glass4c36be02017-07-25 08:30:04 -0600774 config->has_legacy_mode = dev_read_bool(dev, "nvidia,has-legacy-mode");
Simon Glassc3f26502017-07-25 08:30:00 -0600775 config->periph_id = clock_decode_periph_id(dev);
Lucas Stach26c32162013-02-07 07:16:29 +0000776 if (config->periph_id == PERIPH_ID_NONE) {
777 debug("%s: Missing/invalid peripheral ID\n", __func__);
Simon Glass6f7d3422015-03-25 12:22:46 -0600778 return -EINVAL;
Lucas Stach26c32162013-02-07 07:16:29 +0000779 }
Simon Glass4c36be02017-07-25 08:30:04 -0600780 gpio_request_by_name(dev, "nvidia,vbus-gpio", 0, &config->vbus_gpio,
781 GPIOD_IS_OUT);
782 gpio_request_by_name(dev, "nvidia,phy-reset-gpio", 0,
783 &config->phy_reset_gpio, GPIOD_IS_OUT);
784 debug("legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, vbus=%d, phy_reset=%d, dr_mode=%d, reg=%p\n",
785 config->has_legacy_mode, config->utmi, config->ulpi,
786 config->periph_id, gpio_get_number(&config->vbus_gpio),
787 gpio_get_number(&config->phy_reset_gpio), config->dr_mode,
788 config->reg);
Lucas Stach26c32162013-02-07 07:16:29 +0000789
790 return 0;
791}
792
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300793static void fdt_decode_usb_phy(struct udevice *dev)
794{
795 struct fdt_usb *priv = dev_get_priv(dev);
796 struct tegra_utmip_config *utmip_config = &priv->utmip_config;
797 u32 usb_phy_phandle;
798 ofnode usb_phy_node;
799 int ret;
800
801 ret = ofnode_read_u32(dev_ofnode(dev), "nvidia,phy", &usb_phy_phandle);
802 if (ret)
803 log_debug("%s: required usb phy node isn't provided\n", __func__);
804
805 usb_phy_node = ofnode_get_by_phandle(usb_phy_phandle);
806 if (!ofnode_valid(usb_phy_node) || !ofnode_is_enabled(usb_phy_node)) {
807 log_debug("%s: failed to find usb phy node or it is disabled\n", __func__);
808 utmip_config->xcvr_setup_use_fuses = true;
809 } else {
810 utmip_config->xcvr_setup_use_fuses =
811 ofnode_read_bool(usb_phy_node, "nvidia,xcvr-setup-use-fuses");
812 }
813
814 utmip_config->hssync_start_delay =
815 ofnode_read_u32_default(usb_phy_node,
816 "nvidia,hssync-start-delay", 0x9);
817
818 utmip_config->elastic_limit =
819 ofnode_read_u32_default(usb_phy_node,
820 "nvidia,elastic-limit", 0x10);
821
822 utmip_config->idle_wait_delay =
823 ofnode_read_u32_default(usb_phy_node,
824 "nvidia,idle-wait-delay", 0x11);
825
826 utmip_config->term_range_adj =
827 ofnode_read_u32_default(usb_phy_node,
828 "nvidia,term-range-adj", 0x7);
829
830 utmip_config->xcvr_lsfslew =
831 ofnode_read_u32_default(usb_phy_node,
832 "nvidia,xcvr-lsfslew", 0x0);
833
834 utmip_config->xcvr_lsrslew =
835 ofnode_read_u32_default(usb_phy_node,
836 "nvidia,xcvr-lsrslew", 0x3);
837
838 utmip_config->xcvr_hsslew =
839 ofnode_read_u32_default(usb_phy_node,
840 "nvidia,xcvr-hsslew", 0x8);
841
842 utmip_config->hssquelch_level =
843 ofnode_read_u32_default(usb_phy_node,
844 "nvidia,hssquelch-level", 0x2);
845
846 utmip_config->hsdiscon_level =
847 ofnode_read_u32_default(usb_phy_node,
848 "nvidia,hsdiscon-level", 0x1);
849
850 if (!utmip_config->xcvr_setup_use_fuses) {
851 ofnode_read_u32(usb_phy_node, "nvidia,xcvr-setup",
852 &utmip_config->xcvr_setup);
853 }
854}
855
Simon Glass2bd08a92015-03-25 12:22:47 -0600856int usb_common_init(struct fdt_usb *config, enum usb_init_type init)
857{
858 int ret = 0;
859
860 switch (init) {
861 case USB_INIT_HOST:
862 switch (config->dr_mode) {
863 case DR_MODE_HOST:
864 case DR_MODE_OTG:
865 break;
866 default:
867 printf("tegrausb: Invalid dr_mode %d for host mode\n",
868 config->dr_mode);
869 return -1;
870 }
871 break;
872 case USB_INIT_DEVICE:
873 if (config->periph_id != PERIPH_ID_USBD) {
874 printf("tegrausb: Device mode only supported on first USB controller\n");
875 return -1;
876 }
877 if (!config->utmi) {
878 printf("tegrausb: Device mode only supported with UTMI PHY\n");
879 return -1;
880 }
881 switch (config->dr_mode) {
882 case DR_MODE_DEVICE:
883 case DR_MODE_OTG:
884 break;
885 default:
886 printf("tegrausb: Invalid dr_mode %d for device mode\n",
887 config->dr_mode);
888 return -1;
889 }
890 break;
891 default:
892 printf("tegrausb: Unknown USB_INIT_* %d\n", init);
893 return -1;
894 }
895
Simon Glass2bd08a92015-03-25 12:22:47 -0600896 debug("%d, %d\n", config->utmi, config->ulpi);
897 if (config->utmi)
898 ret = init_utmi_usb_controller(config, init);
899 else if (config->ulpi)
900 ret = init_ulpi_usb_controller(config, init);
901 if (ret)
902 return ret;
903
904 set_up_vbus(config, init);
905
906 config->init_type = init;
907
908 return 0;
909}
910
911void usb_common_uninit(struct fdt_usb *priv)
912{
913 struct usb_ctlr *usbctlr;
914
915 usbctlr = priv->reg;
916
917 /* Stop controller */
918 writel(0, &usbctlr->usb_cmd);
919 udelay(1000);
920
921 /* Initiate controller reset */
922 writel(2, &usbctlr->usb_cmd);
923 udelay(1000);
924}
925
Simon Glassdc9f3ed2015-03-25 12:22:27 -0600926static const struct ehci_ops tegra_ehci_ops = {
927 .set_usb_mode = tegra_ehci_set_usbmode,
928 .get_port_speed = tegra_ehci_get_port_speed,
929 .powerup_fixup = tegra_ehci_powerup_fixup,
930};
931
Simon Glassaad29ae2020-12-03 16:55:21 -0700932static int ehci_usb_of_to_plat(struct udevice *dev)
Simon Glass9c574772015-03-25 12:22:48 -0600933{
934 struct fdt_usb *priv = dev_get_priv(dev);
935 int ret;
936
Simon Glass09717782015-08-11 08:33:29 -0600937 ret = fdt_decode_usb(dev, priv);
Simon Glass9c574772015-03-25 12:22:48 -0600938 if (ret)
939 return ret;
940
941 priv->type = dev_get_driver_data(dev);
942
Svyatoslav Ryhelf87b40f2023-08-17 20:15:18 +0300943 fdt_decode_usb_phy(dev);
944
Simon Glass9c574772015-03-25 12:22:48 -0600945 return 0;
946}
947
948static int ehci_usb_probe(struct udevice *dev)
949{
Simon Glassb75b15b2020-12-03 16:55:23 -0700950 struct usb_plat *plat = dev_get_plat(dev);
Simon Glass9c574772015-03-25 12:22:48 -0600951 struct fdt_usb *priv = dev_get_priv(dev);
952 struct ehci_hccr *hccr;
953 struct ehci_hcor *hcor;
954 static bool clk_done;
955 int ret;
956
957 ret = usb_common_init(priv, plat->init_type);
958 if (ret)
959 return ret;
960 hccr = (struct ehci_hccr *)&priv->reg->cap_length;
961 hcor = (struct ehci_hcor *)&priv->reg->usb_cmd;
962 if (!clk_done) {
963 config_clock(get_pll_timing(&fdt_usb_controllers[priv->type]));
964 clk_done = true;
965 }
966
967 return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0,
968 plat->init_type);
969}
970
Simon Glass9c574772015-03-25 12:22:48 -0600971static const struct udevice_id ehci_usb_ids[] = {
972 { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
973 { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
974 { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
Tom Warrenab0cc6b2015-03-04 16:36:00 -0700975 { .compatible = "nvidia,tegra210-ehci", .data = USB_CTLR_T210 },
Simon Glass9c574772015-03-25 12:22:48 -0600976 { }
977};
978
979U_BOOT_DRIVER(usb_ehci) = {
980 .name = "ehci_tegra",
981 .id = UCLASS_USB,
982 .of_match = ehci_usb_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700983 .of_to_plat = ehci_usb_of_to_plat,
Simon Glass9c574772015-03-25 12:22:48 -0600984 .probe = ehci_usb_probe,
Masahiro Yamadad41919b2016-09-06 22:17:34 +0900985 .remove = ehci_deregister,
Simon Glass9c574772015-03-25 12:22:48 -0600986 .ops = &ehci_usb_ops,
Simon Glassb75b15b2020-12-03 16:55:23 -0700987 .plat_auto = sizeof(struct usb_plat),
Simon Glass8a2b47f2020-12-03 16:55:17 -0700988 .priv_auto = sizeof(struct fdt_usb),
Simon Glass9c574772015-03-25 12:22:48 -0600989 .flags = DM_FLAG_ALLOC_PRIV_DMA,
990};