dts: bindings: usb: Specify fifo sizes in devicetree#99510
dts: bindings: usb: Specify fifo sizes in devicetree#99510tmon-nordic wants to merge 2 commits intozephyrproject-rtos:mainfrom
Conversation
|
|
||
| usb0: usb@ffb30000 { | ||
| compatible = "snps,dwc2"; | ||
| reg = <0xffb30000 0xffff>; |
There was a problem hiding this comment.
@nashif I found fifo information in Cyclone V HPS Register Address Map and Definitions but there the usb0 is at 0xFFB00000 and not 0xFFB30000. Is it a bug in zephyr devicetree or am I looking at wrong place?
There was a problem hiding this comment.
@nashif I found fifo information in Cyclone V HPS Register Address Map and Definitions but there the usb0 is at 0xFFB00000 and not 0xFFB30000. Is it a bug in zephyr devicetree or am I looking at wrong place?
I think this might be a bug in the Zephyr devicetree. The Linux kernel also uses 0xFFB00000 as the base address for Cyclone V usb0.
|
@raffarost Can you provide the devicetree values from esp32-s3? |
|
@jean12332 can you verify whether this also fixes #95500? |
hi @tmon-nordic, |
What is actual GDFIFOCFG register value? The upper 16 bits show how many locations are available for fifos, the lower 16 bits show total SPRAM size. When DMA is used, some locations are used for storing DMA pointers (this is where the difference between the upper 16 bits and lower 16 bits come from). GHWCFG3 upper 16 bits report available DFIFO Depth (after reset should be the same as upper 16 bits from GDFIFOCFG register). |
81ea271 to
7c6577c
Compare
7c6577c to
e95f5bb
Compare
6e80138 to
d70234e
Compare
|
Rebased to fix conflict in |
|
jfischer-no
left a comment
There was a problem hiding this comment.
Dynamically allocating fifo sizes leads to very complex code that yields
subpar results.
For sure not, #94766 is not complex, and provides the necessary FIFO sizes based on actual USB device configuration. Using devicetree would not scale, and we have already far too many overlays in the tree.
It is not complex, but it does not allow the users to take control over the allocations. One problem is for example deciding whether to have at least two wMaxPacketSize available for bulk endpoints (this does have significant impact on MSC performance). There is a reason why reference Synopsys DWC2 driver (the one in Linux mainline) does use these very devicetree entries. I feel it is not worth it to try to come up with smarter code. However, if you want to go that path - do propose something that gives actual control to the application developer. There are already multiple problems with endpoint assignemnt logic in Zephyr (see #102041 (comment)) and trying to come up with magic code for allocating fifos is not making the task any simpler. You are also completely ignoring the fact that Synopsys DWC2 can have different limitations for individual fifos. Such limitation in actual silicon is the original reason why #96206 was opened. The actual hardware limitations together with application specific requirements make me strongly believe that leaving fifo assignments up to user is not only the simplest but also the best solution.
With reasonable default generic fifo configurations like proposed here, I don't think there would be a need for any per-sample specific overlays. For platforms with large SPRAM and flexible fifos, I doubt anyone would ever have to change it. For the small SPRAM most likely the users won't actually adjust (unless they have very specific use case, but that's up to application). Allowing the user to specify the fifo sizes IMHO is most beneficial is for devices with middle sized SPRAM, because it then allows developers to tailor cut it for their actual application. Another issue that would be trivial to solve with devicetree and IMHO not really worth attempting to come up a "clever code" is to determine when to enable thresholding. It should be up to the user, because there are way too many variables to consider (memory access times being one of them). |
|
Thinking about this, why not have both? If the user does not specify the fifo sizes in Devicetree the the stack can heuristically determine the sizes, and otherwise the ones provided in the overlay are used instead. |
Having both may sound like a good idea, but then we wouldn't get the benefit of being able to remove a significant chunk of code that gives subpar results. Stack is currently not really suited for having sensible heuristics (I believe the only way for the heuristics to be sensible is if the stack provided complete overview of all endpoints used in configuration to UDC driver in a single call). Driver is currently attempting to dynamically allocate memory (fifo space) based on |
Well, we would if we had a new Kconfig option (that could be enabled by default), something like (pseudocode): |
This would actually complicate the code even more instead of making it cleaner. The reasons to have this fixed at build time are:
The workaround for the significant bulk endpoint hit could be as simple as multiplying zephyr/drivers/usb/udc/udc_dwc2.c Line 1394 in 79e6e32 by 2 if endpoint is bulk type. This however would be just applying a bandaid instead of solving the actual root cause (having to dynamically allocate SPRAM locations without having full system overview). |
Even bigger thing is that we don't have a working allocator. There are multiple ways where the current fifo allocation fails. This is summed up in commit message Last time the 1-to-1 endpoint number was attempted to be fixed (#95654) it went out of budget during review. There is also a hidden cost in delaying this PR: every time new |
Add g-rx-fifo-size, g-np-tx-fifo-size and g-tx-fifo-size required properties to snps,dwc2 compatible. Property names are the same as used in Linux because Zephyr aims for devicetree source compatibility with other operating systems. Specifying fifo sizes in devicetree greatly reduces necessary driver complexity and allows application developer to adjust the sizes if necessary to best utilize underlying hardware. Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Dynamically allocating fifo sizes leads to very complex code that yields
subpar results. DWC2 controller has very specific requirements related
to configured FIFO sizes that significantly increase the complexity:
* each fifo has specific upper bound on both size and starting
location (fixed for each silicon)
* assigned locations must be contiguous
* assigned locations cannot be changed on-the-fly
Zephyr tried to dynamically assign fifos using simple but essentially
broken algorithm that:
* assumed 1-to-1 endpoint number to TxFIFO mapping
DWC2 controller can be configured with non-contiguous IN endpoint
numbers, but TxFIFOs are always contiguous.
* allocated minimum required space for each endpoint
There is no benefit in using less SPRAM than hardware has available,
but using only 128 locations per bulk endpoint significantly limits
maximum transfer rate when using DMA. At least 256 locations allows
DMA to load next packet data before previous packet is transmitted
on the bus. Actual performance degradation depends on clock rates
and latencies. MSC on nRF54H20 using bulk endpoints with only 128
locations can achieve no more than 15.6 MB/s throughput, while with
256 locations speeds up to 36.9 MB/s are possible (running otherwise
identical software).
* used one-size-fits-all defaults for RxFIFO
Remedied with some upper limits calculated at runtime, but the limit
was not taking into account complete configuration.
* was unable to effectively handle multiple alternate settings
This did lead to set interface failures where e.g. HID interface
with wMaxPacketSize > 64 was not using the highest numbered IN
endpoint within active configuration.
Instead of trying to come up with bandaid for each issue that would
significantly complicate the code, just shift the responsibility towards
firmware developer. While for many typical applications board defaults
are perfectly fine, the application developer may want to come up with
specific devicetree overrides best suited for their use case.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
|



Add g-rx-fifo-size, g-np-tx-fifo-size and g-tx-fifo-size required properties to snps,dwc2 compatible. Property names are the same as used in Linux because Zephyr aims for devicetree source compatibility with other operating systems.
Specifying fifo sizes in devicetree greatly reduces necessary driver complexity and allows application developer to adjust the sizes if necessary to best utilize underlying hardware.
Implements #96206