zynq_usb.c revision 1.1.10.2 1 1.1.10.2 martin /* $NetBSD: zynq_usb.c,v 1.1.10.2 2020/04/13 08:03:38 martin Exp $ */
2 1.1.10.2 martin
3 1.1.10.2 martin /*-
4 1.1.10.2 martin * Copyright (c) 2015 Genetec Corporation. All rights reserved.
5 1.1.10.2 martin * Written by Hashimoto Kenichi for Genetec Corporation.
6 1.1.10.2 martin *
7 1.1.10.2 martin * Redistribution and use in source and binary forms, with or without
8 1.1.10.2 martin * modification, are permitted provided that the following conditions
9 1.1.10.2 martin * are met:
10 1.1.10.2 martin * 1. Redistributions of source code must retain the above copyright
11 1.1.10.2 martin * notice, this list of conditions and the following disclaimer.
12 1.1.10.2 martin * 2. Redistributions in binary form must reproduce the above copyright
13 1.1.10.2 martin * notice, this list of conditions and the following disclaimer in the
14 1.1.10.2 martin * documentation and/or other materials provided with the distribution.
15 1.1.10.2 martin *
16 1.1.10.2 martin * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1.10.2 martin * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1.10.2 martin * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1.10.2 martin * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1.10.2 martin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1.10.2 martin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1.10.2 martin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1.10.2 martin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1.10.2 martin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1.10.2 martin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1.10.2 martin * POSSIBILITY OF SUCH DAMAGE.
27 1.1.10.2 martin */
28 1.1.10.2 martin
29 1.1.10.2 martin #include <sys/cdefs.h>
30 1.1.10.2 martin __KERNEL_RCSID(0, "$NetBSD: zynq_usb.c,v 1.1.10.2 2020/04/13 08:03:38 martin Exp $");
31 1.1.10.2 martin
32 1.1.10.2 martin #include "opt_soc.h"
33 1.1.10.2 martin
34 1.1.10.2 martin #include <sys/param.h>
35 1.1.10.2 martin #include <sys/bus.h>
36 1.1.10.2 martin #include <sys/conf.h>
37 1.1.10.2 martin #include <sys/device.h>
38 1.1.10.2 martin #include <sys/kernel.h>
39 1.1.10.2 martin #include <sys/intr.h>
40 1.1.10.2 martin #include <sys/systm.h>
41 1.1.10.2 martin
42 1.1.10.2 martin #include <dev/usb/usb.h>
43 1.1.10.2 martin #include <dev/usb/usbdi.h>
44 1.1.10.2 martin #include <dev/usb/usbdivar.h>
45 1.1.10.2 martin #include <dev/usb/usb_mem.h>
46 1.1.10.2 martin
47 1.1.10.2 martin #include <dev/usb/ehcireg.h>
48 1.1.10.2 martin #include <dev/usb/ehcivar.h>
49 1.1.10.2 martin #include <dev/usb/ulpireg.h>
50 1.1.10.2 martin
51 1.1.10.2 martin #include <arm/xilinx/zynq_usbreg.h>
52 1.1.10.2 martin #include <arm/xilinx/zynq_usbvar.h>
53 1.1.10.2 martin
54 1.1.10.2 martin #include "locators.h"
55 1.1.10.2 martin
56 1.1.10.2 martin static uint8_t ulpi_read(struct zynqehci_softc *sc, int addr);
57 1.1.10.2 martin static void ulpi_write(struct zynqehci_softc *sc, int addr, uint8_t data);
58 1.1.10.2 martin static void ulpi_reset(struct zynqehci_softc *sc);
59 1.1.10.2 martin
60 1.1.10.2 martin static void zynqusb_select_interface(struct zynqehci_softc *, enum zynq_usb_if);
61 1.1.10.2 martin static void zynqusb_init(struct ehci_softc *);
62 1.1.10.2 martin static void zynqusb_reset(struct zynqehci_softc *);
63 1.1.10.2 martin
64 1.1.10.2 martin void
65 1.1.10.2 martin zynqusb_attach_common(device_t parent, device_t self, bus_space_tag_t iot,
66 1.1.10.2 martin bus_dma_tag_t dmat, paddr_t iobase, size_t size, int flags,
67 1.1.10.2 martin enum zynq_usb_if type, enum zynq_usb_role role)
68 1.1.10.2 martin {
69 1.1.10.2 martin struct zynqehci_softc *sc = device_private(self);
70 1.1.10.2 martin ehci_softc_t *hsc = &sc->sc_hsc;
71 1.1.10.2 martin uint16_t hcirev;
72 1.1.10.2 martin uint32_t id, hwhost, hwdevice;
73 1.1.10.2 martin const char *comma;
74 1.1.10.2 martin
75 1.1.10.2 martin sc->sc_hsc.sc_dev = self;
76 1.1.10.2 martin sc->sc_iot = sc->sc_hsc.iot = iot;
77 1.1.10.2 martin sc->sc_iftype = type;
78 1.1.10.2 martin sc->sc_role = role;
79 1.1.10.2 martin
80 1.1.10.2 martin hsc->sc_bus.ub_hcpriv = sc;
81 1.1.10.2 martin hsc->sc_bus.ub_revision = USBREV_2_0;
82 1.1.10.2 martin hsc->sc_flags |= EHCIF_ETTF;
83 1.1.10.2 martin hsc->sc_vendor_init = zynqusb_init;
84 1.1.10.2 martin
85 1.1.10.2 martin aprint_normal("\n");
86 1.1.10.2 martin
87 1.1.10.2 martin if (bus_space_map(iot, iobase, size, 0, &sc->sc_ioh)) {
88 1.1.10.2 martin
89 1.1.10.2 martin aprint_error_dev(self, "unable to map device\n");
90 1.1.10.2 martin return;
91 1.1.10.2 martin }
92 1.1.10.2 martin
93 1.1.10.2 martin if (bus_space_subregion(iot, sc->sc_ioh,
94 1.1.10.2 martin ZYNQUSB_EHCIREGS, ZYNQUSB_EHCI_SIZE - ZYNQUSB_EHCIREGS,
95 1.1.10.2 martin &sc->sc_hsc.ioh)) {
96 1.1.10.2 martin
97 1.1.10.2 martin aprint_error_dev(self, "unable to map subregion\n");
98 1.1.10.2 martin return;
99 1.1.10.2 martin }
100 1.1.10.2 martin
101 1.1.10.2 martin id = bus_space_read_4(iot, sc->sc_ioh, ZYNQUSB_ID);
102 1.1.10.2 martin hcirev = bus_space_read_2(iot, sc->sc_hsc.ioh, EHCI_HCIVERSION);
103 1.1.10.2 martin
104 1.1.10.2 martin aprint_normal_dev(self,
105 1.1.10.2 martin "Zynq USB Controller id=%d revision=%d version=%d\n",
106 1.1.10.2 martin (int)__SHIFTOUT(id, ZYNQUSB_ID_ID),
107 1.1.10.2 martin (int)__SHIFTOUT(id, ZYNQUSB_ID_REVISION),
108 1.1.10.2 martin (int)__SHIFTOUT(id, ZYNQUSB_ID_VERSION));
109 1.1.10.2 martin aprint_normal_dev(self, "HCI revision=0x%x\n", hcirev);
110 1.1.10.2 martin
111 1.1.10.2 martin hwhost = bus_space_read_4(iot, sc->sc_ioh, ZYNQUSB_HWHOST);
112 1.1.10.2 martin hwdevice = bus_space_read_4(iot, sc->sc_ioh, ZYNQUSB_HWDEVICE);
113 1.1.10.2 martin
114 1.1.10.2 martin aprint_normal_dev(self, "");
115 1.1.10.2 martin
116 1.1.10.2 martin comma = "";
117 1.1.10.2 martin if (hwhost & HWHOST_HC) {
118 1.1.10.2 martin int n_ports = 1 + __SHIFTOUT(hwhost, HWHOST_NPORT);
119 1.1.10.2 martin aprint_normal("%d host port%s",
120 1.1.10.2 martin n_ports, n_ports > 1 ? "s" : "");
121 1.1.10.2 martin comma = ", ";
122 1.1.10.2 martin }
123 1.1.10.2 martin
124 1.1.10.2 martin if (hwdevice & HWDEVICE_DC) {
125 1.1.10.2 martin int n_endpoints = __SHIFTOUT(hwdevice, HWDEVICE_DEVEP);
126 1.1.10.2 martin aprint_normal("%sdevice capable, %d endpoint%s",
127 1.1.10.2 martin comma,
128 1.1.10.2 martin n_endpoints, n_endpoints > 1 ? "s" : "");
129 1.1.10.2 martin }
130 1.1.10.2 martin aprint_normal("\n");
131 1.1.10.2 martin
132 1.1.10.2 martin sc->sc_hsc.sc_bus.ub_dmatag = dmat;
133 1.1.10.2 martin
134 1.1.10.2 martin sc->sc_hsc.sc_offs = bus_space_read_1(iot, sc->sc_hsc.ioh,
135 1.1.10.2 martin EHCI_CAPLENGTH);
136 1.1.10.2 martin
137 1.1.10.2 martin zynqusb_reset(sc);
138 1.1.10.2 martin zynqusb_select_interface(sc, sc->sc_iftype);
139 1.1.10.2 martin
140 1.1.10.2 martin if (sc->sc_iftype == ZYNQUSBC_IF_ULPI) {
141 1.1.10.2 martin bus_space_write_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_ULPIVIEW, 0);
142 1.1.10.2 martin
143 1.1.10.2 martin aprint_normal_dev(hsc->sc_dev,
144 1.1.10.2 martin "ULPI phy VID 0x%04x PID 0x%04x\n",
145 1.1.10.2 martin (ulpi_read(sc, ULPI_VENDOR_ID_LOW) |
146 1.1.10.2 martin ulpi_read(sc, ULPI_VENDOR_ID_HIGH) << 8),
147 1.1.10.2 martin (ulpi_read(sc, ULPI_PRODUCT_ID_LOW) |
148 1.1.10.2 martin ulpi_read(sc, ULPI_PRODUCT_ID_HIGH) << 8));
149 1.1.10.2 martin
150 1.1.10.2 martin ulpi_reset(sc);
151 1.1.10.2 martin }
152 1.1.10.2 martin
153 1.1.10.2 martin if (sc->sc_iftype == ZYNQUSBC_IF_ULPI) {
154 1.1.10.2 martin if (hsc->sc_bus.ub_revision == USBREV_2_0) {
155 1.1.10.2 martin ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_CLEAR,
156 1.1.10.2 martin FUNCTION_CONTROL_XCVRSELECT);
157 1.1.10.2 martin ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_SET,
158 1.1.10.2 martin FUNCTION_CONTROL_TERMSELECT);
159 1.1.10.2 martin } else {
160 1.1.10.2 martin ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_SET,
161 1.1.10.2 martin XCVRSELECT_FSLS);
162 1.1.10.2 martin ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_CLEAR,
163 1.1.10.2 martin FUNCTION_CONTROL_TERMSELECT);
164 1.1.10.2 martin }
165 1.1.10.2 martin
166 1.1.10.2 martin ulpi_write(sc, ULPI_OTG_CONTROL + ULPI_REG_SET,
167 1.1.10.2 martin OTG_CONTROL_USEEXTVBUSIND |
168 1.1.10.2 martin OTG_CONTROL_DRVVBUSEXT |
169 1.1.10.2 martin OTG_CONTROL_DRVVBUS |
170 1.1.10.2 martin OTG_CONTROL_CHRGVBUS);
171 1.1.10.2 martin }
172 1.1.10.2 martin
173 1.1.10.2 martin /* Disable interrupts, so we don't get any spurious ones. */
174 1.1.10.2 martin EOWRITE4(hsc, EHCI_USBINTR, 0);
175 1.1.10.2 martin
176 1.1.10.2 martin /*intr_establish(intr, IPL_USB, IST_LEVEL, ehci_intr, hsc);*/
177 1.1.10.2 martin
178 1.1.10.2 martin int err = ehci_init(hsc);
179 1.1.10.2 martin if (err) {
180 1.1.10.2 martin aprint_error_dev(self, "init failed, error = %d\n", err);
181 1.1.10.2 martin return;
182 1.1.10.2 martin }
183 1.1.10.2 martin
184 1.1.10.2 martin /* Attach usb device. */
185 1.1.10.2 martin hsc->sc_child = config_found(self, &hsc->sc_bus, usbctlprint);
186 1.1.10.2 martin }
187 1.1.10.2 martin
188 1.1.10.2 martin static void
189 1.1.10.2 martin zynqusb_select_interface(struct zynqehci_softc *sc, enum zynq_usb_if interface)
190 1.1.10.2 martin {
191 1.1.10.2 martin uint32_t reg;
192 1.1.10.2 martin struct ehci_softc *hsc = &sc->sc_hsc;
193 1.1.10.2 martin
194 1.1.10.2 martin reg = EOREAD4(hsc, EHCI_PORTSC(1));
195 1.1.10.2 martin reg &= ~(PORTSC_PTS | PORTSC_PTW);
196 1.1.10.2 martin switch (interface) {
197 1.1.10.2 martin case ZYNQUSBC_IF_UTMI_WIDE:
198 1.1.10.2 martin reg |= PORTSC_PTW_16;
199 1.1.10.2 martin case ZYNQUSBC_IF_UTMI:
200 1.1.10.2 martin reg |= PORTSC_PTS_UTMI;
201 1.1.10.2 martin break;
202 1.1.10.2 martin case ZYNQUSBC_IF_PHILIPS:
203 1.1.10.2 martin reg |= PORTSC_PTS_PHILIPS;
204 1.1.10.2 martin break;
205 1.1.10.2 martin case ZYNQUSBC_IF_ULPI:
206 1.1.10.2 martin reg |= PORTSC_PTS_ULPI;
207 1.1.10.2 martin break;
208 1.1.10.2 martin case ZYNQUSBC_IF_SERIAL:
209 1.1.10.2 martin reg |= PORTSC_PTS_SERIAL;
210 1.1.10.2 martin break;
211 1.1.10.2 martin }
212 1.1.10.2 martin EOWRITE4(hsc, EHCI_PORTSC(1), reg);
213 1.1.10.2 martin }
214 1.1.10.2 martin
215 1.1.10.2 martin static uint32_t
216 1.1.10.2 martin ulpi_wakeup(struct zynqehci_softc *sc, int tout)
217 1.1.10.2 martin {
218 1.1.10.2 martin uint32_t ulpi_view;
219 1.1.10.2 martin int i = 0;
220 1.1.10.2 martin ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_ULPIVIEW);
221 1.1.10.2 martin
222 1.1.10.2 martin if ( !(ulpi_view & ULPI_SS) ) {
223 1.1.10.2 martin bus_space_write_4(sc->sc_iot, sc->sc_ioh,
224 1.1.10.2 martin ZYNQUSB_ULPIVIEW, ULPI_WU);
225 1.1.10.2 martin for (i = 0; (tout < 0) || (i < tout); i++) {
226 1.1.10.2 martin ulpi_view = bus_space_read_4(sc->sc_iot,
227 1.1.10.2 martin sc->sc_ioh, ZYNQUSB_ULPIVIEW);
228 1.1.10.2 martin if ( !(ulpi_view & ULPI_WU) )
229 1.1.10.2 martin break;
230 1.1.10.2 martin delay(1);
231 1.1.10.2 martin };
232 1.1.10.2 martin }
233 1.1.10.2 martin
234 1.1.10.2 martin if ((tout > 0) && (i >= tout)) {
235 1.1.10.2 martin aprint_error_dev(sc->sc_hsc.sc_dev, "%s: timeout\n", __func__);
236 1.1.10.2 martin }
237 1.1.10.2 martin
238 1.1.10.2 martin return ulpi_view;
239 1.1.10.2 martin }
240 1.1.10.2 martin
241 1.1.10.2 martin static uint32_t
242 1.1.10.2 martin ulpi_wait(struct zynqehci_softc *sc, int tout)
243 1.1.10.2 martin {
244 1.1.10.2 martin uint32_t ulpi_view;
245 1.1.10.2 martin int i;
246 1.1.10.2 martin ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_ULPIVIEW);
247 1.1.10.2 martin
248 1.1.10.2 martin for (i = 0; (tout < 0) | (i < tout); i++) {
249 1.1.10.2 martin ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
250 1.1.10.2 martin ZYNQUSB_ULPIVIEW);
251 1.1.10.2 martin if (!(ulpi_view & ULPI_RUN))
252 1.1.10.2 martin break;
253 1.1.10.2 martin delay(1);
254 1.1.10.2 martin }
255 1.1.10.2 martin
256 1.1.10.2 martin if ((tout > 0) && (i >= tout)) {
257 1.1.10.2 martin aprint_error_dev(sc->sc_hsc.sc_dev, "%s: timeout\n", __func__);
258 1.1.10.2 martin }
259 1.1.10.2 martin
260 1.1.10.2 martin return ulpi_view;
261 1.1.10.2 martin }
262 1.1.10.2 martin
263 1.1.10.2 martin #define TIMEOUT 100000
264 1.1.10.2 martin
265 1.1.10.2 martin static uint8_t
266 1.1.10.2 martin ulpi_read(struct zynqehci_softc *sc, int addr)
267 1.1.10.2 martin {
268 1.1.10.2 martin uint32_t data;
269 1.1.10.2 martin
270 1.1.10.2 martin ulpi_wakeup(sc, TIMEOUT);
271 1.1.10.2 martin
272 1.1.10.2 martin data = ULPI_RUN | __SHIFTIN(addr, ULPI_ADDR);
273 1.1.10.2 martin bus_space_write_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_ULPIVIEW, data);
274 1.1.10.2 martin
275 1.1.10.2 martin data = ulpi_wait(sc, TIMEOUT);
276 1.1.10.2 martin
277 1.1.10.2 martin return __SHIFTOUT(data, ULPI_DATRD);
278 1.1.10.2 martin }
279 1.1.10.2 martin
280 1.1.10.2 martin static void
281 1.1.10.2 martin ulpi_write(struct zynqehci_softc *sc, int addr, uint8_t data)
282 1.1.10.2 martin {
283 1.1.10.2 martin uint32_t reg;
284 1.1.10.2 martin
285 1.1.10.2 martin ulpi_wakeup(sc, TIMEOUT);
286 1.1.10.2 martin
287 1.1.10.2 martin reg = ULPI_RUN | ULPI_RW | __SHIFTIN(addr, ULPI_ADDR) | __SHIFTIN(data, ULPI_DATWR);
288 1.1.10.2 martin bus_space_write_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_ULPIVIEW, reg);
289 1.1.10.2 martin
290 1.1.10.2 martin ulpi_wait(sc, TIMEOUT);
291 1.1.10.2 martin
292 1.1.10.2 martin return;
293 1.1.10.2 martin }
294 1.1.10.2 martin
295 1.1.10.2 martin static void
296 1.1.10.2 martin ulpi_reset(struct zynqehci_softc *sc)
297 1.1.10.2 martin {
298 1.1.10.2 martin uint8_t data;
299 1.1.10.2 martin int timo = 1000 * 1000; /* XXXX: 1sec */
300 1.1.10.2 martin
301 1.1.10.2 martin ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_SET,
302 1.1.10.2 martin FUNCTION_CONTROL_RESET /*0x20*/);
303 1.1.10.2 martin do {
304 1.1.10.2 martin data = ulpi_read(sc, ULPI_FUNCTION_CONTROL);
305 1.1.10.2 martin if (!(data & FUNCTION_CONTROL_RESET))
306 1.1.10.2 martin break;
307 1.1.10.2 martin delay(100);
308 1.1.10.2 martin timo -= 100;
309 1.1.10.2 martin } while (timo > 0);
310 1.1.10.2 martin if (timo <= 0) {
311 1.1.10.2 martin aprint_error_dev(sc->sc_hsc.sc_dev, "%s: reset failed!!\n",
312 1.1.10.2 martin __func__);
313 1.1.10.2 martin return;
314 1.1.10.2 martin }
315 1.1.10.2 martin
316 1.1.10.2 martin return;
317 1.1.10.2 martin }
318 1.1.10.2 martin
319 1.1.10.2 martin static void
320 1.1.10.2 martin zynqusb_reset(struct zynqehci_softc *sc)
321 1.1.10.2 martin {
322 1.1.10.2 martin uint32_t reg;
323 1.1.10.2 martin int i;
324 1.1.10.2 martin struct ehci_softc *hsc = &sc->sc_hsc;
325 1.1.10.2 martin #define RESET_TIMEOUT 100
326 1.1.10.2 martin reg = EOREAD4(hsc, EHCI_USBCMD);
327 1.1.10.2 martin reg &= ~EHCI_CMD_RS;
328 1.1.10.2 martin EOWRITE4(hsc, EHCI_USBCMD, reg);
329 1.1.10.2 martin
330 1.1.10.2 martin for (i=0; i < RESET_TIMEOUT; ++i) {
331 1.1.10.2 martin reg = EOREAD4(hsc, EHCI_USBCMD);
332 1.1.10.2 martin if ((reg & EHCI_CMD_RS) == 0)
333 1.1.10.2 martin break;
334 1.1.10.2 martin usb_delay_ms(&hsc->sc_bus, 1);
335 1.1.10.2 martin }
336 1.1.10.2 martin
337 1.1.10.2 martin EOWRITE4(hsc, EHCI_USBCMD, reg | EHCI_CMD_HCRESET);
338 1.1.10.2 martin for (i = 0; i < RESET_TIMEOUT; i++) {
339 1.1.10.2 martin reg = EOREAD4(hsc, EHCI_USBCMD);
340 1.1.10.2 martin if ((reg & EHCI_CMD_HCRESET) == 0)
341 1.1.10.2 martin break;
342 1.1.10.2 martin usb_delay_ms(&hsc->sc_bus, 1);
343 1.1.10.2 martin }
344 1.1.10.2 martin if (i >= RESET_TIMEOUT) {
345 1.1.10.2 martin aprint_error_dev(hsc->sc_dev, "reset timeout (%x)\n", reg);
346 1.1.10.2 martin }
347 1.1.10.2 martin
348 1.1.10.2 martin usb_delay_ms(&hsc->sc_bus, 100);
349 1.1.10.2 martin }
350 1.1.10.2 martin
351 1.1.10.2 martin static void
352 1.1.10.2 martin zynqusb_init(struct ehci_softc *hsc)
353 1.1.10.2 martin {
354 1.1.10.2 martin struct zynqehci_softc *sc = device_private(hsc->sc_dev);
355 1.1.10.2 martin uint32_t reg;
356 1.1.10.2 martin
357 1.1.10.2 martin reg = EOREAD4(hsc, EHCI_PORTSC(1));
358 1.1.10.2 martin reg &= ~(EHCI_PS_CSC | EHCI_PS_PEC | EHCI_PS_OCC);
359 1.1.10.2 martin reg |= EHCI_PS_PP | EHCI_PS_PE;
360 1.1.10.2 martin EOWRITE4(hsc, EHCI_PORTSC(1), reg);
361 1.1.10.2 martin
362 1.1.10.2 martin reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_OTGSC);
363 1.1.10.2 martin reg |= OTGSC_IDPU;
364 1.1.10.2 martin reg |= OTGSC_DPIE | OTGSC_IDIE;
365 1.1.10.2 martin bus_space_write_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_OTGSC, reg);
366 1.1.10.2 martin
367 1.1.10.2 martin reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_USBMODE);
368 1.1.10.2 martin reg &= ~USBMODE_CM;
369 1.1.10.2 martin reg |= USBMODE_CM_HOST;
370 1.1.10.2 martin bus_space_write_4(sc->sc_iot, sc->sc_ioh, ZYNQUSB_USBMODE, reg);
371 1.1.10.2 martin }
372