Synopsys DesignWare Core SuperSpeed USB 3.0 Controller

Author:Felipe Balbi <felipe.balbi@linux.intel.com>
Date:April 2017

Introduction

TheSynopsys DesignWare Core SuperSpeed USB 3.0 Controller(hereinafter referred to asDWC3) is a USB SuperSpeed compliantcontroller which can be configured in one of 4 ways:

  1. Peripheral-only configuration
  2. Host-only configuration
  3. Dual-Role configuration
  4. Hub configuration

Linux currently supports several versions of this controller. In alllikelyhood, the version in your SoC is already supported. At the timeof this writing, known tested versions range from 2.02a to 3.10a. As arule of thumb, anything above 2.02a should work reliably well.

Currently, we have many known users for this driver. In alphabeticalorder:

  1. Cavium
  2. Intel Corporation
  3. Qualcomm
  4. Rockchip
  5. ST
  6. Samsung
  7. Texas Instruments
  8. Xilinx

Summary of Features

For details about features supported by your version of DWC3, consultyour IP team and/orSynopsys DesignWare Core SuperSpeed USB 3.0Controller Databook. Following is a list of features supported by thedriver at the time of this writing:

  1. Up to 16 bidirectional endpoints (including the controlpipe - ep0)
  2. Flexible endpoint configuration
  3. Simultaneous IN and OUT transfer support
  4. Scatter-list support
  5. Up to 256 TRBs[1] per endpoint
  6. Support for all transfer types (Control,Bulk,Interrupt, andIsochronous)
  7. SuperSpeed Bulk Streams
  8. Link Power Management
  9. Trace Events for debugging
  10. DebugFS[3] interface

These features have all been exercised with many of thein-treegadget drivers. We have verified bothConfigFS[4] andlegacy gadget drivers.

Driver Design

The DWC3 driver sits on thedrivers/usb/dwc3/ directory. All filesrelated to this driver are in this one directory. This makes it easyfor new-comers to read the code and understand how it behaves.

Because of DWC3’s configuration flexibility, the driver is a littlecomplex in some places but it should be rather straightforward tounderstand.

The biggest part of the driver refers to the Gadget API.

Known Limitations

Like any other HW, DWC3 has its own set of limitations. To avoidconstant questions about such problems, we decided to document themhere and have a single location to where we could point users.

OUT Transfer Size Requirements

According to Synopsys Databook, all OUT transfer TRBs[1] musthave theirsize field set to a value which is integer divisible bythe endpoint’swMaxPacketSize. This means thate.g. in order toreceive a Mass StorageCBW[5], req->length must either be setto a value that’s divisible bywMaxPacketSize (1024 on SuperSpeed,512 on HighSpeed, etc), or DWC3 driver must add a Chained TRB pointingto a throw-away buffer for the remaining length. Without this, OUTtransfers willNOT start.

Note that as of this writing, this won’t be a problem because DWC3 isfully capable of appending a chained TRB for the remaining length andcompletely hide this detail from the gadget driver. It’s still worthmentioning because this seems to be the largest source of queriesabout DWC3 andnon-working transfers.

TRB Ring Size Limitation

We, currently, have a hard limit of 256 TRBs[1] per endpoint,with the last TRB being a Link TRB[2] pointing back to thefirst. This limit is arbitrary but it has the benefit of adding up toexactly 4096 bytes, or 1 Page.

DWC3 driver will try its best to cope with more than 255 requests and,for the most part, it should work normally. However this is notsomething that has been exercised very frequently. If you experienceany problems, see sectionReporting Bugs below.

Reporting Bugs

Whenever you encounter a problem with DWC3, first and foremost youshould make sure that:

  1. You’re running latest tag fromLinus’ tree
  2. You can reproduce the error without any out-of-tree changesto DWC3
  3. You have checked that it’s not a fault on the host machine

After all these are verified, then here’s how to capture enoughinformation so we can be of any help to you.

Required Information

DWC3 relies exclusively on Trace Events for debugging. Everything isexposed there, with some extra bits being exposed to DebugFS[3].

In order to capture DWC3’s Trace Events you should run the followingcommandsbefore plugging the USB cable to a host machine:

# mkdir -p /d# mkdir -p /t# mount -t debugfs none /d# mount -t tracefs none /t# echo 81920 > /t/buffer_size_kb# echo 1 > /t/events/dwc3/enable

After this is done, you can connect your USB cable and reproduce theproblem. As soon as the fault is reproduced, make a copy of filestrace andregdump, like so:

# cp /t/trace /root/trace.txt# cat /d/*dwc3*/regdump > /root/regdump.txt

Make sure to compresstrace.txt andregdump.txt in a tarballand email it tome withlinux-usb in Cc. If you want to be extrasure that I’ll help you, write your subject line in the followingformat:

[BUG REPORT] usb: dwc3: Bug while doing XYZ

On the email body, make sure to detail what you doing, which gadgetdriver you were using, how to reproduce the problem, what SoC you’reusing, which OS (and its version) was running on the Host machine.

With all this information, we should be able to understand what’sgoing on and be helpful to you.

Debugging

First and foremost a disclaimer:

DISCLAIMER: The information available on DebugFS and/or TraceFS canchange at any time at any Major Linux Kernel Release. If writingscripts, do **NOT** assume information to be available in thecurrent format.

With that out of the way, let’s carry on.

If you’re willing to debug your own problem, you deserve a round ofapplause :-)

Anyway, there isn’t much to say here other than Trace Events will bereally helpful in figuring out issues with DWC3. Also, access toSynopsys Databook will bereally valuable in this case.

A USB Sniffer can be helpful at times but it’s not entirely required,there’s a lot that can be understood without looking at the wire.

Feel free to emailme and Cclinux-usb if you need any help.

DebugFS

DebugFS is very good for gathering snapshots of what’s going onwith DWC3 and/or any endpoint.

On DWC3’sDebugFS directory, you will find the following files anddirectories:

ep[0..15]{in,out}/link_stateregdumptestmode

link_state

