blob: adcd319b6d0b865f57a2201716603cd03d9f1756 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Thomas Abraham38f424f2009-01-04 09:41:03 +05302/*
3 * Mentor USB OTG Core host controller driver.
4 *
5 * Copyright (c) 2008 Texas Instruments
6 *
Thomas Abraham38f424f2009-01-04 09:41:03 +05307 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
8 */
9
10#include <common.h>
Ilya Yanoka1cf10f2012-11-06 13:48:20 +000011#include <usb.h>
Thomas Abraham38f424f2009-01-04 09:41:03 +053012#include "musb_hcd.h"
13
14/* MSC control transfers */
15#define USB_MSC_BBB_RESET 0xFF
16#define USB_MSC_BBB_GET_MAX_LUN 0xFE
17
18/* Endpoint configuration information */
Mike Frysinger671bc3d2010-10-20 07:15:35 -040019static const struct musb_epinfo epinfo[3] = {
Thomas Abraham38f424f2009-01-04 09:41:03 +053020 {MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */
21 {MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In - 512 Bytes */
22 {MUSB_INTR_EP, 0, 64} /* EP2 - Interrupt IN - 64 Bytes */
23};
24
Bryan Wu73073cc2010-01-09 16:53:54 -050025/* --- Virtual Root Hub ---------------------------------------------------- */
26#ifdef MUSB_NO_MULTIPOINT
27static int rh_devnum;
28static u32 port_status;
29
Stephen Warren39c89682014-02-13 21:15:18 -070030#include <usbroothubdes.h>
Bryan Wu73073cc2010-01-09 16:53:54 -050031
Bryan Wu73073cc2010-01-09 16:53:54 -050032#endif
33
Thomas Abraham38f424f2009-01-04 09:41:03 +053034/*
35 * This function writes the data toggle value.
36 */
37static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out)
38{
39 u16 toggle = usb_gettoggle(dev, ep, dir_out);
40 u16 csr;
41
42 if (dir_out) {
Bryan Wufe439d22010-08-09 14:58:24 -040043 csr = readw(&musbr->txcsr);
44 if (!toggle) {
45 if (csr & MUSB_TXCSR_MODE)
46 csr = MUSB_TXCSR_CLRDATATOG;
47 else
48 csr = 0;
49 writew(csr, &musbr->txcsr);
50 } else {
Thomas Abraham38f424f2009-01-04 09:41:03 +053051 csr |= MUSB_TXCSR_H_WR_DATATOGGLE;
52 writew(csr, &musbr->txcsr);
53 csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT);
54 writew(csr, &musbr->txcsr);
55 }
56 } else {
Bryan Wufe439d22010-08-09 14:58:24 -040057 if (!toggle) {
58 csr = readw(&musbr->txcsr);
59 if (csr & MUSB_TXCSR_MODE)
60 csr = MUSB_RXCSR_CLRDATATOG;
61 else
62 csr = 0;
63 writew(csr, &musbr->rxcsr);
64 } else {
Thomas Abraham38f424f2009-01-04 09:41:03 +053065 csr = readw(&musbr->rxcsr);
66 csr |= MUSB_RXCSR_H_WR_DATATOGGLE;
67 writew(csr, &musbr->rxcsr);
68 csr |= (toggle << MUSB_S_RXCSR_H_DATATOGGLE);
69 writew(csr, &musbr->rxcsr);
70 }
71 }
72}
73
74/*
Vagrant Cascadianedfdb992016-04-30 19:18:00 -070075 * This function checks if RxStall has occurred on the endpoint. If a RxStall
76 * has occurred, the RxStall is cleared and 1 is returned. If RxStall has
77 * not occurred, 0 is returned.
Thomas Abraham38f424f2009-01-04 09:41:03 +053078 */
79static u8 check_stall(u8 ep, u8 dir_out)
80{
81 u16 csr;
82
83 /* For endpoint 0 */
84 if (!ep) {
85 csr = readw(&musbr->txcsr);
86 if (csr & MUSB_CSR0_H_RXSTALL) {
87 csr &= ~MUSB_CSR0_H_RXSTALL;
88 writew(csr, &musbr->txcsr);
89 return 1;
90 }
91 } else { /* For non-ep0 */
92 if (dir_out) { /* is it tx ep */
93 csr = readw(&musbr->txcsr);
94 if (csr & MUSB_TXCSR_H_RXSTALL) {
95 csr &= ~MUSB_TXCSR_H_RXSTALL;
96 writew(csr, &musbr->txcsr);
97 return 1;
98 }
99 } else { /* is it rx ep */
100 csr = readw(&musbr->rxcsr);
101 if (csr & MUSB_RXCSR_H_RXSTALL) {
102 csr &= ~MUSB_RXCSR_H_RXSTALL;
103 writew(csr, &musbr->rxcsr);
104 return 1;
105 }
106 }
107 }
108 return 0;
109}
110
111/*
112 * waits until ep0 is ready. Returns 0 if ep is ready, -1 for timeout
113 * error and -2 for stall.
114 */
115static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
116{
117 u16 csr;
118 int result = 1;
Paul Kocialkowskif34dfcb2015-08-04 17:04:06 +0200119 int timeout = CONFIG_USB_MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530120
121 while (result > 0) {
122 csr = readw(&musbr->txcsr);
123 if (csr & MUSB_CSR0_H_ERROR) {
124 csr &= ~MUSB_CSR0_H_ERROR;
125 writew(csr, &musbr->txcsr);
126 dev->status = USB_ST_CRC_ERR;
127 result = -1;
128 break;
129 }
130
131 switch (bit_mask) {
132 case MUSB_CSR0_TXPKTRDY:
133 if (!(csr & MUSB_CSR0_TXPKTRDY)) {
134 if (check_stall(MUSB_CONTROL_EP, 0)) {
135 dev->status = USB_ST_STALLED;
136 result = -2;
137 } else
138 result = 0;
139 }
140 break;
141
142 case MUSB_CSR0_RXPKTRDY:
143 if (check_stall(MUSB_CONTROL_EP, 0)) {
144 dev->status = USB_ST_STALLED;
145 result = -2;
146 } else
147 if (csr & MUSB_CSR0_RXPKTRDY)
148 result = 0;
149 break;
150
151 case MUSB_CSR0_H_REQPKT:
152 if (!(csr & MUSB_CSR0_H_REQPKT)) {
153 if (check_stall(MUSB_CONTROL_EP, 0)) {
154 dev->status = USB_ST_STALLED;
155 result = -2;
156 } else
157 result = 0;
158 }
159 break;
160 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400161
162 /* Check the timeout */
163 if (--timeout)
164 udelay(1);
165 else {
166 dev->status = USB_ST_CRC_ERR;
167 result = -1;
168 break;
169 }
Thomas Abraham38f424f2009-01-04 09:41:03 +0530170 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400171
Thomas Abraham38f424f2009-01-04 09:41:03 +0530172 return result;
173}
174
175/*
176 * waits until tx ep is ready. Returns 1 when ep is ready and 0 on error.
177 */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100178static int wait_until_txep_ready(struct usb_device *dev, u8 ep)
Thomas Abraham38f424f2009-01-04 09:41:03 +0530179{
180 u16 csr;
Paul Kocialkowskif34dfcb2015-08-04 17:04:06 +0200181 int timeout = CONFIG_USB_MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530182
183 do {
184 if (check_stall(ep, 1)) {
185 dev->status = USB_ST_STALLED;
186 return 0;
187 }
188
189 csr = readw(&musbr->txcsr);
190 if (csr & MUSB_TXCSR_H_ERROR) {
191 dev->status = USB_ST_CRC_ERR;
192 return 0;
193 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400194
195 /* Check the timeout */
196 if (--timeout)
197 udelay(1);
198 else {
199 dev->status = USB_ST_CRC_ERR;
200 return -1;
201 }
202
Thomas Abraham38f424f2009-01-04 09:41:03 +0530203 } while (csr & MUSB_TXCSR_TXPKTRDY);
204 return 1;
205}
206
207/*
208 * waits until rx ep is ready. Returns 1 when ep is ready and 0 on error.
209 */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100210static int wait_until_rxep_ready(struct usb_device *dev, u8 ep)
Thomas Abraham38f424f2009-01-04 09:41:03 +0530211{
212 u16 csr;
Paul Kocialkowskif34dfcb2015-08-04 17:04:06 +0200213 int timeout = CONFIG_USB_MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530214
215 do {
216 if (check_stall(ep, 0)) {
217 dev->status = USB_ST_STALLED;
218 return 0;
219 }
220
221 csr = readw(&musbr->rxcsr);
222 if (csr & MUSB_RXCSR_H_ERROR) {
223 dev->status = USB_ST_CRC_ERR;
224 return 0;
225 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400226
227 /* Check the timeout */
228 if (--timeout)
229 udelay(1);
230 else {
231 dev->status = USB_ST_CRC_ERR;
232 return -1;
233 }
234
Thomas Abraham38f424f2009-01-04 09:41:03 +0530235 } while (!(csr & MUSB_RXCSR_RXPKTRDY));
236 return 1;
237}
238
239/*
240 * This function performs the setup phase of the control transfer
241 */
242static int ctrlreq_setup_phase(struct usb_device *dev, struct devrequest *setup)
243{
244 int result;
245 u16 csr;
246
247 /* write the control request to ep0 fifo */
248 write_fifo(MUSB_CONTROL_EP, sizeof(struct devrequest), (void *)setup);
249
250 /* enable transfer of setup packet */
251 csr = readw(&musbr->txcsr);
252 csr |= (MUSB_CSR0_TXPKTRDY|MUSB_CSR0_H_SETUPPKT);
253 writew(csr, &musbr->txcsr);
254
255 /* wait until the setup packet is transmitted */
256 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
257 dev->act_len = 0;
258 return result;
259}
260
261/*
262 * This function handles the control transfer in data phase
263 */
264static int ctrlreq_in_data_phase(struct usb_device *dev, u32 len, void *buffer)
265{
266 u16 csr;
267 u32 rxlen = 0;
268 u32 nextlen = 0;
269 u8 maxpktsize = (1 << dev->maxpacketsize) * 8;
270 u8 *rxbuff = (u8 *)buffer;
271 u8 rxedlength;
272 int result;
273
274 while (rxlen < len) {
275 /* Determine the next read length */
276 nextlen = ((len-rxlen) > maxpktsize) ? maxpktsize : (len-rxlen);
277
278 /* Set the ReqPkt bit */
279 csr = readw(&musbr->txcsr);
280 writew(csr | MUSB_CSR0_H_REQPKT, &musbr->txcsr);
281 result = wait_until_ep0_ready(dev, MUSB_CSR0_RXPKTRDY);
282 if (result < 0)
283 return result;
284
285 /* Actual number of bytes received by usb */
286 rxedlength = readb(&musbr->rxcount);
287
288 /* Read the data from the RxFIFO */
289 read_fifo(MUSB_CONTROL_EP, rxedlength, &rxbuff[rxlen]);
290
291 /* Clear the RxPktRdy Bit */
292 csr = readw(&musbr->txcsr);
293 csr &= ~MUSB_CSR0_RXPKTRDY;
294 writew(csr, &musbr->txcsr);
295
296 /* short packet? */
297 if (rxedlength != nextlen) {
298 dev->act_len += rxedlength;
299 break;
300 }
301 rxlen += nextlen;
302 dev->act_len = rxlen;
303 }
304 return 0;
305}
306
307/*
308 * This function handles the control transfer out data phase
309 */
310static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
311{
312 u16 csr;
313 u32 txlen = 0;
314 u32 nextlen = 0;
315 u8 maxpktsize = (1 << dev->maxpacketsize) * 8;
316 u8 *txbuff = (u8 *)buffer;
317 int result = 0;
318
319 while (txlen < len) {
320 /* Determine the next write length */
321 nextlen = ((len-txlen) > maxpktsize) ? maxpktsize : (len-txlen);
322
323 /* Load the data to send in FIFO */
324 write_fifo(MUSB_CONTROL_EP, txlen, &txbuff[txlen]);
325
326 /* Set TXPKTRDY bit */
327 csr = readw(&musbr->txcsr);
Andrew Murray98529262013-09-29 18:02:22 +0100328
329 csr |= MUSB_CSR0_TXPKTRDY;
Andrew Murray98529262013-09-29 18:02:22 +0100330 csr |= MUSB_CSR0_H_DIS_PING;
Andrew Murray98529262013-09-29 18:02:22 +0100331 writew(csr, &musbr->txcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530332 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
333 if (result < 0)
334 break;
335
336 txlen += nextlen;
337 dev->act_len = txlen;
338 }
339 return result;
340}
341
342/*
343 * This function handles the control transfer out status phase
344 */
345static int ctrlreq_out_status_phase(struct usb_device *dev)
346{
347 u16 csr;
348 int result;
349
350 /* Set the StatusPkt bit */
351 csr = readw(&musbr->txcsr);
Andrew Murray98529262013-09-29 18:02:22 +0100352 csr |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_H_STATUSPKT);
Andrew Murray98529262013-09-29 18:02:22 +0100353 csr |= MUSB_CSR0_H_DIS_PING;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530354 writew(csr, &musbr->txcsr);
355
356 /* Wait until TXPKTRDY bit is cleared */
357 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
358 return result;
359}
360
361/*
362 * This function handles the control transfer in status phase
363 */
364static int ctrlreq_in_status_phase(struct usb_device *dev)
365{
366 u16 csr;
367 int result;
368
369 /* Set the StatusPkt bit and ReqPkt bit */
Andrew Murray98529262013-09-29 18:02:22 +0100370 csr = MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
Andrew Murray98529262013-09-29 18:02:22 +0100371 csr |= MUSB_CSR0_H_DIS_PING;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530372 writew(csr, &musbr->txcsr);
373 result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);
374
375 /* clear StatusPkt bit and RxPktRdy bit */
376 csr = readw(&musbr->txcsr);
377 csr &= ~(MUSB_CSR0_RXPKTRDY | MUSB_CSR0_H_STATUSPKT);
378 writew(csr, &musbr->txcsr);
379 return result;
380}
381
382/*
383 * determines the speed of the device (High/Full/Slow)
384 */
385static u8 get_dev_speed(struct usb_device *dev)
386{
Ilya Yanoka1cf10f2012-11-06 13:48:20 +0000387 return (dev->speed == USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
388 ((dev->speed == USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
Thomas Abraham38f424f2009-01-04 09:41:03 +0530389 MUSB_TYPE_SPEED_FULL);
390}
391
392/*
393 * configure the hub address and the port address.
394 */
395static void config_hub_port(struct usb_device *dev, u8 ep)
396{
397 u8 chid;
398 u8 hub;
399
400 /* Find out the nearest parent which is high speed */
401 while (dev->parent->parent != NULL)
402 if (get_dev_speed(dev->parent) != MUSB_TYPE_SPEED_HIGH)
403 dev = dev->parent;
404 else
405 break;
406
407 /* determine the port address at that hub */
408 hub = dev->parent->devnum;
409 for (chid = 0; chid < USB_MAXCHILDREN; chid++)
410 if (dev->parent->children[chid] == dev)
411 break;
412
Bryan Wu784f1382009-12-16 22:04:00 -0500413#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530414 /* configure the hub address and the port address */
415 writeb(hub, &musbr->tar[ep].txhubaddr);
416 writeb((chid + 1), &musbr->tar[ep].txhubport);
417 writeb(hub, &musbr->tar[ep].rxhubaddr);
418 writeb((chid + 1), &musbr->tar[ep].rxhubport);
Bryan Wu784f1382009-12-16 22:04:00 -0500419#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530420}
421
Bryan Wu73073cc2010-01-09 16:53:54 -0500422#ifdef MUSB_NO_MULTIPOINT
423
424static void musb_port_reset(int do_reset)
425{
426 u8 power = readb(&musbr->power);
427
428 if (do_reset) {
429 power &= 0xf0;
430 writeb(power | MUSB_POWER_RESET, &musbr->power);
431 port_status |= USB_PORT_STAT_RESET;
432 port_status &= ~USB_PORT_STAT_ENABLE;
433 udelay(30000);
434 } else {
435 writeb(power & ~MUSB_POWER_RESET, &musbr->power);
436
437 power = readb(&musbr->power);
438 if (power & MUSB_POWER_HSMODE)
439 port_status |= USB_PORT_STAT_HIGH_SPEED;
440
441 port_status &= ~(USB_PORT_STAT_RESET | (USB_PORT_STAT_C_CONNECTION << 16));
442 port_status |= USB_PORT_STAT_ENABLE
443 | (USB_PORT_STAT_C_RESET << 16)
444 | (USB_PORT_STAT_C_ENABLE << 16);
445 }
446}
447
Thomas Abraham38f424f2009-01-04 09:41:03 +0530448/*
Bryan Wu73073cc2010-01-09 16:53:54 -0500449 * root hub control
450 */
451static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
452 void *buffer, int transfer_len,
453 struct devrequest *cmd)
454{
455 int leni = transfer_len;
456 int len = 0;
457 int stat = 0;
458 u32 datab[4];
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400459 const u8 *data_buf = (u8 *) datab;
Bryan Wu73073cc2010-01-09 16:53:54 -0500460 u16 bmRType_bReq;
461 u16 wValue;
462 u16 wIndex;
463 u16 wLength;
464 u16 int_usb;
465
466 if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
467 debug("Root-Hub submit IRQ: NOT implemented\n");
468 return 0;
469 }
470
471 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
472 wValue = swap_16(cmd->value);
473 wIndex = swap_16(cmd->index);
474 wLength = swap_16(cmd->length);
475
476 debug("--- HUB ----------------------------------------\n");
477 debug("submit rh urb, req=%x val=%#x index=%#x len=%d\n",
478 bmRType_bReq, wValue, wIndex, wLength);
479 debug("------------------------------------------------\n");
480
481 switch (bmRType_bReq) {
482 case RH_GET_STATUS:
483 debug("RH_GET_STATUS\n");
484
485 *(__u16 *) data_buf = swap_16(1);
486 len = 2;
487 break;
488
489 case RH_GET_STATUS | RH_INTERFACE:
490 debug("RH_GET_STATUS | RH_INTERFACE\n");
491
492 *(__u16 *) data_buf = swap_16(0);
493 len = 2;
494 break;
495
496 case RH_GET_STATUS | RH_ENDPOINT:
497 debug("RH_GET_STATUS | RH_ENDPOINT\n");
498
499 *(__u16 *) data_buf = swap_16(0);
500 len = 2;
501 break;
502
503 case RH_GET_STATUS | RH_CLASS:
504 debug("RH_GET_STATUS | RH_CLASS\n");
505
506 *(__u32 *) data_buf = swap_32(0);
507 len = 4;
508 break;
509
510 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
511 debug("RH_GET_STATUS | RH_OTHER | RH_CLASS\n");
512
513 int_usb = readw(&musbr->intrusb);
514 if (int_usb & MUSB_INTR_CONNECT) {
515 port_status |= USB_PORT_STAT_CONNECTION
516 | (USB_PORT_STAT_C_CONNECTION << 16);
517 port_status |= USB_PORT_STAT_HIGH_SPEED
518 | USB_PORT_STAT_ENABLE;
519 }
520
521 if (port_status & USB_PORT_STAT_RESET)
522 musb_port_reset(0);
523
524 *(__u32 *) data_buf = swap_32(port_status);
525 len = 4;
526 break;
527
528 case RH_CLEAR_FEATURE | RH_ENDPOINT:
529 debug("RH_CLEAR_FEATURE | RH_ENDPOINT\n");
530
531 switch (wValue) {
532 case RH_ENDPOINT_STALL:
533 debug("C_HUB_ENDPOINT_STALL\n");
534 len = 0;
535 break;
536 }
537 port_status &= ~(1 << wValue);
538 break;
539
540 case RH_CLEAR_FEATURE | RH_CLASS:
541 debug("RH_CLEAR_FEATURE | RH_CLASS\n");
542
543 switch (wValue) {
544 case RH_C_HUB_LOCAL_POWER:
545 debug("C_HUB_LOCAL_POWER\n");
546 len = 0;
547 break;
548
549 case RH_C_HUB_OVER_CURRENT:
550 debug("C_HUB_OVER_CURRENT\n");
551 len = 0;
552 break;
553 }
554 port_status &= ~(1 << wValue);
555 break;
556
557 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
558 debug("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS\n");
559
560 switch (wValue) {
561 case RH_PORT_ENABLE:
562 len = 0;
563 break;
564
565 case RH_PORT_SUSPEND:
566 len = 0;
567 break;
568
569 case RH_PORT_POWER:
570 len = 0;
571 break;
572
573 case RH_C_PORT_CONNECTION:
574 len = 0;
575 break;
576
577 case RH_C_PORT_ENABLE:
578 len = 0;
579 break;
580
581 case RH_C_PORT_SUSPEND:
582 len = 0;
583 break;
584
585 case RH_C_PORT_OVER_CURRENT:
586 len = 0;
587 break;
588
589 case RH_C_PORT_RESET:
590 len = 0;
591 break;
592
593 default:
594 debug("invalid wValue\n");
595 stat = USB_ST_STALLED;
596 }
597
598 port_status &= ~(1 << wValue);
599 break;
600
601 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
602 debug("RH_SET_FEATURE | RH_OTHER | RH_CLASS\n");
603
604 switch (wValue) {
605 case RH_PORT_SUSPEND:
606 len = 0;
607 break;
608
609 case RH_PORT_RESET:
610 musb_port_reset(1);
611 len = 0;
612 break;
613
614 case RH_PORT_POWER:
615 len = 0;
616 break;
617
618 case RH_PORT_ENABLE:
619 len = 0;
620 break;
621
622 default:
623 debug("invalid wValue\n");
624 stat = USB_ST_STALLED;
625 }
626
627 port_status |= 1 << wValue;
628 break;
629
630 case RH_SET_ADDRESS:
631 debug("RH_SET_ADDRESS\n");
632
633 rh_devnum = wValue;
634 len = 0;
635 break;
636
637 case RH_GET_DESCRIPTOR:
638 debug("RH_GET_DESCRIPTOR: %x, %d\n", wValue, wLength);
639
640 switch (wValue) {
641 case (USB_DT_DEVICE << 8): /* device descriptor */
642 len = min_t(unsigned int,
643 leni, min_t(unsigned int,
644 sizeof(root_hub_dev_des),
645 wLength));
646 data_buf = root_hub_dev_des;
647 break;
648
649 case (USB_DT_CONFIG << 8): /* configuration descriptor */
650 len = min_t(unsigned int,
651 leni, min_t(unsigned int,
652 sizeof(root_hub_config_des),
653 wLength));
654 data_buf = root_hub_config_des;
655 break;
656
657 case ((USB_DT_STRING << 8) | 0x00): /* string 0 descriptors */
658 len = min_t(unsigned int,
659 leni, min_t(unsigned int,
660 sizeof(root_hub_str_index0),
661 wLength));
662 data_buf = root_hub_str_index0;
663 break;
664
665 case ((USB_DT_STRING << 8) | 0x01): /* string 1 descriptors */
666 len = min_t(unsigned int,
667 leni, min_t(unsigned int,
668 sizeof(root_hub_str_index1),
669 wLength));
670 data_buf = root_hub_str_index1;
671 break;
672
673 default:
674 debug("invalid wValue\n");
675 stat = USB_ST_STALLED;
676 }
677
678 break;
679
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400680 case RH_GET_DESCRIPTOR | RH_CLASS: {
681 u8 *_data_buf = (u8 *) datab;
Bryan Wu73073cc2010-01-09 16:53:54 -0500682 debug("RH_GET_DESCRIPTOR | RH_CLASS\n");
683
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400684 _data_buf[0] = 0x09; /* min length; */
685 _data_buf[1] = 0x29;
686 _data_buf[2] = 0x1; /* 1 port */
687 _data_buf[3] = 0x01; /* per-port power switching */
688 _data_buf[3] |= 0x10; /* no overcurrent reporting */
Bryan Wu73073cc2010-01-09 16:53:54 -0500689
690 /* Corresponds to data_buf[4-7] */
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400691 _data_buf[4] = 0;
692 _data_buf[5] = 5;
693 _data_buf[6] = 0;
694 _data_buf[7] = 0x02;
695 _data_buf[8] = 0xff;
Bryan Wu73073cc2010-01-09 16:53:54 -0500696
697 len = min_t(unsigned int, leni,
698 min_t(unsigned int, data_buf[0], wLength));
699 break;
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400700 }
Bryan Wu73073cc2010-01-09 16:53:54 -0500701
702 case RH_GET_CONFIGURATION:
703 debug("RH_GET_CONFIGURATION\n");
704
705 *(__u8 *) data_buf = 0x01;
706 len = 1;
707 break;
708
709 case RH_SET_CONFIGURATION:
710 debug("RH_SET_CONFIGURATION\n");
711
712 len = 0;
713 break;
714
715 default:
716 debug("*** *** *** unsupported root hub command *** *** ***\n");
717 stat = USB_ST_STALLED;
718 }
719
720 len = min_t(int, len, leni);
721 if (buffer != data_buf)
722 memcpy(buffer, data_buf, len);
723
724 dev->act_len = len;
725 dev->status = stat;
Mike Frysinger68896282012-02-03 03:03:04 +0000726 debug("dev act_len %d, status %lu\n", dev->act_len, dev->status);
Bryan Wu73073cc2010-01-09 16:53:54 -0500727
728 return stat;
729}
730
731static void musb_rh_init(void)
732{
733 rh_devnum = 0;
734 port_status = 0;
735}
736
737#else
738
739static void musb_rh_init(void) {}
740
741#endif
742
743/*
Thomas Abraham38f424f2009-01-04 09:41:03 +0530744 * do a control transfer
745 */
746int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
747 int len, struct devrequest *setup)
748{
749 int devnum = usb_pipedevice(pipe);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530750 u8 devspeed;
751
Bryan Wu73073cc2010-01-09 16:53:54 -0500752#ifdef MUSB_NO_MULTIPOINT
753 /* Control message is for the HUB? */
Cliff Cai94cfe2a2011-04-21 12:42:10 -0400754 if (devnum == rh_devnum) {
755 int stat = musb_submit_rh_msg(dev, pipe, buffer, len, setup);
756 if (stat)
757 return stat;
758 }
Bryan Wu73073cc2010-01-09 16:53:54 -0500759#endif
760
Thomas Abraham38f424f2009-01-04 09:41:03 +0530761 /* select control endpoint */
762 writeb(MUSB_CONTROL_EP, &musbr->index);
Anatolij Gustschinb2aed5d2011-11-19 13:12:09 +0000763 readw(&musbr->txcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530764
Bryan Wu784f1382009-12-16 22:04:00 -0500765#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530766 /* target addr and (for multipoint) hub addr/port */
767 writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].txfuncaddr);
768 writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -0500769#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530770
771 /* configure the hub address and the port number as required */
772 devspeed = get_dev_speed(dev);
773 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
774 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
775 config_hub_port(dev, MUSB_CONTROL_EP);
776 writeb(devspeed << 6, &musbr->txtype);
777 } else {
778 writeb(musb_cfg.musb_speed << 6, &musbr->txtype);
Bryan Wu784f1382009-12-16 22:04:00 -0500779#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530780 writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubaddr);
781 writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubport);
782 writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubaddr);
783 writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubport);
Bryan Wu784f1382009-12-16 22:04:00 -0500784#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530785 }
786
787 /* Control transfer setup phase */
788 if (ctrlreq_setup_phase(dev, setup) < 0)
789 return 0;
790
791 switch (setup->request) {
792 case USB_REQ_GET_DESCRIPTOR:
793 case USB_REQ_GET_CONFIGURATION:
794 case USB_REQ_GET_INTERFACE:
795 case USB_REQ_GET_STATUS:
796 case USB_MSC_BBB_GET_MAX_LUN:
797 /* control transfer in-data-phase */
798 if (ctrlreq_in_data_phase(dev, len, buffer) < 0)
799 return 0;
800 /* control transfer out-status-phase */
801 if (ctrlreq_out_status_phase(dev) < 0)
802 return 0;
803 break;
804
805 case USB_REQ_SET_ADDRESS:
806 case USB_REQ_SET_CONFIGURATION:
807 case USB_REQ_SET_FEATURE:
808 case USB_REQ_SET_INTERFACE:
809 case USB_REQ_CLEAR_FEATURE:
810 case USB_MSC_BBB_RESET:
811 /* control transfer in status phase */
812 if (ctrlreq_in_status_phase(dev) < 0)
813 return 0;
814 break;
815
816 case USB_REQ_SET_DESCRIPTOR:
817 /* control transfer out data phase */
818 if (ctrlreq_out_data_phase(dev, len, buffer) < 0)
819 return 0;
820 /* control transfer in status phase */
821 if (ctrlreq_in_status_phase(dev) < 0)
822 return 0;
823 break;
824
825 default:
826 /* unhandled control transfer */
827 return -1;
828 }
829
830 dev->status = 0;
831 dev->act_len = len;
Bryan Wu953ee312010-08-09 18:41:12 -0400832
833#ifdef MUSB_NO_MULTIPOINT
834 /* Set device address to USB_FADDR register */
835 if (setup->request == USB_REQ_SET_ADDRESS)
836 writeb(dev->devnum, &musbr->faddr);
837#endif
838
Thomas Abraham38f424f2009-01-04 09:41:03 +0530839 return len;
840}
841
842/*
843 * do a bulk transfer
844 */
845int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
846 void *buffer, int len)
847{
848 int dir_out = usb_pipeout(pipe);
849 int ep = usb_pipeendpoint(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -0500850#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530851 int devnum = usb_pipedevice(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -0500852#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530853 u8 type;
854 u16 csr;
855 u32 txlen = 0;
856 u32 nextlen = 0;
857 u8 devspeed;
858
859 /* select bulk endpoint */
860 writeb(MUSB_BULK_EP, &musbr->index);
861
Bryan Wu784f1382009-12-16 22:04:00 -0500862#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530863 /* write the address of the device */
864 if (dir_out)
865 writeb(devnum, &musbr->tar[MUSB_BULK_EP].txfuncaddr);
866 else
867 writeb(devnum, &musbr->tar[MUSB_BULK_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -0500868#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530869
870 /* configure the hub address and the port number as required */
871 devspeed = get_dev_speed(dev);
872 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
873 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
874 /*
875 * MUSB is in high speed and the destination device is full
876 * speed device. So configure the hub address and port
877 * address registers.
878 */
879 config_hub_port(dev, MUSB_BULK_EP);
880 } else {
Bryan Wu784f1382009-12-16 22:04:00 -0500881#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530882 if (dir_out) {
883 writeb(0, &musbr->tar[MUSB_BULK_EP].txhubaddr);
884 writeb(0, &musbr->tar[MUSB_BULK_EP].txhubport);
885 } else {
886 writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubaddr);
887 writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubport);
888 }
Bryan Wu784f1382009-12-16 22:04:00 -0500889#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530890 devspeed = musb_cfg.musb_speed;
891 }
892
893 /* Write the saved toggle bit value */
894 write_toggle(dev, ep, dir_out);
895
896 if (dir_out) { /* bulk-out transfer */
897 /* Program the TxType register */
898 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
899 (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
900 (ep & MUSB_TYPE_REMOTE_END);
901 writeb(type, &musbr->txtype);
902
903 /* Write maximum packet size to the TxMaxp register */
904 writew(dev->epmaxpacketout[ep], &musbr->txmaxp);
905 while (txlen < len) {
906 nextlen = ((len-txlen) < dev->epmaxpacketout[ep]) ?
907 (len-txlen) : dev->epmaxpacketout[ep];
908
909 /* Write the data to the FIFO */
910 write_fifo(MUSB_BULK_EP, nextlen,
911 (void *)(((u8 *)buffer) + txlen));
912
913 /* Set the TxPktRdy bit */
914 csr = readw(&musbr->txcsr);
915 writew(csr | MUSB_TXCSR_TXPKTRDY, &musbr->txcsr);
916
917 /* Wait until the TxPktRdy bit is cleared */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100918 if (wait_until_txep_ready(dev, MUSB_BULK_EP) != 1) {
Thomas Abraham38f424f2009-01-04 09:41:03 +0530919 readw(&musbr->txcsr);
920 usb_settoggle(dev, ep, dir_out,
921 (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
922 dev->act_len = txlen;
923 return 0;
924 }
925 txlen += nextlen;
926 }
927
928 /* Keep a copy of the data toggle bit */
929 csr = readw(&musbr->txcsr);
930 usb_settoggle(dev, ep, dir_out,
931 (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
932 } else { /* bulk-in transfer */
933 /* Write the saved toggle bit value */
934 write_toggle(dev, ep, dir_out);
935
936 /* Program the RxType register */
937 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
938 (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
939 (ep & MUSB_TYPE_REMOTE_END);
940 writeb(type, &musbr->rxtype);
941
942 /* Write the maximum packet size to the RxMaxp register */
943 writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
944 while (txlen < len) {
945 nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
946 (len-txlen) : dev->epmaxpacketin[ep];
947
948 /* Set the ReqPkt bit */
Bryan Wu65b99d32009-12-16 22:04:01 -0500949 csr = readw(&musbr->rxcsr);
950 writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530951
952 /* Wait until the RxPktRdy bit is set */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100953 if (wait_until_rxep_ready(dev, MUSB_BULK_EP) != 1) {
Thomas Abraham38f424f2009-01-04 09:41:03 +0530954 csr = readw(&musbr->rxcsr);
955 usb_settoggle(dev, ep, dir_out,
956 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
957 csr &= ~MUSB_RXCSR_RXPKTRDY;
958 writew(csr, &musbr->rxcsr);
959 dev->act_len = txlen;
960 return 0;
961 }
962
963 /* Read the data from the FIFO */
964 read_fifo(MUSB_BULK_EP, nextlen,
965 (void *)(((u8 *)buffer) + txlen));
966
967 /* Clear the RxPktRdy bit */
968 csr = readw(&musbr->rxcsr);
969 csr &= ~MUSB_RXCSR_RXPKTRDY;
970 writew(csr, &musbr->rxcsr);
971 txlen += nextlen;
972 }
973
974 /* Keep a copy of the data toggle bit */
975 csr = readw(&musbr->rxcsr);
976 usb_settoggle(dev, ep, dir_out,
977 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
978 }
979
980 /* bulk transfer is complete */
981 dev->status = 0;
982 dev->act_len = len;
983 return 0;
984}
985
986/*
987 * This function initializes the usb controller module.
988 */
Troy Kisky8f9c49d2013-10-10 15:27:56 -0700989int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
Thomas Abraham38f424f2009-01-04 09:41:03 +0530990{
991 u8 power;
992 u32 timeout;
993
Bryan Wu73073cc2010-01-09 16:53:54 -0500994 musb_rh_init();
995
Thomas Abraham38f424f2009-01-04 09:41:03 +0530996 if (musb_platform_init() == -1)
997 return -1;
998
999 /* Configure all the endpoint FIFO's and start usb controller */
1000 musbr = musb_cfg.regs;
Axel Lind6272f22013-06-23 00:57:46 +08001001 musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo));
Thomas Abraham38f424f2009-01-04 09:41:03 +05301002 musb_start();
1003
1004 /*
1005 * Wait until musb is enabled in host mode with a timeout. There
1006 * should be a usb device connected.
1007 */
1008 timeout = musb_cfg.timeout;
Matej Frančeškin36eccd22012-08-30 09:24:39 +02001009 while (--timeout)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301010 if (readb(&musbr->devctl) & MUSB_DEVCTL_HM)
1011 break;
1012
1013 /* if musb core is not in host mode, then return */
1014 if (!timeout)
1015 return -1;
1016
1017 /* start usb bus reset */
1018 power = readb(&musbr->power);
1019 writeb(power | MUSB_POWER_RESET, &musbr->power);
1020
1021 /* After initiating a usb reset, wait for about 20ms to 30ms */
1022 udelay(30000);
1023
1024 /* stop usb bus reset */
1025 power = readb(&musbr->power);
1026 power &= ~MUSB_POWER_RESET;
1027 writeb(power, &musbr->power);
1028
1029 /* Determine if the connected device is a high/full/low speed device */
1030 musb_cfg.musb_speed = (readb(&musbr->power) & MUSB_POWER_HSMODE) ?
1031 MUSB_TYPE_SPEED_HIGH :
1032 ((readb(&musbr->devctl) & MUSB_DEVCTL_FSDEV) ?
1033 MUSB_TYPE_SPEED_FULL : MUSB_TYPE_SPEED_LOW);
1034 return 0;
1035}
1036
1037/*
1038 * This function stops the operation of the davinci usb module.
1039 */
Lucas Stacha3231282012-09-26 00:14:34 +02001040int usb_lowlevel_stop(int index)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301041{
1042 /* Reset the USB module */
1043 musb_platform_deinit();
1044 writeb(0, &musbr->devctl);
1045 return 0;
1046}
1047
1048/*
1049 * This function supports usb interrupt transfers. Currently, usb interrupt
1050 * transfers are not supported.
1051 */
Jean-Jacques Hiblot4f34e362019-09-11 09:44:10 +02001052int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1053 int len, int interval, bool nonblock)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301054{
1055 int dir_out = usb_pipeout(pipe);
1056 int ep = usb_pipeendpoint(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -05001057#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301058 int devnum = usb_pipedevice(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -05001059#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301060 u8 type;
1061 u16 csr;
1062 u32 txlen = 0;
1063 u32 nextlen = 0;
1064 u8 devspeed;
1065
1066 /* select interrupt endpoint */
1067 writeb(MUSB_INTR_EP, &musbr->index);
1068
Bryan Wu784f1382009-12-16 22:04:00 -05001069#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301070 /* write the address of the device */
1071 if (dir_out)
1072 writeb(devnum, &musbr->tar[MUSB_INTR_EP].txfuncaddr);
1073 else
1074 writeb(devnum, &musbr->tar[MUSB_INTR_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -05001075#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301076
1077 /* configure the hub address and the port number as required */
1078 devspeed = get_dev_speed(dev);
1079 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
1080 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
1081 /*
1082 * MUSB is in high speed and the destination device is full
1083 * speed device. So configure the hub address and port
1084 * address registers.
1085 */
1086 config_hub_port(dev, MUSB_INTR_EP);
1087 } else {
Bryan Wu784f1382009-12-16 22:04:00 -05001088#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301089 if (dir_out) {
1090 writeb(0, &musbr->tar[MUSB_INTR_EP].txhubaddr);
1091 writeb(0, &musbr->tar[MUSB_INTR_EP].txhubport);
1092 } else {
1093 writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubaddr);
1094 writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubport);
1095 }
Bryan Wu784f1382009-12-16 22:04:00 -05001096#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301097 devspeed = musb_cfg.musb_speed;
1098 }
1099
1100 /* Write the saved toggle bit value */
1101 write_toggle(dev, ep, dir_out);
1102
1103 if (!dir_out) { /* intrrupt-in transfer */
1104 /* Write the saved toggle bit value */
1105 write_toggle(dev, ep, dir_out);
1106 writeb(interval, &musbr->rxinterval);
1107
1108 /* Program the RxType register */
1109 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
1110 (MUSB_TYPE_PROTO_INTR << MUSB_TYPE_PROTO_SHIFT) |
1111 (ep & MUSB_TYPE_REMOTE_END);
1112 writeb(type, &musbr->rxtype);
1113
1114 /* Write the maximum packet size to the RxMaxp register */
1115 writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
1116
1117 while (txlen < len) {
1118 nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
1119 (len-txlen) : dev->epmaxpacketin[ep];
1120
1121 /* Set the ReqPkt bit */
Bryan Wu65b99d32009-12-16 22:04:01 -05001122 csr = readw(&musbr->rxcsr);
1123 writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +05301124
1125 /* Wait until the RxPktRdy bit is set */
Andrew Murrayca6dfde2013-10-01 15:58:56 +01001126 if (wait_until_rxep_ready(dev, MUSB_INTR_EP) != 1) {
Thomas Abraham38f424f2009-01-04 09:41:03 +05301127 csr = readw(&musbr->rxcsr);
1128 usb_settoggle(dev, ep, dir_out,
1129 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1130 csr &= ~MUSB_RXCSR_RXPKTRDY;
1131 writew(csr, &musbr->rxcsr);
1132 dev->act_len = txlen;
1133 return 0;
1134 }
1135
1136 /* Read the data from the FIFO */
1137 read_fifo(MUSB_INTR_EP, nextlen,
1138 (void *)(((u8 *)buffer) + txlen));
1139
1140 /* Clear the RxPktRdy bit */
1141 csr = readw(&musbr->rxcsr);
1142 csr &= ~MUSB_RXCSR_RXPKTRDY;
1143 writew(csr, &musbr->rxcsr);
1144 txlen += nextlen;
1145 }
1146
1147 /* Keep a copy of the data toggle bit */
1148 csr = readw(&musbr->rxcsr);
1149 usb_settoggle(dev, ep, dir_out,
1150 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1151 }
1152
1153 /* interrupt transfer is complete */
1154 dev->irq_status = 0;
1155 dev->irq_act_len = len;
1156 dev->irq_handle(dev);
1157 dev->status = 0;
1158 dev->act_len = len;
1159 return 0;
1160}