Related problem is single-board computers that relies on USB-PD for power. USB-PD sources requires the sink to do power delivery negotiation within 5 seconds, or it will cut its power or do funny things. Because USB-PD negotiation is handled in Linux, by the time Linux boots it will be too late, and power supply will cut the power, so it will be stuck in a boot loop: https://www.spinics.net/lists/linux-usb/msg239175.html
They way they're trying to solve it is very similar to this article, by doing the USB-PD negotiation during U-boot bootloader stage:
- https://gitlab.collabora.com/hardware-enablement/rockchip-35...
- https://lore.kernel.org/u-boot/20241015152719.88678-1-sebast...
Interesting, thanks for sharing. I missed that evolution of "thin" USB-C controllers which delegate the PD handshake elsewhere.
I don't know yet how I feel about the fact that a driver in the OS is supposed to take this role and tell the power-supply how much power to deliver. Not necessarily a novel security concern, but a potential nightmare from a plain B2C customer service perspective (i.e. a faulty driver causing the system to shut down during boot, fry the Motherboard,...)
It's not, per-se, a driver doing the PD negotiation in software; it's more that the USB chipset isnt initialized and configured for PD negotiation (or anything else for that matter) until the CPU twiddles its PCI configuration space.
I would have imagined that USB controller chipsets would likely offer some nonvolatile means to set the PD configuration (like jumpers or eeprom) precisely because of this issue. It's surprising to me that such a feature isnt common
Having persistent state between components is a nightmare in embedded world
Nevertheless I'm surprised USB controller initialization is done by the OS instead of the motherboard chipset
it would be the role of embedded controller instead of SOC to handle PD negotiation. But on SBC, EC may not available.
Reading the thread, the behaviour seems to depend on the power supply. I have powered a Pinebook Pro via USB-C with a PinePower PSU, didn't even have a FUSB302 driver in the OS then (am currently adding one).
Other boards don't do USB-PD at all and just rely you using a PSU with a USB-C connector that defaults to 5V, e.g. RPi and Orange pi 5 (RK3588).
For 5V output (like used on the Pinebook) you don't need to negotiate anything over USB-PD, that's the default provided by a USB-C PSU to ensure legacy USB compatibility. Support for higher currents can then be "unlocked" with resistors between the Alt Data-Lines (like a USB-A charger would).
Everything beyond 5V requires a handshake between device and PSU, which ensures that the connected device can actual handle higher power output.
It's arguably not "negotiation", but if the connector is USB-C on both ends, then even 5V requires a couple of resistors to determine which side is the source and which side is the sink.
It's pretty common for really cheap electronics to skip these resistors, and then they can only be powered with a USB-A to USB-C cable, not C-to-C. (Because USB-A ports always a source and never a sink.) Adafruit even makes a $4.50 adapter to fix the issue.
But you're right that everything higher than 5V & 3A gets significantly more complex.
All correct and agreed.
My comment was in context of the active communication between source/sink on USB-PD and the increased complexity, intentionally excluding passive configuration using different resistors.
It kinda blows my mind that the Ethernet or USB phy doesn't have this stored in some tiny nvram and handle all of the negotiations. What if I have a battery to charge while the device is off such as a laptop? How does Android deal with this when it's not booted? Does the bios handle this stuff?
> What if I have a battery to charge while the device is off such as a laptop? How does Android deal with this when it's not booted? Does the bios handle this stuff?
In my experience, if the device doesn't have enough power to actually boot it will simply slow charge at the default USB rate.
This can be problematic with devices that immediately try to boot when powered on.
> This can be problematic with devices that immediately try to boot when powered on.
I had an iPad 3 stuck in a low-battery reboot loop like this for hours once upon a time. I eventually got the idea to force it into DFU mode and was finally able to let it charge long enough to complete its boot process.
I have likewise had the same situation with a Kindle Fire and a Huawei Watch, in both cases I was glad I had rooted them and thus had a much easier path to boot to recovery than I would have stock.
There are standalone PD controllers that can be configured with the desired power profile(s) in flash.
And those add an extra few cents to the BOM which bean counters will ask if it can be eliminated and handled in software, which it can for the most part be leading to the problem discussed.
That said, my personal experience with this problem is all with devices that predate the standardization of or at least widespread use of USB PD.
Apple solves this by doing all PD negotiation in hardware.
Unless you are very price sensitive, using USB Power Delivery ICs is the norm now for most devices, but PD is different than POE. PD is just loose tolerance resistors on USB.
Incorrect. https://en.wikipedia.org/wiki/USB_hardware#USB_Power_Deliver... is a good start about the subject: "PD-aware devices implement a flexible power management scheme by interfacing with the power source through a bidirectional data channel and requesting a certain level of electrical power <...>".
No, it's not. You can do very basic selection with resistors, but you can't get above 5V (or more than a couple of amps IIRC) without using the actual PD communication protocol.