On Mon 04 Oct 17:36 PDT 2021, Doug Anderson wrote: > Hi, > > On Fri, Oct 1, 2021 at 2:00 PM Bjorn Andersson > <bjorn.andersson@xxxxxxxxxx> wrote: > > > > On Fri 27 Aug 13:52 PDT 2021, Doug Anderson wrote: > > > > > Hi, > > > > > > On Mon, Jul 26, 2021 at 4:15 PM Bjorn Andersson > > > <bjorn.andersson@xxxxxxxxxx> wrote: > > > > > > > > +static int dp_parser_find_panel(struct dp_parser *parser) > > > > +{ > > > > + struct device_node *np = parser->pdev->dev.of_node; > > > > + int rc; > > > > + > > > > + rc = drm_of_find_panel_or_bridge(np, 2, 0, &parser->drm_panel, NULL); > > > > > > Why port 2? Shouldn't this just be port 1 always? The yaml says that > > > port 1 is "Output endpoint of the controller". We should just use port > > > 1 here, right? > > > > > > > Finally got back to this, changed it to 1 and figured out why I left it > > at 2. > > > > drm_of_find_panel_or_bridge() on a DP controller will find the of_graph > > reference to the USB-C controller, scan through the registered panels > > and conclude that the of_node of the USB-C controller isn't a registered > > panel and return -EPROBE_DEFER. > > I'm confused, but maybe it would help if I could see something > concrete. Is there a specific board this was happening on? > Right, let's make this more concrete with a snippet from the actual SC8180x DT. > Under the DP node in the device tree I expect: > > ports { > port@1 { > reg = <1>; > edp_out: endpoint { > remote-endpoint = <&edp_panel_in>; > }; > }; > }; > /* We got a panel */ panel { ... ports { port { auo_b133han05_in: endpoint { remote-endpoint = <&mdss_edp_out>; }; }; }; }; /* And a 2-port USB-C controller */ type-c-controller { ... connector@0 { ports { port@0 { reg = <0>; ucsi_port_0_dp: endpoint { remote-endpoint = <&dp0_mode>; }; }; port@1 { reg = <1>; ucsi_port_0_switch: endpoint { remote-endpoint = <&primary_qmp_phy>; }; }; }; }; connector@1 { ports { port@0 { reg = <0>; ucsi_port_1_dp: endpoint { remote-endpoint = <&dp1_mode>; }; }; port@1 { reg = <1>; ucsi_port_1_switch: endpoint { remote-endpoint = <&second_qmp_phy>; }; }; }; }; }; /* And then our 2 DP and single eDP controllers */ &mdss_dp0 { ports { port@1 { reg = <1>; dp0_mode: endpoint { remote-endpoint = <&ucsi_port_0_dp>; }; }; }; }; &mdss_dp1 { ports { port@1 { reg = <1>; dp1_mode: endpoint { remote-endpoint = <&ucsi_port_1_dp>; }; }; }; }; &mdss_edp { ports { port@1 { reg = <1>; mdss_edp_out: endpoint { remote-endpoint = <&auo_b133han05_in>; }; }; }; }; > If you have "port@1" pointing to a USB-C controller but this instance > of the DP controller is actually hooked up straight to a panel then > you should simply delete the "port@1" that points to the typeC and > replace it with one that points to a panel, right? > As you can see, port 1 on &mdss_dp0 and &mdss_dp1 points to the two UCSI connectors and the eDP points to the panel, exactly like we agreed. So now I call: drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); which for the two DP nodes will pass respective UCSI connector to drm_find_panel() and get EPROBE_DEFER back - because they are not on panel_list. There's nothing indicating in the of_graph that the USB connectors aren't panels (or bridges), so I don't see a way to distinguish the two types remotes. Hope that clarifies my conundrum. Regards, Bjorn