When read,link_state will print out one ofU0,U1,U2,U3,SS.Disabled,RX.Detect,SS.Inactive,Polling,Recovery,HotReset,Compliance,Loopback,Reset,Resume orUNKNOWNlinkstate.

This file can also be written to in order to force link to one of thestates above.

regdump

File name is self-explanatory. When read,regdump will print out aregister dump of DWC3. Note that this file can be grepped to find theinformation you want.

testmode

When read,testmode will print out a name of one of the specifiedUSB 2.0 Testmodes (test_j,test_k,test_se0_nak,test_packet,test_force_enable) or the stringnotest incase no tests are currently being executed.

In order to start any of these test modes, the same strings can bewritten to the file and DWC3 will enter the requested test mode.

ep[0..15]{in,out}

For each endpoint we expose one directory following the namingconventionep$num$dir(ep0in, ep0out, ep1in, …). Inside eachof these directories you will find the following files:

descriptor_fetch_queueevent_queuerx_fifo_queuerx_info_queuerx_request_queuetransfer_typetrb_ringtx_fifo_queuetx_request_queue

With access to Synopsys Databook, you can decode the information onthem.

transfer_type

When read,transfer_type will print out one ofcontrol,bulk,interrupt orisochronous depending on what theendpoint descriptor says. If the endpoint hasn’t been enabled yet, itwill print--.

trb_ring

When read,trb_ring will print out details about all TRBs on thering. It will also tell you where our enqueue and dequeue pointers arelocated in the ring:

buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo000000002c754000,481,normal,1,0,1,0,0,0000000002c75c000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c75c000,481,normal,1,0,1,0,0,0000000002c784000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c784000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c784000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c784000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c75c000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c75c000,481,normal,1,0,1,0,0,0000000002c780000,481,normal,1,0,1,0,0,0000000002c784000,481,normal,1,0,1,0,0,0000000002c788000,481,normal,1,0,1,0,0,0000000002c78c000,481,normal,1,0,1,0,0,0000000002c790000,481,normal,1,0,1,0,0,0000000002c754000,481,normal,1,0,1,0,0,0000000002c758000,481,normal,1,0,1,0,0,0000000002c75c000,512,normal,1,0,1,0,0,1        D0000000000000000,0,UNKNOWN,0,0,0,0,0,0       E0000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,00000000000000000,0,UNKNOWN,0,0,0,0,0,000000000381ab000,0,link,0,0,0,0,0,1

Trace Events

DWC3 also provides several trace events which help us gatheringinformation about the behavior of the driver during runtime.

In order to use these events, you must enableCONFIG_FTRACE inyour kernel config.

For details about how enable DWC3 events, see sectionReportingBugs.

The following subsections will give details about each Event Class andeach Event defined by DWC3.

MMIO

It is sometimes useful to look at every MMIO access when looking forbugs. Because of that, DWC3 offers two Trace Events (one fordwc3_readl() and one for dwc3_writel()).TP_printk follows:

TP_printk("addr %p value %08x", __entry->base + __entry->offset,              __entry->value)

Interrupt Events

Every IRQ event can be logged and decoded into a human readablestring. Because every event will be different, we don’t give anexample other than theTP_printk format used:

TP_printk("event (%08x): %s", __entry->event,              dwc3_decode_event(__entry->event, __entry->ep0state))

Control Request

Every USB Control Request can be logged to the trace buffer. Theoutput format is:

TP_printk("%s", dwc3_decode_ctrl(__entry->bRequestType,                              __entry->bRequest, __entry->wValue,                              __entry->wIndex, __entry->wLength))

Note that Standard Control Requests will be decoded intohuman-readable strings with their respective arguments. Class andVendor requests will be printed out a sequence of 8 bytes in hexformat.

Lifetime of astructusb_request

The entire lifetime of astructusb_request can be tracked on thetrace buffer. We have one event for each of allocation, free,queueing, dequeueing, and giveback. Output format is:

TP_printk("%s: req %p length %u/%u %s%s%s ==> %d",      __get_str(name), __entry->req, __entry->actual, __entry->length,      __entry->zero ? "Z" : "z",      __entry->short_not_ok ? "S" : "s",      __entry->no_interrupt ? "i" : "I",      __entry->status)

Generic Commands

We can log and decode every Generic Command with its completioncode. Format is:

TP_printk("cmd '%s' [%x] param %08x --> status: %s",      dwc3_gadget_generic_cmd_string(__entry->cmd),      __entry->cmd, __entry->param,      dwc3_gadget_generic_cmd_status_string(__entry->status))

Endpoint Commands

Endpoints commands can also be logged together with completioncode. Format is:

TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x --> status: %s",      __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd),      __entry->cmd, __entry->param0,      __entry->param1, __entry->param2,      dwc3_ep_cmd_status_string(__entry->cmd_status))

Lifetime of aTRB

ATRB Lifetime is simple. We are either preparing aTRB orcompleting it. With these two events, we can see how aTRB changesover time. Format is:

TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)",      __get_str(name), __entry->queued, __entry->allocated,      __entry->trb, __entry->bph, __entry->bpl,      ({char *s;      int pcm = ((__entry->size >> 24) & 3) + 1;      switch (__entry->type) {      case USB_ENDPOINT_XFER_INT:      case USB_ENDPOINT_XFER_ISOC:              switch (pcm) {              case 1:                      s = "1x ";                      break;              case 2:                      s = "2x ";                      break;              case 3:                      s = "3x ";                      break;              }      default:              s = "";      } s; }),      DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl,      __entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h',      __entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l',      __entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c',      __entry->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's',      __entry->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's',      __entry->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c',    dwc3_trb_type_string(DWC3_TRBCTL_TYPE(__entry->ctrl)))

Lifetime of an Endpoint

And endpoint’s lifetime is summarized with enable and disableoperations, both of which can be traced. Format is:

TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c:%c",      __get_str(name), __entry->maxpacket,      __entry->maxpacket_limit, __entry->max_streams,      __entry->maxburst, __entry->trb_enqueue,      __entry->trb_dequeue,      __entry->flags & DWC3_EP_ENABLED ? 'E' : 'e',      __entry->flags & DWC3_EP_STALL ? 'S' : 's',      __entry->flags & DWC3_EP_WEDGE ? 'W' : 'w',      __entry->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b',      __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',      __entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e',      __entry->direction ? '<' : '>')

Structures, Methods and Definitions

structdwc3_event_buffer

Software event buffer representation

Definition

struct dwc3_event_buffer {  void *buf;  void *cache;  unsigned length;  unsigned int            lpos;  unsigned int            count;  unsigned int            flags;#define DWC3_EVENT_PENDING      BIT(0);  dma_addr_t dma;  struct dwc3             *dwc;};

Members

buf
_THE_ buffer
cache
The buffer cache used in the threaded interrupt
length
size of this buffer
lpos
event offset
count
cache of last read event count register
flags
flags related to this event buffer
dma
dma_addr_t
dwc
pointer to DWC controller
structdwc3_ep

device side endpoint representation

Definition

struct dwc3_ep {  struct usb_ep           endpoint;  struct list_head        cancelled_list;  struct list_head        pending_list;  struct list_head        started_list;  void __iomem            *regs;  struct dwc3_trb         *trb_pool;  dma_addr_t trb_pool_dma;  struct dwc3             *dwc;  u32 saved_state;  unsigned flags;#define DWC3_EP_ENABLED         BIT(0);#define DWC3_EP_STALL           BIT(1);#define DWC3_EP_WEDGE           BIT(2);#define DWC3_EP_TRANSFER_STARTED BIT(3);#define DWC3_EP_END_TRANSFER_PENDING BIT(4);#define DWC3_EP_PENDING_REQUEST BIT(5);#define DWC3_EP_DELAY_START     BIT(6);#define DWC3_EP_WAIT_TRANSFER_COMPLETE  BIT(7);#define DWC3_EP_IGNORE_NEXT_NOSTREAM    BIT(8);#define DWC3_EP_FORCE_RESTART_STREAM    BIT(9);#define DWC3_EP_FIRST_STREAM_PRIMED     BIT(10);#define DWC3_EP0_DIR_IN         BIT(31);  u8 trb_enqueue;  u8 trb_dequeue;  u8 number;  u8 type;  u8 resource_index;  u32 frame_number;  u32 interval;  char name[20];  unsigned direction:1;  unsigned stream_capable:1;  u8 combo_num;  int start_cmd_status;};

Members

endpoint
usb endpoint
cancelled_list
list of cancelled requests for this endpoint
pending_list
list of pending requests for this endpoint
started_list
list of started requests on this endpoint
regs
pointer to first endpoint register
trb_pool
array of transaction buffers
trb_pool_dma
dma address oftrb_pool
dwc
pointer to DWC controller
saved_state
ep state saved during hibernation
flags
endpoint flags (wedged, stalled, …)
trb_enqueue
enqueue ‘pointer’ into TRB array
trb_dequeue
dequeue ‘pointer’ into TRB array
number
endpoint number (1 - 15)
type
set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
resource_index
Resource transfer index
frame_number
set to the frame number we want this transfer to start (ISOC)
interval
the interval on which the ISOC transfer is started
name
a human readable name e.g. ep1out-bulk
direction
true for TX, false for RX
stream_capable
true when streams are enabled
combo_num
the test combination BIT[15:14] of the frame number to testisochronous START TRANSFER command failure workaround
start_cmd_status
the status of testing START TRANSFER command withcombo_num = ‘b00
structdwc3_trb

transfer request block (hw format)

Definition

struct dwc3_trb {  u32 bpl;  u32 bph;  u32 size;  u32 ctrl;};

Members

bpl
DW0-3
bph
DW4-7
size
DW8-B
ctrl
DWC-F
structdwc3_hwparams

copy of HWPARAMS registers

Definition

struct dwc3_hwparams {  u32 hwparams0;  u32 hwparams1;  u32 hwparams2;  u32 hwparams3;  u32 hwparams4;  u32 hwparams5;  u32 hwparams6;  u32 hwparams7;  u32 hwparams8;};

Members

hwparams0
GHWPARAMS0
hwparams1
GHWPARAMS1
hwparams2
GHWPARAMS2
hwparams3
GHWPARAMS3
hwparams4
GHWPARAMS4
hwparams5
GHWPARAMS5
hwparams6
GHWPARAMS6
hwparams7
GHWPARAMS7
hwparams8
GHWPARAMS8
structdwc3_request

representation of a transfer request

Definition

struct dwc3_request {  struct usb_request      request;  struct list_head        list;  struct dwc3_ep          *dep;  struct scatterlist      *sg;  struct scatterlist      *start_sg;  unsigned num_pending_sgs;  unsigned int            num_queued_sgs;  unsigned remaining;  unsigned int            status;#define DWC3_REQUEST_STATUS_QUEUED      0;#define DWC3_REQUEST_STATUS_STARTED     1;#define DWC3_REQUEST_STATUS_CANCELLED   2;#define DWC3_REQUEST_STATUS_COMPLETED   3;#define DWC3_REQUEST_STATUS_UNKNOWN     -1;  u8 epnum;  struct dwc3_trb         *trb;  dma_addr_t trb_dma;  unsigned num_trbs;  unsigned needs_extra_trb:1;  unsigned direction:1;  unsigned mapped:1;};

Members

request
struct usb_request to be transferred
list
a list_head used for request queueing
dep
struct dwc3_ep owning this request
sg
pointer to first incomplete sg
start_sg
pointer to the sg which should be queued next
num_pending_sgs
counter to pending sgs
num_queued_sgs
counter to the number of sgs which already got queued
remaining
amount of data remaining
status
internal dwc3 request status tracking
epnum
endpoint number to which this request refers
trb
pointer to struct dwc3_trb
trb_dma
DMA address oftrb
num_trbs
number of TRBs used by this request
needs_extra_trb
true when request needs one extra TRB (either due to ZLPor unaligned OUT)
direction
IN or OUT direction flag
mapped
true when request has been dma-mapped
structdwc3

representation of our controller

Definition

struct dwc3 {  struct work_struct      drd_work;  struct dwc3_trb         *ep0_trb;  void *bounce;  void *scratchbuf;  u8 *setup_buf;  dma_addr_t ep0_trb_addr;  dma_addr_t bounce_addr;  dma_addr_t scratch_addr;  struct dwc3_request     ep0_usb_req;  struct completion       ep0_in_setup;  spinlock_t lock;  struct device           *dev;  struct device           *sysdev;  struct platform_device  *xhci;  struct resource         xhci_resources[DWC3_XHCI_RESOURCES_NUM];  struct dwc3_event_buffer *ev_buf;  struct dwc3_ep          *eps[DWC3_ENDPOINTS_NUM];  struct usb_gadget       gadget;  struct usb_gadget_driver *gadget_driver;  struct clk_bulk_data    *clks;  int num_clks;  struct reset_control    *reset;  struct usb_phy          *usb2_phy;  struct usb_phy          *usb3_phy;  struct phy              *usb2_generic_phy;  struct phy              *usb3_generic_phy;  bool phys_ready;  struct ulpi             *ulpi;  bool ulpi_ready;  void __iomem            *regs;  size_t regs_size;  enum usb_dr_mode        dr_mode;  u32 current_dr_role;  u32 desired_dr_role;  struct extcon_dev       *edev;  struct notifier_block   edev_nb;  enum usb_phy_interface  hsphy_mode;  struct usb_role_switch  *role_sw;  enum usb_dr_mode        role_switch_default_mode;  u32 fladj;  u32 irq_gadget;  u32 otg_irq;  u32 current_otg_role;  u32 desired_otg_role;  bool otg_restart_host;  u32 nr_scratch;  u32 u1u2;  u32 maximum_speed;  u32 ip;#define DWC3_IP                 0x5533;#define DWC31_IP                0x3331;#define DWC32_IP                0x3332;  u32 revision;#define DWC3_REVISION_ANY       0x0;#define DWC3_REVISION_173A      0x5533173a;#define DWC3_REVISION_175A      0x5533175a;#define DWC3_REVISION_180A      0x5533180a;#define DWC3_REVISION_183A      0x5533183a;#define DWC3_REVISION_185A      0x5533185a;#define DWC3_REVISION_187A      0x5533187a;#define DWC3_REVISION_188A      0x5533188a;#define DWC3_REVISION_190A      0x5533190a;#define DWC3_REVISION_194A      0x5533194a;#define DWC3_REVISION_200A      0x5533200a;#define DWC3_REVISION_202A      0x5533202a;#define DWC3_REVISION_210A      0x5533210a;#define DWC3_REVISION_220A      0x5533220a;#define DWC3_REVISION_230A      0x5533230a;#define DWC3_REVISION_240A      0x5533240a;#define DWC3_REVISION_250A      0x5533250a;#define DWC3_REVISION_260A      0x5533260a;#define DWC3_REVISION_270A      0x5533270a;#define DWC3_REVISION_280A      0x5533280a;#define DWC3_REVISION_290A      0x5533290a;#define DWC3_REVISION_300A      0x5533300a;#define DWC3_REVISION_310A      0x5533310a;#define DWC3_REVISION_330A      0x5533330a;#define DWC31_REVISION_ANY      0x0;#define DWC31_REVISION_110A     0x3131302a;#define DWC31_REVISION_120A     0x3132302a;#define DWC31_REVISION_160A     0x3136302a;#define DWC31_REVISION_170A     0x3137302a;#define DWC31_REVISION_180A     0x3138302a;#define DWC31_REVISION_190A     0x3139302a;#define DWC32_REVISION_ANY      0x0;#define DWC32_REVISION_100A     0x3130302a;  u32 version_type;#define DWC31_VERSIONTYPE_ANY           0x0;#define DWC31_VERSIONTYPE_EA01          0x65613031;#define DWC31_VERSIONTYPE_EA02          0x65613032;#define DWC31_VERSIONTYPE_EA03          0x65613033;#define DWC31_VERSIONTYPE_EA04          0x65613034;#define DWC31_VERSIONTYPE_EA05          0x65613035;#define DWC31_VERSIONTYPE_EA06          0x65613036;  enum dwc3_ep0_next      ep0_next_event;  enum dwc3_ep0_state     ep0state;  enum dwc3_link_state    link_state;  u16 u2sel;  u16 u2pel;  u8 u1sel;  u8 u1pel;  u8 speed;  u8 num_eps;  struct dwc3_hwparams    hwparams;  struct dentry           *root;  struct debugfs_regset32 *regset;  u32 dbg_lsp_select;  u8 test_mode;  u8 test_mode_nr;  u8 lpm_nyet_threshold;  u8 hird_threshold;  u8 rx_thr_num_pkt_prd;  u8 rx_max_burst_prd;  u8 tx_thr_num_pkt_prd;  u8 tx_max_burst_prd;  const char              *hsphy_interface;  unsigned connected:1;  unsigned delayed_status:1;  unsigned ep0_bounced:1;  unsigned ep0_expect_in:1;  unsigned has_hibernation:1;  unsigned sysdev_is_parent:1;  unsigned has_lpm_erratum:1;  unsigned is_utmi_l1_suspend:1;  unsigned is_fpga:1;  unsigned pending_events:1;  unsigned pullups_connected:1;  unsigned setup_packet_pending:1;  unsigned three_stage_setup:1;  unsigned dis_start_transfer_quirk:1;  unsigned usb3_lpm_capable:1;  unsigned usb2_lpm_disable:1;  unsigned disable_scramble_quirk:1;  unsigned u2exit_lfps_quirk:1;  unsigned u2ss_inp3_quirk:1;  unsigned req_p1p2p3_quirk:1;  unsigned del_p1p2p3_quirk:1;  unsigned del_phy_power_chg_quirk:1;  unsigned lfps_filter_quirk:1;  unsigned rx_detect_poll_quirk:1;  unsigned dis_u3_susphy_quirk:1;  unsigned dis_u2_susphy_quirk:1;  unsigned dis_enblslpm_quirk:1;  unsigned dis_u1_entry_quirk:1;  unsigned dis_u2_entry_quirk:1;  unsigned dis_rxdet_inp3_quirk:1;  unsigned dis_u2_freeclk_exists_quirk:1;  unsigned dis_del_phy_power_chg_quirk:1;  unsigned dis_tx_ipgap_linecheck_quirk:1;  unsigned parkmode_disable_ss_quirk:1;  unsigned tx_de_emphasis_quirk:1;  unsigned tx_de_emphasis:2;  unsigned dis_metastability_quirk:1;  u16 imod_interval;};

Members

drd_work
workqueue used for role swapping
ep0_trb
trb which is used for the ctrl_req
bounce
address of bounce buffer
scratchbuf
address of scratch buffer
setup_buf
used while precessing STD USB requests
ep0_trb_addr
dma address ofep0_trb
bounce_addr
dma address ofbounce
scratch_addr
dma address of scratchbuf
ep0_usb_req
dummy req used while handling STD USB requests
ep0_in_setup
one control transfer is completed and enter setup phase
lock
for synchronizing
dev
pointer to our struct device
sysdev
pointer to the DMA-capable device
xhci
pointer to our xHCI child
xhci_resources
struct resources for ourxhci child
ev_buf
struct dwc3_event_buffer pointer
eps
endpoint array
gadget
device side representation of the peripheral controller
gadget_driver
pointer to the gadget driver
clks
array of clocks
num_clks
number of clocks
reset
reset control
usb2_phy
pointer to USB2 PHY
usb3_phy
pointer to USB3 PHY
usb2_generic_phy
pointer to USB2 PHY
usb3_generic_phy
pointer to USB3 PHY
phys_ready
flag to indicate that PHYs are ready
ulpi
pointer to ulpi interface
ulpi_ready
flag to indicate that ULPI is initialized
regs
base address for our registers
regs_size
address space size
dr_mode
requested mode of operation
current_dr_role
current role of operation when in dual-role mode
desired_dr_role
desired role of operation when in dual-role mode
edev
extcon handle
edev_nb
extcon notifier
hsphy_mode
UTMI phy mode, one of following:- USBPHY_INTERFACE_MODE_UTMI- USBPHY_INTERFACE_MODE_UTMIW
role_sw
usb_role_switch handle
role_switch_default_mode
default operation mode of controller whileusb role is USB_ROLE_NONE.
fladj
frame length adjustment
irq_gadget
peripheral controller’s IRQ number
otg_irq
IRQ number for OTG IRQs
current_otg_role
current role of operation while using the OTG block
desired_otg_role
desired role of operation while using the OTG block
otg_restart_host
flag that OTG controller needs to restart host
nr_scratch
number of scratch buffers
u1u2
only used on revisions <1.83a for workaround
maximum_speed
maximum speed requested (mainly for testing purposes)
ip
controller’s ID
revision
controller’s version of an IP
version_type
VERSIONTYPE register contents, a sub release of a revision
ep0_next_event
hold the next expected event
ep0state
state of endpoint zero
link_state
link state
u2sel
parameter from Set SEL request.
u2pel
parameter from Set SEL request.
u1sel
parameter from Set SEL request.
u1pel
parameter from Set SEL request.
speed
device speed (super, high, full, low)
num_eps
number of endpoints
hwparams
copy of hwparams registers
root
debugfs root folder pointer
regset
debugfs pointer to regdump file
dbg_lsp_select
current debug lsp mux register selection
test_mode
true when we’re entering a USB test mode
test_mode_nr
test feature selector
lpm_nyet_threshold
LPM NYET response threshold
hird_threshold
HIRD threshold
rx_thr_num_pkt_prd
periodic ESS receive packet count
rx_max_burst_prd
max periodic ESS receive burst size
tx_thr_num_pkt_prd
periodic ESS transmit packet count
tx_max_burst_prd
max periodic ESS transmit burst size
hsphy_interface
“utmi” or “ulpi”
connected
true when we’re connected to a host, false otherwise
delayed_status
true when gadget driver asks for delayed status
ep0_bounced
true when we used bounce buffer
ep0_expect_in
true when we expect a DATA IN transfer
has_hibernation
true when dwc3 was configured with Hibernation
sysdev_is_parent
true when dwc3 device has a parent driver
has_lpm_erratum
true when core was configured with LPM Erratum. Note thatthere’s now way for software to detect this in runtime.
is_utmi_l1_suspend
the core asserts output signal0 - utmi_sleep_n1 - utmi_l1_suspend_n
is_fpga
true when we are using the FPGA board
pending_events
true when we have pending IRQs to be handled
pullups_connected
true when Run/Stop bit is set
setup_packet_pending
true when there’s a Setup Packet in FIFO. Workaround
three_stage_setup
set if we perform a three phase setup
dis_start_transfer_quirk
set if start_transfer failure SW workaround isnot needed for DWC_usb31 version 1.70a-ea06 and below
usb3_lpm_capable
set if hadrware supports Link Power Management
usb2_lpm_disable
set to disable usb2 lpm
disable_scramble_quirk
set if we enable the disable scramble quirk
u2exit_lfps_quirk
set if we enable u2exit lfps quirk
u2ss_inp3_quirk
set if we enable P3 OK for U2/SS Inactive quirk
req_p1p2p3_quirk
set if we enable request p1p2p3 quirk
del_p1p2p3_quirk
set if we enable delay p1p2p3 quirk
del_phy_power_chg_quirk
set if we enable delay phy power change quirk
lfps_filter_quirk
set if we enable LFPS filter quirk
rx_detect_poll_quirk
set if we enable rx_detect to polling lfps quirk
dis_u3_susphy_quirk
set if we disable usb3 suspend phy
dis_u2_susphy_quirk
set if we disable usb2 suspend phy
dis_enblslpm_quirk
set if we clear enblslpm in GUSB2PHYCFG,disabling the suspend signal to the PHY.
dis_u1_entry_quirk
set if link entering into U1 state needs to be disabled.
dis_u2_entry_quirk
set if link entering into U2 state needs to be disabled.
dis_rxdet_inp3_quirk
set if we disable Rx.Detect in P3
dis_u2_freeclk_exists_quirk
set if we clear u2_freeclk_existsin GUSB2PHYCFG, specify that USB2 PHY doesn’tprovide a free-running PHY clock.
dis_del_phy_power_chg_quirk
set if we disable delay phy powerchange quirk.
dis_tx_ipgap_linecheck_quirk
set if we disable u2mac linestatecheck during HS transmit.
parkmode_disable_ss_quirk
set if we need to disable all SuperSpeedinstances in park mode.
tx_de_emphasis_quirk
set if we enable Tx de-emphasis quirk
tx_de_emphasis
Tx de-emphasis value0 - -6dB de-emphasis1 - -3.5dB de-emphasis2 - No de-emphasis3 - Reserved
dis_metastability_quirk
set to disable metastability quirk.
imod_interval
set the interrupt moderation interval in 250nsincrements or 0 to disable.
structdwc3_event_depevt

Device Endpoint Events

Definition

struct dwc3_event_depevt {  u32 one_bit:1;  u32 endpoint_number:5;  u32 endpoint_event:4;  u32 reserved11_10:2;  u32 status:4;#define DEPEVT_STATUS_TRANSFER_ACTIVE   BIT(3);#define DEPEVT_STATUS_BUSERR    BIT(0);#define DEPEVT_STATUS_SHORT     BIT(1);#define DEPEVT_STATUS_IOC       BIT(2);#define DEPEVT_STATUS_LST       BIT(3) ;#define DEPEVT_STATUS_MISSED_ISOC BIT(3) ;#define DEPEVT_STREAMEVT_FOUND          1;#define DEPEVT_STREAMEVT_NOTFOUND       2;#define DEPEVT_STREAM_PRIME             0xfffe;#define DEPEVT_STREAM_NOSTREAM          0x0;#define DEPEVT_STATUS_CONTROL_DATA      1;#define DEPEVT_STATUS_CONTROL_STATUS    2;#define DEPEVT_STATUS_CONTROL_PHASE(n)  ((n) & 3);#define DEPEVT_TRANSFER_NO_RESOURCE     1;#define DEPEVT_TRANSFER_BUS_EXPIRY      2;  u32 parameters:16;#define DEPEVT_PARAMETER_CMD(n) (((n) & (0xf << 8)) >> 8);};

Members

one_bit
indicates this is an endpoint event (not used)
endpoint_number
number of the endpoint
endpoint_event
The event we have:0x00 - Reserved0x01 - XferComplete0x02 - XferInProgress0x03 - XferNotReady0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun)0x05 - Reserved0x06 - StreamEvt0x07 - EPCmdCmplt
reserved11_10
Reserved, don’t use.
status
Indicates the status of the event. Refer to databook formore information.
parameters
Parameters of the current event. Refer to databook formore information.
structdwc3_event_devt

Device Events

Definition

struct dwc3_event_devt {  u32 one_bit:1;  u32 device_event:7;  u32 type:4;  u32 reserved15_12:4;  u32 event_info:9;  u32 reserved31_25:7;};

Members

one_bit
indicates this is a non-endpoint event (not used)
device_event
indicates it’s a device event. Should read as 0x00
type
indicates the type of device event.0 - DisconnEvt1 - USBRst2 - ConnectDone3 - ULStChng4 - WkUpEvt5 - Reserved6 - EOPF7 - SOF8 - Reserved9 - ErrticErr10 - CmdCmplt11 - EvntOverflow12 - VndrDevTstRcved
reserved15_12
Reserved, not used
event_info
Information about this event
reserved31_25
Reserved, not used
structdwc3_event_gevt

Other Core Events

Definition

struct dwc3_event_gevt {  u32 one_bit:1;  u32 device_event:7;  u32 phy_port_number:4;  u32 reserved31_12:20;};

Members

one_bit
indicates this is a non-endpoint event (not used)
device_event
indicates it’s (0x03) Carkit or (0x04) I2C event.
phy_port_number
self-explanatory
reserved31_12
Reserved, not used.
uniondwc3_event

representation of Event Buffer contents

Definition

union dwc3_event {  u32 raw;  struct dwc3_event_type          type;  struct dwc3_event_depevt        depevt;  struct dwc3_event_devt          devt;  struct dwc3_event_gevt          gevt;};

Members

raw
raw 32-bit event
type
the type of the event
depevt
Device Endpoint Event
devt
Device Event
gevt
Global Event
structdwc3_gadget_ep_cmd_params

representation of endpoint command parameters

Definition

struct dwc3_gadget_ep_cmd_params {  u32 param2;  u32 param1;  u32 param0;};

Members

param2
third parameter
param1
second parameter
param0
first parameter
structdwc3_request *next_request(struct list_head * list)

gets the next request on the given list

Parameters

structlist_head*list
the request list to operate on

Description

Caller should take care of locking. This function returnNULL or the firstrequest available onlist.

voiddwc3_gadget_move_started_request(structdwc3_request * req)

movereq to the started_list

Parameters

structdwc3_request*req
the request to be moved

Description

Caller should take care of locking. This function will movereq from itscurrent list to the endpoint’s started_list.

voiddwc3_gadget_move_cancelled_request(structdwc3_request * req)

movereq to the cancelled_list

Parameters

structdwc3_request*req
the request to be moved

Description

Caller should take care of locking. This function will movereq from itscurrent list to the endpoint’s cancelled_list.

voiddwc3_gadget_ep_get_transfer_index(structdwc3_ep * dep)

Gets transfer index from HW

Parameters

structdwc3_ep*dep
dwc3 endpoint

Description

Caller should take care of locking. Returns the transfer resourceindex for a given endpoint.

voiddwc3_gadget_dctl_write_safe(structdwc3 * dwc, u32 value)

write to DCTL safe from link state change

Parameters

structdwc3*dwc
pointer to our context structure
u32value
value to write to DCTL

Description

Use this function when doing read-modify-write to DCTL. It will notsend link state change request.

intdwc3_gadget_set_test_mode(structdwc3 * dwc, int mode)

enables usb2 test modes

Parameters

structdwc3*dwc
pointer to our context structure
intmode
the mode to set (J, K SE0 NAK, Force Enable)

Description

Caller should take care of locking. This function will return 0 onsuccess or -EINVAL if wrong Test Selector is passed.

intdwc3_gadget_get_link_state(structdwc3 * dwc)

gets current state of usb link

Parameters

structdwc3*dwc
pointer to our context structure

Description

Caller should take care of locking. This function willreturn the link state on success (>= 0) or -ETIMEDOUT.

intdwc3_gadget_set_link_state(structdwc3 * dwc, enum dwc3_link_state state)

sets usb link to a particular state

Parameters

structdwc3*dwc
pointer to our context structure
enumdwc3_link_statestate
the state to put link into

Description

Caller should take care of locking. This function willreturn 0 on success or -ETIMEDOUT.

voiddwc3_ep_inc_trb(u8 * index)

increment a trb index.

Parameters

u8*index
Pointer to the TRB index to increment.

Description

The index should never point to the link TRB. After incrementing,if it is point to the link TRB, wrap around to the beginning. Thelink TRB is always at the last TRB entry.

voiddwc3_ep_inc_enq(structdwc3_ep * dep)

increment endpoint’s enqueue pointer

Parameters

structdwc3_ep*dep
The endpoint whose enqueue pointer we’re incrementing
voiddwc3_ep_inc_deq(structdwc3_ep * dep)

increment endpoint’s dequeue pointer

Parameters

structdwc3_ep*dep
The endpoint whose enqueue pointer we’re incrementing
voiddwc3_gadget_giveback(structdwc3_ep * dep, structdwc3_request * req, int status)

call struct usb_request’s ->complete callback

Parameters

structdwc3_ep*dep
The endpoint to whom the request belongs to
structdwc3_request*req
The request we’re giving back
intstatus
completion code for the request

Description

Must be called with controller’s lock held and interrupts disabled. Thisfunction will unmapreq and call its ->complete() callback to notify upperlayers that it has completed.

intdwc3_send_gadget_generic_command(structdwc3 * dwc, unsigned cmd, u32 param)

issue a generic command for the controller

Parameters

structdwc3*dwc
pointer to the controller context
unsignedcmd
the command to be issued
u32param
command parameter

Description

Caller should take care of locking. Issuecmd with a givenparam todwcand wait for its completion.

intdwc3_send_gadget_ep_cmd(structdwc3_ep * dep, unsigned cmd, structdwc3_gadget_ep_cmd_params * params)

issue an endpoint command

Parameters

structdwc3_ep*dep
the endpoint to which the command is going to be issued
unsignedcmd
the command to be issued
structdwc3_gadget_ep_cmd_params*params
parameters to the command

Description

Caller should handle locking. This function will issuecmd with givenparams todep and wait for its completion.

intdwc3_gadget_start_config(structdwc3_ep * dep)

configure ep resources

Parameters

structdwc3_ep*dep
endpoint that is being enabled

Description

Issue aDWC3_DEPCMD_DEPSTARTCFG command todep. After the command’scompletion, it will set Transfer Resource for all available endpoints.

The assignment of transfer resources cannot perfectly follow the data bookdue to the fact that the controller driver does not have all knowledge of theconfiguration in advance. It is given this information piecemeal by thecomposite gadget framework after every SET_CONFIGURATION andSET_INTERFACE. Trying to follow the databook programming model in thisscenario can cause errors. For two reasons:

1) The databook says to doDWC3_DEPCMD_DEPSTARTCFG for everyUSB_REQ_SET_CONFIGURATION andUSB_REQ_SET_INTERFACE (8.1.5). This isincorrect in the scenario of multiple interfaces.

2) The databook does not mention doing moreDWC3_DEPCMD_DEPXFERCFG for newendpoint on alt setting (8.1.6).

The following simplified method is used instead:

All hardware endpoints can be assigned a transfer resource and this settingwill stay persistent until either a core reset or hibernation. So whenever wedo aDWC3_DEPCMD_DEPSTARTCFG``(0)wecangoaheadanddo``DWC3_DEPCMD_DEPXFERCFG for every hardware endpoint as well. We areguaranteed that there are as many transfer resources as endpoints.

This function is called for each endpoint when it is being enabled but istriggered only when called for EP0-out, which always happens first, and whichshould only happen in one of the above conditions.

int__dwc3_gadget_ep_enable(structdwc3_ep * dep, unsigned int action)

initializes a hw endpoint

Parameters

structdwc3_ep*dep
endpoint to be initialized
unsignedintaction
one of INIT, MODIFY or RESTORE

Description

Caller should take care of locking. Execute all necessary commands toinitialize a HW endpoint so it can be used by a gadget driver.

int__dwc3_gadget_ep_disable(structdwc3_ep * dep)

disables a hw endpoint

Parameters

structdwc3_ep*dep
the endpoint to disable

Description

This function undoes what __dwc3_gadget_ep_enable did and also removesrequests which are currently being processed by the hardware and those whichare not yet scheduled.

Caller should take care of locking.

structdwc3_trb *dwc3_ep_prev_trb(structdwc3_ep * dep, u8 index)

returns the previous TRB in the ring

Parameters

structdwc3_ep*dep
The endpoint with the TRB ring
u8index
The index of the current TRB in the ring

Description

Returns the TRB prior to the one pointed to by the index. If theindex is 0, we will wrap backwards, skip the link TRB, and returnthe one just before that.

voiddwc3_prepare_one_trb(structdwc3_ep * dep, structdwc3_request * req, unsigned int trb_length, unsigned chain, unsigned node)

setup one TRB from one request

Parameters

structdwc3_ep*dep
endpoint for which this request is prepared
structdwc3_request*req
dwc3_request pointer
unsignedinttrb_length
buffer size of the TRB
unsignedchain
should this TRB be chained to the next?
unsignednode
only for isochronous endpoints. First TRB needs different type.
intdwc3_gadget_start_isoc_quirk(structdwc3_ep * dep)

workaround invalid frame number

Parameters

structdwc3_ep*dep
isoc endpoint

Description

This function tests for the correct combination of BIT[15:14] from the 16-bitmicroframe number reported by the XferNotReady event for the future framenumber to start the isoc transfer.

In DWC_usb31 version 1.70a-ea06 and prior, for highspeed and fullspeedisochronous IN, BIT[15:14] of the 16-bit microframe number reported by theXferNotReady event are invalid. The driver uses this number to schedule theisochronous transfer and passes it to the START TRANSFER command. Becausethis number is invalid, the command may fail. If BIT[15:14] matches theinternal 16-bit microframe, the START TRANSFER command will pass and thetransfer will start at the scheduled time, if it is off by 1, the commandwill still pass, but the transfer will start 2 seconds in the future. For allother conditions, the START TRANSFER command will fail with bus-expiry.

In order to workaround this issue, we can test for the correct combination ofBIT[15:14] by sending START TRANSFER commands with different values ofBIT[15:14]: ‘b00, ‘b01, ‘b10, and ‘b11. Each combination is 2^14 uframe apart(or 2 seconds). 4 seconds into the future will result in a bus-expiry status.As the result, within the 4 possible combinations for BIT[15:14], there willbe 2 successful and 2 failure START COMMAND status. One of the 2 successfulcommand status will result in a 2-second delay start. The smaller BIT[15:14]value is the correct combination.

Since there are only 4 outcomes and the results are ordered, we can simplytest 2 START TRANSFER commands with BIT[15:14] combinations ‘b00 and ‘b01 todeduce the smaller successful combination.

Let test0 = test status for combination ‘b00 and test1 = test status for ‘b01of BIT[15:14]. The correct combination is as follow:

if test0 fails and test1 passes, BIT[15:14] is ‘b01if test0 fails and test1 fails, BIT[15:14] is ‘b10if test0 passes and test1 fails, BIT[15:14] is ‘b11if test0 passes and test1 passes, BIT[15:14] is ‘b00

Synopsys STAR 9001202023: Wrong microframe number for isochronous INendpoints.

voiddwc3_gadget_setup_nump(structdwc3 * dwc)

calculate and initialize NUMP field ofDWC3_DCFG

Parameters

structdwc3*dwc
pointer to our context structure

Description

The following looks like complex but it’s actually very simple. In order tocalculate the number of packets we can burst at once on OUT transfers, we’regonna use RxFIFO size.

To calculate RxFIFO size we need two numbers:MDWIDTH = size, in bits, of the internal memory busRAM2_DEPTH = depth, in MDWIDTH, of internal RAM2 (where RxFIFO sits)

Given these two numbers, the formula is simple:

RxFIFO Size = (RAM2_DEPTH * MDWIDTH / 8) - 24 - 16;

24 bytes is for 3x SETUP packets16 bytes is a clock domain crossing tolerance

Given RxFIFO Size, NUMP = RxFIFOSize / 1024;

intdwc3_gadget_init(structdwc3 * dwc)

initializes gadget related registers

Parameters

structdwc3*dwc
pointer to our controller context structure

Description

Returns 0 on success otherwise negative errno.

DWC3_DEFAULT_AUTOSUSPEND_DELAY()

DesignWare USB3 DRD Controller Core file

Parameters

Description

Copyright (C) 2010-2011 Texas Instruments Incorporated -https://www.ti.com

Authors: Felipe Balbi <balbi**ti.com**>,
Sebastian Andrzej Siewior <bigeasy**linutronix.de**>
intdwc3_get_dr_mode(structdwc3 * dwc)

Validates and sets dr_mode

Parameters

structdwc3*dwc
pointer to our context structure
intdwc3_core_soft_reset(structdwc3 * dwc)

Issues core soft reset and PHY reset

Parameters

structdwc3*dwc
pointer to our context structure
voiddwc3_free_one_event_buffer(structdwc3 * dwc, structdwc3_event_buffer * evt)

Frees one event buffer

Parameters

structdwc3*dwc
Pointer to our controller context structure
structdwc3_event_buffer*evt
Pointer to event buffer to be freed
structdwc3_event_buffer *dwc3_alloc_one_event_buffer(structdwc3 * dwc, unsigned length)

Allocates one event buffer structure

Parameters

structdwc3*dwc
Pointer to our controller context structure
unsignedlength
size of the event buffer

Description

Returns a pointer to the allocated event buffer structure on successotherwise ERR_PTR(errno).

voiddwc3_free_event_buffers(structdwc3 * dwc)

frees all allocated event buffers

Parameters

structdwc3*dwc
Pointer to our controller context structure
intdwc3_alloc_event_buffers(structdwc3 * dwc, unsigned length)

Allocatesnum event buffers of sizelength

Parameters

structdwc3*dwc
pointer to our controller context structure
unsignedlength
size of event buffer

Description

Returns 0 on success otherwise negative errno. In the error case, dwcmay contain some buffers allocated but not all which were requested.

intdwc3_event_buffers_setup(structdwc3 * dwc)

setup our allocated event buffers

Parameters

structdwc3*dwc
pointer to our controller context structure

Description

Returns 0 on success otherwise negative errno.

intdwc3_phy_setup(structdwc3 * dwc)

Configure USB PHY Interface of DWC3 Core

Parameters

structdwc3*dwc
Pointer to our controller context structure

Description

Returns 0 on success. The USB PHY interfaces are configured but notinitialized. The PHY interfaces and the PHYs get initialized together withthe core in dwc3_core_init.

intdwc3_core_init(structdwc3 * dwc)

Low-level initialization of DWC3 Core

Parameters

structdwc3*dwc
Pointer to our controller context structure

Description

Returns 0 on success otherwise negative errno.

[1](1,2,3) Transfer Request Block
[2]Transfer Request Block pointing to another TransferRequest Block.
[3](1,2) The Debug File System
[4]The Config File System
[5]Command Block Wrapper