1 /** @file
2
3 Copyright (c) 2015-2017, Linaro. All rights reserved.
4
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <IndustryStandard/Usb.h>
16 #include <Library/ArmLib.h>
17 #include <Library/TimerLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/UefiDriverEntryPoint.h>
21 #include <Library/UefiRuntimeServicesTableLib.h>
22 #include <Library/IoLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UncachedMemoryAllocationLib.h>
25 #include <Library/CacheMaintenanceLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/BaseLib.h>
28 #include <Protocol/DwUsb.h>
29 #include <Protocol/UsbDevice.h>
30
31 #include "DwUsbDxe.h"
32
33 #define USB_TYPE_LENGTH 16
34 #define USB_BLOCK_HIGH_SPEED_SIZE 512
35 #define DATA_SIZE 32768
36 #define CMD_SIZE 512
37 #define MATCH_CMD_LITERAL(Cmd, Buf) !AsciiStrnCmp (Cmd, Buf, sizeof (Cmd) - 1)
38
39 // The time between interrupt polls, in units of 100 nanoseconds
40 // 10 Microseconds
41 #define DW_INTERRUPT_POLL_PERIOD 10000
42
43 EFI_GUID gDwUsbProtocolGuid = DW_USB_PROTOCOL_GUID;
44
45 STATIC dwc_otg_dev_dma_desc_t *gDmaDesc,*gDmaDescEp0,*gDmaDescIn;
46 STATIC USB_DEVICE_REQUEST *gCtrlReq;
47 STATIC VOID *RxBuf;
48 STATIC UINTN RxDescBytes = 0;
49 STATIC UINTN mNumDataBytes;
50
51 STATIC DW_USB_PROTOCOL *DwUsb;
52
53 STATIC USB_DEVICE_DESCRIPTOR *mDeviceDescriptor;
54
55 // The config descriptor, interface descriptor, and endpoint descriptors in a
56 // buffer (in that order)
57 STATIC VOID *mDescriptors;
58 // Convenience pointers to those descriptors inside the buffer:
59 STATIC USB_INTERFACE_DESCRIPTOR *mInterfaceDescriptor;
60 STATIC USB_CONFIG_DESCRIPTOR *mConfigDescriptor;
61 STATIC USB_ENDPOINT_DESCRIPTOR *mEndpointDescriptors;
62
63 STATIC USB_DEVICE_RX_CALLBACK mDataReceivedCallback;
64 STATIC USB_DEVICE_TX_CALLBACK mDataSentCallback;
65
66
67 /* To detect which mode was run, high speed or full speed */
68 STATIC
69 UINTN
UsbDrvPortSpeed(VOID)70 UsbDrvPortSpeed (
71 VOID
72 )
73 {
74 /*
75 * 2'b00: High speed (PHY clock is running at 30 or 60 MHz)
76 */
77 UINT32 Val = READ_REG32 (DSTS) & 2;
78 return (!Val);
79 }
80
81 STATIC
82 VOID
ResetEndpoints(VOID)83 ResetEndpoints (
84 VOID
85 )
86 {
87 /* EP0 IN ACTIVE NEXT=1 */
88 WRITE_REG32 (DIEPCTL0, DXEPCTL_USBACTEP | BIT11);
89
90 /* EP0 OUT ACTIVE */
91 WRITE_REG32 (DOEPCTL0, DXEPCTL_USBACTEP);
92
93 /* Clear any pending OTG Interrupts */
94 WRITE_REG32 (GOTGINT, ~0);
95
96 /* Clear any pending interrupts */
97 WRITE_REG32 (GINTSTS, ~0);
98 WRITE_REG32 (DIEPINT0, ~0);
99 WRITE_REG32 (DOEPINT0, ~0);
100 WRITE_REG32 (DIEPINT1, ~0);
101 WRITE_REG32 (DOEPINT1, ~0);
102
103 /* IN EP interrupt mask */
104 WRITE_REG32 (DIEPMSK, DXEPMSK_TIMEOUTMSK | DXEPMSK_AHBERMSK | DXEPMSK_XFERCOMPLMSK);
105 /* OUT EP interrupt mask */
106 WRITE_REG32 (DOEPMSK, DXEPMSK_TIMEOUTMSK | DXEPMSK_AHBERMSK | DXEPMSK_XFERCOMPLMSK);
107 /* Enable interrupts on Ep0 */
108 WRITE_REG32 (DAINTMSK, (1 << DAINTMSK_OUTEPMSK_SHIFT) | (1 << DAINTMSK_INEPMSK_SHIFT));
109
110 /* EP0 OUT Transfer Size:64 Bytes, 1 Packet, 3 Setup Packet, Read to receive setup packet*/
111 WRITE_REG32 (DOEPTSIZ0, DXEPTSIZ_SUPCNT(3) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(64));
112
113 //notes that:the compulsive conversion is expectable.
114 gDmaDescEp0->status.b.bs = 0x3;
115 gDmaDescEp0->status.b.mtrf = 0;
116 gDmaDescEp0->status.b.sr = 0;
117 gDmaDescEp0->status.b.l = 1;
118 gDmaDescEp0->status.b.ioc = 1;
119 gDmaDescEp0->status.b.sp = 0;
120 gDmaDescEp0->status.b.bytes = 64;
121 gDmaDescEp0->buf = (UINT32)(UINTN)(gCtrlReq);
122 gDmaDescEp0->status.b.sts = 0;
123 gDmaDescEp0->status.b.bs = 0x0;
124 WRITE_REG32 (DOEPDMA0, (UINT32)(UINTN)(gDmaDescEp0));
125 /* EP0 OUT ENABLE CLEARNAK */
126 WRITE_REG32 (DOEPCTL0, (READ_REG32 (DOEPCTL0) | DXEPCTL_EPENA | DXEPCTL_CNAK));
127 }
128
129 STATIC
130 VOID
EpTx(IN UINT8 Ep,IN CONST VOID * Ptr,IN UINTN Len)131 EpTx (
132 IN UINT8 Ep,
133 IN CONST VOID *Ptr,
134 IN UINTN Len
135 )
136 {
137 UINT32 BlockSize;
138 UINT32 Packets;
139
140 /* EPx OUT ACTIVE */
141 WRITE_REG32 (DIEPCTL (Ep), (READ_REG32 (DIEPCTL (Ep))) | DXEPCTL_USBACTEP);
142 if (!Ep) {
143 BlockSize = 64;
144 } else {
145 BlockSize = UsbDrvPortSpeed () ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
146 }
147 Packets = (Len + BlockSize - 1) / BlockSize;
148
149 if (!Len) {
150 /* send one empty packet */
151 gDmaDescIn->status.b.bs = 0x3;
152 gDmaDescIn->status.b.l = 1;
153 gDmaDescIn->status.b.ioc = 1;
154 gDmaDescIn->status.b.sp = 1;
155 gDmaDescIn->status.b.bytes = 0;
156 gDmaDescIn->buf = 0;
157 gDmaDescIn->status.b.sts = 0;
158 gDmaDescIn->status.b.bs = 0x0;
159
160 WRITE_REG32 (DIEPDMA (Ep), (UINT32)(UINTN)(gDmaDescIn)); // DMA Address (DMAAddr) is zero
161 } else {
162 WRITE_REG32 (DIEPTSIZ (Ep), Len | (Packets << 19));
163
164 //flush cache
165 WriteBackDataCacheRange ((VOID *)Ptr, Len);
166
167 gDmaDescIn->status.b.bs = 0x3;
168 gDmaDescIn->status.b.l = 1;
169 gDmaDescIn->status.b.ioc = 1;
170 gDmaDescIn->status.b.sp = 1;
171 gDmaDescIn->status.b.bytes = Len;
172 gDmaDescIn->buf = (UINT32)((UINTN)Ptr);
173 gDmaDescIn->status.b.sts = 0;
174 gDmaDescIn->status.b.bs = 0x0;
175 WRITE_REG32 (DIEPDMA (Ep), (UINT32)(UINTN)(gDmaDescIn)); // Ptr is DMA address
176 }
177 ArmDataSynchronizationBarrier ();
178 /* epena & cnak */
179 WRITE_REG32 (DIEPCTL (Ep), READ_REG32 (DIEPCTL (Ep)) | DXEPCTL_EPENA | DXEPCTL_CNAK | BIT11);
180 }
181
182 STATIC
183 VOID
EpRx(IN UINTN Ep,IN UINTN Len)184 EpRx (
185 IN UINTN Ep,
186 IN UINTN Len
187 )
188 {
189 /* EPx UNSTALL */
190 WRITE_REG32 (DOEPCTL (Ep), ((READ_REG32 (DOEPCTL (Ep))) & (~DXEPCTL_STALL)));
191 /* EPx OUT ACTIVE */
192 WRITE_REG32 (DOEPCTL (Ep), (READ_REG32 (DOEPCTL (Ep)) | DXEPCTL_USBACTEP));
193
194 if (Len >= DATA_SIZE) {
195 RxDescBytes = DATA_SIZE;
196 } else {
197 RxDescBytes = Len;
198 }
199
200 RxBuf = AllocateZeroPool (DATA_SIZE);
201 ASSERT (RxBuf != NULL);
202
203 InvalidateDataCacheRange (RxBuf, Len);
204
205 gDmaDesc->status.b.bs = 0x3;
206 gDmaDesc->status.b.mtrf = 0;
207 gDmaDesc->status.b.sr = 0;
208 gDmaDesc->status.b.l = 1;
209 gDmaDesc->status.b.ioc = 1;
210 gDmaDesc->status.b.sp = 0;
211 gDmaDesc->status.b.bytes = (UINT32)RxDescBytes;
212 gDmaDesc->buf = (UINT32)((UINTN)RxBuf);
213 gDmaDesc->status.b.sts = 0;
214 gDmaDesc->status.b.bs = 0x0;
215
216 ArmDataSynchronizationBarrier ();
217 WRITE_REG32 (DOEPDMA (Ep), (UINT32)((UINTN)gDmaDesc));
218 /* EPx OUT ENABLE CLEARNAK */
219 WRITE_REG32 (DOEPCTL (Ep), (READ_REG32 (DOEPCTL (Ep)) | DXEPCTL_EPENA | DXEPCTL_CNAK));
220 }
221
222 STATIC
223 EFI_STATUS
HandleGetDescriptor(IN USB_DEVICE_REQUEST * Request)224 HandleGetDescriptor (
225 IN USB_DEVICE_REQUEST *Request
226 )
227 {
228 UINT8 DescriptorType;
229 UINTN ResponseSize;
230 VOID *ResponseData;
231 EFI_USB_STRING_DESCRIPTOR *Descriptor = NULL;
232 UINTN DescriptorSize;
233
234 ResponseSize = 0;
235 ResponseData = NULL;
236
237 // Pretty confused if bmRequestType is anything but this:
238 ASSERT (Request->RequestType == USB_DEV_GET_DESCRIPTOR_REQ_TYPE);
239
240 // Choose the response
241 DescriptorType = Request->Value >> 8;
242 switch (DescriptorType) {
243 case USB_DESC_TYPE_DEVICE:
244 DEBUG ((DEBUG_INFO, "USB: Got a request for device descriptor\n"));
245 ResponseSize = sizeof (USB_DEVICE_DESCRIPTOR);
246 ResponseData = mDeviceDescriptor;
247 break;
248 case USB_DESC_TYPE_CONFIG:
249 DEBUG ((DEBUG_INFO, "USB: Got a request for config descriptor\n"));
250 ResponseSize = mConfigDescriptor->TotalLength;
251 ResponseData = mDescriptors;
252 break;
253 case USB_DESC_TYPE_STRING:
254 DEBUG ((DEBUG_INFO, "USB: Got a request for String descriptor %d\n", Request->Value & 0xFF));
255 switch (Request->Value & 0xff) {
256 case 0:
257 DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
258 LANG_LENGTH * sizeof (CHAR16) + 1;
259 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
260 ASSERT (Descriptor != NULL);
261 Descriptor->Length = LANG_LENGTH * sizeof (CHAR16);
262 Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
263 DwUsb->GetLang (Descriptor->String, &Descriptor->Length);
264 ResponseSize = Descriptor->Length;
265 ResponseData = Descriptor;
266 break;
267 case 1:
268 DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
269 MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16) + 1;
270 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
271 ASSERT (Descriptor != NULL);
272 Descriptor->Length = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16);
273 Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
274 DwUsb->GetManuFacturer (Descriptor->String, &Descriptor->Length);
275 ResponseSize = Descriptor->Length;
276 ResponseData = Descriptor;
277 break;
278 case 2:
279 DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
280 PRODUCT_STRING_LENGTH * sizeof (CHAR16) + 1;
281 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
282 ASSERT (Descriptor != NULL);
283 Descriptor->Length = PRODUCT_STRING_LENGTH * sizeof (CHAR16);
284 Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
285 DwUsb->GetProduct (Descriptor->String, &Descriptor->Length);
286 ResponseSize = Descriptor->Length;
287 ResponseData = Descriptor;
288 break;
289 case 3:
290 DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
291 SERIAL_STRING_LENGTH * sizeof (CHAR16) + 1;
292 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
293 ASSERT (Descriptor != NULL);
294 Descriptor->Length = SERIAL_STRING_LENGTH * sizeof (CHAR16);
295 Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
296 DwUsb->GetSerialNo (Descriptor->String, &Descriptor->Length);
297 ResponseSize = Descriptor->Length;
298 ResponseData = Descriptor;
299 break;
300 }
301 break;
302 default:
303 DEBUG ((DEBUG_INFO, "USB: Didn't understand request for descriptor 0x%04x\n", Request->Value));
304 break;
305 }
306
307 // Send the response
308 if (ResponseData) {
309 ASSERT (ResponseSize != 0);
310
311 if (Request->Length < ResponseSize) {
312 // Truncate response
313 ResponseSize = Request->Length;
314 } else if (Request->Length > ResponseSize) {
315 DEBUG ((DEBUG_INFO, "USB: Info: ResponseSize < wLength\n"));
316 }
317
318 EpTx (0, ResponseData, ResponseSize);
319 }
320 if (Descriptor) {
321 FreePool (Descriptor);
322 }
323
324 return EFI_SUCCESS;
325 }
326
327 STATIC
328 EFI_STATUS
HandleSetAddress(IN USB_DEVICE_REQUEST * Request)329 HandleSetAddress (
330 IN USB_DEVICE_REQUEST *Request
331 )
332 {
333 // Pretty confused if bmRequestType is anything but this:
334 ASSERT (Request->RequestType == USB_DEV_SET_ADDRESS_REQ_TYPE);
335 DEBUG ((DEBUG_INFO, "USB: Setting address to %d\n", Request->Value));
336 ResetEndpoints ();
337
338 WRITE_REG32 (DCFG, (READ_REG32 (DCFG) & ~DCFG_DEVADDR_MASK) | DCFG_DEVADDR(Request->Value));
339 EpTx (0, 0, 0);
340
341 return EFI_SUCCESS;
342 }
343
344 STATIC
345 UINTN
UsbDrvRequestEndpoint(IN UINTN Type,IN UINTN Dir)346 UsbDrvRequestEndpoint (
347 IN UINTN Type,
348 IN UINTN Dir
349 )
350 {
351 UINTN Ep = 1;
352 UINTN Ret, NewBits;
353
354 Ret = Ep | Dir;
355 NewBits = (Type << 18) | 0x10000000;
356
357 /*
358 * (Type << 18):Endpoint Type (EPType)
359 * 0x10000000:Endpoint Enable (EPEna)
360 * 0x000C000:Endpoint Type (EPType);Hardcoded to 00 for control.
361 * (ep<<22):TxFIFO Number (TxFNum)
362 * 0x20000:NAK Status (NAKSts);The core is transmitting NAK handshakes on this endpoint.
363 */
364 if (Dir) { // IN: to host
365 WRITE_REG32 (DIEPCTL (Ep), ((READ_REG32 (DIEPCTL (Ep))) & ~DXEPCTL_EPTYPE_MASK) | NewBits | (Ep << 22) | DXEPCTL_NAKSTS);
366 } else { // OUT: to device
367 WRITE_REG32 (DOEPCTL (Ep), ((READ_REG32 (DOEPCTL (Ep))) & ~DXEPCTL_EPTYPE_MASK) | NewBits);
368 }
369
370 return Ret;
371 }
372
373 STATIC
374 EFI_STATUS
HandleSetConfiguration(IN USB_DEVICE_REQUEST * Request)375 HandleSetConfiguration (
376 IN USB_DEVICE_REQUEST *Request
377 )
378 {
379 ASSERT (Request->RequestType == USB_DEV_SET_CONFIGURATION_REQ_TYPE);
380
381 // Cancel all transfers
382 ResetEndpoints ();
383
384 UsbDrvRequestEndpoint (2, 0);
385 UsbDrvRequestEndpoint (2, 0x80);
386
387 WRITE_REG32 (DIEPCTL1, (READ_REG32 (DIEPCTL1)) | BIT28 | BIT19 | DXEPCTL_USBACTEP | BIT11);
388
389 /* Enable interrupts on all endpoints */
390 WRITE_REG32 (DAINTMSK, ~0);
391
392 EpRx (1, CMD_SIZE);
393 EpTx (0, 0, 0);
394 return EFI_SUCCESS;
395 }
396
397
398 STATIC
399 EFI_STATUS
HandleDeviceRequest(IN USB_DEVICE_REQUEST * Request)400 HandleDeviceRequest (
401 IN USB_DEVICE_REQUEST *Request
402 )
403 {
404 EFI_STATUS Status;
405
406 switch (Request->Request) {
407 case USB_DEV_GET_DESCRIPTOR:
408 Status = HandleGetDescriptor (Request);
409 break;
410 case USB_DEV_SET_ADDRESS:
411 Status = HandleSetAddress (Request);
412 break;
413 case USB_DEV_SET_CONFIGURATION:
414 Status = HandleSetConfiguration (Request);
415 break;
416 default:
417 DEBUG ((DEBUG_ERROR,
418 "Didn't understand RequestType 0x%x Request 0x%x\n",
419 Request->RequestType, Request->Request));
420 Status = EFI_INVALID_PARAMETER;
421 break;
422 }
423
424 return Status;
425 }
426
427
428 // Instead of actually registering interrupt handlers, we poll the controller's
429 // interrupt source register in this function.
430 STATIC
431 VOID
CheckInterrupts(IN EFI_EVENT Event,IN VOID * Context)432 CheckInterrupts (
433 IN EFI_EVENT Event,
434 IN VOID *Context
435 )
436 {
437 UINT32 Ints, EpInts;
438
439
440 // interrupt register
441 Ints = READ_REG32 (GINTSTS);
442
443 /*
444 * bus reset
445 * The core sets this bit to indicate that a reset is detected on the USB.
446 */
447 if (Ints & GINTSTS_USBRST) {
448 WRITE_REG32 (DCFG, DCFG_DESCDMA | DCFG_NZ_STS_OUT_HSHK);
449 ResetEndpoints ();
450 }
451
452 /*
453 * enumeration done, we now know the speed
454 * The core sets this bit to indicate that speed enumeration is complete. The
455 * application must read the Device Status (DSTS) register to obtain the
456 * enumerated speed.
457 */
458 if (Ints & GINTSTS_ENUMDONE) {
459 /* Set up the maximum packet sizes accordingly */
460 UINTN MaxPacket = UsbDrvPortSpeed () ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
461 //Set Maximum In Packet Size (MPS)
462 WRITE_REG32 (DIEPCTL1, ((READ_REG32 (DIEPCTL1)) & ~DXEPCTL_MPS_MASK) | MaxPacket);
463 //Set Maximum Out Packet Size (MPS)
464 WRITE_REG32 (DOEPCTL1, ((READ_REG32 (DOEPCTL1)) & ~DXEPCTL_MPS_MASK) | MaxPacket);
465 }
466
467 /*
468 * IN EP event
469 * The core sets this bit to indicate that an interrupt is pending on one of the IN
470 * endpoInts of the core (in Device mode). The application must read the
471 * Device All EndpoInts Interrupt (DAINT) register to determine the exact
472 * number of the IN endpoint on which the interrupt occurred, and then read
473 * the corresponding Device IN Endpoint-n Interrupt (DIEPINTn) register to
474 * determine the exact cause of the interrupt. The application must clear the
475 * appropriate status bit in the corresponding DIEPINTn register to clear this bit.
476 */
477 if (Ints & GINTSTS_IEPINT) {
478 EpInts = READ_REG32 (DIEPINT0);
479 WRITE_REG32 (DIEPINT0, EpInts);
480 if (EpInts & DXEPINT_XFERCOMPL) {
481 DEBUG ((DEBUG_INFO, "INT: IN TX completed.DIEPTSIZ (0) = 0x%x.\n", READ_REG32 (DIEPTSIZ0)));
482 }
483
484 EpInts = READ_REG32 (DIEPINT1);
485 WRITE_REG32 (DIEPINT1, EpInts);
486 if (EpInts & DXEPINT_XFERCOMPL) {
487 DEBUG ((DEBUG_INFO, "ep1: IN TX completed\n"));
488 }
489 }
490
491 /*
492 * OUT EP event
493 * The core sets this bit to indicate that an interrupt is pending on one of the
494 * OUT endpoints of the core (in Device mode). The application must read the
495 * Device All EndpoInts Interrupt (DAINT) register to determine the exact
496 * number of the OUT endpoint on which the interrupt occurred, and then read
497 * the corresponding Device OUT Endpoint-n Interrupt (DOEPINTn) register
498 * to determine the exact cause of the interrupt. The application must clear the
499 * appropriate status bit in the corresponding DOEPINTn register to clear this bit.
500 */
501 if (Ints & GINTSTS_OEPINT) {
502 /* indicates the status of an endpoint
503 * with respect to USB- and AHB-related events. */
504 EpInts = READ_REG32 (DOEPINT0);
505 if (EpInts) {
506 WRITE_REG32 (DOEPINT0, EpInts);
507 if (EpInts & DXEPINT_XFERCOMPL) {
508 DEBUG ((DEBUG_INFO, "INT: EP0 RX completed. DOEPTSIZ(0) = 0x%x.\n", READ_REG32 (DOEPTSIZ0)));
509 }
510 /*
511 *
512 IN Token Received When TxFIFO is Empty (INTknTXFEmp)
513 * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic)
514 * was empty. This interrupt is asserted on the endpoint for which the IN token
515 * was received.
516 */
517 if (EpInts & BIT3) { /* SETUP phase done */
518 WRITE_REG32 (DIEPCTL0, READ_REG32 (DIEPCTL0) | DXEPCTL_SNAK);
519 WRITE_REG32 (DOEPCTL0, READ_REG32 (DOEPCTL0) | DXEPCTL_SNAK);
520 /*clear IN EP intr*/
521 WRITE_REG32 (DIEPINT0, ~0);
522 HandleDeviceRequest((USB_DEVICE_REQUEST *)gCtrlReq);
523 }
524
525 /* Make sure EP0 OUT is set up to accept the next request */
526 WRITE_REG32 (DOEPTSIZ0, DXEPTSIZ_SUPCNT(3) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(64));
527 /*
528 * IN Token Received When TxFIFO is Empty (INTknTXFEmp)
529 * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic)
530 * was empty. This interrupt is asserted on the endpoint for which the IN token
531 * was received.
532 */
533 gDmaDescEp0->status.b.bs = 0x3;
534 gDmaDescEp0->status.b.mtrf = 0;
535 gDmaDescEp0->status.b.sr = 0;
536 gDmaDescEp0->status.b.l = 1;
537 gDmaDescEp0->status.b.ioc = 1;
538 gDmaDescEp0->status.b.sp = 0;
539 gDmaDescEp0->status.b.bytes = 64;
540 gDmaDescEp0->buf = (UINT32)(UINTN)(gCtrlReq);
541 gDmaDescEp0->status.b.sts = 0;
542 gDmaDescEp0->status.b.bs = 0x0;
543 WRITE_REG32 (DOEPDMA0, (UINT32)(UINTN)(gDmaDescEp0));
544 // endpoint enable; clear NAK
545 WRITE_REG32 (DOEPCTL0, DXEPCTL_EPENA | DXEPCTL_CNAK);
546 }
547
548 EpInts = (READ_REG32 (DOEPINT1));
549 if (EpInts) {
550 WRITE_REG32 (DOEPINT1, EpInts);
551 /* Transfer Completed Interrupt (XferCompl);Transfer completed */
552 if (EpInts & DXEPINT_XFERCOMPL) {
553
554 UINTN Bytes = RxDescBytes - gDmaDesc->status.b.bytes;
555 UINTN Len = 0;
556
557 ArmDataSynchronizationBarrier ();
558 if (MATCH_CMD_LITERAL ("download:", RxBuf)) {
559 mNumDataBytes = AsciiStrHexToUint64 (RxBuf + sizeof ("download:"));
560 } else {
561 if (mNumDataBytes != 0) {
562 mNumDataBytes -= Bytes;
563 }
564 }
565
566 mDataReceivedCallback (Bytes, RxBuf);
567
568 if (mNumDataBytes == 0) {
569 Len = CMD_SIZE;
570 } else if (mNumDataBytes > DATA_SIZE) {
571 Len = DATA_SIZE;
572 } else {
573 Len = mNumDataBytes;
574 }
575
576 EpRx (1, Len);
577 }
578 }
579 }
580
581 //WRITE_REG32 clear ints
582 WRITE_REG32 (GINTSTS, Ints);
583 }
584
585 EFI_STATUS
DwUsbSend(IN UINT8 EndpointIndex,IN UINTN Size,IN CONST VOID * Buffer)586 DwUsbSend (
587 IN UINT8 EndpointIndex,
588 IN UINTN Size,
589 IN CONST VOID *Buffer
590 )
591 {
592 EpTx (EndpointIndex, Buffer, Size);
593 return EFI_SUCCESS;
594 }
595
596 STATIC
597 VOID
DwUsbInit(VOID)598 DwUsbInit (
599 VOID
600 )
601 {
602 VOID *Buf;
603 UINT32 Data;
604
605 Buf = UncachedAllocatePages (16);
606 gDmaDesc = Buf;
607 gDmaDescEp0 = gDmaDesc + sizeof (dwc_otg_dev_dma_desc_t);
608 gDmaDescIn = gDmaDescEp0 + sizeof (dwc_otg_dev_dma_desc_t);
609 gCtrlReq = (USB_DEVICE_REQUEST *)gDmaDescIn + sizeof (dwc_otg_dev_dma_desc_t);
610
611 ZeroMem (gDmaDesc, sizeof (dwc_otg_dev_dma_desc_t));
612 ZeroMem (gDmaDescEp0, sizeof (dwc_otg_dev_dma_desc_t));
613 ZeroMem (gDmaDescIn, sizeof (dwc_otg_dev_dma_desc_t));
614
615 /*Reset usb controller.*/
616 /* Wait for OTG AHB master idle */
617 do {
618 Data = READ_REG32 (GRSTCTL) & GRSTCTL_AHBIDLE;
619 } while (Data == 0);
620
621 /* OTG: Assert Software Reset */
622 WRITE_REG32 (GRSTCTL, GRSTCTL_CSFTRST);
623
624 /* Wait for OTG to ack reset */
625 while (READ_REG32 (GRSTCTL) & GRSTCTL_CSFTRST);
626
627 /* Wait for OTG AHB master idle */
628 while ((READ_REG32 (GRSTCTL) & GRSTCTL_AHBIDLE) == 0);
629
630 WRITE_REG32 (GDFIFOCFG, DATA_FIFO_CONFIG);
631 WRITE_REG32 (GRXFSIZ, RX_SIZE);
632 WRITE_REG32 (GNPTXFSIZ, ENDPOINT_TX_SIZE);
633 WRITE_REG32 (DIEPTXF1, DATA_IN_ENDPOINT_TX_FIFO1);
634 WRITE_REG32 (DIEPTXF2, DATA_IN_ENDPOINT_TX_FIFO2);
635 WRITE_REG32 (DIEPTXF3, DATA_IN_ENDPOINT_TX_FIFO3);
636 WRITE_REG32 (DIEPTXF4, DATA_IN_ENDPOINT_TX_FIFO4);
637 WRITE_REG32 (DIEPTXF5, DATA_IN_ENDPOINT_TX_FIFO5);
638 WRITE_REG32 (DIEPTXF6, DATA_IN_ENDPOINT_TX_FIFO6);
639 WRITE_REG32 (DIEPTXF7, DATA_IN_ENDPOINT_TX_FIFO7);
640 WRITE_REG32 (DIEPTXF8, DATA_IN_ENDPOINT_TX_FIFO8);
641 WRITE_REG32 (DIEPTXF9, DATA_IN_ENDPOINT_TX_FIFO9);
642 WRITE_REG32 (DIEPTXF10, DATA_IN_ENDPOINT_TX_FIFO10);
643 WRITE_REG32 (DIEPTXF11, DATA_IN_ENDPOINT_TX_FIFO11);
644 WRITE_REG32 (DIEPTXF12, DATA_IN_ENDPOINT_TX_FIFO12);
645 WRITE_REG32 (DIEPTXF13, DATA_IN_ENDPOINT_TX_FIFO13);
646 WRITE_REG32 (DIEPTXF14, DATA_IN_ENDPOINT_TX_FIFO14);
647 WRITE_REG32 (DIEPTXF15, DATA_IN_ENDPOINT_TX_FIFO15);
648
649 /*
650 * set Periodic TxFIFO Empty Level,
651 * Non-Periodic TxFIFO Empty Level,
652 * Enable DMA, Unmask Global Intr
653 */
654 WRITE_REG32 (GAHBCFG, GAHBCFG_CTRL_MASK);
655
656 /*select 8bit UTMI+, ULPI Inerface*/
657 WRITE_REG32 (GUSBCFG, 0x2400);
658
659 /* Detect usb work mode,host or device? */
660 do {
661 Data = READ_REG32 (GINTSTS);
662 } while (Data & GINTSTS_CURMODE_HOST);
663 MicroSecondDelay (3);
664
665 /*Init global and device mode csr register.*/
666 /*set Non-Zero-Length status out handshake */
667 Data = (0x20 << DCFG_EPMISCNT_SHIFT) | DCFG_NZ_STS_OUT_HSHK;
668 WRITE_REG32 (DCFG, Data);
669
670 /* Interrupt unmask: IN event, OUT event, bus reset */
671 Data = GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_ENUMDONE | GINTSTS_USBRST;
672 WRITE_REG32 (GINTMSK, Data);
673
674 do {
675 Data = READ_REG32 (GINTSTS) & GINTSTS_ENUMDONE;
676 } while (Data);
677
678 /* Clear any pending OTG Interrupts */
679 WRITE_REG32 (GOTGINT, ~0);
680 /* Clear any pending interrupts */
681 WRITE_REG32 (GINTSTS, ~0);
682 WRITE_REG32 (GINTMSK, ~0);
683 Data = READ_REG32 (GOTGINT);
684 Data &= ~0x3000;
685 WRITE_REG32 (GOTGINT, Data);
686
687 /* endpoint settings cfg */
688 ResetEndpoints ();
689 MicroSecondDelay (1);
690
691 /* init finish. and ready to transfer data */
692
693 /* Soft Disconnect */
694 WRITE_REG32 (DCTL, DCTL_PWRONPRGDONE | DCTL_SFTDISCON);
695 MicroSecondDelay (10000);
696
697 /* Soft Reconnect */
698 WRITE_REG32 (DCTL, DCTL_PWRONPRGDONE);
699 }
700
701 EFI_STATUS
702 EFIAPI
DwUsbStart(IN USB_DEVICE_DESCRIPTOR * DeviceDescriptor,IN VOID ** Descriptors,IN USB_DEVICE_RX_CALLBACK RxCallback,IN USB_DEVICE_TX_CALLBACK TxCallback)703 DwUsbStart (
704 IN USB_DEVICE_DESCRIPTOR *DeviceDescriptor,
705 IN VOID **Descriptors,
706 IN USB_DEVICE_RX_CALLBACK RxCallback,
707 IN USB_DEVICE_TX_CALLBACK TxCallback
708 )
709 {
710 UINT8 *Ptr;
711 EFI_STATUS Status;
712 EFI_EVENT TimerEvent;
713
714 ASSERT (DeviceDescriptor != NULL);
715 ASSERT (Descriptors[0] != NULL);
716 ASSERT (RxCallback != NULL);
717 ASSERT (TxCallback != NULL);
718
719 DwUsbInit();
720
721 mDeviceDescriptor = DeviceDescriptor;
722 mDescriptors = Descriptors[0];
723
724 // Right now we just support one configuration
725 ASSERT (mDeviceDescriptor->NumConfigurations == 1);
726 mDeviceDescriptor->StrManufacturer = 1;
727 mDeviceDescriptor->StrProduct = 2;
728 mDeviceDescriptor->StrSerialNumber = 3;
729 // ... and one interface
730 mConfigDescriptor = (USB_CONFIG_DESCRIPTOR *)mDescriptors;
731 ASSERT (mConfigDescriptor->NumInterfaces == 1);
732
733 Ptr = ((UINT8 *) mDescriptors) + sizeof (USB_CONFIG_DESCRIPTOR);
734 mInterfaceDescriptor = (USB_INTERFACE_DESCRIPTOR *) Ptr;
735 Ptr += sizeof (USB_INTERFACE_DESCRIPTOR);
736
737 mEndpointDescriptors = (USB_ENDPOINT_DESCRIPTOR *) Ptr;
738
739 mDataReceivedCallback = RxCallback;
740 mDataSentCallback = TxCallback;
741
742 // Register a timer event so CheckInterupts gets called periodically
743 Status = gBS->CreateEvent (
744 EVT_TIMER | EVT_NOTIFY_SIGNAL,
745 TPL_CALLBACK,
746 CheckInterrupts,
747 NULL,
748 &TimerEvent
749 );
750 ASSERT_EFI_ERROR (Status);
751 if (EFI_ERROR (Status)) {
752 return Status;
753 }
754
755 Status = gBS->SetTimer (
756 TimerEvent,
757 TimerPeriodic,
758 DW_INTERRUPT_POLL_PERIOD
759 );
760 ASSERT_EFI_ERROR (Status);
761
762 return Status;
763 }
764
765 USB_DEVICE_PROTOCOL mUsbDevice = {
766 DwUsbStart,
767 DwUsbSend
768 };
769
770
771 EFI_STATUS
772 EFIAPI
DwUsbEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)773 DwUsbEntryPoint (
774 IN EFI_HANDLE ImageHandle,
775 IN EFI_SYSTEM_TABLE *SystemTable
776 )
777 {
778 EFI_STATUS Status;
779
780 Status = gBS->LocateProtocol (&gDwUsbProtocolGuid, NULL, (VOID **) &DwUsb);
781 if (EFI_ERROR (Status)) {
782 return Status;
783 }
784
785 Status = DwUsb->PhyInit(USB_DEVICE_MODE);
786 if (EFI_ERROR (Status)) {
787 return Status;
788 }
789
790 return gBS->InstallProtocolInterface (
791 &ImageHandle,
792 &gUsbDeviceProtocolGuid,
793 EFI_NATIVE_INTERFACE,
794 &mUsbDevice
795 );
796 }
797