xref: /aosp_15_r20/external/coreboot/src/soc/nvidia/tegra/usb.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <delay.h>
4 #include <device/mmio.h>
5 #include <console/console.h>
6 #include <soc/clock.h>
7 
8 #include "usb.h"
9 
10 struct utmip_ctlr {
11 	u32 pll0;
12 	u32 pll1;
13 	u32 xcvr0;
14 	u32 bias0;
15 	u32 hsrx0;
16 	u32 hsrx1;
17 	u32 fslsrx0;
18 	u32 fslsrx1;
19 	u32 tx;
20 	u32 misc0;
21 	u32 misc1;
22 	u32 debounce;
23 	u32 batchrgr;
24 	u32 spare;
25 	u32 xcvr1;
26 	u32 bias1;
27 	u32 bias_sts;
28 	u32 chrgr_debounce;
29 	u32 misc_sts;
30 	u32 pmc_wakeup;
31 };
32 check_member(utmip_ctlr, pmc_wakeup, 0x84c - 0x800);
33 
34 struct usb_ctlr {
35 	u32 id;
36 	u32 _rsv0;
37 	u32 host;
38 	u32 device;
39 	u32 txbuf;			/* 0x010 */
40 	u32 rxbuf;
41 	u32 _rsv1[58];
42 	u16 ehci_caplen;		/* 0x100 */
43 	u16 ehci_version;
44 	u32 ehci_hcsp;
45 	u32 ehci_hccp;
46 	u32 _rsv2[5];
47 	u32 dci_version;		/* 0x120 */
48 	u32 dcc_params;
49 	u32 extsts;
50 	u32 extintr;
51 	u32 ehci_usbcmd;		/* 0x130 */
52 	u32 ehci_usbsts;
53 	u32 ehci_usbintr;
54 	u32 ehci_frindex;
55 	u32 _rsv3;			/* 0x140 */
56 	u32 ehci_periodic_base;
57 	u32 ehci_async_base;
58 	u32 async_ttsts;
59 	u32 burst_size;			/* 0x150 */
60 	u32 tx_fill_tuning;
61 	u32 _rsv4;
62 	u32 icusb_ctrl;
63 	u32 ulpi_viewport;		/* 0x160 */
64 	u32 _rsv5[4];
65 	u32 ehci_portsc;
66 	u32 _rsv6[15];
67 	u32 lpm_ctrl;
68 	u32 _rsv7[15];
69 	u32 otgsc;
70 	u32 usb_mode;
71 	u32 _rsv8;
72 	u32 ep_nak;			/* 0x200 */
73 	u32 ep_nak_enable;
74 	u32 ep_setup;
75 	u32 ep_init;
76 	u32 ep_deinit;
77 	u32 ep_sts;
78 	u32 ep_complete;
79 	u32 ep_ctrl[16];
80 	u32 _rsv9[105];
81 	u32 suspend_ctrl;		/* 0x400 */
82 	u32 vbus_sensors;
83 	u32 vbus_wakeup_id;
84 	u32 alt_vbus_sts;
85 	u32 legacy_ctrl;
86 	u32 _rsv10[3];
87 	u32 interpacket_delay;
88 	u32 _rsv11[27];
89 	u32 resume_delay;
90 	u32 _rsv12;
91 	u32 spare;
92 	u32 _rsv13[9];
93 	u32 new_ctrl;
94 	u32 _rsv14[207];
95 	struct utmip_ctlr utmip;	/* 0x800 */
96 };
97 check_member(usb_ctlr, utmip, 0x800);
98 
99 /*
100  * Tegra EHCI controllers need their usb_mode, lpm_ctrl and tx_fill_tuning
101  * registers initialized after every EHCI reset and before any other actions
102  * (such as Run/Stop bit) are taken. We reset the controller here, set those
103  * registers and rely on the fact that libpayload doesn't reset EHCI controllers
104  * on initialization for whatever weird reason. This is ugly, fragile, and I
105  * really don't like it, but making this work will require an ugly hack one way
106  * or another so we might as well take the path of least resistance for now.
107  */
usb_ehci_reset_and_prepare(struct usb_ctlr * usb,enum usb_phy_type type)108 static void usb_ehci_reset_and_prepare(struct usb_ctlr *usb, enum usb_phy_type type)
109 {
110 	int timeout = 1000;
111 
112 	write32(&usb->ehci_usbcmd, 1 << 1);	/* Host Controller Reset */
113 	/* TODO: Resets are long, find way to parallelize... or just use XHCI */
114 	while (--timeout && (read32(&usb->ehci_usbcmd) & 1 << 1))
115 		/* wait for HC to reset */;
116 
117 	if (!timeout) {
118 		printk(BIOS_ERR, "EHCI(%p) reset timeout", usb);
119 		return;
120 	}
121 
122 	/* Controller mode: HOST */
123 	write32(&usb->usb_mode, 3 << 0);
124 	/* Parallel transceiver selct */
125 	write32(&usb->lpm_ctrl, type << 29);
126 	/* Tx FIFO Burst thresh */
127 	write32(&usb->tx_fill_tuning, 0x10 << 16);
128 }
129 
130 /* Assume USBx clocked, out of reset, UTMI+ PLL set up, SAMP_x out of pwrdn */
usb_setup_utmip(void * usb_base)131 void usb_setup_utmip(void *usb_base)
132 {
133 	struct usb_ctlr *usb = (struct usb_ctlr *)usb_base;
134 
135 	/* KHz formulas were guessed from U-Boot constants. Formats unclear. */
136 	int khz = clock_get_pll_input_khz();
137 
138 	/* Stop UTMI+ crystal clock while we mess with its settings */
139 	clrbits32(&usb->utmip.misc1, 1 << 30);	/* PHY_XTAL_CLKEN */
140 	udelay(1);
141 
142 	/* Take stuff out of pwrdn and add some magic numbers from U-Boot */
143 	write32(&usb->utmip.xcvr0,
144 		0x8 << 25 |		/* HS slew rate [10:4] */
145 		0x3 << 22 |		/* HS driver output 'SETUP' [6:4] */
146 		  0 << 21 |		/* LS bias selection */
147 		  0 << 18 |		/* PDZI pwrdn */
148 		  0 << 16 |		/* PD2 pwrdn */
149 		  0 << 14 |		/* PD pwrdn */
150 		  1 << 13 |		/* (rst) HS receiver terminations */
151 		0x1 << 10 |		/* (rst) LS falling slew rate */
152 		0x1 <<  8 |		/* (rst) LS rising slew rate */
153 		0x4 <<  0);		/* HS driver output 'SETUP' [3:0] */
154 	write32(&usb->utmip.xcvr1,
155 		0x7 << 18 |		/* Termination range adjustment */
156 		  0 <<  4 |		/* PDDR pwrdn */
157 		  0 <<  2 |		/* PDCHRP pwrdn */
158 		  0 <<  0);		/* PDDISC pwrdn */
159 	write32(&usb->utmip.tx,
160 		  1 << 19 |		/* FS send initial J before sync(?) */
161 		  1 << 16 |		/* (rst) Allow stuff error on SoP */
162 		  1 <<  9);		/* (rst) Check disc only on EoP */
163 	write32(&usb->utmip.hsrx0,
164 		0x2 << 30 |		/* (rst) Keep pattern on active */
165 		  1 << 28 |		/* (rst) Realign inertia on pkt */
166 		0x0 << 24 |		/* (rst) edges-1 to move sampling */
167 		0x3 << 21 |		/* (rst) squelch delay on EoP */
168 	       0x11 << 15 |		/* cycles until IDLE */
169 	       0x10 << 10);		/* elastic input depth */
170 
171 	/* U-Boot claims the USBD values for these are used across all UTMI+
172 	 * PHYs. That sounds so horribly wrong that I'm not going to implement
173 	 * it, but keep it in mind if we're ever not using the USBD port. */
174 	write32(&usb->utmip.bias0,
175 		0x1 << 24 |		/* HS disconnect detect level [2] */
176 		  1 << 23 |		/* (rst) IDPD value */
177 		  1 << 22 |		/* (rst) IDPD select */
178 		  1 << 11 |		/* (rst) OTG pwrdn */
179 		  0 << 10 |		/* bias pwrdn */
180 		0x1 <<  2 |		/* HS disconnect detect level [1:0] */
181 		0x2 <<  0);		/* HS squelch detect level */
182 
183 	write32(&usb->utmip.bias1,
184 		khz / 2200 << 3 |	/* bias pwrdn cycles (20us?) */
185 			 1 << 2 |	/* (rst) VBUS wakeup pwrdn */
186 			 0 << 0);	/* PDTRK pwrdn */
187 
188 	write32(&usb->utmip.debounce,
189 		       0xffff << 16 |	/* (rst) */
190 		25 * khz / 10 <<  0);	/* TODO: what's this, really? */
191 
192 	udelay(1);
193 	setbits32(&usb->utmip.misc1, 1 << 30); /* PHY_XTAL_CLKEN */
194 
195 	write32(&usb->suspend_ctrl,
196 		  1 << 12 |		/* UTMI+ enable */
197 		  0 << 11);		/* UTMI+ reset */
198 
199 	usb_ehci_reset_and_prepare(usb, USB_PHY_UTMIP);
200 	printk(BIOS_DEBUG, "USB controller @ %p set up with UTMI+ PHY\n",usb_base);
201 }
202