1 /** @file 2 3 Copyright (c) 2017, Linaro Limited. 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/BaseLib.h> 18 #include <Library/BaseMemoryLib.h> 19 #include <Library/CacheMaintenanceLib.h> 20 #include <Library/DebugLib.h> 21 #include <Library/IoLib.h> 22 #include <Library/MemoryAllocationLib.h> 23 #include <Library/TimerLib.h> 24 #include <Library/UefiBootServicesTableLib.h> 25 #include <Library/UefiDriverEntryPoint.h> 26 #include <Library/UefiRuntimeServicesTableLib.h> 27 #include <Library/UncachedMemoryAllocationLib.h> 28 #include <Protocol/DwUsb.h> 29 #include <Protocol/UsbDevice.h> 30 31 #include "DwUsb3Dxe.h" 32 33 #define FIFO_DIR_TX 0 34 #define FIFO_DIR_RX 1 35 36 #define TX_FIFO_ADDR 0 37 #define RX_FIFO_ADDR 0 38 39 #define RAM_WIDTH 8 40 #define RAM_TX0_DEPTH 2048 41 #define RAM_TX1_DEPTH 4096 42 #define RAM_RX_DEPTH 8192 43 44 #define USB_TYPE_LENGTH 16 45 #define USB_BLOCK_HIGH_SPEED_SIZE 512 46 #define DATA_SIZE 131072 47 #define CMD_SIZE 512 48 #define MATCH_CMD_LITERAL(Cmd, Buf) !AsciiStrnCmp (Cmd, Buf, sizeof (Cmd) - 1) 49 50 // The time between interrupt polls, in units of 100 nanoseconds 51 // 10 Microseconds 52 #define DW_INTERRUPT_POLL_PERIOD 100 53 54 #define DWUSB3_EVENT_BUF_SIZE 256 55 56 // Maxpacket size for EP0, defined by USB3 spec 57 #define USB3_MAX_EP0_SIZE 512 58 59 // Maxpacket size for any EP, defined by USB3 spec 60 #define USB3_MAX_PACKET_SIZE 1024 61 #define USB2_HS_MAX_PACKET_SIZE 512 62 #define USB2_FS_MAX_PACKET_SIZE 64 63 64 #define USB3_STATE_UNCONNECTED 0 65 #define USB3_STATE_DEFAULT 1 66 #define USB3_STATE_ADDRESSED 2 67 #define USB3_STATE_CONFIGURED 3 68 69 #define GET_EVENTBUF_COUNT() (GEVNTCOUNT_EVNTCOUNT (MmioRead32 (GEVNTCOUNT (0)))) 70 #define UPDATE_EVENTBUF_COUNT(x) (MmioWrite32 (GEVNTCOUNT (0), GEVNTCOUNT_EVNTCOUNT (x))) 71 #define CLEAR_EVENTBUF() do { \ 72 MmioOr32 (GEVNTSIZ (0), GEVNTSIZ_EVNTINTMASK); \ 73 MmioOr32 (GEVNTCOUNT (0), 0); \ 74 } while (0) 75 76 #define SET_DEVADDR(x) (MmioAndThenOr32 (DCFG, ~DCFG_DEVADDR_MASK, DCFG_DEVADDR (x))) 77 78 EFI_GUID gDwUsbProtocolGuid = DW_USB_PROTOCOL_GUID; 79 80 STATIC DW_USB_PROTOCOL *DwUsb; 81 82 STATIC usb3_pcd_t gPcd; 83 STATIC UINT32 *gEventBuf, *gEventPtr; 84 STATIC struct usb_device_descriptor gDwUsb3DevDesc; 85 STATIC VOID *gRxBuf; 86 87 STATIC usb_setup_pkt_t *gEndPoint0SetupPacket; 88 #define USB3_STATUS_BUF_SIZE 512 89 STATIC UINT8 *gEndPoint0StatusBuf; 90 STATIC USB_DEVICE_RX_CALLBACK mDataReceivedCallback; 91 STATIC UINTN mDataBufferSize; 92 /* 93 UINT8 ep0_status_buf[USB3_STATUS_BUF_SIZE]; 94 */ 95 96 struct usb_interface_descriptor intf = { 97 sizeof (struct usb_interface_descriptor), 98 UDESC_INTERFACE, 99 0, 100 0, 101 2, 102 USB_CLASS_VENDOR_SPEC, 103 0x42, 104 0x03, 105 0 106 }; 107 108 const struct usb_ss_ep_comp_descriptor ep_comp = { 109 sizeof (struct usb_ss_ep_comp_descriptor), 110 UDESC_SS_USB_COMPANION, 111 0, 112 0, 113 0 114 }; 115 116 const struct usb_endpoint_descriptor hs_bulk_in = { 117 sizeof (struct usb_endpoint_descriptor), 118 UDESC_ENDPOINT, 119 UE_DIR_IN | USB3_BULK_IN_EP, 120 USB_ENDPOINT_XFER_BULK, 121 0x200, 122 0 123 }; 124 125 const struct usb_endpoint_descriptor 126 hs_bulk_out = { 127 sizeof(struct usb_endpoint_descriptor), /* bLength */ 128 UDESC_ENDPOINT, /* bDescriptorType */ 129 130 UE_DIR_OUT | USB3_BULK_OUT_EP, /* bEndpointAddress */ 131 USB_ENDPOINT_XFER_BULK, /* bmAttributes */ 132 0x200, /* wMaxPacketSize: 512 of high-speed */ 133 1, /* bInterval */ 134 }; 135 136 const struct usb_endpoint_descriptor ss_bulk_in = { 137 sizeof(struct usb_endpoint_descriptor), /* bLength */ 138 UDESC_ENDPOINT, /* bDescriptorType */ 139 140 UE_DIR_IN | USB3_BULK_IN_EP, /* bEndpointAddress */ 141 USB_ENDPOINT_XFER_BULK, /* bmAttributes */ 142 0x400, /* wMaxPacketSize: 1024 of super-speed */ 143 0, /* bInterval */ 144 }; 145 146 const struct usb_endpoint_descriptor ss_bulk_out = { 147 sizeof(struct usb_endpoint_descriptor), /* bLength */ 148 UDESC_ENDPOINT, /* bDescriptorType */ 149 150 UE_DIR_OUT | USB3_BULK_OUT_EP, /* bEndpointAddress */ 151 USB_ENDPOINT_XFER_BULK, /* bmAttributes */ 152 0x400, /* wMaxPacketSize: 1024 of super-speed */ 153 0, /* bInterval */ 154 }; 155 156 /** The BOS Descriptor */ 157 158 const struct usb_dev_cap_20_ext_desc cap1 = { 159 sizeof(struct usb_dev_cap_20_ext_desc), /* bLength */ 160 UDESC_DEVICE_CAPABILITY, /* bDescriptorType */ 161 USB_DEVICE_CAPABILITY_20_EXTENSION, /* bDevCapabilityType */ 162 0x2, /* bmAttributes */ 163 }; 164 165 const struct usb_dev_cap_ss_usb 166 cap2 = { 167 sizeof(struct usb_dev_cap_ss_usb), /* bLength */ 168 UDESC_DEVICE_CAPABILITY, /* bDescriptorType */ 169 USB_DEVICE_CAPABILITY_SS_USB, /* bDevCapabilityType */ 170 0x0, /* bmAttributes */ 171 (USB_DC_SS_USB_SPEED_SUPPORT_SS | 172 USB_DC_SS_USB_SPEED_SUPPORT_HIGH), /* wSpeedsSupported */ 173 0x2, /* bFunctionalitySupport */ 174 /* @todo set these to correct value */ 175 0xa, /* bU1DevExitLat */ 176 0x100, /* wU2DevExitLat */ 177 }; 178 179 const struct usb_dev_cap_container_id 180 cap3 = { 181 sizeof(struct usb_dev_cap_container_id),/* bLength */ 182 UDESC_DEVICE_CAPABILITY, /* bDescriptorType */ 183 USB_DEVICE_CAPABILITY_CONTAINER_ID, /* bDevCapabilityType */ 184 0, /* bReserved */ 185 /* @todo Create UUID */ 186 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* containerID */ 187 }; 188 189 const struct wusb_bos_desc 190 bos = { 191 sizeof(struct wusb_bos_desc), /* bLength */ 192 UDESC_BOS, /* bDescriptorType */ 193 (sizeof(struct wusb_bos_desc) /* wTotalLength */ 194 + sizeof(cap1) + sizeof(cap2) + sizeof(cap3)), 195 3, /* bNumDeviceCaps */ 196 }; 197 198 STATIC struct usb_enum_port_param usb_port_activity_config = { 199 .idVendor = USB_ENUM_ADB_PORT_VID, 200 .idProduct = USB_ENUM_ADB_PORT_PID, 201 .bInterfaceSubClass = USB_ENUM_INTERFACE_ADB_SUBCLASS, 202 .bInterfaceProtocol = USB_ENUM_INTERFACE_ADB_PROTOCOL 203 }; 204 205 STATIC 206 UINT32 207 DwUsb3GetEventBufEvent ( 208 IN UINTN Size 209 ) 210 { 211 UINT32 Event; 212 213 Event = *gEventPtr++; 214 if ((UINT32)(UINTN)gEventPtr >= (UINT32)(UINTN)gEventBuf + Size) { 215 gEventPtr = gEventBuf; 216 } 217 return Event; 218 } 219 220 STATIC 221 VOID 222 DwUsb3SetFifoSize ( 223 IN UINT32 Addr, 224 IN UINT32 Depth, 225 IN UINT32 Dir, 226 IN UINT32 FifoNum 227 ) 228 { 229 UINT32 Reg; 230 231 if (Dir == FIFO_DIR_TX) { 232 Reg = GTXFIFOSIZ (FifoNum); 233 } else if (Dir == FIFO_DIR_RX) { 234 Reg = GRXFIFOSIZ (FifoNum); 235 } else { 236 ASSERT (0); 237 } 238 MmioWrite32 (Reg, FIFOSIZ_DEP (Depth) | FIFOSIZ_ADDR (Addr)); 239 } 240 241 STATIC 242 UINT32 243 Handshake ( 244 IN UINT32 Reg, 245 IN UINT32 Mask, 246 IN UINT32 Done 247 ) 248 { 249 UINT32 Timeout = 100000; 250 251 do { 252 if ((MmioRead32 (Reg) & Mask) == Done) { 253 return 1; 254 } 255 MicroSecondDelay (1); 256 } while (Timeout-- > 0); 257 return 0; 258 } 259 260 STATIC 261 VOID 262 DwUsb3FillDesc ( 263 IN usb3_dma_desc_t *desc, 264 IN UINT64 dma_addr, 265 IN UINT32 dma_len, 266 IN UINT32 stream, 267 IN UINT32 type, 268 IN UINT32 ctrlbits, 269 IN UINT32 own 270 ) 271 { 272 desc->bptl = (UINT32)(dma_addr & 0xFFFFFFFF); 273 desc->bpth = (UINT32)(dma_addr >> 32); 274 desc->status = DSCSTS_XFERCNT (dma_len); 275 if (type) { 276 desc->control = DSCCTL_TRBCTL (type); 277 } 278 desc->control |= DSCCTL_STRMID_SOFN (stream) | ctrlbits; 279 ArmDataSynchronizationBarrier (); 280 /* must execute this operation at last */ 281 if (own) { 282 desc->control |= DSCCTL_HWO; 283 } 284 ArmDataSynchronizationBarrier (); 285 } 286 287 STATIC 288 VOID 289 DwUsb3DepStartNewCfg ( 290 IN UINT32 EpIdx, 291 IN UINT32 RsrcIdx 292 ) 293 { 294 /* start the command */ 295 MmioWrite32 ( 296 DEPCMD (EpIdx), 297 DEPCMD_XFER_RSRC_IDX (RsrcIdx) | DEPCMD_CMDTYPE (CMDTYPE_START_NEW_CFG) | DEPCMD_CMDACT 298 ); 299 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 300 } 301 302 STATIC 303 VOID 304 DwUsb3DepCfg ( 305 IN UINT32 EpIdx, 306 IN UINT32 DepCfg0, 307 IN UINT32 DepCfg1, 308 IN UINT32 DepCfg2 309 ) 310 { 311 MmioWrite32 (DEPCMDPAR2 (EpIdx), DepCfg2); 312 MmioWrite32 (DEPCMDPAR1 (EpIdx), DepCfg1); 313 MmioWrite32 (DEPCMDPAR0 (EpIdx), DepCfg0); 314 MmioWrite32 (DEPCMD (EpIdx), DEPCMD_CMDTYPE (CMDTYPE_SET_EP_CFG) | DEPCMD_CMDACT); 315 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 316 } 317 318 STATIC 319 VOID 320 DwUsb3DepXferCfg ( 321 IN UINT32 EpIdx, 322 IN UINT32 DepStrmCfg 323 ) 324 { 325 MmioWrite32 (DEPCMDPAR0 (EpIdx), DepStrmCfg); 326 MmioWrite32 (DEPCMD (EpIdx), DEPCMD_CMDTYPE (CMDTYPE_SET_XFER_CFG) | DEPCMD_CMDACT); 327 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 328 } 329 330 STATIC 331 UINT8 332 DwUsb3DepStartXfer ( 333 IN UINT32 EpIdx, 334 IN UINT64 DmaAddr, 335 IN UINT32 StreamOrUf 336 ) 337 { 338 UINT32 Data; 339 340 MmioWrite32 (DEPCMDPAR1 (EpIdx), (UINT32)DmaAddr); 341 MmioWrite32 (DEPCMDPAR0 (EpIdx), (UINT32)(DmaAddr >> 32)); 342 MmioWrite32 ( 343 DEPCMD (EpIdx), 344 DEPCMD_STR_NUM_OR_UF (StreamOrUf) | DEPCMD_CMDTYPE (CMDTYPE_START_XFER) | DEPCMD_CMDACT 345 ); 346 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 347 Data = MmioRead32 (DEPCMD (EpIdx)); 348 return GET_DEPCMD_XFER_RSRC_IDX(Data); 349 } 350 351 STATIC 352 VOID 353 DwUsb3DepStopXfer ( 354 IN UINT32 EpIdx, 355 IN UINT32 Tri 356 ) 357 { 358 MmioWrite32 (DEPCMDPAR2 (EpIdx), 0); 359 MmioWrite32 (DEPCMDPAR1 (EpIdx), 0); 360 MmioWrite32 (DEPCMDPAR0 (EpIdx), 0); 361 MmioWrite32 ( 362 DEPCMD (EpIdx), 363 DEPCMD_XFER_RSRC_IDX (Tri) | DEPCMD_CMDTYPE (CMDTYPE_END_XFER) | DEPCMD_CMDACT 364 ); 365 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 366 } 367 368 VOID 369 DwUsb3DepUpdateXfer ( 370 IN UINT32 EpIdx, 371 IN UINT32 Tri 372 ) 373 { 374 MmioWrite32 ( 375 DEPCMD (EpIdx), 376 DEPCMD_XFER_RSRC_IDX (Tri) | DEPCMD_CMDTYPE (CMDTYPE_UPDATE_XFER) | DEPCMD_CMDACT 377 ); 378 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 379 } 380 381 STATIC 382 VOID 383 DwUsb3DepClearStall ( 384 IN UINTN EpIdx 385 ) 386 { 387 MmioWrite32 (DEPCMD (EpIdx), DEPCMD_CMDTYPE (CMDTYPE_CLR_STALL) | DEPCMD_CMDACT); 388 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 389 } 390 391 392 STATIC 393 VOID 394 DwUsb3DepSetStall ( 395 IN UINTN EpIdx 396 ) 397 { 398 MmioWrite32 (DEPCMD (EpIdx), DEPCMD_CMDTYPE (CMDTYPE_SET_STALL) | DEPCMD_CMDACT); 399 Handshake (DEPCMD (EpIdx), DEPCMD_CMDACT, 0); 400 } 401 402 STATIC 403 VOID 404 DwUsb3EnableEp ( 405 IN UINT32 EpIdx, 406 IN usb3_pcd_ep_t *ep 407 ) 408 { 409 UINT32 Dalepena; 410 411 Dalepena = MmioRead32 (DALEPENA); 412 /* If the EP is already enabled, skip to set it again. */ 413 if (Dalepena & (1 << EpIdx)) { 414 return; 415 } 416 Dalepena |= 1 << EpIdx; 417 MmioWrite32 (DALEPENA, Dalepena); 418 } 419 420 STATIC 421 VOID 422 DwUsb3Ep0Activate ( 423 IN OUT usb3_pcd_t *pcd 424 ) 425 { 426 /* issue DEPCFG command to EP0 OUT */ 427 DwUsb3DepStartNewCfg (EP_OUT_IDX (0), 0); 428 DwUsb3DepCfg ( 429 EP_OUT_IDX (0), 430 EPCFG0_EPTYPE (EPTYPE_CONTROL) | EPCFG0_MPS (512), 431 EPCFG1_XFER_CMPL | EPCFG1_XFER_NRDY, 432 0 433 ); 434 /* issue DEPSTRMCFG command to EP0 OUT */ 435 DwUsb3DepXferCfg (EP_OUT_IDX (0), 1); // one stream 436 /* issue DEPCFG command to EP0 IN */ 437 DwUsb3DepCfg ( 438 EP_IN_IDX (0), 439 EPCFG0_EPTYPE (EPTYPE_CONTROL) | EPCFG0_MPS (512) | EPCFG0_TXFNUM (pcd->ep0.tx_fifo_num), 440 EPCFG1_XFER_NRDY | EPCFG1_XFER_CMPL | EPCFG1_EP_DIR_IN, 441 0 442 ); 443 /* issue DEPSTRMCFG command to EP0 IN */ 444 DwUsb3DepXferCfg (EP_IN_IDX (0), 1); // one stream 445 pcd->ep0.active = 1; 446 } 447 448 STATIC 449 VOID 450 DwUsb3EpActivate ( 451 IN OUT usb3_pcd_t *pcd, 452 IN OUT usb3_pcd_ep_t *ep 453 ) 454 { 455 UINT32 EpIdx, DepCfg0, DepCfg1; 456 if (ep->is_in) { 457 EpIdx = EP_IN_IDX (ep->num); 458 } else { 459 EpIdx = EP_OUT_IDX (ep->num); 460 } 461 462 /* Start a new configurate when enable the first EP. */ 463 if (!pcd->eps_enabled) { 464 pcd->eps_enabled = 1; 465 /* Issue DEPCFG command to physical EP1 (logical EP0 IN) first. 466 * It resets the core's Tx FIFO mapping table. 467 */ 468 DepCfg0 = EPCFG0_EPTYPE (EPTYPE_CONTROL); 469 DepCfg0 |= EPCFG0_CFG_ACTION (CFG_ACTION_MODIFY); 470 DepCfg1 = EPCFG1_XFER_CMPL | EPCFG1_XFER_NRDY | EPCFG1_EP_DIR_IN; 471 472 switch (pcd->speed) { 473 case USB_SPEED_SUPER: 474 DepCfg0 |= EPCFG0_MPS (512); 475 break; 476 case USB_SPEED_HIGH: 477 case USB_SPEED_FULL: 478 DepCfg0 |= EPCFG0_MPS (64); 479 break; 480 case USB_SPEED_LOW: 481 DepCfg0 |= EPCFG0_MPS (8); 482 break; 483 default: 484 ASSERT (0); 485 break; 486 } 487 DwUsb3DepCfg (EP_IN_IDX (0), DepCfg0, DepCfg1, 0); 488 DwUsb3DepStartNewCfg (EP_OUT_IDX (0), 2); 489 } 490 /* issue DEPCFG command to EP */ 491 DepCfg0 = EPCFG0_EPTYPE (ep->type); 492 DepCfg0 |= EPCFG0_MPS (ep->maxpacket); 493 if (ep->is_in) { 494 DepCfg0 |= EPCFG0_TXFNUM (ep->tx_fifo_num); 495 } 496 DepCfg0 |= EPCFG0_BRSTSIZ (ep->maxburst); 497 DepCfg1 = EPCFG1_EP_NUM (ep->num); 498 if (ep->is_in) { 499 DepCfg1 |= EPCFG1_EP_DIR_IN; 500 } else { 501 DepCfg1 |= EPCFG1_XFER_CMPL; 502 } 503 DwUsb3DepCfg (EpIdx, DepCfg0, DepCfg1, 0); 504 /* issue DEPSTRMCFG command to EP */ 505 DwUsb3DepXferCfg (EpIdx, 1); 506 DwUsb3EnableEp (EpIdx, ep); 507 ep->active = 1; 508 } 509 510 STATIC 511 VOID 512 DwUsb3Ep0OutStart ( 513 IN usb3_pcd_t *pcd 514 ) 515 { 516 usb3_dma_desc_t *desc; 517 518 /* Get the SETUP packet DMA Descriptor (TRB) */ 519 desc = pcd->ep0_setup_desc; 520 521 /* DMA Descriptor setup */ 522 DwUsb3FillDesc ( 523 desc, 524 (UINT64)gEndPoint0SetupPacket, 525 pcd->ep0.maxpacket, 526 0, 527 TRBCTL_SETUP, 528 DSCCTL_IOC | DSCCTL_ISP | DSCCTL_LST, 529 1 530 ); 531 532 /* issue DEPSTRTXFER command to EP0 OUT */ 533 pcd->ep0.tri_out = DwUsb3DepStartXfer (EP_OUT_IDX (0), (UINT64)desc, 0); 534 } 535 536 STATIC 537 VOID 538 DwUsb3Init ( 539 VOID 540 ) 541 { 542 UINT32 Data, Addr; 543 usb3_pcd_t *pcd = &gPcd; 544 545 /* soft reset the usb core */ 546 do { 547 MmioAndThenOr32 (DCTL, ~DCTL_RUN_STOP, DCTL_CSFTRST); 548 549 do { 550 MicroSecondDelay (1000); 551 Data = MmioRead32 (DCTL); 552 } while (Data & DCTL_CSFTRST); 553 // wait for at least 3 PHY clocks 554 MicroSecondDelay (1000); 555 } while (0); 556 557 pcd->link_state = 0; 558 559 /* TI PHY: Set Turnaround Time = 9 (8-bit UTMI+ / ULPI) */ 560 MmioAndThenOr32 (GUSB2PHYCFG (0), ~GUSB2PHYCFG_USBTRDTIM_MASK, GUSB2PHYCFG_USBTRDTIM (9)); 561 562 /* set TX FIFO size */ 563 Addr = TX_FIFO_ADDR; 564 DwUsb3SetFifoSize (Addr, RAM_TX0_DEPTH / RAM_WIDTH, FIFO_DIR_TX, 0); 565 Addr += RAM_TX0_DEPTH / RAM_WIDTH; 566 DwUsb3SetFifoSize (Addr, RAM_TX1_DEPTH / RAM_WIDTH, FIFO_DIR_TX, 1); 567 /* set RX FIFO size */ 568 DwUsb3SetFifoSize (RX_FIFO_ADDR, RAM_RX_DEPTH / RAM_WIDTH, FIFO_DIR_RX, 0); 569 570 /* set LFPS filter delay1trans */ 571 MmioAndThenOr32 ( 572 GUSB3PIPECTL (0), 573 ~PIPECTL_DELAYP1TRANS, 574 PIPECTL_LFPS_FILTER | PIPECTL_TX_DEMPH (1) 575 ); 576 577 /* set GCTL */ 578 Data = GCTL_U2EXIT_LFPS | GCTL_PRTCAPDIR_DEVICE | GCTL_U2RSTECN | 579 GCTL_PWRDNSCALE(2); 580 MmioWrite32 (GCTL, Data); 581 582 /* init event buf */ 583 MmioWrite32 (GEVNTADRL(0), (UINT32)(UINTN)gEventBuf); 584 MmioWrite32 (GEVNTADRH(0), (UINTN)gEventBuf >> 32); 585 MmioWrite32 (GEVNTSIZ(0), DWUSB3_EVENT_BUF_SIZE << 2); 586 MmioWrite32 (GEVNTCOUNT(0), 0); 587 588 /* set max speed to super speed */ 589 MmioAndThenOr32 ( 590 DCFG, 591 ~DCFG_DEVSPD_MASK, 592 DCFG_DEVSPD (DEVSPD_SS_PHY_125MHZ_OR_250MHZ) 593 ); 594 595 /* set nump */ 596 MmioAndThenOr32 (DCFG, ~DCFG_NUMP_MASK, DCFG_NUMP (16)); 597 598 /* init address */ 599 SET_DEVADDR (0); 600 601 /* disable phy suspend */ 602 MmioAnd32 (GUSB3PIPECTL (0), ~PIPECTL_SUSPEND_EN); 603 MmioAnd32 (GUSB2PHYCFG (0), ~GUSB2PHYCFG_SUSPHY); 604 605 /* clear any pending interrupts */ 606 #if 0 607 CLEAR_EVENTBUF (); 608 #else 609 Data = MmioRead32 (GEVNTCOUNT (0)); 610 MmioWrite32 (GEVNTCOUNT (0), Data); 611 #endif 612 /* enable device interrupts */ 613 MmioWrite32 (DEVTEN, DEVTEN_CONNECTDONEEN | DEVTEN_USBRSTEN); 614 /* activate EP0 */ 615 DwUsb3Ep0Activate (pcd); 616 /* start EP0 to receive SETUP packets */ 617 DwUsb3Ep0OutStart (pcd); 618 619 /* enable EP0 OUT/IN in DALEPENA */ 620 MmioWrite32 (DALEPENA, (1 << EP_OUT_IDX (0)) | (1 << EP_IN_IDX (0))); 621 622 /* set RUN/STOP bit */ 623 MmioOr32 (DCTL, DCTL_RUN_STOP); 624 } 625 626 #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) 627 628 STATIC 629 VOID 630 DriverInit ( 631 VOID 632 ) 633 { 634 usb3_pcd_t *pcd = &gPcd; 635 usb3_pcd_ep_t *ep; 636 637 pcd->speed = USB_SPEED_UNKNOWN; 638 639 // init EP0 640 ep = &pcd->ep0; 641 ep->pcd = pcd; 642 ep->stopped = 1; 643 ep->is_in = 0; 644 ep->active = 0; 645 ep->phys = 0; 646 ep->num = 0; 647 ep->tx_fifo_num = 0; 648 ep->type = EPTYPE_CONTROL; 649 ep->maxburst = 0; 650 ep->maxpacket = USB3_MAX_EP0_SIZE; 651 ep->send_zlp = 0; 652 ep->req.length = 0; 653 ep->req.actual = 0; 654 pcd->ep0_req.length = 0; 655 pcd->ep0_req.actual = 0; 656 657 // init EP1 OUT 658 ep = &pcd->out_ep; 659 ep->pcd = pcd; 660 ep->stopped = 1; 661 ep->is_in = 0; 662 ep->active = 0; 663 ep->phys = USB3_BULK_OUT_EP << 1; 664 ep->num = 1; 665 ep->tx_fifo_num = 0; 666 // bulk ep is activated 667 ep->type = EPTYPE_BULK; 668 ep->maxburst = 0; 669 ep->maxpacket = USB3_MAX_PACKET_SIZE; 670 ep->send_zlp = 0; 671 ep->req.length = 0; 672 ep->req.actual = 0; 673 674 // init EP1 IN 675 ep = &pcd->in_ep; 676 ep->stopped = 1; 677 ep->is_in = 1; 678 ep->active = 0; 679 ep->phys = (USB3_BULK_IN_EP << 1) | 1; 680 ep->num = 1; 681 ep->tx_fifo_num = USB3_BULK_IN_EP; 682 // bulk ep is activated 683 ep->type = EPTYPE_BULK; 684 ep->maxburst = 0; 685 ep->maxpacket = USB3_MAX_PACKET_SIZE; 686 ep->send_zlp = 0; 687 ep->req.length = 0; 688 ep->req.actual = 0; 689 690 pcd->ep0state = EP0_IDLE; 691 pcd->ep0.maxpacket = USB3_MAX_EP0_SIZE; 692 pcd->ep0.type = EPTYPE_CONTROL; 693 694 #if 0 695 pcd->ep0_setup_desc = (usb3_dma_desc_t *)ALIGN ((UINTN)pcd->ep0_setup, 16); 696 pcd->ep0_in_desc = (usb3_dma_desc_t *)ALIGN ((UINTN)pcd->ep0_in, 16); 697 pcd->ep0_out_desc = (usb3_dma_desc_t *)ALIGN ((UINTN)pcd->ep0_out, 16); 698 pcd->in_ep.ep_desc = (usb3_dma_desc_t *)ALIGN ((UINTN)pcd->in_ep.epx_desc, 16); 699 pcd->out_ep.ep_desc = (usb3_dma_desc_t *)ALIGN ((UINTN)pcd->out_ep.epx_desc, 16); 700 #else 701 pcd->ep0_setup_desc = (usb3_dma_desc_t *)UncachedAllocateAlignedZeroPool (64, 64); 702 pcd->ep0_in_desc = (usb3_dma_desc_t *)UncachedAllocateAlignedZeroPool (64, 64); 703 pcd->ep0_out_desc = (usb3_dma_desc_t *)UncachedAllocateAlignedZeroPool (64, 64); 704 pcd->in_ep.ep_desc = (usb3_dma_desc_t *)UncachedAllocateAlignedZeroPool (64, 64); 705 pcd->out_ep.ep_desc = (usb3_dma_desc_t *)UncachedAllocateAlignedZeroPool (64, 64); 706 #endif 707 } 708 709 STATIC 710 VOID 711 DwUsb3HandleUsbResetInterrupt ( 712 IN usb3_pcd_t *pcd 713 ) 714 { 715 usb3_pcd_ep_t *ep; 716 717 // clear stall on each EP 718 ep = &pcd->in_ep; 719 if (ep->xfer_started) { 720 if (ep->is_in) { 721 DwUsb3DepStopXfer (EP_IN_IDX (ep->num), ep->tri_in); 722 } else { 723 DwUsb3DepStopXfer (EP_OUT_IDX (ep->num), ep->tri_out); 724 } 725 } 726 if (ep->stopped) { 727 if (ep->is_in) { 728 DwUsb3DepClearStall (EP_IN_IDX (ep->num)); 729 } else { 730 DwUsb3DepClearStall (EP_OUT_IDX (ep->num)); 731 } 732 } 733 734 ep = &pcd->out_ep; 735 if (ep->xfer_started) { 736 if (ep->is_in) { 737 DwUsb3DepStopXfer (EP_IN_IDX (ep->num), ep->tri_in); 738 } else { 739 DwUsb3DepStopXfer (EP_OUT_IDX (ep->num), ep->tri_out); 740 } 741 } 742 if (ep->stopped) { 743 if (ep->is_in) { 744 DwUsb3DepClearStall (EP_IN_IDX (ep->num)); 745 } else { 746 DwUsb3DepClearStall (EP_OUT_IDX (ep->num)); 747 } 748 } 749 750 // set device address to 0 751 SET_DEVADDR (0); 752 753 pcd->ltm_enable = 0; 754 DEBUG ((DEBUG_INFO, "usb reset\n")); 755 } 756 757 STATIC 758 UINT32 759 DwUsb3GetDeviceSpeed ( 760 IN usb3_pcd_t *pcd 761 ) 762 { 763 UINT32 Data, Speed; 764 765 Data = MmioRead32 (DSTS); 766 switch (DSTS_GET_DEVSPD (Data)) { 767 case DEVSPD_HS_PHY_30MHZ_OR_60MHZ: 768 Speed = USB_SPEED_HIGH; 769 break; 770 case DEVSPD_FS_PHY_30MHZ_OR_60MHZ: 771 case DEVSPD_FS_PHY_48MHZ: 772 Speed = USB_SPEED_FULL; 773 break; 774 case DEVSPD_LS_PHY_6MHZ: 775 Speed = USB_SPEED_LOW; 776 break; 777 case DEVSPD_SS_PHY_125MHZ_OR_250MHZ: 778 Speed = USB_SPEED_SUPER; 779 break; 780 default: 781 DEBUG ((DEBUG_ERROR, "DwUsb3GetDeviceSpeed: invalid DSTS:0x%x\n", Data)); 782 Speed = USB_SPEED_UNKNOWN; 783 break; 784 } 785 return Speed; 786 } 787 788 STATIC 789 VOID 790 DwUsb3PcdSetSpeed ( 791 IN usb3_pcd_t *pcd, 792 IN UINTN speed 793 ) 794 { 795 // set the MPS of EP0 based on the connection speed 796 switch (speed) { 797 case USB_SPEED_SUPER: 798 pcd->ep0.maxpacket = 512; 799 pcd->in_ep.maxpacket = USB3_MAX_PACKET_SIZE; 800 pcd->out_ep.maxpacket = USB3_MAX_PACKET_SIZE; 801 break; 802 case USB_SPEED_HIGH: 803 pcd->ep0.maxpacket = 64; 804 pcd->in_ep.maxpacket = USB2_HS_MAX_PACKET_SIZE; 805 pcd->out_ep.maxpacket = USB2_HS_MAX_PACKET_SIZE; 806 break; 807 case USB_SPEED_FULL: 808 pcd->ep0.maxpacket = 64; 809 pcd->in_ep.maxpacket = USB2_FS_MAX_PACKET_SIZE; 810 pcd->out_ep.maxpacket = USB2_FS_MAX_PACKET_SIZE; 811 break; 812 default: 813 DEBUG ((DEBUG_ERROR, "invalid speed: %d\n", speed)); 814 break; 815 } 816 } 817 818 STATIC 819 VOID 820 DwUsb3HandleConnectDoneInterrupt ( 821 IN usb3_pcd_t *pcd 822 ) 823 { 824 usb3_pcd_ep_t *ep0 = &pcd->ep0; 825 UINT32 DiepCfg0, DoepCfg0, DiepCfg1, DoepCfg1; 826 UINT32 Speed; 827 828 ep0->stopped = 0; 829 Speed = (UINT32)DwUsb3GetDeviceSpeed (pcd); 830 pcd->speed = (UINT8)Speed; 831 832 DwUsb3PcdSetSpeed (pcd, Speed); 833 // set the MPS of EP0 based on the connection speed 834 DiepCfg0 = EPCFG0_EPTYPE (EPTYPE_CONTROL) | EPCFG0_CFG_ACTION (CFG_ACTION_MODIFY); 835 DiepCfg1 = EPCFG1_XFER_CMPL | EPCFG1_XFER_NRDY | EPCFG1_EP_DIR_IN; 836 DoepCfg0 = EPCFG0_EPTYPE (EPTYPE_CONTROL) | EPCFG0_CFG_ACTION (CFG_ACTION_MODIFY); 837 DoepCfg1 = EPCFG1_XFER_CMPL | EPCFG1_XFER_NRDY; 838 839 switch (Speed) { 840 case USB_SPEED_SUPER: 841 DiepCfg0 |= EPCFG0_MPS (512); 842 DoepCfg0 |= EPCFG0_MPS (512); 843 break; 844 case USB_SPEED_HIGH: 845 case USB_SPEED_FULL: 846 DiepCfg0 |= EPCFG0_MPS (64); 847 DoepCfg0 |= EPCFG0_MPS (64); 848 break; 849 case USB_SPEED_LOW: 850 DiepCfg0 |= EPCFG0_MPS (8); 851 DoepCfg0 |= EPCFG0_MPS (8); 852 break; 853 default: 854 DEBUG ((DEBUG_ERROR, "DwUsb3HandleConnectDoneInterrupt: invalid speed %d\n", Speed)); 855 break; 856 } 857 DiepCfg0 |= EPCFG0_TXFNUM (ep0->tx_fifo_num); 858 // issue DEPCFG command to EP0 OUT 859 DwUsb3DepCfg (EP_OUT_IDX (0), DoepCfg0, DoepCfg1, 0); 860 // issue DEPCFG command to EP0 IN 861 DwUsb3DepCfg (EP_IN_IDX (0), DiepCfg0, DiepCfg1, 0); 862 pcd->state = USB3_STATE_DEFAULT; 863 } 864 865 STATIC 866 VOID 867 DwUsb3HandleDeviceInterrupt ( 868 IN usb3_pcd_t *pcd, 869 IN UINT32 Event 870 ) 871 { 872 switch (Event & GEVNT_DEVT_MASK) { 873 case GEVNT_DEVT_USBRESET: 874 DwUsb3HandleUsbResetInterrupt (pcd); 875 break; 876 case GEVNT_DEVT_CONNDONE: 877 DwUsb3HandleConnectDoneInterrupt (pcd); 878 break; 879 default: 880 DEBUG ((DEBUG_ERROR, "DwUsb3HandleDeviceInterrupt: invalid event\n")); 881 break; 882 } 883 } 884 885 STATIC 886 usb3_pcd_ep_t * 887 DwUsb3GetOutEndPoint ( 888 IN usb3_pcd_t *pcd, 889 IN UINT32 EndPointNum 890 ) 891 { 892 if (EndPointNum == 0) { 893 return &pcd->ep0; 894 } 895 return &pcd->out_ep; 896 } 897 898 STATIC 899 usb3_pcd_ep_t * 900 DwUsb3GetInEndPoint ( 901 IN usb3_pcd_t *pcd, 902 IN UINT32 EndPointNum 903 ) 904 { 905 if (EndPointNum == 0) { 906 return &pcd->ep0; 907 } 908 return &pcd->in_ep; 909 } 910 911 STATIC 912 VOID 913 EndPoint0DoStall ( 914 IN usb3_pcd_t *pcd 915 ) 916 { 917 usb3_pcd_ep_t *ep0 = &pcd->ep0; 918 919 // stall EP0 IN & OUT simultanelusly 920 ep0->is_in = 1; 921 DwUsb3DepSetStall (EP_IN_IDX (0)); 922 ep0->is_in = 0; 923 DwUsb3DepSetStall (EP_OUT_IDX (0)); 924 // prepare for the next setup transfer 925 ep0->stopped = 1; 926 pcd->ep0state = EP0_IDLE; 927 DwUsb3Ep0OutStart (pcd); 928 } 929 930 STATIC 931 VOID 932 EndPoint0ContinueTransfer ( 933 IN usb3_pcd_t *pcd, 934 IN usb3_pcd_req_t *req 935 ) 936 { 937 usb3_pcd_ep_t *ep0 = &pcd->ep0; 938 usb3_dma_desc_t *desc; 939 UINT64 desc_dma; 940 UINT8 tri; 941 942 // send a 0-byte length packet after the end of transfer 943 if (ep0->is_in) { 944 desc = pcd->ep0_in_desc; 945 desc_dma = (UINT64)pcd->ep0_in_desc; 946 // DMA descriptor setup 947 DwUsb3FillDesc ( 948 desc, 949 (UINT64)req->bufdma, 950 0, 951 0, 952 TRBCTL_NORMAL, 953 DSCCTL_IOC | DSCCTL_ISP | DSCCTL_LST, 954 1 955 ); 956 tri = DwUsb3DepStartXfer (EP_IN_IDX (0), desc_dma, 0); 957 ep0->tri_in = tri; 958 } 959 } 960 961 STATIC 962 VOID 963 EndPoint0CompleteRequest ( 964 IN usb3_pcd_t *pcd, 965 IN usb3_pcd_req_t *req, 966 IN usb3_dma_desc_t *desc 967 ) 968 { 969 usb3_pcd_ep_t *ep = &pcd->ep0; 970 971 if (req == NULL) { 972 return; 973 } 974 975 if ((pcd->ep0state == EP0_OUT_DATA_PHASE) || 976 (pcd->ep0state == EP0_IN_DATA_PHASE)) { 977 if (ep->is_in) { 978 if (GET_DSCSTS_XFERCNT (desc->status) == 0) { 979 pcd->ep0.is_in = 0; 980 pcd->ep0state = EP0_OUT_WAIT_NRDY; 981 } 982 } else { 983 pcd->ep0.is_in = 1; 984 pcd->ep0state = EP0_IN_WAIT_NRDY; 985 } 986 } 987 } 988 989 STATIC 990 VOID 991 DwUsb3OsGetTrb ( 992 IN usb3_pcd_t *pcd, 993 IN usb3_pcd_ep_t *ep, 994 IN usb3_pcd_req_t *req 995 ) 996 { 997 // If EP0, fill request with EP0 IN/OUT data TRB 998 if (ep == &pcd->ep0) { 999 if (ep->is_in) { 1000 req->trb = pcd->ep0_in_desc; 1001 req->trbdma = (UINT64)pcd->ep0_in_desc; 1002 } else { 1003 req->trb = pcd->ep0_out_desc; 1004 req->trbdma = (UINT64)pcd->ep0_out_desc; 1005 } 1006 } else { 1007 // fill request with TRB from the non-EP0 allocation 1008 req->trb = ep->ep_desc; 1009 req->trbdma = (UINT64)ep->ep_desc; 1010 } 1011 } 1012 1013 STATIC 1014 VOID 1015 DwUsb3EndPoint0StartTransfer ( 1016 IN usb3_pcd_t *pcd, 1017 IN usb3_pcd_req_t *req 1018 ) 1019 { 1020 usb3_pcd_ep_t *ep0 = &pcd->ep0; 1021 usb3_dma_desc_t *desc; 1022 UINT64 desc_dma; 1023 UINT32 desc_type, len; 1024 1025 // get the DMA descriptor (TRB) for this request 1026 DwUsb3OsGetTrb (pcd, ep0, req); 1027 desc = req->trb; 1028 desc_dma = req->trbdma; 1029 1030 if (ep0->is_in) { 1031 // start DMA on EP0 IN 1032 // DMA Descriptor (TRB) setup 1033 len = req->length; 1034 if (pcd->ep0state == EP0_IN_STATUS_PHASE) { 1035 if (ep0->three_stage) { 1036 desc_type = TRBCTL_STATUS_3; 1037 } else { 1038 desc_type = TRBCTL_STATUS_2; 1039 } 1040 } else { 1041 desc_type = TRBCTL_CTLDATA_1ST; 1042 } 1043 DwUsb3FillDesc ( 1044 desc, 1045 (UINT64)req->bufdma, 1046 len, 1047 0, 1048 desc_type, 1049 DSCCTL_IOC | DSCCTL_ISP | DSCCTL_LST, 1050 1 1051 ); 1052 // issue DEPSTRTXFER command to EP0 IN 1053 ep0->tri_in = DwUsb3DepStartXfer (EP_IN_IDX (0), desc_dma, 0); 1054 } else { 1055 // start DMA on EP0 OUT 1056 // DMA Descriptor (TRB) setup 1057 len = ALIGN (req->length, ep0->maxpacket); 1058 if (pcd->ep0state == EP0_OUT_STATUS_PHASE) { 1059 if (ep0->three_stage) { 1060 desc_type = TRBCTL_STATUS_3; 1061 } else { 1062 desc_type = TRBCTL_STATUS_2; 1063 } 1064 } else { 1065 desc_type = TRBCTL_CTLDATA_1ST; 1066 } 1067 DwUsb3FillDesc ( 1068 desc, 1069 (UINT64)req->bufdma, 1070 len, 1071 0, 1072 desc_type, 1073 DSCCTL_IOC | DSCCTL_ISP | DSCCTL_LST, 1074 1 1075 ); 1076 // issue DEPSTRTXFER command to EP0 OUT 1077 ep0->tri_out = DwUsb3DepStartXfer (EP_OUT_IDX (0), desc_dma, 0); 1078 } 1079 } 1080 1081 STATIC 1082 INTN 1083 DwUsb3EndPointXStartTransfer ( 1084 IN usb3_pcd_t *pcd, 1085 IN usb3_pcd_ep_t *ep 1086 ) 1087 { 1088 usb3_pcd_req_t *req = &ep->req; 1089 usb3_dma_desc_t *desc; 1090 UINT64 desc_dma; 1091 UINT32 len; 1092 1093 // get the TRB for this request 1094 DwUsb3OsGetTrb (pcd, ep, req); 1095 desc = req->trb; 1096 desc_dma = req->trbdma; 1097 1098 if (ep->is_in) { 1099 // For IN, TRB length is just xfer length 1100 len = req->length; 1101 if (ep->xfer_started && !(desc->control & DSCCTL_HWO)) { 1102 DEBUG ((DEBUG_INFO, "[%a] last tx succ, but not in 10s!\n", __func__)); 1103 ep->xfer_started = 0; 1104 } 1105 } else { 1106 // For OUT, TRB length must be multiple of maxpacket 1107 // must be power of 2, use cheap AND 1108 len = (req->length + ep->maxpacket - 1) & ~(ep->maxpacket - 1); 1109 req->length = len; 1110 } 1111 // DMA descriptor setup 1112 DwUsb3FillDesc ( 1113 desc, 1114 (UINT64)req->bufdma, 1115 len, 1116 0, 1117 TRBCTL_NORMAL, 1118 DSCCTL_IOC | DSCCTL_ISP | DSCCTL_LST, 1119 1 1120 ); 1121 if (ep->is_in) { 1122 // start DMA on EPn IN 1123 if (ep->xfer_started) { 1124 // issue DEPUPDTXFER command to EP 1125 DwUsb3DepUpdateXfer (EP_IN_IDX (ep->num), ep->tri_in); 1126 } else { 1127 ep->tri_in = DwUsb3DepStartXfer (EP_IN_IDX (ep->num), desc_dma, 0); 1128 ep->xfer_started = 1; 1129 } 1130 } else { 1131 // start DMA on EPn OUT 1132 if (ep->xfer_started) { 1133 // issue DEPUPDTXFER command to EP 1134 DwUsb3DepUpdateXfer (EP_OUT_IDX (ep->num), ep->tri_out); 1135 } else { 1136 ep->tri_out = DwUsb3DepStartXfer (EP_OUT_IDX (ep->num), desc_dma, 0); 1137 ep->xfer_started = 1; 1138 } 1139 } 1140 if (ep->is_in) { 1141 UINT32 count = 0; 1142 // wait until send complete 1143 while ((desc->control & DSCCTL_HWO) && (count < 1000000)) { 1144 MicroSecondDelay (10); 1145 count++; 1146 } 1147 if (count >= 1000000) { 1148 DEBUG ((DEBUG_INFO, "[%a]: ep%d transfer timeout!\n", __func__, ep->num)); 1149 DEBUG ((DEBUG_INFO, "please disconnect then connect USB cable again to recovery!\n")); 1150 return -1; 1151 } 1152 ep->xfer_started = 0; 1153 } 1154 return 0; 1155 } 1156 1157 #if 0 1158 STATIC 1159 VOID 1160 DwUsb3EndPointXStopTransfer ( 1161 IN usb3_pcd_t *pcd, 1162 IN usb3_pcd_ep_t *ep 1163 ) 1164 { 1165 if (ep->is_in) { 1166 DwUsb3DepStopXfer (EP_IN_IDX (ep->num), ep->tri_in); 1167 } else { 1168 DwUsb3DepStopXfer (EP_OUT_IDX (ep->num), ep->tri_out); 1169 } 1170 } 1171 #endif 1172 1173 STATIC 1174 VOID 1175 SetupInStatusPhase ( 1176 IN usb3_pcd_t *pcd, 1177 IN VOID *buf 1178 ) 1179 { 1180 usb3_pcd_ep_t *ep0 = &pcd->ep0; 1181 1182 if (pcd->ep0state == EP0_STALL) 1183 return; 1184 1185 ep0->is_in = 1; 1186 pcd->ep0state = EP0_IN_STATUS_PHASE; 1187 pcd->ep0_req.bufdma = buf; 1188 pcd->ep0_req.length = 0; 1189 pcd->ep0_req.actual = 0; 1190 DwUsb3EndPoint0StartTransfer (pcd, &pcd->ep0_req); 1191 } 1192 1193 STATIC 1194 VOID 1195 SetupOutStatusPhase ( 1196 IN usb3_pcd_t *pcd, 1197 IN VOID *buf 1198 ) 1199 { 1200 usb3_pcd_ep_t *ep0 = &pcd->ep0; 1201 1202 if (pcd->ep0state == EP0_STALL) 1203 return; 1204 1205 ep0->is_in = 0; 1206 pcd->ep0state = EP0_OUT_STATUS_PHASE; 1207 pcd->ep0_req.bufdma = buf; 1208 pcd->ep0_req.length = 0; 1209 pcd->ep0_req.actual = 0; 1210 DwUsb3EndPoint0StartTransfer (pcd, &pcd->ep0_req); 1211 } 1212 1213 STATIC 1214 VOID 1215 DwUsb3HandleEndPoint0 ( 1216 IN usb3_pcd_t *pcd, 1217 IN usb3_pcd_req_t *req, 1218 IN UINT32 event 1219 ) 1220 { 1221 usb3_pcd_ep_t *ep0 = &pcd->ep0; 1222 usb3_dma_desc_t *desc; 1223 UINT32 byte_count, len; 1224 1225 switch (pcd->ep0state) { 1226 case EP0_IN_DATA_PHASE: 1227 if (req == NULL) { 1228 req = &pcd->ep0_req; 1229 } 1230 desc = pcd->ep0_in_desc; 1231 1232 if (desc->control & DSCCTL_HWO) { 1233 goto out; 1234 } 1235 1236 if (GET_DSCSTS_TRBRSP (desc->status) == TRBRSP_SETUP_PEND) { 1237 // start of a new control transfer 1238 desc->status = 0; 1239 } 1240 byte_count = req->length - GET_DSCSTS_XFERCNT (desc->status); 1241 req->actual += byte_count; 1242 req->bufdma += byte_count; 1243 1244 if (req->actual < req->length) { 1245 // IN CONTINUE, stall EP0 1246 EndPoint0DoStall (pcd); 1247 } else if (ep0->send_zlp) { 1248 // CONTINUE TRANSFER IN ZLP 1249 EndPoint0ContinueTransfer (pcd, req); 1250 ep0->send_zlp = 0; 1251 } else { 1252 // COMPLETE IN TRANSFER 1253 EndPoint0CompleteRequest (pcd, req, desc); 1254 } 1255 break; 1256 case EP0_OUT_DATA_PHASE: 1257 if (req == NULL) { 1258 req = &pcd->ep0_req; 1259 } 1260 desc = pcd->ep0_out_desc; 1261 1262 if (desc->control & DSCCTL_HWO) { 1263 goto out; 1264 } 1265 1266 if (GET_DSCSTS_TRBRSP (desc->status) == TRBRSP_SETUP_PEND) { 1267 // start of a new control transfer 1268 desc->status = 0; 1269 } 1270 len = (req->length + ep0->maxpacket - 1) & ~(ep0->maxpacket - 1); 1271 byte_count = len - GET_DSCSTS_XFERCNT (desc->status); 1272 req->actual += byte_count; 1273 req->bufdma += byte_count; 1274 1275 if (req->actual < req->length) { 1276 // IN CONTINUE, stall EP0 1277 EndPoint0DoStall (pcd); 1278 } else if (ep0->send_zlp) { 1279 // CONTINUE TRANSFER IN ZLP 1280 EndPoint0ContinueTransfer (pcd, req); 1281 ep0->send_zlp = 0; 1282 } else { 1283 // COMPLETE IN TRANSFER 1284 EndPoint0CompleteRequest (pcd, req, desc); 1285 } 1286 break; 1287 #if 0 1288 case EP0_IN_WAIT_NRDY: 1289 case EP0_OUT_WAIT_NRDY: 1290 if (ep0->is_in) { 1291 SetupInStatusPhase (pcd, gEndPoint0SetupPacket); 1292 } else { 1293 SetupOutStatusPhase (pcd, gEndPoint0SetupPacket); 1294 } 1295 break; 1296 case EP0_IN_STATUS_PHASE: 1297 case EP0_OUT_STATUS_PHASE: 1298 if (ep0->is_in) { 1299 desc = pcd->ep0_in_desc; 1300 } else { 1301 desc = pcd->ep0_out_desc; 1302 } 1303 //ASSERT (0); 1304 EndPoint0CompleteRequest (pcd, req, desc); 1305 // skip test mode 1306 pcd->ep0state = EP0_IDLE; 1307 ep0->stopped = 1; 1308 ep0->is_in = 0; // OUT for next SETUP 1309 // prepare for more SETUP packets 1310 DwUsb3Ep0OutStart (pcd); 1311 break; 1312 #else 1313 case EP0_IN_WAIT_NRDY: 1314 if (ep0->is_in) { 1315 SetupInStatusPhase (pcd, gEndPoint0SetupPacket); 1316 } else { 1317 ASSERT (0); 1318 } 1319 break; 1320 case EP0_OUT_WAIT_NRDY: 1321 if (!ep0->is_in) { 1322 SetupOutStatusPhase (pcd, gEndPoint0SetupPacket); 1323 } else { 1324 ASSERT (0); 1325 } 1326 break; 1327 case EP0_IN_STATUS_PHASE: 1328 if (ep0->is_in) { 1329 desc = pcd->ep0_in_desc; 1330 } else { 1331 ASSERT (0); 1332 } 1333 EndPoint0CompleteRequest (pcd, req, desc); 1334 pcd->ep0state = EP0_IDLE; 1335 ep0->stopped = 1; 1336 ep0->is_in = 0; // OUT for next SETUP 1337 // prepare for more SETUP packets 1338 DwUsb3Ep0OutStart (pcd); 1339 break; 1340 case EP0_OUT_STATUS_PHASE: 1341 if (!ep0->is_in) { 1342 desc = pcd->ep0_out_desc; 1343 } else { 1344 ASSERT (0); 1345 } 1346 EndPoint0CompleteRequest (pcd, req, desc); 1347 pcd->ep0state = EP0_IDLE; 1348 ep0->stopped = 1; 1349 ep0->is_in = 0; // OUT for next SETUP 1350 // prepare for more SETUP packets 1351 DwUsb3Ep0OutStart (pcd); 1352 break; 1353 #endif 1354 case EP0_STALL: 1355 break; 1356 case EP0_IDLE: 1357 break; 1358 default: 1359 DEBUG ((DEBUG_ERROR, "%a: invalid state %d\n", __func__, pcd->ep0state)); 1360 break; 1361 } 1362 out: 1363 return; 1364 } 1365 1366 STATIC 1367 usb3_pcd_ep_t * 1368 Addr2EndPoint ( 1369 IN usb3_pcd_t *pcd, 1370 IN UINT16 index 1371 ) 1372 { 1373 UINT32 ep_num; 1374 1375 ep_num = UE_GET_ADDR (index); 1376 if (ep_num == 0) { 1377 return &pcd->ep0; 1378 } else { 1379 if (UE_GET_DIR (index) == UE_DIR_IN) { 1380 return &pcd->in_ep; 1381 } 1382 return &pcd->out_ep; 1383 } 1384 } 1385 1386 STATIC 1387 VOID 1388 DwUsb3DoGetStatus ( 1389 IN usb3_pcd_t *pcd 1390 ) 1391 { 1392 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1393 UINT8 *status = gEndPoint0StatusBuf; 1394 usb3_pcd_ep_t *ep; 1395 1396 if (ctrl->wLength != 2) { 1397 EndPoint0DoStall (pcd); 1398 return; 1399 } 1400 1401 switch (UT_GET_RECIPIENT (ctrl->bmRequestType)) { 1402 case UT_DEVICE: 1403 *status = 0; // bus powered 1404 if (pcd->speed == USB_SPEED_SUPER) { 1405 if (pcd->state == USB3_STATE_CONFIGURED) { 1406 if (MmioRead32 (DCTL) & DCTL_INIT_U1_EN) { 1407 *status |= 1 << 2; 1408 } 1409 if (MmioRead32 (DCTL) & DCTL_INIT_U2_EN) { 1410 *status |= 1 << 3; 1411 } 1412 *status |= (UINT8)(pcd->ltm_enable << 4); 1413 } 1414 } 1415 *(status + 1) = 0; 1416 break; 1417 case UT_INTERFACE: 1418 *status = 0; 1419 *(status + 1) = 0; 1420 break; 1421 case UT_ENDPOINT: 1422 ep = Addr2EndPoint (pcd, ctrl->wIndex); 1423 *status = ep->stopped; 1424 *(status + 1) = 0; 1425 break; 1426 default: 1427 EndPoint0DoStall (pcd); 1428 return; 1429 } 1430 pcd->ep0_req.bufdma = (UINT64 *)status; 1431 pcd->ep0_req.length = 2; 1432 pcd->ep0_req.actual = 0; 1433 DwUsb3EndPoint0StartTransfer (pcd, &pcd->ep0_req); 1434 } 1435 1436 STATIC 1437 VOID 1438 DoClearHalt ( 1439 IN usb3_pcd_t *pcd, 1440 IN usb3_pcd_ep_t *ep 1441 ) 1442 { 1443 if (ep->is_in) { 1444 DwUsb3DepClearStall (EP_IN_IDX (ep->num)); 1445 } else { 1446 DwUsb3DepClearStall (EP_OUT_IDX (ep->num)); 1447 } 1448 if (ep->stopped) { 1449 ep->stopped = 0; 1450 } 1451 } 1452 1453 STATIC 1454 VOID 1455 Usb3PcdEpEnable ( 1456 IN usb3_pcd_t *pcd, 1457 IN usb3_pcd_ep_t *ep 1458 ) 1459 { 1460 // activate the EP 1461 ep->stopped = 0; 1462 ep->xfer_started = 0; 1463 ep->ep_desc->control = 0; 1464 ep->ep_desc->status = 0; 1465 // set initial data pid. 1466 if (ep->type == EPTYPE_BULK) { 1467 ep->data_pid_start = 0; 1468 } 1469 DwUsb3EpActivate (pcd, ep); 1470 } 1471 1472 STATIC 1473 VOID 1474 DwUsb3DoClearFeature ( 1475 IN usb3_pcd_t *pcd 1476 ) 1477 { 1478 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1479 usb3_pcd_ep_t *ep; 1480 1481 switch (UT_GET_RECIPIENT (ctrl->bmRequestType)) { 1482 case UT_DEVICE: 1483 switch (ctrl->wValue) { 1484 case UF_U1_ENABLE: 1485 if ((pcd->speed != USB_SPEED_SUPER) || 1486 (pcd->state != USB3_STATE_CONFIGURED)) { 1487 EndPoint0DoStall (pcd); 1488 return; 1489 } 1490 MmioAnd32 (DCTL, ~DCTL_INIT_U1_EN); 1491 break; 1492 case UF_U2_ENABLE: 1493 if ((pcd->speed != USB_SPEED_SUPER) || 1494 (pcd->state != USB3_STATE_CONFIGURED)) { 1495 EndPoint0DoStall (pcd); 1496 return; 1497 } 1498 MmioAnd32 (DCTL, ~DCTL_INIT_U2_EN); 1499 break; 1500 case UF_LTM_ENABLE: 1501 if ((pcd->speed != USB_SPEED_SUPER) || 1502 (pcd->state != USB3_STATE_CONFIGURED) || 1503 (ctrl->wIndex != 0)) { 1504 EndPoint0DoStall (pcd); 1505 return; 1506 } 1507 pcd->ltm_enable = 0; 1508 break; 1509 default: 1510 EndPoint0DoStall (pcd); 1511 return; 1512 } 1513 break; 1514 case UT_INTERFACE: 1515 // if FUNCTION_SUSPEND 1516 if (ctrl->wValue) { 1517 EndPoint0DoStall (pcd); 1518 return; 1519 } 1520 break; 1521 case UT_ENDPOINT: 1522 ep = Addr2EndPoint (pcd, ctrl->wIndex); 1523 if (ctrl->wValue != UF_ENDPOINT_HALT) { 1524 EndPoint0DoStall (pcd); 1525 return; 1526 } 1527 DoClearHalt (pcd, ep); 1528 break; 1529 default: 1530 DEBUG ((DEBUG_ERROR, "invalid bmRequestType :%d\n", UT_GET_RECIPIENT (ctrl->bmRequestType))); 1531 break; 1532 } 1533 pcd->ep0.is_in = 1; 1534 pcd->ep0state = EP0_IN_WAIT_NRDY; 1535 } 1536 1537 STATIC 1538 VOID 1539 DwUsb3DoSetFeature ( 1540 IN usb3_pcd_t *pcd 1541 ) 1542 { 1543 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1544 usb3_pcd_ep_t *ep; 1545 1546 switch (UT_GET_RECIPIENT (ctrl->bmRequestType)) { 1547 case UT_DEVICE: 1548 switch (ctrl->wValue) { 1549 case UF_DEVICE_REMOTE_WAKEUP: 1550 break; 1551 case UF_TEST_MODE: 1552 pcd->test_mode_nr = ctrl->wIndex >> 8; 1553 pcd->test_mode = 1; 1554 break; 1555 case UF_U1_ENABLE: 1556 if ((pcd->speed != USB_SPEED_SUPER) || 1557 (pcd->state != USB3_STATE_CONFIGURED)) { 1558 EndPoint0DoStall (pcd); 1559 return; 1560 } 1561 MmioOr32 (DCTL, DCTL_INIT_U1_EN); 1562 break; 1563 case UF_U2_ENABLE: 1564 if ((pcd->speed != USB_SPEED_SUPER) || 1565 (pcd->state != USB3_STATE_CONFIGURED)) { 1566 EndPoint0DoStall (pcd); 1567 return; 1568 } 1569 MmioOr32 (DCTL, DCTL_INIT_U2_EN); 1570 break; 1571 case UF_LTM_ENABLE: 1572 if ((pcd->speed != USB_SPEED_SUPER) || 1573 (pcd->state != USB3_STATE_CONFIGURED) || 1574 (ctrl->wIndex != 0)) { 1575 EndPoint0DoStall (pcd); 1576 return; 1577 } 1578 pcd->ltm_enable = 1; 1579 break; 1580 default: 1581 EndPoint0DoStall (pcd); 1582 return; 1583 } 1584 break; 1585 case UT_INTERFACE: 1586 // if FUNCTION_SUSPEND 1587 if (ctrl->wValue) { 1588 EndPoint0DoStall (pcd); 1589 return; 1590 } 1591 break; 1592 case UT_ENDPOINT: 1593 ep = Addr2EndPoint (pcd, ctrl->wIndex); 1594 if (ctrl->wValue != UF_ENDPOINT_HALT) { 1595 EndPoint0DoStall (pcd); 1596 return; 1597 } 1598 ep->stopped = 1; 1599 if (ep->is_in) { 1600 DwUsb3DepClearStall (EP_IN_IDX (ep->num)); 1601 } else { 1602 DwUsb3DepClearStall (EP_OUT_IDX (ep->num)); 1603 } 1604 break; 1605 default: 1606 DEBUG ((DEBUG_ERROR, "invalid bmRequestType %d\n", UT_GET_RECIPIENT (ctrl->bmRequestType))); 1607 break; 1608 } 1609 pcd->ep0.is_in = 1; 1610 pcd->ep0state = EP0_IN_WAIT_NRDY; 1611 } 1612 1613 STATIC 1614 VOID 1615 DwUsb3DoSetAddress ( 1616 IN usb3_pcd_t *pcd 1617 ) 1618 { 1619 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1620 1621 if (ctrl->bmRequestType == UT_DEVICE) { 1622 SET_DEVADDR (ctrl->wValue); 1623 pcd->ep0.is_in = 1; 1624 pcd->ep0state = EP0_IN_WAIT_NRDY; 1625 if (ctrl->wValue) { 1626 pcd->state = USB3_STATE_ADDRESSED; 1627 } else { 1628 pcd->state = USB3_STATE_DEFAULT; 1629 } 1630 } 1631 } 1632 1633 #if 0 1634 STATIC 1635 UINTN 1636 UsbStatus ( 1637 IN UINTN online, 1638 IN UINTN speed 1639 ) 1640 { 1641 if (online) { 1642 } 1643 1644 VOID 1645 DwUsb3SetConfig ( 1646 IN usb3_pcd_t *pcd 1647 ) 1648 { 1649 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1650 UINT16 wvalue = ctrl->wValue; 1651 usb3_pcd_ep_t *ep; 1652 1653 DEBUG ((DEBUG_ERROR, "#%a, %d, wvalue:0x%x\n", __func__, __LINE__, wvalue)); 1654 if (ctrl->bmRequestType != (UT_WRITE | UT_STANDARD | UT_DEVICE)) { 1655 EndPoint0DoStall (pcd); 1656 return; 1657 } 1658 1659 if (!wvalue || (wvalue == CONFIG_VALUE)) { 1660 UINT32 speed; 1661 pcd->new_config = (UINT8)wvalue; 1662 // set new configuration 1663 if (wvalue) { 1664 // activate bulk in endpoint 1665 ep = &pcd->in_ep; 1666 Usb3PcdEpEnable (pcd, ep); 1667 // activate bulk out endpoint 1668 ep = &pcd->out_ep; 1669 Usb3PcdEpEnable (pcd, ep); 1670 // prepare for next bulk transfer 1671 speed = DwUsb3GetDeviceSpeed (pcd); 1672 (VOID)speed; 1673 1674 #if 0 1675 if (g_usb_ops->status) { 1676 g_usb_ops->status (ctrl->wValue ? 1 : 0, 1677 speed == USB_SPEED_SUPER ? USB_SS : speed == USB_SPEED_HIGH ? USB_HS : USB_FS); 1678 } 1679 usb_status (); 1680 #endif 1681 pcd->state = USB3_STATE_CONFIGURED; 1682 } else { 1683 pcd->state = USB3_STATE_ADDRESSED; 1684 } 1685 DEBUG ((DEBUG_ERROR, "#%a, %d, state:%d\n", __func__, __LINE__, pcd->state)); 1686 pcd->ep0.is_in = 1; 1687 pcd->ep0state = EP0_IN_WAIT_NRDY; 1688 } else { 1689 EndPoint0DoStall (pcd); 1690 } 1691 } 1692 #endif 1693 1694 STATIC 1695 VOID 1696 DwUsb3DoGetConfig ( 1697 IN usb3_pcd_t *pcd 1698 ) 1699 { 1700 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1701 UINT8 *status = gEndPoint0StatusBuf; 1702 1703 if (ctrl->bmRequestType != (UT_READ | UT_STANDARD | UT_DEVICE)) { 1704 EndPoint0DoStall (pcd); 1705 return; 1706 } 1707 // Notify host the current config value 1708 *status = pcd->new_config; 1709 pcd->ep0_req.bufdma = (UINT64 *)status; 1710 pcd->ep0_req.length = 1; 1711 pcd->ep0_req.actual = 0; 1712 DwUsb3EndPoint0StartTransfer (pcd, &pcd->ep0_req); 1713 } 1714 1715 STATIC 1716 VOID 1717 DwUsb3DoSetConfig ( 1718 IN usb3_pcd_t *pcd 1719 ) 1720 { 1721 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1722 UINT16 wvalue = ctrl->wValue; 1723 usb3_pcd_ep_t *ep; 1724 1725 if (ctrl->bmRequestType != (UT_WRITE | UT_STANDARD | UT_DEVICE)) { 1726 EndPoint0DoStall (pcd); 1727 return; 1728 } 1729 1730 if (!wvalue || (wvalue == CONFIG_VALUE)) { 1731 //UINT32 speed; 1732 1733 pcd->new_config = (UINT8)wvalue; 1734 // set new configuration 1735 if (wvalue) { 1736 // activate bulk in endpoint 1737 ep = &pcd->in_ep; 1738 Usb3PcdEpEnable (pcd, ep); 1739 // activate bulk out endpoint 1740 ep = &pcd->out_ep; 1741 Usb3PcdEpEnable (pcd, ep); 1742 #if 0 1743 // prepare for next bulk transfer 1744 speed = DwUsb3GetDeviceSpeed (pcd); 1745 (VOID)speed; 1746 g_usb_ops->status 1747 #endif 1748 pcd->state = USB3_STATE_CONFIGURED; 1749 { 1750 // prepare for EP1 OUT 1751 usb3_pcd_ep_t *ep = &pcd->out_ep; 1752 usb3_pcd_req_t *req = &ep->req; 1753 1754 // AndroidFast App will free the rx buffer. 1755 gRxBuf = AllocatePool (DATA_SIZE); 1756 ASSERT (gRxBuf != NULL); 1757 WriteBackDataCacheRange (gRxBuf, DATA_SIZE); 1758 req->bufdma = (UINT64 *)gRxBuf; 1759 if (mDataBufferSize == 0) { 1760 req->length = CMD_SIZE; 1761 } else if (mDataBufferSize > DATA_SIZE) { 1762 req->length = DATA_SIZE; 1763 mDataBufferSize = mDataBufferSize - DATA_SIZE; 1764 } else if (mDataBufferSize > CMD_SIZE) { 1765 req->length = CMD_SIZE; 1766 mDataBufferSize = mDataBufferSize - CMD_SIZE; 1767 } else { 1768 req->length = mDataBufferSize; 1769 mDataBufferSize = 0; 1770 } 1771 DwUsb3EndPointXStartTransfer (pcd, ep); 1772 } 1773 } else { 1774 pcd->state = USB3_STATE_ADDRESSED; 1775 } 1776 pcd->ep0.is_in = 1; 1777 pcd->ep0state = EP0_IN_WAIT_NRDY; 1778 } else { 1779 EndPoint0DoStall (pcd); 1780 } 1781 } 1782 1783 STATIC 1784 VOID 1785 DwUsb3DoGetDescriptor ( 1786 IN usb3_pcd_t *pcd 1787 ) 1788 { 1789 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1790 UINT8 dt = ctrl->wValue >> 8; 1791 UINT8 index = (UINT8)ctrl->wValue; 1792 UINT16 len = ctrl->wLength; 1793 UINT8 *buf = gEndPoint0StatusBuf; 1794 UINT16 value = 0; 1795 EFI_USB_STRING_DESCRIPTOR *Descriptor = NULL; 1796 1797 if (ctrl->bmRequestType != (UT_READ | UT_STANDARD | UT_DEVICE)) { 1798 EndPoint0DoStall (pcd); 1799 return; 1800 } 1801 1802 switch (dt) { 1803 case UDESC_DEVICE: 1804 { 1805 struct usb_device_descriptor *dev = &gDwUsb3DevDesc; 1806 dev->bLength = sizeof (struct usb_device_descriptor); 1807 dev->bDescriptorType = UDESC_DEVICE; 1808 dev->bDeviceClass = 0; 1809 dev->bDeviceSubClass = 0; 1810 dev->bDeviceProtocol = 0; 1811 if (pcd->speed == USB_SPEED_SUPER) { 1812 dev->bcdUSB = 0x300; 1813 // 2^9 = 512 1814 dev->bMaxPacketSize0 = 9; 1815 } else { 1816 dev->bcdUSB = 0x0200; 1817 dev->bMaxPacketSize0 = 0x40; 1818 } 1819 dev->idVendor = usb_port_activity_config.idVendor; 1820 dev->idProduct = usb_port_activity_config.idProduct; 1821 dev->bcdDevice = 0x0100; 1822 dev->iManufacturer = STRING_MANUFACTURER; 1823 dev->iProduct = STRING_PRODUCT; 1824 dev->iSerialNumber = STRING_SERIAL; 1825 dev->bNumConfigurations = 1; 1826 value = sizeof (struct usb_device_descriptor); 1827 CopyMem ((void *)buf, (void *)dev, value); 1828 } 1829 break; 1830 case UDESC_DEVICE_QUALIFIER: 1831 { 1832 struct usb_qualifier_descriptor *qual = (struct usb_qualifier_descriptor *)buf; 1833 struct usb_device_descriptor *dev = &gDwUsb3DevDesc; 1834 1835 qual->bLength = sizeof (*qual); 1836 qual->bDescriptorType = UDESC_DEVICE_QUALIFIER; 1837 qual->bcdUSB = dev->bcdUSB; 1838 qual->bDeviceClass = dev->bDeviceClass; 1839 qual->bDeviceSubClass = dev->bDeviceSubClass; 1840 qual->bDeviceProtocol = dev->bDeviceProtocol; 1841 qual->bMaxPacketSize0 = dev->bMaxPacketSize0; 1842 qual->bNumConfigurations = 1; 1843 qual->bRESERVED = 0; 1844 value = sizeof (struct usb_qualifier_descriptor); 1845 } 1846 break; 1847 1848 case UDESC_CONFIG: 1849 { 1850 struct usb_config_descriptor *config = (struct usb_config_descriptor *)buf; 1851 1852 config->bLength = sizeof (*config); 1853 config->bDescriptorType = UDESC_CONFIG; 1854 config->bNumInterfaces = 1; 1855 config->bConfigurationValue = 1; 1856 config->iConfiguration = 0; 1857 config->bmAttributes = USB_CONFIG_ATT_ONE; 1858 1859 if (pcd->speed == USB_SPEED_SUPER) { 1860 config->bMaxPower = 0x50; 1861 } else { 1862 config->bMaxPower = 0x80; 1863 } 1864 buf += sizeof (*config); 1865 1866 intf.bInterfaceSubClass = usb_port_activity_config.bInterfaceSubClass; 1867 intf.bInterfaceProtocol = usb_port_activity_config.bInterfaceProtocol; 1868 CopyMem ((void *)buf, (void *)&intf, sizeof (intf)); 1869 buf += sizeof (intf); 1870 1871 switch (pcd->speed) { 1872 case USB_SPEED_SUPER: 1873 CopyMem (buf, &ss_bulk_in, sizeof (ss_bulk_in)); 1874 buf += sizeof (ss_bulk_in); 1875 CopyMem (buf, &ep_comp, sizeof (ep_comp)); 1876 buf += sizeof (ep_comp); 1877 CopyMem (buf, &ss_bulk_out, sizeof (ss_bulk_out)); 1878 buf += sizeof (ss_bulk_out); 1879 CopyMem (buf, &ep_comp, sizeof (ep_comp)); 1880 1881 config->wTotalLength = sizeof (*config) + sizeof (intf) + sizeof (ss_bulk_in) + 1882 sizeof (ep_comp) + sizeof (ss_bulk_out) + sizeof (ep_comp); 1883 break; 1884 1885 default: // HS/FS 1886 { 1887 struct usb_endpoint_descriptor *endp = (struct usb_endpoint_descriptor *)buf; 1888 1889 CopyMem (buf, &hs_bulk_in, sizeof (hs_bulk_in)); 1890 (endp++)->wMaxPacketSize = pcd->in_ep.maxpacket; 1891 buf += sizeof (hs_bulk_in); 1892 CopyMem (buf, &hs_bulk_out, sizeof (hs_bulk_out)); 1893 endp->wMaxPacketSize = pcd->out_ep.maxpacket; 1894 config->wTotalLength = sizeof (*config) + sizeof (intf) + sizeof (hs_bulk_in) + 1895 sizeof (hs_bulk_out); 1896 break; 1897 } 1898 } 1899 value = config->wTotalLength; 1900 } 1901 break; 1902 1903 case UDESC_STRING: 1904 { 1905 switch (index) { 1906 case STRING_LANGUAGE: 1907 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)(UINTN)gEndPoint0StatusBuf; 1908 ASSERT (Descriptor != NULL); 1909 Descriptor->Length = LANG_LENGTH * sizeof (CHAR16); 1910 Descriptor->DescriptorType = USB_DESC_TYPE_STRING; 1911 DwUsb->GetLang (Descriptor->String, &Descriptor->Length); 1912 value = Descriptor->Length; 1913 break; 1914 case STRING_MANUFACTURER: 1915 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)(UINTN)gEndPoint0StatusBuf; 1916 ASSERT (Descriptor != NULL); 1917 Descriptor->Length = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16); 1918 Descriptor->DescriptorType = USB_DESC_TYPE_STRING; 1919 DwUsb->GetManuFacturer (Descriptor->String, &Descriptor->Length); 1920 value = Descriptor->Length; 1921 break; 1922 case STRING_PRODUCT: 1923 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)(UINTN)gEndPoint0StatusBuf; 1924 ASSERT (Descriptor != NULL); 1925 Descriptor->Length = PRODUCT_STRING_LENGTH * sizeof (CHAR16); 1926 Descriptor->DescriptorType = USB_DESC_TYPE_STRING; 1927 DwUsb->GetProduct (Descriptor->String, &Descriptor->Length); 1928 value = Descriptor->Length; 1929 break; 1930 case STRING_SERIAL: 1931 Descriptor = (EFI_USB_STRING_DESCRIPTOR *)(UINTN)gEndPoint0StatusBuf; 1932 ASSERT (Descriptor != NULL); 1933 Descriptor->Length = SERIAL_STRING_LENGTH * sizeof (CHAR16); 1934 Descriptor->DescriptorType = USB_DESC_TYPE_STRING; 1935 DwUsb->GetSerialNo (Descriptor->String, &Descriptor->Length); 1936 value = Descriptor->Length; 1937 break; 1938 default: 1939 EndPoint0DoStall (pcd); 1940 break; 1941 } 1942 } 1943 break; 1944 1945 case UDESC_BOS: 1946 if (pcd->speed != USB_SPEED_SUPER) { 1947 EndPoint0DoStall (pcd); 1948 return; 1949 } 1950 value = bos.wTotalLength; 1951 CopyMem (buf, &bos, sizeof (bos)); 1952 buf += sizeof (bos); 1953 CopyMem (buf, &cap1, sizeof (cap1)); 1954 buf += sizeof (cap1); 1955 CopyMem (buf, &cap2, sizeof (cap2)); 1956 buf += sizeof (cap2); 1957 CopyMem (buf, &cap3, sizeof (cap3)); 1958 break; 1959 default: 1960 EndPoint0DoStall (pcd); 1961 return; 1962 } 1963 pcd->ep0_req.bufdma = (UINT64 *)gEndPoint0StatusBuf; 1964 pcd->ep0_req.length = value < len ? value : len; 1965 pcd->ep0_req.actual = 0; 1966 DwUsb3EndPoint0StartTransfer (pcd, &pcd->ep0_req); 1967 } 1968 1969 STATIC 1970 VOID 1971 DwUsb3DoSetup ( 1972 IN usb3_pcd_t *pcd 1973 ) 1974 { 1975 usb_device_request_t *ctrl = &gEndPoint0SetupPacket->req; 1976 usb3_pcd_ep_t *ep0 = &pcd->ep0; 1977 UINT16 wLength; 1978 1979 wLength = ctrl->wLength; 1980 ep0->stopped = 0; 1981 ep0->three_stage = 1; 1982 if (ctrl->bmRequestType & UE_DIR_IN) { 1983 ep0->is_in = 1; 1984 pcd->ep0state = EP0_IN_DATA_PHASE; 1985 } else { 1986 ep0->is_in = 0; 1987 pcd->ep0state = EP0_OUT_DATA_PHASE; 1988 } 1989 1990 if (wLength == 0) { 1991 ep0->is_in = 1; 1992 pcd->ep0state = EP0_IN_WAIT_NRDY; 1993 ep0->three_stage = 0; 1994 } 1995 if (UT_GET_TYPE (ctrl->bmRequestType) != UT_STANDARD) { 1996 EndPoint0DoStall (pcd); 1997 return; 1998 } 1999 2000 switch (ctrl->bRequest) { 2001 case UR_GET_STATUS: 2002 DwUsb3DoGetStatus (pcd); 2003 break; 2004 case UR_CLEAR_FEATURE: 2005 DwUsb3DoClearFeature (pcd); 2006 break; 2007 case UR_SET_FEATURE: 2008 DwUsb3DoSetFeature (pcd); 2009 break; 2010 case UR_SET_ADDRESS: 2011 DwUsb3DoSetAddress (pcd); 2012 break; 2013 case UR_SET_CONFIG: 2014 DwUsb3DoSetConfig (pcd); 2015 MmioOr32 (DCTL, DCTL_ACCEPT_U1_EN); 2016 MmioOr32 (DCTL, DCTL_ACCEPT_U2_EN); 2017 DEBUG ((DEBUG_INFO, "enum done")); 2018 pcd->ltm_enable = 0; 2019 break; 2020 case UR_GET_CONFIG: 2021 DwUsb3DoGetConfig (pcd); 2022 break; 2023 case UR_GET_DESCRIPTOR: 2024 DwUsb3DoGetDescriptor (pcd); 2025 break; 2026 case UR_SET_SEL: 2027 // for now this is a no-op 2028 pcd->ep0_req.bufdma = (UINT64 *)gEndPoint0StatusBuf; 2029 pcd->ep0_req.length = USB3_STATUS_BUF_SIZE; 2030 pcd->ep0_req.actual = 0; 2031 ep0->send_zlp = 0; 2032 DwUsb3EndPoint0StartTransfer (pcd, &pcd->ep0_req); 2033 break; 2034 default: 2035 EndPoint0DoStall (pcd); 2036 break; 2037 } 2038 } 2039 2040 STATIC 2041 VOID 2042 DwUsb3OsHandleEndPoint0 ( 2043 IN usb3_pcd_t *pcd, 2044 IN UINT32 event 2045 ) 2046 { 2047 if (pcd->ep0state == EP0_IDLE) { 2048 DwUsb3DoSetup (pcd); 2049 } else { 2050 DwUsb3HandleEndPoint0 (pcd, NULL, event); 2051 } 2052 } 2053 2054 STATIC 2055 VOID 2056 DwUsb3RequestDone ( 2057 IN usb3_pcd_t *pcd, 2058 IN usb3_pcd_ep_t *ep, 2059 IN usb3_pcd_req_t *req, 2060 IN UINTN status 2061 ) 2062 { 2063 if (ep != &pcd->ep0) { 2064 req->trb = NULL; 2065 } 2066 if (req->complete) { 2067 req->complete (req->actual, status); 2068 } else { 2069 if (!ep->is_in) { 2070 ASSERT (req->actual <= req->length); 2071 InvalidateDataCacheRange (gRxBuf, req->actual); 2072 mDataReceivedCallback (req->actual, gRxBuf); 2073 } 2074 } 2075 req->actual = 0; 2076 } 2077 2078 STATIC 2079 VOID 2080 DwUsb3EndPointcompleteRequest ( 2081 IN usb3_pcd_t *pcd, 2082 IN usb3_pcd_ep_t *ep, 2083 IN UINT32 event 2084 ) 2085 { 2086 usb3_pcd_req_t *req = &ep->req; 2087 usb3_dma_desc_t *desc = req->trb; 2088 UINT32 byte_count; 2089 2090 ep->send_zlp = 0; 2091 if (!desc) { 2092 return; 2093 } 2094 2095 if (desc->control & DSCCTL_HWO) { 2096 return; 2097 } 2098 2099 if (ep->is_in) { 2100 // IN ep 2101 if (GET_DSCSTS_XFERCNT (desc->status) == 0) { 2102 req->actual += req->length; 2103 } 2104 // reset IN tri 2105 ep->tri_in = 0; 2106 // complete the IN request 2107 // flush for dma? 2108 DwUsb3RequestDone (pcd, ep, req, 0); 2109 } else { 2110 // OUT ep 2111 byte_count = req->length - GET_DSCSTS_XFERCNT (desc->status); 2112 req->actual += byte_count; 2113 //req->bufdma += byte_count; 2114 // reset OUT tri 2115 ep->tri_out = 0; 2116 // OUT transfer complete or not 2117 // complete the OUT request 2118 // FIXME flush dma? 2119 DwUsb3RequestDone (pcd, ep, req, 0); 2120 { 2121 // prepare for EP1 OUT 2122 usb3_pcd_ep_t *ep = &pcd->out_ep; 2123 usb3_pcd_req_t *req = &ep->req; 2124 2125 ZeroMem (req, sizeof (usb3_pcd_req_t)); 2126 gRxBuf = AllocatePool (DATA_SIZE); 2127 ASSERT (gRxBuf != NULL); 2128 WriteBackDataCacheRange (gRxBuf, DATA_SIZE); 2129 req->bufdma = (UINT64 *)gRxBuf; 2130 if (mDataBufferSize == 0) { 2131 req->length = CMD_SIZE; 2132 } else if (mDataBufferSize > DATA_SIZE) { 2133 req->length = DATA_SIZE; 2134 mDataBufferSize = mDataBufferSize - DATA_SIZE; 2135 } else if (mDataBufferSize > CMD_SIZE) { 2136 req->length = CMD_SIZE; 2137 mDataBufferSize = mDataBufferSize - CMD_SIZE; 2138 } else { 2139 req->length = mDataBufferSize; 2140 mDataBufferSize = 0; 2141 } 2142 DwUsb3EndPointXStartTransfer (pcd, ep); 2143 } 2144 } 2145 } 2146 2147 STATIC 2148 VOID 2149 DwUsb3HandleEndPointInterrupt ( 2150 IN usb3_pcd_t *pcd, 2151 IN UINTN PhySep, 2152 IN UINT32 event 2153 ) 2154 { 2155 usb3_pcd_ep_t *ep; 2156 UINT32 epnum, is_in; 2157 2158 // Physical Out EPs are even, physical In EPs are odd 2159 is_in = (UINT32)PhySep & 1; 2160 epnum = ((UINT32)PhySep >> 1) & 0xF; 2161 2162 // Get the EP pointer 2163 if (is_in) { 2164 ep = DwUsb3GetInEndPoint (pcd, epnum); 2165 } else { 2166 ep = DwUsb3GetOutEndPoint (pcd, epnum); 2167 } 2168 2169 switch (event & GEVNT_DEPEVT_INTTYPE_MASK) { 2170 case GEVNT_DEPEVT_INTTYPE_XFER_CMPL: 2171 ep->xfer_started = 0; 2172 // complete the transfer 2173 if (epnum == 0) { 2174 DwUsb3OsHandleEndPoint0 (pcd, event); 2175 } else { 2176 DwUsb3EndPointcompleteRequest (pcd, ep, event); 2177 } 2178 break; 2179 case GEVNT_DEPEVT_INTTYPE_XFER_IN_PROG: 2180 break; 2181 case GEVNT_DEPEVT_INTTYPE_XFER_NRDY: 2182 if (epnum == 0) { 2183 switch (pcd->ep0state) { 2184 #if 1 2185 case EP0_IN_WAIT_NRDY: 2186 if (is_in) { 2187 DwUsb3OsHandleEndPoint0 (pcd, event); 2188 } else { 2189 } 2190 break; 2191 case EP0_OUT_WAIT_NRDY: 2192 if (!is_in) { 2193 DwUsb3OsHandleEndPoint0 (pcd, event); 2194 } else { 2195 } 2196 break; 2197 #else 2198 case EP0_IN_WAIT_NRDY: 2199 case EP0_OUT_WAIT_NRDY: 2200 DwUsb3OsHandleEndPoint0 (pcd, event); 2201 break; 2202 #endif 2203 default: 2204 break; 2205 } 2206 } else { 2207 } 2208 break; 2209 default: 2210 DEBUG ((DEBUG_ERROR, "invalid event %d\n", event & GEVNT_DEPEVT_INTTYPE_MASK)); 2211 break; 2212 } 2213 } 2214 2215 STATIC 2216 UINTN 2217 DwUsb3HandleEvent ( 2218 VOID 2219 ) 2220 { 2221 usb3_pcd_t *pcd = &gPcd; 2222 UINT32 Count, Index, Event, Intr; 2223 UINT32 PhySep; 2224 2225 Count = GET_EVENTBUF_COUNT (); 2226 // reset event buffer when it's full 2227 if ((GEVNTCOUNT_EVNTCOUNT (Count) == GEVNTCOUNT_EVNTCOUNT_MASK) || 2228 (Count >= DWUSB3_EVENT_BUF_SIZE * sizeof (UINT32))) { 2229 UPDATE_EVENTBUF_COUNT (Count); 2230 Count = 0; 2231 } 2232 2233 for (Index = 0; Index < Count; Index += sizeof (UINT32)) { 2234 Event = DwUsb3GetEventBufEvent (DWUSB3_EVENT_BUF_SIZE << 2); 2235 UPDATE_EVENTBUF_COUNT (sizeof (UINT32)); 2236 if (Event == 0) { 2237 // ignore null events 2238 continue; 2239 } 2240 if (Event & GEVNT_NON_EP) { 2241 Intr = Event & GEVNT_INTTYPE_MASK; 2242 if (Intr == GEVNT_INTTYPE (EVENT_DEV_INT)) { 2243 DwUsb3HandleDeviceInterrupt (pcd, Event); 2244 } 2245 } else { 2246 PhySep = (Event & GEVNT_DEPEVT_EPNUM_MASK) >> GEVNT_DEPEVT_EPNUM_SHIFT; 2247 DwUsb3HandleEndPointInterrupt (pcd, PhySep, Event); 2248 } 2249 } 2250 return 0; 2251 } 2252 2253 STATIC 2254 VOID 2255 DwUsb3Poll ( 2256 IN EFI_EVENT Event, 2257 IN VOID *Context 2258 ) 2259 { 2260 if (DwUsb3HandleEvent ()) { 2261 DEBUG ((DEBUG_ERROR, "error: exit from usb_poll\n")); 2262 return; 2263 } 2264 } 2265 2266 EFI_STATUS 2267 EFIAPI 2268 DwUsb3Start ( 2269 IN USB_DEVICE_DESCRIPTOR *DeviceDescriptor, 2270 IN VOID **Descriptors, 2271 IN USB_DEVICE_RX_CALLBACK RxCallback, 2272 IN USB_DEVICE_TX_CALLBACK TxCallback 2273 ) 2274 { 2275 EFI_STATUS Status; 2276 EFI_EVENT TimerEvent; 2277 2278 //gEventBuf = UncachedAllocateAlignedZeroPool (DWUSB3_EVENT_BUF_SIZE << 2, 256); 2279 gEventBuf = UncachedAllocatePages (EFI_SIZE_TO_PAGES (DWUSB3_EVENT_BUF_SIZE << 2)); 2280 if (gEventBuf == NULL) { 2281 return EFI_OUT_OF_RESOURCES; 2282 } 2283 ZeroMem (gEventBuf, EFI_SIZE_TO_PAGES (DWUSB3_EVENT_BUF_SIZE << 2)); 2284 gEventPtr = gEventBuf; 2285 DriverInit (); 2286 DwUsb3Init (); 2287 Status = gBS->CreateEvent ( 2288 EVT_TIMER | EVT_NOTIFY_SIGNAL, 2289 TPL_CALLBACK, 2290 DwUsb3Poll, 2291 NULL, 2292 &TimerEvent 2293 ); 2294 ASSERT_EFI_ERROR (Status); 2295 if (EFI_ERROR (Status)) { 2296 return Status; 2297 } 2298 2299 Status = gBS->SetTimer ( 2300 TimerEvent, 2301 TimerPeriodic, 2302 DW_INTERRUPT_POLL_PERIOD 2303 ); 2304 ASSERT_EFI_ERROR (Status); 2305 mDataReceivedCallback = RxCallback; 2306 return Status; 2307 } 2308 2309 EFI_STATUS 2310 DwUsb3Send ( 2311 IN UINT8 EndpointIndex, 2312 IN UINTN Size, 2313 IN CONST VOID *Buffer 2314 ) 2315 { 2316 usb3_pcd_t *pcd = &gPcd; 2317 usb3_pcd_ep_t *ep = &pcd->in_ep; 2318 usb3_pcd_req_t *req = &ep->req; 2319 2320 WriteBackDataCacheRange ((VOID *)Buffer, Size); 2321 req->bufdma = (UINT64 *)Buffer; 2322 req->length = Size; 2323 DwUsb3EndPointXStartTransfer (pcd, ep); 2324 return EFI_SUCCESS; 2325 } 2326 2327 EFI_STATUS 2328 DwUsb3Request ( 2329 IN UINTN BufferSize 2330 ) 2331 { 2332 if (BufferSize) { 2333 mDataBufferSize = BufferSize; 2334 } 2335 return EFI_SUCCESS; 2336 } 2337 2338 USB_DEVICE_PROTOCOL mUsbDevice = { 2339 DwUsb3Start, 2340 DwUsb3Send, 2341 DwUsb3Request 2342 }; 2343 2344 EFI_STATUS 2345 EFIAPI 2346 DwUsb3EntryPoint ( 2347 IN EFI_HANDLE ImageHandle, 2348 IN EFI_SYSTEM_TABLE *SystemTable 2349 ) 2350 { 2351 EFI_STATUS Status; 2352 2353 gEndPoint0SetupPacket = UncachedAllocatePages (EFI_SIZE_TO_PAGES (sizeof (usb_setup_pkt_t) * 5)); 2354 if (gEndPoint0SetupPacket == NULL) { 2355 return EFI_OUT_OF_RESOURCES; 2356 } 2357 gEndPoint0StatusBuf = UncachedAllocatePages (EFI_SIZE_TO_PAGES (USB3_STATUS_BUF_SIZE * sizeof (UINT8))); 2358 if (gEndPoint0StatusBuf == NULL) { 2359 return EFI_OUT_OF_RESOURCES; 2360 } 2361 #if 0 2362 gRxBuf = UncachedAllocatePages (1); 2363 if (gRxBuf == NULL) { 2364 return EFI_OUT_OF_RESOURCES; 2365 } 2366 #endif 2367 Status = gBS->LocateProtocol (&gDwUsbProtocolGuid, NULL, (VOID **) &DwUsb); 2368 if (EFI_ERROR (Status)) { 2369 return Status; 2370 } 2371 Status = DwUsb->PhyInit(USB_DEVICE_MODE); 2372 if (EFI_ERROR (Status)) { 2373 return Status; 2374 } 2375 2376 return gBS->InstallProtocolInterface ( 2377 &ImageHandle, 2378 &gUsbDeviceProtocolGuid, 2379 EFI_NATIVE_INTERFACE, 2380 &mUsbDevice 2381 ); 2382 } 2383