@juliancalaby Right, the problem is the existing interface isn't even consistent, because it evolved from simpler hardware and is now a mess for more complex hardware.
There's a "USB Role Switch" interface which is part of the USB subsystem, and is called by both drivers in the "extcon" subsystem and the "usb/typec" subsystem. But that is just host/device, it doesn't cover any TypeC shenanigans (this started in the miniUSB/microUSB days). This is what actually triggers the USB controller to switch modes between host/device.
Then there is the TypeC mux interface, which is intended to just change modes for the TypeC pins. But it doesn't know anything about host/device roles, that is assumed to be independent.
Then there is the TypeC USB-PD stuff, which is intended to handle USB-PD interface details for chips which are basically USB-PD PHYs.
Then there's the reset subsystem, which provides out-of-band control over reset lines for peripherals.
And then there is the PHY interface, which just deals, in principle, with a single PHY for a single protocol in front of a single controller.
So this whole thing was designed for a system where you have discrete components:
-
USB/DP/etc controllers, which each interact (potentially) with their own PHY, completely under their control
-
A TypeC USB-PD PHY with the PD protocol managed in software
-
A dumb mux (and/or possibly retimer) chip to switch the data lines between backing PHYs
-
Some unrelated reset control, if necessary
And then the mess we have right now is:
-
The tipd driver handles the USB-PD controller chip, which is not just a PD PHY but actually autonomously does everything the TypeC subsystem wants to do manually, which doesn't work well with the subsystem. It also manages the retimer chips autonomously (but they are just retimers, not muxes). So it skips all those layers and calls into the mux and role switch layers directly.
-
The dwc3 driver handles the role switching and calls into the phy drivers for USB2/USB3, but only to an extent.
-
Our display controller driver delegates its stuff to DCP firmware, but DCP firmware calls back into the display controller driver for PHY management, so it has to forward that to the (DP) PHY subsystem.
-
Our atcphy driver tries to be all of a reset controller, all the PHYs, and USB-C mux, all at once, to tie everything together. But since the mux side doesn't know about host/device roles, and since the PHY side is split up into different logical PHYs, and since the order everything is called is not consistent, and since dwc3 insists on doing role switching in a workqueue asynchronously, and since it's actually tipd doing the calls to both the role switch and mux sides, it's a giant mess.
The ultimate problem here is there is a fixed hierarchy of calls. The design of the subsystems assumes the PD stuff will call into roleswitch and mux. But what we really need is a top-level management driver that just receives status notifications from the PD driver, and then drives the PHY config as needed, coordinating the roleswitch and DisplayPort HPD calls exactly when needed.
@marcan My perspective on this is mostly USB2, but the same problem exists there too: some drivers do everything in-house, some have external PHY drivers that do ... something maybe involving a MUX thing, etc.
IMHO you should go further than just a "top-level management" driver coordinating things for the PD device and build something more like a "port" driver: status flows up from every device (driver) involved and control flows down to the various components and _nothing_ does anything without the go-ahead of this driver.
The problem then becomes that this would probably require significant refactoring of just about every driver involved, and worse, would probably require coring out most of the "logic" from the dwc3 driver, which is probably just hacked together "port" drivers for other SoCs.
@marcan My perspective on this is mostly USB2, but the same problem exists there too: some drivers do everything in-house, some have external PHY drivers that do ... something maybe involving a MUX thing, etc.
IMHO you should go further than just a "top-level management" driver coordinating things for the PD device and build something more like a "port" driver: status flows up from every device (driver) involved and control flows down to the various components and _nothing_ does anything without...