Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/nvidia/tegra_usbphy.c
39483 views
1
/*-
2
* Copyright (c) 2016 Michal Meloun <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#include <sys/cdefs.h>
28
/*
29
* USB phy driver for Tegra SoCs.
30
*/
31
#include <sys/param.h>
32
#include <sys/systm.h>
33
#include <sys/bus.h>
34
#include <sys/kernel.h>
35
#include <sys/module.h>
36
#include <sys/malloc.h>
37
#include <sys/rman.h>
38
39
#include <machine/bus.h>
40
41
#include <dev/clk/clk.h>
42
#include <dev/hwreset/hwreset.h>
43
#include <dev/phy/phy.h>
44
#include <dev/regulator/regulator.h>
45
#include <dev/fdt/fdt_pinctrl.h>
46
#include <dev/ofw/openfirm.h>
47
#include <dev/ofw/ofw_bus.h>
48
#include <dev/ofw/ofw_bus_subr.h>
49
50
#include "phynode_if.h"
51
52
#define CTRL_ICUSB_CTRL 0x15c
53
#define ICUSB_CTR_IC_ENB1 (1 << 3)
54
55
#define CTRL_USB_USBMODE 0x1f8
56
#define USB_USBMODE_MASK (3 << 0)
57
#define USB_USBMODE_HOST (3 << 0)
58
#define USB_USBMODE_DEVICE (2 << 0)
59
60
#define CTRL_USB_HOSTPC1_DEVLC 0x1b4
61
#define USB_HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29)
62
#define USB_HOSTPC1_DEVLC_STS (1 << 28)
63
#define USB_HOSTPC1_DEVLC_PHCD (1 << 22)
64
65
#define IF_USB_SUSP_CTRL 0x400
66
#define FAST_WAKEUP_RESP (1 << 26)
67
#define UTMIP_SUSPL1_SET (1 << 25)
68
#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
69
#define USB_SUSP_SET (1 << 14)
70
#define UTMIP_PHY_ENB (1 << 12)
71
#define UTMIP_RESET (1 << 11)
72
#define USB_SUSP_POL (1 << 10)
73
#define USB_PHY_CLK_VALID_INT_ENB (1 << 9)
74
#define USB_PHY_CLK_VALID_INT_STS (1 << 8)
75
#define USB_PHY_CLK_VALID (1 << 7)
76
#define USB_CLKEN (1 << 6)
77
#define USB_SUSP_CLR (1 << 5)
78
#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
79
#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
80
#define USB_WAKE_ON_RESUME_EN (1 << 2)
81
#define USB_WAKEUP_INT_ENB (1 << 1)
82
#define USB_WAKEUP_INT_STS (1 << 0)
83
84
#define IF_USB_PHY_VBUS_SENSORS 0x404
85
#define B_SESS_END_SW_VALUE (1 << 4)
86
#define B_SESS_END_SW_EN (1 << 3)
87
88
#define UTMIP_XCVR_CFG0 0x808
89
#define UTMIP_XCVR_HSSLEW_MSB(x) ((((x) & 0x1fc) >> 2) << 25)
90
#define UTMIP_XCVR_SETUP_MSB(x) ((((x) & 0x70) >> 4) << 22)
91
#define UTMIP_XCVR_LSBIAS_SEL (1 << 21)
92
#define UTMIP_XCVR_DISCON_METHOD (1 << 20)
93
#define UTMIP_FORCE_PDZI_POWERUP (1 << 19)
94
#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
95
#define UTMIP_FORCE_PD2_POWERUP (1 << 17)
96
#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
97
#define UTMIP_FORCE_PD_POWERUP (1 << 15)
98
#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
99
#define UTMIP_XCVR_TERMEN (1 << 13)
100
#define UTMIP_XCVR_HSLOOPBACK (1 << 12)
101
#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10)
102
#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8)
103
#define UTMIP_XCVR_FSSLEW(x) (((x) & 0x3) << 6)
104
#define UTMIP_XCVR_HSSLEW(x) (((x) & 0x3) << 4)
105
#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0)
106
107
#define UTMIP_BIAS_CFG0 0x80C
108
#define UTMIP_IDDIG_C_VAL (1 << 30)
109
#define UTMIP_IDDIG_C_SEL (1 << 29)
110
#define UTMIP_IDDIG_B_VAL (1 << 28)
111
#define UTMIP_IDDIG_B_SEL (1 << 27)
112
#define UTMIP_IDDIG_A_VAL (1 << 26)
113
#define UTMIP_IDDIG_A_SEL (1 << 25)
114
#define UTMIP_HSDISCON_LEVEL_MSB(x) ((((x) & 0x4) >> 2) << 24)
115
#define UTMIP_IDPD_VAL (1 << 23)
116
#define UTMIP_IDPD_SEL (1 << 22)
117
#define UTMIP_IDDIG_VAL (1 << 21)
118
#define UTMIP_IDDIG_SEL (1 << 20)
119
#define UTMIP_GPI_VAL (1 << 19)
120
#define UTMIP_GPI_SEL (1 << 18)
121
#define UTMIP_ACTIVE_TERM_OFFSET(x) (((x) & 0x7) << 15)
122
#define UTMIP_ACTIVE_PULLUP_OFFSET(x) (((x) & 0x7) << 12)
123
#define UTMIP_OTGPD (1 << 11)
124
#define UTMIP_BIASPD (1 << 10)
125
#define UTMIP_VBUS_LEVEL_LEVEL(x) (((x) & 0x3) << 8)
126
#define UTMIP_SESS_LEVEL_LEVEL(x) (((x) & 0x3) << 6)
127
#define UTMIP_HSCHIRP_LEVEL(x) (((x) & 0x3) << 4)
128
#define UTMIP_HSDISCON_LEVEL(x) (((x) & 0x3) << 2)
129
#define UTMIP_HSSQUELCH_LEVEL(x) (((x) & 0x3) << 0)
130
131
#define UTMIP_HSRX_CFG0 0x810
132
#define UTMIP_KEEP_PATT_ON_ACTIVE(x) (((x) & 0x3) << 30)
133
#define UTMIP_ALLOW_CONSEC_UPDN (1 << 29)
134
#define UTMIP_REALIGN_ON_NEW_PKT (1 << 28)
135
#define UTMIP_PCOUNT_UPDN_DIV(x) (((x) & 0xf) << 24)
136
#define UTMIP_SQUELCH_EOP_DLY(x) (((x) & 0x7) << 21)
137
#define UTMIP_NO_STRIPPING (1 << 20)
138
#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15)
139
#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10)
140
#define UTMIP_ELASTIC_OVERRUN_DISABLE (1 << 9)
141
#define UTMIP_ELASTIC_UNDERRUN_DISABLE (1 << 8)
142
#define UTMIP_PASS_CHIRP (1 << 7)
143
#define UTMIP_PASS_FEEDBACK (1 << 6)
144
#define UTMIP_PCOUNT_INERTIA(x) (((x) & 0x3) << 4)
145
#define UTMIP_PHASE_ADJUST(x) (((x) & 0x3) << 2)
146
#define UTMIP_THREE_SYNCBITS (1 << 1)
147
#define UTMIP_USE4SYNC_TRAN (1 << 0)
148
149
#define UTMIP_HSRX_CFG1 0x814
150
#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1F) << 1)
151
#define UTMIP_HS_ALLOW_KEEP_ALIVE (1 << 0)
152
153
#define UTMIP_TX_CFG0 0x820
154
#define UTMIP_FS_PREAMBLE_J (1 << 19)
155
#define UTMIP_FS_POSTAMBLE_OUTPUT_ENABLE (1 << 18)
156
#define UTMIP_FS_PREAMBLE_OUTPUT_ENABLE (1 << 17)
157
#define UTMIP_FSLS_ALLOW_SOP_TX_STUFF_ERR (1 << 16)
158
#define UTMIP_HS_READY_WAIT_FOR_VALID (1 << 15)
159
#define UTMIP_HS_TX_IPG_DLY(x) (((x) & 0x1f) << 10)
160
#define UTMIP_HS_DISCON_EOP_ONLY (1 << 9)
161
#define UTMIP_HS_DISCON_DISABLE (1 << 8)
162
#define UTMIP_HS_POSTAMBLE_OUTPUT_ENABLE (1 << 7)
163
#define UTMIP_HS_PREAMBLE_OUTPUT_ENABLE (1 << 6)
164
#define UTMIP_SIE_RESUME_ON_LINESTATE (1 << 5)
165
#define UTMIP_SOF_ON_NO_STUFF (1 << 4)
166
#define UTMIP_SOF_ON_NO_ENCODE (1 << 3)
167
#define UTMIP_NO_STUFFING (1 << 2)
168
#define UTMIP_NO_ENCODING (1 << 1)
169
#define UTMIP_NO_SYNC_NO_EOP (1 << 0)
170
171
#define UTMIP_MISC_CFG0 0x824
172
#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27)
173
#define UTMIP_DPDM_OBSERVE (1 << 26)
174
#define UTMIP_KEEP_XCVR_PD_ON_SOFT_DISCON (1 << 25)
175
#define UTMIP_ALLOW_LS_ON_SOFT_DISCON (1 << 24)
176
#define UTMIP_FORCE_FS_DISABLE_ON_DEV_CHIRP (1 << 23)
177
#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22)
178
#define UTMIP_LS_TO_FS_SKIP_4MS (1 << 21)
179
#define UTMIP_INJECT_ERROR_TYPE(x) (((x) & 0x3) << 19)
180
#define UTMIP_FORCE_HS_CLOCK_ON (1 << 18)
181
#define UTMIP_DISABLE_HS_TERM (1 << 17)
182
#define UTMIP_FORCE_HS_TERM (1 << 16)
183
#define UTMIP_DISABLE_PULLUP_DP (1 << 15)
184
#define UTMIP_DISABLE_PULLUP_DM (1 << 14)
185
#define UTMIP_DISABLE_PULLDN_DP (1 << 13)
186
#define UTMIP_DISABLE_PULLDN_DM (1 << 12)
187
#define UTMIP_FORCE_PULLUP_DP (1 << 11)
188
#define UTMIP_FORCE_PULLUP_DM (1 << 10)
189
#define UTMIP_FORCE_PULLDN_DP (1 << 9)
190
#define UTMIP_FORCE_PULLDN_DM (1 << 8)
191
#define UTMIP_STABLE_COUNT(x) (((x) & 0x7) << 5)
192
#define UTMIP_STABLE_ALL (1 << 4)
193
#define UTMIP_NO_FREE_ON_SUSPEND (1 << 3)
194
#define UTMIP_NEVER_FREE_RUNNING_TERMS (1 << 2)
195
#define UTMIP_ALWAYS_FREE_RUNNING_TERMS (1 << 1)
196
#define UTMIP_COMB_TERMS (1 << 0)
197
198
#define UTMIP_MISC_CFG1 0x828
199
#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30)
200
201
#define UTMIP_DEBOUNCE_CFG0 0x82C
202
#define UTMIP_BIAS_DEBOUNCE_B(x) (((x) & 0xffff) << 16)
203
#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0)
204
205
#define UTMIP_BAT_CHRG_CFG0 0x830
206
#define UTMIP_CHRG_DEBOUNCE_TIMESCALE(x) (((x) & 0x1f) << 8)
207
#define UTMIP_OP_I_SRC_ENG (1 << 5)
208
#define UTMIP_ON_SRC_ENG (1 << 4)
209
#define UTMIP_OP_SRC_ENG (1 << 3)
210
#define UTMIP_ON_SINK_ENG (1 << 2)
211
#define UTMIP_OP_SINK_ENG (1 << 1)
212
#define UTMIP_PD_CHRG (1 << 0)
213
214
#define UTMIP_SPARE_CFG0 0x834
215
#define FUSE_HS_IREF_CAP_CFG (1 << 7)
216
#define FUSE_HS_SQUELCH_LEVEL (1 << 6)
217
#define FUSE_SPARE (1 << 5)
218
#define FUSE_TERM_RANGE_ADJ_SEL (1 << 4)
219
#define FUSE_SETUP_SEL (1 << 3)
220
#define HS_RX_LATE_SQUELCH (1 << 2)
221
#define HS_RX_FLUSH_ALAP (1 << 1)
222
#define HS_RX_IPG_ERROR_ENABLE (1 << 0)
223
224
#define UTMIP_XCVR_CFG1 0x838
225
#define UTMIP_XCVR_RPU_RANGE_ADJ(x) (((x) & 0x3) << 26)
226
#define UTMIP_XCVR_HS_IREF_CAP(x) (((x) & 0x3) << 24)
227
#define UTMIP_XCVR_SPARE(x) (((x) & 0x3) << 22)
228
#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18)
229
#define UTMIP_RCTRL_SW_SET (1 << 17)
230
#define UTMIP_RCTRL_SW_VAL(x) (((x) & 0x1f) << 12)
231
#define UTMIP_TCTRL_SW_SET (1 << 11)
232
#define UTMIP_TCTRL_SW_VAL(x) (((x) & 0x1f) << 6)
233
#define UTMIP_FORCE_PDDR_POWERUP (1 << 5)
234
#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
235
#define UTMIP_FORCE_PDCHRP_POWERUP (1 << 3)
236
#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
237
#define UTMIP_FORCE_PDDISC_POWERUP (1 << 1)
238
#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
239
240
#define UTMIP_BIAS_CFG1 0x83c
241
#define UTMIP_BIAS_DEBOUNCE_TIMESCALE(x) (((x) & 0x3f) << 8)
242
#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
243
#define UTMIP_VBUS_WAKEUP_POWERDOWN (1 << 2)
244
#define UTMIP_FORCE_PDTRK_POWERUP (1 << 1)
245
#define UTMIP_FORCE_PDTRK_POWERDOWN (1 << 0)
246
247
static int usbpby_enable_cnt;
248
249
enum usb_ifc_type {
250
USB_IFC_TYPE_UNKNOWN = 0,
251
USB_IFC_TYPE_UTMI,
252
USB_IFC_TYPE_ULPI
253
};
254
255
enum usb_dr_mode {
256
USB_DR_MODE_UNKNOWN = 0,
257
USB_DR_MODE_DEVICE,
258
USB_DR_MODE_HOST,
259
USB_DR_MODE_OTG
260
};
261
262
struct usbphy_softc {
263
device_t dev;
264
struct resource *mem_res;
265
struct resource *pads_res;
266
clk_t clk_reg;
267
clk_t clk_pads;
268
clk_t clk_pllu;
269
regulator_t supply_vbus;
270
hwreset_t reset_usb;
271
hwreset_t reset_pads;
272
enum usb_ifc_type ifc_type;
273
enum usb_dr_mode dr_mode;
274
bool have_utmi_regs;
275
276
/* UTMI params */
277
int hssync_start_delay;
278
int elastic_limit;
279
int idle_wait_delay;
280
int term_range_adj;
281
int xcvr_lsfslew;
282
int xcvr_lsrslew;
283
int xcvr_hsslew;
284
int hssquelch_level;
285
int hsdiscon_level;
286
int xcvr_setup;
287
int xcvr_setup_use_fuses;
288
};
289
290
static struct ofw_compat_data compat_data[] = {
291
{"nvidia,tegra210-usb-phy", 1},
292
{"nvidia,tegra30-usb-phy", 1},
293
{NULL, 0},
294
};
295
296
/* Phy controller class and methods. */
297
static int usbphy_phy_enable(struct phynode *phy, bool enable);
298
static phynode_method_t usbphy_phynode_methods[] = {
299
PHYNODEMETHOD(phynode_enable, usbphy_phy_enable),
300
301
PHYNODEMETHOD_END
302
};
303
DEFINE_CLASS_1(usbphy_phynode, usbphy_phynode_class, usbphy_phynode_methods,
304
0, phynode_class);
305
306
#define RD4(sc, offs) \
307
bus_read_4(sc->mem_res, offs)
308
309
#define WR4(sc, offs, val) \
310
bus_write_4(sc->mem_res, offs, val)
311
312
static int
313
reg_wait(struct usbphy_softc *sc, uint32_t reg, uint32_t mask, uint32_t val)
314
{
315
int i;
316
317
for (i = 0; i < 1000; i++) {
318
if ((RD4(sc, reg) & mask) == val)
319
return (0);
320
DELAY(10);
321
}
322
return (ETIMEDOUT);
323
}
324
325
static int
326
usbphy_utmi_phy_clk(struct usbphy_softc *sc, bool enable)
327
{
328
uint32_t val;
329
int rv;
330
331
val = RD4(sc, CTRL_USB_HOSTPC1_DEVLC);
332
if (enable)
333
val &= ~USB_HOSTPC1_DEVLC_PHCD;
334
else
335
val |= USB_HOSTPC1_DEVLC_PHCD;
336
WR4(sc, CTRL_USB_HOSTPC1_DEVLC, val);
337
338
rv = reg_wait(sc, IF_USB_SUSP_CTRL, USB_PHY_CLK_VALID,
339
enable ? USB_PHY_CLK_VALID: 0);
340
if (rv != 0) {
341
device_printf(sc->dev, "USB phy clock timeout.\n");
342
return (ETIMEDOUT);
343
}
344
return (0);
345
}
346
347
static int
348
usbphy_utmi_enable(struct usbphy_softc *sc)
349
{
350
int rv;
351
uint32_t val;
352
353
/* Reset phy */
354
val = RD4(sc, IF_USB_SUSP_CTRL);
355
val |= UTMIP_RESET;
356
WR4(sc, IF_USB_SUSP_CTRL, val);
357
358
val = RD4(sc, UTMIP_TX_CFG0);
359
val |= UTMIP_FS_PREAMBLE_J;
360
WR4(sc, UTMIP_TX_CFG0, val);
361
362
val = RD4(sc, UTMIP_HSRX_CFG0);
363
val &= ~UTMIP_IDLE_WAIT(~0);
364
val &= ~UTMIP_ELASTIC_LIMIT(~0);
365
val |= UTMIP_IDLE_WAIT(sc->idle_wait_delay);
366
val |= UTMIP_ELASTIC_LIMIT(sc->elastic_limit);
367
WR4(sc, UTMIP_HSRX_CFG0, val);
368
369
val = RD4(sc, UTMIP_HSRX_CFG1);
370
val &= ~UTMIP_HS_SYNC_START_DLY(~0);
371
val |= UTMIP_HS_SYNC_START_DLY(sc->hssync_start_delay);
372
WR4(sc, UTMIP_HSRX_CFG1, val);
373
374
val = RD4(sc, UTMIP_DEBOUNCE_CFG0);
375
val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
376
val |= UTMIP_BIAS_DEBOUNCE_A(0x7530); /* For 12MHz */
377
WR4(sc, UTMIP_DEBOUNCE_CFG0, val);
378
379
val = RD4(sc, UTMIP_MISC_CFG0);
380
val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
381
WR4(sc, UTMIP_MISC_CFG0, val);
382
383
if (sc->dr_mode == USB_DR_MODE_DEVICE) {
384
val = RD4(sc,IF_USB_SUSP_CTRL);
385
val &= ~USB_WAKE_ON_CNNT_EN_DEV;
386
val &= ~USB_WAKE_ON_DISCON_EN_DEV;
387
WR4(sc, IF_USB_SUSP_CTRL, val);
388
389
val = RD4(sc, UTMIP_BAT_CHRG_CFG0);
390
val &= ~UTMIP_PD_CHRG;
391
WR4(sc, UTMIP_BAT_CHRG_CFG0, val);
392
} else {
393
val = RD4(sc, UTMIP_BAT_CHRG_CFG0);
394
val |= UTMIP_PD_CHRG;
395
WR4(sc, UTMIP_BAT_CHRG_CFG0, val);
396
}
397
398
usbpby_enable_cnt++;
399
if (usbpby_enable_cnt == 1) {
400
rv = hwreset_deassert(sc->reset_pads);
401
if (rv != 0) {
402
device_printf(sc->dev,
403
"Cannot unreset 'utmi-pads' reset\n");
404
return (rv);
405
}
406
rv = clk_enable(sc->clk_pads);
407
if (rv != 0) {
408
device_printf(sc->dev,
409
"Cannot enable 'utmi-pads' clock\n");
410
return (rv);
411
}
412
413
val = bus_read_4(sc->pads_res, UTMIP_BIAS_CFG0);
414
val &= ~UTMIP_OTGPD;
415
val &= ~UTMIP_BIASPD;
416
val &= ~UTMIP_HSSQUELCH_LEVEL(~0);
417
val &= ~UTMIP_HSDISCON_LEVEL(~0);
418
val &= ~UTMIP_HSDISCON_LEVEL_MSB(~0);
419
val |= UTMIP_HSSQUELCH_LEVEL(sc->hssquelch_level);
420
val |= UTMIP_HSDISCON_LEVEL(sc->hsdiscon_level);
421
val |= UTMIP_HSDISCON_LEVEL_MSB(sc->hsdiscon_level);
422
bus_write_4(sc->pads_res, UTMIP_BIAS_CFG0, val);
423
424
rv = clk_disable(sc->clk_pads);
425
if (rv != 0) {
426
device_printf(sc->dev,
427
"Cannot disable 'utmi-pads' clock\n");
428
return (rv);
429
}
430
}
431
432
val = RD4(sc, UTMIP_XCVR_CFG0);
433
val &= ~UTMIP_FORCE_PD_POWERDOWN;
434
val &= ~UTMIP_FORCE_PD2_POWERDOWN ;
435
val &= ~UTMIP_FORCE_PDZI_POWERDOWN;
436
val &= ~UTMIP_XCVR_LSBIAS_SEL;
437
val &= ~UTMIP_XCVR_LSFSLEW(~0);
438
val &= ~UTMIP_XCVR_LSRSLEW(~0);
439
val &= ~UTMIP_XCVR_HSSLEW(~0);
440
val &= ~UTMIP_XCVR_HSSLEW_MSB(~0);
441
val |= UTMIP_XCVR_LSFSLEW(sc->xcvr_lsfslew);
442
val |= UTMIP_XCVR_LSRSLEW(sc->xcvr_lsrslew);
443
val |= UTMIP_XCVR_HSSLEW(sc->xcvr_hsslew);
444
val |= UTMIP_XCVR_HSSLEW_MSB(sc->xcvr_hsslew);
445
if (!sc->xcvr_setup_use_fuses) {
446
val &= ~UTMIP_XCVR_SETUP(~0);
447
val &= ~UTMIP_XCVR_SETUP_MSB(~0);
448
val |= UTMIP_XCVR_SETUP(sc->xcvr_setup);
449
val |= UTMIP_XCVR_SETUP_MSB(sc->xcvr_setup);
450
}
451
WR4(sc, UTMIP_XCVR_CFG0, val);
452
453
val = RD4(sc, UTMIP_XCVR_CFG1);
454
val &= ~UTMIP_FORCE_PDDISC_POWERDOWN;
455
val &= ~UTMIP_FORCE_PDCHRP_POWERDOWN;
456
val &= ~UTMIP_FORCE_PDDR_POWERDOWN;
457
val &= ~UTMIP_XCVR_TERM_RANGE_ADJ(~0);
458
val |= UTMIP_XCVR_TERM_RANGE_ADJ(sc->term_range_adj);
459
WR4(sc, UTMIP_XCVR_CFG1, val);
460
461
val = RD4(sc, UTMIP_BIAS_CFG1);
462
val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
463
val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
464
WR4(sc, UTMIP_BIAS_CFG1, val);
465
466
val = RD4(sc, UTMIP_SPARE_CFG0);
467
if (sc->xcvr_setup_use_fuses)
468
val |= FUSE_SETUP_SEL;
469
else
470
val &= ~FUSE_SETUP_SEL;
471
WR4(sc, UTMIP_SPARE_CFG0, val);
472
473
val = RD4(sc, IF_USB_SUSP_CTRL);
474
val |= UTMIP_PHY_ENB;
475
WR4(sc, IF_USB_SUSP_CTRL, val);
476
477
val = RD4(sc, IF_USB_SUSP_CTRL);
478
val &= ~UTMIP_RESET;
479
WR4(sc, IF_USB_SUSP_CTRL, val);
480
481
usbphy_utmi_phy_clk(sc, true);
482
483
val = RD4(sc, CTRL_USB_USBMODE);
484
val &= ~USB_USBMODE_MASK;
485
if (sc->dr_mode == USB_DR_MODE_HOST)
486
val |= USB_USBMODE_HOST;
487
else
488
val |= USB_USBMODE_DEVICE;
489
WR4(sc, CTRL_USB_USBMODE, val);
490
491
val = RD4(sc, CTRL_USB_HOSTPC1_DEVLC);
492
val &= ~USB_HOSTPC1_DEVLC_PTS(~0);
493
val |= USB_HOSTPC1_DEVLC_PTS(0);
494
WR4(sc, CTRL_USB_HOSTPC1_DEVLC, val);
495
496
return (0);
497
}
498
499
static int
500
usbphy_utmi_disable(struct usbphy_softc *sc)
501
{
502
int rv;
503
uint32_t val;
504
505
usbphy_utmi_phy_clk(sc, false);
506
507
if (sc->dr_mode == USB_DR_MODE_DEVICE) {
508
val = RD4(sc, IF_USB_SUSP_CTRL);
509
val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
510
val |= USB_WAKE_ON_CNNT_EN_DEV;
511
val |= USB_WAKEUP_DEBOUNCE_COUNT(5);
512
WR4(sc, IF_USB_SUSP_CTRL, val);
513
}
514
515
val = RD4(sc, IF_USB_SUSP_CTRL);
516
val |= UTMIP_RESET;
517
WR4(sc, IF_USB_SUSP_CTRL, val);
518
519
val = RD4(sc, UTMIP_BAT_CHRG_CFG0);
520
val |= UTMIP_PD_CHRG;
521
WR4(sc, UTMIP_BAT_CHRG_CFG0, val);
522
523
val = RD4(sc, UTMIP_XCVR_CFG0);
524
val |= UTMIP_FORCE_PD_POWERDOWN;
525
val |= UTMIP_FORCE_PD2_POWERDOWN;
526
val |= UTMIP_FORCE_PDZI_POWERDOWN;
527
WR4(sc, UTMIP_XCVR_CFG0, val);
528
529
val = RD4(sc, UTMIP_XCVR_CFG1);
530
val |= UTMIP_FORCE_PDDISC_POWERDOWN;
531
val |= UTMIP_FORCE_PDCHRP_POWERDOWN;
532
val |= UTMIP_FORCE_PDDR_POWERDOWN;
533
WR4(sc, UTMIP_XCVR_CFG1, val);
534
535
usbpby_enable_cnt--;
536
if (usbpby_enable_cnt <= 0) {
537
rv = clk_enable(sc->clk_pads);
538
if (rv != 0) {
539
device_printf(sc->dev,
540
"Cannot enable 'utmi-pads' clock\n");
541
return (rv);
542
}
543
val =bus_read_4(sc->pads_res, UTMIP_BIAS_CFG0);
544
val |= UTMIP_OTGPD;
545
val |= UTMIP_BIASPD;
546
bus_write_4(sc->pads_res, UTMIP_BIAS_CFG0, val);
547
548
rv = clk_disable(sc->clk_pads);
549
if (rv != 0) {
550
device_printf(sc->dev,
551
"Cannot disable 'utmi-pads' clock\n");
552
return (rv);
553
}
554
}
555
return (0);
556
}
557
558
static int
559
usbphy_phy_enable(struct phynode *phy, bool enable)
560
{
561
device_t dev;
562
struct usbphy_softc *sc;
563
int rv = 0;
564
565
dev = phynode_get_device(phy);
566
sc = device_get_softc(dev);
567
568
if (sc->ifc_type != USB_IFC_TYPE_UTMI) {
569
device_printf(sc->dev,
570
"Only UTMI interface is supported.\n");
571
return (ENXIO);
572
}
573
if (enable)
574
rv = usbphy_utmi_enable(sc);
575
else
576
rv = usbphy_utmi_disable(sc);
577
578
return (rv);
579
}
580
581
static enum usb_ifc_type
582
usb_get_ifc_mode(device_t dev, phandle_t node, char *name)
583
{
584
char *tmpstr;
585
int rv;
586
enum usb_ifc_type ret;
587
588
rv = OF_getprop_alloc(node, name, (void **)&tmpstr);
589
if (rv <= 0)
590
return (USB_IFC_TYPE_UNKNOWN);
591
592
ret = USB_IFC_TYPE_UNKNOWN;
593
if (strcmp(tmpstr, "utmi") == 0)
594
ret = USB_IFC_TYPE_UTMI;
595
else if (strcmp(tmpstr, "ulpi") == 0)
596
ret = USB_IFC_TYPE_ULPI;
597
else
598
device_printf(dev, "Unsupported phy type: %s\n", tmpstr);
599
OF_prop_free(tmpstr);
600
return (ret);
601
}
602
603
static enum usb_dr_mode
604
usb_get_dr_mode(device_t dev, phandle_t node, char *name)
605
{
606
char *tmpstr;
607
int rv;
608
enum usb_dr_mode ret;
609
610
rv = OF_getprop_alloc(node, name, (void **)&tmpstr);
611
if (rv <= 0)
612
return (USB_DR_MODE_UNKNOWN);
613
614
ret = USB_DR_MODE_UNKNOWN;
615
if (strcmp(tmpstr, "device") == 0)
616
ret = USB_DR_MODE_DEVICE;
617
else if (strcmp(tmpstr, "host") == 0)
618
ret = USB_DR_MODE_HOST;
619
else if (strcmp(tmpstr, "otg") == 0)
620
ret = USB_DR_MODE_OTG;
621
else
622
device_printf(dev, "Unknown dr mode: %s\n", tmpstr);
623
OF_prop_free(tmpstr);
624
return (ret);
625
}
626
627
static int
628
usbphy_utmi_read_params(struct usbphy_softc *sc, phandle_t node)
629
{
630
int rv;
631
632
rv = OF_getencprop(node, "nvidia,hssync-start-delay",
633
&sc->hssync_start_delay, sizeof (sc->hssync_start_delay));
634
if (rv <= 0)
635
return (ENXIO);
636
637
rv = OF_getencprop(node, "nvidia,elastic-limit",
638
&sc->elastic_limit, sizeof (sc->elastic_limit));
639
if (rv <= 0)
640
return (ENXIO);
641
642
rv = OF_getencprop(node, "nvidia,idle-wait-delay",
643
&sc->idle_wait_delay, sizeof (sc->idle_wait_delay));
644
if (rv <= 0)
645
return (ENXIO);
646
647
rv = OF_getencprop(node, "nvidia,term-range-adj",
648
&sc->term_range_adj, sizeof (sc->term_range_adj));
649
if (rv <= 0)
650
return (ENXIO);
651
652
rv = OF_getencprop(node, "nvidia,xcvr-lsfslew",
653
&sc->xcvr_lsfslew, sizeof (sc->xcvr_lsfslew));
654
if (rv <= 0)
655
return (ENXIO);
656
657
rv = OF_getencprop(node, "nvidia,xcvr-lsrslew",
658
&sc->xcvr_lsrslew, sizeof (sc->xcvr_lsrslew));
659
if (rv <= 0)
660
return (ENXIO);
661
662
rv = OF_getencprop(node, "nvidia,xcvr-hsslew",
663
&sc->xcvr_hsslew, sizeof (sc->xcvr_hsslew));
664
if (rv <= 0)
665
return (ENXIO);
666
667
rv = OF_getencprop(node, "nvidia,hssquelch-level",
668
&sc->hssquelch_level, sizeof (sc->hssquelch_level));
669
if (rv <= 0)
670
return (ENXIO);
671
672
rv = OF_getencprop(node, "nvidia,hsdiscon-level",
673
&sc->hsdiscon_level, sizeof (sc->hsdiscon_level));
674
if (rv <= 0)
675
return (ENXIO);
676
677
rv = OF_getproplen(node, "nvidia,xcvr-setup-use-fuses");
678
if (rv >= 1) {
679
sc->xcvr_setup_use_fuses = 1;
680
} else {
681
rv = OF_getencprop(node, "nvidia,xcvr-setup",
682
&sc->xcvr_setup, sizeof (sc->xcvr_setup));
683
if (rv <= 0)
684
return (ENXIO);
685
}
686
687
return (0);
688
}
689
690
static int
691
usbphy_probe(device_t dev)
692
{
693
694
if (!ofw_bus_status_okay(dev))
695
return (ENXIO);
696
697
if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
698
return (ENXIO);
699
700
device_set_desc(dev, "Tegra USB phy");
701
return (BUS_PROBE_DEFAULT);
702
}
703
704
static int
705
usbphy_attach(device_t dev)
706
{
707
struct usbphy_softc *sc;
708
int rid, rv;
709
phandle_t node;
710
struct phynode *phynode;
711
struct phynode_init_def phy_init;
712
713
sc = device_get_softc(dev);
714
sc->dev = dev;
715
716
rid = 0;
717
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
718
RF_ACTIVE | RF_SHAREABLE);
719
if (sc->mem_res == NULL) {
720
device_printf(dev, "Cannot allocate memory resources\n");
721
return (ENXIO);
722
}
723
724
rid = 1;
725
sc->pads_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
726
RF_ACTIVE | RF_SHAREABLE);
727
if (sc->mem_res == NULL) {
728
device_printf(dev, "Cannot allocate memory resources\n");
729
return (ENXIO);
730
}
731
732
node = ofw_bus_get_node(dev);
733
734
rv = hwreset_get_by_ofw_name(sc->dev, 0, "usb", &sc->reset_usb);
735
if (rv != 0) {
736
device_printf(dev, "Cannot get 'usb' reset\n");
737
return (ENXIO);
738
}
739
rv = hwreset_get_by_ofw_name(sc->dev, 0, "utmi-pads", &sc->reset_pads);
740
if (rv != 0) {
741
device_printf(dev, "Cannot get 'utmi-pads' reset\n");
742
return (ENXIO);
743
}
744
745
rv = clk_get_by_ofw_name(sc->dev, 0, "reg", &sc->clk_reg);
746
if (rv != 0) {
747
device_printf(sc->dev, "Cannot get 'reg' clock\n");
748
return (ENXIO);
749
}
750
rv = clk_get_by_ofw_name(sc->dev, 0, "pll_u", &sc->clk_pllu);
751
if (rv != 0) {
752
device_printf(sc->dev, "Cannot get 'pll_u' clock\n");
753
return (ENXIO);
754
}
755
rv = clk_get_by_ofw_name(sc->dev, 0, "utmi-pads", &sc->clk_pads);
756
if (rv != 0) {
757
device_printf(sc->dev, "Cannot get 'utmi-pads' clock\n");
758
return (ENXIO);
759
}
760
761
rv = hwreset_deassert(sc->reset_usb);
762
if (rv != 0) {
763
device_printf(dev, "Cannot unreset 'usb' reset\n");
764
return (ENXIO);
765
}
766
767
rv = clk_enable(sc->clk_pllu);
768
if (rv != 0) {
769
device_printf(sc->dev, "Cannot enable 'pllu' clock\n");
770
return (ENXIO);
771
}
772
rv = clk_enable(sc->clk_reg);
773
if (rv != 0) {
774
device_printf(sc->dev, "Cannot enable 'reg' clock\n");
775
return (ENXIO);
776
}
777
if (OF_hasprop(node, "nvidia,has-utmi-pad-registers"))
778
sc->have_utmi_regs = true;
779
780
sc->dr_mode = usb_get_dr_mode(dev, node, "dr_mode");
781
if (sc->dr_mode == USB_DR_MODE_UNKNOWN)
782
sc->dr_mode = USB_DR_MODE_HOST;
783
784
sc->ifc_type = usb_get_ifc_mode(dev, node, "phy_type");
785
786
/* We supports only utmi phy mode for now .... */
787
if (sc->ifc_type != USB_IFC_TYPE_UTMI) {
788
device_printf(dev, "Unsupported phy type\n");
789
return (ENXIO);
790
}
791
rv = usbphy_utmi_read_params(sc, node);
792
if (rv < 0)
793
return rv;
794
795
if (OF_hasprop(node, "vbus-supply")) {
796
rv = regulator_get_by_ofw_property(sc->dev, 0, "vbus-supply",
797
&sc->supply_vbus);
798
if (rv != 0) {
799
device_printf(sc->dev,
800
"Cannot get \"vbus\" regulator\n");
801
return (ENXIO);
802
}
803
rv = regulator_enable(sc->supply_vbus);
804
if (rv != 0) {
805
device_printf(sc->dev,
806
"Cannot enable \"vbus\" regulator\n");
807
return (rv);
808
}
809
}
810
811
/* Create and register phy. */
812
bzero(&phy_init, sizeof(phy_init));
813
phy_init.id = 1;
814
phy_init.ofw_node = node;
815
phynode = phynode_create(dev, &usbphy_phynode_class, &phy_init);
816
if (phynode == NULL) {
817
device_printf(sc->dev, "Cannot create phy\n");
818
return (ENXIO);
819
}
820
if (phynode_register(phynode) == NULL) {
821
device_printf(sc->dev, "Cannot create phy\n");
822
return (ENXIO);
823
}
824
825
return (0);
826
}
827
828
static int
829
usbphy_detach(device_t dev)
830
{
831
832
/* This device is always present. */
833
return (EBUSY);
834
}
835
836
static device_method_t tegra_usbphy_methods[] = {
837
/* Device interface */
838
DEVMETHOD(device_probe, usbphy_probe),
839
DEVMETHOD(device_attach, usbphy_attach),
840
DEVMETHOD(device_detach, usbphy_detach),
841
842
DEVMETHOD_END
843
};
844
845
static DEFINE_CLASS_0(usbphy, tegra_usbphy_driver, tegra_usbphy_methods,
846
sizeof(struct usbphy_softc));
847
EARLY_DRIVER_MODULE(tegra_usbphy, simplebus, tegra_usbphy_driver, NULL, NULL,
848
79);
849
850