On 9/29/2025 5:27 AM, Dmitry Baryshkov wrote:
On Sun, Sep 28, 2025 at 05:52:35PM +0800, Chaoyi Chen wrote:
On 9/23/2025 9:50 AM, Dmitry Baryshkov wrote:
[...]
+ /* One endpoint may correspond to one HPD bridge. */
+ for_each_of_graph_port_endpoint(port, dp_ep) {
+ /* Try to get "port" node of correspond PHY device */
+ struct device_node *phy_ep __free(device_node) =
+ of_graph_get_remote_endpoint(dp_ep);
+ struct device_node *phy_port __free(device_node) =
+ of_get_parent(phy_ep);
+
+ if (!phy_port) {
+ continue;
+ }
+
+ /*
+ * A PHY port may contain two endpoints: USB connector port or
CDN-DP port.
+ * Try to find the node of USB connector.
And then there can be a retimer between PHY and the USB-C connector. Or
some signal MUX. Or DP-to-HDMI bridge. Please, don't parse DT for other
devices. Instead you can add drm_aux_bridge to your PHY and let DRM core
build the bridge chain following OF graph.
I think building a bridge chain across multiple drm_aux_hpd_bridge may be
difficult. First, drm_dp_hpd_bridge_register() cannot register the bridge
immediately; instead, it is deferred until drm_aux_hpd_bridge_probe(). When it
is added to the bridge_list, it may not yet be attached, and attempting to
attach it at that point is too late.
But, if I only use drm_aux_bridge on the USB-C connector, and use my own custom
bridge on the PHY device and managing the alloc and attach bridge process
myself, then things would become much easier.
Well... consider a your board, but add onnn,nb7vpq904m retimer between
the CDP and usb-c connector (it's not an uncommon device nowadays). Or
add fsa4480 analog audio switch. Build all the drivers as modules. You
should not need any changes to your drivers to handle such boards and
such kernel config.
With those devices you can't handle everything inside the DP driver,
since there are two "streams" of probe events: the DRM bridge needs the
"next" bridge (in the direction from the SoC to the connector), but the
USB-C events code needs "previous" mux, switch or retirmer. After some
trial and error we have ended up with having a chain of drm_aux_bridge
devices ending up with the drm_aux_hpd_bridge inside the Type-C port
manager driver. This way the typec_* depetencies are resolved first,
going from the SoC to the Type-C controller driver then the DRM bridge
devices probe backwards, creating the chain, which is finally consumer
by the DP driver inside the SoC.
Sorry, I kept trying to look for the "next bridge" in "drm_hpd_aux_bridge", and I didn't notice
that "drm_aux_bridge" already had a similar implementation about "next bridge". Thanks again for
your patience.
BTW the devm_drm_of_get_bridge(&auxdev->dev, auxdev->dev.of_node, 0, 0) in
drm_aux_bridge cannot be used directly with tcphy->dev. I may need to create a device for
the dp-port child node, and then use drm_aux_bridge_register(). But this is no longer a big
issue :)
--
Best,
Chaoyi