On Fri, Dec 10, 2021 at 04:47:07PM +0530, Jagan Teki wrote: > Having component_add for running all drm bind callbacks returns > error or unbound due to chain of DSI devices connected across > bridge topology on a display pipeline. I'm not sure what that means? > In a typical bridge oriented display pipeline where the host is > connected to the bridge converter and that indeed connected to > a panel. > > DRM => SUN6I DSI Host => Chipone ICN6211 => BananaPi Panel > > The bridge converter is looking for a panel to probe first and > then attach the host. The host attach is looking for a bridge > converter to probe and preserve bridge pointer, at this movement ^ moment ? > the host is trying to bind the all callbacks and one of the bind > callback in the DSI host is trying to find the bridge using the > bridge pointer in sun6i_dsi_attach call. > > chipone_probe().start > drm_of_find_panel_or_bridge > mipi_dsi_attach > sun6i_dsi_attach > drm_of_find_panel_or_bridge > chipone_probe().done > > sun6i_dsi_probe().start > mipi_dsi_host_register > component_add > sun6i_dsi_probe().done > > However, the movement when panel defers the probe, will make the > bridge converter defer the host attach call which eventually found > a NULL bridge pointer during DSI component bind callback. > > So, in order to prevent this scenario of binding invalid bridge, > wait for DSI devices on the pipeline to probe first and start the > binding process by moving component_add in host probe to attach call. > > chipone_probe().start > drm_of_find_panel_or_bridge > mipi_dsi_attach > sun6i_dsi_attach > drm_of_find_panel_or_bridge > component_add > chipone_probe().done > > sun6i_dsi_probe().start > mipi_dsi_host_register > sun6i_dsi_probe().done > > Signed-off-by: Jagan Teki <jagan@xxxxxxxxxxxxxxxxxxxx> > --- > Changes for v6: > - none > Changes for v5: > - new patch > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 120 +++++++++++++------------ > 1 file changed, 61 insertions(+), 59 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > index 4bdcce8f1d84..9cf91dcac3f2 100644 > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c > @@ -959,11 +959,63 @@ static int sun6i_dsi_dcs_read(struct sun6i_dsi *dsi, > return 1; > } > > +static int sun6i_dsi_bind(struct device *dev, struct device *master, > + void *data) > +{ > + struct drm_device *drm = data; > + struct sun6i_dsi *dsi = dev_get_drvdata(dev); > + int ret; > + > + drm_encoder_helper_add(&dsi->encoder, > + &sun6i_dsi_enc_helper_funcs); > + ret = drm_simple_encoder_init(drm, &dsi->encoder, > + DRM_MODE_ENCODER_DSI); > + if (ret) { > + dev_err(dsi->dev, "Couldn't initialise the DSI encoder\n"); > + return ret; > + } > + dsi->encoder.possible_crtcs = BIT(0); > + > + drm_connector_helper_add(&dsi->connector, > + &sun6i_dsi_connector_helper_funcs); > + ret = drm_connector_init(drm, &dsi->connector, > + &sun6i_dsi_connector_funcs, > + DRM_MODE_CONNECTOR_DSI); > + if (ret) { > + dev_err(dsi->dev, > + "Couldn't initialise the DSI connector\n"); > + goto err_cleanup_connector; > + } > + > + drm_connector_attach_encoder(&dsi->connector, &dsi->encoder); > + > + return 0; > + > +err_cleanup_connector: > + drm_encoder_cleanup(&dsi->encoder); > + return ret; > +} > + > +static void sun6i_dsi_unbind(struct device *dev, struct device *master, > + void *data) > +{ > + struct sun6i_dsi *dsi = dev_get_drvdata(dev); > + > + drm_encoder_cleanup(&dsi->encoder); > +} > + > +static const struct component_ops sun6i_dsi_ops = { > + .bind = sun6i_dsi_bind, > + .unbind = sun6i_dsi_unbind, > +}; Just use a forward declaration there, it will make the patch more straightforward. Maxime
Attachment:
signature.asc
Description: PGP signature