openbouffalo / linux

Linux kernel source tree
Other
6 stars 4 forks source link

Bl808/usb upgrade fotg210 #3

Open grant-olson opened 1 year ago

grant-olson commented 1 year ago

This upgrades the drivers for the USB IP used by the BL808. The new drivers were primarily written by Faraday Semiconductor and are available at https://github.com/FaradayA380Platform/Linux This PR just ports over these and makes required changes for them to work on linux 6.2.

There is a set of 5 patches:

  1. Replace old drivers with new ones as is, all code authored by Faraday Semiconductor.
  2. Patches to make the drivers work with the current linux kernel version.
  3. DTS updates
  4. Basic defconfig update, which only enables core USB functionality.
  5. Advanced defconfig update, with most of the usb accessory options that a typical user will want.

This patch will not physically power up the USB as that happens in the BL808 PDS subsystem. The code to power up the USB is included in the current version of OBLFR, but needs to be enabled in the OBLFR config for the device to work.

We implement both HDC (host) and UCD (peripheral) modes. However HDC/host mode suffers the same problems we are seeing on the bare metal SDK implementation, recorded as Issue 65 in the SDK repo. I think it's working as well as can be expected until Bouffalo provides a fix. Because of this we enable UCD/peripheral mode by default.

To test you'll need to load a USB gadget which determines the mode we use for a USB peripheral. An script with several examples of working gadgets is available here: https://github.com/grant-olson/buildroot_bouffalo/blob/usb_gadgets/board/pine64/ox64/rootfs-overlay/etc/init.d/S70gadgets

Fishwaldo commented 1 year ago

Is this actually "stable"? I kept seeing in the chat that it dies after 2-3Mb's of traffic? or was that the u-boot implementation?

grant-olson commented 1 year ago

My initial tests were just running top for several hours. I'm just now getting around to @madushan1000 reports. What I'm seeing is there does seem to be some problems with large transfers. If I transfer a 10 Mb file the system locks up. However I can send 1 Mb files all day and it works:

grant@grant-ubuntu buildroot % dd if=/dev/zero of=1_meg.dat bs=1024 count=1000 
1000+0 records in
1000+0 records out
1024000 bytes (1.0 MB, 1000 KiB) copied, 0.00181078 s, 566 MB/s
grant@grant-ubuntu buildroot % dd if=/dev/zero of=10_meg.dat bs=1024 count=10000
10000+0 records in
10000+0 records out
10240000 bytes (10 MB, 9.8 MiB) copied, 0.0317984 s, 322 MB/s
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root                        
1_meg.dat: 1 file pushed. 2.3 MB/s (1024000 bytes in 0.432s)
grant@grant-ubuntu buildroot % 
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.3 MB/s (1024000 bytes in 0.433s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.3 MB/s (1024000 bytes in 0.432s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.2 MB/s (1024000 bytes in 0.440s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.2 MB/s (1024000 bytes in 0.437s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.3 MB/s (1024000 bytes in 0.431s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.2 MB/s (1024000 bytes in 0.436s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.3 MB/s (1024000 bytes in 0.430s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.3 MB/s (1024000 bytes in 0.434s)
grant@grant-ubuntu buildroot % adb push 1_meg.dat /root
1_meg.dat: 1 file pushed. 2.2 MB/s (1024000 bytes in 0.436s)
grant@grant-ubuntu buildroot % adb push 10_meg.dat /root
[ 25%] /root/10_meg.dat
madushan1000 commented 1 year ago

I managed to get the mainstream driver working too and it has the same issue. anything under around ~2Mb works fine, and can do repeated transfers. but anything bigger will get stuck around ~3Mb mark. I narrowed it down to an interrupt issue. Once the fifo has some data, the controller should fire an interrupt to let the driver know that it can read data, sometimes controller will set all the other registers to show that there is some data in a fifo but the interrupt doesn't come. This happens with both out and in transfers. I'm wondering if this is some issues with the m0 interrupt forwarding code.

Fishwaldo commented 1 year ago

Once the fifo has some data, the controller should fire an interrupt to let the driver know that it can read data, sometimes controller will set all the other registers to show that there is some data in a fifo but the interrupt doesn't come.

in the IRQ forwarder - When we get a interupt, we disable that interupt, send it off to D0 and wait for a EOI intertupt back (which happens after the IRQ hander runs on linux) then re-enable the interupt

what might be happening is a USB interupt is fired while we are pending a EOI from linux (and thus masked). Two things you could try: 1) Move this line straight after reading the register here

2) comment out this line but this isn't really a solution, it would just be useful for diagnostics

Fishwaldo commented 1 year ago

(note - Both potentially could introduce a race condition into the IRQ forwarding, so a proper solution needs to be implemented if this does fix your issues)

madushan1000 commented 1 year ago

Looks like the 2nd trick solves it. I was able to push/pull 100Mb file with it.

alexhorner commented 1 year ago

Looks like the 2nd trick solves it. I was able to push/pull 100Mb file with it.

A good candidate to test once the new IRQ driver is in then?

grant-olson commented 1 year ago

I did a buildroot build with the discussed OBLFR hack to make it easier for people to test. It is available here: https://github.com/grant-olson/buildroot_bouffalo/releases/tag/usb_gadget-beta2

So far I'm able to send large 100 Mb files with either zmodem or adb push and they get through and have good checksums. I'm not seeing indications that they're needing to retransmit packets due to checksum errors, but honestly not sure if that would be logged normally.

This also seems to resolve a problem I would see when using the ethernet gadget where it wouldn't die like we see during a file transfer, but would 'flap' and disconnect and reconnect from the host machine. I now get a good solid software ethernet connection.