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