3 Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
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
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.
15 #include <Library/DebugLib.h>
16 #include <Library/UefiBootServicesTableLib.h>
17 #include <Library/UefiDriverEntryPoint.h>
18 #include <Library/IoLib.h>
19 #include <Library/MemoryAllocationLib.h>
21 #include <IndustryStandard/Usb.h>
23 #include <Protocol/UsbDevice.h>
25 #include "Isp1761UsbDxe.h"
28 Driver for using the NXP ISP1761 as a USB Peripheral controller.
29 Doesn't use USB OTG - just sets it in Pure Peripheral mode.
31 The ISP1582 datasheet has a little more info on the Peripheral controller
32 registers than the ISP1761 datasheet
34 We don't do string descriptors. They're optional.
35 We currently assume the device has one configuration, one interface, one IN
36 endpoint, and one OUT endpoint (plus the default control endpoint).
38 In fact, this driver is the minimum required to implement fastboot.
41 // TODO Make sure the controller isn't sending empty packets when it shouldn't
42 // (check behaviour in cases when Buffer Length isn't explcitly set)
45 // "Data transfers preceding the status stage must first be fully
46 // completed before the STATUS bit can be set."
47 // This variable stores whether some control data has been pended in the EP0TX
48 // Tx buffer, so that when an EP0TX interrupt is received we can set the STATUS
49 // bit to go to the Status stage of the control transfer.
50 STATIC BOOLEAN mControlTxPending
= FALSE
;
52 STATIC USB_DEVICE_DESCRIPTOR
*mDeviceDescriptor
;
54 // The config descriptor, interface descriptor, and endpoint descriptors in a
55 // buffer (in that order)
56 STATIC VOID
*mDescriptors
;
57 // Convenience pointers to those descriptors inside the buffer:
58 STATIC USB_INTERFACE_DESCRIPTOR
*mInterfaceDescriptor
;
59 STATIC USB_CONFIG_DESCRIPTOR
*mConfigDescriptor
;
60 STATIC USB_ENDPOINT_DESCRIPTOR
*mEndpointDescriptors
;
62 STATIC USB_DEVICE_RX_CALLBACK mDataReceivedCallback
;
63 STATIC USB_DEVICE_TX_CALLBACK mDataSentCallback
;
65 // The time between interrupt polls, in units of 100 nanoseconds
67 #define ISP1761_INTERRUPT_POLL_PERIOD 10000
75 // The DMA Endpoint Index must not point to the same as the
76 // Endpoint Index Register.
77 WRITE_REG32 (ISP1761_DMA_ENDPOINT_INDEX
, ((Endpoint
+ 2) % ISP1761_NUM_ENDPOINTS
));
78 WRITE_REG32 (ISP1761_ENDPOINT_INDEX
, Endpoint
);
81 // Enable going to the Data stage of a control transfer
88 SelectEndpoint (Endpoint
);
89 WRITE_REG32 (ISP1761_CTRL_FUNCTION
, ISP1761_CTRL_FUNCTION_DSEN
);
92 // Go to the Status stage of a successful control transfer
99 SelectEndpoint (Endpoint
);
100 WRITE_REG32 (ISP1761_CTRL_FUNCTION
, ISP1761_CTRL_FUNCTION_STATUS
);
103 // Read the FIFO for the endpoint indexed by Endpoint, into the buffer pointed
104 // at by Buffer, whose size is *Size bytes.
106 // If *Size is less than the number of bytes in the FIFO, return EFI_BUFFER_TOO_SMALL
108 // Update *Size with the number of bytes of data in the FIFO.
117 UINT16 NumBytesAvailable
;
122 SelectEndpoint (Endpoint
);
124 NumBytesAvailable
= READ_REG16 (ISP1761_BUFFER_LENGTH
);
126 if (NumBytesAvailable
> *Size
) {
127 *Size
= NumBytesAvailable
;
128 return EFI_BUFFER_TOO_SMALL
;
130 *Size
= NumBytesAvailable
;
133 The datasheet says the Data Port is 16 bits but it actually appears to
137 // Read 32-bit chunks
138 for (Index
= 0; Index
< NumBytesAvailable
/ 4; Index
++) {
139 ((UINT32
*) Buffer
)[Index
] = READ_REG32 (ISP1761_DATA_PORT
);
142 // Read remaining bytes
144 // Round NumBytesAvailable down to nearest power of 4
145 NumBytesRead
= NumBytesAvailable
& (~0x3);
146 if (NumBytesRead
!= NumBytesAvailable
) {
147 Val32
= READ_REG32 (ISP1761_DATA_PORT
);
148 // Copy each required byte of 32-bit word into buffer
149 for (Index
= 0; Index
< NumBytesAvailable
% 4; Index
++) {
150 ((UINT8
*) Buffer
)[NumBytesRead
+ Index
] = Val32
>> (Index
* 8);
157 Write an endpoint buffer. Parameters:
158 Endpoint Endpoint index (see Endpoint Index Register in datasheet)
159 MaxPacketSize The MaxPacketSize this endpoint is configured for
160 Size The size of the Buffer
163 Assumes MaxPacketSize is a multiple of 4.
164 (It seems that all valid values for MaxPacketSize _are_ multiples of 4)
168 WriteEndpointBuffer (
170 IN UINTN MaxPacketSize
,
172 IN CONST VOID
*Buffer
178 DwordBuffer
= (UINT32
*) Buffer
;
179 SelectEndpoint (Endpoint
);
182 The datasheet says the Data Port is 16 bits but it actually appears to
186 // Write packets of size MaxPacketSize
187 while (Size
> MaxPacketSize
) {
188 for (Index
= 0; Index
< MaxPacketSize
/ 4; Index
++) {
189 WRITE_REG32 (ISP1761_DATA_PORT
, DwordBuffer
[Index
]);
191 Size
-= MaxPacketSize
;
192 DwordBuffer
+= (MaxPacketSize
/ sizeof (UINT32
));
195 // Write remaining data
198 WRITE_REG32 (ISP1761_BUFFER_LENGTH
, Size
);
201 WRITE_REG32 (ISP1761_DATA_PORT
, DwordBuffer
[0]);
207 WRITE_REG32 (ISP1761_DATA_PORT
, DwordBuffer
[0]);
216 HandleGetDescriptor (
217 IN USB_DEVICE_REQUEST
*Request
221 UINT8 DescriptorType
;
227 Status
= EFI_SUCCESS
;
229 // Pretty confused if bmRequestType is anything but this:
230 ASSERT (Request
->RequestType
== USB_DEV_GET_DESCRIPTOR_REQ_TYPE
);
232 // Choose the response
233 DescriptorType
= Request
->Value
>> 8;
234 switch (DescriptorType
) {
235 case USB_DESC_TYPE_DEVICE
:
236 DEBUG ((EFI_D_INFO
, "USB: Got a request for device descriptor\n"));
237 ResponseSize
= sizeof (USB_DEVICE_DESCRIPTOR
);
238 ResponseData
= mDeviceDescriptor
;
240 case USB_DESC_TYPE_CONFIG
:
241 DEBUG ((EFI_D_INFO
, "USB: Got a request for config descriptor\n"));
242 ResponseSize
= mConfigDescriptor
->TotalLength
;
243 ResponseData
= mDescriptors
;
245 case USB_DESC_TYPE_STRING
:
246 DEBUG ((EFI_D_INFO
, "USB: Got a request for String descriptor %d\n", Request
->Value
& 0xFF));
249 DEBUG ((EFI_D_INFO
, "USB: Didn't understand request for descriptor 0x%04x\n", Request
->Value
));
250 Status
= EFI_NOT_FOUND
;
256 ASSERT (ResponseSize
!= 0);
258 if (Request
->Length
< ResponseSize
) {
260 ResponseSize
= Request
->Length
;
261 } else if (Request
->Length
> ResponseSize
) {
262 DEBUG ((EFI_D_INFO
, "USB: Info: ResponseSize < wLength\n"));
265 DataStageEnable (ISP1761_EP0TX
);
266 Status
= WriteEndpointBuffer (
268 MAX_PACKET_SIZE_CONTROL
,
272 if (!EFI_ERROR (Status
)) {
273 // Setting this value should cause us to go to the Status stage on the
274 // next EP0TX interrupt
275 mControlTxPending
= TRUE
;
285 IN USB_DEVICE_REQUEST
*Request
288 // Pretty confused if bmRequestType is anything but this:
289 ASSERT (Request
->RequestType
== USB_DEV_SET_ADDRESS_REQ_TYPE
);
290 // USB Spec: "The USB device does not change its device address until after
291 // the Status stage of this request is completed successfully."
292 // ISP1582 datasheet: "The new device address is activated when the
293 // device receives an acknowledgment from the host for the empty packet
294 // token". (StatusAcknowledge causes an empty packet to be sent).
295 // So, we write the Address register _before_ acking the SET_ADDRESS.
296 DEBUG ((EFI_D_INFO
, "USB: Setting address to %d\n", Request
->Value
));
297 WRITE_REG32 (ISP1761_ADDRESS
, Request
->Value
| ISP1761_ADDRESS_DEVEN
);
298 StatusAcknowledge (ISP1761_EP0TX
);
303 // Move the device to the Configured state.
304 // (This code only supports one configuration for a device, so the configuration
308 HandleSetConfiguration (
309 IN USB_DEVICE_REQUEST
*Request
312 USB_ENDPOINT_DESCRIPTOR
*EPDesc
;
316 ASSERT (Request
->RequestType
== USB_DEV_SET_CONFIGURATION_REQ_TYPE
);
317 DEBUG ((EFI_D_INFO
, "USB: Setting configuration.\n"));
319 // Configure endpoints
320 for (Index
= 0; Index
< mInterfaceDescriptor
->NumEndpoints
; Index
++) {
321 EPDesc
= &mEndpointDescriptors
[Index
];
323 // To simplify for now, assume endpoints aren't "sparse", and are in order.
324 ASSERT ((EPDesc
->EndpointAddress
& 0xF) == ((Index
/ 2) + 1));
326 // Convert from USB endpoint index to ISP1761 endpoint Index
327 // USB: Endpoint number is bits [3:0], IN/OUT is bit [7]
328 // ISP1761: Endpoint number is bits [4:1], IN/OUT is bit [0]
329 EndpointIndex
= ((EPDesc
->EndpointAddress
& 0xF) << 1) |
330 ((EPDesc
->EndpointAddress
& BIT7
) >> 7);
331 SelectEndpoint (EndpointIndex
);
332 // Set endpoint type (Bulk/Isochronous/Interrupt)
333 WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE
, EPDesc
->MaxPacketSize
);
334 // Hardware foible (bug?): Although the datasheet seems to suggest it should
335 // automatically be set to MaxPacketSize, the Buffer Length register appears
336 // to be reset to 0, which causes an empty packet to be sent in response to
337 // the first IN token of the session. The NOEMPKT field of the Endpoint Type
338 // register sounds like it might fix this problem, but it doesn't
339 // (it's "applicable only in the DMA mode").
340 WRITE_REG32 (ISP1761_BUFFER_LENGTH
, EPDesc
->MaxPacketSize
);
341 WRITE_REG32 (ISP1761_ENDPOINT_TYPE
, (EPDesc
->Attributes
& 0x3) |
342 ISP1761_ENDPOINT_TYPE_ENABLE
);
345 StatusAcknowledge (ISP1761_EP0TX
);
351 HandleDeviceRequest (
352 IN USB_DEVICE_REQUEST
*Request
357 Status
= EFI_SUCCESS
;
359 switch (Request
->Request
) {
360 case USB_DEV_GET_DESCRIPTOR
:
361 Status
= HandleGetDescriptor (Request
);
363 case USB_DEV_SET_ADDRESS
:
364 Status
= HandleSetAddress (Request
);
366 case USB_DEV_SET_CONFIGURATION
:
367 Status
= HandleSetConfiguration (Request
);
371 "Didn't understand RequestType 0x%x Request 0x%x\n",
372 Request
->RequestType
, Request
->Request
));
373 Status
= EFI_INVALID_PARAMETER
;
380 // Instead of actually registering interrupt handlers, we poll the controller's
381 // interrupt source register in this function.
394 UINT32 HandledInterrupts
;
395 UINT32 UnhandledInterrupts
;
398 // Set bits in HandledInterrupts to mark the interrupt source handled.
399 HandledInterrupts
= 0;
401 WRITE_REG32 (ISP1761_DEVICE_UNLOCK
, ISP1761_DEVICE_UNLOCK_MAGIC
);
403 DcInterrupts
= READ_REG32 (ISP1761_DC_INTERRUPT
);
404 if (DcInterrupts
& ISP1761_DC_INTERRUPT_SUSP
) {
405 DEBUG ((EFI_D_INFO
, "USB: Suspend\n"));
406 HandledInterrupts
|= ISP1761_DC_INTERRUPT_SUSP
;
408 if (DcInterrupts
& ISP1761_DC_INTERRUPT_RESUME
) {
409 DEBUG ((EFI_D_INFO
, "USB: Resume\n"));
410 HandledInterrupts
|= ISP1761_DC_INTERRUPT_RESUME
;
412 if (DcInterrupts
& ISP1761_DC_INTERRUPT_EP0SETUP
) {
414 ReadEndpointBuffer (0x20, &NumBytes
, &Packet
);
415 ASSERT (NumBytes
== 8);
416 HandleDeviceRequest ((USB_DEVICE_REQUEST
*) Packet
);
417 HandledInterrupts
|= ISP1761_DC_INTERRUPT_EP0SETUP
;
419 if (DcInterrupts
& ISP1761_DC_INTERRUPT_EP0RX
) {
420 HandledInterrupts
|= ISP1761_DC_INTERRUPT_EP0RX
;
422 if (DcInterrupts
& ISP1761_DC_INTERRUPT_EP0TX
) {
423 if (mControlTxPending
) {
424 // We previously put some data in the Control Endpoint's IN (Tx) FIFO.
425 // We assume that that data has now been sent in response to the IN token
426 // that triggered this interrupt. We can therefore go to the Status stage
427 // of the control transfer.
428 StatusAcknowledge (ISP1761_EP0TX
);
429 mControlTxPending
= FALSE
;
431 HandledInterrupts
|= ISP1761_DC_INTERRUPT_EP0TX
;
433 if (DcInterrupts
& ISP1761_DC_INTERRUPT_EP1RX
) {
435 DataPacket
= AllocatePool (NumBytes
);
436 Status
= ReadEndpointBuffer (ISP1761_EP1RX
, &NumBytes
, DataPacket
);
437 if (EFI_ERROR (Status
) || NumBytes
== 0) {
438 if (EFI_ERROR (Status
)) {
439 DEBUG ((EFI_D_ERROR
, "Couldn't read EP1RX data: %r\n", Status
));
441 FreePool (DataPacket
);
443 // Signal this event again so we poll again ASAP
444 gBS
->SignalEvent (Event
);
445 mDataReceivedCallback (NumBytes
, DataPacket
);
447 HandledInterrupts
|= ISP1761_DC_INTERRUPT_EP1RX
;
449 if (DcInterrupts
& ISP1761_DC_INTERRUPT_EP1TX
) {
450 mDataSentCallback (1);
451 HandledInterrupts
|= ISP1761_DC_INTERRUPT_EP1TX
;
453 if (DcInterrupts
& (ISP1761_DC_INTERRUPT_SOF
| ISP1761_DC_INTERRUPT_PSOF
)) {
454 // Don't care about SOFs or pseudo-SOFs
455 HandledInterrupts
|= (ISP1761_DC_INTERRUPT_SOF
| ISP1761_DC_INTERRUPT_PSOF
);
457 if (ISP1761_DC_INTERRUPT_BRESET
) {
458 HandledInterrupts
|= ISP1761_DC_INTERRUPT_BRESET
;
460 if (ISP1761_DC_INTERRUPT_HS_STAT
) {
461 HandledInterrupts
|= ISP1761_DC_INTERRUPT_HS_STAT
;
463 if (ISP1761_DC_INTERRUPT_VBUS
) {
464 HandledInterrupts
|= ISP1761_DC_INTERRUPT_VBUS
;
467 UnhandledInterrupts
= DcInterrupts
& (~HandledInterrupts
) & ISP1761_DC_INTERRUPT_MASK
;
468 if (UnhandledInterrupts
) {
469 DEBUG ((EFI_D_ERROR
, "USB: Unhandled DC Interrupts: 0x%08x\n",
470 UnhandledInterrupts
));
473 // Check if we received any more data while we were handling the interrupt.
474 SelectEndpoint (ISP1761_EP1RX
);
475 MoreBytes
= READ_REG16 (ISP1761_BUFFER_LENGTH
);
477 HandledInterrupts
&= ~ISP1761_DC_INTERRUPT_EP1RX
;
480 WRITE_REG32 (ISP1761_DC_INTERRUPT
, HandledInterrupts
);
485 IN UINT8 EndpointIndex
,
487 IN CONST VOID
*Buffer
490 return WriteEndpointBuffer (
491 (EndpointIndex
<< 1) | 0x1, //Convert to ISP1761 endpoint index, Tx
492 MAX_PACKET_SIZE_BULK
,
501 IN USB_DEVICE_DESCRIPTOR
*DeviceDescriptor
,
502 IN VOID
**Descriptors
,
503 IN USB_DEVICE_RX_CALLBACK RxCallback
,
504 IN USB_DEVICE_TX_CALLBACK TxCallback
510 EFI_EVENT TimerEvent
;
512 ASSERT (DeviceDescriptor
!= NULL
);
513 ASSERT (Descriptors
[0] != NULL
);
514 ASSERT (RxCallback
!= NULL
);
515 ASSERT (TxCallback
!= NULL
);
517 WRITE_REG32 (ISP1761_DEVICE_UNLOCK
, ISP1761_DEVICE_UNLOCK_MAGIC
);
519 WRITE_REG32 (ISP1761_SW_RESET_REG
, ISP1761_SW_RESET_ALL
);
520 while (READ_REG32 (ISP1761_SW_RESET_REG
) & ISP1761_SW_RESET_ALL
) {
523 WRITE_REG32 (ISP1761_MODE
, ISP1761_MODE_SFRESET
);
524 while (READ_REG32 (ISP1761_MODE
) & ISP1761_MODE_SFRESET
) {
527 DEBUG ((EFI_D_INFO
, "USB: Software reset done\n"));
529 WRITE_REG32 (ISP1761_DC_INTERRUPT_ENABLE
, 0x03FFFFFF);
530 WRITE_REG32 (ISP1761_OTG_INTERRUPT_ENABLE_RISE
, 0x07FF);
532 WRITE_REG8 (ISP1761_ADDRESS
, ISP1761_ADDRESS_DEVEN
);
533 WRITE_REG8 (ISP1761_MODE
, ISP1761_MODE_WKUPCS
| ISP1761_MODE_CLKAON
);
535 // Use port 1 as peripheral controller (magic - disagrees with datasheet)
536 WRITE_REG32 (ISP1761_OTG_CTRL_SET
, 0xffff0000);
537 WRITE_REG32 (ISP1761_OTG_CTRL_SET
, 0x000014d1);
539 OtgStatus
= READ_REG16 (ISP1761_OTG_STATUS
);
540 if ((OtgStatus
& ISP1761_OTG_STATUS_B_SESS_END
) != 0) {
541 DEBUG ((EFI_D_ERROR
, "USB: Vbus not powered.\n"));
543 if ((OtgStatus
& ISP1761_OTG_STATUS_A_B_SESS_VLD
) == 0) {
544 DEBUG ((EFI_D_ERROR
, "USB: Session not valid.\n"));
547 // Configure Control endpoints
548 SelectEndpoint (0x20);
549 WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE
, MAX_PACKET_SIZE_CONTROL
);
550 WRITE_REG32 (ISP1761_ENDPOINT_TYPE
, ISP1761_ENDPOINT_TYPE_ENABLE
);
551 SelectEndpoint (0x0);
552 WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE
, MAX_PACKET_SIZE_CONTROL
);
553 WRITE_REG32 (ISP1761_ENDPOINT_TYPE
, ISP1761_ENDPOINT_TYPE_ENABLE
);
554 SelectEndpoint (0x1);
555 WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE
, MAX_PACKET_SIZE_CONTROL
);
556 WRITE_REG32 (ISP1761_ENDPOINT_TYPE
, ISP1761_ENDPOINT_TYPE_ENABLE
);
558 // Interrupt on all ACK and NAK
559 WRITE_REG32 (ISP1761_INTERRUPT_CONFIG
, ISP1761_INTERRUPT_CONFIG_ACK_ONLY
);
561 mDeviceDescriptor
= DeviceDescriptor
;
562 mDescriptors
= Descriptors
[0];
564 // Right now we just support one configuration
565 ASSERT (mDeviceDescriptor
->NumConfigurations
== 1);
566 // ... and one interface
567 mConfigDescriptor
= (USB_CONFIG_DESCRIPTOR
*)mDescriptors
;
568 ASSERT (mConfigDescriptor
->NumInterfaces
== 1);
570 Ptr
= ((UINT8
*) mDescriptors
) + sizeof (USB_CONFIG_DESCRIPTOR
);
571 mInterfaceDescriptor
= (USB_INTERFACE_DESCRIPTOR
*) Ptr
;
572 Ptr
+= sizeof (USB_INTERFACE_DESCRIPTOR
);
574 mEndpointDescriptors
= (USB_ENDPOINT_DESCRIPTOR
*) Ptr
;
576 mDataReceivedCallback
= RxCallback
;
577 mDataSentCallback
= TxCallback
;
579 // Register a timer event so CheckInterupts gets called periodically
580 Status
= gBS
->CreateEvent (
581 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
587 ASSERT_EFI_ERROR (Status
);
588 if (EFI_ERROR (Status
)) {
592 Status
= gBS
->SetTimer (
595 ISP1761_INTERRUPT_POLL_PERIOD
597 ASSERT_EFI_ERROR (Status
);
602 USB_DEVICE_PROTOCOL mUsbDevice
= {
610 Isp1761PeriphEntryPoint (
611 IN EFI_HANDLE ImageHandle
,
612 IN EFI_SYSTEM_TABLE
*SystemTable
618 DeviceId
= READ_REG32 (ISP1761_DEVICE_ID
);
620 if (DeviceId
!= ISP1761_DEVICE_ID_VAL
) {
622 "ERROR: Read incorrect device ID for ISP1761: 0x%08x, expected 0x%08x\n",
623 DeviceId
, ISP1761_DEVICE_ID_VAL
625 return EFI_DEVICE_ERROR
;
629 return gBS
->InstallProtocolInterface (
631 &gUsbDeviceProtocolGuid
,
632 EFI_NATIVE_INTERFACE
,